chattr: bugfixes and size reduction

This commit is contained in:
Denis Vlasenko 2006-12-26 03:36:28 +00:00
parent 407b8c0b70
commit 5dd7ef0f37
3 changed files with 31 additions and 41 deletions

View File

@ -59,14 +59,13 @@ static const struct flags_char flags_array[] = {
static unsigned long get_flag(char c) static unsigned long get_flag(char c)
{ {
const struct flags_char *fp; const struct flags_char *fp;
for (fp = flags_array; fp->flag; fp++) for (fp = flags_array; fp->optchar; fp++)
if (fp->optchar == c) if (fp->optchar == c)
return fp->flag; return fp->flag;
bb_show_usage(); bb_show_usage();
/*return 0;*/
} }
static int decode_arg(char *arg) static int decode_arg(const char *arg)
{ {
unsigned long *fl; unsigned long *fl;
char opt = *arg++; char opt = *arg++;
@ -89,15 +88,27 @@ static int decode_arg(char *arg)
return 1; return 1;
} }
static int chattr_dir_proc(const char *, struct dirent *, void *); static void change_attributes(const char *name);
static void change_attributes(const char * name) static int chattr_dir_proc(const char *dir_name, struct dirent *de,
void *private ATTRIBUTE_UNUSED)
{
char *path = concat_subpath_file(dir_name, de->d_name);
/* path is NULL if de->d_name is "." or "..", else... */
if (path) {
change_attributes(path);
free(path);
}
return 0;
}
static void change_attributes(const char *name)
{ {
unsigned long fsflags; unsigned long fsflags;
struct stat st; struct stat st;
if (lstat(name, &st) == -1) { if (lstat(name, &st) == -1) {
bb_error_msg("stat %s failed", name); bb_perror_msg("stat %s", name);
return; return;
} }
if (S_ISLNK(st.st_mode) && recursive) if (S_ISLNK(st.st_mode) && recursive)
@ -112,13 +123,13 @@ static void change_attributes(const char * name)
if (flags & OPT_SET_VER) if (flags & OPT_SET_VER)
if (fsetversion(name, version) == -1) if (fsetversion(name, version) == -1)
bb_error_msg("setting version on %s", name); bb_perror_msg("setting version on %s", name);
if (flags & OPT_SET) { if (flags & OPT_SET) {
fsflags = sf; fsflags = sf;
} else { } else {
if (fgetflags(name, &fsflags) == -1) { if (fgetflags(name, &fsflags) == -1) {
bb_error_msg("reading flags on %s", name); bb_perror_msg("reading flags on %s", name);
goto skip_setflags; goto skip_setflags;
} }
if (flags & OPT_REM) if (flags & OPT_REM)
@ -129,38 +140,19 @@ static void change_attributes(const char * name)
fsflags &= ~EXT2_DIRSYNC_FL; fsflags &= ~EXT2_DIRSYNC_FL;
} }
if (fsetflags(name, fsflags) == -1) if (fsetflags(name, fsflags) == -1)
bb_error_msg("setting flags on %s", name); bb_perror_msg("setting flags on %s", name);
skip_setflags: skip_setflags:
if (S_ISDIR(st.st_mode) && recursive) if (recursive && S_ISDIR(st.st_mode))
iterate_on_dir(name, chattr_dir_proc, NULL); iterate_on_dir(name, chattr_dir_proc, NULL);
} }
static int chattr_dir_proc(const char *dir_name, struct dirent *de,
void *private ATTRIBUTE_UNUSED)
{
/*if (strcmp(de->d_name, ".") || strcmp(de->d_name, "..")) {*/
if (de->d_name[0] == '.'
&& (!de->d_name[1] || LONE_CHAR(de->d_name+1, '.'))
) {
char *path = concat_subpath_file(dir_name, de->d_name);
if (path) {
change_attributes(path);
free(path);
}
}
return 0;
}
int chattr_main(int argc, char **argv) int chattr_main(int argc, char **argv)
{ {
int i;
char *arg; char *arg;
/* parse the args */ /* parse the args */
for (i = 1; i < argc; ++i) { while ((arg = *++argv)) {
arg = argv[i];
/* take care of -R and -v <version> */ /* take care of -R and -v <version> */
if (arg[0] == '-') { if (arg[0] == '-') {
if (arg[1] == 'R' && arg[2] == '\0') { if (arg[1] == 'R' && arg[2] == '\0') {
@ -168,10 +160,9 @@ int chattr_main(int argc, char **argv)
continue; continue;
} }
if (arg[1] == 'v' && arg[2] == '\0') { if (arg[1] == 'v' && arg[2] == '\0') {
++i; if (!*++argv)
if (i >= argc)
bb_show_usage(); bb_show_usage();
version = xatoul(argv[i]); version = xatoul(*argv);
flags |= OPT_SET_VER; flags |= OPT_SET_VER;
continue; continue;
} }
@ -182,18 +173,17 @@ int chattr_main(int argc, char **argv)
} }
/* run sanity checks on all the arguments given us */ /* run sanity checks on all the arguments given us */
if (i >= argc) if (!*argv)
bb_show_usage(); bb_show_usage();
if ((flags & OPT_SET) && (flags & (OPT_ADD|OPT_REM))) if ((flags & OPT_SET) && (flags & (OPT_ADD|OPT_REM)))
bb_error_msg_and_die("= is incompatible with - and +"); bb_error_msg_and_die("= is incompatible with - and +");
if (rf & af) if (rf & af)
bb_error_msg_and_die("Can't set and unset a flag"); bb_error_msg_and_die("can't set and unset a flag");
if (!flags) if (!flags)
bb_error_msg_and_die("Must use '-v', =, - or +"); bb_error_msg_and_die("must use '-v', =, - or +");
/* now run chattr on all the files passed to us */ /* now run chattr on all the files passed to us */
while (i < argc) do change_attributes(*argv); while (*++argv);
change_attributes(argv[i++]);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -174,7 +174,7 @@
" S Write file contents synchronously\n" \ " S Write file contents synchronously\n" \
" t Disable tail-merging of partial blocks with other files\n" \ " t Disable tail-merging of partial blocks with other files\n" \
" u Allow file to be undeleted\n" \ " u Allow file to be undeleted\n" \
" Options:\n" \ "Options:\n" \
" -R Recursively list subdirectories\n" \ " -R Recursively list subdirectories\n" \
" -v Set the file's version/generation number" " -v Set the file's version/generation number"

View File

@ -10,14 +10,14 @@
/* /*
This function make special for recursive actions with usage This function make special for recursive actions with usage
concat_path_file(path, filename) concat_path_file(path, filename)
and skiping "." and ".." directory entries and skipping "." and ".." directory entries
*/ */
#include "libbb.h" #include "libbb.h"
char *concat_subpath_file(const char *path, const char *f) char *concat_subpath_file(const char *path, const char *f)
{ {
if(f && *f == '.' && (!f[1] || (f[1] == '.' && !f[2]))) if (f && *f == '.' && (!f[1] || (f[1] == '.' && !f[2])))
return NULL; return NULL;
return concat_path_file(path, f); return concat_path_file(path, f);
} }