diff options
| author | Ron Yorston <rmy@pobox.com> | 2025-08-15 09:00:13 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2025-08-15 09:00:13 +0100 |
| commit | 01ff9c492111cf7d51ad074629d6e72bc69fc149 (patch) | |
| tree | 394973e4e5f25dcd638185be75b84430c39ebab2 /coreutils | |
| parent | 9a2d9345377d38c428df6d3e0887956d359807ab (diff) | |
| parent | 8bde71eb1502a5cdf186769b47d470038f99bc95 (diff) | |
| download | busybox-w32-01ff9c492111cf7d51ad074629d6e72bc69fc149.tar.gz busybox-w32-01ff9c492111cf7d51ad074629d6e72bc69fc149.tar.bz2 busybox-w32-01ff9c492111cf7d51ad074629d6e72bc69fc149.zip | |
Merge branch 'busybox' into merge
Diffstat (limited to 'coreutils')
| -rw-r--r-- | coreutils/date.c | 2 | ||||
| -rw-r--r-- | coreutils/ls.c | 246 | ||||
| -rw-r--r-- | coreutils/md5_sha1_sum.c | 58 |
3 files changed, 209 insertions, 97 deletions
diff --git a/coreutils/date.c b/coreutils/date.c index 3a89b6caf..ef482af1b 100644 --- a/coreutils/date.c +++ b/coreutils/date.c | |||
| @@ -289,7 +289,7 @@ int date_main(int argc UNUSED_PARAM, char **argv) | |||
| 289 | 289 | ||
| 290 | /* if setting time, set it */ | 290 | /* if setting time, set it */ |
| 291 | if ((opt & OPT_SET) && clock_settime(CLOCK_REALTIME, &ts) < 0) { | 291 | if ((opt & OPT_SET) && clock_settime(CLOCK_REALTIME, &ts) < 0) { |
| 292 | bb_simple_perror_msg("can't set date"); | 292 | bb_simple_perror_msg_and_die("can't set date"); |
| 293 | } | 293 | } |
| 294 | } | 294 | } |
| 295 | 295 | ||
diff --git a/coreutils/ls.c b/coreutils/ls.c index 5d2e96a1e..2153554e8 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
| @@ -129,6 +129,8 @@ | |||
| 129 | //usage: "\n -F Append indicator (one of */=@|) to names" | 129 | //usage: "\n -F Append indicator (one of */=@|) to names" |
| 130 | //usage: ) | 130 | //usage: ) |
| 131 | //usage: "\n -l Long format" | 131 | //usage: "\n -l Long format" |
| 132 | ////usage: "\n -g Long format without group column" | ||
| 133 | ////TODO: support -G too ("suppress owner column", GNUism) | ||
| 132 | //usage: "\n -i List inode numbers" | 134 | //usage: "\n -i List inode numbers" |
| 133 | //usage: "\n -n List numeric UIDs and GIDs instead of names" | 135 | //usage: "\n -n List numeric UIDs and GIDs instead of names" |
| 134 | //usage: "\n -s List allocated blocks" | 136 | //usage: "\n -s List allocated blocks" |
| @@ -162,6 +164,8 @@ | |||
| 162 | //usage: IF_FEATURE_LS_WIDTH( | 164 | //usage: IF_FEATURE_LS_WIDTH( |
| 163 | //usage: "\n -w N Format N columns wide" | 165 | //usage: "\n -w N Format N columns wide" |
| 164 | //usage: ) | 166 | //usage: ) |
| 167 | ////usage: "\n -Q Double-quote names" | ||
| 168 | ////usage: "\n -q Replace unprintable chars with '?'" | ||
| 165 | //usage: IF_FEATURE_LS_COLOR( | 169 | //usage: IF_FEATURE_LS_COLOR( |
| 166 | //usage: "\n --color[={always,never,auto}]" | 170 | //usage: "\n --color[={always,never,auto}]" |
| 167 | //usage: ) | 171 | //usage: ) |
| @@ -199,27 +203,47 @@ SPLIT_SUBDIR = 2, | |||
| 199 | 203 | ||
| 200 | /* -Cadi1l Std options, busybox always supports */ | 204 | /* -Cadi1l Std options, busybox always supports */ |
| 201 | /* -gnsxA Std options, busybox always supports */ | 205 | /* -gnsxA Std options, busybox always supports */ |
| 202 | /* -Q GNU option, busybox always supports */ | 206 | /* -Q GNU option, busybox always supports: */ |
| 203 | /* -k Std option, busybox always supports (by ignoring) */ | 207 | /* -Q, --quote-name */ |
| 204 | /* It means "for -s, show sizes in kbytes" */ | 208 | /* enclose entry names in double quotes */ |
| 205 | /* Seems to only affect "POSIXLY_CORRECT=1 ls -sk" */ | ||
| 206 | /* since otherwise -s shows kbytes anyway */ | ||
| 207 | /* -LHRctur Std options, busybox optionally supports */ | 209 | /* -LHRctur Std options, busybox optionally supports */ |
| 208 | /* -Fp Std options, busybox optionally supports */ | 210 | /* -Fp Std options, busybox optionally supports */ |
| 209 | /* -SXvhTw GNU options, busybox optionally supports */ | 211 | /* -SXvhTw GNU options, busybox optionally supports */ |
| 210 | /* -T WIDTH Ignored (we don't use tabs on output) */ | 212 | /* -T WIDTH Ignored (we don't use tabs on output) */ |
| 211 | /* -Z SELinux mandated option, busybox optionally supports */ | 213 | /* -Z SELinux mandated option, busybox optionally supports */ |
| 214 | /* -q Std option, busybox always supports: */ | ||
| 215 | /* https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html: */ | ||
| 216 | /* Force each instance of non-printable filename characters and */ | ||
| 217 | /* <tab> characters to be written as the <question-mark> ('?') */ | ||
| 218 | /* character. Implementations may provide this option by default */ | ||
| 219 | /* if the output is to a terminal device. */ | ||
| 220 | /* -k Std option, busybox always supports (by ignoring) */ | ||
| 221 | /* It means "for -s, show sizes in kbytes" */ | ||
| 222 | /* Seems to only affect "POSIXLY_CORRECT=1 ls -sk" */ | ||
| 223 | /* since otherwise -s shows kbytes anyway */ | ||
| 212 | #define ls_options \ | 224 | #define ls_options \ |
| 213 | "Cadi1lgnsxAk" /* 12 opts, total 12 */ \ | 225 | "Cadi1lgnsxA" /* 11 opts, total 11 */ \ |
| 214 | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 14 */ \ | 226 | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 13 */ \ |
| 215 | IF_FEATURE_LS_RECURSIVE("R") /* 1, 15 */ \ | 227 | IF_FEATURE_LS_RECURSIVE("R") /* 1, 14 */ \ |
| 216 | IF_SELINUX("Z") /* 1, 16 */ \ | 228 | IF_SELINUX("Z") /* 1, 15 */ \ |
| 217 | "Q" /* 1, 17 */ \ | 229 | "Q" /* 1, 16 */ \ |
| 218 | IF_FEATURE_LS_TIMESTAMPS("ctu") /* 3, 20 */ \ | 230 | IF_FEATURE_LS_TIMESTAMPS("ctu") /* 3, 19 */ \ |
| 219 | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 24 */ \ | 231 | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 23 */ \ |
| 220 | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 26 */ \ | 232 | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 25 */ \ |
| 221 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 27 */ \ | 233 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 26 */ \ |
| 222 | IF_FEATURE_LS_WIDTH("T:w:") /* 2, 29 */ | 234 | IF_FEATURE_LS_WIDTH("T:w:") /* 2, 28 */ \ |
| 235 | IF_LONG_OPTS("\xff") /* 1, 29 */ \ | ||
| 236 | IF_LONG_OPTS("\xfe") /* 1, 30 */ \ | ||
| 237 | IF_LONG_OPTS("\xfd") /* 1, 31 */ \ | ||
| 238 | "qk" /* 2, 33 */ | ||
| 239 | |||
| 240 | #if ENABLE_LONG_OPTS | ||
| 241 | static const char ls_longopts[] ALIGN1 = | ||
| 242 | "full-time\0" No_argument "\xff" | ||
| 243 | "group-directories-first\0" No_argument "\xfe" | ||
| 244 | IF_FEATURE_LS_COLOR("color\0" Optional_argument "\xfd") | ||
| 245 | ; | ||
| 246 | #endif | ||
| 223 | 247 | ||
| 224 | enum { | 248 | enum { |
| 225 | OPT_C = (1 << 0), | 249 | OPT_C = (1 << 0), |
| @@ -233,29 +257,31 @@ enum { | |||
| 233 | OPT_s = (1 << 8), | 257 | OPT_s = (1 << 8), |
| 234 | OPT_x = (1 << 9), | 258 | OPT_x = (1 << 9), |
| 235 | OPT_A = (1 << 10), | 259 | OPT_A = (1 << 10), |
| 236 | //OPT_k = (1 << 11), | ||
| 237 | 260 | ||
| 238 | OPTBIT_F = 12, | 261 | OPTBIT_F = 11, |
| 239 | OPTBIT_p, /* 13 */ | 262 | OPTBIT_p, /* 12 */ |
| 240 | OPTBIT_R = OPTBIT_F + 2 * ENABLE_FEATURE_LS_FILETYPES, | 263 | OPTBIT_R = OPTBIT_F + 2 * ENABLE_FEATURE_LS_FILETYPES, |
| 241 | OPTBIT_Z = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE, | 264 | OPTBIT_Z = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE, |
| 242 | OPTBIT_Q = OPTBIT_Z + 1 * ENABLE_SELINUX, | 265 | OPTBIT_Q = OPTBIT_Z + 1 * ENABLE_SELINUX, |
| 243 | OPTBIT_c, /* 17 */ | 266 | OPTBIT_c, /* 16 */ |
| 244 | OPTBIT_t, /* 18 */ | 267 | OPTBIT_t, /* 17 */ |
| 245 | OPTBIT_u, /* 19 */ | 268 | OPTBIT_u, /* 18 */ |
| 246 | OPTBIT_S = OPTBIT_c + 3 * ENABLE_FEATURE_LS_TIMESTAMPS, | 269 | OPTBIT_S = OPTBIT_c + 3 * ENABLE_FEATURE_LS_TIMESTAMPS, |
| 247 | OPTBIT_X, /* 21 */ | 270 | OPTBIT_X, /* 20 */ |
| 248 | OPTBIT_r, /* 22 */ | 271 | OPTBIT_r, /* 21 */ |
| 249 | OPTBIT_v, /* 23 */ | 272 | OPTBIT_v, /* 22 */ |
| 250 | OPTBIT_L = OPTBIT_S + 4 * ENABLE_FEATURE_LS_SORTFILES, | 273 | OPTBIT_L = OPTBIT_S + 4 * ENABLE_FEATURE_LS_SORTFILES, |
| 251 | OPTBIT_H, /* 25 */ | 274 | OPTBIT_H, /* 24 */ |
| 252 | OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS, | 275 | OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS, |
| 253 | OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE, | 276 | OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE, |
| 254 | OPTBIT_w, /* 28 */ | 277 | OPTBIT_w, /* 27 */ |
| 255 | OPTBIT_full_time = OPTBIT_T + 2 * ENABLE_FEATURE_LS_WIDTH, | 278 | OPTBIT_full_time = OPTBIT_T + 2 * ENABLE_FEATURE_LS_WIDTH, |
| 256 | OPTBIT_dirs_first, | 279 | OPTBIT_dirs_first, |
| 257 | OPTBIT_color, /* 31 */ | 280 | OPTBIT_color, /* 30 */ |
| 258 | /* with long opts, we use all 32 bits */ | 281 | OPTBIT_q = OPTBIT_color + 1, /* 31 */ |
| 282 | OPTBIT_k = OPTBIT_q + 1, /* 32 */ | ||
| 283 | /* with all options enabled, we use all 32 bits and even one extra bit! */ | ||
| 284 | /* this works because -k is ignored, and getopt32 allows such "ignore" options past 31th bit */ | ||
| 259 | 285 | ||
| 260 | OPT_F = (1 << OPTBIT_F) * ENABLE_FEATURE_LS_FILETYPES, | 286 | OPT_F = (1 << OPTBIT_F) * ENABLE_FEATURE_LS_FILETYPES, |
| 261 | OPT_p = (1 << OPTBIT_p) * ENABLE_FEATURE_LS_FILETYPES, | 287 | OPT_p = (1 << OPTBIT_p) * ENABLE_FEATURE_LS_FILETYPES, |
| @@ -277,6 +303,8 @@ enum { | |||
| 277 | OPT_full_time = (1 << OPTBIT_full_time ) * ENABLE_LONG_OPTS, | 303 | OPT_full_time = (1 << OPTBIT_full_time ) * ENABLE_LONG_OPTS, |
| 278 | OPT_dirs_first = (1 << OPTBIT_dirs_first) * ENABLE_LONG_OPTS, | 304 | OPT_dirs_first = (1 << OPTBIT_dirs_first) * ENABLE_LONG_OPTS, |
| 279 | OPT_color = (1 << OPTBIT_color ) * ENABLE_FEATURE_LS_COLOR, | 305 | OPT_color = (1 << OPTBIT_color ) * ENABLE_FEATURE_LS_COLOR, |
| 306 | OPT_q = (1 << OPTBIT_q), | ||
| 307 | //-k is ignored: OPT_k = (1 << OPTBIT_k), | ||
| 280 | }; | 308 | }; |
| 281 | 309 | ||
| 282 | /* | 310 | /* |
| @@ -333,6 +361,7 @@ struct globals { | |||
| 333 | #endif | 361 | #endif |
| 334 | smallint exit_code; | 362 | smallint exit_code; |
| 335 | smallint show_dirname; | 363 | smallint show_dirname; |
| 364 | smallint tty_out; | ||
| 336 | #if ENABLE_FEATURE_LS_WIDTH | 365 | #if ENABLE_FEATURE_LS_WIDTH |
| 337 | unsigned terminal_width; | 366 | unsigned terminal_width; |
| 338 | # define G_terminal_width (G.terminal_width) | 367 | # define G_terminal_width (G.terminal_width) |
| @@ -353,16 +382,21 @@ struct globals { | |||
| 353 | setup_common_bufsiz(); \ | 382 | setup_common_bufsiz(); \ |
| 354 | /* we have to zero it out because of NOEXEC */ \ | 383 | /* we have to zero it out because of NOEXEC */ \ |
| 355 | memset(&G, 0, sizeof(G)); \ | 384 | memset(&G, 0, sizeof(G)); \ |
| 356 | IF_FEATURE_LS_WIDTH(G_terminal_width = TERMINAL_WIDTH;) \ | 385 | IF_FEATURE_LS_WIDTH(G_terminal_width = ~0U;) \ |
| 357 | IF_FEATURE_LS_TIMESTAMPS(time(&G.current_time_t);) \ | 386 | IF_FEATURE_LS_TIMESTAMPS(time(&G.current_time_t);) \ |
| 358 | } while (0) | 387 | } while (0) |
| 359 | 388 | ||
| 360 | #define ESC "\033" | 389 | #define ESC "\033" |
| 361 | 390 | ||
| 391 | static int G_isatty(void) | ||
| 392 | { | ||
| 393 | if (!G.tty_out) /* not known yet? */ | ||
| 394 | G.tty_out = isatty(STDOUT_FILENO) + 1; | ||
| 395 | return (G.tty_out == 2); | ||
| 396 | } | ||
| 362 | 397 | ||
| 363 | /*** Output code ***/ | 398 | /*** Output code ***/ |
| 364 | 399 | ||
| 365 | |||
| 366 | /* FYI type values: 1:fifo 2:char 4:dir 6:blk 8:file 10:link 12:socket | 400 | /* FYI type values: 1:fifo 2:char 4:dir 6:blk 8:file 10:link 12:socket |
| 367 | * (various wacky OSes: 13:Sun door 14:BSD whiteout 5:XENIX named file | 401 | * (various wacky OSes: 13:Sun door 14:BSD whiteout 5:XENIX named file |
| 368 | * 3/7:multiplexed char/block device) | 402 | * 3/7:multiplexed char/block device) |
| @@ -425,56 +459,93 @@ static char append_char(mode_t mode) | |||
| 425 | } | 459 | } |
| 426 | #endif | 460 | #endif |
| 427 | 461 | ||
| 462 | /* Return the number of used columns. | ||
| 463 | * Note that only columnar output uses return value. | ||
| 464 | * -l and -1 modes don't care. | ||
| 465 | * coreutils 7.2 also supports: | ||
| 466 | * ls -b (--escape) = octal escapes (although it doesn't look like working) | ||
| 467 | * ls -N (--literal) = not escape at all | ||
| 468 | */ | ||
| 428 | static unsigned calc_name_len(const char *name) | 469 | static unsigned calc_name_len(const char *name) |
| 429 | { | 470 | { |
| 430 | unsigned len; | 471 | unsigned len; |
| 431 | uni_stat_t uni_stat; | 472 | uni_stat_t uni_stat; |
| 432 | 473 | ||
| 433 | // TODO: quote tab as \t, etc, if -Q | 474 | if (!(option_mask32 & (OPT_q|OPT_Q))) |
| 434 | name = printable_string2(&uni_stat, name); | 475 | return strlen(name); |
| 435 | 476 | ||
| 436 | if (!(option_mask32 & OPT_Q)) { | 477 | if (!(option_mask32 & OPT_Q)) { |
| 478 | /* the most likely branch: "ls" to tty (it auto-enables -q behavior) */ | ||
| 479 | printable_string2(&uni_stat, name); | ||
| 437 | return uni_stat.unicode_width; | 480 | return uni_stat.unicode_width; |
| 438 | } | 481 | } |
| 439 | 482 | ||
| 440 | len = 2 + uni_stat.unicode_width; | 483 | len = 2 + strlen(name); |
| 441 | while (*name) { | 484 | while (*name) { |
| 485 | unsigned char ch = (unsigned char)*name; | ||
| 486 | if (ch < ' ' || ch > 0x7e) { | ||
| 487 | ch -= 7; | ||
| 488 | if (ch <= 6) { | ||
| 489 | /* quote chars 7..13 as \a,b,t,n,v,f,r */ | ||
| 490 | goto two; | ||
| 491 | } | ||
| 492 | /* other chars <32 or >126 as \ooo octal */ | ||
| 493 | len += 3; | ||
| 494 | goto next; | ||
| 495 | } | ||
| 442 | if (*name == '"' || *name == '\\') { | 496 | if (*name == '"' || *name == '\\') { |
| 497 | two: | ||
| 443 | len++; | 498 | len++; |
| 444 | } | 499 | } |
| 500 | next: | ||
| 445 | name++; | 501 | name++; |
| 446 | } | 502 | } |
| 447 | return len; | 503 | return len; |
| 448 | } | 504 | } |
| 449 | |||
| 450 | /* Return the number of used columns. | ||
| 451 | * Note that only columnar output uses return value. | ||
| 452 | * -l and -1 modes don't care. | ||
| 453 | * coreutils 7.2 also supports: | ||
| 454 | * ls -b (--escape) = octal escapes (although it doesn't look like working) | ||
| 455 | * ls -N (--literal) = not escape at all | ||
| 456 | */ | ||
| 457 | static unsigned print_name(const char *name) | 505 | static unsigned print_name(const char *name) |
| 458 | { | 506 | { |
| 459 | unsigned len; | 507 | unsigned len; |
| 460 | uni_stat_t uni_stat; | 508 | uni_stat_t uni_stat; |
| 461 | 509 | ||
| 462 | // TODO: quote tab as \t, etc, if -Q | 510 | if (!(option_mask32 & (OPT_q|OPT_Q))) { |
| 463 | name = printable_string2(&uni_stat, name); | 511 | fputs_stdout(name); |
| 512 | return strlen(name); | ||
| 513 | } | ||
| 464 | 514 | ||
| 465 | if (!(option_mask32 & OPT_Q)) { | 515 | if (!(option_mask32 & OPT_Q)) { |
| 516 | /* the most likely branch: "ls" to tty (it auto-enables -q behavior) */ | ||
| 517 | name = printable_string2(&uni_stat, name); | ||
| 466 | fputs_stdout(name); | 518 | fputs_stdout(name); |
| 467 | return uni_stat.unicode_width; | 519 | return uni_stat.unicode_width; |
| 468 | } | 520 | } |
| 469 | 521 | ||
| 470 | len = 2 + uni_stat.unicode_width; | 522 | len = 2 + strlen(name); |
| 471 | putchar('"'); | 523 | putchar('"'); |
| 472 | while (*name) { | 524 | while (*name) { |
| 473 | if (*name == '"' || *name == '\\') { | 525 | unsigned char ch = (unsigned char)*name; |
| 526 | if (ch < ' ' || ch > 0x7e) { | ||
| 474 | putchar('\\'); | 527 | putchar('\\'); |
| 528 | ch -= 7; | ||
| 529 | if (ch <= 6) { | ||
| 530 | /* quote chars 7..13 as \a,b,t,n,v,f,r */ | ||
| 531 | ch = c_escape_conv_str07[1 + 3 * ch]; | ||
| 532 | goto two; | ||
| 533 | } | ||
| 534 | /* other chars <32 or >126 as \ooo octal */ | ||
| 535 | ch = (unsigned char)*name; | ||
| 536 | putchar('0' + (ch>>6)); | ||
| 537 | putchar('0' + ((ch>>3) & 7)); | ||
| 538 | ch = '0' + (ch & 7); | ||
| 539 | len += 3; | ||
| 540 | goto put_ch; | ||
| 541 | } | ||
| 542 | if (ch == '"' || ch == '\\') { | ||
| 543 | putchar('\\'); | ||
| 544 | two: | ||
| 475 | len++; | 545 | len++; |
| 476 | } | 546 | } |
| 477 | putchar(*name); | 547 | put_ch: |
| 548 | putchar(ch); | ||
| 478 | name++; | 549 | name++; |
| 479 | } | 550 | } |
| 480 | putchar('"'); | 551 | putchar('"'); |
| @@ -660,7 +731,7 @@ static void display_files(struct dnode **dn, unsigned nfiles) | |||
| 660 | unsigned i, ncols, nrows, row, nc; | 731 | unsigned i, ncols, nrows, row, nc; |
| 661 | unsigned column; | 732 | unsigned column; |
| 662 | unsigned nexttab; | 733 | unsigned nexttab; |
| 663 | unsigned column_width = 0; /* used only by coulmnal output */ | 734 | unsigned column_width = 0; /* used only by columnar output */ |
| 664 | 735 | ||
| 665 | if (option_mask32 & (OPT_l|OPT_1)) { | 736 | if (option_mask32 & (OPT_l|OPT_1)) { |
| 666 | ncols = 1; | 737 | ncols = 1; |
| @@ -709,6 +780,11 @@ static void display_files(struct dnode **dn, unsigned nfiles) | |||
| 709 | } | 780 | } |
| 710 | nexttab = column + column_width; | 781 | nexttab = column + column_width; |
| 711 | column += display_single(dn[i]); | 782 | column += display_single(dn[i]); |
| 783 | } else { | ||
| 784 | /* if -w999999999, ncols can be very large */ | ||
| 785 | //bb_error_msg(" col:%u ncol:%u i:%i", nc, ncols, i); sleep1(); | ||
| 786 | /* without "break", we loop millions of times here */ | ||
| 787 | break; | ||
| 712 | } | 788 | } |
| 713 | } | 789 | } |
| 714 | putchar('\n'); | 790 | putchar('\n'); |
| @@ -1155,25 +1231,11 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
| 1155 | /* need to initialize since --color has _an optional_ argument */ | 1231 | /* need to initialize since --color has _an optional_ argument */ |
| 1156 | const char *color_opt = color_str; /* "always" */ | 1232 | const char *color_opt = color_str; /* "always" */ |
| 1157 | #endif | 1233 | #endif |
| 1158 | #if ENABLE_LONG_OPTS | ||
| 1159 | static const char ls_longopts[] ALIGN1 = | ||
| 1160 | "full-time\0" No_argument "\xff" | ||
| 1161 | "group-directories-first\0" No_argument "\xfe" | ||
| 1162 | IF_FEATURE_LS_COLOR("color\0" Optional_argument "\xfd") | ||
| 1163 | ; | ||
| 1164 | #endif | ||
| 1165 | 1234 | ||
| 1166 | INIT_G(); | 1235 | INIT_G(); |
| 1167 | 1236 | ||
| 1168 | init_unicode(); | 1237 | init_unicode(); |
| 1169 | 1238 | ||
| 1170 | #if ENABLE_FEATURE_LS_WIDTH | ||
| 1171 | /* obtain the terminal width */ | ||
| 1172 | G_terminal_width = get_terminal_width(STDIN_FILENO); | ||
| 1173 | /* go one less... */ | ||
| 1174 | G_terminal_width--; | ||
| 1175 | #endif | ||
| 1176 | |||
| 1177 | /* process options */ | 1239 | /* process options */ |
| 1178 | opt = getopt32long(argv, "^" | 1240 | opt = getopt32long(argv, "^" |
| 1179 | ls_options | 1241 | ls_options |
| @@ -1211,6 +1273,29 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
| 1211 | exit(0); | 1273 | exit(0); |
| 1212 | #endif | 1274 | #endif |
| 1213 | 1275 | ||
| 1276 | /* ftpd secret backdoor? */ | ||
| 1277 | if (ENABLE_FTPD && applet_name[0] == 'f') { | ||
| 1278 | /* dirs first are much nicer */ | ||
| 1279 | opt = option_mask32 |= OPT_dirs_first; | ||
| 1280 | /* don't show SEcontext */ | ||
| 1281 | IF_SELINUX(opt = option_mask32 &= ~OPT_Z;) | ||
| 1282 | /* do not query stdout about size and tty-ness */ | ||
| 1283 | IF_FEATURE_LS_WIDTH(G_terminal_width = INT_MAX;) | ||
| 1284 | G.tty_out = 1; /* not a tty */ | ||
| 1285 | goto skip_if_ftpd; | ||
| 1286 | } | ||
| 1287 | |||
| 1288 | #if ENABLE_FEATURE_LS_WIDTH | ||
| 1289 | if ((int)G_terminal_width < 0) { | ||
| 1290 | /* obtain the terminal width */ | ||
| 1291 | G_terminal_width = get_terminal_width(STDIN_FILENO); | ||
| 1292 | /* go one less... */ | ||
| 1293 | G_terminal_width--; | ||
| 1294 | } | ||
| 1295 | if (G_terminal_width == 0) /* -w0 */ | ||
| 1296 | G_terminal_width = INT_MAX; /* "infinite" */ | ||
| 1297 | #endif | ||
| 1298 | |||
| 1214 | #if ENABLE_SELINUX | 1299 | #if ENABLE_SELINUX |
| 1215 | if (opt & OPT_Z) { | 1300 | if (opt & OPT_Z) { |
| 1216 | if (!is_selinux_enabled()) | 1301 | if (!is_selinux_enabled()) |
| @@ -1229,7 +1314,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
| 1229 | # endif | 1314 | # endif |
| 1230 | /* LS_COLORS is unset, or (not empty && not "none") ? */ | 1315 | /* LS_COLORS is unset, or (not empty && not "none") ? */ |
| 1231 | if (!p || (p[0] && strcmp(p, "none") != 0)) { | 1316 | if (!p || (p[0] && strcmp(p, "none") != 0)) { |
| 1232 | if (isatty(STDOUT_FILENO)) { | 1317 | if (G_isatty()) { |
| 1233 | /* check isatty() last because it's expensive (syscall) */ | 1318 | /* check isatty() last because it's expensive (syscall) */ |
| 1234 | G_show_color = 1; | 1319 | G_show_color = 1; |
| 1235 | } | 1320 | } |
| @@ -1238,23 +1323,28 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
| 1238 | if (opt & OPT_color) { | 1323 | if (opt & OPT_color) { |
| 1239 | if (color_opt[0] == 'n') | 1324 | if (color_opt[0] == 'n') |
| 1240 | G_show_color = 0; | 1325 | G_show_color = 0; |
| 1241 | else switch (index_in_substrings(color_str, color_opt)) { | 1326 | else if (!G_show_color) { |
| 1242 | case 3: | 1327 | /* if() is not needed, but avoids extra isatty() if G_show_color is already set */ |
| 1243 | case 4: | 1328 | /* Check --color=COLOR_OPT and maybe set show_color=1 */ |
| 1244 | case 5: | 1329 | switch (index_in_substrings(color_str, color_opt)) { |
| 1245 | if (!is_TERM_dumb() && isatty(STDOUT_FILENO)) { | 1330 | case 3: // auto |
| 1246 | case 0: | 1331 | case 4: // tty |
| 1247 | case 1: | 1332 | case 5: // if-tty |
| 1248 | case 2: | 1333 | if (!is_TERM_dumb() && G_isatty()) { |
| 1249 | G_show_color = 1; | 1334 | case 0: // always |
| 1335 | case 1: // yes | ||
| 1336 | case 2: // force | ||
| 1337 | G_show_color = 1; | ||
| 1338 | } | ||
| 1250 | } | 1339 | } |
| 1251 | } | 1340 | } |
| 1252 | } | 1341 | } |
| 1253 | #endif | 1342 | #endif |
| 1343 | skip_if_ftpd: | ||
| 1254 | 1344 | ||
| 1255 | /* sort out which command line options take precedence */ | 1345 | /* sort out which command line options take precedence */ |
| 1256 | if (ENABLE_FEATURE_LS_RECURSIVE && (opt & OPT_d)) | 1346 | if (ENABLE_FEATURE_LS_RECURSIVE && (opt & OPT_d)) |
| 1257 | option_mask32 &= ~OPT_R; /* no recurse if listing only dir */ | 1347 | opt = option_mask32 &= ~OPT_R; /* no recurse if listing only dir */ |
| 1258 | if (!(opt & OPT_l)) { /* not -l? */ | 1348 | if (!(opt & OPT_l)) { /* not -l? */ |
| 1259 | if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) { | 1349 | if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) { |
| 1260 | /* when to sort by time? -t[cu] sorts by time even with -l */ | 1350 | /* when to sort by time? -t[cu] sorts by time even with -l */ |
| @@ -1262,19 +1352,17 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
| 1262 | /* without -l, bare -c or -u enable sort too */ | 1352 | /* without -l, bare -c or -u enable sort too */ |
| 1263 | /* (with -l, bare -c or -u just select which time to show) */ | 1353 | /* (with -l, bare -c or -u just select which time to show) */ |
| 1264 | if (opt & (OPT_c|OPT_u)) { | 1354 | if (opt & (OPT_c|OPT_u)) { |
| 1265 | option_mask32 |= OPT_t; | 1355 | opt = option_mask32 |= OPT_t; |
| 1266 | } | 1356 | } |
| 1267 | } | 1357 | } |
| 1268 | } | 1358 | } |
| 1269 | 1359 | ||
| 1270 | /* choose a display format if one was not already specified by an option */ | 1360 | /* choose a display format if one was not already specified by an option */ |
| 1271 | if (!(option_mask32 & (OPT_l|OPT_1|OPT_x|OPT_C))) | 1361 | if (!(opt & (OPT_l|OPT_1|OPT_x|OPT_C))) |
| 1272 | option_mask32 |= (isatty(STDOUT_FILENO) ? OPT_C : OPT_1); | 1362 | opt = option_mask32 |= (G_isatty() ? OPT_C : OPT_1); |
| 1273 | 1363 | ||
| 1274 | if (ENABLE_FTPD && applet_name[0] == 'f') { | 1364 | if (!(opt & OPT_q) && G_isatty()) |
| 1275 | /* ftpd secret backdoor. dirs first are much nicer */ | 1365 | opt = option_mask32 |= OPT_q; |
| 1276 | option_mask32 |= OPT_dirs_first; | ||
| 1277 | } | ||
| 1278 | 1366 | ||
| 1279 | #if ENABLE_FEATURE_EXTRA_FILE_DATA | 1367 | #if ENABLE_FEATURE_EXTRA_FILE_DATA |
| 1280 | /* Enable accurate link counts for directories */ | 1368 | /* Enable accurate link counts for directories */ |
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c index 978d328f1..4506aeb56 100644 --- a/coreutils/md5_sha1_sum.c +++ b/coreutils/md5_sha1_sum.c | |||
| @@ -23,6 +23,12 @@ | |||
| 23 | //config: help | 23 | //config: help |
| 24 | //config: Compute and check SHA256 message digest | 24 | //config: Compute and check SHA256 message digest |
| 25 | //config: | 25 | //config: |
| 26 | //config:config SHA384SUM | ||
| 27 | //config: bool "sha384sum (7.3 kb)" | ||
| 28 | //config: default y | ||
| 29 | //config: help | ||
| 30 | //config: Compute and check SHA384 message digest | ||
| 31 | //config: | ||
| 26 | //config:config SHA512SUM | 32 | //config:config SHA512SUM |
| 27 | //config: bool "sha512sum (7.3 kb)" | 33 | //config: bool "sha512sum (7.3 kb)" |
| 28 | //config: default y | 34 | //config: default y |
| @@ -35,13 +41,13 @@ | |||
| 35 | //config: help | 41 | //config: help |
| 36 | //config: Compute and check SHA3 message digest | 42 | //config: Compute and check SHA3 message digest |
| 37 | //config: | 43 | //config: |
| 38 | //config:comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum" | 44 | //config:comment "Common options for md5sum, sha1sum, sha256sum, ..., sha3sum" |
| 39 | //config: depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM | 45 | //config: depends on MD5SUM || SHA1SUM || SHA256SUM || SHA384SUM || SHA512SUM || SHA3SUM |
| 40 | //config: | 46 | //config: |
| 41 | //config:config FEATURE_MD5_SHA1_SUM_CHECK | 47 | //config:config FEATURE_MD5_SHA1_SUM_CHECK |
| 42 | //config: bool "Enable -c, -s and -w options" | 48 | //config: bool "Enable -c, -s and -w options" |
| 43 | //config: default y | 49 | //config: default y |
| 44 | //config: depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM | 50 | //config: depends on MD5SUM || SHA1SUM || SHA256SUM || SHA384SUM || SHA512SUM || SHA3SUM |
| 45 | //config: help | 51 | //config: help |
| 46 | //config: Enabling the -c options allows files to be checked | 52 | //config: Enabling the -c options allows files to be checked |
| 47 | //config: against pre-calculated hash values. | 53 | //config: against pre-calculated hash values. |
| @@ -51,11 +57,13 @@ | |||
| 51 | //applet:IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum)) | 57 | //applet:IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum)) |
| 52 | //applet:IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum)) | 58 | //applet:IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum)) |
| 53 | //applet:IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum)) | 59 | //applet:IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum)) |
| 60 | //applet:IF_SHA384SUM(APPLET_NOEXEC(sha384sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha384sum)) | ||
| 54 | //applet:IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum)) | 61 | //applet:IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum)) |
| 55 | 62 | ||
| 56 | //kbuild:lib-$(CONFIG_MD5SUM) += md5_sha1_sum.o | 63 | //kbuild:lib-$(CONFIG_MD5SUM) += md5_sha1_sum.o |
| 57 | //kbuild:lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o | 64 | //kbuild:lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o |
| 58 | //kbuild:lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o | 65 | //kbuild:lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o |
| 66 | //kbuild:lib-$(CONFIG_SHA384SUM) += md5_sha1_sum.o | ||
| 59 | //kbuild:lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o | 67 | //kbuild:lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o |
| 60 | //kbuild:lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o | 68 | //kbuild:lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o |
| 61 | 69 | ||
| @@ -99,6 +107,16 @@ | |||
| 99 | //usage: "\n -w Warn about improperly formatted checksum lines" | 107 | //usage: "\n -w Warn about improperly formatted checksum lines" |
| 100 | //usage: ) | 108 | //usage: ) |
| 101 | //usage: | 109 | //usage: |
| 110 | //usage:#define sha384sum_trivial_usage | ||
| 111 | //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..." | ||
| 112 | //usage:#define sha384sum_full_usage "\n\n" | ||
| 113 | //usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA384 checksums" | ||
| 114 | //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n" | ||
| 115 | //usage: "\n -c Check sums against list in FILEs" | ||
| 116 | //usage: "\n -s Don't output anything, status code shows success" | ||
| 117 | //usage: "\n -w Warn about improperly formatted checksum lines" | ||
| 118 | //usage: ) | ||
| 119 | //usage: | ||
| 102 | //usage:#define sha512sum_trivial_usage | 120 | //usage:#define sha512sum_trivial_usage |
| 103 | //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..." | 121 | //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..." |
| 104 | //usage:#define sha512sum_full_usage "\n\n" | 122 | //usage:#define sha512sum_full_usage "\n\n" |
| @@ -130,11 +148,12 @@ | |||
| 130 | 148 | ||
| 131 | enum { | 149 | enum { |
| 132 | /* 4th letter of applet_name is... */ | 150 | /* 4th letter of applet_name is... */ |
| 133 | HASH_MD5 = 's', /* "md5>s<um" */ | 151 | HASH_MD5 = 's', /* "md5>s<um" */ |
| 134 | HASH_SHA1 = '1', | 152 | HASH_SHA1 = '1', |
| 135 | HASH_SHA256 = '2', | 153 | HASH_SHA256 = '2', |
| 136 | HASH_SHA3 = '3', | 154 | HASH_SHA3 = '3', |
| 137 | HASH_SHA512 = '5', | 155 | HASH_SHA512 = '5', |
| 156 | /* unfortunately, sha384sum has the same '3' as sha3 */ | ||
| 138 | }; | 157 | }; |
| 139 | 158 | ||
| 140 | #define FLAG_SILENT 1 | 159 | #define FLAG_SILENT 1 |
| @@ -158,10 +177,11 @@ static unsigned char *hash_bin_to_hex(unsigned char *hash_value, | |||
| 158 | #endif | 177 | #endif |
| 159 | static uint8_t *hash_file(unsigned char *in_buf, const char *filename, unsigned sha3_width) | 178 | static uint8_t *hash_file(unsigned char *in_buf, const char *filename, unsigned sha3_width) |
| 160 | { | 179 | { |
| 161 | int src_fd, hash_len, count; | 180 | int src_fd, count; |
| 162 | union _ctx_ { | 181 | union _ctx_ { |
| 163 | sha3_ctx_t sha3; | 182 | sha3_ctx_t sha3; |
| 164 | sha512_ctx_t sha512; | 183 | sha512_ctx_t sha512; |
| 184 | sha384_ctx_t sha384; | ||
| 165 | sha256_ctx_t sha256; | 185 | sha256_ctx_t sha256; |
| 166 | sha1_ctx_t sha1; | 186 | sha1_ctx_t sha1; |
| 167 | md5_ctx_t md5; | 187 | md5_ctx_t md5; |
| @@ -183,25 +203,31 @@ static uint8_t *hash_file(unsigned char *in_buf, const char *filename, unsigned | |||
| 183 | md5_begin(&context.md5); | 203 | md5_begin(&context.md5); |
| 184 | update = (void*)md5_hash; | 204 | update = (void*)md5_hash; |
| 185 | final = (void*)md5_end; | 205 | final = (void*)md5_end; |
| 186 | hash_len = 16; | ||
| 187 | } | 206 | } |
| 188 | else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) { | 207 | else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) { |
| 189 | sha1_begin(&context.sha1); | 208 | sha1_begin(&context.sha1); |
| 190 | update = (void*)sha1_hash; | 209 | update = (void*)sha1_hash; |
| 191 | final = (void*)sha1_end; | 210 | final = (void*)sha1_end; |
| 192 | hash_len = 20; | ||
| 193 | } | 211 | } |
| 194 | else if (ENABLE_SHA256SUM && hash_algo == HASH_SHA256) { | 212 | else if (ENABLE_SHA256SUM && hash_algo == HASH_SHA256) { |
| 195 | sha256_begin(&context.sha256); | 213 | sha256_begin(&context.sha256); |
| 196 | update = (void*)sha256_hash; | 214 | update = (void*)sha256_hash; |
| 197 | final = (void*)sha256_end; | 215 | final = (void*)sha256_end; |
| 198 | hash_len = 32; | 216 | } |
| 217 | else if (ENABLE_SHA384SUM | ||
| 218 | && (ENABLE_SHA3SUM | ||
| 219 | ? (applet_name[4] == '8') /* check for "sha384", but do not match "sha3" */ | ||
| 220 | : (hash_algo == '3') /* applet_name = "sha3sum" is not possible */ | ||
| 221 | ) | ||
| 222 | ) { | ||
| 223 | sha384_begin(&context.sha384); | ||
| 224 | update = (void*)sha384_hash; | ||
| 225 | final = (void*)sha384_end; | ||
| 199 | } | 226 | } |
| 200 | else if (ENABLE_SHA512SUM && hash_algo == HASH_SHA512) { | 227 | else if (ENABLE_SHA512SUM && hash_algo == HASH_SHA512) { |
| 201 | sha512_begin(&context.sha512); | 228 | sha512_begin(&context.sha512); |
| 202 | update = (void*)sha512_hash; | 229 | update = (void*)sha512_hash; |
| 203 | final = (void*)sha512_end; | 230 | final = (void*)sha512_end; |
| 204 | hash_len = 64; | ||
| 205 | } | 231 | } |
| 206 | #if ENABLE_SHA3SUM | 232 | #if ENABLE_SHA3SUM |
| 207 | else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) { | 233 | else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) { |
| @@ -219,9 +245,7 @@ static uint8_t *hash_file(unsigned char *in_buf, const char *filename, unsigned | |||
| 219 | ) { | 245 | ) { |
| 220 | bb_error_msg_and_die("bad -a%u", sha3_width); | 246 | bb_error_msg_and_die("bad -a%u", sha3_width); |
| 221 | } | 247 | } |
| 222 | sha3_width /= 4; | 248 | context.sha3.input_block_bytes = 1600/8 - sha3_width/4; |
| 223 | context.sha3.input_block_bytes = 1600/8 - sha3_width; | ||
| 224 | hash_len = sha3_width/2; | ||
| 225 | } | 249 | } |
| 226 | #endif | 250 | #endif |
| 227 | else { | 251 | else { |
| @@ -236,7 +260,7 @@ static uint8_t *hash_file(unsigned char *in_buf, const char *filename, unsigned | |||
| 236 | if (count < 0) | 260 | if (count < 0) |
| 237 | bb_perror_msg("can't read '%s'", filename); | 261 | bb_perror_msg("can't read '%s'", filename); |
| 238 | else /* count == 0 */ { | 262 | else /* count == 0 */ { |
| 239 | final(&context, in_buf); | 263 | unsigned hash_len = final(&context, in_buf); |
| 240 | hash_value = hash_bin_to_hex(in_buf, hash_len); | 264 | hash_value = hash_bin_to_hex(in_buf, hash_len); |
| 241 | } | 265 | } |
| 242 | } | 266 | } |
| @@ -262,14 +286,14 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) | |||
| 262 | /* -b "binary", -t "text" are ignored (shaNNNsum compat) */ | 286 | /* -b "binary", -t "text" are ignored (shaNNNsum compat) */ |
| 263 | /* -s and -w require -c */ | 287 | /* -s and -w require -c */ |
| 264 | #if ENABLE_SHA3SUM | 288 | #if ENABLE_SHA3SUM |
| 265 | if (applet_name[3] == HASH_SHA3) | 289 | if (applet_name[3] == HASH_SHA3 && (!ENABLE_SHA384SUM || applet_name[4] != '8')) |
| 266 | flags = getopt32(argv, "^" "scwbta:+" "\0" "s?c:w?c", &sha3_width); | 290 | flags = getopt32(argv, "^" "scwbta:+" "\0" "s?c:w?c", &sha3_width); |
| 267 | else | 291 | else |
| 268 | #endif | 292 | #endif |
| 269 | flags = getopt32(argv, "^" "scwbt" "\0" "s?c:w?c"); | 293 | flags = getopt32(argv, "^" "scwbt" "\0" "s?c:w?c"); |
| 270 | } else { | 294 | } else { |
| 271 | #if ENABLE_SHA3SUM | 295 | #if ENABLE_SHA3SUM |
| 272 | if (applet_name[3] == HASH_SHA3) | 296 | if (applet_name[3] == HASH_SHA3 && (!ENABLE_SHA384SUM || applet_name[4] != '8')) |
| 273 | getopt32(argv, "a:+", &sha3_width); | 297 | getopt32(argv, "a:+", &sha3_width); |
| 274 | else | 298 | else |
| 275 | #endif | 299 | #endif |
