diff options
author | aldot <aldot@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-08-28 23:31:54 +0000 |
---|---|---|
committer | aldot <aldot@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-08-28 23:31:54 +0000 |
commit | d52f45a484fc7fc049ab40db9adc6ead7ea9b122 (patch) | |
tree | 2a57564b8917a983365c765d4daa83032d9f0a17 /coreutils | |
parent | 2803d256e9decd450b955c2846bf945db72bb79e (diff) | |
download | busybox-w32-d52f45a484fc7fc049ab40db9adc6ead7ea9b122.tar.gz busybox-w32-d52f45a484fc7fc049ab40db9adc6ead7ea9b122.tar.bz2 busybox-w32-d52f45a484fc7fc049ab40db9adc6ead7ea9b122.zip |
- pull from busybox_scratch: r15829:15850
Various fixes, cleanups and shrinkage:
saves 952 Bytes:
text data bss dec hex filename
1087742 15853 790632 1894227 1ce753 ../busybox/busybox.old
1086790 15853 790632 1893275 1ce39b busybox
via:
# scripts/bloat-o-meter ../busybox/busybox_unstripped.old busybox_unstripped
function old new delta
ipcrm_main 756 822 +66
getval - 61 +61
maybe_set_utc - 40 +40
udhcpc_main 2896 2912 +16
md5_hash_block 428 437 +9
opt 8 16 +8
qgravechar 106 110 +4
make_bitmap 292 295 +3
inflate_unzip 2056 2059 +3
add_partition 1412 1414 +2
__parsespent 156 158 +2
qrealloc 41 42 +1
format - 1 +1
catv_main 313 314 +1
watch_main 293 292 -1
varunset 81 80 -1
part 1 - -1
check_if_skip 837 836 -1
start_stop_daemon_main 840 837 -3
create_lost_and_found 175 172 -3
supress_non_delimited_lines 4 - -4
static.l 4 - -4
static.c 5 1 -4
bsd_sum_file 237 233 -4
eval2 338 332 -6
arithmetic_common 166 158 -8
cmpfunc 22 5 -17
cksum_main 294 275 -19
cmp_main 465 439 -26
dd_main 1535 1508 -27
rmmod_main 376 333 -43
cut_file 727 644 -83
ipcs_main 3809 3721 -88
cut_main 722 614 -108
date_main 1443 1263 -180
remove_ids 222 - -222
------------------------------------------------------------------------------
(add/remove: 3/4 grow/shrink: 11/18 up/down: 217/-853) Total: -636 bytes
git-svn-id: svn://busybox.net/trunk/busybox@16009 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/catv.c | 44 | ||||
-rw-r--r-- | coreutils/cksum.c | 31 | ||||
-rw-r--r-- | coreutils/cmp.c | 47 | ||||
-rw-r--r-- | coreutils/cut.c | 479 | ||||
-rw-r--r-- | coreutils/date.c | 260 | ||||
-rw-r--r-- | coreutils/dd.c | 128 | ||||
-rw-r--r-- | coreutils/du.c | 9 | ||||
-rw-r--r-- | coreutils/expr.c | 406 | ||||
-rw-r--r-- | coreutils/sum.c | 21 | ||||
-rw-r--r-- | coreutils/tail.c | 21 | ||||
-rw-r--r-- | coreutils/tee.c | 3 | ||||
-rw-r--r-- | coreutils/watch.c | 21 |
12 files changed, 703 insertions, 767 deletions
diff --git a/coreutils/catv.c b/coreutils/catv.c index e18203915..f8229c20e 100644 --- a/coreutils/catv.c +++ b/coreutils/catv.c | |||
@@ -14,49 +14,55 @@ | |||
14 | 14 | ||
15 | int catv_main(int argc, char **argv) | 15 | int catv_main(int argc, char **argv) |
16 | { | 16 | { |
17 | int retval = EXIT_SUCCESS, fd, flags; | 17 | int retval = EXIT_SUCCESS, fd; |
18 | unsigned long flags; | ||
18 | 19 | ||
19 | flags = bb_getopt_ulflags(argc, argv, "etv"); | 20 | flags = bb_getopt_ulflags(argc, argv, "etv"); |
20 | flags ^= 4; | 21 | #define CATV_OPT_e (1<<0) |
21 | 22 | #define CATV_OPT_t (1<<1) | |
22 | // Loop through files. | 23 | #define CATV_OPT_v (1<<2) |
24 | flags ^= CATV_OPT_v; | ||
23 | 25 | ||
24 | argv += optind; | 26 | argv += optind; |
25 | do { | 27 | do { |
26 | // Read from stdin if there's nothing else to do. | 28 | /* Read from stdin if there's nothing else to do. */ |
27 | |||
28 | fd = 0; | 29 | fd = 0; |
29 | if (*argv && 0>(fd = xopen(*argv, O_RDONLY))) retval = EXIT_FAILURE; | 30 | if (*argv && 0 > (fd = xopen(*argv, O_RDONLY))) |
30 | else for(;;) { | 31 | retval = EXIT_FAILURE; |
32 | else for (;;) { | ||
31 | int i, res; | 33 | int i, res; |
32 | 34 | ||
33 | res = read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1)); | 35 | res = read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1)); |
34 | if (res < 0) retval = EXIT_FAILURE; | 36 | if (res < 0) |
35 | if (res <1) break; | 37 | retval = EXIT_FAILURE; |
36 | for (i=0; i<res; i++) { | 38 | if (res < 1) |
37 | char c=bb_common_bufsiz1[i]; | 39 | break; |
40 | for (i = 0; i < res; i++) { | ||
41 | char c = bb_common_bufsiz1[i]; | ||
38 | 42 | ||
39 | if (c > 126 && (flags & 4)) { | 43 | if (c > 126 && (flags & CATV_OPT_v)) { |
40 | if (c == 127) { | 44 | if (c == 127) { |
41 | printf("^?"); | 45 | bb_printf("^?"); |
42 | continue; | 46 | continue; |
43 | } else { | 47 | } else { |
44 | printf("M-"); | 48 | bb_printf("M-"); |
45 | c -= 128; | 49 | c -= 128; |
46 | } | 50 | } |
47 | } | 51 | } |
48 | if (c < 32) { | 52 | if (c < 32) { |
49 | if (c == 10) { | 53 | if (c == 10) { |
50 | if (flags & 1) putchar('$'); | 54 | if (flags & CATV_OPT_e) |
51 | } else if (flags & (c==9 ? 2 : 4)) { | 55 | putchar('$'); |
52 | printf("^%c", c+'@'); | 56 | } else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) { |
57 | bb_printf("^%c", c+'@'); | ||
53 | continue; | 58 | continue; |
54 | } | 59 | } |
55 | } | 60 | } |
56 | putchar(c); | 61 | putchar(c); |
57 | } | 62 | } |
58 | } | 63 | } |
59 | if (ENABLE_FEATURE_CLEAN_UP && fd) close(fd); | 64 | if (ENABLE_FEATURE_CLEAN_UP && fd) |
65 | close(fd); | ||
60 | } while (*++argv); | 66 | } while (*++argv); |
61 | 67 | ||
62 | return retval; | 68 | return retval; |
diff --git a/coreutils/cksum.c b/coreutils/cksum.c index 5849ddab2..9a45fd656 100644 --- a/coreutils/cksum.c +++ b/coreutils/cksum.c | |||
@@ -3,12 +3,13 @@ | |||
3 | * cksum - calculate the CRC32 checksum of a file | 3 | * cksum - calculate the CRC32 checksum of a file |
4 | * | 4 | * |
5 | * Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms | 5 | * Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms |
6 | * | 6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ |
8 | 8 | ||
9 | #include "busybox.h" | 9 | #include "busybox.h" |
10 | 10 | ||
11 | int cksum_main(int argc, char **argv) { | 11 | int cksum_main(int argc, char **argv) |
12 | { | ||
12 | 13 | ||
13 | uint32_t *crc32_table = crc32_filltable(1); | 14 | uint32_t *crc32_table = crc32_filltable(1); |
14 | 15 | ||
@@ -17,36 +18,36 @@ int cksum_main(int argc, char **argv) { | |||
17 | long length, filesize; | 18 | long length, filesize; |
18 | int bytes_read; | 19 | int bytes_read; |
19 | char *cp; | 20 | char *cp; |
20 | RESERVE_CONFIG_BUFFER(buf, BUFSIZ); | 21 | |
21 | int inp_stdin = (argc == optind) ? 1 : 0; | 22 | int inp_stdin = (argc == optind) ? 1 : 0; |
22 | 23 | ||
23 | do { | 24 | do { |
24 | fp = bb_wfopen_input((inp_stdin) ? bb_msg_standard_input : *++argv); | 25 | fp = bb_wfopen_input((inp_stdin) ? bb_msg_standard_input : *++argv); |
25 | 26 | ||
26 | crc = 0; | 27 | crc = 0; |
27 | length = 0; | 28 | length = 0; |
28 | 29 | ||
29 | while ((bytes_read = fread(buf, 1, BUFSIZ, fp)) > 0) { | 30 | while ((bytes_read = fread(bb_common_bufsiz1, 1, BUFSIZ, fp)) > 0) { |
30 | cp = buf; | 31 | cp = bb_common_bufsiz1; |
31 | length += bytes_read; | 32 | length += bytes_read; |
32 | while (bytes_read--) | 33 | while (bytes_read--) |
33 | crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL]; | 34 | crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL]; |
34 | } | 35 | } |
35 | 36 | ||
36 | filesize = length; | 37 | filesize = length; |
37 | 38 | ||
38 | for (; length; length >>= 8) | 39 | for (; length; length >>= 8) |
39 | crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL]; | 40 | crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL]; |
40 | crc ^= 0xffffffffL; | 41 | crc ^= 0xffffffffL; |
41 | 42 | ||
42 | if (inp_stdin) { | 43 | if (inp_stdin) { |
43 | printf("%"PRIu32" %li\n", crc, filesize); | 44 | bb_printf("%" PRIu32 " %li\n", crc, filesize); |
44 | break; | 45 | break; |
45 | } | 46 | } |
46 | 47 | ||
47 | printf("%"PRIu32" %li %s\n", crc, filesize, *argv); | 48 | bb_printf("%" PRIu32 " %li %s\n", crc, filesize, *argv); |
48 | fclose(fp); | 49 | fclose(fp); |
49 | } while (*(argv+1)); | 50 | } while (*(argv + 1)); |
50 | 51 | ||
51 | return EXIT_SUCCESS; | 52 | return EXIT_SUCCESS; |
52 | } | 53 | } |
diff --git a/coreutils/cmp.c b/coreutils/cmp.c index a569eb3fe..ae3f50279 100644 --- a/coreutils/cmp.c +++ b/coreutils/cmp.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | #include "busybox.h" | 24 | #include "busybox.h" |
25 | 25 | ||
26 | static FILE *cmp_xfopen_input(const char *filename) | 26 | static FILE *cmp_xfopen_input(const char * const filename) |
27 | { | 27 | { |
28 | FILE *fp; | 28 | FILE *fp; |
29 | 29 | ||
@@ -40,32 +40,28 @@ static const char fmt_differ[] = "%s %s differ: char %d, line %d\n"; | |||
40 | static const char fmt_l_opt[] = "%.0s%.0s%d %3o %3o\n"; | 40 | static const char fmt_l_opt[] = "%.0s%.0s%d %3o %3o\n"; |
41 | 41 | ||
42 | static const char opt_chars[] = "sl"; | 42 | static const char opt_chars[] = "sl"; |
43 | 43 | #define CMP_OPT_s (1<<0) | |
44 | enum { | 44 | #define CMP_OPT_l (1<<1) |
45 | OPT_s = 1, | ||
46 | OPT_l = 2 | ||
47 | }; | ||
48 | 45 | ||
49 | int cmp_main(int argc, char **argv) | 46 | int cmp_main(int argc, char **argv) |
50 | { | 47 | { |
51 | FILE *fp1, *fp2, *outfile = stdout; | 48 | FILE *fp1, *fp2, *outfile = stdout; |
52 | const char *filename1, *filename2; | 49 | const char *filename1, *filename2 = "-"; |
53 | const char *fmt; | 50 | const char *fmt; |
54 | int c1, c2, char_pos, line_pos; | 51 | int c1, c2, char_pos = 0, line_pos = 1; |
55 | int opt_flags; | 52 | unsigned opt; |
56 | int exit_val = 0; | 53 | int retval = 0; |
57 | 54 | ||
58 | bb_default_error_retval = 2; /* 1 is returned if files are different. */ | 55 | bb_default_error_retval = 2; /* 1 is returned if files are different. */ |
59 | 56 | ||
60 | opt_flags = bb_getopt_ulflags(argc, argv, opt_chars); | 57 | opt = bb_getopt_ulflags(argc, argv, opt_chars); |
61 | 58 | ||
62 | if ((opt_flags == 3) || (((unsigned int)(--argc - optind)) > 1)) { | 59 | if ((opt & (CMP_OPT_s|CMP_OPT_l)) |
60 | || (((unsigned int)(--argc - optind)) > 1)) | ||
63 | bb_show_usage(); | 61 | bb_show_usage(); |
64 | } | ||
65 | 62 | ||
66 | fp1 = cmp_xfopen_input(filename1 = *(argv += optind)); | 63 | fp1 = cmp_xfopen_input(filename1 = *(argv += optind)); |
67 | 64 | ||
68 | filename2 = "-"; | ||
69 | if (*++argv) { | 65 | if (*++argv) { |
70 | filename2 = *argv; | 66 | filename2 = *argv; |
71 | } | 67 | } |
@@ -79,19 +75,17 @@ int cmp_main(int argc, char **argv) | |||
79 | return 0; | 75 | return 0; |
80 | } | 76 | } |
81 | 77 | ||
82 | fmt = fmt_differ; | 78 | if (opt & CMP_OPT_l) |
83 | if (opt_flags == OPT_l) { | ||
84 | fmt = fmt_l_opt; | 79 | fmt = fmt_l_opt; |
85 | } | 80 | else |
81 | fmt = fmt_differ; | ||
86 | 82 | ||
87 | char_pos = 0; | ||
88 | line_pos = 1; | ||
89 | do { | 83 | do { |
90 | c1 = getc(fp1); | 84 | c1 = getc(fp1); |
91 | c2 = getc(fp2); | 85 | c2 = getc(fp2); |
92 | ++char_pos; | 86 | ++char_pos; |
93 | if (c1 != c2) { /* Remember -- a read error may have occurred. */ | 87 | if (c1 != c2) { /* Remember: a read error may have occurred. */ |
94 | exit_val = 1; /* But assume the files are different for now. */ | 88 | retval = 1; /* But assume the files are different for now. */ |
95 | if (c2 == EOF) { | 89 | if (c2 == EOF) { |
96 | /* We know that fp1 isn't at EOF or in an error state. But to | 90 | /* We know that fp1 isn't at EOF or in an error state. But to |
97 | * save space below, things are setup to expect an EOF in fp1 | 91 | * save space below, things are setup to expect an EOF in fp1 |
@@ -109,13 +103,14 @@ int cmp_main(int argc, char **argv) | |||
109 | * make sure we fflush before writing to stderr. */ | 103 | * make sure we fflush before writing to stderr. */ |
110 | xfflush_stdout(); | 104 | xfflush_stdout(); |
111 | } | 105 | } |
112 | if (opt_flags != OPT_s) { | 106 | if (!opt & CMP_OPT_s) { |
113 | if (opt_flags == OPT_l) { | 107 | if (opt & CMP_OPT_l) { |
114 | line_pos = c1; /* line_pos is unused in the -l case. */ | 108 | line_pos = c1; /* line_pos is unused in the -l case. */ |
115 | } | 109 | } |
116 | bb_fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2); | 110 | bb_fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2); |
117 | if (opt_flags) { /* This must be -l since not -s. */ | 111 | if (opt) { /* This must be -l since not -s. */ |
118 | /* If we encountered and EOF, the while check will catch it. */ | 112 | /* If we encountered an EOF, |
113 | * the while check will catch it. */ | ||
119 | continue; | 114 | continue; |
120 | } | 115 | } |
121 | } | 116 | } |
@@ -129,5 +124,5 @@ int cmp_main(int argc, char **argv) | |||
129 | xferror(fp1, filename1); | 124 | xferror(fp1, filename1); |
130 | xferror(fp2, filename2); | 125 | xferror(fp2, filename2); |
131 | 126 | ||
132 | bb_fflush_stdout_and_exit(exit_val); | 127 | bb_fflush_stdout_and_exit(retval); |
133 | } | 128 | } |
diff --git a/coreutils/cut.c b/coreutils/cut.c index 1b80e7e73..d88a891b0 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c | |||
@@ -4,28 +4,24 @@ | |||
4 | * | 4 | * |
5 | * Copyright (C) 1999,2000,2001 by Lineo, inc. | 5 | * Copyright (C) 1999,2000,2001 by Lineo, inc. |
6 | * Written by Mark Whitley <markw@codepoet.org> | 6 | * Written by Mark Whitley <markw@codepoet.org> |
7 | * debloated by Bernhard Fischer | ||
7 | * | 8 | * |
8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 9 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
9 | */ | 10 | */ |
10 | 11 | ||
11 | #include <stdio.h> | ||
12 | #include <stdlib.h> | ||
13 | #include <unistd.h> | ||
14 | #include <string.h> | ||
15 | #include <limits.h> | ||
16 | #include "busybox.h" | 12 | #include "busybox.h" |
17 | 13 | ||
18 | |||
19 | /* option vars */ | 14 | /* option vars */ |
20 | static const char optstring[] = "b:c:f:d:sn"; | 15 | static const char *const optstring = "b:c:f:d:sn"; |
21 | #define OPT_BYTE_FLGS 1 | 16 | |
22 | #define OPT_CHAR_FLGS 2 | 17 | #define CUT_OPT_BYTE_FLGS (1<<0) |
23 | #define OPT_FIELDS_FLGS 4 | 18 | #define CUT_OPT_CHAR_FLGS (1<<1) |
24 | #define OPT_DELIM_FLGS 8 | 19 | #define CUT_OPT_FIELDS_FLGS (1<<2) |
25 | #define OPT_SUPRESS_FLGS 16 | 20 | #define CUT_OPT_DELIM_FLGS (1<<3) |
26 | static char part; /* (b)yte, (c)har, (f)ields */ | 21 | #define CUT_OPT_SUPPRESS_FLGS (1<<4) |
27 | static unsigned int supress_non_delimited_lines; | 22 | static unsigned long opt; |
28 | static char delim = '\t'; /* delimiter, default is tab */ | 23 | |
24 | static char delim = '\t'; /* delimiter, default is tab */ | ||
29 | 25 | ||
30 | struct cut_list { | 26 | struct cut_list { |
31 | int startpos; | 27 | int startpos; |
@@ -38,295 +34,268 @@ enum { | |||
38 | NON_RANGE = -1 | 34 | NON_RANGE = -1 |
39 | }; | 35 | }; |
40 | 36 | ||
41 | static struct cut_list *cut_lists = NULL; /* growable array holding a series of lists */ | 37 | /* growable array holding a series of lists */ |
42 | static unsigned int nlists = 0; /* number of elements in above list */ | 38 | static struct cut_list *cut_lists; |
39 | static unsigned int nlists; /* number of elements in above list */ | ||
43 | 40 | ||
44 | 41 | ||
45 | static int cmpfunc(const void *a, const void *b) | 42 | static int cmpfunc(const void *a, const void *b) |
46 | { | 43 | { |
47 | struct cut_list *la = (struct cut_list *)a; | 44 | return (((struct cut_list *) a)->startpos - |
48 | struct cut_list *lb = (struct cut_list *)b; | 45 | ((struct cut_list *) b)->startpos); |
49 | |||
50 | if (la->startpos > lb->startpos) | ||
51 | return 1; | ||
52 | if (la->startpos < lb->startpos) | ||
53 | return -1; | ||
54 | return 0; | ||
55 | } | ||
56 | 46 | ||
47 | } | ||
57 | 48 | ||
58 | /* | 49 | static void cut_file(FILE * file) |
59 | * parse_lists() - parses a list and puts values into startpos and endpos. | ||
60 | * valid list formats: N, N-, N-M, -M | ||
61 | * more than one list can be separated by commas | ||
62 | */ | ||
63 | static void parse_lists(char *lists) | ||
64 | { | 50 | { |
65 | char *ltok = NULL; | 51 | char *line = NULL; |
66 | char *ntok = NULL; | 52 | unsigned int linenum = 0; /* keep these zero-based to be consistent */ |
67 | char *junk; | ||
68 | int s = 0, e = 0; | ||
69 | |||
70 | /* take apart the lists, one by one (they are separated with commas */ | ||
71 | while ((ltok = strsep(&lists, ",")) != NULL) { | ||
72 | |||
73 | /* it's actually legal to pass an empty list */ | ||
74 | if (strlen(ltok) == 0) | ||
75 | continue; | ||
76 | |||
77 | /* get the start pos */ | ||
78 | ntok = strsep(<ok, "-"); | ||
79 | if (ntok == NULL) { | ||
80 | fprintf(stderr, "Help ntok is null for starting position! What do I do?\n"); | ||
81 | } else if (strlen(ntok) == 0) { | ||
82 | s = BOL; | ||
83 | } else { | ||
84 | s = strtoul(ntok, &junk, 10); | ||
85 | if(*junk != '\0' || s < 0) | ||
86 | bb_error_msg_and_die("invalid byte or field list"); | ||
87 | |||
88 | /* account for the fact that arrays are zero based, while the user | ||
89 | * expects the first char on the line to be char # 1 */ | ||
90 | if (s != 0) | ||
91 | s--; | ||
92 | } | ||
93 | |||
94 | /* get the end pos */ | ||
95 | ntok = strsep(<ok, "-"); | ||
96 | if (ntok == NULL) { | ||
97 | e = NON_RANGE; | ||
98 | } else if (strlen(ntok) == 0) { | ||
99 | e = EOL; | ||
100 | } else { | ||
101 | e = strtoul(ntok, &junk, 10); | ||
102 | if(*junk != '\0' || e < 0) | ||
103 | bb_error_msg_and_die("invalid byte or field list"); | ||
104 | /* if the user specified and end position of 0, that means "til the | ||
105 | * end of the line */ | ||
106 | if (e == 0) | ||
107 | e = INT_MAX; | ||
108 | e--; /* again, arrays are zero based, lines are 1 based */ | ||
109 | if (e == s) | ||
110 | e = NON_RANGE; | ||
111 | } | ||
112 | |||
113 | /* if there's something left to tokenize, the user past an invalid list */ | ||
114 | if (ltok) | ||
115 | bb_error_msg_and_die("invalid byte or field list"); | ||
116 | |||
117 | /* add the new list */ | ||
118 | cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists)); | ||
119 | cut_lists[nlists-1].startpos = s; | ||
120 | cut_lists[nlists-1].endpos = e; | ||
121 | } | ||
122 | |||
123 | /* make sure we got some cut positions out of all that */ | ||
124 | if (nlists == 0) | ||
125 | bb_error_msg_and_die("missing list of positions"); | ||
126 | |||
127 | /* now that the lists are parsed, we need to sort them to make life easier | ||
128 | * on us when it comes time to print the chars / fields / lines */ | ||
129 | qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc); | ||
130 | 53 | ||
131 | } | 54 | /* go through every line in the file */ |
55 | while ((line = bb_get_chomped_line_from_file(file)) != NULL) { | ||
132 | 56 | ||
57 | /* set up a list so we can keep track of what's been printed */ | ||
58 | char * printed = xzalloc(strlen(line) * sizeof(char)); | ||
59 | char * orig_line = line; | ||
60 | unsigned int cl_pos = 0; | ||
61 | int spos; | ||
133 | 62 | ||
134 | static void cut_line_by_chars(const char *line) | 63 | /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ |
135 | { | 64 | if ((opt & (CUT_OPT_CHAR_FLGS | CUT_OPT_BYTE_FLGS))) { |
136 | int c, l; | 65 | /* print the chars specified in each cut list */ |
137 | /* set up a list so we can keep track of what's been printed */ | 66 | for (; cl_pos < nlists; cl_pos++) { |
138 | char *printed = xzalloc(strlen(line)); | 67 | spos = cut_lists[cl_pos].startpos; |
139 | 68 | while (spos < strlen(line)) { | |
140 | /* print the chars specified in each cut list */ | 69 | if (!printed[spos]) { |
141 | for (c = 0; c < nlists; c++) { | 70 | printed[spos] = 'X'; |
142 | l = cut_lists[c].startpos; | 71 | putchar(line[spos]); |
143 | while (l < strlen(line)) { | 72 | } |
144 | if (!printed[l]) { | 73 | spos++; |
145 | putchar(line[l]); | 74 | if (spos > cut_lists[cl_pos].endpos |
146 | printed[l] = 'X'; | 75 | || cut_lists[cl_pos].endpos == NON_RANGE) |
76 | break; | ||
77 | } | ||
78 | } | ||
79 | } else if (delim == '\n') { /* cut by lines */ | ||
80 | spos = cut_lists[cl_pos].startpos; | ||
81 | |||
82 | /* get out if we have no more lists to process or if the lines | ||
83 | * are lower than what we're interested in */ | ||
84 | if (linenum < spos || cl_pos >= nlists) | ||
85 | goto next_line; | ||
86 | |||
87 | /* if the line we're looking for is lower than the one we were | ||
88 | * passed, it means we displayed it already, so move on */ | ||
89 | while (spos < linenum) { | ||
90 | spos++; | ||
91 | /* go to the next list if we're at the end of this one */ | ||
92 | if (spos > cut_lists[cl_pos].endpos | ||
93 | || cut_lists[cl_pos].endpos == NON_RANGE) { | ||
94 | cl_pos++; | ||
95 | /* get out if there's no more lists to process */ | ||
96 | if (cl_pos >= nlists) | ||
97 | goto next_line; | ||
98 | spos = cut_lists[cl_pos].startpos; | ||
99 | /* get out if the current line is lower than the one | ||
100 | * we just became interested in */ | ||
101 | if (linenum < spos) | ||
102 | goto next_line; | ||
103 | } | ||
147 | } | 104 | } |
148 | l++; | ||
149 | if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos) | ||
150 | break; | ||
151 | } | ||
152 | } | ||
153 | putchar('\n'); /* cuz we were handed a chomped line */ | ||
154 | free(printed); | ||
155 | } | ||
156 | |||
157 | 105 | ||
158 | static void cut_line_by_fields(char *line) | 106 | /* If we made it here, it means we've found the line we're |
159 | { | 107 | * looking for, so print it */ |
160 | int c, f; | ||
161 | int ndelim = -1; /* zero-based / one-based problem */ | ||
162 | int nfields_printed = 0; | ||
163 | char *field = NULL; | ||
164 | char d[2] = { delim, 0 }; | ||
165 | char *printed; | ||
166 | |||
167 | /* test the easy case first: does this line contain any delimiters? */ | ||
168 | if (strchr(line, delim) == NULL) { | ||
169 | if (!supress_non_delimited_lines) | ||
170 | puts(line); | 108 | puts(line); |
171 | return; | 109 | goto next_line; |
172 | } | 110 | } else { /* cut by fields */ |
173 | 111 | int ndelim = -1; /* zero-based / one-based problem */ | |
174 | /* set up a list so we can keep track of what's been printed */ | 112 | int nfields_printed = 0; |
175 | printed = xzalloc(strlen(line)); | 113 | char *field = NULL; |
176 | 114 | const char delimiter[2] = { delim, 0 }; | |
177 | /* process each list on this line, for as long as we've got a line to process */ | 115 | |
178 | for (c = 0; c < nlists && line; c++) { | 116 | /* does this line contain any delimiters? */ |
179 | f = cut_lists[c].startpos; | 117 | if (strchr(line, delim) == NULL) { |
180 | do { | 118 | if (!(opt & CUT_OPT_SUPPRESS_FLGS)) |
181 | 119 | puts(line); | |
182 | /* find the field we're looking for */ | 120 | goto next_line; |
183 | while (line && ndelim < f) { | ||
184 | field = strsep(&line, d); | ||
185 | ndelim++; | ||
186 | } | 121 | } |
187 | 122 | ||
188 | /* we found it, and it hasn't been printed yet */ | 123 | /* process each list on this line, for as long as we've got |
189 | if (field && ndelim == f && !printed[ndelim]) { | 124 | * a line to process */ |
190 | /* if this isn't our first time through, we need to print the | 125 | for (; cl_pos < nlists && line; cl_pos++) { |
191 | * delimiter after the last field that was printed */ | 126 | spos = cut_lists[cl_pos].startpos; |
192 | if (nfields_printed > 0) | 127 | do { |
193 | putchar(delim); | 128 | |
194 | fputs(field, stdout); | 129 | /* find the field we're looking for */ |
195 | printed[ndelim] = 'X'; | 130 | while (line && ndelim < spos) { |
196 | nfields_printed++; | 131 | field = strsep(&line, delimiter); |
132 | ndelim++; | ||
133 | } | ||
134 | |||
135 | /* we found it, and it hasn't been printed yet */ | ||
136 | if (field && ndelim == spos && !printed[ndelim]) { | ||
137 | /* if this isn't our first time through, we need to | ||
138 | * print the delimiter after the last field that was | ||
139 | * printed */ | ||
140 | if (nfields_printed > 0) | ||
141 | putchar(delim); | ||
142 | fputs(field, stdout); | ||
143 | printed[ndelim] = 'X'; | ||
144 | nfields_printed++; /* shouldn't overflow.. */ | ||
145 | } | ||
146 | |||
147 | spos++; | ||
148 | |||
149 | /* keep going as long as we have a line to work with, | ||
150 | * this is a list, and we're not at the end of that | ||
151 | * list */ | ||
152 | } while (spos <= cut_lists[cl_pos].endpos && line | ||
153 | && cut_lists[cl_pos].endpos != NON_RANGE); | ||
197 | } | 154 | } |
198 | |||
199 | f++; | ||
200 | |||
201 | /* keep going as long as we have a line to work with, this is a | ||
202 | * list, and we're not at the end of that list */ | ||
203 | } while (line && cut_lists[c].endpos != NON_RANGE && f <= cut_lists[c].endpos); | ||
204 | } | ||
205 | |||
206 | /* if we printed anything at all, we need to finish it with a newline cuz | ||
207 | * we were handed a chomped line */ | ||
208 | putchar('\n'); | ||
209 | |||
210 | free(printed); | ||
211 | } | ||
212 | |||
213 | |||
214 | static void cut_file_by_lines(const char *line, unsigned int linenum) | ||
215 | { | ||
216 | static int c = 0; | ||
217 | static int l = -1; | ||
218 | |||
219 | /* I can't initialize this above cuz the "initializer isn't | ||
220 | * constant" *sigh* */ | ||
221 | if (l == -1) | ||
222 | l = cut_lists[c].startpos; | ||
223 | |||
224 | /* get out if we have no more lists to process or if the lines are lower | ||
225 | * than what we're interested in */ | ||
226 | if (c >= nlists || linenum < l) | ||
227 | return; | ||
228 | |||
229 | /* if the line we're looking for is lower than the one we were passed, it | ||
230 | * means we displayed it already, so move on */ | ||
231 | while (l < linenum) { | ||
232 | l++; | ||
233 | /* move on to the next list if we're at the end of this one */ | ||
234 | if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos) { | ||
235 | c++; | ||
236 | /* get out if there's no more lists to process */ | ||
237 | if (c >= nlists) | ||
238 | return; | ||
239 | l = cut_lists[c].startpos; | ||
240 | /* get out if the current line is lower than the one we just became | ||
241 | * interested in */ | ||
242 | if (linenum < l) | ||
243 | return; | ||
244 | } | 155 | } |
156 | /* if we printed anything at all, we need to finish it with a | ||
157 | * newline cuz we were handed a chomped line */ | ||
158 | putchar('\n'); | ||
159 | next_line: | ||
160 | linenum++; | ||
161 | free(printed); | ||
162 | free(orig_line); | ||
245 | } | 163 | } |
246 | |||
247 | /* If we made it here, it means we've found the line we're looking for, so print it */ | ||
248 | puts(line); | ||
249 | } | 164 | } |
250 | 165 | ||
251 | 166 | static int getval(char *ntok) | |
252 | /* | ||
253 | * snippy-snip | ||
254 | */ | ||
255 | static void cut_file(FILE *file) | ||
256 | { | 167 | { |
257 | char *line = NULL; | 168 | char *junk; |
258 | unsigned int linenum = 0; /* keep these zero-based to be consistent */ | 169 | int i = strtoul(ntok, &junk, 10); |
259 | |||
260 | /* go through every line in the file */ | ||
261 | while ((line = bb_get_chomped_line_from_file(file)) != NULL) { | ||
262 | |||
263 | /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ | ||
264 | if ((part & (OPT_CHAR_FLGS | OPT_BYTE_FLGS))) | ||
265 | cut_line_by_chars(line); | ||
266 | |||
267 | /* cut based on fields */ | ||
268 | else { | ||
269 | if (delim == '\n') | ||
270 | cut_file_by_lines(line, linenum); | ||
271 | else | ||
272 | cut_line_by_fields(line); | ||
273 | } | ||
274 | 170 | ||
275 | linenum++; | 171 | if (*junk != '\0' || i < 0) |
276 | free(line); | 172 | bb_error_msg_and_die("invalid byte or field list"); |
277 | } | 173 | return i; |
278 | } | 174 | } |
279 | 175 | ||
176 | static const char * const _op_on_field = " only when operating on fields"; | ||
280 | 177 | ||
281 | int cut_main(int argc, char **argv) | 178 | int cut_main(int argc, char **argv) |
282 | { | 179 | { |
283 | unsigned long opt; | 180 | char *sopt, *ltok; |
284 | char *sopt, *sdopt; | ||
285 | 181 | ||
286 | bb_opt_complementally = "b--bcf:c--bcf:f--bcf"; | 182 | bb_opt_complementally = "b--bcf:c--bcf:f--bcf"; |
287 | opt = bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, &sdopt); | 183 | opt = |
288 | part = opt & (OPT_BYTE_FLGS|OPT_CHAR_FLGS|OPT_FIELDS_FLGS); | 184 | bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, <ok); |
289 | if(part == 0) | 185 | if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS))) |
290 | bb_error_msg_and_die("you must specify a list of bytes, characters, or fields"); | 186 | bb_error_msg_and_die |
291 | if(opt & BB_GETOPT_ERROR) | 187 | ("expected a list of bytes, characters, or fields"); |
188 | if (opt & BB_GETOPT_ERROR) | ||
292 | bb_error_msg_and_die("only one type of list may be specified"); | 189 | bb_error_msg_and_die("only one type of list may be specified"); |
293 | parse_lists(sopt); | 190 | |
294 | if((opt & (OPT_DELIM_FLGS))) { | 191 | if ((opt & (CUT_OPT_DELIM_FLGS))) { |
295 | if (strlen(sdopt) > 1) { | 192 | if (strlen(ltok) > 1) { |
296 | bb_error_msg_and_die("the delimiter must be a single character"); | 193 | bb_error_msg_and_die("the delimiter must be a single character"); |
297 | } | 194 | } |
298 | delim = sdopt[0]; | 195 | delim = ltok[0]; |
299 | } | 196 | } |
300 | supress_non_delimited_lines = opt & OPT_SUPRESS_FLGS; | ||
301 | 197 | ||
302 | /* non-field (char or byte) cutting has some special handling */ | 198 | /* non-field (char or byte) cutting has some special handling */ |
303 | if (part != OPT_FIELDS_FLGS) { | 199 | if (!(opt & CUT_OPT_FIELDS_FLGS)) { |
304 | if (supress_non_delimited_lines) { | 200 | if (opt & CUT_OPT_SUPPRESS_FLGS) { |
305 | bb_error_msg_and_die("suppressing non-delimited lines makes sense" | 201 | bb_error_msg_and_die |
306 | " only when operating on fields"); | 202 | ("suppressing non-delimited lines makes sense%s", |
203 | _op_on_field); | ||
307 | } | 204 | } |
308 | if (delim != '\t') { | 205 | if (delim != '\t') { |
309 | bb_error_msg_and_die("a delimiter may be specified only when operating on fields"); | 206 | bb_error_msg_and_die |
207 | ("a delimiter may be specified%s", _op_on_field); | ||
310 | } | 208 | } |
311 | } | 209 | } |
312 | 210 | ||
211 | /* | ||
212 | * parse list and put values into startpos and endpos. | ||
213 | * valid list formats: N, N-, N-M, -M | ||
214 | * more than one list can be separated by commas | ||
215 | */ | ||
216 | { | ||
217 | char *ntok; | ||
218 | int s = 0, e = 0; | ||
219 | |||
220 | /* take apart the lists, one by one (they are separated with commas */ | ||
221 | while ((ltok = strsep(&sopt, ",")) != NULL) { | ||
222 | |||
223 | /* it's actually legal to pass an empty list */ | ||
224 | if (strlen(ltok) == 0) | ||
225 | continue; | ||
226 | |||
227 | /* get the start pos */ | ||
228 | ntok = strsep(<ok, "-"); | ||
229 | if (ntok == NULL) { | ||
230 | bb_error_msg | ||
231 | ("internal error: ntok is null for start pos!?\n"); | ||
232 | } else if (strlen(ntok) == 0) { | ||
233 | s = BOL; | ||
234 | } else { | ||
235 | s = getval(ntok); | ||
236 | /* account for the fact that arrays are zero based, while | ||
237 | * the user expects the first char on the line to be char #1 */ | ||
238 | if (s != 0) | ||
239 | s--; | ||
240 | } | ||
241 | |||
242 | /* get the end pos */ | ||
243 | ntok = strsep(<ok, "-"); | ||
244 | if (ntok == NULL) { | ||
245 | e = NON_RANGE; | ||
246 | } else if (strlen(ntok) == 0) { | ||
247 | e = EOL; | ||
248 | } else { | ||
249 | e = getval(ntok); | ||
250 | /* if the user specified and end position of 0, that means "til the | ||
251 | * end of the line */ | ||
252 | if (e == 0) | ||
253 | e = EOL; | ||
254 | e--; /* again, arrays are zero based, lines are 1 based */ | ||
255 | if (e == s) | ||
256 | e = NON_RANGE; | ||
257 | } | ||
258 | |||
259 | /* if there's something left to tokenize, the user passed | ||
260 | * an invalid list */ | ||
261 | if (ltok) | ||
262 | bb_error_msg_and_die("invalid byte or field list"); | ||
263 | |||
264 | /* add the new list */ | ||
265 | cut_lists = | ||
266 | xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists)); | ||
267 | cut_lists[nlists - 1].startpos = s; | ||
268 | cut_lists[nlists - 1].endpos = e; | ||
269 | } | ||
270 | |||
271 | /* make sure we got some cut positions out of all that */ | ||
272 | if (nlists == 0) | ||
273 | bb_error_msg_and_die("missing list of positions"); | ||
274 | |||
275 | /* now that the lists are parsed, we need to sort them to make life | ||
276 | * easier on us when it comes time to print the chars / fields / lines | ||
277 | */ | ||
278 | qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc); | ||
279 | } | ||
280 | |||
313 | /* argv[(optind)..(argc-1)] should be names of file to process. If no | 281 | /* argv[(optind)..(argc-1)] should be names of file to process. If no |
314 | * files were specified or '-' was specified, take input from stdin. | 282 | * files were specified or '-' was specified, take input from stdin. |
315 | * Otherwise, we process all the files specified. */ | 283 | * Otherwise, we process all the files specified. */ |
316 | if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) { | 284 | if (argv[optind] == NULL |
285 | || (argv[optind][0] == '-' && argv[optind][1] == '\0')) { | ||
317 | cut_file(stdin); | 286 | cut_file(stdin); |
318 | } | 287 | } else { |
319 | else { | ||
320 | int i; | ||
321 | FILE *file; | 288 | FILE *file; |
322 | for (i = optind; i < argc; i++) { | 289 | |
323 | file = bb_wfopen(argv[i], "r"); | 290 | for (; optind < argc; optind++) { |
324 | if(file) { | 291 | file = bb_wfopen(argv[optind], "r"); |
292 | if (file) { | ||
325 | cut_file(file); | 293 | cut_file(file); |
326 | fclose(file); | 294 | fclose(file); |
327 | } | 295 | } |
328 | } | 296 | } |
329 | } | 297 | } |
330 | 298 | if (ENABLE_FEATURE_CLEAN_UP) | |
299 | free(cut_lists); | ||
331 | return EXIT_SUCCESS; | 300 | return EXIT_SUCCESS; |
332 | } | 301 | } |
diff --git a/coreutils/date.c b/coreutils/date.c index f08392ec2..2a82e0413 100644 --- a/coreutils/date.c +++ b/coreutils/date.c | |||
@@ -5,14 +5,17 @@ | |||
5 | * by Matthew Grant <grantma@anathoth.gen.nz> | 5 | * by Matthew Grant <grantma@anathoth.gen.nz> |
6 | * | 6 | * |
7 | * iso-format handling added by Robert Griebl <griebl@gmx.de> | 7 | * iso-format handling added by Robert Griebl <griebl@gmx.de> |
8 | * bugfixes and cleanup by Bernhard Fischer | ||
8 | * | 9 | * |
9 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 10 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
10 | */ | 11 | */ |
11 | 12 | ||
13 | #include "busybox.h" | ||
14 | |||
12 | /* This 'date' command supports only 2 time setting formats, | 15 | /* This 'date' command supports only 2 time setting formats, |
13 | all the GNU strftime stuff (its in libc, lets use it), | 16 | all the GNU strftime stuff (its in libc, lets use it), |
14 | setting time using UTC and displaying int, as well as | 17 | setting time using UTC and displaying it, as well as |
15 | an RFC 822 complient date output for shell scripting | 18 | an RFC 2822 compliant date output for shell scripting |
16 | mail commands */ | 19 | mail commands */ |
17 | 20 | ||
18 | /* Input parsing code is always bulky - used heavy duty libc stuff as | 21 | /* Input parsing code is always bulky - used heavy duty libc stuff as |
@@ -20,13 +23,6 @@ | |||
20 | 23 | ||
21 | /* Default input handling to save surprising some people */ | 24 | /* Default input handling to save surprising some people */ |
22 | 25 | ||
23 | #include <stdlib.h> | ||
24 | #include <errno.h> | ||
25 | #include <unistd.h> | ||
26 | #include <time.h> | ||
27 | #include <stdio.h> | ||
28 | #include <string.h> | ||
29 | #include "busybox.h" | ||
30 | 26 | ||
31 | #define DATE_OPT_RFC2822 0x01 | 27 | #define DATE_OPT_RFC2822 0x01 |
32 | #define DATE_OPT_SET 0x02 | 28 | #define DATE_OPT_SET 0x02 |
@@ -36,119 +32,45 @@ | |||
36 | #define DATE_OPT_TIMESPEC 0x20 | 32 | #define DATE_OPT_TIMESPEC 0x20 |
37 | #define DATE_OPT_HINT 0x40 | 33 | #define DATE_OPT_HINT 0x40 |
38 | 34 | ||
39 | 35 | static void maybe_set_utc(int opt) | |
40 | static struct tm *date_conv_time(struct tm *tm_time, const char *t_string) | ||
41 | { | ||
42 | int nr; | ||
43 | char *cp; | ||
44 | |||
45 | nr = sscanf(t_string, "%2d%2d%2d%2d%d", &(tm_time->tm_mon), | ||
46 | &(tm_time->tm_mday), &(tm_time->tm_hour), &(tm_time->tm_min), | ||
47 | &(tm_time->tm_year)); | ||
48 | |||
49 | if (nr < 4 || nr > 5) { | ||
50 | bb_error_msg_and_die(bb_msg_invalid_date, t_string); | ||
51 | } | ||
52 | |||
53 | cp = strchr(t_string, '.'); | ||
54 | if (cp) { | ||
55 | nr = sscanf(cp + 1, "%2d", &(tm_time->tm_sec)); | ||
56 | if (nr != 1) { | ||
57 | bb_error_msg_and_die(bb_msg_invalid_date, t_string); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | /* correct for century - minor Y2K problem here? */ | ||
62 | if (tm_time->tm_year >= 1900) { | ||
63 | tm_time->tm_year -= 1900; | ||
64 | } | ||
65 | /* adjust date */ | ||
66 | tm_time->tm_mon -= 1; | ||
67 | |||
68 | return (tm_time); | ||
69 | |||
70 | } | ||
71 | |||
72 | |||
73 | /* The new stuff for LRP */ | ||
74 | |||
75 | static struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string) | ||
76 | { | 36 | { |
77 | struct tm t; | 37 | if ((opt & DATE_OPT_UTC) && putenv("TZ=UTC0") != 0) |
78 | 38 | bb_error_msg_and_die(bb_msg_memory_exhausted); | |
79 | /* Parse input and assign appropriately to tm_time */ | ||
80 | |||
81 | if (t = *tm_time, sscanf(t_string, "%d:%d:%d", &t.tm_hour, &t.tm_min, | ||
82 | &t.tm_sec) == 3) { | ||
83 | /* no adjustments needed */ | ||
84 | } else if (t = *tm_time, sscanf(t_string, "%d:%d", &t.tm_hour, | ||
85 | &t.tm_min) == 2) { | ||
86 | /* no adjustments needed */ | ||
87 | } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d:%d", &t.tm_mon, | ||
88 | &t.tm_mday, &t.tm_hour, | ||
89 | &t.tm_min, &t.tm_sec) == 5) { | ||
90 | /* Adjust dates from 1-12 to 0-11 */ | ||
91 | t.tm_mon -= 1; | ||
92 | } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d", &t.tm_mon, | ||
93 | &t.tm_mday, | ||
94 | &t.tm_hour, &t.tm_min) == 4) { | ||
95 | /* Adjust dates from 1-12 to 0-11 */ | ||
96 | t.tm_mon -= 1; | ||
97 | } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d:%d", &t.tm_year, | ||
98 | &t.tm_mon, &t.tm_mday, | ||
99 | &t.tm_hour, &t.tm_min, | ||
100 | &t.tm_sec) == 6) { | ||
101 | t.tm_year -= 1900; /* Adjust years */ | ||
102 | t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
103 | } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d", &t.tm_year, | ||
104 | &t.tm_mon, &t.tm_mday, | ||
105 | &t.tm_hour, &t.tm_min) == 5) { | ||
106 | t.tm_year -= 1900; /* Adjust years */ | ||
107 | t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
108 | } else { | ||
109 | bb_error_msg_and_die(bb_msg_invalid_date, t_string); | ||
110 | } | ||
111 | *tm_time = t; | ||
112 | return (tm_time); | ||
113 | } | 39 | } |
114 | 40 | ||
115 | int date_main(int argc, char **argv) | 41 | int date_main(int argc, char **argv) |
116 | { | 42 | { |
117 | char *date_str = NULL; | ||
118 | char *date_fmt = NULL; | ||
119 | int set_time; | ||
120 | int utc; | ||
121 | time_t tm; | 43 | time_t tm; |
122 | unsigned long opt; | ||
123 | struct tm tm_time; | 44 | struct tm tm_time; |
45 | unsigned long opt; | ||
46 | int ifmt = -1; | ||
47 | char *date_str = NULL; | ||
48 | char *date_fmt = NULL; | ||
124 | char *filename = NULL; | 49 | char *filename = NULL; |
125 | |||
126 | int ifmt = 0; | ||
127 | char *isofmt_arg; | 50 | char *isofmt_arg; |
128 | char *hintfmt_arg; | 51 | char *hintfmt_arg; |
129 | 52 | ||
130 | bb_opt_complementally = "?:d--s:s--d"; | 53 | bb_opt_complementally = "?:d--s:s--d" |
54 | USE_FEATURE_DATE_ISOFMT(":R--I:I--R"); | ||
131 | opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" | 55 | opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" |
132 | USE_FEATURE_DATE_ISOFMT("I::D:"), | 56 | USE_FEATURE_DATE_ISOFMT("I::D:"), |
133 | &date_str, &date_str, &filename | 57 | &date_str, &date_str, &filename |
134 | USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg)); | 58 | USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg)); |
135 | set_time = opt & DATE_OPT_SET; | 59 | maybe_set_utc(opt); |
136 | utc = opt & DATE_OPT_UTC; | ||
137 | if (utc && putenv("TZ=UTC0") != 0) { | ||
138 | bb_error_msg_and_die(bb_msg_memory_exhausted); | ||
139 | } | ||
140 | 60 | ||
141 | if(ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) { | 61 | if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) { |
142 | if (!isofmt_arg) { | 62 | if (!isofmt_arg) { |
143 | ifmt = 1; | 63 | ifmt = 0; /* default is date */ |
144 | } else { | 64 | } else { |
145 | char *isoformats[]={"date","hours","minutes","seconds"}; | 65 | const char * const isoformats[] = |
146 | for(ifmt = 4; ifmt;) | 66 | {"date", "hours", "minutes", "seconds"}; |
147 | if(!strcmp(isofmt_arg,isoformats[--ifmt])) | 67 | |
68 | for (ifmt = 0; ifmt < 4; ifmt++) | ||
69 | if (!strcmp(isofmt_arg, isoformats[ifmt])) { | ||
148 | break; | 70 | break; |
149 | } | 71 | } |
150 | if (!ifmt) { | 72 | if (ifmt == 4) /* parse error */ |
151 | bb_show_usage(); | 73 | bb_show_usage(); |
152 | } | 74 | } |
153 | } | 75 | } |
154 | 76 | ||
@@ -156,18 +78,19 @@ int date_main(int argc, char **argv) | |||
156 | if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) { | 78 | if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) { |
157 | date_fmt = &argv[optind][1]; /* Skip over the '+' */ | 79 | date_fmt = &argv[optind][1]; /* Skip over the '+' */ |
158 | } else if (date_str == NULL) { | 80 | } else if (date_str == NULL) { |
159 | set_time = 1; | 81 | opt |= DATE_OPT_SET; |
160 | date_str = argv[optind]; | 82 | date_str = argv[optind]; |
161 | } | 83 | } |
162 | 84 | ||
163 | /* Now we have parsed all the information except the date format | 85 | /* Now we have parsed all the information except the date format |
164 | which depends on whether the clock is being set or read */ | 86 | which depends on whether the clock is being set or read */ |
165 | 87 | ||
166 | if(filename) { | 88 | if (filename) { |
167 | struct stat statbuf; | 89 | struct stat statbuf; |
168 | xstat(filename,&statbuf); | 90 | xstat(filename, &statbuf); |
169 | tm=statbuf.st_mtime; | 91 | tm = statbuf.st_mtime; |
170 | } else time(&tm); | 92 | } else |
93 | time(&tm); | ||
171 | memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); | 94 | memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); |
172 | /* Zero out fields - take her back to midnight! */ | 95 | /* Zero out fields - take her back to midnight! */ |
173 | if (date_str != NULL) { | 96 | if (date_str != NULL) { |
@@ -179,9 +102,64 @@ int date_main(int argc, char **argv) | |||
179 | if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) { | 102 | if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) { |
180 | strptime(date_str, hintfmt_arg, &tm_time); | 103 | strptime(date_str, hintfmt_arg, &tm_time); |
181 | } else if (strchr(date_str, ':') != NULL) { | 104 | } else if (strchr(date_str, ':') != NULL) { |
182 | date_conv_ftime(&tm_time, date_str); | 105 | /* Parse input and assign appropriately to tm_time */ |
106 | |||
107 | if (sscanf(date_str, "%d:%d:%d", &tm_time.tm_hour, &tm_time.tm_min, | ||
108 | &tm_time.tm_sec) == 3) { | ||
109 | /* no adjustments needed */ | ||
110 | } else if (sscanf(date_str, "%d:%d", &tm_time.tm_hour, | ||
111 | &tm_time.tm_min) == 2) { | ||
112 | /* no adjustments needed */ | ||
113 | } else if (sscanf(date_str, "%d.%d-%d:%d:%d", &tm_time.tm_mon, | ||
114 | &tm_time.tm_mday, &tm_time.tm_hour, | ||
115 | &tm_time.tm_min, &tm_time.tm_sec) == 5) { | ||
116 | /* Adjust dates from 1-12 to 0-11 */ | ||
117 | tm_time.tm_mon -= 1; | ||
118 | } else if (sscanf(date_str, "%d.%d-%d:%d", &tm_time.tm_mon, | ||
119 | &tm_time.tm_mday, | ||
120 | &tm_time.tm_hour, &tm_time.tm_min) == 4) { | ||
121 | /* Adjust dates from 1-12 to 0-11 */ | ||
122 | tm_time.tm_mon -= 1; | ||
123 | } else if (sscanf(date_str, "%d.%d.%d-%d:%d:%d", &tm_time.tm_year, | ||
124 | &tm_time.tm_mon, &tm_time.tm_mday, | ||
125 | &tm_time.tm_hour, &tm_time.tm_min, | ||
126 | &tm_time.tm_sec) == 6) { | ||
127 | tm_time.tm_year -= 1900; /* Adjust years */ | ||
128 | tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
129 | } else if (sscanf(date_str, "%d.%d.%d-%d:%d", &tm_time.tm_year, | ||
130 | &tm_time.tm_mon, &tm_time.tm_mday, | ||
131 | &tm_time.tm_hour, &tm_time.tm_min) == 5) { | ||
132 | tm_time.tm_year -= 1900; /* Adjust years */ | ||
133 | tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | ||
134 | } else { | ||
135 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); | ||
136 | } | ||
183 | } else { | 137 | } else { |
184 | date_conv_time(&tm_time, date_str); | 138 | int nr; |
139 | char *cp; | ||
140 | |||
141 | nr = sscanf(date_str, "%2d%2d%2d%2d%d", &tm_time.tm_mon, | ||
142 | &tm_time.tm_mday, &tm_time.tm_hour, &tm_time.tm_min, | ||
143 | &tm_time.tm_year); | ||
144 | |||
145 | if (nr < 4 || nr > 5) { | ||
146 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); | ||
147 | } | ||
148 | |||
149 | cp = strchr(date_str, '.'); | ||
150 | if (cp) { | ||
151 | nr = sscanf(cp + 1, "%2d", &tm_time.tm_sec); | ||
152 | if (nr != 1) { | ||
153 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | /* correct for century - minor Y2K problem here? */ | ||
158 | if (tm_time.tm_year >= 1900) { | ||
159 | tm_time.tm_year -= 1900; | ||
160 | } | ||
161 | /* adjust date */ | ||
162 | tm_time.tm_mon -= 1; | ||
185 | } | 163 | } |
186 | 164 | ||
187 | /* Correct any day of week and day of year etc. fields */ | 165 | /* Correct any day of week and day of year etc. fields */ |
@@ -190,12 +168,10 @@ int date_main(int argc, char **argv) | |||
190 | if (tm < 0) { | 168 | if (tm < 0) { |
191 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); | 169 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); |
192 | } | 170 | } |
193 | if (utc && putenv("TZ=UTC0") != 0) { | 171 | maybe_set_utc(opt); |
194 | bb_error_msg_and_die(bb_msg_memory_exhausted); | ||
195 | } | ||
196 | 172 | ||
197 | /* if setting time, set it */ | 173 | /* if setting time, set it */ |
198 | if (set_time && stime(&tm) < 0) { | 174 | if ((opt & DATE_OPT_SET) && stime(&tm) < 0) { |
199 | bb_perror_msg("cannot set date"); | 175 | bb_perror_msg("cannot set date"); |
200 | } | 176 | } |
201 | } | 177 | } |
@@ -203,33 +179,43 @@ int date_main(int argc, char **argv) | |||
203 | /* Display output */ | 179 | /* Display output */ |
204 | 180 | ||
205 | /* Deal with format string */ | 181 | /* Deal with format string */ |
182 | |||
206 | if (date_fmt == NULL) { | 183 | if (date_fmt == NULL) { |
207 | /* Start with the default case */ | 184 | int i; |
208 | 185 | date_fmt = xzalloc(32); | |
209 | date_fmt = (opt & DATE_OPT_RFC2822 ? | 186 | if (ENABLE_FEATURE_DATE_ISOFMT && ifmt >= 0) { |
210 | (utc ? "%a, %d %b %Y %H:%M:%S GMT" : | 187 | strcpy(date_fmt, "%Y-%m-%d"); |
211 | "%a, %d %b %Y %H:%M:%S %z") : | 188 | if (ifmt > 0) { |
212 | "%a %b %e %H:%M:%S %Z %Y"); | 189 | i = 8; |
213 | 190 | date_fmt[i++] = 'T'; | |
214 | if (ENABLE_FEATURE_DATE_ISOFMT) { | 191 | date_fmt[i++] = '%'; |
215 | if (ifmt == 4) | 192 | date_fmt[i++] = 'H'; |
216 | date_fmt = utc ? "%Y-%m-%dT%H:%M:%SZ" : "%Y-%m-%dT%H:%M:%S%z"; | 193 | if (ifmt > 1) { |
217 | else if (ifmt == 3) | 194 | date_fmt[i++] = ':'; |
218 | date_fmt = utc ? "%Y-%m-%dT%H:%MZ" : "%Y-%m-%dT%H:%M%z"; | 195 | date_fmt[i++] = '%'; |
219 | else if (ifmt == 2) | 196 | date_fmt[i++] = 'M'; |
220 | date_fmt = utc ? "%Y-%m-%dT%HZ" : "%Y-%m-%dT%H%z"; | 197 | } |
221 | else if (ifmt == 1) | 198 | if (ifmt > 2) { |
222 | date_fmt = "%Y-%m-%d"; | 199 | date_fmt[i++] = ':'; |
223 | } | 200 | date_fmt[i++] = '%'; |
201 | date_fmt[i++] = 'S'; | ||
202 | } | ||
203 | format_utc: | ||
204 | date_fmt[i++] = '%'; | ||
205 | date_fmt[i] = (opt & DATE_OPT_UTC) ? 'Z' : 'z'; | ||
206 | } | ||
207 | } else if (opt & DATE_OPT_RFC2822) { | ||
208 | strcpy(date_fmt, "%a, %d %b %Y %H:%M:%S "); | ||
209 | i = 22; | ||
210 | goto format_utc; | ||
211 | } else /* default case */ | ||
212 | date_fmt = "%a %b %e %H:%M:%S %Z %Y"; | ||
224 | } | 213 | } |
225 | |||
226 | if (*date_fmt == '\0') { | ||
227 | 214 | ||
215 | if (*date_fmt == '\0') { | ||
228 | /* With no format string, just print a blank line */ | 216 | /* With no format string, just print a blank line */ |
229 | 217 | *bb_common_bufsiz1 = 0; | |
230 | *bb_common_bufsiz1=0; | ||
231 | } else { | 218 | } else { |
232 | |||
233 | /* Handle special conversions */ | 219 | /* Handle special conversions */ |
234 | 220 | ||
235 | if (strncmp(date_fmt, "%f", 2) == 0) { | 221 | if (strncmp(date_fmt, "%f", 2) == 0) { |
diff --git a/coreutils/dd.c b/coreutils/dd.c index 052cd2902..a9536a584 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include "busybox.h" | 11 | #include "busybox.h" |
12 | #include <signal.h> /* For FEATURE_DD_SIGNAL_HANDLING */ | ||
12 | 13 | ||
13 | static const struct suffix_mult dd_suffixes[] = { | 14 | static const struct suffix_mult dd_suffixes[] = { |
14 | { "c", 1 }, | 15 | { "c", 1 }, |
@@ -23,72 +24,72 @@ static const struct suffix_mult dd_suffixes[] = { | |||
23 | { NULL, 0 } | 24 | { NULL, 0 } |
24 | }; | 25 | }; |
25 | 26 | ||
26 | static size_t out_full; | 27 | static size_t out_full, out_part, in_full, in_part; |
27 | static size_t out_part; | ||
28 | static size_t in_full; | ||
29 | static size_t in_part; | ||
30 | 28 | ||
31 | static void dd_output_status(int cur_signal) | 29 | static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal) |
32 | { | 30 | { |
33 | fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n", | 31 | bb_fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n", |
34 | (long)in_full, (long)in_part, | 32 | (long)in_full, (long)in_part, |
35 | (long)out_full, (long)out_part); | 33 | (long)out_full, (long)out_part); |
36 | } | 34 | } |
37 | 35 | ||
38 | int dd_main(int argc, char **argv) | 36 | int dd_main(int argc, char **argv) |
39 | { | 37 | { |
38 | #define sync_flag (1<<0) | ||
39 | #define noerror (1<<1) | ||
40 | #define trunc_flag (1<<2) | ||
41 | #define twobufs_flag (1<<3) | ||
42 | int flags = trunc_flag; | ||
40 | size_t count = -1, oc = 0, ibs = 512, obs = 512; | 43 | size_t count = -1, oc = 0, ibs = 512, obs = 512; |
41 | ssize_t n; | 44 | ssize_t n; |
42 | off_t seek = 0, skip = 0; | 45 | off_t seek = 0, skip = 0; |
43 | int sync_flag = FALSE, noerror = FALSE, trunc_flag = TRUE, twobufs_flag = 0, | 46 | int oflag, ifd, ofd; |
44 | oflag, ifd, ofd, i; | ||
45 | const char *infile = NULL, *outfile = NULL; | 47 | const char *infile = NULL, *outfile = NULL; |
46 | char *ibuf, *obuf; | 48 | char *ibuf, *obuf; |
47 | 49 | ||
48 | if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) | 50 | if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) { |
49 | { | ||
50 | struct sigaction sa; | 51 | struct sigaction sa; |
51 | 52 | ||
52 | memset(&sa, 0, sizeof(sa)); | 53 | memset(&sa, 0, sizeof(sa)); |
53 | sa.sa_handler = dd_output_status; | 54 | sa.sa_handler = dd_output_status; |
54 | sa.sa_flags = SA_RESTART; | 55 | sa.sa_flags = SA_RESTART; |
55 | sigemptyset(&sa.sa_mask); | 56 | sigemptyset(&sa.sa_mask); |
56 | sigaction(SIGUSR1, &sa, 0); | 57 | sigaction(SIGUSR1, &sa, 0); |
57 | } | 58 | } |
58 | 59 | ||
59 | for (i = 1; i < argc; i++) { | 60 | for (n = 1; n < argc; n++) { |
60 | if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[i], 4)) { | 61 | if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[n], 4)) { |
61 | ibs = bb_xparse_number(argv[i]+4, dd_suffixes); | 62 | ibs = bb_xparse_number(argv[n]+4, dd_suffixes); |
62 | twobufs_flag++; | 63 | flags |= twobufs_flag; |
63 | } else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[i], 4)) { | 64 | } else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[n], 4)) { |
64 | obs = bb_xparse_number(argv[i]+4, dd_suffixes); | 65 | obs = bb_xparse_number(argv[n]+4, dd_suffixes); |
65 | twobufs_flag++; | 66 | flags |= twobufs_flag; |
66 | } else if (!strncmp("bs=", argv[i], 3)) { | 67 | } else if (!strncmp("bs=", argv[n], 3)) |
67 | ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes); | 68 | ibs = obs = bb_xparse_number(argv[n]+3, dd_suffixes); |
68 | } else if (!strncmp("count=", argv[i], 6)) | 69 | else if (!strncmp("count=", argv[n], 6)) |
69 | count = bb_xparse_number(argv[i]+6, dd_suffixes); | 70 | count = bb_xparse_number(argv[n]+6, dd_suffixes); |
70 | else if (!strncmp("seek=", argv[i], 5)) | 71 | else if (!strncmp("seek=", argv[n], 5)) |
71 | seek = bb_xparse_number(argv[i]+5, dd_suffixes); | 72 | seek = bb_xparse_number(argv[n]+5, dd_suffixes); |
72 | else if (!strncmp("skip=", argv[i], 5)) | 73 | else if (!strncmp("skip=", argv[n], 5)) |
73 | skip = bb_xparse_number(argv[i]+5, dd_suffixes); | 74 | skip = bb_xparse_number(argv[n]+5, dd_suffixes); |
74 | else if (!strncmp("if=", argv[i], 3)) | 75 | else if (!strncmp("if=", argv[n], 3)) |
75 | infile = argv[i]+3; | 76 | infile = argv[n]+3; |
76 | else if (!strncmp("of=", argv[i], 3)) | 77 | else if (!strncmp("of=", argv[n], 3)) |
77 | outfile = argv[i]+3; | 78 | outfile = argv[n]+3; |
78 | else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[i], 5)) { | 79 | else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[n], 5)) { |
79 | ibuf = argv[i]+5; | 80 | ibuf = argv[n]+5; |
80 | while (1) { | 81 | while (1) { |
81 | if (!strncmp("notrunc", ibuf, 7)) { | 82 | if (!strncmp("notrunc", ibuf, 7)) { |
82 | trunc_flag = FALSE; | 83 | flags ^= trunc_flag; |
83 | ibuf += 7; | 84 | ibuf += 7; |
84 | } else if (!strncmp("sync", ibuf, 4)) { | 85 | } else if (!strncmp("sync", ibuf, 4)) { |
85 | sync_flag = TRUE; | 86 | flags |= sync_flag; |
86 | ibuf += 4; | 87 | ibuf += 4; |
87 | } else if (!strncmp("noerror", ibuf, 7)) { | 88 | } else if (!strncmp("noerror", ibuf, 7)) { |
88 | noerror = TRUE; | 89 | flags |= noerror; |
89 | ibuf += 7; | 90 | ibuf += 7; |
90 | } else { | 91 | } else { |
91 | bb_error_msg_and_die(bb_msg_invalid_arg, argv[i]+5, "conv"); | 92 | bb_error_msg_and_die(bb_msg_invalid_arg, argv[n]+5, "conv"); |
92 | } | 93 | } |
93 | if (ibuf[0] == '\0') break; | 94 | if (ibuf[0] == '\0') break; |
94 | if (ibuf[0] == ',') ibuf++; | 95 | if (ibuf[0] == ',') ibuf++; |
@@ -98,12 +99,14 @@ int dd_main(int argc, char **argv) | |||
98 | } | 99 | } |
99 | ibuf = xmalloc(ibs); | 100 | ibuf = xmalloc(ibs); |
100 | 101 | ||
101 | if (twobufs_flag) obuf = xmalloc(obs); | 102 | if (flags & twobufs_flag) |
102 | else obuf = ibuf; | 103 | obuf = xmalloc(obs); |
104 | else | ||
105 | obuf = ibuf; | ||
103 | 106 | ||
104 | if (infile != NULL) { | 107 | if (infile != NULL) |
105 | ifd = xopen(infile, O_RDONLY); | 108 | ifd = xopen(infile, O_RDONLY); |
106 | } else { | 109 | else { |
107 | ifd = STDIN_FILENO; | 110 | ifd = STDIN_FILENO; |
108 | infile = bb_msg_standard_input; | 111 | infile = bb_msg_standard_input; |
109 | } | 112 | } |
@@ -111,20 +114,18 @@ int dd_main(int argc, char **argv) | |||
111 | if (outfile != NULL) { | 114 | if (outfile != NULL) { |
112 | oflag = O_WRONLY | O_CREAT; | 115 | oflag = O_WRONLY | O_CREAT; |
113 | 116 | ||
114 | if (!seek && trunc_flag) { | 117 | if (!seek && (flags & trunc_flag)) |
115 | oflag |= O_TRUNC; | 118 | oflag |= O_TRUNC; |
116 | } | ||
117 | 119 | ||
118 | ofd = xopen3(outfile, oflag, 0666); | 120 | ofd = xopen3(outfile, oflag, 0666); |
119 | 121 | ||
120 | if (seek && trunc_flag) { | 122 | if (seek && (flags & trunc_flag)) { |
121 | if (ftruncate(ofd, seek * obs) < 0) { | 123 | if (ftruncate(ofd, seek * obs) < 0) { |
122 | struct stat st; | 124 | struct stat st; |
123 | 125 | ||
124 | if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) || | 126 | if (fstat(ofd, &st) < 0 || S_ISREG(st.st_mode) || |
125 | S_ISDIR (st.st_mode)) { | 127 | S_ISDIR(st.st_mode)) |
126 | bb_perror_msg_and_die("%s", outfile); | 128 | goto die_outfile; |
127 | } | ||
128 | } | 129 | } |
129 | } | 130 | } |
130 | } else { | 131 | } else { |
@@ -145,44 +146,42 @@ int dd_main(int argc, char **argv) | |||
145 | } | 146 | } |
146 | 147 | ||
147 | if (seek) { | 148 | if (seek) { |
148 | if (lseek(ofd, seek * obs, SEEK_CUR) < 0) { | 149 | if (lseek(ofd, seek * obs, SEEK_CUR) < 0) |
149 | bb_perror_msg_and_die("%s", outfile); | 150 | goto die_outfile; |
150 | } | ||
151 | } | 151 | } |
152 | 152 | ||
153 | while (in_full + in_part != count) { | 153 | while (in_full + in_part != count) { |
154 | if (noerror) { | 154 | if (flags & noerror) { |
155 | /* Pre-zero the buffer when doing the noerror thing */ | 155 | /* Pre-zero the buffer when doing the noerror thing */ |
156 | memset(ibuf, '\0', ibs); | 156 | memset(ibuf, '\0', ibs); |
157 | } | 157 | } |
158 | 158 | ||
159 | n = safe_read(ifd, ibuf, ibs); | 159 | n = safe_read(ifd, ibuf, ibs); |
160 | if (n == 0) { | 160 | if (n == 0) |
161 | break; | 161 | break; |
162 | } | ||
163 | if (n < 0) { | 162 | if (n < 0) { |
164 | if (noerror) { | 163 | if (flags & noerror) { |
165 | n = ibs; | 164 | n = ibs; |
166 | bb_perror_msg("%s", infile); | 165 | bb_perror_msg("%s", infile); |
167 | } else { | 166 | } else |
168 | bb_perror_msg_and_die("%s", infile); | 167 | bb_perror_msg_and_die("%s", infile); |
169 | } | ||
170 | } | 168 | } |
171 | if ((size_t)n == ibs) { | 169 | if ((size_t)n == ibs) |
172 | in_full++; | 170 | in_full++; |
173 | } else { | 171 | else { |
174 | in_part++; | 172 | in_part++; |
175 | if (sync_flag) { | 173 | if (sync_flag) { |
176 | memset(ibuf + n, '\0', ibs - n); | 174 | memset(ibuf + n, '\0', ibs - n); |
177 | n = ibs; | 175 | n = ibs; |
178 | } | 176 | } |
179 | } | 177 | } |
180 | if (twobufs_flag) { | 178 | if (flags & twobufs_flag) { |
181 | char *tmp = ibuf; | 179 | char *tmp = ibuf; |
182 | while (n) { | 180 | while (n) { |
183 | size_t d = obs - oc; | 181 | size_t d = obs - oc; |
184 | 182 | ||
185 | if (d > n) d = n; | 183 | if (d > n) |
184 | d = n; | ||
186 | memcpy(obuf + oc, tmp, d); | 185 | memcpy(obuf + oc, tmp, d); |
187 | n -= d; | 186 | n -= d; |
188 | tmp += d; | 187 | tmp += d; |
@@ -195,8 +194,10 @@ int dd_main(int argc, char **argv) | |||
195 | } | 194 | } |
196 | } else { | 195 | } else { |
197 | xwrite(ofd, ibuf, n); | 196 | xwrite(ofd, ibuf, n); |
198 | if (n == ibs) out_full++; | 197 | if (n == ibs) |
199 | else out_part++; | 198 | out_full++; |
199 | else | ||
200 | out_part++; | ||
200 | } | 201 | } |
201 | } | 202 | } |
202 | 203 | ||
@@ -209,6 +210,7 @@ int dd_main(int argc, char **argv) | |||
209 | } | 210 | } |
210 | 211 | ||
211 | if (close (ofd) < 0) { | 212 | if (close (ofd) < 0) { |
213 | die_outfile: | ||
212 | bb_perror_msg_and_die("%s", outfile); | 214 | bb_perror_msg_and_die("%s", outfile); |
213 | } | 215 | } |
214 | 216 | ||
diff --git a/coreutils/du.c b/coreutils/du.c index 29427c779..3cc935553 100644 --- a/coreutils/du.c +++ b/coreutils/du.c | |||
@@ -23,11 +23,6 @@ | |||
23 | * 4) Fixed busybox bug #1284 involving long overflow with human_readable. | 23 | * 4) Fixed busybox bug #1284 involving long overflow with human_readable. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <stdlib.h> | ||
27 | #include <limits.h> | ||
28 | #include <unistd.h> | ||
29 | #include <dirent.h> | ||
30 | #include <sys/stat.h> | ||
31 | #include "busybox.h" | 26 | #include "busybox.h" |
32 | 27 | ||
33 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 28 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
@@ -57,7 +52,7 @@ static int one_file_system; | |||
57 | static dev_t dir_dev; | 52 | static dev_t dir_dev; |
58 | 53 | ||
59 | 54 | ||
60 | static void print(long size, char *filename) | 55 | static void print(long size, const char * const filename) |
61 | { | 56 | { |
62 | /* TODO - May not want to defer error checking here. */ | 57 | /* TODO - May not want to defer error checking here. */ |
63 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 58 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
@@ -73,7 +68,7 @@ static void print(long size, char *filename) | |||
73 | } | 68 | } |
74 | 69 | ||
75 | /* tiny recursive du */ | 70 | /* tiny recursive du */ |
76 | static long du(char *filename) | 71 | static long du(const char * const filename) |
77 | { | 72 | { |
78 | struct stat statbuf; | 73 | struct stat statbuf; |
79 | long sum; | 74 | long sum; |
diff --git a/coreutils/expr.c b/coreutils/expr.c index 0a1baa19d..e7fdc5f1e 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c | |||
@@ -37,11 +37,13 @@ typedef enum valtype TYPE; | |||
37 | 37 | ||
38 | #if ENABLE_EXPR_MATH_SUPPORT_64 | 38 | #if ENABLE_EXPR_MATH_SUPPORT_64 |
39 | typedef int64_t arith_t; | 39 | typedef int64_t arith_t; |
40 | |||
40 | #define PF_REZ "ll" | 41 | #define PF_REZ "ll" |
41 | #define PF_REZ_TYPE (long long) | 42 | #define PF_REZ_TYPE (long long) |
42 | #define STRTOL(s, e, b) strtoll(s, e, b) | 43 | #define STRTOL(s, e, b) strtoll(s, e, b) |
43 | #else | 44 | #else |
44 | typedef long arith_t; | 45 | typedef long arith_t; |
46 | |||
45 | #define PF_REZ "l" | 47 | #define PF_REZ "l" |
46 | #define PF_REZ_TYPE (long) | 48 | #define PF_REZ_TYPE (long) |
47 | #define STRTOL(s, e, b) strtol(s, e, b) | 49 | #define STRTOL(s, e, b) strtol(s, e, b) |
@@ -49,8 +51,8 @@ typedef long arith_t; | |||
49 | 51 | ||
50 | /* A value is.... */ | 52 | /* A value is.... */ |
51 | struct valinfo { | 53 | struct valinfo { |
52 | TYPE type; /* Which kind. */ | 54 | TYPE type; /* Which kind. */ |
53 | union { /* The value itself. */ | 55 | union { /* The value itself. */ |
54 | arith_t i; | 56 | arith_t i; |
55 | char *s; | 57 | char *s; |
56 | } u; | 58 | } u; |
@@ -60,17 +62,17 @@ typedef struct valinfo VALUE; | |||
60 | /* The arguments given to the program, minus the program name. */ | 62 | /* The arguments given to the program, minus the program name. */ |
61 | static char **args; | 63 | static char **args; |
62 | 64 | ||
63 | static VALUE *docolon (VALUE *sv, VALUE *pv); | 65 | static VALUE *docolon(VALUE * sv, VALUE * pv); |
64 | static VALUE *eval (void); | 66 | static VALUE *eval(void); |
65 | static VALUE *int_value (arith_t i); | 67 | static VALUE *int_value(arith_t i); |
66 | static VALUE *str_value (char *s); | 68 | static VALUE *str_value(char *s); |
67 | static int nextarg (char *str); | 69 | static int nextarg(char *str); |
68 | static int null (VALUE *v); | 70 | static int null(VALUE * v); |
69 | static int toarith (VALUE *v); | 71 | static int toarith(VALUE * v); |
70 | static void freev (VALUE *v); | 72 | static void freev(VALUE * v); |
71 | static void tostring (VALUE *v); | 73 | static void tostring(VALUE * v); |
72 | 74 | ||
73 | int expr_main (int argc, char **argv) | 75 | int expr_main(int argc, char **argv) |
74 | { | 76 | { |
75 | VALUE *v; | 77 | VALUE *v; |
76 | 78 | ||
@@ -80,25 +82,25 @@ int expr_main (int argc, char **argv) | |||
80 | 82 | ||
81 | args = argv + 1; | 83 | args = argv + 1; |
82 | 84 | ||
83 | v = eval (); | 85 | v = eval(); |
84 | if (*args) | 86 | if (*args) |
85 | bb_error_msg_and_die ("syntax error"); | 87 | bb_error_msg_and_die("syntax error"); |
86 | 88 | ||
87 | if (v->type == integer) | 89 | if (v->type == integer) |
88 | printf ("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); | 90 | bb_printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); |
89 | else | 91 | else |
90 | puts (v->u.s); | 92 | puts(v->u.s); |
91 | 93 | ||
92 | exit (null (v)); | 94 | exit(null(v)); |
93 | } | 95 | } |
94 | 96 | ||
95 | /* Return a VALUE for I. */ | 97 | /* Return a VALUE for I. */ |
96 | 98 | ||
97 | static VALUE *int_value (arith_t i) | 99 | static VALUE *int_value(arith_t i) |
98 | { | 100 | { |
99 | VALUE *v; | 101 | VALUE *v; |
100 | 102 | ||
101 | v = xmalloc (sizeof(VALUE)); | 103 | v = xmalloc(sizeof(VALUE)); |
102 | v->type = integer; | 104 | v->type = integer; |
103 | v->u.i = i; | 105 | v->u.i = i; |
104 | return v; | 106 | return v; |
@@ -106,7 +108,7 @@ static VALUE *int_value (arith_t i) | |||
106 | 108 | ||
107 | /* Return a VALUE for S. */ | 109 | /* Return a VALUE for S. */ |
108 | 110 | ||
109 | static VALUE *str_value (char *s) | 111 | static VALUE *str_value(char *s) |
110 | { | 112 | { |
111 | VALUE *v; | 113 | VALUE *v; |
112 | 114 | ||
@@ -118,28 +120,26 @@ static VALUE *str_value (char *s) | |||
118 | 120 | ||
119 | /* Free VALUE V, including structure components. */ | 121 | /* Free VALUE V, including structure components. */ |
120 | 122 | ||
121 | static void freev (VALUE *v) | 123 | static void freev(VALUE * v) |
122 | { | 124 | { |
123 | if (v->type == string) | 125 | if (v->type == string) |
124 | free (v->u.s); | 126 | free(v->u.s); |
125 | free (v); | 127 | free(v); |
126 | } | 128 | } |
127 | 129 | ||
128 | /* Return nonzero if V is a null-string or zero-number. */ | 130 | /* Return nonzero if V is a null-string or zero-number. */ |
129 | 131 | ||
130 | static int null (VALUE *v) | 132 | static int null(VALUE * v) |
131 | { | 133 | { |
132 | switch (v->type) { | 134 | if (v->type == integer) |
133 | case integer: | 135 | return v->u.i == 0; |
134 | return v->u.i == 0; | 136 | else /* string: */ |
135 | default: /* string: */ | 137 | return v->u.s[0] == '\0' || strcmp(v->u.s, "0") == 0; |
136 | return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0; | ||
137 | } | ||
138 | } | 138 | } |
139 | 139 | ||
140 | /* Coerce V to a string value (can't fail). */ | 140 | /* Coerce V to a string value (can't fail). */ |
141 | 141 | ||
142 | static void tostring (VALUE *v) | 142 | static void tostring(VALUE * v) |
143 | { | 143 | { |
144 | if (v->type == integer) { | 144 | if (v->type == integer) { |
145 | v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i); | 145 | v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i); |
@@ -149,9 +149,9 @@ static void tostring (VALUE *v) | |||
149 | 149 | ||
150 | /* Coerce V to an integer value. Return 1 on success, 0 on failure. */ | 150 | /* Coerce V to an integer value. Return 1 on success, 0 on failure. */ |
151 | 151 | ||
152 | static int toarith (VALUE *v) | 152 | static int toarith(VALUE * v) |
153 | { | 153 | { |
154 | if(v->type == string) { | 154 | if (v->type == string) { |
155 | arith_t i; | 155 | arith_t i; |
156 | char *e; | 156 | char *e; |
157 | 157 | ||
@@ -160,7 +160,7 @@ static int toarith (VALUE *v) | |||
160 | i = STRTOL(v->u.s, &e, 10); | 160 | i = STRTOL(v->u.s, &e, 10); |
161 | if ((v->u.s == e) || *e) | 161 | if ((v->u.s == e) || *e) |
162 | return 0; | 162 | return 0; |
163 | free (v->u.s); | 163 | free(v->u.s); |
164 | v->u.i = i; | 164 | v->u.i = i; |
165 | v->type = integer; | 165 | v->type = integer; |
166 | } | 166 | } |
@@ -170,221 +170,207 @@ static int toarith (VALUE *v) | |||
170 | /* Return nonzero if the next token matches STR exactly. | 170 | /* Return nonzero if the next token matches STR exactly. |
171 | STR must not be NULL. */ | 171 | STR must not be NULL. */ |
172 | 172 | ||
173 | static int | 173 | static int nextarg(char *str) |
174 | nextarg (char *str) | ||
175 | { | 174 | { |
176 | if (*args == NULL) | 175 | if (*args == NULL) |
177 | return 0; | 176 | return 0; |
178 | return strcmp (*args, str) == 0; | 177 | return strcmp(*args, str) == 0; |
179 | } | 178 | } |
180 | 179 | ||
181 | /* The comparison operator handling functions. */ | 180 | /* The comparison operator handling functions. */ |
182 | 181 | ||
183 | static int cmp_common (VALUE *l, VALUE *r, int op) | 182 | static int cmp_common(VALUE * l, VALUE * r, int op) |
184 | { | 183 | { |
185 | int cmpval; | 184 | int cmpval; |
186 | 185 | ||
187 | if (l->type == string || r->type == string) { | 186 | if (l->type == string || r->type == string) { |
188 | tostring (l); | 187 | tostring(l); |
189 | tostring (r); | 188 | tostring(r); |
190 | cmpval = strcmp (l->u.s, r->u.s); | 189 | cmpval = strcmp(l->u.s, r->u.s); |
191 | } | 190 | } else |
192 | else | ||
193 | cmpval = l->u.i - r->u.i; | 191 | cmpval = l->u.i - r->u.i; |
194 | switch(op) { | 192 | if (op == '<') |
195 | case '<': | 193 | return cmpval < 0; |
196 | return cmpval < 0; | 194 | else if (op == ('L' + 'E')) |
197 | case ('L'+'E'): | 195 | return cmpval <= 0; |
198 | return cmpval <= 0; | 196 | else if (op == '=') |
199 | case '=': | 197 | return cmpval == 0; |
200 | return cmpval == 0; | 198 | else if (op == '!') |
201 | case '!': | 199 | return cmpval != 0; |
202 | return cmpval != 0; | 200 | else if (op == '>') |
203 | case '>': | 201 | return cmpval > 0; |
204 | return cmpval > 0; | 202 | else /* >= */ |
205 | default: /* >= */ | 203 | return cmpval >= 0; |
206 | return cmpval >= 0; | ||
207 | } | ||
208 | } | 204 | } |
209 | 205 | ||
210 | /* The arithmetic operator handling functions. */ | 206 | /* The arithmetic operator handling functions. */ |
211 | 207 | ||
212 | static arith_t arithmetic_common (VALUE *l, VALUE *r, int op) | 208 | static arith_t arithmetic_common(VALUE * l, VALUE * r, int op) |
213 | { | 209 | { |
214 | arith_t li, ri; | 210 | arith_t li, ri; |
215 | 211 | ||
216 | if (!toarith (l) || !toarith (r)) | 212 | if (!toarith(l) || !toarith(r)) |
217 | bb_error_msg_and_die ("non-numeric argument"); | 213 | bb_error_msg_and_die("non-numeric argument"); |
218 | li = l->u.i; | 214 | li = l->u.i; |
219 | ri = r->u.i; | 215 | ri = r->u.i; |
220 | if((op == '/' || op == '%') && ri == 0) | 216 | if ((op == '/' || op == '%') && ri == 0) |
221 | bb_error_msg_and_die ( "division by zero"); | 217 | bb_error_msg_and_die("division by zero"); |
222 | switch(op) { | 218 | if (op == '+') |
223 | case '+': | ||
224 | return li + ri; | 219 | return li + ri; |
225 | case '-': | 220 | else if (op == '-') |
226 | return li - ri; | 221 | return li - ri; |
227 | case '*': | 222 | else if (op == '*') |
228 | return li * ri; | 223 | return li * ri; |
229 | case '/': | 224 | else if (op == '/') |
230 | return li / ri; | 225 | return li / ri; |
231 | default: | 226 | else |
232 | return li % ri; | 227 | return li % ri; |
233 | } | ||
234 | } | 228 | } |
235 | 229 | ||
236 | /* Do the : operator. | 230 | /* Do the : operator. |
237 | SV is the VALUE for the lhs (the string), | 231 | SV is the VALUE for the lhs (the string), |
238 | PV is the VALUE for the rhs (the pattern). */ | 232 | PV is the VALUE for the rhs (the pattern). */ |
239 | 233 | ||
240 | static VALUE *docolon (VALUE *sv, VALUE *pv) | 234 | static VALUE *docolon(VALUE * sv, VALUE * pv) |
241 | { | 235 | { |
242 | VALUE *v; | 236 | VALUE *v; |
243 | regex_t re_buffer; | 237 | regex_t re_buffer; |
244 | const int NMATCH = 2; | 238 | const int NMATCH = 2; |
245 | regmatch_t re_regs[NMATCH]; | 239 | regmatch_t re_regs[NMATCH]; |
246 | 240 | ||
247 | tostring (sv); | 241 | tostring(sv); |
248 | tostring (pv); | 242 | tostring(pv); |
249 | 243 | ||
250 | if (pv->u.s[0] == '^') { | 244 | if (pv->u.s[0] == '^') { |
251 | fprintf (stderr, "\ | 245 | fprintf(stderr, "\ |
252 | warning: unportable BRE: `%s': using `^' as the first character\n\ | 246 | warning: unportable BRE: `%s': using `^' as the first character\n\ |
253 | of a basic regular expression is not portable; it is being ignored", | 247 | of a basic regular expression is not portable; it is being ignored", pv->u.s); |
254 | pv->u.s); | ||
255 | } | 248 | } |
256 | 249 | ||
257 | memset (&re_buffer, 0, sizeof (re_buffer)); | 250 | memset(&re_buffer, 0, sizeof(re_buffer)); |
258 | memset (re_regs, 0, sizeof (*re_regs)); | 251 | memset(re_regs, 0, sizeof(*re_regs)); |
259 | if( regcomp (&re_buffer, pv->u.s, 0) != 0 ) | 252 | if (regcomp(&re_buffer, pv->u.s, 0) != 0) |
260 | bb_error_msg_and_die("Invalid regular expression"); | 253 | bb_error_msg_and_die("Invalid regular expression"); |
261 | 254 | ||
262 | /* expr uses an anchored pattern match, so check that there was a | 255 | /* expr uses an anchored pattern match, so check that there was a |
263 | * match and that the match starts at offset 0. */ | 256 | * match and that the match starts at offset 0. */ |
264 | if (regexec (&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH && | 257 | if (regexec(&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH && |
265 | re_regs[0].rm_so == 0) { | 258 | re_regs[0].rm_so == 0) { |
266 | /* Were \(...\) used? */ | 259 | /* Were \(...\) used? */ |
267 | if (re_buffer.re_nsub > 0) { | 260 | if (re_buffer.re_nsub > 0) { |
268 | sv->u.s[re_regs[1].rm_eo] = '\0'; | 261 | sv->u.s[re_regs[1].rm_eo] = '\0'; |
269 | v = str_value (sv->u.s + re_regs[1].rm_so); | 262 | v = str_value(sv->u.s + re_regs[1].rm_so); |
270 | } | 263 | } else |
271 | else | 264 | v = int_value(re_regs[0].rm_eo); |
272 | v = int_value (re_regs[0].rm_eo); | 265 | } else { |
273 | } | ||
274 | else { | ||
275 | /* Match failed -- return the right kind of null. */ | 266 | /* Match failed -- return the right kind of null. */ |
276 | if (re_buffer.re_nsub > 0) | 267 | if (re_buffer.re_nsub > 0) |
277 | v = str_value (""); | 268 | v = str_value(""); |
278 | else | 269 | else |
279 | v = int_value (0); | 270 | v = int_value(0); |
280 | } | 271 | } |
281 | return v; | 272 | return v; |
282 | } | 273 | } |
283 | 274 | ||
284 | /* Handle bare operands and ( expr ) syntax. */ | 275 | /* Handle bare operands and ( expr ) syntax. */ |
285 | 276 | ||
286 | static VALUE *eval7 (void) | 277 | static VALUE *eval7(void) |
287 | { | 278 | { |
288 | VALUE *v; | 279 | VALUE *v; |
289 | 280 | ||
290 | if (!*args) | 281 | if (!*args) |
291 | bb_error_msg_and_die ( "syntax error"); | 282 | bb_error_msg_and_die("syntax error"); |
292 | 283 | ||
293 | if (nextarg ("(")) { | 284 | if (nextarg("(")) { |
294 | args++; | 285 | args++; |
295 | v = eval (); | 286 | v = eval(); |
296 | if (!nextarg (")")) | 287 | if (!nextarg(")")) |
297 | bb_error_msg_and_die ( "syntax error"); | 288 | bb_error_msg_and_die("syntax error"); |
298 | args++; | 289 | args++; |
299 | return v; | 290 | return v; |
300 | } | 291 | } |
301 | 292 | ||
302 | if (nextarg (")")) | 293 | if (nextarg(")")) |
303 | bb_error_msg_and_die ( "syntax error"); | 294 | bb_error_msg_and_die("syntax error"); |
304 | 295 | ||
305 | return str_value (*args++); | 296 | return str_value(*args++); |
306 | } | 297 | } |
307 | 298 | ||
308 | /* Handle match, substr, index, length, and quote keywords. */ | 299 | /* Handle match, substr, index, length, and quote keywords. */ |
309 | 300 | ||
310 | static VALUE *eval6 (void) | 301 | static VALUE *eval6(void) |
311 | { | 302 | { |
312 | VALUE *l, *r, *v, *i1, *i2; | 303 | VALUE *l, *r, *v, *i1, *i2; |
313 | 304 | ||
314 | if (nextarg ("quote")) { | 305 | if (nextarg("quote")) { |
315 | args++; | 306 | args++; |
316 | if (!*args) | 307 | if (!*args) |
317 | bb_error_msg_and_die ( "syntax error"); | 308 | bb_error_msg_and_die("syntax error"); |
318 | return str_value (*args++); | 309 | return str_value(*args++); |
319 | } | 310 | } else if (nextarg("length")) { |
320 | else if (nextarg ("length")) { | ||
321 | args++; | 311 | args++; |
322 | r = eval6 (); | 312 | r = eval6(); |
323 | tostring (r); | 313 | tostring(r); |
324 | v = int_value (strlen (r->u.s)); | 314 | v = int_value(strlen(r->u.s)); |
325 | freev (r); | 315 | freev(r); |
326 | return v; | 316 | return v; |
327 | } | 317 | } else if (nextarg("match")) { |
328 | else if (nextarg ("match")) { | ||
329 | args++; | 318 | args++; |
330 | l = eval6 (); | 319 | l = eval6(); |
331 | r = eval6 (); | 320 | r = eval6(); |
332 | v = docolon (l, r); | 321 | v = docolon(l, r); |
333 | freev (l); | 322 | freev(l); |
334 | freev (r); | 323 | freev(r); |
335 | return v; | 324 | return v; |
336 | } | 325 | } else if (nextarg("index")) { |
337 | else if (nextarg ("index")) { | ||
338 | args++; | 326 | args++; |
339 | l = eval6 (); | 327 | l = eval6(); |
340 | r = eval6 (); | 328 | r = eval6(); |
341 | tostring (l); | 329 | tostring(l); |
342 | tostring (r); | 330 | tostring(r); |
343 | v = int_value (strcspn (l->u.s, r->u.s) + 1); | 331 | v = int_value(strcspn(l->u.s, r->u.s) + 1); |
344 | if (v->u.i == (arith_t) strlen (l->u.s) + 1) | 332 | if (v->u.i == (arith_t) strlen(l->u.s) + 1) |
345 | v->u.i = 0; | 333 | v->u.i = 0; |
346 | freev (l); | 334 | freev(l); |
347 | freev (r); | 335 | freev(r); |
348 | return v; | 336 | return v; |
349 | } | 337 | } else if (nextarg("substr")) { |
350 | else if (nextarg ("substr")) { | ||
351 | args++; | 338 | args++; |
352 | l = eval6 (); | 339 | l = eval6(); |
353 | i1 = eval6 (); | 340 | i1 = eval6(); |
354 | i2 = eval6 (); | 341 | i2 = eval6(); |
355 | tostring (l); | 342 | tostring(l); |
356 | if (!toarith (i1) || !toarith (i2) | 343 | if (!toarith(i1) || !toarith(i2) |
357 | || i1->u.i > (arith_t) strlen (l->u.s) | 344 | || i1->u.i > (arith_t) strlen(l->u.s) |
358 | || i1->u.i <= 0 || i2->u.i <= 0) | 345 | || i1->u.i <= 0 || i2->u.i <= 0) |
359 | v = str_value (""); | 346 | v = str_value(""); |
360 | else { | 347 | else { |
361 | v = xmalloc (sizeof(VALUE)); | 348 | v = xmalloc(sizeof(VALUE)); |
362 | v->type = string; | 349 | v->type = string; |
363 | v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i); | 350 | v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i); |
364 | } | 351 | } |
365 | freev (l); | 352 | freev(l); |
366 | freev (i1); | 353 | freev(i1); |
367 | freev (i2); | 354 | freev(i2); |
368 | return v; | 355 | return v; |
369 | } | 356 | } else |
370 | else | 357 | return eval7(); |
371 | return eval7 (); | ||
372 | } | 358 | } |
373 | 359 | ||
374 | /* Handle : operator (pattern matching). | 360 | /* Handle : operator (pattern matching). |
375 | Calls docolon to do the real work. */ | 361 | Calls docolon to do the real work. */ |
376 | 362 | ||
377 | static VALUE *eval5 (void) | 363 | static VALUE *eval5(void) |
378 | { | 364 | { |
379 | VALUE *l, *r, *v; | 365 | VALUE *l, *r, *v; |
380 | 366 | ||
381 | l = eval6 (); | 367 | l = eval6(); |
382 | while (nextarg (":")) { | 368 | while (nextarg(":")) { |
383 | args++; | 369 | args++; |
384 | r = eval6 (); | 370 | r = eval6(); |
385 | v = docolon (l, r); | 371 | v = docolon(l, r); |
386 | freev (l); | 372 | freev(l); |
387 | freev (r); | 373 | freev(r); |
388 | l = v; | 374 | l = v; |
389 | } | 375 | } |
390 | return l; | 376 | return l; |
@@ -392,128 +378,126 @@ static VALUE *eval5 (void) | |||
392 | 378 | ||
393 | /* Handle *, /, % operators. */ | 379 | /* Handle *, /, % operators. */ |
394 | 380 | ||
395 | static VALUE *eval4 (void) | 381 | static VALUE *eval4(void) |
396 | { | 382 | { |
397 | VALUE *l, *r; | 383 | VALUE *l, *r; |
398 | int op; | 384 | int op; |
399 | arith_t val; | 385 | arith_t val; |
400 | 386 | ||
401 | l = eval5 (); | 387 | l = eval5(); |
402 | while (1) { | 388 | while (1) { |
403 | if (nextarg ("*")) | 389 | if (nextarg("*")) |
404 | op = '*'; | 390 | op = '*'; |
405 | else if (nextarg ("/")) | 391 | else if (nextarg("/")) |
406 | op = '/'; | 392 | op = '/'; |
407 | else if (nextarg ("%")) | 393 | else if (nextarg("%")) |
408 | op = '%'; | 394 | op = '%'; |
409 | else | 395 | else |
410 | return l; | 396 | return l; |
411 | args++; | 397 | args++; |
412 | r = eval5 (); | 398 | r = eval5(); |
413 | val = arithmetic_common (l, r, op); | 399 | val = arithmetic_common(l, r, op); |
414 | freev (l); | 400 | freev(l); |
415 | freev (r); | 401 | freev(r); |
416 | l = int_value (val); | 402 | l = int_value(val); |
417 | } | 403 | } |
418 | } | 404 | } |
419 | 405 | ||
420 | /* Handle +, - operators. */ | 406 | /* Handle +, - operators. */ |
421 | 407 | ||
422 | static VALUE *eval3 (void) | 408 | static VALUE *eval3(void) |
423 | { | 409 | { |
424 | VALUE *l, *r; | 410 | VALUE *l, *r; |
425 | int op; | 411 | int op; |
426 | arith_t val; | 412 | arith_t val; |
427 | 413 | ||
428 | l = eval4 (); | 414 | l = eval4(); |
429 | while (1) { | 415 | while (1) { |
430 | if (nextarg ("+")) | 416 | if (nextarg("+")) |
431 | op = '+'; | 417 | op = '+'; |
432 | else if (nextarg ("-")) | 418 | else if (nextarg("-")) |
433 | op = '-'; | 419 | op = '-'; |
434 | else | 420 | else |
435 | return l; | 421 | return l; |
436 | args++; | 422 | args++; |
437 | r = eval4 (); | 423 | r = eval4(); |
438 | val = arithmetic_common (l, r, op); | 424 | val = arithmetic_common(l, r, op); |
439 | freev (l); | 425 | freev(l); |
440 | freev (r); | 426 | freev(r); |
441 | l = int_value (val); | 427 | l = int_value(val); |
442 | } | 428 | } |
443 | } | 429 | } |
444 | 430 | ||
445 | /* Handle comparisons. */ | 431 | /* Handle comparisons. */ |
446 | 432 | ||
447 | static VALUE *eval2 (void) | 433 | static VALUE *eval2(void) |
448 | { | 434 | { |
449 | VALUE *l, *r; | 435 | VALUE *l, *r; |
450 | int op; | 436 | int op; |
451 | arith_t val; | 437 | arith_t val; |
452 | 438 | ||
453 | l = eval3 (); | 439 | l = eval3(); |
454 | while (1) { | 440 | while (1) { |
455 | if (nextarg ("<")) | 441 | if (nextarg("<")) |
456 | op = '<'; | 442 | op = '<'; |
457 | else if (nextarg ("<=")) | 443 | else if (nextarg("<=")) |
458 | op = 'L'+'E'; | 444 | op = 'L' + 'E'; |
459 | else if (nextarg ("=") || nextarg ("==")) | 445 | else if (nextarg("=") || nextarg("==")) |
460 | op = '='; | 446 | op = '='; |
461 | else if (nextarg ("!=")) | 447 | else if (nextarg("!=")) |
462 | op = '!'; | 448 | op = '!'; |
463 | else if (nextarg (">=")) | 449 | else if (nextarg(">=")) |
464 | op = 'G'+'E'; | 450 | op = 'G' + 'E'; |
465 | else if (nextarg (">")) | 451 | else if (nextarg(">")) |
466 | op = '>'; | 452 | op = '>'; |
467 | else | 453 | else |
468 | return l; | 454 | return l; |
469 | args++; | 455 | args++; |
470 | r = eval3 (); | 456 | r = eval3(); |
471 | toarith (l); | 457 | toarith(l); |
472 | toarith (r); | 458 | toarith(r); |
473 | val = cmp_common (l, r, op); | 459 | val = cmp_common(l, r, op); |
474 | freev (l); | 460 | freev(l); |
475 | freev (r); | 461 | freev(r); |
476 | l = int_value (val); | 462 | l = int_value(val); |
477 | } | 463 | } |
478 | } | 464 | } |
479 | 465 | ||
480 | /* Handle &. */ | 466 | /* Handle &. */ |
481 | 467 | ||
482 | static VALUE *eval1 (void) | 468 | static VALUE *eval1(void) |
483 | { | 469 | { |
484 | VALUE *l, *r; | 470 | VALUE *l, *r; |
485 | 471 | ||
486 | l = eval2 (); | 472 | l = eval2(); |
487 | while (nextarg ("&")) { | 473 | while (nextarg("&")) { |
488 | args++; | 474 | args++; |
489 | r = eval2 (); | 475 | r = eval2(); |
490 | if (null (l) || null (r)) { | 476 | if (null(l) || null(r)) { |
491 | freev (l); | 477 | freev(l); |
492 | freev (r); | 478 | freev(r); |
493 | l = int_value (0); | 479 | l = int_value(0); |
494 | } | 480 | } else |
495 | else | 481 | freev(r); |
496 | freev (r); | ||
497 | } | 482 | } |
498 | return l; | 483 | return l; |
499 | } | 484 | } |
500 | 485 | ||
501 | /* Handle |. */ | 486 | /* Handle |. */ |
502 | 487 | ||
503 | static VALUE *eval (void) | 488 | static VALUE *eval(void) |
504 | { | 489 | { |
505 | VALUE *l, *r; | 490 | VALUE *l, *r; |
506 | 491 | ||
507 | l = eval1 (); | 492 | l = eval1(); |
508 | while (nextarg ("|")) { | 493 | while (nextarg("|")) { |
509 | args++; | 494 | args++; |
510 | r = eval1 (); | 495 | r = eval1(); |
511 | if (null (l)) { | 496 | if (null(l)) { |
512 | freev (l); | 497 | freev(l); |
513 | l = r; | 498 | l = r; |
514 | } | 499 | } else |
515 | else | 500 | freev(r); |
516 | freev (r); | ||
517 | } | 501 | } |
518 | return l; | 502 | return l; |
519 | } | 503 | } |
diff --git a/coreutils/sum.c b/coreutils/sum.c index 2edd92036..d6a76dbbc 100644 --- a/coreutils/sum.c +++ b/coreutils/sum.c | |||
@@ -13,12 +13,6 @@ | |||
13 | * Licensed under the GPL v2, see the file LICENSE in this tarball. | 13 | * Licensed under the GPL v2, see the file LICENSE in this tarball. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <stdio.h> | ||
17 | #include <sys/types.h> | ||
18 | #include <sys/stat.h> | ||
19 | #include <fcntl.h> | ||
20 | #include <unistd.h> | ||
21 | |||
22 | #include "busybox.h" | 16 | #include "busybox.h" |
23 | 17 | ||
24 | /* 1 if any of the files read were the standard input */ | 18 | /* 1 if any of the files read were the standard input */ |
@@ -38,14 +32,15 @@ static int bsd_sum_file(const char *file, int print_name) | |||
38 | int checksum = 0; /* The checksum mod 2^16. */ | 32 | int checksum = 0; /* The checksum mod 2^16. */ |
39 | uintmax_t total_bytes = 0; /* The number of bytes. */ | 33 | uintmax_t total_bytes = 0; /* The number of bytes. */ |
40 | int ch; /* Each character read. */ | 34 | int ch; /* Each character read. */ |
35 | int ret = 0; | ||
41 | 36 | ||
42 | if (IS_STDIN(file)) { | 37 | if (IS_STDIN(file)) { |
43 | fp = stdin; | 38 | fp = stdin; |
44 | have_read_stdin = 1; | 39 | have_read_stdin++; |
45 | } else { | 40 | } else { |
46 | fp = bb_wfopen(file, "r"); | 41 | fp = bb_wfopen(file, "r"); |
47 | if (fp == NULL) | 42 | if (fp == NULL) |
48 | return 0; | 43 | goto out; |
49 | } | 44 | } |
50 | 45 | ||
51 | while ((ch = getc(fp)) != EOF) { | 46 | while ((ch = getc(fp)) != EOF) { |
@@ -58,21 +53,21 @@ static int bsd_sum_file(const char *file, int print_name) | |||
58 | if (ferror(fp)) { | 53 | if (ferror(fp)) { |
59 | bb_perror_msg(file); | 54 | bb_perror_msg(file); |
60 | bb_fclose_nonstdin(fp); | 55 | bb_fclose_nonstdin(fp); |
61 | return 0; | 56 | goto out; |
62 | } | 57 | } |
63 | 58 | ||
64 | if (bb_fclose_nonstdin(fp) == EOF) { | 59 | if (bb_fclose_nonstdin(fp) == EOF) { |
65 | bb_perror_msg(file); | 60 | bb_perror_msg(file); |
66 | return 0; | 61 | goto out; |
67 | } | 62 | } |
68 | 63 | ret++; | |
69 | printf("%05d %5ju ", checksum, (total_bytes+1023)/1024); | 64 | printf("%05d %5ju ", checksum, (total_bytes+1023)/1024); |
70 | if (print_name > 1) | 65 | if (print_name > 1) |
71 | puts(file); | 66 | puts(file); |
72 | else | 67 | else |
73 | printf("\n"); | 68 | printf("\n"); |
74 | 69 | out: | |
75 | return 1; | 70 | return ret; |
76 | } | 71 | } |
77 | 72 | ||
78 | /* Calculate and print the checksum and the size in 512-byte blocks | 73 | /* Calculate and print the checksum and the size in 512-byte blocks |
diff --git a/coreutils/tail.c b/coreutils/tail.c index 80a66fbf5..49f1bcd6a 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c | |||
@@ -42,20 +42,25 @@ static const struct suffix_mult tail_suffixes[] = { | |||
42 | 42 | ||
43 | static int status; | 43 | static int status; |
44 | 44 | ||
45 | static void tail_xprint_header(const char *fmt, const char *filename) | 45 | static void tail_xbb_full_write(const char *buf, size_t len) |
46 | { | 46 | { |
47 | /* If we get an output error, there is really no sense in continuing. */ | 47 | /* If we get a write error, there is really no sense in continuing. */ |
48 | if (dprintf(STDOUT_FILENO, fmt, filename) < 0) { | 48 | if (full_write(STDOUT_FILENO, buf, len) < 0) |
49 | bb_perror_nomsg_and_die(); | 49 | bb_perror_nomsg_and_die(); |
50 | } | ||
51 | } | 50 | } |
52 | 51 | ||
53 | /* len should probably be size_t */ | 52 | static void tail_xprint_header(const char *fmt, const char *filename) |
54 | static void tail_xbb_full_write(const char *buf, size_t len) | ||
55 | { | 53 | { |
56 | /* If we get a write error, there is really no sense in continuing. */ | 54 | #if defined __GLIBC__ |
57 | if (full_write(STDOUT_FILENO, buf, len) < 0) | 55 | if (dprintf(STDOUT_FILENO, fmt, filename) < 0) { |
58 | bb_perror_nomsg_and_die(); | 56 | bb_perror_nomsg_and_die(); |
57 | } | ||
58 | #else | ||
59 | int hdr_len = strlen(fmt) + strlen(filename); | ||
60 | char *hdr = xzalloc(hdr_len); | ||
61 | sprintf(hdr, filename, filename); | ||
62 | tail_xbb_full_write(hdr, hdr_len); | ||
63 | #endif | ||
59 | } | 64 | } |
60 | 65 | ||
61 | static ssize_t tail_read(int fd, char *buf, size_t count) | 66 | static ssize_t tail_read(int fd, char *buf, size_t count) |
diff --git a/coreutils/tee.c b/coreutils/tee.c index 4d0e6ff85..1f59f0361 100644 --- a/coreutils/tee.c +++ b/coreutils/tee.c | |||
@@ -11,6 +11,7 @@ | |||
11 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */ | 11 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */ |
12 | 12 | ||
13 | #include "busybox.h" | 13 | #include "busybox.h" |
14 | #include <signal.h> | ||
14 | 15 | ||
15 | int tee_main(int argc, char **argv) | 16 | int tee_main(int argc, char **argv) |
16 | { | 17 | { |
@@ -37,7 +38,7 @@ int tee_main(int argc, char **argv) | |||
37 | 38 | ||
38 | /* gnu tee ignores SIGPIPE in case one of the output files is a pipe | 39 | /* gnu tee ignores SIGPIPE in case one of the output files is a pipe |
39 | * that doesn't consume all its input. Good idea... */ | 40 | * that doesn't consume all its input. Good idea... */ |
40 | signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction.*/ | 41 | signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction.*/ |
41 | 42 | ||
42 | /* Allocate an array of FILE *'s, with one extra for a sentinal. */ | 43 | /* Allocate an array of FILE *'s, with one extra for a sentinal. */ |
43 | p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2)); | 44 | p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2)); |
diff --git a/coreutils/watch.c b/coreutils/watch.c index c8b16b908..7b9c6698a 100644 --- a/coreutils/watch.c +++ b/coreutils/watch.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Mini watch implementation for busybox | 3 | * Mini watch implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 2001 by Michael Habermann <mhabermann@gmx.de> | 5 | * Copyright (C) 2001 by Michael Habermann <mhabermann@gmx.de> |
6 | * Copyrigjt (C) Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
6 | * | 7 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 9 | */ |
@@ -10,14 +11,9 @@ | |||
10 | /* BB_AUDIT SUSv3 N/A */ | 11 | /* BB_AUDIT SUSv3 N/A */ |
11 | /* BB_AUDIT GNU defects -- only option -n is supported. */ | 12 | /* BB_AUDIT GNU defects -- only option -n is supported. */ |
12 | 13 | ||
13 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
14 | * | ||
15 | * Removed dependency on date_main(), added proper error checking, and | ||
16 | * reduced size. | ||
17 | */ | ||
18 | |||
19 | #include "busybox.h" | 14 | #include "busybox.h" |
20 | 15 | ||
16 | |||
21 | int watch_main(int argc, char **argv) | 17 | int watch_main(int argc, char **argv) |
22 | { | 18 | { |
23 | int width, len; | 19 | int width, len; |
@@ -26,19 +22,18 @@ int watch_main(int argc, char **argv) | |||
26 | 22 | ||
27 | if (argc < 2) bb_show_usage(); | 23 | if (argc < 2) bb_show_usage(); |
28 | 24 | ||
29 | get_terminal_width_height(1, &width, 0); | 25 | get_terminal_width_height(STDOUT_FILENO, &width, 0); |
30 | header = xzalloc(width--); | 26 | header = xzalloc(width--); |
31 | 27 | ||
32 | /* don't use getopt, because it permutes the arguments */ | 28 | /* don't use getopt, because it permutes the arguments */ |
33 | ++argv; | 29 | ++argv; |
34 | if ((argc > 3) && !strcmp(*argv, "-n")) { | 30 | if ((argc > 3) && argv[0][0] == '-' && argv[0][1] == 'n') { |
35 | period = bb_xgetularg10_bnd(argv[1], 1, UINT_MAX); | 31 | period = bb_xgetularg10_bnd(argv[1], 1, UINT_MAX); |
36 | argv += 2; | 32 | argv += 2; |
37 | } | 33 | } |
38 | watched_argv = argv; | 34 | watched_argv = argv; |
39 | 35 | ||
40 | /* create header */ | 36 | /* create header */ |
41 | |||
42 | len = snprintf(header, width, "Every %ds:", period); | 37 | len = snprintf(header, width, "Every %ds:", period); |
43 | while (*argv && len<width) | 38 | while (*argv && len<width) |
44 | snprintf(header+len, width-len, " %s", *(argv++)); | 39 | snprintf(header+len, width-len, " %s", *(argv++)); |
@@ -50,11 +45,13 @@ int watch_main(int argc, char **argv) | |||
50 | time(&t); | 45 | time(&t); |
51 | thyme = ctime(&t); | 46 | thyme = ctime(&t); |
52 | len = strlen(thyme); | 47 | len = strlen(thyme); |
53 | if (len < width) header[width-len] = 0; | 48 | if (len < width) |
54 | 49 | header[width-len] = 0; | |
55 | printf("\033[H\033[J%s %s\n", header, thyme); | 50 | bb_printf("\033[H\033[J%s %s\n", header, thyme); |
56 | 51 | ||
57 | waitpid(xspawn(watched_argv),0,0); | 52 | waitpid(xspawn(watched_argv),0,0); |
58 | sleep(period); | 53 | sleep(period); |
59 | } | 54 | } |
55 | if (ENABLE_FEATURE_CLEAN_UP) | ||
56 | free(header); | ||
60 | } | 57 | } |