diff options
author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2006-08-28 23:31:54 +0000 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2006-08-28 23:31:54 +0000 |
commit | 73561cc75ac31e63bcab4b4ebfaf738e4ca225e6 (patch) | |
tree | 2a57564b8917a983365c765d4daa83032d9f0a17 | |
parent | 6ce8dae1d5a201156a83201de6c49cdcc4c8df3e (diff) | |
download | busybox-w32-73561cc75ac31e63bcab4b4ebfaf738e4ca225e6.tar.gz busybox-w32-73561cc75ac31e63bcab4b4ebfaf738e4ca225e6.tar.bz2 busybox-w32-73561cc75ac31e63bcab4b4ebfaf738e4ca225e6.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
-rw-r--r-- | Makefile | 1 | ||||
-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 | ||||
-rw-r--r-- | include/libbb.h | 28 | ||||
-rw-r--r-- | include/unarchive.h | 2 | ||||
-rw-r--r-- | include/usage.h | 10 | ||||
-rw-r--r-- | libbb/xfuncs.c | 133 | ||||
-rwxr-xr-x | testsuite/all_sourcecode.tests | 1 | ||||
-rw-r--r-- | util-linux/ipcrm.c | 216 | ||||
-rw-r--r-- | util-linux/ipcs.c | 584 |
20 files changed, 1162 insertions, 1283 deletions
@@ -278,6 +278,7 @@ endif # CONFIG_FEATURE_FULL_LIBBUSYBOX | |||
278 | APPLET_SRC:=$(APPLET_SRC-y) | 278 | APPLET_SRC:=$(APPLET_SRC-y) |
279 | APPLETS_DEFINE:=$(APPLETS_DEFINE-y) | 279 | APPLETS_DEFINE:=$(APPLETS_DEFINE-y) |
280 | else # CONFIG_BUILD_AT_ONCE | 280 | else # CONFIG_BUILD_AT_ONCE |
281 | APPLET_SRC:= | ||
281 | # no --combine, build archives out of the individual .o | 282 | # no --combine, build archives out of the individual .o |
282 | # This was the old way the binary was built. | 283 | # This was the old way the binary was built. |
283 | libbusybox-obj:=archival/libunarchive/libunarchive.a \ | 284 | libbusybox-obj:=archival/libunarchive/libunarchive.a \ |
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 | } |
diff --git a/include/libbb.h b/include/libbb.h index 3c563a96f..b94586165 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -60,10 +60,6 @@ | |||
60 | #define PATH_MAX 256 | 60 | #define PATH_MAX 256 |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | #ifdef DMALLOC | ||
64 | #include <dmalloc.h> | ||
65 | #endif | ||
66 | |||
67 | /* Some useful definitions */ | 63 | /* Some useful definitions */ |
68 | #undef FALSE | 64 | #undef FALSE |
69 | #define FALSE ((int) 0) | 65 | #define FALSE ((int) 0) |
@@ -211,7 +207,9 @@ extern int bb_fprintf(FILE * __restrict stream, const char * __restrict format, | |||
211 | extern int bb_printf(const char * __restrict format, ...) | 207 | extern int bb_printf(const char * __restrict format, ...) |
212 | __attribute__ ((format (printf, 1, 2))); | 208 | __attribute__ ((format (printf, 1, 2))); |
213 | 209 | ||
214 | //#warning rename to xferror_filename? | 210 | #if ENABLE_NITPICK |
211 | #warning rename to xferror_filename? | ||
212 | #endif | ||
215 | extern void xferror(FILE *fp, const char *fn); | 213 | extern void xferror(FILE *fp, const char *fn); |
216 | extern void xferror_stdout(void); | 214 | extern void xferror_stdout(void); |
217 | extern void xfflush_stdout(void); | 215 | extern void xfflush_stdout(void); |
@@ -265,7 +263,9 @@ extern long bb_xgetlarg_bnd_sfx(const char *arg, int base, | |||
265 | extern long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes); | 263 | extern long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes); |
266 | 264 | ||
267 | 265 | ||
268 | //#warning pitchable now? | 266 | #if ENABLE_NITPICK |
267 | #warning pitchable now? | ||
268 | #endif | ||
269 | extern unsigned long bb_xparse_number(const char *numstr, | 269 | extern unsigned long bb_xparse_number(const char *numstr, |
270 | const struct suffix_mult *suffixes); | 270 | const struct suffix_mult *suffixes); |
271 | 271 | ||
@@ -330,7 +330,9 @@ char *concat_path_file(const char *path, const char *filename); | |||
330 | char *concat_subpath_file(const char *path, const char *filename); | 330 | char *concat_subpath_file(const char *path, const char *filename); |
331 | char *last_char_is(const char *s, int c); | 331 | char *last_char_is(const char *s, int c); |
332 | 332 | ||
333 | //#warning yuk! | 333 | #if ENABLE_NITPICK |
334 | #warning yuk! | ||
335 | #endif | ||
334 | char *fgets_str(FILE *file, const char *terminating_string); | 336 | char *fgets_str(FILE *file, const char *terminating_string); |
335 | 337 | ||
336 | extern int uncompress(int fd_in, int fd_out); | 338 | extern int uncompress(int fd_in, int fd_out); |
@@ -344,7 +346,9 @@ extern int xconnect(struct sockaddr_in *s_addr); | |||
344 | extern unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port); | 346 | extern unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port); |
345 | extern void bb_lookup_host(struct sockaddr_in *s_in, const char *host); | 347 | extern void bb_lookup_host(struct sockaddr_in *s_in, const char *host); |
346 | 348 | ||
347 | //#warning wrap this? | 349 | #if ENABLE_NITPICK |
350 | #warning wrap this? | ||
351 | #endif | ||
348 | char *dirname (char *path); | 352 | char *dirname (char *path); |
349 | 353 | ||
350 | int bb_make_directory (char *path, long mode, int flags); | 354 | int bb_make_directory (char *path, long mode, int flags); |
@@ -456,8 +460,10 @@ extern int bb_default_error_retval; | |||
456 | # define FB_0 "/dev/fb0" | 460 | # define FB_0 "/dev/fb0" |
457 | #endif | 461 | #endif |
458 | 462 | ||
459 | //#warning put these in .o files | ||
460 | 463 | ||
464 | #if ENABLE_NITPICK | ||
465 | #warning put these in .o files | ||
466 | #endif | ||
461 | /* The following devices are the same on devfs and non-devfs systems. */ | 467 | /* The following devices are the same on devfs and non-devfs systems. */ |
462 | #define CURRENT_TTY "/dev/tty" | 468 | #define CURRENT_TTY "/dev/tty" |
463 | #define CONSOLE_DEV "/dev/console" | 469 | #define CONSOLE_DEV "/dev/console" |
@@ -581,4 +587,8 @@ extern const char BB_BANNER[]; | |||
581 | #undef isupper | 587 | #undef isupper |
582 | #undef isxdigit | 588 | #undef isxdigit |
583 | 589 | ||
590 | #ifdef DMALLOC | ||
591 | #include <dmalloc.h> | ||
592 | #endif | ||
593 | |||
584 | #endif /* __LIBBUSYBOX_H__ */ | 594 | #endif /* __LIBBUSYBOX_H__ */ |
diff --git a/include/unarchive.h b/include/unarchive.h index 05ab0c16a..1dbbc009d 100644 --- a/include/unarchive.h +++ b/include/unarchive.h | |||
@@ -10,8 +10,6 @@ | |||
10 | #define ARCHIVE_NOPRESERVE_OWN 32 | 10 | #define ARCHIVE_NOPRESERVE_OWN 32 |
11 | #define ARCHIVE_NOPRESERVE_PERM 64 | 11 | #define ARCHIVE_NOPRESERVE_PERM 64 |
12 | 12 | ||
13 | #include <sys/types.h> | ||
14 | #include <stdio.h> | ||
15 | #include "libbb.h" | 13 | #include "libbb.h" |
16 | 14 | ||
17 | typedef struct file_headers_s { | 15 | typedef struct file_headers_s { |
diff --git a/include/usage.h b/include/usage.h index ced9f68c7..0f95708c5 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -1426,12 +1426,12 @@ USE_FEATURE_DATE_ISOFMT( \ | |||
1426 | #define ipcrm_trivial_usage \ | 1426 | #define ipcrm_trivial_usage \ |
1427 | "[-[MQS] key] [-[mqs] id]" | 1427 | "[-[MQS] key] [-[mqs] id]" |
1428 | #define ipcrm_full_usage \ | 1428 | #define ipcrm_full_usage \ |
1429 | "The upper-case options MQS are used to remove a shared memory\n" \ | 1429 | "The upper-case options MQS are used to remove a shared memory segment by a\n" \ |
1430 | "segment by an shmkey value. The lower-case options mqs are used\n" \ | 1430 | "segment by a shmkey value. The lower-case options mqs are used\n" \ |
1431 | "to remove a segment by shmid value.\n" \ | 1431 | "to remove a segment by shmid value.\n" \ |
1432 | "\t-m | -M\tRemove the memory segment after the last detach\n" \ | 1432 | "\t-[mM]\tRemove the memory segment after the last detach\n" \ |
1433 | "\t-q | -Q\tRemove the message queue\n" \ | 1433 | "\t-[qQ]\tRemove the message queue\n" \ |
1434 | "\t-s | -S\tRemove the semaphore" | 1434 | "\t-[sS]\tRemove the semaphore" |
1435 | 1435 | ||
1436 | #define ipcs_trivial_usage \ | 1436 | #define ipcs_trivial_usage \ |
1437 | "[[-smq] -i shmid] | [[-asmq] [-tclup]]" | 1437 | "[[-smq] -i shmid] | [[-asmq] [-tclup]]" |
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 4d81fdc28..b2b53a712 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
@@ -16,8 +16,12 @@ | |||
16 | * succeeded. */ | 16 | * succeeded. */ |
17 | 17 | ||
18 | #ifndef DMALLOC | 18 | #ifndef DMALLOC |
19 | /* dmalloc provides variants of these that do abort() on failure. | ||
20 | * Since dmalloc's prototypes overwrite the impls here as they are | ||
21 | * included after these prototypes in libbb.h, all is well. | ||
22 | */ | ||
19 | #ifdef L_xmalloc | 23 | #ifdef L_xmalloc |
20 | // Die if we can't allocate size bytes of memory. | 24 | /* Die if we can't allocate size bytes of memory. */ |
21 | void *xmalloc(size_t size) | 25 | void *xmalloc(size_t size) |
22 | { | 26 | { |
23 | void *ptr = malloc(size); | 27 | void *ptr = malloc(size); |
@@ -28,9 +32,9 @@ void *xmalloc(size_t size) | |||
28 | #endif | 32 | #endif |
29 | 33 | ||
30 | #ifdef L_xrealloc | 34 | #ifdef L_xrealloc |
31 | // Die if we can't resize previously allocated memory. (This returns a pointer | 35 | /* Die if we can't resize previously allocated memory. (This returns a pointer |
32 | // to the new memory, which may or may not be the same as the old memory. | 36 | * to the new memory, which may or may not be the same as the old memory. |
33 | // It'll copy the contents to a new chunk and free the old one if necessary.) | 37 | * It'll copy the contents to a new chunk and free the old one if necessary.) */ |
34 | void *xrealloc(void *ptr, size_t size) | 38 | void *xrealloc(void *ptr, size_t size) |
35 | { | 39 | { |
36 | ptr = realloc(ptr, size); | 40 | ptr = realloc(ptr, size); |
@@ -39,9 +43,11 @@ void *xrealloc(void *ptr, size_t size) | |||
39 | return ptr; | 43 | return ptr; |
40 | } | 44 | } |
41 | #endif | 45 | #endif |
46 | #endif /* DMALLOC */ | ||
47 | |||
42 | 48 | ||
43 | #ifdef L_xzalloc | 49 | #ifdef L_xzalloc |
44 | // Die if we can't allocate and zero size bytes of memory. | 50 | /* Die if we can't allocate and zero size bytes of memory. */ |
45 | void *xzalloc(size_t size) | 51 | void *xzalloc(size_t size) |
46 | { | 52 | { |
47 | void *ptr = xmalloc(size); | 53 | void *ptr = xmalloc(size); |
@@ -50,10 +56,8 @@ void *xzalloc(size_t size) | |||
50 | } | 56 | } |
51 | #endif | 57 | #endif |
52 | 58 | ||
53 | #endif /* DMALLOC */ | ||
54 | |||
55 | #ifdef L_xstrdup | 59 | #ifdef L_xstrdup |
56 | // Die if we can't copy a string to freshly allocated memory. | 60 | /* Die if we can't copy a string to freshly allocated memory. */ |
57 | char * xstrdup(const char *s) | 61 | char * xstrdup(const char *s) |
58 | { | 62 | { |
59 | char *t; | 63 | char *t; |
@@ -71,8 +75,9 @@ char * xstrdup(const char *s) | |||
71 | #endif | 75 | #endif |
72 | 76 | ||
73 | #ifdef L_xstrndup | 77 | #ifdef L_xstrndup |
74 | // Die if we can't allocate n+1 bytes (space for the null terminator) and copy | 78 | /* Die if we can't allocate n+1 bytes (space for the null terminator) and copy |
75 | // the (possibly truncated to length n) string into it. | 79 | * the (possibly truncated to length n) string into it. |
80 | */ | ||
76 | char * xstrndup(const char *s, int n) | 81 | char * xstrndup(const char *s, int n) |
77 | { | 82 | { |
78 | char *t; | 83 | char *t; |
@@ -87,8 +92,9 @@ char * xstrndup(const char *s, int n) | |||
87 | #endif | 92 | #endif |
88 | 93 | ||
89 | #ifdef L_xfopen | 94 | #ifdef L_xfopen |
90 | // Die if we can't open a file and return a FILE * to it. | 95 | /* Die if we can't open a file and return a FILE * to it. |
91 | // Notice we haven't got xfread(), This is for use with fscanf() and friends. | 96 | * Notice we haven't got xfread(), This is for use with fscanf() and friends. |
97 | */ | ||
92 | FILE *xfopen(const char *path, const char *mode) | 98 | FILE *xfopen(const char *path, const char *mode) |
93 | { | 99 | { |
94 | FILE *fp; | 100 | FILE *fp; |
@@ -99,7 +105,7 @@ FILE *xfopen(const char *path, const char *mode) | |||
99 | #endif | 105 | #endif |
100 | 106 | ||
101 | #ifdef L_xopen | 107 | #ifdef L_xopen |
102 | // Die if we can't open an existing file and return an fd. | 108 | /* Die if we can't open an existing file and return an fd. */ |
103 | int xopen(const char *pathname, int flags) | 109 | int xopen(const char *pathname, int flags) |
104 | { | 110 | { |
105 | if (ENABLE_DEBUG && (flags && O_CREAT)) | 111 | if (ENABLE_DEBUG && (flags && O_CREAT)) |
@@ -110,7 +116,7 @@ int xopen(const char *pathname, int flags) | |||
110 | #endif | 116 | #endif |
111 | 117 | ||
112 | #ifdef L_xopen3 | 118 | #ifdef L_xopen3 |
113 | // Die if we can't open a new file and return an fd. | 119 | /* Die if we can't open a new file and return an fd. */ |
114 | int xopen3(const char *pathname, int flags, int mode) | 120 | int xopen3(const char *pathname, int flags, int mode) |
115 | { | 121 | { |
116 | int ret; | 122 | int ret; |
@@ -124,7 +130,7 @@ int xopen3(const char *pathname, int flags, int mode) | |||
124 | #endif | 130 | #endif |
125 | 131 | ||
126 | #ifdef L_xread | 132 | #ifdef L_xread |
127 | // Die with an error message if we can't read the entire buffer. | 133 | /* Die with an error message if we can't read the entire buffer. */ |
128 | void xread(int fd, void *buf, size_t count) | 134 | void xread(int fd, void *buf, size_t count) |
129 | { | 135 | { |
130 | while (count) { | 136 | while (count) { |
@@ -139,7 +145,7 @@ void xread(int fd, void *buf, size_t count) | |||
139 | #endif | 145 | #endif |
140 | 146 | ||
141 | #ifdef L_xwrite | 147 | #ifdef L_xwrite |
142 | // Die with an error message if we can't write the entire buffer. | 148 | /* Die with an error message if we can't write the entire buffer. */ |
143 | void xwrite(int fd, void *buf, size_t count) | 149 | void xwrite(int fd, void *buf, size_t count) |
144 | { | 150 | { |
145 | while (count) { | 151 | while (count) { |
@@ -154,7 +160,7 @@ void xwrite(int fd, void *buf, size_t count) | |||
154 | #endif | 160 | #endif |
155 | 161 | ||
156 | #ifdef L_xlseek | 162 | #ifdef L_xlseek |
157 | // Die with an error message if we can't lseek to the right spot. | 163 | /* Die with an error message if we can't lseek to the right spot. */ |
158 | void xlseek(int fd, off_t offset, int whence) | 164 | void xlseek(int fd, off_t offset, int whence) |
159 | { | 165 | { |
160 | if (offset != lseek(fd, offset, whence)) bb_error_msg_and_die("lseek"); | 166 | if (offset != lseek(fd, offset, whence)) bb_error_msg_and_die("lseek"); |
@@ -162,7 +168,7 @@ void xlseek(int fd, off_t offset, int whence) | |||
162 | #endif | 168 | #endif |
163 | 169 | ||
164 | #ifdef L_xread_char | 170 | #ifdef L_xread_char |
165 | // Die with an error message if we can't read one character. | 171 | /* Die with an error message if we can't read one character. */ |
166 | unsigned char xread_char(int fd) | 172 | unsigned char xread_char(int fd) |
167 | { | 173 | { |
168 | char tmp; | 174 | char tmp; |
@@ -174,7 +180,7 @@ unsigned char xread_char(int fd) | |||
174 | #endif | 180 | #endif |
175 | 181 | ||
176 | #ifdef L_xferror | 182 | #ifdef L_xferror |
177 | // Die with supplied error message if this FILE * has ferror set. | 183 | /* Die with supplied error message if this FILE * has ferror set. */ |
178 | void xferror(FILE *fp, const char *fn) | 184 | void xferror(FILE *fp, const char *fn) |
179 | { | 185 | { |
180 | if (ferror(fp)) { | 186 | if (ferror(fp)) { |
@@ -184,7 +190,7 @@ void xferror(FILE *fp, const char *fn) | |||
184 | #endif | 190 | #endif |
185 | 191 | ||
186 | #ifdef L_xferror_stdout | 192 | #ifdef L_xferror_stdout |
187 | // Die with an error message if stdout has ferror set. | 193 | /* Die with an error message if stdout has ferror set. */ |
188 | void xferror_stdout(void) | 194 | void xferror_stdout(void) |
189 | { | 195 | { |
190 | xferror(stdout, bb_msg_standard_output); | 196 | xferror(stdout, bb_msg_standard_output); |
@@ -192,7 +198,7 @@ void xferror_stdout(void) | |||
192 | #endif | 198 | #endif |
193 | 199 | ||
194 | #ifdef L_xfflush_stdout | 200 | #ifdef L_xfflush_stdout |
195 | // Die with an error message if we have trouble flushing stdout. | 201 | /* Die with an error message if we have trouble flushing stdout. */ |
196 | void xfflush_stdout(void) | 202 | void xfflush_stdout(void) |
197 | { | 203 | { |
198 | if (fflush(stdout)) { | 204 | if (fflush(stdout)) { |
@@ -202,24 +208,25 @@ void xfflush_stdout(void) | |||
202 | #endif | 208 | #endif |
203 | 209 | ||
204 | #ifdef L_spawn | 210 | #ifdef L_spawn |
205 | // This does a fork/exec in one call, using vfork(). Return PID of new child, | 211 | /* This does a fork/exec in one call, using vfork(). Return PID of new child, |
206 | // -1 for failure. Runs argv[0], searching path if that has no / in it. | 212 | * -1 for failure. Runs argv[0], searching path if that has no / in it. |
213 | */ | ||
207 | pid_t spawn(char **argv) | 214 | pid_t spawn(char **argv) |
208 | { | 215 | { |
209 | static int failed; | 216 | static int failed; |
210 | pid_t pid; | 217 | pid_t pid; |
211 | void *app = ENABLE_FEATURE_SH_STANDALONE_SHELL ? find_applet_by_name(argv[0]) : 0; | 218 | void *app = ENABLE_FEATURE_SH_STANDALONE_SHELL ? find_applet_by_name(argv[0]) : 0; |
212 | 219 | ||
213 | // Be nice to nommu machines. | 220 | /* Be nice to nommu machines. */ |
214 | failed = 0; | 221 | failed = 0; |
215 | pid = vfork(); | 222 | pid = vfork(); |
216 | if (pid < 0) return pid; | 223 | if (pid < 0) return pid; |
217 | if (!pid) { | 224 | if (!pid) { |
218 | execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv); | 225 | execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv); |
219 | 226 | ||
220 | // We're sharing a stack with blocked parent, let parent know we failed | 227 | /* We're sharing a stack with blocked parent, let parent know we failed |
221 | // and then exit to unblock parent (but don't run atexit() stuff, which | 228 | * and then exit to unblock parent (but don't run atexit() stuff, which |
222 | // would screw up parent.) | 229 | would screw up parent.) */ |
223 | 230 | ||
224 | failed = -1; | 231 | failed = -1; |
225 | _exit(0); | 232 | _exit(0); |
@@ -229,7 +236,7 @@ pid_t spawn(char **argv) | |||
229 | #endif | 236 | #endif |
230 | 237 | ||
231 | #ifdef L_xspawn | 238 | #ifdef L_xspawn |
232 | // Die with an error message if we can't spawn a child process. | 239 | /* Die with an error message if we can't spawn a child process. */ |
233 | pid_t xspawn(char **argv) | 240 | pid_t xspawn(char **argv) |
234 | { | 241 | { |
235 | pid_t pid = spawn(argv); | 242 | pid_t pid = spawn(argv); |
@@ -239,7 +246,7 @@ pid_t xspawn(char **argv) | |||
239 | #endif | 246 | #endif |
240 | 247 | ||
241 | #ifdef L_wait4 | 248 | #ifdef L_wait4 |
242 | // Wait for the specified child PID to exit, returning child's error return. | 249 | /* Wait for the specified child PID to exit, returning child's error return. */ |
243 | int wait4pid(int pid) | 250 | int wait4pid(int pid) |
244 | { | 251 | { |
245 | int status; | 252 | int status; |
@@ -252,9 +259,9 @@ int wait4pid(int pid) | |||
252 | #endif | 259 | #endif |
253 | 260 | ||
254 | #ifdef L_itoa | 261 | #ifdef L_itoa |
255 | // Convert unsigned integer to ascii, writing into supplied buffer. A | 262 | /* Convert unsigned integer to ascii, writing into supplied buffer. A |
256 | // truncated result is always null terminated (unless buflen is 0), and | 263 | * truncated result is always null terminated (unless buflen is 0), and |
257 | // contains the first few digits of the result ala strncpy. | 264 | * contains the first few digits of the result ala strncpy. */ |
258 | void utoa_to_buf(unsigned n, char *buf, unsigned buflen) | 265 | void utoa_to_buf(unsigned n, char *buf, unsigned buflen) |
259 | { | 266 | { |
260 | int i, out = 0; | 267 | int i, out = 0; |
@@ -272,7 +279,7 @@ void utoa_to_buf(unsigned n, char *buf, unsigned buflen) | |||
272 | } | 279 | } |
273 | } | 280 | } |
274 | 281 | ||
275 | // Convert signed integer to ascii, like utoa_to_buf() | 282 | /* Convert signed integer to ascii, like utoa_to_buf() */ |
276 | void itoa_to_buf(int n, char *buf, unsigned buflen) | 283 | void itoa_to_buf(int n, char *buf, unsigned buflen) |
277 | { | 284 | { |
278 | if (buflen && n<0) { | 285 | if (buflen && n<0) { |
@@ -283,16 +290,16 @@ void itoa_to_buf(int n, char *buf, unsigned buflen) | |||
283 | utoa_to_buf((unsigned)n, buf, buflen); | 290 | utoa_to_buf((unsigned)n, buf, buflen); |
284 | } | 291 | } |
285 | 292 | ||
286 | // The following two functions use a static buffer, so calling either one a | 293 | /* The following two functions use a static buffer, so calling either one a |
287 | // second time will overwrite previous results. | 294 | * second time will overwrite previous results. |
288 | // | 295 | * |
289 | // The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes. | 296 | * The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes. |
290 | // Int should always be 32 bits on any remotely Unix-like system, see | 297 | * Int should always be 32 bits on any remotely Unix-like system, see |
291 | // http://www.unix.org/whitepapers/64bit.html for the reasons why. | 298 | * http://www.unix.org/whitepapers/64bit.html for the reasons why. |
292 | 299 | */ | |
293 | static char local_buf[12]; | 300 | static char local_buf[12]; |
294 | 301 | ||
295 | // Convert unsigned integer to ascii using a static buffer (returned). | 302 | /* Convert unsigned integer to ascii using a static buffer (returned). */ |
296 | char *utoa(unsigned n) | 303 | char *utoa(unsigned n) |
297 | { | 304 | { |
298 | utoa_to_buf(n, local_buf, sizeof(local_buf)); | 305 | utoa_to_buf(n, local_buf, sizeof(local_buf)); |
@@ -300,7 +307,7 @@ char *utoa(unsigned n) | |||
300 | return local_buf; | 307 | return local_buf; |
301 | } | 308 | } |
302 | 309 | ||
303 | // Convert signed integer to ascii using a static buffer (returned). | 310 | /* Convert signed integer to ascii using a static buffer (returned). */ |
304 | char *itoa(int n) | 311 | char *itoa(int n) |
305 | { | 312 | { |
306 | itoa_to_buf(n, local_buf, sizeof(local_buf)); | 313 | itoa_to_buf(n, local_buf, sizeof(local_buf)); |
@@ -310,15 +317,15 @@ char *itoa(int n) | |||
310 | #endif | 317 | #endif |
311 | 318 | ||
312 | #ifdef L_setuid | 319 | #ifdef L_setuid |
313 | // Die with an error message if we can't set gid. (Because resource limits may | 320 | /* Die with an error message if we can't set gid. (Because resource limits may |
314 | // limit this user to a given number of processes, and if that fills up the | 321 | * limit this user to a given number of processes, and if that fills up the |
315 | // setgid() will fail and we'll _still_be_root_, which is bad.) | 322 | * setgid() will fail and we'll _still_be_root_, which is bad.) */ |
316 | void xsetgid(gid_t gid) | 323 | void xsetgid(gid_t gid) |
317 | { | 324 | { |
318 | if (setgid(gid)) bb_error_msg_and_die("setgid"); | 325 | if (setgid(gid)) bb_error_msg_and_die("setgid"); |
319 | } | 326 | } |
320 | 327 | ||
321 | // Die with an error message if we cant' set uid. (See xsetgid() for why.) | 328 | /* Die with an error message if we cant' set uid. (See xsetgid() for why.) */ |
322 | void xsetuid(uid_t uid) | 329 | void xsetuid(uid_t uid) |
323 | { | 330 | { |
324 | if (setuid(uid)) bb_error_msg_and_die("setuid"); | 331 | if (setuid(uid)) bb_error_msg_and_die("setuid"); |
@@ -326,31 +333,31 @@ void xsetuid(uid_t uid) | |||
326 | #endif | 333 | #endif |
327 | 334 | ||
328 | #ifdef L_fdlength | 335 | #ifdef L_fdlength |
329 | // Return how long the file at fd is, if there's any way to determine it. | 336 | /* Return how long the file at fd is, if there's any way to determine it. */ |
330 | off_t fdlength(int fd) | 337 | off_t fdlength(int fd) |
331 | { | 338 | { |
332 | off_t bottom = 0, top = 0, pos; | 339 | off_t bottom = 0, top = 0, pos; |
333 | long size; | 340 | long size; |
334 | 341 | ||
335 | // If the ioctl works for this, return it. | 342 | /* If the ioctl works for this, return it. */ |
336 | 343 | ||
337 | if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512; | 344 | if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512; |
338 | 345 | ||
339 | // If not, do a binary search for the last location we can read. (Some | 346 | /* If not, do a binary search for the last location we can read. (Some |
340 | // block devices don't do BLKGETSIZE right.) | 347 | * block devices don't do BLKGETSIZE right.) */ |
341 | 348 | ||
342 | do { | 349 | do { |
343 | char temp; | 350 | char temp; |
344 | 351 | ||
345 | pos = bottom + (top - bottom) / 2;; | 352 | pos = bottom + (top - bottom) / 2;; |
346 | 353 | ||
347 | // If we can read from the current location, it's bigger. | 354 | /* If we can read from the current location, it's bigger. */ |
348 | 355 | ||
349 | if (lseek(fd, pos, 0)>=0 && safe_read(fd, &temp, 1)==1) { | 356 | if (lseek(fd, pos, 0)>=0 && safe_read(fd, &temp, 1)==1) { |
350 | if (bottom == top) bottom = top = (top+1) * 2; | 357 | if (bottom == top) bottom = top = (top+1) * 2; |
351 | else bottom = pos; | 358 | else bottom = pos; |
352 | 359 | ||
353 | // If we can't, it's smaller. | 360 | /* If we can't, it's smaller. */ |
354 | 361 | ||
355 | } else { | 362 | } else { |
356 | if (bottom == top) { | 363 | if (bottom == top) { |
@@ -366,8 +373,8 @@ off_t fdlength(int fd) | |||
366 | #endif | 373 | #endif |
367 | 374 | ||
368 | #ifdef L_xasprintf | 375 | #ifdef L_xasprintf |
369 | // Die with an error message if we can't malloc() enough space and do an | 376 | /* Die with an error message if we can't malloc() enough space and do an |
370 | // sprintf() into that space. | 377 | * sprintf() into that space. */ |
371 | char *xasprintf(const char *format, ...) | 378 | char *xasprintf(const char *format, ...) |
372 | { | 379 | { |
373 | va_list p; | 380 | va_list p; |
@@ -396,8 +403,8 @@ char *xasprintf(const char *format, ...) | |||
396 | #endif | 403 | #endif |
397 | 404 | ||
398 | #ifdef L_xprint_and_close_file | 405 | #ifdef L_xprint_and_close_file |
399 | // Die with an error message if we can't copy an entire FILE * to stdout, then | 406 | /* Die with an error message if we can't copy an entire FILE * to stdout, then |
400 | // close that file. | 407 | * close that file. */ |
401 | void xprint_and_close_file(FILE *file) | 408 | void xprint_and_close_file(FILE *file) |
402 | { | 409 | { |
403 | // copyfd outputs error messages for us. | 410 | // copyfd outputs error messages for us. |
@@ -408,7 +415,7 @@ void xprint_and_close_file(FILE *file) | |||
408 | #endif | 415 | #endif |
409 | 416 | ||
410 | #ifdef L_xchdir | 417 | #ifdef L_xchdir |
411 | // Die if we can't chdir to a new path. | 418 | /* Die if we can't chdir to a new path. */ |
412 | void xchdir(const char *path) | 419 | void xchdir(const char *path) |
413 | { | 420 | { |
414 | if (chdir(path)) | 421 | if (chdir(path)) |
@@ -417,7 +424,7 @@ void xchdir(const char *path) | |||
417 | #endif | 424 | #endif |
418 | 425 | ||
419 | #ifdef L_warn_opendir | 426 | #ifdef L_warn_opendir |
420 | // Print a warning message if opendir() fails, but don't die. | 427 | /* Print a warning message if opendir() fails, but don't die. */ |
421 | DIR *warn_opendir(const char *path) | 428 | DIR *warn_opendir(const char *path) |
422 | { | 429 | { |
423 | DIR *dp; | 430 | DIR *dp; |
@@ -431,7 +438,7 @@ DIR *warn_opendir(const char *path) | |||
431 | #endif | 438 | #endif |
432 | 439 | ||
433 | #ifdef L_xopendir | 440 | #ifdef L_xopendir |
434 | // Die with an error message if opendir() fails. | 441 | /* Die with an error message if opendir() fails. */ |
435 | DIR *xopendir(const char *path) | 442 | DIR *xopendir(const char *path) |
436 | { | 443 | { |
437 | DIR *dp; | 444 | DIR *dp; |
@@ -444,7 +451,7 @@ DIR *xopendir(const char *path) | |||
444 | 451 | ||
445 | #ifdef L_xdaemon | 452 | #ifdef L_xdaemon |
446 | #ifndef BB_NOMMU | 453 | #ifndef BB_NOMMU |
447 | // Die with an error message if we can't daemonize. | 454 | /* Die with an error message if we can't daemonize. */ |
448 | void xdaemon(int nochdir, int noclose) | 455 | void xdaemon(int nochdir, int noclose) |
449 | { | 456 | { |
450 | if (daemon(nochdir, noclose)) bb_perror_msg_and_die("daemon"); | 457 | if (daemon(nochdir, noclose)) bb_perror_msg_and_die("daemon"); |
@@ -453,7 +460,7 @@ void xdaemon(int nochdir, int noclose) | |||
453 | #endif | 460 | #endif |
454 | 461 | ||
455 | #ifdef L_xsocket | 462 | #ifdef L_xsocket |
456 | // Die with an error message if we can't open a new socket. | 463 | /* Die with an error message if we can't open a new socket. */ |
457 | int xsocket(int domain, int type, int protocol) | 464 | int xsocket(int domain, int type, int protocol) |
458 | { | 465 | { |
459 | int r = socket(domain, type, protocol); | 466 | int r = socket(domain, type, protocol); |
@@ -465,7 +472,7 @@ int xsocket(int domain, int type, int protocol) | |||
465 | #endif | 472 | #endif |
466 | 473 | ||
467 | #ifdef L_xbind | 474 | #ifdef L_xbind |
468 | // Die with an error message if we can't bind a socket to an address. | 475 | /* Die with an error message if we can't bind a socket to an address. */ |
469 | void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) | 476 | void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) |
470 | { | 477 | { |
471 | if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind"); | 478 | if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind"); |
@@ -473,7 +480,7 @@ void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) | |||
473 | #endif | 480 | #endif |
474 | 481 | ||
475 | #ifdef L_xlisten | 482 | #ifdef L_xlisten |
476 | // Die with an error message if we can't listen for connections on a socket. | 483 | /* Die with an error message if we can't listen for connections on a socket. */ |
477 | void xlisten(int s, int backlog) | 484 | void xlisten(int s, int backlog) |
478 | { | 485 | { |
479 | if (listen(s, backlog)) bb_perror_msg_and_die("listen"); | 486 | if (listen(s, backlog)) bb_perror_msg_and_die("listen"); |
diff --git a/testsuite/all_sourcecode.tests b/testsuite/all_sourcecode.tests index 42360eb31..c115878fe 100755 --- a/testsuite/all_sourcecode.tests +++ b/testsuite/all_sourcecode.tests | |||
@@ -49,6 +49,7 @@ find $srcdir/../ \ | |||
49 | -e '\<algorithic\>' \ | 49 | -e '\<algorithic\>' \ |
50 | -e '\<deamon\>' \ | 50 | -e '\<deamon\>' \ |
51 | -e '\<derefernce\>' \ | 51 | -e '\<derefernce\>' \ |
52 | -e '\<acomadate\>' \ | ||
52 | | sed -e "s:^$srcdir/\.\./::g" > src.typos | 53 | | sed -e "s:^$srcdir/\.\./::g" > src.typos |
53 | testing "Common typos" "cat src.typos" "" "" "" | 54 | testing "Common typos" "cat src.typos" "" "" "" |
54 | rm -f src.typos | 55 | rm -f src.typos |
diff --git a/util-linux/ipcrm.c b/util-linux/ipcrm.c index 2e164b8b3..735a8955b 100644 --- a/util-linux/ipcrm.c +++ b/util-linux/ipcrm.c | |||
@@ -1,56 +1,22 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * ipcrm.c -- utility to allow removal of IPC objects and data structures. | 3 | * ipcrm.c - utility to allow removal of IPC objects and data structures. |
4 | * | 4 | * |
5 | * 01 Sept 2004 - Rodney Radford <rradford@mindspring.com> | 5 | * 01 Sept 2004 - Rodney Radford <rradford@mindspring.com> |
6 | * Adapted for busybox from util-linux-2.12a. | 6 | * Adapted for busybox from util-linux-2.12a. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | * | ||
22 | * --- Pre-busybox history from util-linux-2.12a ------------------------ | ||
23 | * | ||
24 | * 1999-04-02 frank zago | ||
25 | * - can now remove several id's in the same call | ||
26 | * | ||
27 | * 1999-02-22 Arkadiusz Miÿkiewicz <misiek@pld.ORG.PL> | ||
28 | * - added Native Language Support | ||
29 | * | ||
30 | * Original author - krishna balasubramanian 1993 | ||
31 | */ | 9 | */ |
32 | 10 | ||
33 | #include <stdio.h> | 11 | #include "busybox.h" |
34 | #include <stdlib.h> | ||
35 | #include <string.h> | ||
36 | #include <errno.h> | ||
37 | 12 | ||
38 | #include <sys/types.h> | 13 | /* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */ |
14 | /* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */ | ||
39 | #include <sys/ipc.h> | 15 | #include <sys/ipc.h> |
40 | #include <sys/shm.h> | 16 | #include <sys/shm.h> |
41 | #include <sys/msg.h> | 17 | #include <sys/msg.h> |
42 | #include <sys/sem.h> | 18 | #include <sys/sem.h> |
43 | 19 | ||
44 | /* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */ | ||
45 | /* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */ | ||
46 | /* for getopt */ | ||
47 | #include <unistd.h> | ||
48 | |||
49 | /* for tolower and isupper */ | ||
50 | #include <ctype.h> | ||
51 | |||
52 | #include "busybox.h" | ||
53 | |||
54 | #if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) | 20 | #if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) |
55 | /* union semun is defined by including <sys/sem.h> */ | 21 | /* union semun is defined by including <sys/sem.h> */ |
56 | #else | 22 | #else |
@@ -63,164 +29,149 @@ union semun { | |||
63 | }; | 29 | }; |
64 | #endif | 30 | #endif |
65 | 31 | ||
32 | #ifndef CONFIG_IPCRM_DROP_LEGACY | ||
33 | |||
66 | typedef enum type_id { | 34 | typedef enum type_id { |
67 | SHM, | 35 | SHM, |
68 | SEM, | 36 | SEM, |
69 | MSG | 37 | MSG |
70 | } type_id; | 38 | } type_id; |
71 | 39 | ||
72 | static int | 40 | static int remove_ids(type_id type, int argc, char **argv) |
73 | remove_ids(type_id type, int argc, char **argv) { | 41 | { |
74 | int id; | 42 | int id; |
75 | int ret = 0; /* for gcc */ | 43 | int ret = 0; /* silence gcc */ |
76 | char *end; | 44 | char *end; |
77 | int nb_errors = 0; | 45 | int nb_errors = 0; |
78 | union semun arg; | 46 | union semun arg; |
79 | 47 | ||
80 | arg.val = 0; | 48 | arg.val = 0; |
81 | 49 | ||
82 | while(argc) { | 50 | while (argc) { |
83 | 51 | ||
84 | id = strtoul(argv[0], &end, 10); | 52 | id = strtoul(argv[0], &end, 10); |
85 | 53 | ||
86 | if (*end != 0) { | 54 | if (*end != 0) { |
87 | bb_printf ("invalid id: %s\n", argv[0]); | 55 | bb_error_msg("invalid id: %s", argv[0]); |
88 | nb_errors ++; | 56 | nb_errors++; |
89 | } else { | 57 | } else { |
90 | switch(type) { | 58 | if (type == SEM) |
91 | case SEM: | 59 | ret = semctl(id, 0, IPC_RMID, arg); |
92 | ret = semctl (id, 0, IPC_RMID, arg); | 60 | else if (type == MSG) |
93 | break; | 61 | ret = msgctl(id, IPC_RMID, NULL); |
94 | 62 | else if (type == SHM) | |
95 | case MSG: | 63 | ret = shmctl(id, IPC_RMID, NULL); |
96 | ret = msgctl (id, IPC_RMID, NULL); | ||
97 | break; | ||
98 | |||
99 | case SHM: | ||
100 | ret = shmctl (id, IPC_RMID, NULL); | ||
101 | break; | ||
102 | } | ||
103 | 64 | ||
104 | if (ret) { | 65 | if (ret) { |
105 | bb_printf ("cannot remove id %s (%s)\n", | 66 | bb_perror_msg("cannot remove id %s", argv[0]); |
106 | argv[0], strerror(errno)); | 67 | nb_errors++; |
107 | nb_errors ++; | ||
108 | } | 68 | } |
109 | } | 69 | } |
110 | argc--; | 70 | argc--; |
111 | argv++; | 71 | argv++; |
112 | } | 72 | } |
113 | 73 | ||
114 | return(nb_errors); | 74 | return (nb_errors); |
115 | } | ||
116 | |||
117 | static int deprecated_main(int argc, char **argv) | ||
118 | { | ||
119 | if (argc < 3) { | ||
120 | bb_show_usage(); | ||
121 | bb_fflush_stdout_and_exit(1); | ||
122 | } | ||
123 | |||
124 | if (!strcmp(argv[1], "shm")) { | ||
125 | if (remove_ids(SHM, argc-2, &argv[2])) | ||
126 | bb_fflush_stdout_and_exit(1); | ||
127 | } | ||
128 | else if (!strcmp(argv[1], "msg")) { | ||
129 | if (remove_ids(MSG, argc-2, &argv[2])) | ||
130 | bb_fflush_stdout_and_exit(1); | ||
131 | } | ||
132 | else if (!strcmp(argv[1], "sem")) { | ||
133 | if (remove_ids(SEM, argc-2, &argv[2])) | ||
134 | bb_fflush_stdout_and_exit(1); | ||
135 | } | ||
136 | else { | ||
137 | bb_printf ("unknown resource type: %s\n", argv[1]); | ||
138 | bb_show_usage(); | ||
139 | bb_fflush_stdout_and_exit(1); | ||
140 | } | ||
141 | |||
142 | bb_printf ("resource(s) deleted\n"); | ||
143 | return 0; | ||
144 | } | 75 | } |
76 | #endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */ | ||
145 | 77 | ||
146 | 78 | ||
147 | int ipcrm_main(int argc, char **argv) | 79 | int ipcrm_main(int argc, char **argv) |
148 | { | 80 | { |
149 | int c; | 81 | int c; |
150 | int error = 0; | 82 | int error = 0; |
151 | char *prog = argv[0]; | ||
152 | 83 | ||
153 | /* if the command is executed without parameters, do nothing */ | 84 | /* if the command is executed without parameters, do nothing */ |
154 | if (argc == 1) | 85 | if (argc == 1) |
155 | return 0; | 86 | return 0; |
156 | 87 | #ifndef CONFIG_IPCRM_DROP_LEGACY | |
157 | /* check to see if the command is being invoked in the old way if so | 88 | /* check to see if the command is being invoked in the old way if so |
158 | then run the old code */ | 89 | then run the old code. Valid commands are msg, shm, sem. */ |
159 | if (strcmp(argv[1], "shm") == 0 || | 90 | { |
160 | strcmp(argv[1], "msg") == 0 || | 91 | type_id what = 0; /* silence gcc */ |
161 | strcmp(argv[1], "sem") == 0) | 92 | char w; |
162 | return deprecated_main(argc, argv); | 93 | |
94 | if ((((w=argv[1][0]) == 'm' && argv[1][1] == 's' && argv[1][2] == 'g') | ||
95 | || (argv[1][0] == 's' | ||
96 | && ((w=argv[1][1]) == 'h' || w == 'e') | ||
97 | && argv[1][2] == 'm')) | ||
98 | && argv[1][3] == '\0') { | ||
99 | |||
100 | if (argc < 3) | ||
101 | bb_show_usage(); | ||
102 | |||
103 | if (w == 'h') | ||
104 | what = SHM; | ||
105 | else if (w == 'm') | ||
106 | what = MSG; | ||
107 | else if (w == 'e') | ||
108 | what = SEM; | ||
109 | |||
110 | if (remove_ids(what, argc-2, &argv[2])) | ||
111 | bb_fflush_stdout_and_exit(1); | ||
112 | bb_printf("resource(s) deleted\n"); | ||
113 | return 0; | ||
114 | } | ||
115 | } | ||
116 | #endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */ | ||
163 | 117 | ||
164 | /* process new syntax to conform with SYSV ipcrm */ | 118 | /* process new syntax to conform with SYSV ipcrm */ |
165 | while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) { | 119 | while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) { |
166 | int result; | 120 | int result; |
167 | int id = 0; | 121 | int id = 0; |
168 | int iskey = isupper(c); | 122 | int iskey = (isupper)(c); |
169 | 123 | ||
170 | /* needed to delete semaphores */ | 124 | /* needed to delete semaphores */ |
171 | union semun arg; | 125 | union semun arg; |
126 | |||
172 | arg.val = 0; | 127 | arg.val = 0; |
173 | 128 | ||
174 | if ((c == '?') || (c == 'h')) | 129 | if ((c == '?') || (c == 'h')) { |
175 | { | ||
176 | bb_show_usage(); | 130 | bb_show_usage(); |
177 | return 0; | ||
178 | } | 131 | } |
179 | 132 | ||
180 | /* we don't need case information any more */ | 133 | /* we don't need case information any more */ |
181 | c = tolower(c); | 134 | c = tolower(c); |
182 | 135 | ||
183 | /* make sure the option is in range */ | 136 | /* make sure the option is in range: allowed are q, m, s */ |
184 | if (c != 'q' && c != 'm' && c != 's') { | 137 | if (c != 'q' && c != 'm' && c != 's') { |
185 | bb_show_usage(); | 138 | bb_show_usage(); |
186 | error++; | ||
187 | return error; | ||
188 | } | 139 | } |
189 | 140 | ||
190 | if (iskey) { | 141 | if (iskey) { |
191 | /* keys are in hex or decimal */ | 142 | /* keys are in hex or decimal */ |
192 | key_t key = strtoul(optarg, NULL, 0); | 143 | key_t key = strtoul(optarg, NULL, 0); |
144 | |||
193 | if (key == IPC_PRIVATE) { | 145 | if (key == IPC_PRIVATE) { |
194 | error++; | 146 | error++; |
195 | bb_fprintf(stderr, "%s: illegal key (%s)\n", | 147 | bb_error_msg("illegal key (%s)", optarg); |
196 | prog, optarg); | ||
197 | continue; | 148 | continue; |
198 | } | 149 | } |
199 | 150 | ||
200 | /* convert key to id */ | 151 | /* convert key to id */ |
201 | id = ((c == 'q') ? msgget(key, 0) : | 152 | id = ((c == 'q') ? msgget(key, 0) : |
202 | (c == 'm') ? shmget(key, 0, 0) : | 153 | (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0)); |
203 | semget(key, 0, 0)); | ||
204 | 154 | ||
205 | if (id < 0) { | 155 | if (id < 0) { |
206 | char *errmsg; | 156 | char *errmsg; |
157 | const char * const what = "key"; | ||
158 | |||
207 | error++; | 159 | error++; |
208 | switch(errno) { | 160 | switch (errno) { |
209 | case EACCES: | 161 | case EACCES: |
210 | errmsg = "permission denied for key"; | 162 | errmsg = "permission denied for"; |
211 | break; | 163 | break; |
212 | case EIDRM: | 164 | case EIDRM: |
213 | errmsg = "already removed key"; | 165 | errmsg = "already removed"; |
214 | break; | 166 | break; |
215 | case ENOENT: | 167 | case ENOENT: |
216 | errmsg = "invalid key"; | 168 | errmsg = "invalid"; |
217 | break; | 169 | break; |
218 | default: | 170 | default: |
219 | errmsg = "unknown error in key"; | 171 | errmsg = "unknown error in"; |
220 | break; | 172 | break; |
221 | } | 173 | } |
222 | bb_fprintf(stderr, "%s: %s (%s)\n", | 174 | bb_error_msg("%s %s (%s)", errmsg, what, optarg); |
223 | prog, errmsg, optarg); | ||
224 | continue; | 175 | continue; |
225 | } | 176 | } |
226 | } else { | 177 | } else { |
@@ -229,37 +180,30 @@ int ipcrm_main(int argc, char **argv) | |||
229 | } | 180 | } |
230 | 181 | ||
231 | result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) : | 182 | result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) : |
232 | (c == 'm') ? shmctl(id, IPC_RMID, NULL) : | 183 | (c == 'm') ? shmctl(id, IPC_RMID, NULL) : |
233 | semctl(id, 0, IPC_RMID, arg)); | 184 | semctl(id, 0, IPC_RMID, arg)); |
234 | 185 | ||
235 | if (result < 0) { | 186 | if (result) { |
236 | char *errmsg; | 187 | char *errmsg; |
188 | const char * const what = iskey ? "key" : "id"; | ||
189 | |||
237 | error++; | 190 | error++; |
238 | switch(errno) { | 191 | switch (errno) { |
239 | case EACCES: | 192 | case EACCES: |
240 | case EPERM: | 193 | case EPERM: |
241 | errmsg = iskey | 194 | errmsg = "permission denied for"; |
242 | ? "permission denied for key" | ||
243 | : "permission denied for id"; | ||
244 | break; | 195 | break; |
245 | case EINVAL: | 196 | case EINVAL: |
246 | errmsg = iskey | 197 | errmsg = "invalid"; |
247 | ? "invalid key" | ||
248 | : "invalid id"; | ||
249 | break; | 198 | break; |
250 | case EIDRM: | 199 | case EIDRM: |
251 | errmsg = iskey | 200 | errmsg = "already removed"; |
252 | ? "already removed key" | ||
253 | : "already removed id"; | ||
254 | break; | 201 | break; |
255 | default: | 202 | default: |
256 | errmsg = iskey | 203 | errmsg = "unknown error in"; |
257 | ? "unknown error in key" | ||
258 | : "unknown error in id"; | ||
259 | break; | 204 | break; |
260 | } | 205 | } |
261 | bb_fprintf(stderr, "%s: %s (%s)\n", | 206 | bb_error_msg("%s %s (%s)", errmsg, what, optarg); |
262 | prog, errmsg, optarg); | ||
263 | continue; | 207 | continue; |
264 | } | 208 | } |
265 | } | 209 | } |
diff --git a/util-linux/ipcs.c b/util-linux/ipcs.c index fbc75cbee..c7c837669 100644 --- a/util-linux/ipcs.c +++ b/util-linux/ipcs.c | |||
@@ -8,9 +8,7 @@ | |||
8 | * 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. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <stdio.h> | 11 | #include "busybox.h" |
12 | #include <stdlib.h> | ||
13 | #include <getopt.h> | ||
14 | #include <errno.h> | 12 | #include <errno.h> |
15 | #include <time.h> | 13 | #include <time.h> |
16 | #include <pwd.h> | 14 | #include <pwd.h> |
@@ -25,15 +23,15 @@ | |||
25 | #include <sys/msg.h> | 23 | #include <sys/msg.h> |
26 | #include <sys/shm.h> | 24 | #include <sys/shm.h> |
27 | 25 | ||
28 | #include "busybox.h" | 26 | |
29 | 27 | ||
30 | /*-------------------------------------------------------------------*/ | 28 | /*-------------------------------------------------------------------*/ |
31 | /* SHM_DEST and SHM_LOCKED are defined in kernel headers, | 29 | /* SHM_DEST and SHM_LOCKED are defined in kernel headers, |
32 | but inside #ifdef __KERNEL__ ... #endif */ | 30 | but inside #ifdef __KERNEL__ ... #endif */ |
33 | #ifndef SHM_DEST | 31 | #ifndef SHM_DEST |
34 | /* shm_mode upper byte flags */ | 32 | /* shm_mode upper byte flags */ |
35 | #define SHM_DEST 01000 /* segment will be destroyed on last detach */ | 33 | #define SHM_DEST 01000 /* segment will be destroyed on last detach */ |
36 | #define SHM_LOCKED 02000 /* segment will not be swapped */ | 34 | #define SHM_LOCKED 02000 /* segment will not be swapped */ |
37 | #endif | 35 | #endif |
38 | 36 | ||
39 | /* For older kernels the same holds for the defines below */ | 37 | /* For older kernels the same holds for the defines below */ |
@@ -46,12 +44,12 @@ | |||
46 | #define SHM_STAT 13 | 44 | #define SHM_STAT 13 |
47 | #define SHM_INFO 14 | 45 | #define SHM_INFO 14 |
48 | struct shm_info { | 46 | struct shm_info { |
49 | int used_ids; | 47 | int used_ids; |
50 | ulong shm_tot; /* total allocated shm */ | 48 | ulong shm_tot; /* total allocated shm */ |
51 | ulong shm_rss; /* total resident shm */ | 49 | ulong shm_rss; /* total resident shm */ |
52 | ulong shm_swp; /* total swapped shm */ | 50 | ulong shm_swp; /* total swapped shm */ |
53 | ulong swap_attempts; | 51 | ulong swap_attempts; |
54 | ulong swap_successes; | 52 | ulong swap_successes; |
55 | }; | 53 | }; |
56 | #endif | 54 | #endif |
57 | 55 | ||
@@ -98,12 +96,14 @@ union semun { | |||
98 | #define TIME 4 | 96 | #define TIME 4 |
99 | #define PID 5 | 97 | #define PID 5 |
100 | 98 | ||
99 | static char format; | ||
101 | 100 | ||
102 | static void print_perms (int id, struct ipc_perm *ipcp) { | 101 | static void print_perms(int id, struct ipc_perm *ipcp) |
102 | { | ||
103 | struct passwd *pw; | 103 | struct passwd *pw; |
104 | struct group *gr; | 104 | struct group *gr; |
105 | 105 | ||
106 | bb_printf ("%-10d %-10o", id, ipcp->mode & 0777); | 106 | bb_printf("%-10d %-10o", id, ipcp->mode & 0777); |
107 | 107 | ||
108 | if ((pw = getpwuid(ipcp->cuid))) | 108 | if ((pw = getpwuid(ipcp->cuid))) |
109 | bb_printf(" %-10s", pw->pw_name); | 109 | bb_printf(" %-10s", pw->pw_name); |
@@ -125,7 +125,7 @@ static void print_perms (int id, struct ipc_perm *ipcp) { | |||
125 | } | 125 | } |
126 | 126 | ||
127 | 127 | ||
128 | static void do_shm (char format) | 128 | static void do_shm(void) |
129 | { | 129 | { |
130 | int maxid, shmid, id; | 130 | int maxid, shmid, id; |
131 | struct shmid_ds shmseg; | 131 | struct shmid_ds shmseg; |
@@ -134,127 +134,125 @@ static void do_shm (char format) | |||
134 | struct ipc_perm *ipcp = &shmseg.shm_perm; | 134 | struct ipc_perm *ipcp = &shmseg.shm_perm; |
135 | struct passwd *pw; | 135 | struct passwd *pw; |
136 | 136 | ||
137 | maxid = shmctl (0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info); | 137 | maxid = shmctl(0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info); |
138 | if (maxid < 0) { | 138 | if (maxid < 0) { |
139 | bb_printf ("kernel not configured for shared memory\n"); | 139 | bb_printf("kernel not configured for shared memory\n"); |
140 | return; | 140 | return; |
141 | } | 141 | } |
142 | 142 | ||
143 | switch (format) { | 143 | switch (format) { |
144 | case LIMITS: | 144 | case LIMITS: |
145 | bb_printf ("------ Shared Memory Limits --------\n"); | 145 | bb_printf("------ Shared Memory Limits --------\n"); |
146 | if ((shmctl (0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0 ) | 146 | if ((shmctl(0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0) |
147 | return; | 147 | return; |
148 | /* glibc 2.1.3 and all earlier libc's have ints as fields | 148 | /* glibc 2.1.3 and all earlier libc's have ints as fields |
149 | of struct shminfo; glibc 2.1.91 has unsigned long; ach */ | 149 | of struct shminfo; glibc 2.1.91 has unsigned long; ach */ |
150 | bb_printf ("max number of segments = %lu\n" | 150 | bb_printf("max number of segments = %lu\n" |
151 | "max seg size (kbytes) = %lu\n" | 151 | "max seg size (kbytes) = %lu\n" |
152 | "max total shared memory (pages) = %lu\n" | 152 | "max total shared memory (pages) = %lu\n" |
153 | "min seg size (bytes) = %lu\n", | 153 | "min seg size (bytes) = %lu\n", |
154 | (unsigned long) shminfo.shmmni, | 154 | (unsigned long) shminfo.shmmni, |
155 | (unsigned long) (shminfo.shmmax >> 10), | 155 | (unsigned long) (shminfo.shmmax >> 10), |
156 | (unsigned long) shminfo.shmall, | 156 | (unsigned long) shminfo.shmall, |
157 | (unsigned long) shminfo.shmmin); | 157 | (unsigned long) shminfo.shmmin); |
158 | return; | 158 | return; |
159 | 159 | ||
160 | case STATUS: | 160 | case STATUS: |
161 | bb_printf ("------ Shared Memory Status --------\n" | 161 | bb_printf("------ Shared Memory Status --------\n" |
162 | "segments allocated %d\n" | 162 | "segments allocated %d\n" |
163 | "pages allocated %ld\n" | 163 | "pages allocated %ld\n" |
164 | "pages resident %ld\n" | 164 | "pages resident %ld\n" |
165 | "pages swapped %ld\n" | 165 | "pages swapped %ld\n" |
166 | "Swap performance: %ld attempts\t %ld successes\n", | 166 | "Swap performance: %ld attempts\t %ld successes\n", |
167 | shm_info.used_ids, | 167 | shm_info.used_ids, |
168 | shm_info.shm_tot, | 168 | shm_info.shm_tot, |
169 | shm_info.shm_rss, | 169 | shm_info.shm_rss, |
170 | shm_info.shm_swp, | 170 | shm_info.shm_swp, |
171 | shm_info.swap_attempts, shm_info.swap_successes); | 171 | shm_info.swap_attempts, shm_info.swap_successes); |
172 | return; | 172 | return; |
173 | 173 | ||
174 | case CREATOR: | 174 | case CREATOR: |
175 | bb_printf ("------ Shared Memory Segment Creators/Owners --------\n" | 175 | bb_printf("------ Shared Memory Segment Creators/Owners --------\n" |
176 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", | 176 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", |
177 | "shmid","perms","cuid","cgid","uid","gid"); | 177 | "shmid", "perms", "cuid", "cgid", "uid", "gid"); |
178 | break; | 178 | break; |
179 | 179 | ||
180 | case TIME: | 180 | case TIME: |
181 | bb_printf ("------ Shared Memory Attach/Detach/Change Times --------\n" | 181 | bb_printf("------ Shared Memory Attach/Detach/Change Times --------\n" |
182 | "%-10s %-10s %-20s %-20s %-20s\n", | 182 | "%-10s %-10s %-20s %-20s %-20s\n", |
183 | "shmid","owner","attached","detached","changed"); | 183 | "shmid", "owner", "attached", "detached", "changed"); |
184 | break; | 184 | break; |
185 | 185 | ||
186 | case PID: | 186 | case PID: |
187 | bb_printf ("------ Shared Memory Creator/Last-op --------\n" | 187 | bb_printf("------ Shared Memory Creator/Last-op --------\n" |
188 | "%-10s %-10s %-10s %-10s\n", | 188 | "%-10s %-10s %-10s %-10s\n", |
189 | "shmid","owner","cpid","lpid"); | 189 | "shmid", "owner", "cpid", "lpid"); |
190 | break; | 190 | break; |
191 | 191 | ||
192 | default: | 192 | default: |
193 | bb_printf ("------ Shared Memory Segments --------\n" | 193 | bb_printf("------ Shared Memory Segments --------\n" |
194 | "%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n", | 194 | "%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n", |
195 | "key","shmid","owner","perms","bytes","nattch","status"); | 195 | "key", "shmid", "owner", "perms", "bytes", "nattch", |
196 | "status"); | ||
196 | break; | 197 | break; |
197 | } | 198 | } |
198 | 199 | ||
199 | for (id = 0; id <= maxid; id++) { | 200 | for (id = 0; id <= maxid; id++) { |
200 | shmid = shmctl (id, SHM_STAT, &shmseg); | 201 | shmid = shmctl(id, SHM_STAT, &shmseg); |
201 | if (shmid < 0) | 202 | if (shmid < 0) |
202 | continue; | 203 | continue; |
203 | if (format == CREATOR) { | 204 | if (format == CREATOR) { |
204 | print_perms (shmid, ipcp); | 205 | print_perms(shmid, ipcp); |
205 | continue; | 206 | continue; |
206 | } | 207 | } |
207 | pw = getpwuid(ipcp->uid); | 208 | pw = getpwuid(ipcp->uid); |
208 | switch (format) { | 209 | switch (format) { |
209 | case TIME: | 210 | case TIME: |
210 | if (pw) | 211 | if (pw) |
211 | bb_printf ("%-10d %-10.10s", shmid, pw->pw_name); | 212 | bb_printf("%-10d %-10.10s", shmid, pw->pw_name); |
212 | else | 213 | else |
213 | bb_printf ("%-10d %-10d", shmid, ipcp->uid); | 214 | bb_printf("%-10d %-10d", shmid, ipcp->uid); |
214 | /* ctime uses static buffer: use separate calls */ | 215 | /* ctime uses static buffer: use separate calls */ |
215 | bb_printf(" %-20.16s", shmseg.shm_atime | 216 | bb_printf(" %-20.16s", shmseg.shm_atime |
216 | ? ctime(&shmseg.shm_atime) + 4 : "Not set"); | 217 | ? ctime(&shmseg.shm_atime) + 4 : "Not set"); |
217 | bb_printf(" %-20.16s", shmseg.shm_dtime | 218 | bb_printf(" %-20.16s", shmseg.shm_dtime |
218 | ? ctime(&shmseg.shm_dtime) + 4 : "Not set"); | 219 | ? ctime(&shmseg.shm_dtime) + 4 : "Not set"); |
219 | bb_printf(" %-20.16s\n", shmseg.shm_ctime | 220 | bb_printf(" %-20.16s\n", shmseg.shm_ctime |
220 | ? ctime(&shmseg.shm_ctime) + 4 : "Not set"); | 221 | ? ctime(&shmseg.shm_ctime) + 4 : "Not set"); |
221 | break; | 222 | break; |
222 | case PID: | 223 | case PID: |
223 | if (pw) | 224 | if (pw) |
224 | bb_printf ("%-10d %-10.10s", shmid, pw->pw_name); | 225 | bb_printf("%-10d %-10.10s", shmid, pw->pw_name); |
225 | else | 226 | else |
226 | bb_printf ("%-10d %-10d", shmid, ipcp->uid); | 227 | bb_printf("%-10d %-10d", shmid, ipcp->uid); |
227 | bb_printf (" %-10d %-10d\n", | 228 | bb_printf(" %-10d %-10d\n", shmseg.shm_cpid, shmseg.shm_lpid); |
228 | shmseg.shm_cpid, shmseg.shm_lpid); | ||
229 | break; | 229 | break; |
230 | 230 | ||
231 | default: | 231 | default: |
232 | bb_printf("0x%08x ",ipcp->KEY ); | 232 | bb_printf("0x%08x ", ipcp->KEY); |
233 | if (pw) | 233 | if (pw) |
234 | bb_printf ("%-10d %-10.10s", shmid, pw->pw_name); | 234 | bb_printf("%-10d %-10.10s", shmid, pw->pw_name); |
235 | else | 235 | else |
236 | bb_printf ("%-10d %-10d", shmid, ipcp->uid); | 236 | bb_printf("%-10d %-10d", shmid, ipcp->uid); |
237 | bb_printf ("%-10o %-10lu %-10ld %-6s %-6s\n", | 237 | bb_printf("%-10o %-10lu %-10ld %-6s %-6s\n", ipcp->mode & 0777, |
238 | ipcp->mode & 0777, | 238 | /* |
239 | /* | 239 | * earlier: int, Austin has size_t |
240 | * earlier: int, Austin has size_t | 240 | */ |
241 | */ | 241 | (unsigned long) shmseg.shm_segsz, |
242 | (unsigned long) shmseg.shm_segsz, | 242 | /* |
243 | /* | 243 | * glibc-2.1.3 and earlier has unsigned short; |
244 | * glibc-2.1.3 and earlier has unsigned short; | 244 | * Austin has shmatt_t |
245 | * Austin has shmatt_t | 245 | */ |
246 | */ | 246 | (long) shmseg.shm_nattch, |
247 | (long) shmseg.shm_nattch, | 247 | ipcp->mode & SHM_DEST ? "dest" : " ", |
248 | ipcp->mode & SHM_DEST ? "dest" : " ", | 248 | ipcp->mode & SHM_LOCKED ? "locked" : " "); |
249 | ipcp->mode & SHM_LOCKED ? "locked" : " "); | ||
250 | break; | 249 | break; |
251 | } | 250 | } |
252 | } | 251 | } |
253 | return; | ||
254 | } | 252 | } |
255 | 253 | ||
256 | 254 | ||
257 | static void do_sem (char format) | 255 | static void do_sem(void) |
258 | { | 256 | { |
259 | int maxid, semid, id; | 257 | int maxid, semid, id; |
260 | struct semid_ds semary; | 258 | struct semid_ds semary; |
@@ -263,107 +261,104 @@ static void do_sem (char format) | |||
263 | struct passwd *pw; | 261 | struct passwd *pw; |
264 | union semun arg; | 262 | union semun arg; |
265 | 263 | ||
266 | arg.array = (ushort *) (void *) &seminfo; | 264 | arg.array = (ushort *) (void *) &seminfo; |
267 | maxid = semctl (0, 0, SEM_INFO, arg); | 265 | maxid = semctl(0, 0, SEM_INFO, arg); |
268 | if (maxid < 0) { | 266 | if (maxid < 0) { |
269 | bb_printf ("kernel not configured for semaphores\n"); | 267 | bb_printf("kernel not configured for semaphores\n"); |
270 | return; | 268 | return; |
271 | } | 269 | } |
272 | 270 | ||
273 | switch (format) { | 271 | switch (format) { |
274 | case LIMITS: | 272 | case LIMITS: |
275 | bb_printf ("------ Semaphore Limits --------\n"); | 273 | bb_printf("------ Semaphore Limits --------\n"); |
276 | arg.array = (ushort *) (void *) &seminfo; /* damn union */ | 274 | arg.array = (ushort *) (void *) &seminfo; /* damn union */ |
277 | if ((semctl (0, 0, IPC_INFO, arg)) < 0 ) | 275 | if ((semctl(0, 0, IPC_INFO, arg)) < 0) |
278 | return; | 276 | return; |
279 | bb_printf ("max number of arrays = %d\n" | 277 | bb_printf("max number of arrays = %d\n" |
280 | "max semaphores per array = %d\n" | 278 | "max semaphores per array = %d\n" |
281 | "max semaphores system wide = %d\n" | 279 | "max semaphores system wide = %d\n" |
282 | "max ops per semop call = %d\n" | 280 | "max ops per semop call = %d\n" |
283 | "semaphore max value = %d\n", | 281 | "semaphore max value = %d\n", |
284 | seminfo.semmni, | 282 | seminfo.semmni, |
285 | seminfo.semmsl, | 283 | seminfo.semmsl, |
286 | seminfo.semmns, | 284 | seminfo.semmns, seminfo.semopm, seminfo.semvmx); |
287 | seminfo.semopm, | ||
288 | seminfo.semvmx); | ||
289 | return; | 285 | return; |
290 | 286 | ||
291 | case STATUS: | 287 | case STATUS: |
292 | bb_printf ("------ Semaphore Status --------\n" | 288 | bb_printf("------ Semaphore Status --------\n" |
293 | "used arrays = %d\n" | 289 | "used arrays = %d\n" |
294 | "allocated semaphores = %d\n", | 290 | "allocated semaphores = %d\n", |
295 | seminfo.semusz, | 291 | seminfo.semusz, seminfo.semaem); |
296 | seminfo.semaem); | ||
297 | return; | 292 | return; |
298 | 293 | ||
299 | case CREATOR: | 294 | case CREATOR: |
300 | bb_printf ("------ Semaphore Arrays Creators/Owners --------\n" | 295 | bb_printf("------ Semaphore Arrays Creators/Owners --------\n" |
301 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", | 296 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", |
302 | "semid","perms","cuid","cgid","uid","gid"); | 297 | "semid", "perms", "cuid", "cgid", "uid", "gid"); |
303 | break; | 298 | break; |
304 | 299 | ||
305 | case TIME: | 300 | case TIME: |
306 | bb_printf ("------ Shared Memory Operation/Change Times --------\n" | 301 | bb_printf("------ Shared Memory Operation/Change Times --------\n" |
307 | "%-8s %-10s %-26.24s %-26.24s\n", | 302 | "%-8s %-10s %-26.24s %-26.24s\n", |
308 | "shmid","owner","last-op","last-changed"); | 303 | "shmid", "owner", "last-op", "last-changed"); |
309 | break; | 304 | break; |
310 | 305 | ||
311 | case PID: | 306 | case PID: |
312 | break; | 307 | break; |
313 | 308 | ||
314 | default: | 309 | default: |
315 | bb_printf ("------ Semaphore Arrays --------\n" | 310 | bb_printf("------ Semaphore Arrays --------\n" |
316 | "%-10s %-10s %-10s %-10s %-10s\n", | 311 | "%-10s %-10s %-10s %-10s %-10s\n", |
317 | "key","semid","owner","perms","nsems"); | 312 | "key", "semid", "owner", "perms", "nsems"); |
318 | break; | 313 | break; |
319 | } | 314 | } |
320 | 315 | ||
321 | for (id = 0; id <= maxid; id++) { | 316 | for (id = 0; id <= maxid; id++) { |
322 | arg.buf = (struct semid_ds *) &semary; | 317 | arg.buf = (struct semid_ds *) &semary; |
323 | semid = semctl (id, 0, SEM_STAT, arg); | 318 | semid = semctl(id, 0, SEM_STAT, arg); |
324 | if (semid < 0) | 319 | if (semid < 0) |
325 | continue; | 320 | continue; |
326 | if (format == CREATOR) { | 321 | if (format == CREATOR) { |
327 | print_perms (semid, ipcp); | 322 | print_perms(semid, ipcp); |
328 | continue; | 323 | continue; |
329 | } | 324 | } |
330 | pw = getpwuid(ipcp->uid); | 325 | pw = getpwuid(ipcp->uid); |
331 | switch (format) { | 326 | switch (format) { |
332 | case TIME: | 327 | case TIME: |
333 | if (pw) | 328 | if (pw) |
334 | bb_printf ("%-8d %-10.10s", semid, pw->pw_name); | 329 | bb_printf("%-8d %-10.10s", semid, pw->pw_name); |
335 | else | 330 | else |
336 | bb_printf ("%-8d %-10d", semid, ipcp->uid); | 331 | bb_printf("%-8d %-10d", semid, ipcp->uid); |
337 | bb_printf (" %-26.24s", semary.sem_otime | 332 | /* ctime uses static buffer: use separate calls */ |
338 | ? ctime(&semary.sem_otime) : "Not set"); | 333 | bb_printf(" %-26.24s", semary.sem_otime |
339 | bb_printf (" %-26.24s\n", semary.sem_ctime | 334 | ? ctime(&semary.sem_otime) : "Not set"); |
340 | ? ctime(&semary.sem_ctime) : "Not set"); | 335 | bb_printf(" %-26.24s\n", semary.sem_ctime |
336 | ? ctime(&semary.sem_ctime) : "Not set"); | ||
341 | break; | 337 | break; |
342 | case PID: | 338 | case PID: |
343 | break; | 339 | break; |
344 | 340 | ||
345 | default: | 341 | default: |
346 | bb_printf("0x%08x ", ipcp->KEY); | 342 | bb_printf("0x%08x ", ipcp->KEY); |
347 | if (pw) | 343 | if (pw) |
348 | bb_printf ("%-10d %-10.9s", semid, pw->pw_name); | 344 | bb_printf("%-10d %-10.9s", semid, pw->pw_name); |
349 | else | 345 | else |
350 | bb_printf ("%-10d %-9d", semid, ipcp->uid); | 346 | bb_printf("%-10d %-9d", semid, ipcp->uid); |
351 | bb_printf ("%-10o %-10ld\n", | 347 | bb_printf("%-10o %-10ld\n", ipcp->mode & 0777, |
352 | ipcp->mode & 0777, | 348 | /* |
353 | /* | 349 | * glibc-2.1.3 and earlier has unsigned short; |
354 | * glibc-2.1.3 and earlier has unsigned short; | 350 | * glibc-2.1.91 has variation between |
355 | * glibc-2.1.91 has variation between | 351 | * unsigned short and unsigned long |
356 | * unsigned short and unsigned long | 352 | * Austin prescribes unsigned short. |
357 | * Austin prescribes unsigned short. | 353 | */ |
358 | */ | 354 | (long) semary.sem_nsems); |
359 | (long) semary.sem_nsems); | ||
360 | break; | 355 | break; |
361 | } | 356 | } |
362 | } | 357 | } |
363 | } | 358 | } |
364 | 359 | ||
365 | 360 | ||
366 | static void do_msg (char format) | 361 | static void do_msg(void) |
367 | { | 362 | { |
368 | int maxid, msqid, id; | 363 | int maxid, msqid, id; |
369 | struct msqid_ds msgque; | 364 | struct msqid_ds msgque; |
@@ -371,178 +366,165 @@ static void do_msg (char format) | |||
371 | struct ipc_perm *ipcp = &msgque.msg_perm; | 366 | struct ipc_perm *ipcp = &msgque.msg_perm; |
372 | struct passwd *pw; | 367 | struct passwd *pw; |
373 | 368 | ||
374 | maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo); | 369 | maxid = msgctl(0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo); |
375 | if (maxid < 0) { | 370 | if (maxid < 0) { |
376 | bb_printf ("kernel not configured for message queues\n"); | 371 | bb_printf("kernel not configured for message queues\n"); |
377 | return; | 372 | return; |
378 | } | 373 | } |
379 | 374 | ||
380 | switch (format) { | 375 | switch (format) { |
381 | case LIMITS: | 376 | case LIMITS: |
382 | if ((msgctl (0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0 ) | 377 | if ((msgctl(0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0) |
383 | return; | 378 | return; |
384 | bb_printf ("------ Messages: Limits --------\n" | 379 | bb_printf("------ Messages: Limits --------\n" |
385 | "max queues system wide = %d\n" | 380 | "max queues system wide = %d\n" |
386 | "max size of message (bytes) = %d\n" | 381 | "max size of message (bytes) = %d\n" |
387 | "default max size of queue (bytes) = %d\n", | 382 | "default max size of queue (bytes) = %d\n", |
388 | msginfo.msgmni, | 383 | msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb); |
389 | msginfo.msgmax, | ||
390 | msginfo.msgmnb); | ||
391 | return; | 384 | return; |
392 | 385 | ||
393 | case STATUS: | 386 | case STATUS: |
394 | bb_printf ("------ Messages: Status --------\n" | 387 | bb_printf("------ Messages: Status --------\n" |
395 | "allocated queues = %d\n" | 388 | "allocated queues = %d\n" |
396 | "used headers = %d\n" | 389 | "used headers = %d\n" |
397 | "used space = %d bytes\n", | 390 | "used space = %d bytes\n", |
398 | msginfo.msgpool, | 391 | msginfo.msgpool, msginfo.msgmap, msginfo.msgtql); |
399 | msginfo.msgmap, | ||
400 | msginfo.msgtql); | ||
401 | return; | 392 | return; |
402 | 393 | ||
403 | case CREATOR: | 394 | case CREATOR: |
404 | bb_printf ("------ Message Queues: Creators/Owners --------\n" | 395 | bb_printf("------ Message Queues: Creators/Owners --------\n" |
405 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", | 396 | "%-10s %-10s %-10s %-10s %-10s %-10s\n", |
406 | "msqid","perms","cuid","cgid","uid","gid"); | 397 | "msqid", "perms", "cuid", "cgid", "uid", "gid"); |
407 | break; | 398 | break; |
408 | 399 | ||
409 | case TIME: | 400 | case TIME: |
410 | bb_printf ("------ Message Queues Send/Recv/Change Times --------\n" | 401 | bb_printf("------ Message Queues Send/Recv/Change Times --------\n" |
411 | "%-8s %-10s %-20s %-20s %-20s\n", | 402 | "%-8s %-10s %-20s %-20s %-20s\n", |
412 | "msqid","owner","send","recv","change"); | 403 | "msqid", "owner", "send", "recv", "change"); |
413 | break; | 404 | break; |
414 | 405 | ||
415 | case PID: | 406 | case PID: |
416 | bb_printf ("------ Message Queues PIDs --------\n" | 407 | bb_printf("------ Message Queues PIDs --------\n" |
417 | "%-10s %-10s %-10s %-10s\n", | 408 | "%-10s %-10s %-10s %-10s\n", |
418 | "msqid","owner","lspid","lrpid"); | 409 | "msqid", "owner", "lspid", "lrpid"); |
419 | break; | 410 | break; |
420 | 411 | ||
421 | default: | 412 | default: |
422 | bb_printf ("------ Message Queues --------\n" | 413 | bb_printf("------ Message Queues --------\n" |
423 | "%-10s %-10s %-10s %-10s %-12s %-12s\n", | 414 | "%-10s %-10s %-10s %-10s %-12s %-12s\n", |
424 | "key","msqid","owner","perms","used-bytes","messages"); | 415 | "key", "msqid", "owner", "perms", "used-bytes", "messages"); |
425 | break; | 416 | break; |
426 | } | 417 | } |
427 | 418 | ||
428 | for (id = 0; id <= maxid; id++) { | 419 | for (id = 0; id <= maxid; id++) { |
429 | msqid = msgctl (id, MSG_STAT, &msgque); | 420 | msqid = msgctl(id, MSG_STAT, &msgque); |
430 | if (msqid < 0) | 421 | if (msqid < 0) |
431 | continue; | 422 | continue; |
432 | if (format == CREATOR) { | 423 | if (format == CREATOR) { |
433 | print_perms (msqid, ipcp); | 424 | print_perms(msqid, ipcp); |
434 | continue; | 425 | continue; |
435 | } | 426 | } |
436 | pw = getpwuid(ipcp->uid); | 427 | pw = getpwuid(ipcp->uid); |
437 | switch (format) { | 428 | switch (format) { |
438 | case TIME: | 429 | case TIME: |
439 | if (pw) | 430 | if (pw) |
440 | bb_printf ("%-8d %-10.10s", msqid, pw->pw_name); | 431 | bb_printf("%-8d %-10.10s", msqid, pw->pw_name); |
441 | else | 432 | else |
442 | bb_printf ("%-8d %-10d", msqid, ipcp->uid); | 433 | bb_printf("%-8d %-10d", msqid, ipcp->uid); |
443 | bb_printf (" %-20.16s", msgque.msg_stime | 434 | bb_printf(" %-20.16s", msgque.msg_stime |
444 | ? ctime(&msgque.msg_stime) + 4 : "Not set"); | 435 | ? ctime(&msgque.msg_stime) + 4 : "Not set"); |
445 | bb_printf (" %-20.16s", msgque.msg_rtime | 436 | bb_printf(" %-20.16s", msgque.msg_rtime |
446 | ? ctime(&msgque.msg_rtime) + 4 : "Not set"); | 437 | ? ctime(&msgque.msg_rtime) + 4 : "Not set"); |
447 | bb_printf (" %-20.16s\n", msgque.msg_ctime | 438 | bb_printf(" %-20.16s\n", msgque.msg_ctime |
448 | ? ctime(&msgque.msg_ctime) + 4 : "Not set"); | 439 | ? ctime(&msgque.msg_ctime) + 4 : "Not set"); |
449 | break; | 440 | break; |
450 | case PID: | 441 | case PID: |
451 | if (pw) | 442 | if (pw) |
452 | bb_printf ("%-8d %-10.10s", msqid, pw->pw_name); | 443 | bb_printf("%-8d %-10.10s", msqid, pw->pw_name); |
453 | else | 444 | else |
454 | bb_printf ("%-8d %-10d", msqid, ipcp->uid); | 445 | bb_printf("%-8d %-10d", msqid, ipcp->uid); |
455 | bb_printf (" %5d %5d\n", | 446 | bb_printf(" %5d %5d\n", msgque.msg_lspid, msgque.msg_lrpid); |
456 | msgque.msg_lspid, msgque.msg_lrpid); | ||
457 | break; | 447 | break; |
458 | 448 | ||
459 | default: | 449 | default: |
460 | bb_printf( "0x%08x ",ipcp->KEY ); | 450 | bb_printf("0x%08x ", ipcp->KEY); |
461 | if (pw) | 451 | if (pw) |
462 | bb_printf ("%-10d %-10.10s", msqid, pw->pw_name); | 452 | bb_printf("%-10d %-10.10s", msqid, pw->pw_name); |
463 | else | 453 | else |
464 | bb_printf ("%-10d %-10d", msqid, ipcp->uid); | 454 | bb_printf("%-10d %-10d", msqid, ipcp->uid); |
465 | bb_printf (" %-10o %-12ld %-12ld\n", | 455 | bb_printf(" %-10o %-12ld %-12ld\n", ipcp->mode & 0777, |
466 | ipcp->mode & 0777, | 456 | /* |
467 | /* | 457 | * glibc-2.1.3 and earlier has unsigned short; |
468 | * glibc-2.1.3 and earlier has unsigned short; | 458 | * glibc-2.1.91 has variation between |
469 | * glibc-2.1.91 has variation between | 459 | * unsigned short, unsigned long |
470 | * unsigned short, unsigned long | 460 | * Austin has msgqnum_t |
471 | * Austin has msgqnum_t | 461 | */ |
472 | */ | 462 | (long) msgque.msg_cbytes, (long) msgque.msg_qnum); |
473 | (long) msgque.msg_cbytes, | ||
474 | (long) msgque.msg_qnum); | ||
475 | break; | 463 | break; |
476 | } | 464 | } |
477 | } | 465 | } |
478 | return; | ||
479 | } | 466 | } |
480 | 467 | ||
481 | 468 | ||
482 | static void print_shm (int shmid) | 469 | static void print_shm(int shmid) |
483 | { | 470 | { |
484 | struct shmid_ds shmds; | 471 | struct shmid_ds shmds; |
485 | struct ipc_perm *ipcp = &shmds.shm_perm; | 472 | struct ipc_perm *ipcp = &shmds.shm_perm; |
486 | 473 | ||
487 | if (shmctl (shmid, IPC_STAT, &shmds) == -1) { | 474 | if (shmctl(shmid, IPC_STAT, &shmds) == -1) { |
488 | perror ("shmctl "); | 475 | bb_perror_msg("shmctl"); |
489 | return; | 476 | return; |
490 | } | 477 | } |
491 | 478 | ||
492 | bb_printf ("\nShared memory Segment shmid=%d\n" | 479 | bb_printf("\nShared memory Segment shmid=%d\n" |
493 | "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n" | 480 | "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n" |
494 | "mode=%#o\taccess_perms=%#o\n" | 481 | "mode=%#o\taccess_perms=%#o\n" |
495 | "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n" | 482 | "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n", |
496 | "att_time=%-26.24s\n" | 483 | shmid, |
497 | "det_time=%-26.24s\n" | 484 | ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, |
498 | "change_time=%-26.24s\n" | 485 | ipcp->mode, ipcp->mode & 0777, |
499 | "\n", | 486 | (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid, |
500 | shmid, | 487 | (long) shmds.shm_nattch); |
501 | ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, | 488 | bb_printf("att_time=%-26.24s\n", |
502 | ipcp->mode, ipcp->mode & 0777, | 489 | shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set"); |
503 | (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid, | 490 | bb_printf("det_time=%-26.24s\n", |
504 | (long) shmds.shm_nattch, | 491 | shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set"); |
505 | shmds.shm_atime ? ctime (&shmds.shm_atime) : "Not set", | 492 | bb_printf("change_time=%-26.24s\n\n", ctime(&shmds.shm_ctime)); |
506 | shmds.shm_dtime ? ctime (&shmds.shm_dtime) : "Not set", | ||
507 | ctime (&shmds.shm_ctime)); | ||
508 | return; | ||
509 | } | 493 | } |
510 | 494 | ||
511 | 495 | ||
512 | static void print_msg (int msqid) | 496 | static void print_msg(int msqid) |
513 | { | 497 | { |
514 | struct msqid_ds buf; | 498 | struct msqid_ds buf; |
515 | struct ipc_perm *ipcp = &buf.msg_perm; | 499 | struct ipc_perm *ipcp = &buf.msg_perm; |
516 | 500 | ||
517 | if (msgctl (msqid, IPC_STAT, &buf) == -1) { | 501 | if (msgctl(msqid, IPC_STAT, &buf) == -1) { |
518 | perror ("msgctl "); | 502 | bb_perror_msg("msgctl"); |
519 | return; | 503 | return; |
520 | } | 504 | } |
521 | 505 | ||
522 | bb_printf ("\nMessage Queue msqid=%d\n" | 506 | bb_printf("\nMessage Queue msqid=%d\n" |
523 | "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n" | 507 | "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n" |
524 | "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n" | 508 | "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n", |
525 | "send_time=%-26.24s\n" | 509 | msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode, |
526 | "rcv_time=%-26.24s\n" | 510 | /* |
527 | "change_time=%-26.24s\n" | 511 | * glibc-2.1.3 and earlier has unsigned short; |
528 | "\n", | 512 | * glibc-2.1.91 has variation between |
529 | msqid, | 513 | * unsigned short, unsigned long |
530 | ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode, | 514 | * Austin has msgqnum_t (for msg_qbytes) |
531 | /* | 515 | */ |
532 | * glibc-2.1.3 and earlier has unsigned short; | 516 | (long) buf.msg_cbytes, (long) buf.msg_qbytes, |
533 | * glibc-2.1.91 has variation between | 517 | (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid); |
534 | * unsigned short, unsigned long | 518 | |
535 | * Austin has msgqnum_t (for msg_qbytes) | 519 | bb_printf("send_time=%-26.24s\n", |
536 | */ | 520 | buf.msg_stime ? ctime(&buf.msg_stime) : "Not set"); |
537 | (long) buf.msg_cbytes, (long) buf.msg_qbytes, | 521 | bb_printf("rcv_time=%-26.24s\n", |
538 | (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid, | 522 | buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set"); |
539 | buf.msg_stime ? ctime (&buf.msg_stime) : "Not set", | 523 | bb_printf("change_time=%-26.24s\n\n", |
540 | buf.msg_rtime ? ctime (&buf.msg_rtime) : "Not set", | 524 | buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set"); |
541 | buf.msg_ctime ? ctime (&buf.msg_ctime) : "Not set"); | ||
542 | return; | ||
543 | } | 525 | } |
544 | 526 | ||
545 | static void print_sem (int semid) | 527 | static void print_sem(int semid) |
546 | { | 528 | { |
547 | struct semid_ds semds; | 529 | struct semid_ds semds; |
548 | struct ipc_perm *ipcp = &semds.sem_perm; | 530 | struct ipc_perm *ipcp = &semds.sem_perm; |
@@ -550,66 +532,69 @@ static void print_sem (int semid) | |||
550 | unsigned int i; | 532 | unsigned int i; |
551 | 533 | ||
552 | arg.buf = &semds; | 534 | arg.buf = &semds; |
553 | if (semctl (semid, 0, IPC_STAT, arg) < 0) { | 535 | if (semctl(semid, 0, IPC_STAT, arg)) { |
554 | perror ("semctl "); | 536 | bb_perror_msg("semctl"); |
555 | return; | 537 | return; |
556 | } | 538 | } |
557 | 539 | ||
558 | bb_printf ("\nSemaphore Array semid=%d\n" | 540 | bb_printf("\nSemaphore Array semid=%d\n" |
559 | "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n" | 541 | "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n" |
560 | "mode=%#o, access_perms=%#o\n" | 542 | "mode=%#o, access_perms=%#o\n" |
561 | "nsems = %ld\n" | 543 | "nsems = %ld\n" |
562 | "otime = %-26.24s\n" | 544 | "otime = %-26.24s\n", |
563 | "ctime = %-26.24s\n" | 545 | semid, |
564 | "%-10s %-10s %-10s %-10s %-10s\n", | 546 | ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, |
565 | semid, | 547 | ipcp->mode, ipcp->mode & 0777, |
566 | ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, | 548 | (long) semds.sem_nsems, |
567 | ipcp->mode, ipcp->mode & 0777, | 549 | semds.sem_otime ? ctime(&semds.sem_otime) : "Not set"); |
568 | (long) semds.sem_nsems, | 550 | bb_printf("ctime = %-26.24s\n" |
569 | semds.sem_otime ? ctime (&semds.sem_otime) : "Not set", | 551 | "%-10s %-10s %-10s %-10s %-10s\n", |
570 | ctime (&semds.sem_ctime), | 552 | ctime(&semds.sem_ctime), |
571 | "semnum","value","ncount","zcount","pid"); | 553 | "semnum", "value", "ncount", "zcount", "pid"); |
572 | 554 | ||
573 | arg.val = 0; | 555 | arg.val = 0; |
574 | for (i=0; i < semds.sem_nsems; i++) { | 556 | for (i = 0; i < semds.sem_nsems; i++) { |
575 | int val, ncnt, zcnt, pid; | 557 | int val, ncnt, zcnt, pid; |
576 | val = semctl (semid, i, GETVAL, arg); | 558 | |
577 | ncnt = semctl (semid, i, GETNCNT, arg); | 559 | val = semctl(semid, i, GETVAL, arg); |
578 | zcnt = semctl (semid, i, GETZCNT, arg); | 560 | ncnt = semctl(semid, i, GETNCNT, arg); |
579 | pid = semctl (semid, i, GETPID, arg); | 561 | zcnt = semctl(semid, i, GETZCNT, arg); |
562 | pid = semctl(semid, i, GETPID, arg); | ||
580 | if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) { | 563 | if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) { |
581 | perror ("semctl "); | 564 | bb_perror_msg_and_die("semctl"); |
582 | bb_fflush_stdout_and_exit (1); | ||
583 | } | 565 | } |
584 | bb_printf ("%-10d %-10d %-10d %-10d %-10d\n", | 566 | bb_printf("%-10d %-10d %-10d %-10d %-10d\n", i, val, ncnt, zcnt, pid); |
585 | i, val, ncnt, zcnt, pid); | ||
586 | } | 567 | } |
587 | bb_printf ("\n"); | 568 | bb_printf("\n"); |
588 | return; | ||
589 | } | 569 | } |
590 | 570 | ||
591 | int ipcs_main (int argc, char **argv) { | 571 | int ipcs_main(int argc, char **argv) |
592 | int opt, msg = 0, sem = 0, shm = 0, id=0, print=0; | 572 | { |
593 | char format = 0; | 573 | int opt, id = 0; |
594 | char options[] = "atclupsmqi:ih?"; | 574 | unsigned flags = 0; |
595 | 575 | #define flag_print (1<<0) | |
596 | while ((opt = getopt (argc, argv, options)) != -1) { | 576 | #define flag_msg (1<<1) |
577 | #define flag_sem (1<<2) | ||
578 | #define flag_shm (1<<3) | ||
579 | const char *const options = "atclupsmqi:ih?"; | ||
580 | |||
581 | while ((opt = getopt(argc, argv, options)) != -1) { | ||
597 | switch (opt) { | 582 | switch (opt) { |
598 | case 'i': | 583 | case 'i': |
599 | id = atoi (optarg); | 584 | id = atoi(optarg); |
600 | print = 1; | 585 | flags |= flag_print; |
601 | break; | 586 | break; |
602 | case 'a': | 587 | case 'a': |
603 | msg = shm = sem = 1; | 588 | flags |= flag_msg | flag_sem | flag_shm; |
604 | break; | 589 | break; |
605 | case 'q': | 590 | case 'q': |
606 | msg = 1; | 591 | flags |= flag_msg; |
607 | break; | 592 | break; |
608 | case 's': | 593 | case 's': |
609 | sem = 1; | 594 | flags |= flag_sem; |
610 | break; | 595 | break; |
611 | case 'm': | 596 | case 'm': |
612 | shm = 1; | 597 | flags |= flag_shm; |
613 | break; | 598 | break; |
614 | case 't': | 599 | case 't': |
615 | format = TIME; | 600 | format = TIME; |
@@ -629,43 +614,40 @@ int ipcs_main (int argc, char **argv) { | |||
629 | case 'h': | 614 | case 'h': |
630 | case '?': | 615 | case '?': |
631 | bb_show_usage(); | 616 | bb_show_usage(); |
632 | bb_fflush_stdout_and_exit (0); | ||
633 | } | 617 | } |
634 | } | 618 | } |
635 | 619 | ||
636 | if (print) { | 620 | if (flags & flag_print) { |
637 | if (shm) { | 621 | if (flags & flag_shm) { |
638 | print_shm (id); | 622 | print_shm(id); |
639 | bb_fflush_stdout_and_exit (0); | 623 | bb_fflush_stdout_and_exit(0); |
640 | } | 624 | } |
641 | if (sem) { | 625 | if (flags & flag_sem) { |
642 | print_sem (id); | 626 | print_sem(id); |
643 | bb_fflush_stdout_and_exit (0); | 627 | bb_fflush_stdout_and_exit(0); |
644 | } | 628 | } |
645 | if (msg) { | 629 | if (flags & flag_msg) { |
646 | print_msg (id); | 630 | print_msg(id); |
647 | bb_fflush_stdout_and_exit (0); | 631 | bb_fflush_stdout_and_exit(0); |
648 | } | 632 | } |
649 | bb_show_usage(); | 633 | bb_show_usage(); |
650 | bb_fflush_stdout_and_exit (0); | ||
651 | } | 634 | } |
652 | 635 | ||
653 | if ( !shm && !msg && !sem) | 636 | if (!(flags & (flag_shm | flag_msg | flag_sem))) |
654 | msg = sem = shm = 1; | 637 | flags |= flag_msg | flag_shm | flag_sem; |
655 | bb_printf ("\n"); | 638 | bb_printf("\n"); |
656 | 639 | ||
657 | if (shm) { | 640 | if (flags & flag_shm) { |
658 | do_shm (format); | 641 | do_shm(); |
659 | bb_printf ("\n"); | 642 | bb_printf("\n"); |
660 | } | 643 | } |
661 | if (sem) { | 644 | if (flags & flag_sem) { |
662 | do_sem (format); | 645 | do_sem(); |
663 | bb_printf ("\n"); | 646 | bb_printf("\n"); |
664 | } | 647 | } |
665 | if (msg) { | 648 | if (flags & flag_msg) { |
666 | do_msg (format); | 649 | do_msg(); |
667 | bb_printf ("\n"); | 650 | bb_printf("\n"); |
668 | } | 651 | } |
669 | return 0; | 652 | return EXIT_SUCCESS; |
670 | } | 653 | } |
671 | |||