/*----------------------------------------------------------------------*/ static void showdirs(struct dnode **dn, int ndirs) { //printf("=== ls showdirs\n"); int i, nfiles; struct dnode **subdnp; #ifdef CONFIG_FEATURE_LS_RECURSIVE int dndirs; struct dnode **dnd; #endif if (dn == NULL || ndirs < 1) return; for (i = 0; i < ndirs; i++) { if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { printf("\n%s:\n", dn[i]->fullname); } subdnp = list_dir(dn[i]->fullname); nfiles = countfiles(subdnp); if (nfiles > 0) { /* list all files at this level */ #ifdef CONFIG_FEATURE_LS_SORTFILES shellsort(subdnp, nfiles); #endif showfiles(subdnp, nfiles); #ifdef CONFIG_FEATURE_LS_RECURSIVE if (all_fmt & DISP_RECURSIVE) { /* recursive- list the sub-dirs */ dnd = splitdnarray(subdnp, nfiles, SPLIT_SUBDIR); dndirs = countsubdirs(subdnp, nfiles); if (dndirs > 0) { #ifdef CONFIG_FEATURE_LS_SORTFILES shellsort(dnd, dndirs); #endif showdirs(dnd, dndirs); free(dnd); /* free the array of dnode pointers to the dirs */ } } dfree(subdnp); /* free the dnodes and the fullname mem */ #endif } } }
/*----------------------------------------------------------------------*/ extern int ls_main(int argc, char **argv) { struct dnode **dnf, **dnd; int dnfiles, dndirs; struct dnode *dn, *cur, **dnp; int i, nfiles; int opt; int oi, ac; char **av; #ifdef BB_FEATURE_AUTOWIDTH struct winsize win = { 0, 0, 0, 0 }; #endif disp_opts= DISP_NORMAL; style_fmt= STYLE_AUTO; list_fmt= LIST_SHORT; #ifdef BB_FEATURE_LS_SORTFILES sort_opts= SORT_NAME; sort_order= SORT_FORWARD; #endif #ifdef BB_FEATURE_LS_TIMESTAMPS time_fmt= TIME_MOD; #endif #ifdef BB_FEATURE_AUTOWIDTH ioctl(fileno(stdout), TIOCGWINSZ, &win); if (win.ws_row > 4) column_width = win.ws_row - 2; if (win.ws_col > 0) terminal_width = win.ws_col - 1; #endif nfiles=0; /* process options */ while ((opt = getopt(argc, argv, "1AaCdgilnsx" #ifdef BB_FEATURE_AUTOWIDTH "T:w:" #endif #ifdef BB_FEATURE_LS_FILETYPES "Fp" #endif #ifdef BB_FEATURE_LS_RECURSIVE "R" #endif #ifdef BB_FEATURE_LS_SORTFILES "rSvX" #endif #ifdef BB_FEATURE_LS_TIMESTAMPS "cetu" #endif #ifdef BB_FEATURE_LS_FOLLOWLINKS "L" #endif #ifdef BB_FEATURE_HUMAN_READABLE "h" #endif "k")) > 0) { switch (opt) { case '1': style_fmt = STYLE_SINGLE; break; case 'A': disp_opts |= DISP_HIDDEN; break; case 'a': disp_opts |= DISP_HIDDEN | DISP_DOT; break; case 'C': style_fmt = STYLE_COLUMNS; break; case 'd': disp_opts |= DISP_NOLIST; break; case 'g': /* ignore -- for ftp servers */ break; case 'i': list_fmt |= LIST_INO; break; case 'l': style_fmt = STYLE_LONG; list_fmt |= LIST_LONG; #ifdef BB_FEATURE_HUMAN_READABLE ls_disp_hr = FALSE; #endif break; case 'n': list_fmt |= LIST_ID_NUMERIC; break; case 's': list_fmt |= LIST_BLOCKS; break; case 'x': disp_opts = DISP_ROWS; break; #ifdef BB_FEATURE_LS_FILETYPES case 'F': list_fmt |= LIST_FILETYPE | LIST_EXEC; break; case 'p': list_fmt |= LIST_FILETYPE; break; #endif #ifdef BB_FEATURE_LS_RECURSIVE case 'R': disp_opts |= DISP_RECURSIVE; break; #endif #ifdef BB_FEATURE_LS_SORTFILES case 'r': sort_order |= SORT_REVERSE; break; case 'S': sort_opts= SORT_SIZE; break; case 'v': sort_opts= SORT_VERSION; break; case 'X': sort_opts= SORT_EXT; break; #endif #ifdef BB_FEATURE_LS_TIMESTAMPS case 'e': list_fmt |= LIST_FULLTIME; break; case 'c': time_fmt = TIME_CHANGE; #ifdef BB_FEATURE_LS_SORTFILES sort_opts= SORT_CTIME; #endif break; case 'u': time_fmt = TIME_ACCESS; #ifdef BB_FEATURE_LS_SORTFILES sort_opts= SORT_ATIME; #endif break; case 't': #ifdef BB_FEATURE_LS_SORTFILES sort_opts= SORT_MTIME; #endif break; #endif #ifdef BB_FEATURE_LS_FOLLOWLINKS case 'L': follow_links= TRUE; break; #endif #ifdef BB_FEATURE_AUTOWIDTH case 'T': tabstops= atoi(optarg); break; case 'w': terminal_width= atoi(optarg); break; #endif #ifdef BB_FEATURE_HUMAN_READABLE case 'h': ls_disp_hr = TRUE; break; #endif case 'k': break; default: goto print_usage_message; } } /* sort out which command line options take precedence */ #ifdef BB_FEATURE_LS_RECURSIVE if (disp_opts & DISP_NOLIST) disp_opts &= ~DISP_RECURSIVE; /* no recurse if listing only dir */ #endif #if defined (BB_FEATURE_LS_TIMESTAMPS) && defined (BB_FEATURE_LS_SORTFILES) if (time_fmt & TIME_CHANGE) sort_opts= SORT_CTIME; if (time_fmt & TIME_ACCESS) sort_opts= SORT_ATIME; #endif if (style_fmt != STYLE_LONG) list_fmt &= ~LIST_ID_NUMERIC; /* numeric uid only for long list */ #ifdef BB_FEATURE_LS_USERNAME if (style_fmt == STYLE_LONG && (list_fmt & LIST_ID_NUMERIC)) list_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */ #endif /* choose a display format */ if (style_fmt == STYLE_AUTO) style_fmt = isatty(fileno(stdout)) ? STYLE_COLUMNS : STYLE_SINGLE; /* * when there are no cmd line args we have to supply a default "." arg. * we will create a second argv array, "av" that will hold either * our created "." arg, or the real cmd line args. The av array * just holds the pointers- we don't move the date the pointers * point to. */ ac= argc - optind; /* how many cmd line args are left */ if (ac < 1) { av= (char **)xcalloc((size_t)1, (size_t)(sizeof(char *))); av[0]= "."; ac=1; } else { av= (char **)xcalloc((size_t)ac, (size_t)(sizeof(char *))); for (oi=0 ; oi < ac; oi++) { av[oi]= argv[optind++]; /* copy pointer to real cmd line arg */ } } /* now, everything is in the av array */ if (ac > 1) disp_opts |= DISP_DIRNAME; /* 2 or more items? label directories */ /* stuff the command line file names into an dnode array */ dn=NULL; for (oi=0 ; oi < ac; oi++) { cur= (struct dnode *)xmalloc(sizeof(struct dnode)); cur->fullname= xstrdup(av[oi]); cur->name= cur->fullname; if (my_stat(cur)) continue; cur->next= dn; dn= cur; nfiles++; } /* now that we know how many files there are ** allocate memory for an array to hold dnode pointers */ dnp= dnalloc(nfiles); for (i=0, cur=dn; i<nfiles; i++) { dnp[i]= cur; /* save pointer to node in array */ cur= cur->next; } if (disp_opts & DISP_NOLIST) { #ifdef BB_FEATURE_LS_SORTFILES shellsort(dnp, nfiles); #endif if (nfiles > 0) showfiles(dnp, nfiles); } else { dnd= splitdnarray(dnp, nfiles, SPLIT_DIR); dnf= splitdnarray(dnp, nfiles, SPLIT_FILE); dndirs= countdirs(dnp, nfiles); dnfiles= nfiles - dndirs; if (dnfiles > 0) { #ifdef BB_FEATURE_LS_SORTFILES shellsort(dnf, dnfiles); #endif showfiles(dnf, dnfiles); } if (dndirs > 0) { #ifdef BB_FEATURE_LS_SORTFILES shellsort(dnd, dndirs); #endif showdirs(dnd, dndirs); } if (dnd) free(dnd); if (dnf) free(dnf); } free(av); if (dnp) dfree(dnp, nfiles); return(status); print_usage_message: show_usage(); }
extern int ls_main(int argc, char **argv) { struct dnode **dnd; struct dnode **dnf; struct dnode **dnp; struct dnode *dn; struct dnode *cur; long opt; int nfiles = 0; int dnfiles; int dndirs; int oi; int ac; int i; char **av; #ifdef CONFIG_FEATURE_AUTOWIDTH char *tabstops_str = NULL; char *terminal_width_str = NULL; #endif #ifdef CONFIG_SELINUX is_flask_enabled_flag = is_flask_enabled(); #endif all_fmt = LIST_SHORT | DISP_NORMAL | STYLE_AUTO #ifdef CONFIG_FEATURE_LS_TIMESTAMPS | TIME_MOD #endif #ifdef CONFIG_FEATURE_LS_SORTFILES | SORT_NAME | SORT_ORDER_FORWARD #endif ; #ifdef CONFIG_FEATURE_AUTOWIDTH /* Obtain the terminal width. */ get_terminal_width_height(0, &terminal_width, NULL); /* Go one less... */ terminal_width--; #endif #ifdef CONFIG_FEATURE_LS_COLOR if (isatty(fileno(stdout))) show_color = 1; #endif /* process options */ #ifdef CONFIG_FEATURE_AUTOWIDTH opt = bb_getopt_ulflags(argc, argv, ls_options, &tabstops_str, &terminal_width_str); if (tabstops_str) { tabstops = atoi(tabstops_str); } if (terminal_width_str) { terminal_width = atoi(terminal_width_str); } #else opt = bb_getopt_ulflags(argc, argv, ls_options); #endif /* 16 = maximum options minus tabsize and screewn width */ for (i = 0; i < 16; i++) { if (opt & (1 << i)) { unsigned int flags = opt_flags[i]; if (flags & LIST_MASK_TRIGGER) { all_fmt &= ~LIST_MASK; } if (flags & STYLE_MASK_TRIGGER) { all_fmt &= ~STYLE_MASK; } #ifdef CONFIG_FEATURE_LS_SORTFILES if (flags & SORT_MASK_TRIGGER) { all_fmt &= ~SORT_MASK; } #endif if (flags & DISP_MASK_TRIGGER) { all_fmt &= ~DISP_MASK; } #ifdef CONFIG_FEATURE_LS_TIMESTAMPS if (flags & TIME_MASK_TRIGGER) { all_fmt &= ~TIME_MASK; } #endif if (flags & LIST_CONTEXT) { all_fmt |= STYLE_SINGLE; } #ifdef CONFIG_FEATURE_HUMAN_READABLE if (opt == 'l') { all_fmt &= ~LS_DISP_HR; } #endif all_fmt |= flags; } } /* sort out which command line options take precedence */ #ifdef CONFIG_FEATURE_LS_RECURSIVE if (all_fmt & DISP_NOLIST) all_fmt &= ~DISP_RECURSIVE; /* no recurse if listing only dir */ #endif #if defined (CONFIG_FEATURE_LS_TIMESTAMPS) && defined (CONFIG_FEATURE_LS_SORTFILES) if (all_fmt & TIME_CHANGE) all_fmt = (all_fmt & ~SORT_MASK) | SORT_CTIME; if (all_fmt & TIME_ACCESS) all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME; #endif if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */ all_fmt &= ~(LIST_ID_NUMERIC|LIST_FULLTIME|LIST_ID_NAME|LIST_ID_NUMERIC); #ifdef CONFIG_FEATURE_LS_USERNAME if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC)) all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */ #endif /* choose a display format */ if ((all_fmt & STYLE_MASK) == STYLE_AUTO) #if STYLE_AUTO != 0 all_fmt = (all_fmt & ~STYLE_MASK) | (isatty(fileno(stdout)) ? STYLE_COLUMNS : STYLE_SINGLE); #else all_fmt |= (isatty(fileno(stdout)) ? STYLE_COLUMNS : STYLE_SINGLE); #endif /* * when there are no cmd line args we have to supply a default "." arg. * we will create a second argv array, "av" that will hold either * our created "." arg, or the real cmd line args. The av array * just holds the pointers- we don't move the date the pointers * point to. */ ac = argc - optind; /* how many cmd line args are left */ if (ac < 1) { av = (char **) xcalloc((size_t) 1, (size_t) (sizeof(char *))); av[0] = bb_xstrdup("."); ac = 1; } else { av = (char **) xcalloc((size_t) ac, (size_t) (sizeof(char *))); for (oi = 0; oi < ac; oi++) { av[oi] = argv[optind++]; /* copy pointer to real cmd line arg */ } } /* now, everything is in the av array */ if (ac > 1) all_fmt |= DISP_DIRNAME; /* 2 or more items? label directories */ /* stuff the command line file names into an dnode array */ dn = NULL; for (oi = 0; oi < ac; oi++) { char *fullname = bb_xstrdup(av[oi]); cur = my_stat(fullname, fullname); if (!cur) continue; cur->next = dn; dn = cur; nfiles++; } /* now that we know how many files there are ** allocate memory for an array to hold dnode pointers */ dnp = dnalloc(nfiles); for (i = 0, cur = dn; i < nfiles; i++) { dnp[i] = cur; /* save pointer to node in array */ cur = cur->next; } if (all_fmt & DISP_NOLIST) { #ifdef CONFIG_FEATURE_LS_SORTFILES shellsort(dnp, nfiles); #endif if (nfiles > 0) showfiles(dnp, nfiles); } else { dnd = splitdnarray(dnp, nfiles, SPLIT_DIR); dnf = splitdnarray(dnp, nfiles, SPLIT_FILE); dndirs = countdirs(dnp, nfiles); dnfiles = nfiles - dndirs; if (dnfiles > 0) { #ifdef CONFIG_FEATURE_LS_SORTFILES shellsort(dnf, dnfiles); #endif showfiles(dnf, dnfiles); } if (dndirs > 0) { #ifdef CONFIG_FEATURE_LS_SORTFILES shellsort(dnd, dndirs); #endif showdirs(dnd, dndirs); } } return (status); }