Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/coreutils/ls.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/coreutils/ls.c
r821 r1770 30 30 */ 31 31 32 #include <getopt.h> 33 #include "libbb.h" 34 35 /* This is a NOEXEC applet. Be very careful! */ 36 37 32 38 enum { 33 TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */ 34 COLUMN_GAP = 2, /* includes the file type char */ 35 }; 36 37 /************************************************************************/ 38 39 #include "busybox.h" 40 #include <unistd.h> 41 #include <errno.h> 42 #include <string.h> 43 #include <fcntl.h> 44 #include <signal.h> 45 #include <getopt.h> /* struct option */ 46 #include <sys/ioctl.h> 47 #include <sys/sysmacros.h> /* major() and minor() */ 48 #include <time.h> 39 40 TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */ 41 COLUMN_GAP = 2, /* includes the file type char */ 49 42 50 43 /* what is the overall style of the listing */ 51 #define STYLE_COLUMNS (1U<<21) /* fill columns */ 52 #define STYLE_LONG (2U<<21) /* one record per line, extended info */ 53 #define STYLE_SINGLE (3U<<21) /* one record per line */ 54 55 #define STYLE_MASK STYLE_SINGLE 56 #define STYLE_ONE_RECORD_FLAG STYLE_LONG 44 STYLE_COLUMNS = 1 << 21, /* fill columns */ 45 STYLE_LONG = 2 << 21, /* one record per line, extended info */ 46 STYLE_SINGLE = 3 << 21, /* one record per line */ 47 STYLE_MASK = STYLE_SINGLE, 57 48 58 49 /* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */ 59 50 /* what file information will be listed */ 60 #define LIST_INO (1U<<0) 61 #define LIST_BLOCKS (1U<<1) 62 #define LIST_MODEBITS (1U<<2) 63 #define LIST_NLINKS (1U<<3) 64 #define LIST_ID_NAME (1U<<4) 65 #define LIST_ID_NUMERIC (1U<<5) 66 #define LIST_CONTEXT (1U<<6) 67 #define LIST_SIZE (1U<<7) 68 #define LIST_DEV (1U<<8) 69 #define LIST_DATE_TIME (1U<<9) 70 #define LIST_FULLTIME (1U<<10) 71 #define LIST_FILENAME (1U<<11) 72 #define LIST_SYMLINK (1U<<12) 73 #define LIST_FILETYPE (1U<<13) 74 #define LIST_EXEC (1U<<14) 75 76 #define LIST_MASK ((LIST_EXEC << 1) - 1) 51 LIST_INO = 1 << 0, 52 LIST_BLOCKS = 1 << 1, 53 LIST_MODEBITS = 1 << 2, 54 LIST_NLINKS = 1 << 3, 55 LIST_ID_NAME = 1 << 4, 56 LIST_ID_NUMERIC = 1 << 5, 57 LIST_CONTEXT = 1 << 6, 58 LIST_SIZE = 1 << 7, 59 LIST_DEV = 1 << 8, 60 LIST_DATE_TIME = 1 << 9, 61 LIST_FULLTIME = 1 << 10, 62 LIST_FILENAME = 1 << 11, 63 LIST_SYMLINK = 1 << 12, 64 LIST_FILETYPE = 1 << 13, 65 LIST_EXEC = 1 << 14, 66 LIST_MASK = (LIST_EXEC << 1) - 1, 77 67 78 68 /* what files will be displayed */ 79 #define DISP_DIRNAME (1U<<15) /* 2 or more items? label directories */ 80 #define DISP_HIDDEN (1U<<16) /* show filenames starting with . */ 81 #define DISP_DOT (1U<<17) /* show . and .. */ 82 #define DISP_NOLIST (1U<<18) /* show directory as itself, not contents */ 83 #define DISP_RECURSIVE (1U<<19) /* show directory and everything below it */ 84 #define DISP_ROWS (1U<<20) /* print across rows */ 85 86 #define DISP_MASK (((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1)) 87 88 // CONFIG_FEATURE_LS_SORTFILES 89 /* how will the files be sorted */ 90 #define SORT_ORDER_FORWARD 0 /* sort in reverse order */ 91 #define SORT_ORDER_REVERSE (1U<<27) /* sort in reverse order */ 92 93 #define SORT_NAME 0 /* sort by file name */ 94 #define SORT_SIZE (1U<<28) /* sort by file size */ 95 #define SORT_ATIME (2U<<28) /* sort by last access time */ 96 #define SORT_CTIME (3U<<28) /* sort by last change time */ 97 #define SORT_MTIME (4U<<28) /* sort by last modification time */ 98 #define SORT_VERSION (5U<<28) /* sort by version */ 99 #define SORT_EXT (6U<<28) /* sort by file name extension */ 100 #define SORT_DIR (7U<<28) /* sort by file or directory */ 101 102 #define SORT_MASK (7U<<28) 69 DISP_DIRNAME = 1 << 15, /* 2 or more items? label directories */ 70 DISP_HIDDEN = 1 << 16, /* show filenames starting with . */ 71 DISP_DOT = 1 << 17, /* show . and .. */ 72 DISP_NOLIST = 1 << 18, /* show directory as itself, not contents */ 73 DISP_RECURSIVE = 1 << 19, /* show directory and everything below it */ 74 DISP_ROWS = 1 << 20, /* print across rows */ 75 DISP_MASK = ((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1), 76 77 /* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */ 78 SORT_FORWARD = 0, /* sort in reverse order */ 79 SORT_REVERSE = 1 << 27, /* sort in reverse order */ 80 81 SORT_NAME = 0, /* sort by file name */ 82 SORT_SIZE = 1 << 28, /* sort by file size */ 83 SORT_ATIME = 2 << 28, /* sort by last access time */ 84 SORT_CTIME = 3 << 28, /* sort by last change time */ 85 SORT_MTIME = 4 << 28, /* sort by last modification time */ 86 SORT_VERSION = 5 << 28, /* sort by version */ 87 SORT_EXT = 6 << 28, /* sort by file name extension */ 88 SORT_DIR = 7 << 28, /* sort by file or directory */ 89 SORT_MASK = (7 << 28) * ENABLE_FEATURE_LS_SORTFILES, 103 90 104 91 /* which of the three times will be used */ 105 #define TIME_CHANGE ((1U<<23) * ENABLE_FEATURE_LS_TIMESTAMPS) 106 #define TIME_ACCESS ((1U<<24) * ENABLE_FEATURE_LS_TIMESTAMPS) 107 #define TIME_MASK ((3U<<23) * ENABLE_FEATURE_LS_TIMESTAMPS) 108 109 #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS 110 #define FOLLOW_LINKS (1U<<25) 111 #endif 112 #ifdef CONFIG_FEATURE_HUMAN_READABLE 113 #define LS_DISP_HR (1U<<26) 114 #endif 115 116 #define LIST_SHORT (LIST_FILENAME) 117 #define LIST_ISHORT (LIST_INO | LIST_FILENAME) 118 #define LIST_LONG (LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ 119 LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK) 120 #define LIST_ILONG (LIST_INO | LIST_LONG) 121 122 #define SPLIT_DIR 1 123 #define SPLIT_FILE 0 124 #define SPLIT_SUBDIR 2 92 TIME_CHANGE = (1 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS, 93 TIME_ACCESS = (1 << 24) * ENABLE_FEATURE_LS_TIMESTAMPS, 94 TIME_MASK = (3 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS, 95 96 FOLLOW_LINKS = (1 << 25) * ENABLE_FEATURE_LS_FOLLOWLINKS, 97 98 LS_DISP_HR = (1 << 26) * ENABLE_FEATURE_HUMAN_READABLE, 99 100 LIST_SHORT = LIST_FILENAME, 101 LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ 102 LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK, 103 104 SPLIT_DIR = 1, 105 SPLIT_FILE = 0, 106 SPLIT_SUBDIR = 2, 107 108 }; 125 109 126 110 #define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) 127 111 #define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) 128 129 #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined(CONFIG_FEATURE_LS_COLOR) 130 # define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)]) 131 #endif 132 133 /* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */ 134 #ifdef CONFIG_FEATURE_LS_COLOR 135 136 static int show_color = 0; 137 138 /* long option entry used only for --color, which has no short option 139 * equivalent. */ 140 static const struct option ls_color_opt[] = 141 { 142 {"color", optional_argument, NULL, 1}, 143 {NULL, 0, NULL, 0} 144 }; 145 112 #define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)]) 146 113 #define COLOR(mode) ("\000\043\043\043\042\000\043\043"\ 147 114 "\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)]) 148 115 #define ATTR(mode) ("\00\00\01\00\01\00\01\00"\ 149 116 "\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)]) 117 118 /* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */ 119 #if ENABLE_FEATURE_LS_COLOR 120 static smallint show_color; 121 /* long option entry used only for --color, which has no short option 122 * equivalent */ 123 static const char ls_color_opt[] ALIGN1 = 124 "color\0" Optional_argument "\xff" /* no short equivalent */ 125 ; 126 #else 127 enum { show_color = 0 }; 150 128 #endif 151 129 … … 153 131 * a directory entry and its stat info are stored here 154 132 */ 155 struct dnode { 156 c har *name;/* the dir entry name */157 c har *fullname;/* the dir entry name */133 struct dnode { /* the basic node */ 134 const char *name; /* the dir entry name */ 135 const char *fullname; /* the dir entry name */ 158 136 int allocated; 159 struct stat dstat; /* the file stat info */ 160 #ifdef CONFIG_SELINUX 161 security_context_t sid; 162 #endif 163 struct dnode *next; /* point at the next node */ 137 struct stat dstat; /* the file stat info */ 138 USE_SELINUX(security_context_t sid;) 139 struct dnode *next; /* point at the next node */ 164 140 }; 165 141 typedef struct dnode dnode_t; … … 169 145 static int list_single(struct dnode *); 170 146 171 static unsigned intall_fmt;172 173 #if def CONFIG_FEATURE_AUTOWIDTH174 static int terminal_width = TERMINAL_WIDTH;175 static unsigned short tabstops = COLUMN_GAP;147 static unsigned all_fmt; 148 149 #if ENABLE_FEATURE_AUTOWIDTH 150 static unsigned tabstops = COLUMN_GAP; 151 static unsigned terminal_width = TERMINAL_WIDTH; 176 152 #else 177 #define tabstops COLUMN_GAP 178 #define terminal_width TERMINAL_WIDTH 153 enum { 154 tabstops = COLUMN_GAP, 155 terminal_width = TERMINAL_WIDTH, 156 }; 179 157 #endif 180 158 181 159 static int status = EXIT_SUCCESS; 182 160 183 static struct dnode *my_stat(c har *fullname, char *name)161 static struct dnode *my_stat(const char *fullname, const char *name, int force_follow) 184 162 { 185 163 struct stat dstat; 186 164 struct dnode *cur; 187 #ifdef CONFIG_SELINUX 188 security_context_t sid=NULL; 189 #endif 190 191 #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS 192 if (all_fmt & FOLLOW_LINKS) { 193 #ifdef CONFIG_SELINUX 165 USE_SELINUX(security_context_t sid = NULL;) 166 167 if ((all_fmt & FOLLOW_LINKS) || force_follow) { 168 #if ENABLE_SELINUX 194 169 if (is_selinux_enabled()) { 195 getfilecon(fullname, &sid);170 getfilecon(fullname, &sid); 196 171 } 197 172 #endif … … 201 176 return 0; 202 177 } 203 } else 204 #endif 205 { 206 #ifdef CONFIG_SELINUX 207 if (is_selinux_enabled()) { 208 lgetfilecon(fullname,&sid); 178 } else { 179 #if ENABLE_SELINUX 180 if (is_selinux_enabled()) { 181 lgetfilecon(fullname, &sid); 209 182 } 210 183 #endif … … 216 189 } 217 190 218 cur = (struct dnode *)xmalloc(sizeof(struct dnode));191 cur = xmalloc(sizeof(struct dnode)); 219 192 cur->fullname = fullname; 220 193 cur->name = name; 221 194 cur->dstat = dstat; 222 #ifdef CONFIG_SELINUX 223 cur->sid = sid; 224 #endif 195 USE_SELINUX(cur->sid = sid;) 225 196 return cur; 226 197 } 227 198 228 /*----------------------------------------------------------------------*/ 229 #ifdef CONFIG_FEATURE_LS_COLOR 199 #if ENABLE_FEATURE_LS_COLOR 230 200 static char fgcolor(mode_t mode) 231 201 { 232 202 /* Check wheter the file is existing (if so, color it red!) */ 233 if (errno == ENOENT) {203 if (errno == ENOENT) 234 204 return '\037'; 235 }236 205 if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) 237 206 return COLOR(0xF000); /* File is executable ... */ … … 239 208 } 240 209 241 /*----------------------------------------------------------------------*/242 210 static char bgcolor(mode_t mode) 243 211 { … … 248 216 #endif 249 217 250 /*----------------------------------------------------------------------*/ 251 #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined(CONFIG_FEATURE_LS_COLOR) 218 #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR 252 219 static char append_char(mode_t mode) 253 220 { … … 264 231 #endif 265 232 266 /*----------------------------------------------------------------------*/ 267 268 #define countdirs(A,B) count_dirs((A), (B), 1) 269 #define countsubdirs(A,B) count_dirs((A), (B), 0) 270 233 #define countdirs(A, B) count_dirs((A), (B), 1) 234 #define countsubdirs(A, B) count_dirs((A), (B), 0) 271 235 static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs) 272 236 { 273 237 int i, dirs; 274 238 275 if ( dn == NULL || nfiles < 1)276 return (0);239 if (!dn) 240 return 0; 277 241 dirs = 0; 278 242 for (i = 0; i < nfiles; i++) { 279 if (S_ISDIR(dn[i]->dstat.st_mode) 280 && (notsubdirs || 281 ((dn[i]->name[0] != '.') || (dn[i]->name[1] 282 && ((dn[i]->name[1] != '.') 283 || dn[i]->name[2]))))) 243 const char *name; 244 if (!S_ISDIR(dn[i]->dstat.st_mode)) 245 continue; 246 name = dn[i]->name; 247 if (notsubdirs 248 || name[0]!='.' || (name[1] && (name[1]!='.' || name[2])) 249 ) { 284 250 dirs++; 285 } 286 return (dirs); 251 } 252 } 253 return dirs; 287 254 } 288 255 … … 293 260 294 261 if (dnp == NULL) 295 return (0);262 return 0; 296 263 nfiles = 0; 297 for (cur = dnp[0]; cur->next != NULL; cur = cur->next)264 for (cur = dnp[0]; cur->next; cur = cur->next) 298 265 nfiles++; 299 266 nfiles++; 300 return (nfiles);267 return nfiles; 301 268 } 302 269 … … 304 271 static struct dnode **dnalloc(int num) 305 272 { 306 struct dnode **p;307 308 273 if (num < 1) 309 return (NULL); 310 311 p = (struct dnode **) xcalloc((size_t) num, (size_t) (sizeof(struct dnode *))); 312 return (p); 313 } 314 315 #ifdef CONFIG_FEATURE_LS_RECURSIVE 274 return NULL; 275 276 return xzalloc(num * sizeof(struct dnode *)); 277 } 278 279 #if ENABLE_FEATURE_LS_RECURSIVE 316 280 static void dfree(struct dnode **dnp, int nfiles) 317 281 { … … 323 287 for (i = 0; i < nfiles; i++) { 324 288 struct dnode *cur = dnp[i]; 325 if (cur->allocated)326 free( cur->fullname); /* free the filename */289 if (cur->allocated) 290 free((char*)cur->fullname); /* free the filename */ 327 291 free(cur); /* free the dnode */ 328 292 } … … 330 294 } 331 295 #else 332 #define dfree(...) 296 #define dfree(...) ((void)0) 333 297 #endif 334 298 … … 339 303 340 304 if (dn == NULL || nfiles < 1) 341 return (NULL);305 return NULL; 342 306 343 307 /* count how many dirs and regular files there are */ … … 356 320 for (d = i = 0; i < nfiles; i++) { 357 321 if (S_ISDIR(dn[i]->dstat.st_mode)) { 358 if (which & (SPLIT_DIR|SPLIT_SUBDIR)) {359 if ((which & SPLIT_DIR)360 || ((dn[i]->name[0] != '.')361 || (dn[i]->name[1]362 && ((dn[i]->name[1] != '.')363 || dn[i]->name[2])))) {364 dnp[d++] = dn[i];365 }322 const char *name; 323 if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) 324 continue; 325 name = dn[i]->name; 326 if ((which & SPLIT_DIR) 327 || name[0]!='.' || (name[1] && (name[1]!='.' || name[2])) 328 ) { 329 dnp[d++] = dn[i]; 366 330 } 367 331 } else if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) { … … 369 333 } 370 334 } 371 return (dnp); 372 } 373 374 /*----------------------------------------------------------------------*/ 375 #ifdef CONFIG_FEATURE_LS_SORTFILES 335 return dnp; 336 } 337 338 #if ENABLE_FEATURE_LS_SORTFILES 376 339 static int sortcmp(const void *a, const void *b) 377 340 { 378 341 struct dnode *d1 = *(struct dnode **)a; 379 342 struct dnode *d2 = *(struct dnode **)b; 380 unsigned intsort_opts = all_fmt & SORT_MASK;343 unsigned sort_opts = all_fmt & SORT_MASK; 381 344 int dif; 382 345 383 dif = 0; /* assume SORT_NAME */ 346 dif = 0; /* assume SORT_NAME */ 347 // TODO: use pre-initialized function pointer 348 // instead of branch forest 384 349 if (sort_opts == SORT_SIZE) { 385 350 dif = (int) (d2->dstat.st_size - d1->dstat.st_size); … … 397 362 398 363 if (dif == 0) { 399 /* sort by name - may be a tie_breaker for time or size cmp */364 /* sort by name - may be a tie_breaker for time or size cmp */ 400 365 if (ENABLE_LOCALE_SUPPORT) dif = strcoll(d1->name, d2->name); 401 366 else dif = strcmp(d1->name, d2->name); 402 367 } 403 368 404 if (all_fmt & SORT_ ORDER_REVERSE) {369 if (all_fmt & SORT_REVERSE) { 405 370 dif = -dif; 406 371 } 407 return (dif); 408 } 409 410 /*----------------------------------------------------------------------*/ 372 return dif; 373 } 374 411 375 static void dnsort(struct dnode **dn, int size) 412 376 { 413 qsort(dn, size, sizeof *dn, sortcmp);377 qsort(dn, size, sizeof(*dn), sortcmp); 414 378 } 415 379 #else 416 #define sortcmp(a, b) 0 417 #define dnsort(dn, size) 418 #endif 419 420 421 /*----------------------------------------------------------------------*/ 380 #define dnsort(dn, size) ((void)0) 381 #endif 382 383 422 384 static void showfiles(struct dnode **dn, int nfiles) 423 385 { … … 430 392 return; 431 393 432 if (all_fmt & STYLE_ ONE_RECORD_FLAG) {394 if (all_fmt & STYLE_LONG) { 433 395 ncols = 1; 434 396 } else { 435 /* find the longest file name -use that as the column width */397 /* find the longest file name, use that as the column width */ 436 398 for (i = 0; i < nfiles; i++) { 437 int len = strlen(dn[i]->name) + 438 #ifdef CONFIG_SELINUX 439 ((all_fmt & LIST_CONTEXT) ? 33 : 0) + 440 #endif 441 ((all_fmt & LIST_INO) ? 8 : 0) + 442 ((all_fmt & LIST_BLOCKS) ? 5 : 0); 399 int len = strlen(dn[i]->name); 443 400 if (column_width < len) 444 401 column_width = len; 445 402 } 446 column_width += tabstops; 403 column_width += tabstops + 404 USE_SELINUX( ((all_fmt & LIST_CONTEXT) ? 33 : 0) + ) 405 ((all_fmt & LIST_INO) ? 8 : 0) + 406 ((all_fmt & LIST_BLOCKS) ? 5 : 0); 447 407 ncols = (int) (terminal_width / column_width); 448 408 } … … 450 410 if (ncols > 1) { 451 411 nrows = nfiles / ncols; 452 if ( (nrows * ncols)< nfiles)412 if (nrows * ncols < nfiles) 453 413 nrows++; /* round up fractionals */ 454 414 } else { … … 466 426 if (column > 0) { 467 427 nexttab -= column; 468 while (nexttab--) { 469 putchar(' '); 470 column++; 471 } 472 } 428 printf("%*s", nexttab, ""); 429 column += nexttab; 430 } 473 431 nexttab = column + column_width; 474 432 column += list_single(dn[i]); 475 }433 } 476 434 } 477 435 putchar('\n'); … … 480 438 } 481 439 482 /*----------------------------------------------------------------------*/ 440 483 441 static void showdirs(struct dnode **dn, int ndirs, int first) 484 442 { … … 494 452 if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { 495 453 if (!first) 496 p rintf("\n");454 puts(""); 497 455 first = 0; 498 456 printf("%s:\n", dn[i]->fullname); … … 502 460 if (nfiles > 0) { 503 461 /* list all files at this level */ 504 if (ENABLE_FEATURE_LS_SORTFILES)dnsort(subdnp, nfiles);462 dnsort(subdnp, nfiles); 505 463 showfiles(subdnp, nfiles); 506 464 if (ENABLE_FEATURE_LS_RECURSIVE) { … … 510 468 dndirs = countsubdirs(subdnp, nfiles); 511 469 if (dndirs > 0) { 512 if (ENABLE_FEATURE_LS_SORTFILES)dnsort(dnd, dndirs);470 dnsort(dnd, dndirs); 513 471 showdirs(dnd, dndirs, 0); 514 472 /* free the array of dnode pointers to the dirs */ … … 523 481 } 524 482 525 /*----------------------------------------------------------------------*/ 483 526 484 static struct dnode **list_dir(const char *path) 527 485 { … … 532 490 533 491 if (path == NULL) 534 return (NULL);492 return NULL; 535 493 536 494 dn = NULL; 537 495 nfiles = 0; 538 dir = bb_opendir(path);496 dir = warn_opendir(path); 539 497 if (dir == NULL) { 540 498 status = EXIT_FAILURE; 541 return (NULL); /* could not open the dir */499 return NULL; /* could not open the dir */ 542 500 } 543 501 while ((entry = readdir(dir)) != NULL) { … … 546 504 /* are we going to list the file- it may be . or .. or a hidden file */ 547 505 if (entry->d_name[0] == '.') { 548 if ((entry->d_name[1] == 0 || ( 549 entry->d_name[1] == '.' 550 && entry->d_name[2] == 0)) 551 && !(all_fmt & DISP_DOT)) 506 if ((!entry->d_name[1] || (entry->d_name[1] == '.' && !entry->d_name[2])) 507 && !(all_fmt & DISP_DOT) 508 ) { 509 continue; 510 } 511 if (!(all_fmt & DISP_HIDDEN)) 512 continue; 513 } 514 fullname = concat_path_file(path, entry->d_name); 515 cur = my_stat(fullname, bb_basename(fullname), 0); 516 if (!cur) { 517 free(fullname); 552 518 continue; 553 if (!(all_fmt & DISP_HIDDEN)) 554 continue; 555 } 556 fullname = concat_path_file(path, entry->d_name); 557 cur = my_stat(fullname, strrchr(fullname, '/') + 1); 558 if (!cur) 559 continue; 519 } 560 520 cur->allocated = 1; 561 521 cur->next = dn; … … 566 526 567 527 /* now that we know how many files there are 568 ** allocate memory for an array to hold dnode pointers528 * allocate memory for an array to hold dnode pointers 569 529 */ 570 530 if (dn == NULL) 571 return (NULL);531 return NULL; 572 532 dnp = dnalloc(nfiles); 573 533 for (i = 0, cur = dn; i < nfiles; i++) { … … 576 536 } 577 537 578 return (dnp); 579 } 580 581 /*----------------------------------------------------------------------*/ 538 return dnp; 539 } 540 541 542 #if ENABLE_FEATURE_LS_TIMESTAMPS 543 /* Do time() just once. Saves one syscall per file for "ls -l" */ 544 /* Initialized in main() */ 545 static time_t current_time_t; 546 #endif 547 582 548 static int list_single(struct dnode *dn) 583 549 { 584 550 int i, column = 0; 585 551 586 #ifdef CONFIG_FEATURE_LS_USERNAME 587 char scratch[16]; 588 #endif 589 #ifdef CONFIG_FEATURE_LS_TIMESTAMPS 552 #if ENABLE_FEATURE_LS_TIMESTAMPS 590 553 char *filetime; 591 554 time_t ttime, age; 592 555 #endif 593 #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined (CONFIG_FEATURE_LS_COLOR)556 #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR 594 557 struct stat info; 595 558 char append; … … 597 560 598 561 if (dn->fullname == NULL) 599 return (0);600 601 #if def CONFIG_FEATURE_LS_TIMESTAMPS562 return 0; 563 564 #if ENABLE_FEATURE_LS_TIMESTAMPS 602 565 ttime = dn->dstat.st_mtime; /* the default time */ 603 566 if (all_fmt & TIME_ACCESS) … … 607 570 filetime = ctime(&ttime); 608 571 #endif 609 #if def CONFIG_FEATURE_LS_FILETYPES572 #if ENABLE_FEATURE_LS_FILETYPES 610 573 append = append_char(dn->dstat.st_mode); 611 574 #endif … … 614 577 switch (all_fmt & (1 << i)) { 615 578 case LIST_INO: 616 column += printf("%7ld ", (long int) dn->dstat.st_ino);579 column += printf("%7ld ", (long) dn->dstat.st_ino); 617 580 break; 618 581 case LIST_BLOCKS: 619 #if _FILE_OFFSET_BITS == 64 620 column += printf("%4lld ", (long long)dn->dstat.st_blocks >> 1); 621 #else 622 column += printf("%4ld ", dn->dstat.st_blocks >> 1); 623 #endif 582 column += printf("%4"OFF_FMT"d ", (off_t) dn->dstat.st_blocks >> 1); 624 583 break; 625 584 case LIST_MODEBITS: … … 630 589 break; 631 590 case LIST_ID_NAME: 632 #ifdef CONFIG_FEATURE_LS_USERNAME 633 bb_getpwuid(scratch, dn->dstat.st_uid, sizeof(scratch)); 634 printf("%-8.8s ", scratch); 635 bb_getgrgid(scratch, dn->dstat.st_gid, sizeof(scratch)); 636 printf("%-8.8s", scratch); 591 #if ENABLE_FEATURE_LS_USERNAME 592 printf("%-8.8s %-8.8s", 593 get_cached_username(dn->dstat.st_uid), 594 get_cached_groupname(dn->dstat.st_gid)); 637 595 column += 17; 638 596 break; … … 647 605 (int) minor(dn->dstat.st_rdev)); 648 606 } else { 649 #ifdef CONFIG_FEATURE_HUMAN_READABLE650 607 if (all_fmt & LS_DISP_HR) { 651 608 column += printf("%9s ", 652 make_human_readable_str(dn->dstat.st_size, 1, 0)); 653 } else 654 #endif 655 { 656 #if _FILE_OFFSET_BITS == 64 657 column += printf("%9lld ", (long long) dn->dstat.st_size); 658 #else 659 column += printf("%9ld ", dn->dstat.st_size); 660 #endif 609 make_human_readable_str(dn->dstat.st_size, 1, 0)); 610 } else { 611 column += printf("%9"OFF_FMT"d ", (off_t) dn->dstat.st_size); 661 612 } 662 613 } 663 614 break; 664 #if def CONFIG_FEATURE_LS_TIMESTAMPS615 #if ENABLE_FEATURE_LS_TIMESTAMPS 665 616 case LIST_FULLTIME: 666 617 printf("%24.24s ", filetime); … … 669 620 case LIST_DATE_TIME: 670 621 if ((all_fmt & LIST_FULLTIME) == 0) { 671 age = time(NULL) - ttime; 622 /* current_time_t ~== time(NULL) */ 623 age = current_time_t - ttime; 672 624 printf("%6.6s ", filetime + 4); 673 625 if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) { … … 681 633 break; 682 634 #endif 683 #if def CONFIG_SELINUX635 #if ENABLE_SELINUX 684 636 case LIST_CONTEXT: 685 637 { … … 688 640 689 641 if (dn->sid) { 690 /* I assume sid initilized with NULL*/691 len = strlen(dn->sid)+1;692 693 694 } else {695 642 /* I assume sid initilized with NULL */ 643 len = strlen(dn->sid) + 1; 644 safe_strncpy(context, dn->sid, len); 645 freecon(dn->sid); 646 } else { 647 safe_strncpy(context, "unknown", 8); 696 648 } 697 649 printf("%-32s ", context); … … 701 653 #endif 702 654 case LIST_FILENAME: 703 #ifdef CONFIG_FEATURE_LS_COLOR704 655 errno = 0; 656 #if ENABLE_FEATURE_LS_COLOR 705 657 if (show_color && !lstat(dn->fullname, &info)) { 706 658 printf("\033[%d;%dm", bgcolor(info.st_mode), 707 659 fgcolor(info.st_mode)); 708 660 } 709 661 #endif 710 662 column += printf("%s", dn->name); 711 #ifdef CONFIG_FEATURE_LS_COLOR712 663 if (show_color) { 713 664 printf("\033[0m"); 714 665 } 715 #endif716 666 break; 717 667 case LIST_SYMLINK: 718 668 if (S_ISLNK(dn->dstat.st_mode)) { 719 char *lpath = xreadlink(dn->fullname); 720 721 if (lpath) { 722 printf(" -> "); 723 #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined (CONFIG_FEATURE_LS_COLOR) 724 if (!stat(dn->fullname, &info)) { 725 append = append_char(info.st_mode); 726 } 727 #endif 728 #ifdef CONFIG_FEATURE_LS_COLOR 729 if (show_color) { 730 errno = 0; 731 printf("\033[%d;%dm", bgcolor(info.st_mode), 732 fgcolor(info.st_mode)); 733 } 734 #endif 735 column += printf("%s", lpath) + 4; 736 #ifdef CONFIG_FEATURE_LS_COLOR 737 if (show_color) { 738 printf("\033[0m"); 739 } 740 #endif 741 free(lpath); 669 char *lpath = xmalloc_readlink_or_warn(dn->fullname); 670 if (!lpath) break; 671 printf(" -> "); 672 #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR 673 if (!stat(dn->fullname, &info)) { 674 append = append_char(info.st_mode); 742 675 } 743 } 744 break; 745 #ifdef CONFIG_FEATURE_LS_FILETYPES 676 #endif 677 #if ENABLE_FEATURE_LS_COLOR 678 if (show_color) { 679 errno = 0; 680 printf("\033[%d;%dm", bgcolor(info.st_mode), 681 fgcolor(info.st_mode)); 682 } 683 #endif 684 column += printf("%s", lpath) + 4; 685 if (show_color) { 686 printf("\033[0m"); 687 } 688 free(lpath); 689 } 690 break; 691 #if ENABLE_FEATURE_LS_FILETYPES 746 692 case LIST_FILETYPE: 747 if (append != '\0') {748 p rintf("%1c",append);693 if (append) { 694 putchar(append); 749 695 column++; 750 696 } … … 756 702 return column; 757 703 } 758 759 /*----------------------------------------------------------------------*/760 704 761 705 /* "[-]Cadil1", POSIX mandated options, busybox always supports */ … … 767 711 /* "[-]K", SELinux mandated options, busybox optionally supports */ 768 712 /* "[-]e", I think we made this one up */ 769 770 #ifdef CONFIG_FEATURE_LS_TIMESTAMPS 771 # define LS_STR_TIMESTAMPS "cetu" 772 #else 773 # define LS_STR_TIMESTAMPS "" 774 #endif 775 776 #ifdef CONFIG_FEATURE_LS_FILETYPES 777 # define LS_STR_FILETYPES "Fp" 778 #else 779 # define LS_STR_FILETYPES "" 780 #endif 781 782 #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS 783 # define LS_STR_FOLLOW_LINKS "L" 784 #else 785 # define LS_STR_FOLLOW_LINKS "" 786 #endif 787 788 #ifdef CONFIG_FEATURE_LS_RECURSIVE 789 # define LS_STR_RECURSIVE "R" 790 #else 791 # define LS_STR_RECURSIVE "" 792 #endif 793 794 #ifdef CONFIG_FEATURE_HUMAN_READABLE 795 # define LS_STR_HUMAN_READABLE "h" 796 #else 797 # define LS_STR_HUMAN_READABLE "" 798 #endif 799 800 #ifdef CONFIG_SELINUX 801 # define LS_STR_SELINUX "K" 802 #else 803 # define LS_STR_SELINUX "" 804 #endif 805 806 #ifdef CONFIG_FEATURE_AUTOWIDTH 807 # define LS_STR_AUTOWIDTH "T:w:" 808 #else 809 # define LS_STR_AUTOWIDTH "" 810 #endif 811 812 static const char ls_options[]="Cadil1gnsxAk" \ 813 LS_STR_TIMESTAMPS \ 814 USE_FEATURE_LS_SORTFILES("SXrv") \ 815 LS_STR_FILETYPES \ 816 LS_STR_FOLLOW_LINKS \ 817 LS_STR_RECURSIVE \ 818 LS_STR_HUMAN_READABLE \ 819 LS_STR_SELINUX \ 820 LS_STR_AUTOWIDTH; 821 822 #define LIST_MASK_TRIGGER 0 823 #define STYLE_MASK_TRIGGER STYLE_MASK 824 #define SORT_MASK_TRIGGER SORT_MASK 825 #define DISP_MASK_TRIGGER DISP_ROWS 713 static const char ls_options[] ALIGN1 = 714 "Cadil1gnsxAk" 715 USE_FEATURE_LS_TIMESTAMPS("cetu") 716 USE_FEATURE_LS_SORTFILES("SXrv") 717 USE_FEATURE_LS_FILETYPES("Fp") 718 USE_FEATURE_LS_FOLLOWLINKS("L") 719 USE_FEATURE_LS_RECURSIVE("R") 720 USE_FEATURE_HUMAN_READABLE("h") 721 USE_SELINUX("K") 722 USE_FEATURE_AUTOWIDTH("T:w:") 723 USE_SELINUX("Z"); 724 725 enum { 726 LIST_MASK_TRIGGER = 0, 727 STYLE_MASK_TRIGGER = STYLE_MASK, 728 DISP_MASK_TRIGGER = DISP_ROWS, 729 SORT_MASK_TRIGGER = SORT_MASK, 730 }; 826 731 827 732 static const unsigned opt_flags[] = { 828 LIST_SHORT | STYLE_COLUMNS, /* C */ 829 DISP_HIDDEN | DISP_DOT, /* a */ 830 DISP_NOLIST, /* d */ 831 LIST_INO, /* i */ 832 LIST_LONG | STYLE_LONG, /* l - remember LS_DISP_HR in mask! */ 833 LIST_SHORT | STYLE_SINGLE, /* 1 */ 834 0, /* g - ingored */ 835 LIST_ID_NUMERIC, /* n */ 836 LIST_BLOCKS, /* s */ 837 DISP_ROWS, /* x */ 838 DISP_HIDDEN, /* A */ 839 #ifdef CONFIG_SELINUX 840 LIST_CONTEXT, /* k */ 841 #else 842 0, /* k - ingored */ 843 #endif 844 #ifdef CONFIG_FEATURE_LS_TIMESTAMPS 845 TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ 846 LIST_FULLTIME, /* e */ 847 ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */ 848 TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */ 849 #endif 850 #ifdef CONFIG_FEATURE_LS_SORTFILES 851 SORT_SIZE, /* S */ 852 SORT_EXT, /* X */ 853 SORT_ORDER_REVERSE, /* r */ 854 SORT_VERSION, /* v */ 855 #endif 856 #ifdef CONFIG_FEATURE_LS_FILETYPES 857 LIST_FILETYPE | LIST_EXEC, /* F */ 858 LIST_FILETYPE, /* p */ 859 #endif 860 #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS 861 FOLLOW_LINKS, /* L */ 862 #endif 863 #ifdef CONFIG_FEATURE_LS_RECURSIVE 864 DISP_RECURSIVE, /* R */ 865 #endif 866 #ifdef CONFIG_FEATURE_HUMAN_READABLE 867 LS_DISP_HR, /* h */ 868 #endif 869 #ifdef CONFIG_SELINUX 733 LIST_SHORT | STYLE_COLUMNS, /* C */ 734 DISP_HIDDEN | DISP_DOT, /* a */ 735 DISP_NOLIST, /* d */ 736 LIST_INO, /* i */ 737 LIST_LONG | STYLE_LONG, /* l - remember LS_DISP_HR in mask! */ 738 LIST_SHORT | STYLE_SINGLE, /* 1 */ 739 0, /* g - ingored */ 740 LIST_ID_NUMERIC, /* n */ 741 LIST_BLOCKS, /* s */ 742 DISP_ROWS, /* x */ 743 DISP_HIDDEN, /* A */ 744 ENABLE_SELINUX * LIST_CONTEXT, /* k (ignored if !SELINUX) */ 745 #if ENABLE_FEATURE_LS_TIMESTAMPS 746 TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ 747 LIST_FULLTIME, /* e */ 748 ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */ 749 TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */ 750 #endif 751 #if ENABLE_FEATURE_LS_SORTFILES 752 SORT_SIZE, /* S */ 753 SORT_EXT, /* X */ 754 SORT_REVERSE, /* r */ 755 SORT_VERSION, /* v */ 756 #endif 757 #if ENABLE_FEATURE_LS_FILETYPES 758 LIST_FILETYPE | LIST_EXEC, /* F */ 759 LIST_FILETYPE, /* p */ 760 #endif 761 #if ENABLE_FEATURE_LS_FOLLOWLINKS 762 FOLLOW_LINKS, /* L */ 763 #endif 764 #if ENABLE_FEATURE_LS_RECURSIVE 765 DISP_RECURSIVE, /* R */ 766 #endif 767 #if ENABLE_FEATURE_HUMAN_READABLE 768 LS_DISP_HR, /* h */ 769 #endif 770 #if ENABLE_SELINUX 870 771 LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */ 871 772 #endif 872 #ifdef CONFIG_FEATURE_AUTOWIDTH 873 0, 0, /* T, w - ignored */ 773 #if ENABLE_FEATURE_AUTOWIDTH 774 0, 0, /* T, w - ignored */ 775 #endif 776 #if ENABLE_SELINUX 777 LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */ 874 778 #endif 875 779 (1U<<31) … … 877 781 878 782 879 /*----------------------------------------------------------------------*/ 880 783 /* THIS IS A "SAFE" APPLET, main() MAY BE CALLED INTERNALLY FROM SHELL */ 784 /* BE CAREFUL! */ 785 786 int ls_main(int argc, char **argv); 881 787 int ls_main(int argc, char **argv) 882 788 { … … 886 792 struct dnode *dn; 887 793 struct dnode *cur; 888 longopt;794 unsigned opt; 889 795 int nfiles = 0; 890 796 int dnfiles; … … 894 800 int i; 895 801 char **av; 896 #ifdef CONFIG_FEATURE_AUTOWIDTH 897 char *tabstops_str = NULL;898 char *terminal_width_str = NULL;899 #endif 900 #if def CONFIG_FEATURE_LS_COLOR901 char *color_opt;802 USE_FEATURE_AUTOWIDTH(char *tabstops_str = NULL;) 803 USE_FEATURE_AUTOWIDTH(char *terminal_width_str = NULL;) 804 USE_FEATURE_LS_COLOR(char *color_opt;) 805 806 #if ENABLE_FEATURE_LS_TIMESTAMPS 807 time(¤t_time_t); 902 808 #endif 903 809 904 810 all_fmt = LIST_SHORT | 905 (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_ ORDER_FORWARD));906 907 #if def CONFIG_FEATURE_AUTOWIDTH908 /* Obtain the terminal width .*/909 get_terminal_width_height(STD OUT_FILENO, &terminal_width, NULL);811 (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_FORWARD)); 812 813 #if ENABLE_FEATURE_AUTOWIDTH 814 /* Obtain the terminal width */ 815 get_terminal_width_height(STDIN_FILENO, &terminal_width, NULL); 910 816 /* Go one less... */ 911 817 terminal_width--; 912 818 #endif 913 819 914 #ifdef CONFIG_FEATURE_LS_COLOR915 bb_applet_long_options = ls_color_opt;916 #endif917 918 820 /* process options */ 919 #ifdef CONFIG_FEATURE_AUTOWIDTH 920 opt = bb_getopt_ulflags(argc, argv, ls_options, &tabstops_str, &terminal_width_str 921 #ifdef CONFIG_FEATURE_LS_COLOR 922 , &color_opt 923 #endif 924 ); 925 if (tabstops_str) { 926 tabstops = atoi(tabstops_str); 927 } 928 if (terminal_width_str) { 929 terminal_width = atoi(terminal_width_str); 930 } 821 USE_FEATURE_LS_COLOR(applet_long_options = ls_color_opt;) 822 #if ENABLE_FEATURE_AUTOWIDTH 823 opt = getopt32(argv, ls_options, &tabstops_str, &terminal_width_str 824 USE_FEATURE_LS_COLOR(, &color_opt)); 825 if (tabstops_str) 826 tabstops = xatou(tabstops_str); 827 if (terminal_width_str) 828 terminal_width = xatou(terminal_width_str); 931 829 #else 932 opt = bb_getopt_ulflags(argc, argv, ls_options 933 #ifdef CONFIG_FEATURE_LS_COLOR 934 , &color_opt 935 #endif 936 ); 830 opt = getopt32(argv, ls_options USE_FEATURE_LS_COLOR(, &color_opt)); 937 831 #endif 938 832 for (i = 0; opt_flags[i] != (1U<<31); i++) { 939 833 if (opt & (1 << i)) { 940 unsigned intflags = opt_flags[i];941 942 if (flags & LIST_MASK_TRIGGER) {834 unsigned flags = opt_flags[i]; 835 836 if (flags & LIST_MASK_TRIGGER) 943 837 all_fmt &= ~LIST_MASK; 944 } 945 if (flags & STYLE_MASK_TRIGGER) { 838 if (flags & STYLE_MASK_TRIGGER) 946 839 all_fmt &= ~STYLE_MASK; 947 } 948 if (ENABLE_FEATURE_LS_SORTFILES && (flags & SORT_MASK_TRIGGER)) { 840 if (flags & SORT_MASK_TRIGGER) 949 841 all_fmt &= ~SORT_MASK; 950 } 951 if (flags & DISP_MASK_TRIGGER) { 842 if (flags & DISP_MASK_TRIGGER) 952 843 all_fmt &= ~DISP_MASK; 953 } 954 if (flags & TIME_MASK) { 844 if (flags & TIME_MASK) 955 845 all_fmt &= ~TIME_MASK; 956 } 957 if (flags & LIST_CONTEXT) { 846 if (flags & LIST_CONTEXT) 958 847 all_fmt |= STYLE_SINGLE; 959 } 960 #ifdef CONFIG_FEATURE_HUMAN_READABLE 961 if (opt == 'l') { 962 all_fmt &= ~LS_DISP_HR; 963 } 964 #endif 848 /* huh?? opt cannot be 'l' */ 849 //if (LS_DISP_HR && opt == 'l') 850 // all_fmt &= ~LS_DISP_HR; 965 851 all_fmt |= flags; 966 852 } 967 853 } 968 854 969 #ifdef CONFIG_FEATURE_LS_COLOR 970 { 971 /* find color bit value - last position for short getopt */ 972 973 #if CONFIG_FEATURE_LS_COLOR_IS_DEFAULT 974 char *p; 975 976 if ((p = getenv ("LS_COLORS")) != NULL && 977 (*p == '\0' || (strcmp(p, "none") == 0))) { 978 ; 979 } else if (isatty(STDOUT_FILENO)) { 855 #if ENABLE_FEATURE_LS_COLOR 856 /* find color bit value - last position for short getopt */ 857 if (ENABLE_FEATURE_LS_COLOR_IS_DEFAULT && isatty(STDOUT_FILENO)) { 858 char *p = getenv("LS_COLORS"); 859 /* LS_COLORS is unset, or (not empty && not "none") ? */ 860 if (!p || (p[0] && strcmp(p, "none"))) 980 861 show_color = 1; 981 } 982 #endif 983 984 if((opt & (1 << i))) { /* next flag after short options */ 985 if (color_opt == NULL || strcmp("always", color_opt) == 0) 986 show_color = 1; 987 else if (color_opt != NULL && strcmp("never", color_opt) == 0) 988 show_color = 0; 989 else if (color_opt != NULL && strcmp("auto", color_opt) == 0 && isatty(STDOUT_FILENO)) 990 show_color = 1; 991 } 862 } 863 if (opt & (1 << i)) { /* next flag after short options */ 864 if (!color_opt || !strcmp("always", color_opt)) 865 show_color = 1; 866 else if (color_opt && !strcmp("never", color_opt)) 867 show_color = 0; 868 else if (color_opt && !strcmp("auto", color_opt) && isatty(STDOUT_FILENO)) 869 show_color = 1; 992 870 } 993 871 #endif 994 872 995 873 /* sort out which command line options take precedence */ 996 #ifdef CONFIG_FEATURE_LS_RECURSIVE 997 if (all_fmt & DISP_NOLIST) 874 if (ENABLE_FEATURE_LS_RECURSIVE && (all_fmt & DISP_NOLIST)) 998 875 all_fmt &= ~DISP_RECURSIVE; /* no recurse if listing only dir */ 999 #endif1000 876 if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) { 1001 877 if (all_fmt & TIME_CHANGE) … … 1006 882 if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */ 1007 883 all_fmt &= ~(LIST_ID_NUMERIC|LIST_FULLTIME|LIST_ID_NAME|LIST_ID_NUMERIC); 1008 #ifdef CONFIG_FEATURE_LS_USERNAME 1009 if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC)) 1010 all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */ 1011 #endif 884 if (ENABLE_FEATURE_LS_USERNAME) 885 if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC)) 886 all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */ 1012 887 1013 888 /* choose a display format */ … … 1024 899 ac = argc - optind; /* how many cmd line args are left */ 1025 900 if (ac < 1) { 1026 static const char * 901 static const char *const dotdir[] = { "." }; 1027 902 1028 903 av = (char **) dotdir; … … 1036 911 all_fmt |= DISP_DIRNAME; /* 2 or more items? label directories */ 1037 912 1038 /* stuff the command line file names into a ndnode array */913 /* stuff the command line file names into a dnode array */ 1039 914 dn = NULL; 1040 915 for (oi = 0; oi < ac; oi++) { 1041 cur = my_stat(av[oi], av[oi]); 916 /* ls w/o -l follows links on command line */ 917 cur = my_stat(av[oi], av[oi], !(all_fmt & STYLE_LONG)); 1042 918 if (!cur) 1043 919 continue; … … 1049 925 1050 926 /* now that we know how many files there are 1051 ** allocate memory for an array to hold dnode pointers927 * allocate memory for an array to hold dnode pointers 1052 928 */ 1053 929 dnp = dnalloc(nfiles); … … 1058 934 1059 935 if (all_fmt & DISP_NOLIST) { 1060 if (ENABLE_FEATURE_LS_SORTFILES)dnsort(dnp, nfiles);936 dnsort(dnp, nfiles); 1061 937 if (nfiles > 0) 1062 938 showfiles(dnp, nfiles); … … 1067 943 dnfiles = nfiles - dndirs; 1068 944 if (dnfiles > 0) { 1069 if (ENABLE_FEATURE_LS_SORTFILES)dnsort(dnf, dnfiles);945 dnsort(dnf, dnfiles); 1070 946 showfiles(dnf, dnfiles); 1071 947 if (ENABLE_FEATURE_CLEAN_UP) … … 1073 949 } 1074 950 if (dndirs > 0) { 1075 if (ENABLE_FEATURE_LS_SORTFILES)dnsort(dnd, dndirs);951 dnsort(dnd, dndirs); 1076 952 showdirs(dnd, dndirs, dnfiles == 0); 1077 953 if (ENABLE_FEATURE_CLEAN_UP) … … 1081 957 if (ENABLE_FEATURE_CLEAN_UP) 1082 958 dfree(dnp, nfiles); 1083 return (status);1084 } 959 return status; 960 }
Note:
See TracChangeset
for help on using the changeset viewer.