X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=ls.c;h=77de93a0c37a7d2bb03afdc01a34283bcea1fc31;hb=14e9e9d1cab3ef5ed9910fadb5a327b5982c2049;hp=d508a1bfe5ea8040836de69fb661956923e2614b;hpb=cf1189f5a709ed52f862775af63dbf75b8124ccd;p=oweals%2Fbusybox.git diff --git a/ls.c b/ls.c index d508a1bfe..77de93a0c 100644 --- a/ls.c +++ b/ls.c @@ -41,13 +41,15 @@ * 1. requires lstat (BSD) - how do you do it without? */ -#define TERMINAL_WIDTH 80 /* use 79 if your terminal has linefold bug */ -#define COLUMN_WIDTH 14 /* default if AUTOWIDTH not defined */ -#define COLUMN_GAP 2 /* includes the file type char, if present */ +enum { + TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */ + COLUMN_WIDTH = 14, /* default if AUTOWIDTH not defined */ + COLUMN_GAP = 2, /* includes the file type char */ +}; + /************************************************************************/ -#include "busybox.h" #include #include #include @@ -55,21 +57,29 @@ #include #include #include +#include +#include +#include +#include +#include +#include "busybox.h" + #ifdef BB_FEATURE_LS_TIMESTAMPS #include #endif -#include -#ifndef NAJOR +#ifndef MAJOR #define MAJOR(dev) (((dev)>>8)&0xff) #define MINOR(dev) ((dev)&0xff) #endif /* what is the overall style of the listing */ -#define STYLE_AUTO 0 -#define STYLE_LONG 1 /* one record per line, extended info */ -#define STYLE_SINGLE 2 /* one record per line */ -#define STYLE_COLUMNS 3 /* fill columns */ +enum { +STYLE_AUTO = 0, +STYLE_LONG = 1, /* one record per line, extended info */ +STYLE_SINGLE = 2, /* one record per line */ +STYLE_COLUMNS = 3 /* fill columns */ +}; /* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */ /* what file information will be listed */ @@ -99,23 +109,23 @@ #ifdef BB_FEATURE_LS_SORTFILES /* how will the files be sorted */ -#define SORT_FORWARD 0 /* sort in reverse order */ -#define SORT_REVERSE 1 /* sort in reverse order */ -#define SORT_NAME 2 /* sort by file name */ -#define SORT_SIZE 3 /* sort by file size */ -#define SORT_ATIME 4 /* sort by last access time */ -#define SORT_CTIME 5 /* sort by last change time */ -#define SORT_MTIME 6 /* sort by last modification time */ -#define SORT_VERSION 7 /* sort by version */ -#define SORT_EXT 8 /* sort by file name extension */ -#define SORT_DIR 9 /* sort by file or directory */ +static const int SORT_FORWARD = 0; /* sort in reverse order */ +static const int SORT_REVERSE = 1; /* sort in reverse order */ +static const int SORT_NAME = 2; /* sort by file name */ +static const int SORT_SIZE = 3; /* sort by file size */ +static const int SORT_ATIME = 4; /* sort by last access time */ +static const int SORT_CTIME = 5; /* sort by last change time */ +static const int SORT_MTIME = 6; /* sort by last modification time */ +static const int SORT_VERSION = 7; /* sort by version */ +static const int SORT_EXT = 8; /* sort by file name extension */ +static const int SORT_DIR = 9; /* sort by file or directory */ #endif #ifdef BB_FEATURE_LS_TIMESTAMPS /* which of the three times will be used */ -#define TIME_MOD 0 -#define TIME_CHANGE 1 -#define TIME_ACCESS 2 +static const int TIME_MOD = 0; +static const int TIME_CHANGE = 1; +static const int TIME_ACCESS = 2; #endif #define LIST_SHORT (LIST_FILENAME) @@ -125,9 +135,9 @@ LIST_SYMLINK) #define LIST_ILONG (LIST_INO | LIST_LONG) -#define SPLIT_DIR 0 -#define SPLIT_FILE 1 -#define SPLIT_SUBDIR 2 +static const int SPLIT_DIR = 0; +static const int SPLIT_FILE = 1; +static const int SPLIT_SUBDIR = 2; #define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) #define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) @@ -146,19 +156,19 @@ struct dnode { /* the basic node */ }; typedef struct dnode dnode_t; -struct dnode **list_dir(char *); -struct dnode **dnalloc(int); -int list_single(struct dnode *); +static struct dnode **list_dir(char *); +static struct dnode **dnalloc(int); +static int list_single(struct dnode *); -static unsigned int disp_opts= DISP_NORMAL; -static unsigned int style_fmt= STYLE_AUTO ; -static unsigned int list_fmt= LIST_SHORT ; +static unsigned int disp_opts; +static unsigned int style_fmt; +static unsigned int list_fmt; #ifdef BB_FEATURE_LS_SORTFILES -static unsigned int sort_opts= SORT_FORWARD; -static unsigned int sort_order= SORT_FORWARD; +static unsigned int sort_opts; +static unsigned int sort_order; #endif #ifdef BB_FEATURE_LS_TIMESTAMPS -static unsigned int time_fmt= TIME_MOD; +static unsigned int time_fmt; #endif #ifdef BB_FEATURE_LS_FOLLOWLINKS static unsigned int follow_links=FALSE; @@ -168,20 +178,23 @@ static unsigned short column = 0; #ifdef BB_FEATURE_AUTOWIDTH static unsigned short terminal_width = TERMINAL_WIDTH; static unsigned short column_width = COLUMN_WIDTH; -static unsigned short tabstops = 8; +static unsigned short tabstops = COLUMN_GAP; #else -#define terminal_width TERMINAL_WIDTH -#define column_width COLUMN_WIDTH +static unsigned short column_width = COLUMN_WIDTH; #endif static int status = EXIT_SUCCESS; +#ifdef BB_FEATURE_HUMAN_READABLE +static unsigned long ls_disp_hr = 0; +#endif + static int my_stat(struct dnode *cur) { #ifdef BB_FEATURE_LS_FOLLOWLINKS if (follow_links == TRUE) { if (stat(cur->fullname, &cur->dstat)) { - errorMsg("%s: %s\n", cur->fullname, strerror(errno)); + perror_msg("%s", cur->fullname); status = EXIT_FAILURE; free(cur->fullname); free(cur); @@ -190,7 +203,7 @@ static int my_stat(struct dnode *cur) } else #endif if (lstat(cur->fullname, &cur->dstat)) { - errorMsg("%s: %s\n", cur->fullname, strerror(errno)); + perror_msg("%s", cur->fullname); status = EXIT_FAILURE; free(cur->fullname); free(cur); @@ -202,7 +215,7 @@ static int my_stat(struct dnode *cur) static void newline(void) { if (column > 0) { - fprintf(stdout, "\n"); + putchar('\n'); column = 0; } } @@ -229,11 +242,11 @@ static void nexttabstop( void ) n= nexttab - column; if (n < 1) n= 1; while (n--) { - fprintf(stdout, " "); + putchar(' '); column++; } } - nexttab= column + column_width + COLUMN_GAP ; + nexttab= column + column_width + COLUMN_GAP; } /*----------------------------------------------------------------------*/ @@ -243,7 +256,7 @@ static int is_subdir(struct dnode *dn) strcmp(dn->name, "..") != 0); } -int countdirs(struct dnode **dn, int nfiles) +static int countdirs(struct dnode **dn, int nfiles) { int i, dirs; @@ -255,7 +268,7 @@ int countdirs(struct dnode **dn, int nfiles) return(dirs); } -int countsubdirs(struct dnode **dn, int nfiles) +static int countsubdirs(struct dnode **dn, int nfiles) { int i, subdirs; @@ -267,7 +280,7 @@ int countsubdirs(struct dnode **dn, int nfiles) return subdirs; } -int countfiles(struct dnode **dnp) +static int countfiles(struct dnode **dnp) { int nfiles; struct dnode *cur; @@ -280,7 +293,7 @@ int countfiles(struct dnode **dnp) } /* get memory to hold an array of pointers */ -struct dnode **dnalloc(int num) +static struct dnode **dnalloc(int num) { struct dnode **p; @@ -290,7 +303,7 @@ struct dnode **dnalloc(int num) return(p); } -void dfree(struct dnode **dnp) +static void dfree(struct dnode **dnp) { struct dnode *cur, *next; @@ -306,7 +319,7 @@ void dfree(struct dnode **dnp) free(dnp); /* free the array holding the dnode pointers */ } -struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which) +static struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which) { int dncnt, i, d; struct dnode **dnp; @@ -346,7 +359,7 @@ struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which) /*----------------------------------------------------------------------*/ #ifdef BB_FEATURE_LS_SORTFILES -int sortcmp(struct dnode *d1, struct dnode *d2) +static int sortcmp(struct dnode *d1, struct dnode *d2) { int cmp, dif; @@ -383,7 +396,7 @@ int sortcmp(struct dnode *d1, struct dnode *d2) } /*----------------------------------------------------------------------*/ -void shellsort(struct dnode **dn, int size) +static void shellsort(struct dnode **dn, int size) { struct dnode *temp; int gap, i, j; @@ -407,7 +420,7 @@ void shellsort(struct dnode **dn, int size) #endif /*----------------------------------------------------------------------*/ -void showfiles(struct dnode **dn, int nfiles) +static void showfiles(struct dnode **dn, int nfiles) { int i, ncols, nrows, row, nc; #ifdef BB_FEATURE_AUTOWIDTH @@ -424,10 +437,18 @@ void showfiles(struct dnode **dn, int nfiles) ((list_fmt & LIST_INO) ? 8 : 0) + ((list_fmt & LIST_BLOCKS) ? 5 : 0) ; - if (column_width < len) column_width= len; + if (column_width < len) + column_width= len; } + if (column_width >= 6) + ncols = (int)(terminal_width / (column_width + COLUMN_GAP)); + else { + ncols = 1; + column_width = COLUMN_WIDTH; + } +#else + ncols= TERMINAL_WIDTH; #endif - ncols= (int)(terminal_width / (column_width + COLUMN_GAP)); switch (style_fmt) { case STYLE_LONG: /* one record per line, extended info */ case STYLE_SINGLE: /* one record per line */ @@ -435,7 +456,12 @@ void showfiles(struct dnode **dn, int nfiles) break; } - nrows= nfiles / ncols; + if (ncols > 1) { + nrows = nfiles / ncols; + } else { + nrows = nfiles; + ncols = 1; + } if ((nrows * ncols) < nfiles) nrows++; /* round up fractionals */ if (nrows > nfiles) nrows= nfiles; @@ -455,7 +481,7 @@ void showfiles(struct dnode **dn, int nfiles) } /*----------------------------------------------------------------------*/ -void showdirs(struct dnode **dn, int ndirs) +static void showdirs(struct dnode **dn, int ndirs) { int i, nfiles; struct dnode **subdnp; @@ -468,7 +494,7 @@ void showdirs(struct dnode **dn, int ndirs) for (i=0; ifullname); + printf("\n%s:\n", dn[i]->fullname); } subdnp= list_dir(dn[i]->fullname); nfiles= countfiles(subdnp); @@ -498,7 +524,7 @@ void showdirs(struct dnode **dn, int ndirs) } /*----------------------------------------------------------------------*/ -struct dnode **list_dir(char *path) +static struct dnode **list_dir(char *path) { struct dnode *dn, *cur, **dnp; struct dirent *entry; @@ -511,7 +537,7 @@ struct dnode **list_dir(char *path) nfiles= 0; dir = opendir(path); if (dir == NULL) { - errorMsg("%s: %s\n", path, strerror(errno)); + perror_msg("%s", path); status = EXIT_FAILURE; return(NULL); /* could not open the dir */ } @@ -549,7 +575,7 @@ struct dnode **list_dir(char *path) } /*----------------------------------------------------------------------*/ -int list_single(struct dnode *dn) +static int list_single(struct dnode *dn) { int i, len; char scratch[BUFSIZ + 1]; @@ -579,55 +605,57 @@ int list_single(struct dnode *dn) for (i=0; i<=31; i++) { switch (list_fmt & (1<dstat.st_ino); + printf("%7ld ", dn->dstat.st_ino); column += 8; break; case LIST_BLOCKS: +#ifdef BB_FEATURE_HUMAN_READABLE + fprintf(stdout, "%5s ", make_human_readable_str(dn->dstat.st_blocks>>1, + (ls_disp_hr==TRUE)? 0: 1)); +#else #if _FILE_OFFSET_BITS == 64 - fprintf(stdout, "%4lld ", dn->dstat.st_blocks>>1); + printf("%4lld ", dn->dstat.st_blocks>>1); #else - fprintf(stdout, "%4ld ", dn->dstat.st_blocks>>1); + printf("%4ld ", dn->dstat.st_blocks>>1); +#endif #endif column += 5; break; case LIST_MODEBITS: - fprintf(stdout, "%10s", (char *)modeString(dn->dstat.st_mode)); + printf("%10s", (char *)mode_string(dn->dstat.st_mode)); column += 10; break; case LIST_NLINKS: - fprintf(stdout, "%4d ", dn->dstat.st_nlink); + printf("%4d ", dn->dstat.st_nlink); column += 10; break; case LIST_ID_NAME: #ifdef BB_FEATURE_LS_USERNAME - memset(scratch, 0, sizeof(scratch)); my_getpwuid(scratch, dn->dstat.st_uid); - if (*scratch) - fprintf(stdout, "%-8.8s ", scratch); - else - fprintf(stdout, "%-8d ", dn->dstat.st_uid); - memset(scratch, 0, sizeof(scratch)); + printf("%-8.8s ", scratch); my_getgrgid(scratch, dn->dstat.st_gid); - if (*scratch) - fprintf(stdout, "%-8.8s", scratch); - else - fprintf(stdout, "%-8d", dn->dstat.st_gid); + printf("%-8.8s", scratch); column += 17; break; #endif case LIST_ID_NUMERIC: - fprintf(stdout, "%-8d %-8d", dn->dstat.st_uid, dn->dstat.st_gid); + printf("%-8d %-8d", dn->dstat.st_uid, dn->dstat.st_gid); column += 17; break; case LIST_SIZE: case LIST_DEV: if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) { - fprintf(stdout, "%4d, %3d ", (int)MAJOR(dn->dstat.st_rdev), (int)MINOR(dn->dstat.st_rdev)); + printf("%4d, %3d ", (int)MAJOR(dn->dstat.st_rdev), (int)MINOR(dn->dstat.st_rdev)); } else { +#ifdef BB_FEATURE_HUMAN_READABLE + fprintf(stdout, "%9s ", make_human_readable_str(dn->dstat.st_size, + (ls_disp_hr==TRUE)? 0: 1)); +#else #if _FILE_OFFSET_BITS == 64 - fprintf(stdout, "%9lld ", dn->dstat.st_size); + printf("%9lld ", dn->dstat.st_size>>1); #else - fprintf(stdout, "%9ld ", dn->dstat.st_size); + printf("%9ld ", dn->dstat.st_size>>1); +#endif #endif } column += 10; @@ -636,23 +664,23 @@ int list_single(struct dnode *dn) case LIST_FULLTIME: case LIST_DATE_TIME: if (list_fmt & LIST_FULLTIME) { - fprintf(stdout, "%24.24s ", filetime); + printf("%24.24s ", filetime); column += 25; break; } age = time(NULL) - ttime; - fprintf(stdout, "%6.6s ", filetime+4); + printf("%6.6s ", filetime+4); if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) { /* hh:mm if less than 6 months old */ - fprintf(stdout, "%5.5s ", filetime+11); + printf("%5.5s ", filetime+11); } else { - fprintf(stdout, " %4.4s ", filetime+20); + printf(" %4.4s ", filetime+20); } column += 13; break; #endif case LIST_FILENAME: - fprintf(stdout, "%s", dn->name); + printf("%s", dn->name); column += strlen(dn->name); break; case LIST_SYMLINK: @@ -660,7 +688,7 @@ int list_single(struct dnode *dn) len= readlink(dn->fullname, scratch, (sizeof scratch)-1); if (len > 0) { scratch[len]= '\0'; - fprintf(stdout, " -> %s", scratch); + printf(" -> %s", scratch); #ifdef BB_FEATURE_LS_FILETYPES if (!stat(dn->fullname, &info)) { append = append_char(info.st_mode); @@ -673,7 +701,7 @@ int list_single(struct dnode *dn) #ifdef BB_FEATURE_LS_FILETYPES case LIST_FILETYPE: if (append != '\0') { - fprintf(stdout, "%1c", append); + printf("%1c", append); column++; } break; @@ -694,15 +722,26 @@ extern int ls_main(int argc, char **argv) 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; @@ -726,7 +765,10 @@ extern int ls_main(int argc, char **argv) #ifdef BB_FEATURE_LS_FOLLOWLINKS "L" #endif - )) > 0) { +#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; @@ -735,7 +777,13 @@ extern int ls_main(int argc, char **argv) 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; 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; @@ -779,6 +827,10 @@ extern int ls_main(int argc, char **argv) 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; } @@ -873,10 +925,8 @@ extern int ls_main(int argc, char **argv) showdirs(dnd, dndirs); } } - return(status); print_usage_message: - usage(ls_usage); - return(FALSE); + show_usage(); }