- usage fresh bb_getopt_ulflags for ls -- very size reduce.

- small indent corrections
- remove unecessary malloc and free
This commit is contained in:
"Vladimir N. Oleynik" 2005-09-05 15:06:57 +00:00
parent 27421a1878
commit a8c23aa795

View File

@ -83,15 +83,15 @@ enum {
/* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */ /* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */
/* what file information will be listed */ /* what file information will be listed */
#define LIST_INO (1U<<0) #define LIST_INO (1U<<0)
#define LIST_BLOCKS (1U<<1) #define LIST_BLOCKS (1U<<1)
#define LIST_MODEBITS (1U<<2) #define LIST_MODEBITS (1U<<2)
#define LIST_NLINKS (1U<<3) #define LIST_NLINKS (1U<<3)
#define LIST_ID_NAME (1U<<4) #define LIST_ID_NAME (1U<<4)
#define LIST_ID_NUMERIC (1U<<5) #define LIST_ID_NUMERIC (1U<<5)
#define LIST_CONTEXT (1U<<6) #define LIST_CONTEXT (1U<<6)
#define LIST_SIZE (1U<<7) #define LIST_SIZE (1U<<7)
#define LIST_DEV (1U<<8) #define LIST_DEV (1U<<8)
#define LIST_DATE_TIME (1U<<9) #define LIST_DATE_TIME (1U<<9)
#define LIST_FULLTIME (1U<<10) #define LIST_FULLTIME (1U<<10)
#define LIST_FILENAME (1U<<11) #define LIST_FILENAME (1U<<11)
@ -103,22 +103,22 @@ enum {
/* what files will be displayed */ /* what files will be displayed */
/* TODO -- We may be able to make DISP_NORMAL 0 to save a bit slot. */ /* TODO -- We may be able to make DISP_NORMAL 0 to save a bit slot. */
#define DISP_NORMAL (1U<<14) /* show normal filenames */ #define DISP_NORMAL (1U<<14) /* show normal filenames */
#define DISP_DIRNAME (1U<<15) /* 2 or more items? label directories */ #define DISP_DIRNAME (1U<<15) /* 2 or more items? label directories */
#define DISP_HIDDEN (1U<<16) /* show filenames starting with . */ #define DISP_HIDDEN (1U<<16) /* show filenames starting with . */
#define DISP_DOT (1U<<17) /* show . and .. */ #define DISP_DOT (1U<<17) /* show . and .. */
#define DISP_NOLIST (1U<<18) /* show directory as itself, not contents */ #define DISP_NOLIST (1U<<18) /* show directory as itself, not contents */
#define DISP_RECURSIVE (1U<<19) /* show directory and everything below it */ #define DISP_RECURSIVE (1U<<19) /* show directory and everything below it */
#define DISP_ROWS (1U<<20) /* print across rows */ #define DISP_ROWS (1U<<20) /* print across rows */
#define DISP_MASK (((DISP_ROWS << 1) - 1) & ~(DISP_NORMAL - 1)) #define DISP_MASK (((DISP_ROWS << 1) - 1) & ~(DISP_NORMAL - 1))
#ifdef CONFIG_FEATURE_LS_SORTFILES #ifdef CONFIG_FEATURE_LS_SORTFILES
/* how will the files be sorted */ /* how will the files be sorted */
#define SORT_ORDER_FORWARD 0 /* sort in reverse order */ #define SORT_ORDER_FORWARD 0 /* sort in reverse order */
#define SORT_ORDER_REVERSE (1U<<27) /* sort in reverse order */ #define SORT_ORDER_REVERSE (1U<<27) /* sort in reverse order */
#define SORT_NAME 0 /* sort by file name */ #define SORT_NAME 0 /* sort by file name */
#define SORT_SIZE (1U<<28) /* sort by file size */ #define SORT_SIZE (1U<<28) /* sort by file size */
#define SORT_ATIME (2U<<28) /* sort by last access time */ #define SORT_ATIME (2U<<28) /* sort by last access time */
#define SORT_CTIME (3U<<28) /* sort by last change time */ #define SORT_CTIME (3U<<28) /* sort by last change time */
@ -170,25 +170,25 @@ static int show_color = 0;
/* long option entry used only for --color, which has no short option /* long option entry used only for --color, which has no short option
* equivalent. */ * equivalent. */
static int got_color_opt;
static struct option ls_color_opt[] = static struct option ls_color_opt[] =
{ {
{"color", optional_argument, &got_color_opt, 1}, {"color", optional_argument, NULL, 1},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
#define COLOR(mode) ("\000\043\043\043\042\000\043\043"\ #define COLOR(mode) ("\000\043\043\043\042\000\043\043"\
"\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)]) "\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)])
#define ATTR(mode) ("\00\00\01\00\01\00\01\00"\ #define ATTR(mode) ("\00\00\01\00\01\00\01\00"\
"\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)]) "\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)])
#endif #endif
/* /*
* a directory entry and its stat info are stored here * a directory entry and its stat info are stored here
*/ */
struct dnode { /* the basic node */ struct dnode { /* the basic node */
char *name; /* the dir entry name */ char *name; /* the dir entry name */
char *fullname; /* the dir entry name */ char *fullname; /* the dir entry name */
int allocated;
struct stat dstat; /* the file stat info */ struct stat dstat; /* the file stat info */
#ifdef CONFIG_SELINUX #ifdef CONFIG_SELINUX
security_context_t sid; security_context_t sid;
@ -235,8 +235,7 @@ static struct dnode *my_stat(char *fullname, char *name)
} }
#endif #endif
rc = stat(fullname, &dstat); rc = stat(fullname, &dstat);
if(rc) if(rc) {
{
bb_perror_msg("%s", fullname); bb_perror_msg("%s", fullname);
status = EXIT_FAILURE; status = EXIT_FAILURE;
return 0; return 0;
@ -251,8 +250,7 @@ static struct dnode *my_stat(char *fullname, char *name)
} }
#endif #endif
rc = lstat(fullname, &dstat); rc = lstat(fullname, &dstat);
if(rc) if(rc) {
{
bb_perror_msg("%s", fullname); bb_perror_msg("%s", fullname);
status = EXIT_FAILURE; status = EXIT_FAILURE;
return 0; return 0;
@ -320,11 +318,10 @@ static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs)
dirs = 0; dirs = 0;
for (i = 0; i < nfiles; i++) { for (i = 0; i < nfiles; i++) {
if (S_ISDIR(dn[i]->dstat.st_mode) if (S_ISDIR(dn[i]->dstat.st_mode)
&& (notsubdirs && (notsubdirs ||
|| ((dn[i]->name[0] != '.') ((dn[i]->name[0] != '.') || (dn[i]->name[1]
|| (dn[i]->name[1]
&& ((dn[i]->name[1] != '.') && ((dn[i]->name[1] != '.')
|| dn[i]->name[2]))))) || dn[i]->name[2])))))
dirs++; dirs++;
} }
return (dirs); return (dirs);
@ -352,8 +349,7 @@ static struct dnode **dnalloc(int num)
if (num < 1) if (num < 1)
return (NULL); return (NULL);
p = (struct dnode **) xcalloc((size_t) num, p = (struct dnode **) xcalloc((size_t) num, (size_t) (sizeof(struct dnode *)));
(size_t) (sizeof(struct dnode *)));
return (p); return (p);
} }
@ -367,7 +363,8 @@ static void dfree(struct dnode **dnp)
cur = dnp[0]; cur = dnp[0];
while (cur != NULL) { while (cur != NULL) {
free(cur->fullname); /* free the filename */ if(cur->allocated)
free(cur->fullname); /* free the filename */
next = cur->next; next = cur->next;
free(cur); /* free the dnode */ free(cur); /* free the dnode */
cur = next; cur = next;
@ -622,6 +619,7 @@ static struct dnode **list_dir(const char *path)
cur = my_stat(fullname, strrchr(fullname, '/') + 1); cur = my_stat(fullname, strrchr(fullname, '/') + 1);
if (!cur) if (!cur)
continue; continue;
cur->allocated = 1;
cur->next = dn; cur->next = dn;
dn = cur; dn = cur;
nfiles++; nfiles++;
@ -756,7 +754,7 @@ static int list_single(struct dnode *dn)
safe_strncpy(context, dn->sid, len); safe_strncpy(context, dn->sid, len);
freecon(dn->sid); freecon(dn->sid);
}else { }else {
safe_strncpy(context, "unknown",8); safe_strncpy(context, "unknown", 8);
} }
printf("%-32s ", context); printf("%-32s ", context);
column += MAX(33, len); column += MAX(33, len);
@ -951,6 +949,9 @@ static const unsigned opt_flags[] = {
#endif #endif
#ifdef CONFIG_SELINUX #ifdef CONFIG_SELINUX
LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */ LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */
#endif
#ifdef CONFIG_FEATURE_AUTOWIDTH
0, 0, /* T, w - ignored */
#endif #endif
(1U<<31) (1U<<31)
}; };
@ -977,6 +978,9 @@ extern int ls_main(int argc, char **argv)
char *tabstops_str = NULL; char *tabstops_str = NULL;
char *terminal_width_str = NULL; char *terminal_width_str = NULL;
#endif #endif
#ifdef CONFIG_FEATURE_LS_COLOR
char *color_opt;
#endif
all_fmt = LIST_SHORT | DISP_NORMAL | STYLE_AUTO all_fmt = LIST_SHORT | DISP_NORMAL | STYLE_AUTO
#ifdef CONFIG_FEATURE_LS_TIMESTAMPS #ifdef CONFIG_FEATURE_LS_TIMESTAMPS
@ -1000,7 +1004,11 @@ extern int ls_main(int argc, char **argv)
/* process options */ /* process options */
#ifdef CONFIG_FEATURE_AUTOWIDTH #ifdef CONFIG_FEATURE_AUTOWIDTH
opt = bb_getopt_ulflags(argc, argv, ls_options, &tabstops_str, &terminal_width_str); opt = bb_getopt_ulflags(argc, argv, ls_options, &tabstops_str, &terminal_width_str
#ifdef CONFIG_FEATURE_LS_COLOR
, &color_opt
#endif
);
if (tabstops_str) { if (tabstops_str) {
tabstops = atoi(tabstops_str); tabstops = atoi(tabstops_str);
} }
@ -1008,11 +1016,16 @@ extern int ls_main(int argc, char **argv)
terminal_width = atoi(terminal_width_str); terminal_width = atoi(terminal_width_str);
} }
#else #else
opt = bb_getopt_ulflags(argc, argv, ls_options); opt = bb_getopt_ulflags(argc, argv, ls_options
#ifdef CONFIG_FEATURE_LS_COLOR
, &color_opt
#endif
);
#endif #endif
for (i = 0; opt_flags[i] != (1U<<31); i++) { for (i = 0; opt_flags[i] != (1U<<31); i++) {
if (opt & (1 << i)) { if (opt & (1 << i)) {
unsigned int flags = opt_flags[i]; unsigned int flags = opt_flags[i];
if (flags & LIST_MASK_TRIGGER) { if (flags & LIST_MASK_TRIGGER) {
all_fmt &= ~LIST_MASK; all_fmt &= ~LIST_MASK;
} }
@ -1045,51 +1058,28 @@ extern int ls_main(int argc, char **argv)
} }
#ifdef CONFIG_FEATURE_LS_COLOR #ifdef CONFIG_FEATURE_LS_COLOR
if (got_color_opt) { {
/* there is no way for bb_getopt_ulflags() to /* find color bit value - last position for short getopt */
* return us the argument string for long options
* which don't have a short option equivalent.
* all we can find out is that the option was
* present, and we have to rescan to find the
* argument string.
*/
got_color_opt=0;
optind = 1;
while ((i = getopt_long (argc, argv, ls_options,
ls_color_opt, NULL)) >= 0) {
if (i != 0) continue;
if (got_color_opt) {
if (!optarg || strcmp("always", optarg) == 0)
show_color = 1;
else if (strcmp("never", optarg) == 0)
show_color = 0;
else if (strcmp("auto", optarg) == 0 &&
isatty(STDOUT_FILENO))
show_color = 1;
/* don't break; want to a) pick up repeated
* --color options, and b) leave optind
* set correctly when we're done.
*/
got_color_opt = 0;
}
}
#if CONFIG_FEATURE_LS_COLOR_IS_DEFAULT #if CONFIG_FEATURE_LS_COLOR_IS_DEFAULT
} else {
/* if no option set by user, then this config option
* forces "auto", which is what busybox 1.00 and previous
* did. however, provide one more "out" for users that
* don't want color: if LS_COLOR is set, and is null or
* "none" -- then default coloring to "off".
*/
char *p; char *p;
if ((p = getenv ("LS_COLORS")) != NULL && if ((p = getenv ("LS_COLORS")) != NULL &&
(*p == '\0' || (strcmp(p, "none") == 0))) { (*p == '\0' || (strcmp(p, "none") == 0))) {
show_color = 0; ;
} else if (isatty(STDOUT_FILENO)) { } else if (isatty(STDOUT_FILENO)) {
show_color = 1; show_color = 1;
} }
#endif #endif
if((opt & (1 << i))) { /* next flag after short options */
if (color_opt == NULL || strcmp("always", color_opt) == 0)
show_color = 1;
else if (color_opt != NULL && strcmp("never", color_opt) == 0)
show_color = 0;
else if (color_opt != NULL && strcmp("auto", color_opt) == 0 && isatty(STDOUT_FILENO))
show_color = 1;
}
} }
#endif #endif
@ -1129,14 +1119,12 @@ extern int ls_main(int argc, char **argv)
*/ */
ac = argc - optind; /* how many cmd line args are left */ ac = argc - optind; /* how many cmd line args are left */
if (ac < 1) { if (ac < 1) {
av = (char **) xcalloc((size_t) 1, (size_t) (sizeof(char *))); static const char * const dotdir[] = { "." };
av[0] = bb_xstrdup(".");
av = (char **) dotdir;
ac = 1; ac = 1;
} else { } else {
av = (char **) xcalloc((size_t) ac, (size_t) (sizeof(char *))); av = argv + optind;
for (oi = 0; oi < ac; oi++) {
av[oi] = argv[optind++]; /* copy pointer to real cmd line arg */
}
} }
/* now, everything is in the av array */ /* now, everything is in the av array */
@ -1146,11 +1134,10 @@ extern int ls_main(int argc, char **argv)
/* stuff the command line file names into an dnode array */ /* stuff the command line file names into an dnode array */
dn = NULL; dn = NULL;
for (oi = 0; oi < ac; oi++) { for (oi = 0; oi < ac; oi++) {
char *fullname = bb_xstrdup(av[oi]); cur = my_stat(av[oi], av[oi]);
cur = my_stat(fullname, fullname);
if (!cur) if (!cur)
continue; continue;
cur->allocated = 0;
cur->next = dn; cur->next = dn;
dn = cur; dn = cur;
nfiles++; nfiles++;