diff options
Diffstat (limited to 'coreutils')
67 files changed, 3275 insertions, 2783 deletions
diff --git a/coreutils/Config.in b/coreutils/Config.in index 5b9996d5b..9f5c379a3 100644 --- a/coreutils/Config.in +++ b/coreutils/Config.in | |||
@@ -111,17 +111,31 @@ config CONFIG_DOS2UNIX | |||
111 | Please submit a patch to add help text for this item. | 111 | Please submit a patch to add help text for this item. |
112 | 112 | ||
113 | config CONFIG_DU | 113 | config CONFIG_DU |
114 | bool "du" | 114 | bool "du (default blocksize of 512 bytes)" |
115 | default n | 115 | default n |
116 | help | 116 | help |
117 | Please submit a patch to add help text for this item. | 117 | Please submit a patch to add help text for this item. |
118 | 118 | ||
119 | config CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K | ||
120 | bool " Use a default blocksize of 1024 bytes (1K)" | ||
121 | default y | ||
122 | depends on CONFIG_DU | ||
123 | help | ||
124 | Please submit a patch to add help text for this item. | ||
125 | |||
119 | config CONFIG_ECHO | 126 | config CONFIG_ECHO |
120 | bool "echo" | 127 | bool "echo (basic SUSv3 version taking no options" |
121 | default n | 128 | default n |
122 | help | 129 | help |
123 | Please submit a patch to add help text for this item. | 130 | Please submit a patch to add help text for this item. |
124 | 131 | ||
132 | config CONFIG_FEATURE_FANCY_ECHO | ||
133 | bool " Enable echo options (-n and -e)" | ||
134 | default y | ||
135 | depends on CONFIG_ECHO | ||
136 | help | ||
137 | Please submit a patch to add help text for this item. | ||
138 | |||
125 | config CONFIG_ENV | 139 | config CONFIG_ENV |
126 | bool "env" | 140 | bool "env" |
127 | default n | 141 | default n |
@@ -154,6 +168,13 @@ config CONFIG_HEAD | |||
154 | help | 168 | help |
155 | Please submit a patch to add help text for this item. | 169 | Please submit a patch to add help text for this item. |
156 | 170 | ||
171 | config CONFIG_FEATURE_FANCY_HEAD | ||
172 | bool " Enable head options (-c, -q, and -v)" | ||
173 | default n | ||
174 | depends on CONFIG_HEAD | ||
175 | help | ||
176 | Please submit a patch to add help text for this item. | ||
177 | |||
157 | config CONFIG_HOSTID | 178 | config CONFIG_HOSTID |
158 | bool "hostid" | 179 | bool "hostid" |
159 | default n | 180 | default n |
@@ -313,8 +334,15 @@ config CONFIG_SHA1SUM | |||
313 | Compute and check SHA1 message digest | 334 | Compute and check SHA1 message digest |
314 | 335 | ||
315 | config CONFIG_SLEEP | 336 | config CONFIG_SLEEP |
316 | bool "sleep" | 337 | bool "sleep (single integer arg with no suffix)" |
338 | default n | ||
339 | help | ||
340 | Please submit a patch to add help text for this item. | ||
341 | |||
342 | config CONFIG_FEATURE_FANCY_SLEEP | ||
343 | bool " Enable multiple integer args and optional time suffixes" | ||
317 | default n | 344 | default n |
345 | depends on CONFIG_SLEEP | ||
318 | help | 346 | help |
319 | Please submit a patch to add help text for this item. | 347 | Please submit a patch to add help text for this item. |
320 | 348 | ||
@@ -369,6 +397,13 @@ config CONFIG_TEE | |||
369 | help | 397 | help |
370 | Please submit a patch to add help text for this item. | 398 | Please submit a patch to add help text for this item. |
371 | 399 | ||
400 | config CONFIG_FEATURE_TEE_USE_BLOCK_IO | ||
401 | bool " Enable block i/o (larger/faster) instead of byte i/o." | ||
402 | default n | ||
403 | depends on CONFIG_TEE | ||
404 | help | ||
405 | Please submit a patch to add help text for this item. | ||
406 | |||
372 | if CONFIG_ASH || CONFIG_HUSH || CONFIG_LASH || CONFIG_MSH | 407 | if CONFIG_ASH || CONFIG_HUSH || CONFIG_LASH || CONFIG_MSH |
373 | config CONFIG_TEST | 408 | config CONFIG_TEST |
374 | default y | 409 | default y |
diff --git a/coreutils/basename.c b/coreutils/basename.c index bdbcec17a..71bb9b3bd 100644 --- a/coreutils/basename.c +++ b/coreutils/basename.c | |||
@@ -21,32 +21,43 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* getopt not needed */ | 24 | /* BB_AUDIT SUSv3 compliant */ |
25 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/basename.html */ | ||
26 | |||
27 | |||
28 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
29 | * | ||
30 | * Changes: | ||
31 | * 1) Now checks for too many args. Need at least one and at most two. | ||
32 | * 2) Don't check for options, as per SUSv3. | ||
33 | * 3) Save some space by using strcmp(). Calling strncmp() here was silly. | ||
34 | */ | ||
25 | 35 | ||
26 | #include <stdlib.h> | 36 | #include <stdlib.h> |
27 | #include "busybox.h" | 37 | #include <stdio.h> |
28 | #include <string.h> | 38 | #include <string.h> |
39 | #include "busybox.h" | ||
29 | 40 | ||
30 | extern int basename_main(int argc, char **argv) | 41 | extern int basename_main(int argc, char **argv) |
31 | { | 42 | { |
32 | int m, n; | 43 | size_t m, n; |
33 | char *s; | 44 | char *s; |
34 | 45 | ||
35 | if ((argc < 2) || (**(argv + 1) == '-')) { | 46 | if (((unsigned int)(argc-2)) >= 2) { |
36 | show_usage(); | 47 | bb_show_usage(); |
37 | } | 48 | } |
38 | 49 | ||
39 | argv++; | 50 | s = bb_get_last_path_component(*++argv); |
40 | |||
41 | s = get_last_path_component(*argv); | ||
42 | 51 | ||
43 | if (argc>2) { | 52 | if (*++argv) { |
44 | argv++; | ||
45 | n = strlen(*argv); | 53 | n = strlen(*argv); |
46 | m = strlen(s); | 54 | m = strlen(s); |
47 | if (m>n && strncmp(s+m-n, *argv, n)==0) | 55 | if ((m > n) && ((strcmp)(s+m-n, *argv) == 0)) { |
48 | s[m-n] = '\0'; | 56 | s[m-n] = '\0'; |
57 | } | ||
49 | } | 58 | } |
59 | |||
50 | puts(s); | 60 | puts(s); |
51 | return EXIT_SUCCESS; | 61 | |
62 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); | ||
52 | } | 63 | } |
diff --git a/coreutils/cal.c b/coreutils/cal.c index ab631576a..ed480dd78 100644 --- a/coreutils/cal.c +++ b/coreutils/cal.c | |||
@@ -1,3 +1,14 @@ | |||
1 | /* NOTE: | ||
2 | * | ||
3 | * Apparently, all "Steven J. Merrifield" did was grab the util-linux cal applet, | ||
4 | * spend maybe 5 minutes integrating it into busybox, slapped a copyright on it, | ||
5 | * and submitted it. I certainly saw no evidence of any attempt at size reduction. | ||
6 | * Not only do I consider his copyright below meaningless, I also consider his | ||
7 | * actions shameful. | ||
8 | * | ||
9 | * Manuel Novoa III (mjn3@codepoet.org) | ||
10 | */ | ||
11 | |||
1 | /* | 12 | /* |
2 | * Calendar implementation for busybox | 13 | * Calendar implementation for busybox |
3 | * | 14 | * |
@@ -20,7 +31,16 @@ | |||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | * | 32 | * |
22 | */ | 33 | */ |
23 | 34 | ||
35 | /* BB_AUDIT SUSv3 compliant with -j and -y extensions (from util-linux). */ | ||
36 | /* BB_AUDIT BUG: The output of 'cal -j 1752' is incorrect. The upstream | ||
37 | * BB_AUDIT BUG: version in util-linux seems to be broken as well. */ | ||
38 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cal.html */ | ||
39 | |||
40 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
41 | * | ||
42 | * Major size reduction... over 50% (>1.5k) on i386. | ||
43 | */ | ||
24 | 44 | ||
25 | #include <sys/types.h> | 45 | #include <sys/types.h> |
26 | #include <ctype.h> | 46 | #include <ctype.h> |
@@ -46,44 +66,30 @@ | |||
46 | #define MAXDAYS 42 /* max slots in a month array */ | 66 | #define MAXDAYS 42 /* max slots in a month array */ |
47 | #define SPACE -1 /* used in day array */ | 67 | #define SPACE -1 /* used in day array */ |
48 | 68 | ||
49 | static int days_in_month[2][13] = { | 69 | static const char days_in_month[] = { |
50 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, | 70 | 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 |
51 | {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, | ||
52 | }; | 71 | }; |
53 | 72 | ||
54 | int sep1752[MAXDAYS] = { | 73 | static const char sep1752[] = { |
55 | SPACE, SPACE, 1, 2, 14, 15, 16, | 74 | 1, 2, 14, 15, 16, |
56 | 17, 18, 19, 20, 21, 22, 23, | 75 | 17, 18, 19, 20, 21, 22, 23, |
57 | 24, 25, 26, 27, 28, 29, 30, | 76 | 24, 25, 26, 27, 28, 29, 30 |
58 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
59 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
60 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
61 | }, j_sep1752[MAXDAYS] = { | ||
62 | SPACE, SPACE, 245, 246, 258, 259, 260, | ||
63 | 261, 262, 263, 264, 265, 266, 267, | ||
64 | 268, 269, 270, 271, 272, 273, 274, | ||
65 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
66 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
67 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
68 | }, empty[MAXDAYS] = { | ||
69 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
70 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
71 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
72 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
73 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
74 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
75 | }; | 77 | }; |
76 | 78 | ||
77 | char *month_names[12]; | 79 | static int julian; |
78 | |||
79 | char day_headings[] = " "; | ||
80 | char j_day_headings[] = " "; | ||
81 | 80 | ||
82 | /* leap year -- account for gregorian reformation in 1752 */ | 81 | /* leap year -- account for gregorian reformation in 1752 */ |
83 | #define leap_year(yr) \ | 82 | #define leap_year(yr) \ |
84 | ((yr) <= 1752 ? !((yr) % 4) : \ | 83 | ((yr) <= 1752 ? !((yr) % 4) : \ |
85 | (!((yr) % 4) && ((yr) % 100)) || !((yr) % 400)) | 84 | (!((yr) % 4) && ((yr) % 100)) || !((yr) % 400)) |
86 | 85 | ||
86 | static int is_leap_year(int year) | ||
87 | { | ||
88 | return leap_year(year); | ||
89 | } | ||
90 | #undef leap_year | ||
91 | #define leap_year(yr) is_leap_year(yr) | ||
92 | |||
87 | /* number of centuries since 1700, not inclusive */ | 93 | /* number of centuries since 1700, not inclusive */ |
88 | #define centuries_since_1700(yr) \ | 94 | #define centuries_since_1700(yr) \ |
89 | ((yr) > 1700 ? (yr) / 100 - 17 : 0) | 95 | ((yr) > 1700 ? (yr) / 100 - 17 : 0) |
@@ -96,178 +102,129 @@ char j_day_headings[] = " "; | |||
96 | #define leap_years_since_year_1(yr) \ | 102 | #define leap_years_since_year_1(yr) \ |
97 | ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr)) | 103 | ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr)) |
98 | 104 | ||
99 | int julian; | 105 | static void center __P((char *, int, int)); |
100 | void ascii_day __P((char *, int)); | 106 | static void day_array __P((int, int, int *)); |
101 | void center __P((char *, int, int)); | 107 | static void trim_trailing_spaces_and_print __P((char *)); |
102 | void day_array __P((int, int, int *)); | 108 | |
103 | int day_in_week __P((int, int, int)); | 109 | static void blank_string(char *buf, size_t buflen); |
104 | int day_in_year __P((int, int, int)); | 110 | static char *build_row(char *p, int *dp); |
105 | void j_yearly __P((int)); | 111 | |
106 | void monthly __P((int, int)); | 112 | #define DAY_LEN 3 /* 3 spaces per day */ |
107 | void trim_trailing_spaces __P((char *)); | 113 | #define J_DAY_LEN (DAY_LEN + 1) |
108 | void yearly __P((int)); | 114 | #define WEEK_LEN 20 /* 7 * 3 - one space at the end */ |
115 | #define J_WEEK_LEN (WEEK_LEN + 7) | ||
116 | #define HEAD_SEP 2 /* spaces between day headings */ | ||
109 | 117 | ||
110 | int cal_main(int argc, char **argv) | 118 | int cal_main(int argc, char **argv) |
111 | { | 119 | { |
112 | struct tm *local_time; | 120 | struct tm *local_time; |
113 | static struct tm zero_tm; | 121 | struct tm zero_tm; |
114 | time_t now; | 122 | time_t now; |
115 | int ch, month, year, yflag, i; | 123 | int month, year, flags, i; |
124 | char *month_names[12]; | ||
125 | char day_headings[28]; /* 28 for julian, 21 for nonjulian */ | ||
116 | char buf[40]; | 126 | char buf[40]; |
117 | 127 | ||
118 | #ifdef CONFIG_LOCALE_SUPPORT | 128 | #ifdef CONFIG_LOCALE_SUPPORT |
119 | setlocale(LC_TIME, ""); | 129 | setlocale(LC_TIME, ""); |
120 | #endif | 130 | #endif |
121 | 131 | ||
122 | yflag = 0; | 132 | flags = bb_getopt_ulflags(argc, argv, "jy"); |
123 | while ((ch = getopt(argc, argv, "jy")) != -1) | 133 | |
124 | switch(ch) { | 134 | julian = flags & 1; |
125 | case 'j': | 135 | |
126 | julian = 1; | ||
127 | break; | ||
128 | case 'y': | ||
129 | yflag = 1; | ||
130 | break; | ||
131 | default: | ||
132 | show_usage(); | ||
133 | } | ||
134 | argc -= optind; | ||
135 | argv += optind; | 136 | argv += optind; |
136 | 137 | ||
137 | month = 0; | 138 | month = 0; |
138 | switch(argc) { | 139 | |
139 | case 2: | 140 | if ((argc -= optind) > 2) { |
140 | if ((month = atoi(*argv++)) < 1 || month > 12) | 141 | bb_show_usage(); |
141 | error_msg_and_die("Illegal month value: use 1-12"); | 142 | } |
142 | /* FALLTHROUGH */ | 143 | |
143 | case 1: | 144 | if (!argc) { |
144 | if ((year = atoi(*argv)) < 1 || year > 9999) | ||
145 | error_msg_and_die("Illegal year value: use 1-9999"); | ||
146 | break; | ||
147 | case 0: | ||
148 | time(&now); | 145 | time(&now); |
149 | local_time = localtime(&now); | 146 | local_time = localtime(&now); |
150 | year = local_time->tm_year + 1900; | 147 | year = local_time->tm_year + 1900; |
151 | if (!yflag) | 148 | if (!(flags & 2)) { |
152 | month = local_time->tm_mon + 1; | 149 | month = local_time->tm_mon + 1; |
153 | break; | 150 | } |
154 | default: | 151 | } else { |
155 | show_usage(); | 152 | if (argc == 2) { |
153 | month = bb_xgetularg10_bnd(*argv++, 1, 12); | ||
154 | } | ||
155 | year = bb_xgetularg10_bnd(*argv, 1, 9999); | ||
156 | } | 156 | } |
157 | 157 | ||
158 | for (i = 0; i < 12; i++) { | 158 | blank_string(day_headings, sizeof(day_headings) - 7 + 7*julian); |
159 | |||
160 | i = 0; | ||
161 | do { | ||
159 | zero_tm.tm_mon = i; | 162 | zero_tm.tm_mon = i; |
160 | strftime(buf, sizeof(buf), "%B", &zero_tm); | 163 | strftime(buf, sizeof(buf), "%B", &zero_tm); |
161 | month_names[i] = xstrdup(buf); | 164 | month_names[i] = bb_xstrdup(buf); |
162 | } | ||
163 | for (i = 0; i < 7; i++) { | ||
164 | zero_tm.tm_wday = i; | ||
165 | strftime(buf, sizeof(buf), "%a", &zero_tm); | ||
166 | strncpy(day_headings + i * 3, buf, 2); | ||
167 | strncpy(j_day_headings + i * 4 + 1, buf, 2); | ||
168 | } | ||
169 | |||
170 | if (month) | ||
171 | monthly(month, year); | ||
172 | else if (julian) | ||
173 | j_yearly(year); | ||
174 | else | ||
175 | yearly(year); | ||
176 | exit(0); | ||
177 | } | ||
178 | 165 | ||
179 | #define DAY_LEN 3 /* 3 spaces per day */ | 166 | if (i < 7) { |
180 | #define J_DAY_LEN 4 /* 4 spaces per day */ | 167 | zero_tm.tm_wday = i; |
181 | #define WEEK_LEN 20 /* 7 * 3 - one space at the end */ | 168 | strftime(buf, sizeof(buf), "%a", &zero_tm); |
182 | #define J_WEEK_LEN 27 /* 7 * 4 - one space at the end */ | 169 | strncpy(day_headings + i * (3+julian) + julian, buf, 2); |
183 | #define HEAD_SEP 2 /* spaces between day headings */ | ||
184 | #define J_HEAD_SEP 2 | ||
185 | |||
186 | void monthly(int month, int year) | ||
187 | { | ||
188 | int col, row, len, days[MAXDAYS]; | ||
189 | char *p, lineout[30]; | ||
190 | |||
191 | day_array(month, year, days); | ||
192 | len = sprintf(lineout, "%s %d", month_names[month - 1], year); | ||
193 | printf("%*s%s\n%s\n", | ||
194 | ((julian ? J_WEEK_LEN : WEEK_LEN) - len) / 2, "", | ||
195 | lineout, julian ? j_day_headings : day_headings); | ||
196 | for (row = 0; row < 6; row++) { | ||
197 | for (col = 0, p = lineout; col < 7; col++, | ||
198 | p += julian ? J_DAY_LEN : DAY_LEN) | ||
199 | ascii_day(p, days[row * 7 + col]); | ||
200 | *p = '\0'; | ||
201 | trim_trailing_spaces(lineout); | ||
202 | printf("%s\n", lineout); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | void j_yearly(int year) | ||
207 | { | ||
208 | int col, *dp, i, month, row, which_cal; | ||
209 | int days[12][MAXDAYS]; | ||
210 | char *p, lineout[80]; | ||
211 | |||
212 | sprintf(lineout, "%d", year); | ||
213 | center(lineout, J_WEEK_LEN * 2 + J_HEAD_SEP, 0); | ||
214 | printf("\n\n"); | ||
215 | for (i = 0; i < 12; i++) | ||
216 | day_array(i + 1, year, days[i]); | ||
217 | memset(lineout, ' ', sizeof(lineout) - 1); | ||
218 | lineout[sizeof(lineout) - 1] = '\0'; | ||
219 | for (month = 0; month < 12; month += 2) { | ||
220 | center(month_names[month], J_WEEK_LEN, J_HEAD_SEP); | ||
221 | center(month_names[month + 1], J_WEEK_LEN, 0); | ||
222 | printf("\n%s%*s%s\n", j_day_headings, J_HEAD_SEP, "", | ||
223 | j_day_headings); | ||
224 | for (row = 0; row < 6; row++) { | ||
225 | for (which_cal = 0; which_cal < 2; which_cal++) { | ||
226 | p = lineout + which_cal * (J_WEEK_LEN + 2); | ||
227 | dp = &days[month + which_cal][row * 7]; | ||
228 | for (col = 0; col < 7; col++, p += J_DAY_LEN) | ||
229 | ascii_day(p, *dp++); | ||
230 | } | ||
231 | *p = '\0'; | ||
232 | trim_trailing_spaces(lineout); | ||
233 | printf("%s\n", lineout); | ||
234 | } | 170 | } |
235 | } | 171 | } while (++i < 12); |
236 | printf("\n"); | 172 | |
237 | } | 173 | if (month) { |
238 | 174 | int row, len, days[MAXDAYS]; | |
239 | void yearly(int year) | 175 | int *dp = days; |
240 | { | 176 | char lineout[30]; |
241 | int col, *dp, i, month, row, which_cal; | 177 | |
242 | int days[12][MAXDAYS]; | 178 | day_array(month, year, dp); |
243 | char *p, lineout[80]; | 179 | len = sprintf(lineout, "%s %d", month_names[month - 1], year); |
244 | 180 | bb_printf("%*s%s\n%s\n", | |
245 | sprintf(lineout, "%d", year); | 181 | ((7*julian + WEEK_LEN) - len) / 2, "", |
246 | center(lineout, WEEK_LEN * 3 + HEAD_SEP * 2, 0); | 182 | lineout, day_headings); |
247 | printf("\n\n"); | ||
248 | for (i = 0; i < 12; i++) | ||
249 | day_array(i + 1, year, days[i]); | ||
250 | memset(lineout, ' ', sizeof(lineout) - 1); | ||
251 | lineout[sizeof(lineout) - 1] = '\0'; | ||
252 | for (month = 0; month < 12; month += 3) { | ||
253 | center(month_names[month], WEEK_LEN, HEAD_SEP); | ||
254 | center(month_names[month + 1], WEEK_LEN, HEAD_SEP); | ||
255 | center(month_names[month + 2], WEEK_LEN, 0); | ||
256 | printf("\n%s%*s%s%*s%s\n", day_headings, HEAD_SEP, | ||
257 | "", day_headings, HEAD_SEP, "", day_headings); | ||
258 | for (row = 0; row < 6; row++) { | 183 | for (row = 0; row < 6; row++) { |
259 | for (which_cal = 0; which_cal < 3; which_cal++) { | 184 | build_row(lineout, dp)[0] = '\0'; |
260 | p = lineout + which_cal * (WEEK_LEN + 2); | 185 | dp += 7; |
261 | dp = &days[month + which_cal][row * 7]; | 186 | trim_trailing_spaces_and_print(lineout); |
262 | for (col = 0; col < 7; col++, p += DAY_LEN) | 187 | } |
263 | ascii_day(p, *dp++); | 188 | } else { |
189 | int row, which_cal, week_len, days[12][MAXDAYS]; | ||
190 | int *dp; | ||
191 | char lineout[80]; | ||
192 | |||
193 | sprintf(lineout, "%d", year); | ||
194 | center(lineout, | ||
195 | (WEEK_LEN * 3 + HEAD_SEP * 2) | ||
196 | + julian * (J_WEEK_LEN * 2 + HEAD_SEP | ||
197 | - (WEEK_LEN * 3 + HEAD_SEP * 2)), | ||
198 | 0); | ||
199 | puts("\n"); /* two \n's */ | ||
200 | for (i = 0; i < 12; i++) { | ||
201 | day_array(i + 1, year, days[i]); | ||
202 | } | ||
203 | blank_string(lineout, sizeof(lineout)); | ||
204 | week_len = WEEK_LEN + julian * (J_WEEK_LEN - WEEK_LEN); | ||
205 | for (month = 0; month < 12; month += 3-julian) { | ||
206 | center(month_names[month], week_len, HEAD_SEP); | ||
207 | if (!julian) { | ||
208 | center(month_names[month + 1], week_len, HEAD_SEP); | ||
209 | } | ||
210 | center(month_names[month + 2 - julian], week_len, 0); | ||
211 | bb_printf("\n%s%*s%s", day_headings, HEAD_SEP, "", day_headings); | ||
212 | if (!julian) { | ||
213 | bb_printf("%*s%s", HEAD_SEP, "", day_headings); | ||
214 | } | ||
215 | putchar('\n'); | ||
216 | for (row = 0; row < (6*7); row += 7) { | ||
217 | for (which_cal = 0; which_cal < 3-julian; which_cal++) { | ||
218 | dp = days[month + which_cal] + row; | ||
219 | build_row(lineout + which_cal * (week_len + 2), dp); | ||
220 | } | ||
221 | /* blank_string took care of nul termination. */ | ||
222 | trim_trailing_spaces_and_print(lineout); | ||
264 | } | 223 | } |
265 | *p = '\0'; | ||
266 | trim_trailing_spaces(lineout); | ||
267 | printf("%s\n", lineout); | ||
268 | } | 224 | } |
269 | } | 225 | } |
270 | printf("\n"); | 226 | |
227 | bb_fflush_stdout_and_exit(0); | ||
271 | } | 228 | } |
272 | 229 | ||
273 | /* | 230 | /* |
@@ -277,118 +234,129 @@ void yearly(int year) | |||
277 | * out end to end. You would have 42 numbers or spaces. This routine | 234 | * out end to end. You would have 42 numbers or spaces. This routine |
278 | * builds that array for any month from Jan. 1 through Dec. 9999. | 235 | * builds that array for any month from Jan. 1 through Dec. 9999. |
279 | */ | 236 | */ |
280 | void day_array(int month, int year, int *days) | 237 | static void day_array(int month, int year, int *days) |
281 | { | 238 | { |
239 | long temp; | ||
240 | int i; | ||
241 | int j_offset; | ||
282 | int day, dw, dm; | 242 | int day, dw, dm; |
283 | 243 | ||
244 | memset(days, SPACE, MAXDAYS * sizeof(int)); | ||
245 | |||
284 | if ((month == 9) && (year == 1752)) { | 246 | if ((month == 9) && (year == 1752)) { |
285 | memmove(days, | 247 | j_offset = julian * 244; |
286 | julian ? j_sep1752 : sep1752, MAXDAYS * sizeof(int)); | 248 | i = 0; |
249 | do { | ||
250 | days[i+2] = sep1752[i] + j_offset; | ||
251 | } while (++i < sizeof(sep1752)); | ||
252 | |||
287 | return; | 253 | return; |
288 | } | 254 | } |
289 | memmove(days, empty, MAXDAYS * sizeof(int)); | ||
290 | dm = days_in_month[leap_year(year)][month]; | ||
291 | dw = day_in_week(1, month, year); | ||
292 | day = julian ? day_in_year(1, month, year) : 1; | ||
293 | while (dm--) | ||
294 | days[dw++] = day++; | ||
295 | } | ||
296 | 255 | ||
297 | /* | 256 | /* day_in_year |
298 | * day_in_year -- | 257 | * return the 1 based day number within the year |
299 | * return the 1 based day number within the year | 258 | */ |
300 | */ | 259 | day = 1; |
301 | int day_in_year(int day, int month, int year) | 260 | if ((month > 2) && leap_year(year)) { |
302 | { | 261 | ++day; |
303 | int i, leap; | 262 | } |
304 | |||
305 | leap = leap_year(year); | ||
306 | for (i = 1; i < month; i++) | ||
307 | day += days_in_month[leap][i]; | ||
308 | return (day); | ||
309 | } | ||
310 | 263 | ||
311 | /* | 264 | i = month; |
312 | * day_in_week | 265 | while (i) { |
313 | * return the 0 based day number for any date from 1 Jan. 1 to | 266 | day += days_in_month[--i]; |
314 | * 31 Dec. 9999. Assumes the Gregorian reformation eliminates | 267 | } |
315 | * 3 Sep. 1752 through 13 Sep. 1752. Returns Thursday for all | ||
316 | * missing days. | ||
317 | */ | ||
318 | int day_in_week(int day, int month, int year) | ||
319 | { | ||
320 | long temp; | ||
321 | 268 | ||
269 | /* day_in_week | ||
270 | * return the 0 based day number for any date from 1 Jan. 1 to | ||
271 | * 31 Dec. 9999. Assumes the Gregorian reformation eliminates | ||
272 | * 3 Sep. 1752 through 13 Sep. 1752. Returns Thursday for all | ||
273 | * missing days. | ||
274 | */ | ||
275 | dw = THURSDAY; | ||
322 | temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1) | 276 | temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1) |
323 | + day_in_year(day, month, year); | 277 | + day; |
324 | if (temp < FIRST_MISSING_DAY) | 278 | if (temp < FIRST_MISSING_DAY) { |
325 | return ((temp - 1 + SATURDAY) % 7); | 279 | dw = ((temp - 1 + SATURDAY) % 7); |
326 | if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS)) | 280 | } else if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS)) { |
327 | return (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7); | 281 | dw = (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7); |
328 | return (THURSDAY); | 282 | } |
283 | |||
284 | if (!julian) { | ||
285 | day = 1; | ||
286 | } | ||
287 | |||
288 | dm = days_in_month[month]; | ||
289 | if ((month == 2) && leap_year(year)) { | ||
290 | ++dm; | ||
291 | } | ||
292 | |||
293 | while (dm) { | ||
294 | days[dw++] = day++; | ||
295 | --dm; | ||
296 | } | ||
329 | } | 297 | } |
330 | 298 | ||
331 | void ascii_day(char *p, int day) | 299 | static void trim_trailing_spaces_and_print(char *s) |
332 | { | 300 | { |
333 | int display, val; | 301 | char *p = s; |
334 | static char *aday[] = { | 302 | |
335 | "", | 303 | while (*p) { |
336 | " 1", " 2", " 3", " 4", " 5", " 6", " 7", | 304 | ++p; |
337 | " 8", " 9", "10", "11", "12", "13", "14", | ||
338 | "15", "16", "17", "18", "19", "20", "21", | ||
339 | "22", "23", "24", "25", "26", "27", "28", | ||
340 | "29", "30", "31", | ||
341 | }; | ||
342 | |||
343 | if (day == SPACE) { | ||
344 | memset(p, ' ', julian ? J_DAY_LEN : DAY_LEN); | ||
345 | return; | ||
346 | } | 305 | } |
347 | if (julian) { | 306 | while (p > s) { |
348 | if ((val = day / 100) != 0) { | 307 | --p; |
349 | day %= 100; | 308 | if (!(isspace)(*p)) { /* We want the function... not the inline. */ |
350 | *p++ = val + '0'; | 309 | p[1] = '\0'; |
351 | display = 1; | 310 | break; |
352 | } else { | ||
353 | *p++ = ' '; | ||
354 | display = 0; | ||
355 | } | 311 | } |
356 | val = day / 10; | ||
357 | if (val || display) | ||
358 | *p++ = val + '0'; | ||
359 | else | ||
360 | *p++ = ' '; | ||
361 | *p++ = day % 10 + '0'; | ||
362 | } else { | ||
363 | *p++ = aday[day][0]; | ||
364 | *p++ = aday[day][1]; | ||
365 | } | 312 | } |
366 | *p = ' '; | 313 | |
314 | puts(s); | ||
367 | } | 315 | } |
368 | 316 | ||
369 | void trim_trailing_spaces(char *s) | 317 | static void center(char *str, int len, int separate) |
370 | { | 318 | { |
371 | char *p; | 319 | int n = strlen(str); |
320 | len -= n; | ||
321 | bb_printf("%*s%*s", (len/2) + n, str, (len/2) + (len % 2) + separate, ""); | ||
322 | } | ||
372 | 323 | ||
373 | for (p = s; *p; ++p) | 324 | static void blank_string(char *buf, size_t buflen) |
374 | continue; | 325 | { |
375 | while (p > s && (--p, isspace(*p))) | 326 | memset(buf, ' ', buflen); |
376 | continue; | 327 | buf[buflen-1] = '\0'; |
377 | if (p > s) | ||
378 | ++p; | ||
379 | *p = '\0'; | ||
380 | } | 328 | } |
381 | 329 | ||
382 | void center(char *str, int len, int separate) | 330 | static char *build_row(char *p, int *dp) |
383 | { | 331 | { |
332 | int col, val, day; | ||
333 | |||
334 | memset(p, ' ', (julian + DAY_LEN) * 7); | ||
335 | |||
336 | col = 0; | ||
337 | do { | ||
338 | if ((day = *dp++) != SPACE) { | ||
339 | if (julian) { | ||
340 | *++p; | ||
341 | if (day >= 100) { | ||
342 | *p = '0'; | ||
343 | p[-1] = (day / 100) + '0'; | ||
344 | day %= 100; | ||
345 | } | ||
346 | } | ||
347 | if ((val = day / 10) > 0) { | ||
348 | *p = val + '0'; | ||
349 | } | ||
350 | *++p = day % 10 + '0'; | ||
351 | p += 2; | ||
352 | } else { | ||
353 | p += DAY_LEN + julian; | ||
354 | } | ||
355 | } while (++col < 7); | ||
384 | 356 | ||
385 | len -= strlen(str); | 357 | return p; |
386 | printf("%*s%s%*s", len / 2, "", str, len / 2 + len % 2, ""); | ||
387 | if (separate) | ||
388 | printf("%*s", separate, ""); | ||
389 | } | 358 | } |
390 | 359 | ||
391 | |||
392 | /* | 360 | /* |
393 | * Copyright (c) 1989, 1993, 1994 | 361 | * Copyright (c) 1989, 1993, 1994 |
394 | * The Regents of the University of California. All rights reserved. | 362 | * The Regents of the University of California. All rights reserved. |
diff --git a/coreutils/cat.c b/coreutils/cat.c index 33f15da71..865275767 100644 --- a/coreutils/cat.c +++ b/coreutils/cat.c | |||
@@ -1,9 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini Cat implementation for busybox | 3 | * cat implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1999,2000 by Lineo, inc. and Erik Andersen | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * Copyright (C) 1999,2000,2001 by Erik Andersen <andersee@debian.org> | ||
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -21,33 +20,48 @@ | |||
21 | * | 20 | * |
22 | */ | 21 | */ |
23 | 22 | ||
23 | /* BB_AUDIT SUSv3 compliant */ | ||
24 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cat.html */ | ||
25 | |||
26 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
27 | * | ||
28 | * This is a new implementation of 'cat' which aims to be SUSv3 compliant. | ||
29 | * | ||
30 | * Changes from the previous implementation include: | ||
31 | * 1) Multiple '-' args are accepted as required by SUSv3. The previous | ||
32 | * implementation would close stdin and segfault on a subsequent '-'. | ||
33 | * 2) The '-u' options is required by SUSv3. Note that the specified | ||
34 | * behavior for '-u' is done by default, so all we need do is accept | ||
35 | * the option. | ||
36 | */ | ||
37 | |||
24 | #include <stdlib.h> | 38 | #include <stdlib.h> |
25 | #include <string.h> | 39 | #include <stdio.h> |
40 | #include <unistd.h> | ||
26 | #include "busybox.h" | 41 | #include "busybox.h" |
27 | 42 | ||
28 | extern int cat_main(int argc, char **argv) | 43 | extern int cat_main(int argc, char **argv) |
29 | { | 44 | { |
30 | int status = EXIT_SUCCESS; | 45 | FILE *f; |
46 | int retval = EXIT_SUCCESS; | ||
31 | 47 | ||
32 | if (argc == 1) { | 48 | bb_getopt_ulflags(argc, argv, "u"); |
33 | print_file(stdin); | 49 | |
34 | return status; | 50 | argv += optind; |
51 | if (!*argv) { | ||
52 | *--argv = "-"; | ||
35 | } | 53 | } |
36 | 54 | ||
37 | while (--argc > 0) { | 55 | do { |
38 | if(!(strcmp(*++argv, "-"))) { | 56 | if ((f = bb_wfopen_input(*argv)) != NULL) { |
39 | print_file(stdin); | 57 | int r = bb_copyfd(fileno(f), STDOUT_FILENO, 0); |
40 | } else if (! print_file_by_name(*argv)) { | 58 | bb_fclose_nonstdin(f); |
41 | status = EXIT_FAILURE; | 59 | if (r >= 0) { |
60 | continue; | ||
61 | } | ||
42 | } | 62 | } |
43 | } | 63 | retval = EXIT_FAILURE; |
44 | return status; | 64 | } while (*++argv); |
45 | } | ||
46 | 65 | ||
47 | /* | 66 | return retval; |
48 | Local Variables: | 67 | } |
49 | c-file-style: "linux" | ||
50 | c-basic-offset: 4 | ||
51 | tab-width: 4 | ||
52 | End: | ||
53 | */ | ||
diff --git a/coreutils/chgrp.c b/coreutils/chgrp.c index 968b448c0..f5e5d29f1 100644 --- a/coreutils/chgrp.c +++ b/coreutils/chgrp.c | |||
@@ -21,9 +21,12 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <stdio.h> | 24 | /* BB_AUDIT SUSv3 defects - unsupported options -h, -H, -L, and -P. */ |
25 | /* BB_AUDIT GNU defects - unsupported options -h, -c, -f, -v, and long options. */ | ||
26 | /* BB_AUDIT Note: gnu chgrp does not support -H, -L, or -P. */ | ||
27 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/chgrp.html */ | ||
28 | |||
25 | #include <stdlib.h> | 29 | #include <stdlib.h> |
26 | #include <string.h> | ||
27 | #include <unistd.h> | 30 | #include <unistd.h> |
28 | #include "busybox.h" | 31 | #include "busybox.h" |
29 | 32 | ||
@@ -32,53 +35,46 @@ | |||
32 | #define lchown chown | 35 | #define lchown chown |
33 | #endif | 36 | #endif |
34 | 37 | ||
35 | |||
36 | static long gid; | ||
37 | |||
38 | static int fileAction(const char *fileName, struct stat *statbuf, void* junk) | 38 | static int fileAction(const char *fileName, struct stat *statbuf, void* junk) |
39 | { | 39 | { |
40 | if (lchown(fileName, statbuf->st_uid, (gid == -1) ? statbuf->st_gid : gid) == 0) { | 40 | if (lchown(fileName, statbuf->st_uid, *((long *) junk)) == 0) { |
41 | return (TRUE); | 41 | return (TRUE); |
42 | } | 42 | } |
43 | perror(fileName); | 43 | bb_perror_msg("%s", fileName); /* Avoid multibyte problems. */ |
44 | return (FALSE); | 44 | return (FALSE); |
45 | } | 45 | } |
46 | 46 | ||
47 | int chgrp_main(int argc, char **argv) | 47 | int chgrp_main(int argc, char **argv) |
48 | { | 48 | { |
49 | int opt; | 49 | long gid; |
50 | int recursiveFlag = FALSE; | 50 | int recursiveFlag;; |
51 | char *p=NULL; | 51 | int retval = EXIT_SUCCESS; |
52 | char *p; | ||
52 | 53 | ||
53 | /* do normal option parsing */ | 54 | recursiveFlag = bb_getopt_ulflags(argc, argv, "R"); |
54 | while ((opt = getopt(argc, argv, "R")) > 0) { | 55 | |
55 | switch (opt) { | 56 | if (argc - optind < 2) { |
56 | case 'R': | 57 | bb_show_usage(); |
57 | recursiveFlag = TRUE; | ||
58 | break; | ||
59 | default: | ||
60 | show_usage(); | ||
61 | } | ||
62 | } | 58 | } |
63 | 59 | ||
64 | if (argc > optind && argc > 2 && argv[optind]) { | 60 | argv += optind; |
65 | /* Find the selected group */ | 61 | |
66 | gid = strtoul(argv[optind], &p, 10); /* maybe it's already numeric */ | 62 | /* Find the selected group */ |
67 | if (argv[optind] == p) | 63 | gid = strtoul(*argv, &p, 10); /* maybe it's already numeric */ |
68 | gid = my_getgrnam(argv[optind]); | 64 | if (*p || (p == *argv)) { /* trailing chars or nonnumeric */ |
69 | } else { | 65 | gid = my_getgrnam(*argv); |
70 | error_msg_and_die(too_few_args); | ||
71 | } | 66 | } |
67 | ++argv; | ||
72 | 68 | ||
73 | /* Ok, ready to do the deed now */ | 69 | /* Ok, ready to do the deed now */ |
74 | while (++optind < argc) { | 70 | do { |
75 | if (! recursive_action (argv[optind], recursiveFlag, FALSE, FALSE, | 71 | if (! recursive_action (*argv, recursiveFlag, FALSE, FALSE, |
76 | fileAction, fileAction, NULL)) { | 72 | fileAction, fileAction, &gid)) { |
77 | return EXIT_FAILURE; | 73 | retval = EXIT_FAILURE; |
78 | } | 74 | } |
79 | } | 75 | } while (*++argv); |
80 | return EXIT_SUCCESS; | ||
81 | 76 | ||
77 | return retval; | ||
82 | } | 78 | } |
83 | 79 | ||
84 | /* | 80 | /* |
diff --git a/coreutils/chmod.c b/coreutils/chmod.c index ba80e020a..28c98552a 100644 --- a/coreutils/chmod.c +++ b/coreutils/chmod.c | |||
@@ -24,67 +24,84 @@ | |||
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | 26 | ||
27 | /* BB_AUDIT SUSv3 compliant */ | ||
28 | /* BB_AUDIT GNU defects - unsupported options -c, -f, -v, and long options. */ | ||
29 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */ | ||
30 | |||
27 | #include <stdio.h> | 31 | #include <stdio.h> |
28 | #include <stdlib.h> | 32 | #include <stdlib.h> |
29 | #include <string.h> | 33 | #include <string.h> |
30 | #include <unistd.h> | 34 | #include <unistd.h> |
31 | #include <getopt.h> | 35 | #include <sys/stat.h> |
32 | #include "busybox.h" | 36 | #include "busybox.h" |
33 | 37 | ||
34 | static int fileAction(const char *fileName, struct stat *statbuf, void* junk) | 38 | static int fileAction(const char *fileName, struct stat *statbuf, void* junk) |
35 | { | 39 | { |
36 | if (!parse_mode((char *)junk, &(statbuf->st_mode))) | 40 | if (!bb_parse_mode((char *)junk, &(statbuf->st_mode))) |
37 | error_msg_and_die( "unknown mode: %s", (char *)junk); | 41 | bb_error_msg_and_die( "unknown mode: %s", (char *)junk); |
38 | if (chmod(fileName, statbuf->st_mode) == 0) | 42 | if (chmod(fileName, statbuf->st_mode) == 0) |
39 | return (TRUE); | 43 | return (TRUE); |
40 | perror(fileName); | 44 | bb_perror_msg("%s", fileName); /* Avoid multibyte problems. */ |
41 | return (FALSE); | 45 | return (FALSE); |
42 | } | 46 | } |
43 | 47 | ||
44 | int chmod_main(int argc, char **argv) | 48 | int chmod_main(int argc, char **argv) |
45 | { | 49 | { |
46 | int opt; | 50 | int retval = EXIT_SUCCESS; |
47 | int recursiveFlag = FALSE; | 51 | int recursiveFlag = FALSE; |
48 | int modeind = 0; /* Index of the mode argument in `argv'. */ | 52 | int count; |
49 | char *smode; | 53 | char *smode; |
50 | static const char chmod_modes[] = "Rrwxstugoa,+-="; | 54 | char **p; |
55 | char *p0; | ||
56 | char opt = '-'; | ||
51 | 57 | ||
52 | /* do normal option parsing */ | 58 | ++argv; |
53 | while (1) { | 59 | count = 0; |
54 | int thisind = optind ? optind : 1; | ||
55 | 60 | ||
56 | opt = getopt(argc, argv, chmod_modes); | 61 | for (p = argv ; *p ; p++) { |
57 | if (opt == EOF) | 62 | p0 = p[0]; |
58 | break; | 63 | if (p0[0] == opt) { |
59 | smode = strchr(chmod_modes, opt); | 64 | if ((p0[1] == '-') && !p0[2]) { |
60 | if(smode == NULL) | 65 | opt = 0; /* Disable further option processing. */ |
61 | show_usage(); | 66 | continue; |
62 | if(smode == chmod_modes) { /* 'R' */ | 67 | } |
63 | recursiveFlag = TRUE; | 68 | if (p0[1] == 'R') { |
64 | } else { | 69 | char *s = p0 + 2; |
65 | if (modeind != 0 && modeind != thisind) | 70 | while (*s == 'R') { |
66 | show_usage(); | 71 | ++s; |
67 | modeind = thisind; | 72 | } |
73 | if (*s) { | ||
74 | bb_show_usage(); | ||
75 | } | ||
76 | recursiveFlag = TRUE; | ||
77 | continue; | ||
78 | } | ||
79 | if (count) { | ||
80 | bb_show_usage(); | ||
81 | } | ||
68 | } | 82 | } |
83 | argv[count] = p0; | ||
84 | ++count; | ||
69 | } | 85 | } |
70 | 86 | ||
71 | if (modeind == 0) | 87 | argv[count] = NULL; |
72 | modeind = optind++; | ||
73 | 88 | ||
74 | opt = optind; | 89 | if (count < 2) { |
75 | if (opt >= argc) { | 90 | bb_show_usage(); |
76 | error_msg_and_die(too_few_args); | ||
77 | } | 91 | } |
78 | 92 | ||
79 | smode = argv[modeind]; | 93 | smode = *argv; |
94 | ++argv; | ||
95 | |||
80 | /* Ok, ready to do the deed now */ | 96 | /* Ok, ready to do the deed now */ |
81 | for (; opt < argc; opt++) { | 97 | do { |
82 | if (! recursive_action (argv[opt], recursiveFlag, FALSE, FALSE, fileAction, | 98 | if (! recursive_action (*argv, recursiveFlag, FALSE, FALSE, |
83 | fileAction, smode)) { | 99 | fileAction, fileAction, smode)) { |
84 | return EXIT_FAILURE; | 100 | retval = EXIT_FAILURE; |
85 | } | 101 | } |
86 | } | 102 | } while (*++argv); |
87 | return EXIT_SUCCESS; | 103 | |
104 | return retval; | ||
88 | } | 105 | } |
89 | 106 | ||
90 | /* | 107 | /* |
diff --git a/coreutils/chown.c b/coreutils/chown.c index 4e766a90b..3e983cfa6 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c | |||
@@ -21,10 +21,14 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <stdio.h> | 24 | /* BB_AUDIT SUSv3 defects - unsupported options -h, -H, -L, and -P. */ |
25 | /* BB_AUDIT GNU defects - unsupported options -h, -c, -f, -v, and long options. */ | ||
26 | /* BB_AUDIT Note: gnu chown does not support -H, -L, or -P. */ | ||
27 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */ | ||
28 | |||
25 | #include <stdlib.h> | 29 | #include <stdlib.h> |
26 | #include <string.h> | ||
27 | #include <unistd.h> | 30 | #include <unistd.h> |
31 | #include <string.h> | ||
28 | #include "busybox.h" | 32 | #include "busybox.h" |
29 | 33 | ||
30 | /* Don't use lchown for libc5 or glibc older then 2.1.x */ | 34 | /* Don't use lchown for libc5 or glibc older then 2.1.x */ |
@@ -42,65 +46,67 @@ static int fileAction(const char *fileName, struct stat *statbuf, void* junk) | |||
42 | if (chown_func(fileName, uid, (gid == -1) ? statbuf->st_gid : gid) == 0) { | 46 | if (chown_func(fileName, uid, (gid == -1) ? statbuf->st_gid : gid) == 0) { |
43 | return (TRUE); | 47 | return (TRUE); |
44 | } | 48 | } |
45 | perror(fileName); | 49 | bb_perror_msg("%s", fileName); /* Avoid multibyte problems. */ |
46 | return (FALSE); | 50 | return (FALSE); |
47 | } | 51 | } |
48 | 52 | ||
53 | #define FLAG_R 1 | ||
54 | #define FLAG_h 2 | ||
55 | |||
56 | static unsigned long get_ug_id(const char *s, long (*my_getxxnam)(const char *)) | ||
57 | { | ||
58 | unsigned long r; | ||
59 | char *p; | ||
60 | |||
61 | r = strtoul(s, &p, 10); | ||
62 | if (*p || (s == p)) { | ||
63 | r = my_getxxnam(s); | ||
64 | } | ||
65 | |||
66 | return r; | ||
67 | } | ||
68 | |||
49 | int chown_main(int argc, char **argv) | 69 | int chown_main(int argc, char **argv) |
50 | { | 70 | { |
51 | int opt; | 71 | int flags; |
52 | int recursiveFlag = FALSE, | 72 | int retval = EXIT_SUCCESS; |
53 | noderefFlag = FALSE; | 73 | char *groupName; |
54 | char *groupName=NULL; | 74 | |
55 | char *p=NULL; | 75 | flags = bb_getopt_ulflags(argc, argv, "Rh"); |
56 | 76 | ||
57 | /* do normal option parsing */ | 77 | if (flags & FLAG_h) chown_func = lchown; |
58 | while ((opt = getopt(argc, argv, "Rh")) > 0) { | 78 | |
59 | switch (opt) { | 79 | if (argc - optind < 2) { |
60 | case 'R': | 80 | bb_show_usage(); |
61 | recursiveFlag = TRUE; | ||
62 | break; | ||
63 | case 'h': | ||
64 | noderefFlag = TRUE; | ||
65 | break; | ||
66 | default: | ||
67 | show_usage(); | ||
68 | } | ||
69 | } | 81 | } |
70 | 82 | ||
71 | if (noderefFlag) chown_func = lchown; | 83 | argv += optind; |
72 | 84 | ||
73 | if (argc > optind && argc > 2 && argv[optind]) { | 85 | /* First, check if there is a group name here */ |
74 | /* First, check if there is a group name here */ | 86 | if ((groupName = strchr(*argv, '.')) == NULL) { |
75 | groupName = strchr(argv[optind], '.'); | 87 | groupName = strchr(*argv, ':'); |
76 | if (groupName == NULL) | 88 | } |
77 | groupName = strchr(argv[optind], ':'); | 89 | |
78 | if (groupName) { | 90 | gid = -1; |
79 | *groupName++ = '\0'; | 91 | if (groupName) { |
80 | gid = strtoul(groupName, &p, 10); | 92 | *groupName++ = '\0'; |
81 | if (groupName == p) | 93 | gid = get_ug_id(groupName, my_getgrnam); |
82 | gid = my_getgrnam(groupName); | ||
83 | } else { | ||
84 | gid = -1; | ||
85 | } | ||
86 | /* Now check for the username */ | ||
87 | uid = strtoul(argv[optind], &p, 10); /* Is is numeric? */ | ||
88 | if (argv[optind] == p) { | ||
89 | uid = my_getpwnam(argv[optind]); | ||
90 | } | ||
91 | } else { | ||
92 | error_msg_and_die(too_few_args); | ||
93 | } | 94 | } |
94 | 95 | ||
96 | /* Now check for the username */ | ||
97 | uid = get_ug_id(*argv, my_getpwnam); | ||
98 | |||
99 | ++argv; | ||
100 | |||
95 | /* Ok, ready to do the deed now */ | 101 | /* Ok, ready to do the deed now */ |
96 | while (++optind < argc) { | 102 | do { |
97 | if (! recursive_action (argv[optind], recursiveFlag, FALSE, FALSE, | 103 | if (! recursive_action (*argv, (flags & FLAG_R), FALSE, FALSE, |
98 | fileAction, fileAction, NULL)) { | 104 | fileAction, fileAction, NULL)) { |
99 | return EXIT_FAILURE; | 105 | retval = EXIT_FAILURE; |
100 | } | 106 | } |
101 | } | 107 | } while (*++argv); |
102 | return EXIT_SUCCESS; | ||
103 | 108 | ||
109 | return retval; | ||
104 | } | 110 | } |
105 | 111 | ||
106 | /* | 112 | /* |
diff --git a/coreutils/chroot.c b/coreutils/chroot.c index ba3e5f864..01e4d564c 100644 --- a/coreutils/chroot.c +++ b/coreutils/chroot.c | |||
@@ -21,6 +21,8 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ | ||
25 | |||
24 | #include <stdlib.h> | 26 | #include <stdlib.h> |
25 | #include <stdio.h> | 27 | #include <stdio.h> |
26 | #include <unistd.h> | 28 | #include <unistd.h> |
@@ -29,46 +31,24 @@ | |||
29 | 31 | ||
30 | int chroot_main(int argc, char **argv) | 32 | int chroot_main(int argc, char **argv) |
31 | { | 33 | { |
32 | char *prog; | 34 | if (argc < 2) { |
33 | 35 | bb_show_usage(); | |
34 | if ((argc < 2) || (**(argv + 1) == '-')) { | ||
35 | show_usage(); | ||
36 | } | 36 | } |
37 | argc--; | ||
38 | argv++; | ||
39 | 37 | ||
38 | ++argv; | ||
40 | if (chroot(*argv) || (chdir("/"))) { | 39 | if (chroot(*argv) || (chdir("/"))) { |
41 | perror_msg_and_die("cannot change root directory to %s", *argv); | 40 | bb_perror_msg_and_die("cannot change root directory to %s", *argv); |
42 | } | 41 | } |
43 | 42 | ||
44 | argc--; | 43 | ++argv; |
45 | argv++; | 44 | if (argc == 2) { |
46 | if (argc >= 1) { | 45 | argv -= 2; |
47 | prog = *argv; | 46 | if (!(*argv = getenv("SHELL"))) { |
48 | execvp(*argv, argv); | 47 | *argv = (char *) "/bin/sh"; |
49 | } else { | 48 | } |
50 | #if defined shell_main && defined CONFIG_FEATURE_SH_STANDALONE_SHELL | 49 | argv[1] = (char *) "-i"; |
51 | char shell[] = "/bin/sh"; | ||
52 | char *shell_argv[2] = { shell, NULL }; | ||
53 | applet_name = shell; | ||
54 | shell_main(1, shell_argv); | ||
55 | return EXIT_SUCCESS; | ||
56 | #else | ||
57 | prog = getenv("SHELL"); | ||
58 | if (!prog) | ||
59 | prog = "/bin/sh"; | ||
60 | execlp(prog, prog, NULL); | ||
61 | #endif | ||
62 | } | 50 | } |
63 | perror_msg_and_die("cannot execute %s", prog); | ||
64 | 51 | ||
52 | execvp(*argv, argv); | ||
53 | bb_perror_msg_and_die("cannot execute %s", *argv); | ||
65 | } | 54 | } |
66 | |||
67 | |||
68 | /* | ||
69 | Local Variables: | ||
70 | c-file-style: "linux" | ||
71 | c-basic-offset: 4 | ||
72 | tab-width: 4 | ||
73 | End: | ||
74 | */ | ||
diff --git a/coreutils/cmp.c b/coreutils/cmp.c index 07bf3be92..43dbc842f 100644 --- a/coreutils/cmp.c +++ b/coreutils/cmp.c | |||
@@ -20,59 +20,133 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* BB_AUDIT SUSv3 (virtually) compliant -- uses nicer GNU format for -l. */ | ||
24 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cmp.html */ | ||
25 | |||
26 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
27 | * | ||
28 | * Original version majorly reworked for SUSv3 compliance, bug fixes, and | ||
29 | * size optimizations. Changes include: | ||
30 | * 1) Now correctly distingusishes between errors and actual file differences. | ||
31 | * 2) Proper handling of '-' args. | ||
32 | * 3) Actual error checking of i/o. | ||
33 | * 4) Accept SUSv3 -l option. Note that we use the slightly nicer gnu format | ||
34 | * in the '-l' case. | ||
35 | */ | ||
36 | |||
23 | #include <stdio.h> | 37 | #include <stdio.h> |
24 | #include <string.h> | ||
25 | #include <errno.h> | ||
26 | #include <stdlib.h> | 38 | #include <stdlib.h> |
27 | #include <getopt.h> | 39 | #include <unistd.h> |
28 | #include "busybox.h" | 40 | #include "busybox.h" |
29 | 41 | ||
42 | static FILE *cmp_xfopen_input(const char *filename) | ||
43 | { | ||
44 | FILE *fp; | ||
45 | |||
46 | if ((fp = bb_wfopen_input(filename)) != NULL) { | ||
47 | return fp; | ||
48 | } | ||
49 | |||
50 | exit(bb_default_error_retval); /* We already output an error message. */ | ||
51 | } | ||
52 | |||
53 | static const char fmt_eof[] = "cmp: EOF on %s\n"; | ||
54 | static const char fmt_differ[] = "%s %s differ: char %d, line %d\n"; | ||
55 | #if 0 | ||
56 | static const char fmt_l_opt[] = "%.0s%.0s%d %o %o\n"; /* SUSv3 format */ | ||
57 | #else | ||
58 | static const char fmt_l_opt[] = "%.0s%.0s%d %3o %3o\n"; /* nicer gnu format */ | ||
59 | #endif | ||
60 | |||
61 | static const char opt_chars[] = "sl"; | ||
62 | |||
63 | enum { | ||
64 | OPT_s = 1, | ||
65 | OPT_l = 2 | ||
66 | }; | ||
67 | |||
30 | int cmp_main(int argc, char **argv) | 68 | int cmp_main(int argc, char **argv) |
31 | { | 69 | { |
32 | FILE *fp1 = NULL, *fp2 = stdin; | 70 | FILE *fp1, *fp2, *outfile = stdout; |
33 | char *filename1, *filename2 = "-"; | 71 | const char *filename1, *filename2; |
34 | int c, c1, c2, char_pos = 1, line_pos = 1, silent = FALSE; | 72 | const char *fmt; |
35 | 73 | int c1, c2, char_pos, line_pos; | |
36 | while ((c = getopt(argc, argv, "s")) != EOF) { | 74 | int opt_flags; |
37 | switch (c) { | 75 | int exit_val = 0; |
38 | case 's': | 76 | |
39 | silent = TRUE; | 77 | bb_default_error_retval = 2; /* 1 is returned if files are different. */ |
40 | break; | 78 | |
41 | default: | 79 | opt_flags = bb_getopt_ulflags(argc, argv, opt_chars); |
42 | show_usage(); | 80 | |
43 | } | 81 | if ((opt_flags == 3) || (((unsigned int)(--argc - optind)) > 1)) { |
82 | bb_show_usage(); | ||
44 | } | 83 | } |
45 | 84 | ||
46 | filename1 = argv[optind]; | 85 | fp1 = cmp_xfopen_input(filename1 = *(argv += optind)); |
47 | switch (argc - optind) { | 86 | |
48 | case 2: | 87 | filename2 = "-"; |
49 | fp2 = xfopen(filename2 = argv[optind + 1], "r"); | 88 | if (*++argv) { |
50 | case 1: | 89 | filename2 = *argv; |
51 | fp1 = xfopen(filename1, "r"); | ||
52 | break; | ||
53 | default: | ||
54 | show_usage(); | ||
55 | } | 90 | } |
91 | fp2 = cmp_xfopen_input(filename2); | ||
56 | 92 | ||
93 | if (fp1 == fp2) { /* Paranioa check... stdin == stdin? */ | ||
94 | /* Note that we don't bother reading stdin. Neither does gnu wc. | ||
95 | * But perhaps we should, so that other apps down the chain don't | ||
96 | * get the input. Consider 'echo hello | (cmp - - && cat -)'. | ||
97 | */ | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | fmt = fmt_differ; | ||
102 | if (opt_flags == OPT_l) { | ||
103 | fmt = fmt_l_opt; | ||
104 | } | ||
105 | |||
106 | char_pos = 0; | ||
107 | line_pos = 1; | ||
57 | do { | 108 | do { |
58 | c1 = fgetc(fp1); | 109 | c1 = getc(fp1); |
59 | c2 = fgetc(fp2); | 110 | c2 = getc(fp2); |
60 | if (c1 != c2) { | 111 | ++char_pos; |
61 | if (silent) | 112 | if (c1 != c2) { /* Remember -- a read error may have occurred. */ |
62 | return EXIT_FAILURE; | 113 | exit_val = 1; /* But assume the files are different for now. */ |
63 | if (c1 == EOF) | 114 | if (c2 == EOF) { |
64 | printf("EOF on %s\n", filename1); | 115 | /* We know that fp1 isn't at EOF or in an error state. But to |
65 | else if (c2 == EOF) | 116 | * save space below, things are setup to expect an EOF in fp1 |
66 | printf("EOF on %s\n", filename2); | 117 | * if an EOF occurred. So, swap things around. |
67 | else | 118 | */ |
68 | printf("%s %s differ: char %d, line %d\n", filename1, filename2, | 119 | fp1 = fp2; |
69 | char_pos, line_pos); | 120 | filename1 = filename2; |
70 | return EXIT_FAILURE; | 121 | c1 = c2; |
122 | } | ||
123 | if (c1 == EOF) { | ||
124 | bb_xferror(fp1, filename1); | ||
125 | fmt = fmt_eof; /* Well, no error, so it must really be EOF. */ | ||
126 | outfile = stderr; | ||
127 | /* There may have been output to stdout (option -l), so | ||
128 | * make sure we fflush before writing to stderr. */ | ||
129 | bb_xfflush_stdout(); | ||
130 | } | ||
131 | if (opt_flags != OPT_s) { | ||
132 | if (opt_flags == OPT_l) { | ||
133 | line_pos = c1; /* line_pos is unused in the -l case. */ | ||
134 | } | ||
135 | bb_fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2); | ||
136 | if (opt_flags) { /* This must be -l since not -s. */ | ||
137 | /* If we encountered and EOF, the while check will catch it. */ | ||
138 | continue; | ||
139 | } | ||
140 | } | ||
141 | break; | ||
142 | } | ||
143 | if (c1 == '\n') { | ||
144 | ++line_pos; | ||
71 | } | 145 | } |
72 | char_pos++; | ||
73 | if (c1 == '\n') | ||
74 | line_pos++; | ||
75 | } while (c1 != EOF); | 146 | } while (c1 != EOF); |
76 | 147 | ||
77 | return EXIT_SUCCESS; | 148 | bb_xferror(fp1, filename1); |
149 | bb_xferror(fp2, filename2); | ||
150 | |||
151 | bb_fflush_stdout_and_exit(exit_val); | ||
78 | } | 152 | } |
diff --git a/coreutils/cp.c b/coreutils/cp.c index 8f8fe5ed3..c5dd31ec3 100644 --- a/coreutils/cp.c +++ b/coreutils/cp.c | |||
@@ -2,7 +2,6 @@ | |||
2 | /* | 2 | /* |
3 | * Mini cp implementation for busybox | 3 | * Mini cp implementation for busybox |
4 | * | 4 | * |
5 | * | ||
6 | * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> | 5 | * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> |
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -21,6 +20,15 @@ | |||
21 | * | 20 | * |
22 | */ | 21 | */ |
23 | 22 | ||
23 | /* BB_AUDIT SUSv3 defects - unsupported options -H, -L, and -P. */ | ||
24 | /* BB_AUDIT GNU defects - only extension options supported are -a and -d. */ | ||
25 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */ | ||
26 | |||
27 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
28 | * | ||
29 | * Size reduction. | ||
30 | */ | ||
31 | |||
24 | #include <sys/types.h> | 32 | #include <sys/types.h> |
25 | #include <sys/stat.h> | 33 | #include <sys/stat.h> |
26 | #include <unistd.h> | 34 | #include <unistd.h> |
@@ -29,86 +37,76 @@ | |||
29 | #include <errno.h> | 37 | #include <errno.h> |
30 | #include <dirent.h> | 38 | #include <dirent.h> |
31 | #include <stdlib.h> | 39 | #include <stdlib.h> |
32 | 40 | #include <assert.h> | |
33 | #include "busybox.h" | 41 | #include "busybox.h" |
42 | #include "libcoreutils/coreutils.h" | ||
43 | |||
44 | static const char cp_opts[] = "pdRfia"; /* WARNING!! ORDER IS IMPORTANT!! */ | ||
34 | 45 | ||
35 | extern int cp_main(int argc, char **argv) | 46 | extern int cp_main(int argc, char **argv) |
36 | { | 47 | { |
48 | struct stat source_stat; | ||
49 | struct stat dest_stat; | ||
50 | const char *last; | ||
51 | const char *dest; | ||
52 | int s_flags; | ||
53 | int d_flags; | ||
54 | int flags; | ||
37 | int status = 0; | 55 | int status = 0; |
38 | int opt; | ||
39 | int flags = FILEUTILS_DEREFERENCE; | ||
40 | int i; | ||
41 | 56 | ||
42 | while ((opt = getopt(argc, argv, "adfipR")) != -1) | 57 | /* Since these are enums, #if tests will not work. So use assert()s. */ |
43 | switch (opt) { | 58 | assert(FILEUTILS_PRESERVE_STATUS == 1); |
44 | case 'a': | 59 | assert(FILEUTILS_DEREFERENCE == 2); |
45 | flags |= FILEUTILS_PRESERVE_STATUS | FILEUTILS_RECUR; | 60 | assert(FILEUTILS_RECUR == 4); |
46 | /* fallthrough */ | 61 | assert(FILEUTILS_FORCE == 8); |
47 | case 'd': | 62 | assert(FILEUTILS_INTERACTIVE == 16); |
48 | flags &= ~FILEUTILS_DEREFERENCE; | ||
49 | break; | ||
50 | case 'f': | ||
51 | flags |= FILEUTILS_FORCE; | ||
52 | break; | ||
53 | case 'i': | ||
54 | flags |= FILEUTILS_INTERACTIVE; | ||
55 | break; | ||
56 | case 'p': | ||
57 | flags |= FILEUTILS_PRESERVE_STATUS; | ||
58 | break; | ||
59 | case 'R': | ||
60 | flags |= FILEUTILS_RECUR; | ||
61 | break; | ||
62 | default: | ||
63 | show_usage(); | ||
64 | } | ||
65 | |||
66 | if (optind + 2 > argc) | ||
67 | show_usage(); | ||
68 | 63 | ||
69 | /* If there are only two arguments and... */ | 64 | flags = bb_getopt_ulflags(argc, argv, cp_opts); |
70 | if (optind + 2 == argc) { | ||
71 | struct stat source_stat; | ||
72 | struct stat dest_stat; | ||
73 | int source_exists = 1; | ||
74 | int dest_exists = 1; | ||
75 | 65 | ||
76 | if ((!(flags & FILEUTILS_DEREFERENCE) && | 66 | if (flags & 32) { |
77 | lstat(argv[optind], &source_stat) < 0) || | 67 | flags |= (FILEUTILS_PRESERVE_STATUS | FILEUTILS_RECUR | FILEUTILS_DEREFERENCE); |
78 | ((flags & FILEUTILS_DEREFERENCE) && | 68 | } |
79 | stat(argv[optind], &source_stat))) { | 69 | |
80 | if (errno != ENOENT) | 70 | flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */ |
81 | perror_msg_and_die("unable to stat `%s'", argv[optind]); | 71 | |
82 | source_exists = 0; | 72 | if (optind + 2 > argc) { |
83 | } | 73 | bb_show_usage(); |
74 | } | ||
75 | |||
76 | last = argv[argc - 1]; | ||
77 | argv += optind; | ||
84 | 78 | ||
85 | if (stat(argv[optind + 1], &dest_stat) < 0) { | 79 | /* If there are only two arguments and... */ |
86 | if (errno != ENOENT) | 80 | if (optind + 2 == argc) { |
87 | perror_msg_and_die("unable to stat `%s'", argv[optind + 1]); | 81 | s_flags = cp_mv_stat2(*argv, &source_stat, |
88 | dest_exists = 0; | 82 | (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); |
83 | if ((s_flags < 0) || ((d_flags = cp_mv_stat(last, &dest_stat)) < 0)) { | ||
84 | exit(EXIT_FAILURE); | ||
89 | } | 85 | } |
90 | |||
91 | /* ...if neither is a directory or... */ | 86 | /* ...if neither is a directory or... */ |
92 | if (((!source_exists || !S_ISDIR(source_stat.st_mode)) && | 87 | if ( !((s_flags | d_flags) & 2) || |
93 | (!dest_exists || !S_ISDIR(dest_stat.st_mode))) || | 88 | /* ...recursing, the 1st is a directory, and the 2nd doesn't exist... */ |
94 | /* ...recursing, the first is a directory, and the | 89 | /* ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags) */ |
95 | * second doesn't exist, then... */ | 90 | /* Simplify the above since FILEUTILS_RECUR >> 1 == 2. */ |
96 | ((flags & FILEUTILS_RECUR) && S_ISDIR(source_stat.st_mode) && | 91 | ((((flags & FILEUTILS_RECUR) >> 1) & s_flags) && !d_flags) |
97 | !dest_exists)) { | 92 | ) { |
98 | /* ...do a simple copy. */ | 93 | /* ...do a simple copy. */ |
99 | if (copy_file(argv[optind], argv[optind + 1], flags) < 0) | 94 | dest = last; |
100 | status = 1; | 95 | goto DO_COPY; /* Note: optind+2==argc implies argv[1]==last below. */ |
101 | return status; | ||
102 | } | 96 | } |
103 | } | 97 | } |
104 | 98 | ||
105 | for (i = optind; i < argc - 1; i++) { | 99 | do { |
106 | char *dest = concat_path_file(argv[argc - 1], | 100 | dest = concat_path_file(last, bb_get_last_path_component(*argv)); |
107 | get_last_path_component(argv[i])); | 101 | DO_COPY: |
108 | if (copy_file(argv[i], dest, flags) < 0) | 102 | if (copy_file(*argv, dest, flags) < 0) { |
109 | status = 1; | 103 | status = 1; |
110 | free(dest); | 104 | } |
111 | } | 105 | if (*++argv == last) { |
106 | break; | ||
107 | } | ||
108 | free((void *) dest); | ||
109 | } while (1); | ||
112 | 110 | ||
113 | return status; | 111 | exit(status); |
114 | } | 112 | } |
diff --git a/coreutils/cut.c b/coreutils/cut.c index 3ed264870..c24cf6611 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c | |||
@@ -92,7 +92,7 @@ static void parse_lists(char *lists) | |||
92 | } else { | 92 | } else { |
93 | s = strtoul(ntok, &junk, 10); | 93 | s = strtoul(ntok, &junk, 10); |
94 | if(*junk != '\0' || s < 0) | 94 | if(*junk != '\0' || s < 0) |
95 | error_msg_and_die("invalid byte or field list"); | 95 | bb_error_msg_and_die("invalid byte or field list"); |
96 | 96 | ||
97 | /* account for the fact that arrays are zero based, while the user | 97 | /* account for the fact that arrays are zero based, while the user |
98 | * expects the first char on the line to be char # 1 */ | 98 | * expects the first char on the line to be char # 1 */ |
@@ -109,7 +109,7 @@ static void parse_lists(char *lists) | |||
109 | } else { | 109 | } else { |
110 | e = strtoul(ntok, &junk, 10); | 110 | e = strtoul(ntok, &junk, 10); |
111 | if(*junk != '\0' || e < 0) | 111 | if(*junk != '\0' || e < 0) |
112 | error_msg_and_die("invalid byte or field list"); | 112 | bb_error_msg_and_die("invalid byte or field list"); |
113 | /* if the user specified and end position of 0, that means "til the | 113 | /* if the user specified and end position of 0, that means "til the |
114 | * end of the line */ | 114 | * end of the line */ |
115 | if (e == 0) | 115 | if (e == 0) |
@@ -121,7 +121,7 @@ static void parse_lists(char *lists) | |||
121 | 121 | ||
122 | /* if there's something left to tokenize, the user past an invalid list */ | 122 | /* if there's something left to tokenize, the user past an invalid list */ |
123 | if (ltok) | 123 | if (ltok) |
124 | error_msg_and_die("invalid byte or field list"); | 124 | bb_error_msg_and_die("invalid byte or field list"); |
125 | 125 | ||
126 | /* add the new list */ | 126 | /* add the new list */ |
127 | cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists)); | 127 | cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists)); |
@@ -131,7 +131,7 @@ static void parse_lists(char *lists) | |||
131 | 131 | ||
132 | /* make sure we got some cut positions out of all that */ | 132 | /* make sure we got some cut positions out of all that */ |
133 | if (nlists == 0) | 133 | if (nlists == 0) |
134 | error_msg_and_die("missing list of positions"); | 134 | bb_error_msg_and_die("missing list of positions"); |
135 | 135 | ||
136 | /* now that the lists are parsed, we need to sort them to make life easier | 136 | /* now that the lists are parsed, we need to sort them to make life easier |
137 | * on us when it comes time to print the chars / fields / lines */ | 137 | * on us when it comes time to print the chars / fields / lines */ |
@@ -267,8 +267,7 @@ static void cut_file(FILE *file) | |||
267 | unsigned int linenum = 0; /* keep these zero-based to be consistent */ | 267 | unsigned int linenum = 0; /* keep these zero-based to be consistent */ |
268 | 268 | ||
269 | /* go through every line in the file */ | 269 | /* go through every line in the file */ |
270 | while ((line = get_line_from_file(file)) != NULL) { | 270 | while ((line = bb_get_chomped_line_from_file(file)) != NULL) { |
271 | chomp(line); | ||
272 | 271 | ||
273 | /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ | 272 | /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ |
274 | if (part == 'c' || part == 'b') | 273 | if (part == 'c' || part == 'b') |
@@ -299,14 +298,14 @@ extern int cut_main(int argc, char **argv) | |||
299 | case 'f': | 298 | case 'f': |
300 | /* make sure they didn't ask for two types of lists */ | 299 | /* make sure they didn't ask for two types of lists */ |
301 | if (part != 0) { | 300 | if (part != 0) { |
302 | error_msg_and_die("only one type of list may be specified"); | 301 | bb_error_msg_and_die("only one type of list may be specified"); |
303 | } | 302 | } |
304 | part = (char)opt; | 303 | part = (char)opt; |
305 | parse_lists(optarg); | 304 | parse_lists(optarg); |
306 | break; | 305 | break; |
307 | case 'd': | 306 | case 'd': |
308 | if (strlen(optarg) > 1) { | 307 | if (strlen(optarg) > 1) { |
309 | error_msg_and_die("the delimiter must be a single character"); | 308 | bb_error_msg_and_die("the delimiter must be a single character"); |
310 | } | 309 | } |
311 | delim = optarg[0]; | 310 | delim = optarg[0]; |
312 | break; | 311 | break; |
@@ -320,17 +319,17 @@ extern int cut_main(int argc, char **argv) | |||
320 | } | 319 | } |
321 | 320 | ||
322 | if (part == 0) { | 321 | if (part == 0) { |
323 | error_msg_and_die("you must specify a list of bytes, characters, or fields"); | 322 | bb_error_msg_and_die("you must specify a list of bytes, characters, or fields"); |
324 | } | 323 | } |
325 | 324 | ||
326 | /* non-field (char or byte) cutting has some special handling */ | 325 | /* non-field (char or byte) cutting has some special handling */ |
327 | if (part != 'f') { | 326 | if (part != 'f') { |
328 | if (supress_non_delimited_lines) { | 327 | if (supress_non_delimited_lines) { |
329 | error_msg_and_die("suppressing non-delimited lines makes sense" | 328 | bb_error_msg_and_die("suppressing non-delimited lines makes sense" |
330 | " only when operating on fields"); | 329 | " only when operating on fields"); |
331 | } | 330 | } |
332 | if (delim != '\t' && part != 'f') { | 331 | if (delim != '\t' && part != 'f') { |
333 | error_msg_and_die("a delimiter may be specified only when operating on fields"); | 332 | bb_error_msg_and_die("a delimiter may be specified only when operating on fields"); |
334 | } | 333 | } |
335 | } | 334 | } |
336 | 335 | ||
@@ -344,7 +343,7 @@ extern int cut_main(int argc, char **argv) | |||
344 | int i; | 343 | int i; |
345 | FILE *file; | 344 | FILE *file; |
346 | for (i = optind; i < argc; i++) { | 345 | for (i = optind; i < argc; i++) { |
347 | file = wfopen(argv[i], "r"); | 346 | file = bb_wfopen(argv[i], "r"); |
348 | if(file) { | 347 | if(file) { |
349 | cut_file(file); | 348 | cut_file(file); |
350 | fclose(file); | 349 | fclose(file); |
diff --git a/coreutils/date.c b/coreutils/date.c index d68c04a8d..afbedb90d 100644 --- a/coreutils/date.c +++ b/coreutils/date.c | |||
@@ -53,7 +53,7 @@ static struct tm *date_conv_time(struct tm *tm_time, const char *t_string) | |||
53 | &(tm_time->tm_year)); | 53 | &(tm_time->tm_year)); |
54 | 54 | ||
55 | if (nr < 4 || nr > 5) { | 55 | if (nr < 4 || nr > 5) { |
56 | error_msg_and_die(invalid_date, t_string); | 56 | bb_error_msg_and_die(bb_msg_invalid_date, t_string); |
57 | } | 57 | } |
58 | 58 | ||
59 | /* correct for century - minor Y2K problem here? */ | 59 | /* correct for century - minor Y2K problem here? */ |
@@ -108,7 +108,7 @@ static struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string) | |||
108 | t.tm_year -= 1900; /* Adjust years */ | 108 | t.tm_year -= 1900; /* Adjust years */ |
109 | t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | 109 | t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ |
110 | } else { | 110 | } else { |
111 | error_msg_and_die(invalid_date, t_string); | 111 | bb_error_msg_and_die(bb_msg_invalid_date, t_string); |
112 | } | 112 | } |
113 | *tm_time = t; | 113 | *tm_time = t; |
114 | return (tm_time); | 114 | return (tm_time); |
@@ -145,25 +145,25 @@ int date_main(int argc, char **argv) | |||
145 | case 's': | 145 | case 's': |
146 | set_time = 1; | 146 | set_time = 1; |
147 | if ((date_str != NULL) || ((date_str = optarg) == NULL)) { | 147 | if ((date_str != NULL) || ((date_str = optarg) == NULL)) { |
148 | show_usage(); | 148 | bb_show_usage(); |
149 | } | 149 | } |
150 | break; | 150 | break; |
151 | case 'u': | 151 | case 'u': |
152 | utc = 1; | 152 | utc = 1; |
153 | if (putenv("TZ=UTC0") != 0) | 153 | if (putenv("TZ=UTC0") != 0) |
154 | error_msg_and_die(memory_exhausted); | 154 | bb_error_msg_and_die(bb_msg_memory_exhausted); |
155 | break; | 155 | break; |
156 | case 'd': | 156 | case 'd': |
157 | use_arg = 1; | 157 | use_arg = 1; |
158 | if ((date_str != NULL) || ((date_str = optarg) == NULL)) | 158 | if ((date_str != NULL) || ((date_str = optarg) == NULL)) |
159 | show_usage(); | 159 | bb_show_usage(); |
160 | break; | 160 | break; |
161 | #ifdef CONFIG_FEATURE_DATE_ISOFMT | 161 | #ifdef CONFIG_FEATURE_DATE_ISOFMT |
162 | case 'I': | 162 | case 'I': |
163 | if (!optarg) | 163 | if (!optarg) |
164 | ifmt = 1; | 164 | ifmt = 1; |
165 | else { | 165 | else { |
166 | int ifmt_len = xstrlen(optarg); | 166 | int ifmt_len = bb_strlen(optarg); |
167 | 167 | ||
168 | if ((ifmt_len <= 4) | 168 | if ((ifmt_len <= 4) |
169 | && (strncmp(optarg, "date", ifmt_len) == 0)) { | 169 | && (strncmp(optarg, "date", ifmt_len) == 0)) { |
@@ -180,11 +180,11 @@ int date_main(int argc, char **argv) | |||
180 | } | 180 | } |
181 | } | 181 | } |
182 | if (ifmt) { | 182 | if (ifmt) { |
183 | break; /* else show_usage(); */ | 183 | break; /* else bb_show_usage(); */ |
184 | } | 184 | } |
185 | #endif | 185 | #endif |
186 | default: | 186 | default: |
187 | show_usage(); | 187 | bb_show_usage(); |
188 | } | 188 | } |
189 | } | 189 | } |
190 | 190 | ||
@@ -220,15 +220,15 @@ int date_main(int argc, char **argv) | |||
220 | /* Correct any day of week and day of year etc. fields */ | 220 | /* Correct any day of week and day of year etc. fields */ |
221 | tm = mktime(&tm_time); | 221 | tm = mktime(&tm_time); |
222 | if (tm < 0) { | 222 | if (tm < 0) { |
223 | error_msg_and_die(invalid_date, date_str); | 223 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); |
224 | } | 224 | } |
225 | if (utc && (putenv("TZ=UTC0") != 0)) { | 225 | if (utc && (putenv("TZ=UTC0") != 0)) { |
226 | error_msg_and_die(memory_exhausted); | 226 | bb_error_msg_and_die(bb_msg_memory_exhausted); |
227 | } | 227 | } |
228 | 228 | ||
229 | /* if setting time, set it */ | 229 | /* if setting time, set it */ |
230 | if (set_time && (stime(&tm) < 0)) { | 230 | if (set_time && (stime(&tm) < 0)) { |
231 | perror_msg("cannot set date"); | 231 | bb_perror_msg("cannot set date"); |
232 | } | 232 | } |
233 | } | 233 | } |
234 | 234 | ||
diff --git a/coreutils/dd.c b/coreutils/dd.c index 8c7272b5c..11508614f 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -62,19 +62,19 @@ int dd_main(int argc, char **argv) | |||
62 | int ifd; | 62 | int ifd; |
63 | int ofd; | 63 | int ofd; |
64 | int i; | 64 | int i; |
65 | char *infile = NULL; | 65 | const char *infile = NULL; |
66 | char *outfile = NULL; | 66 | const char *outfile = NULL; |
67 | char *buf; | 67 | char *buf; |
68 | 68 | ||
69 | for (i = 1; i < argc; i++) { | 69 | for (i = 1; i < argc; i++) { |
70 | if (strncmp("bs=", argv[i], 3) == 0) | 70 | if (strncmp("bs=", argv[i], 3) == 0) |
71 | bs = parse_number(argv[i]+3, dd_suffixes); | 71 | bs = bb_xparse_number(argv[i]+3, dd_suffixes); |
72 | else if (strncmp("count=", argv[i], 6) == 0) | 72 | else if (strncmp("count=", argv[i], 6) == 0) |
73 | count = parse_number(argv[i]+6, dd_suffixes); | 73 | count = bb_xparse_number(argv[i]+6, dd_suffixes); |
74 | else if (strncmp("seek=", argv[i], 5) == 0) | 74 | else if (strncmp("seek=", argv[i], 5) == 0) |
75 | seek = parse_number(argv[i]+5, dd_suffixes); | 75 | seek = bb_xparse_number(argv[i]+5, dd_suffixes); |
76 | else if (strncmp("skip=", argv[i], 5) == 0) | 76 | else if (strncmp("skip=", argv[i], 5) == 0) |
77 | skip = parse_number(argv[i]+5, dd_suffixes); | 77 | skip = bb_xparse_number(argv[i]+5, dd_suffixes); |
78 | else if (strncmp("if=", argv[i], 3) == 0) | 78 | else if (strncmp("if=", argv[i], 3) == 0) |
79 | infile = argv[i]+3; | 79 | infile = argv[i]+3; |
80 | else if (strncmp("of=", argv[i], 3) == 0) | 80 | else if (strncmp("of=", argv[i], 3) == 0) |
@@ -92,7 +92,7 @@ int dd_main(int argc, char **argv) | |||
92 | noerror = TRUE; | 92 | noerror = TRUE; |
93 | buf += 7; | 93 | buf += 7; |
94 | } else { | 94 | } else { |
95 | error_msg_and_die("invalid conversion `%s'", argv[i]+5); | 95 | bb_error_msg_and_die("invalid conversion `%s'", argv[i]+5); |
96 | } | 96 | } |
97 | if (buf[0] == '\0') | 97 | if (buf[0] == '\0') |
98 | break; | 98 | break; |
@@ -100,18 +100,18 @@ int dd_main(int argc, char **argv) | |||
100 | buf++; | 100 | buf++; |
101 | } | 101 | } |
102 | } else | 102 | } else |
103 | show_usage(); | 103 | bb_show_usage(); |
104 | } | 104 | } |
105 | 105 | ||
106 | buf = xmalloc(bs); | 106 | buf = xmalloc(bs); |
107 | 107 | ||
108 | if (infile != NULL) { | 108 | if (infile != NULL) { |
109 | if ((ifd = open(infile, O_RDONLY)) < 0) { | 109 | if ((ifd = open(infile, O_RDONLY)) < 0) { |
110 | perror_msg_and_die("%s", infile); | 110 | bb_perror_msg_and_die("%s", infile); |
111 | } | 111 | } |
112 | } else { | 112 | } else { |
113 | ifd = STDIN_FILENO; | 113 | ifd = STDIN_FILENO; |
114 | infile = "standard input"; | 114 | infile = bb_msg_standard_input; |
115 | } | 115 | } |
116 | 116 | ||
117 | if (outfile != NULL) { | 117 | if (outfile != NULL) { |
@@ -122,7 +122,7 @@ int dd_main(int argc, char **argv) | |||
122 | } | 122 | } |
123 | 123 | ||
124 | if ((ofd = open(outfile, oflag, 0666)) < 0) { | 124 | if ((ofd = open(outfile, oflag, 0666)) < 0) { |
125 | perror_msg_and_die("%s", outfile); | 125 | bb_perror_msg_and_die("%s", outfile); |
126 | } | 126 | } |
127 | 127 | ||
128 | if (seek && trunc) { | 128 | if (seek && trunc) { |
@@ -131,24 +131,24 @@ int dd_main(int argc, char **argv) | |||
131 | 131 | ||
132 | if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) || | 132 | if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) || |
133 | S_ISDIR (st.st_mode)) { | 133 | S_ISDIR (st.st_mode)) { |
134 | perror_msg_and_die("%s", outfile); | 134 | bb_perror_msg_and_die("%s", outfile); |
135 | } | 135 | } |
136 | } | 136 | } |
137 | } | 137 | } |
138 | } else { | 138 | } else { |
139 | ofd = STDOUT_FILENO; | 139 | ofd = STDOUT_FILENO; |
140 | outfile = "standard output"; | 140 | outfile = bb_msg_standard_output; |
141 | } | 141 | } |
142 | 142 | ||
143 | if (skip) { | 143 | if (skip) { |
144 | if (lseek(ifd, skip * bs, SEEK_CUR) < 0) { | 144 | if (lseek(ifd, skip * bs, SEEK_CUR) < 0) { |
145 | perror_msg_and_die("%s", infile); | 145 | bb_perror_msg_and_die("%s", infile); |
146 | } | 146 | } |
147 | } | 147 | } |
148 | 148 | ||
149 | if (seek) { | 149 | if (seek) { |
150 | if (lseek(ofd, seek * bs, SEEK_CUR) < 0) { | 150 | if (lseek(ofd, seek * bs, SEEK_CUR) < 0) { |
151 | perror_msg_and_die("%s", outfile); | 151 | bb_perror_msg_and_die("%s", outfile); |
152 | } | 152 | } |
153 | } | 153 | } |
154 | 154 | ||
@@ -161,9 +161,9 @@ int dd_main(int argc, char **argv) | |||
161 | if (n < 0) { | 161 | if (n < 0) { |
162 | if (noerror) { | 162 | if (noerror) { |
163 | n = bs; | 163 | n = bs; |
164 | perror_msg("%s", infile); | 164 | bb_perror_msg("%s", infile); |
165 | } else { | 165 | } else { |
166 | perror_msg_and_die("%s", infile); | 166 | bb_perror_msg_and_die("%s", infile); |
167 | } | 167 | } |
168 | } | 168 | } |
169 | if (n == 0) { | 169 | if (n == 0) { |
@@ -178,9 +178,9 @@ int dd_main(int argc, char **argv) | |||
178 | memset(buf + n, '\0', bs - n); | 178 | memset(buf + n, '\0', bs - n); |
179 | n = bs; | 179 | n = bs; |
180 | } | 180 | } |
181 | n = full_write(ofd, buf, n); | 181 | n = bb_full_write(ofd, buf, n); |
182 | if (n < 0) { | 182 | if (n < 0) { |
183 | perror_msg_and_die("%s", outfile); | 183 | bb_perror_msg_and_die("%s", outfile); |
184 | } | 184 | } |
185 | if (n == bs) { | 185 | if (n == bs) { |
186 | out_full++; | 186 | out_full++; |
@@ -190,15 +190,16 @@ int dd_main(int argc, char **argv) | |||
190 | } | 190 | } |
191 | 191 | ||
192 | if (close (ifd) < 0) { | 192 | if (close (ifd) < 0) { |
193 | perror_msg_and_die("%s", infile); | 193 | bb_perror_msg_and_die("%s", infile); |
194 | } | 194 | } |
195 | 195 | ||
196 | if (close (ofd) < 0) { | 196 | if (close (ofd) < 0) { |
197 | perror_msg_and_die("%s", outfile); | 197 | bb_perror_msg_and_die("%s", outfile); |
198 | } | 198 | } |
199 | 199 | ||
200 | fprintf(stderr, "%ld+%ld records in\n", (long)in_full, (long)in_part); | 200 | fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n", |
201 | fprintf(stderr, "%ld+%ld records out\n", (long)out_full, (long)out_part); | 201 | (long)in_full, (long)in_part, |
202 | (long)out_full, (long)out_part); | ||
202 | 203 | ||
203 | return EXIT_SUCCESS; | 204 | return EXIT_SUCCESS; |
204 | } | 205 | } |
diff --git a/coreutils/df.c b/coreutils/df.c index 0e9e5d61a..7d007a003 100644 --- a/coreutils/df.c +++ b/coreutils/df.c | |||
@@ -22,74 +22,45 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | /* BB_AUDIT SUSv3 _NOT_ compliant -- options -P and -t missing. Also blocksize. */ | ||
26 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/df.html */ | ||
27 | |||
28 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
29 | * | ||
30 | * Size reduction. Removed floating point dependency. Added error checking | ||
31 | * on output. Output stats on 0-sized filesystems if specificly listed on | ||
32 | * the command line. Properly round *-blocks, Used, and Available quantities. | ||
33 | */ | ||
34 | |||
25 | #include <stdio.h> | 35 | #include <stdio.h> |
26 | #include <stdlib.h> | 36 | #include <stdlib.h> |
27 | #include <string.h> | 37 | #include <string.h> |
38 | #include <unistd.h> | ||
28 | #include <mntent.h> | 39 | #include <mntent.h> |
29 | #include <sys/vfs.h> | 40 | #include <sys/vfs.h> |
30 | #include <getopt.h> | ||
31 | #include "busybox.h" | 41 | #include "busybox.h" |
32 | 42 | ||
33 | extern const char mtab_file[]; /* Defined in utility.c */ | 43 | #ifndef CONFIG_FEATURE_HUMAN_READABLE |
34 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 44 | static long kscale(long b, long bs) |
35 | static unsigned long df_disp_hr = KILOBYTE; | 45 | { |
46 | return ( b * (long long) bs + KILOBYTE/2 ) / KILOBYTE; | ||
47 | } | ||
36 | #endif | 48 | #endif |
37 | 49 | ||
38 | static int do_df(char *device, const char *mount_point) | 50 | extern int df_main(int argc, char **argv) |
39 | { | 51 | { |
40 | struct statfs s; | ||
41 | long blocks_used; | 52 | long blocks_used; |
42 | long blocks_percent_used; | 53 | long blocks_percent_used; |
43 | |||
44 | if (statfs(mount_point, &s) != 0) { | ||
45 | perror_msg("%s", mount_point); | ||
46 | return FALSE; | ||
47 | } | ||
48 | |||
49 | if (s.f_blocks > 0) { | ||
50 | blocks_used = s.f_blocks - s.f_bfree; | ||
51 | if(blocks_used == 0) | ||
52 | blocks_percent_used = 0; | ||
53 | else { | ||
54 | blocks_percent_used = (long) | ||
55 | (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); | ||
56 | } | ||
57 | if (strcmp(device, "/dev/root") == 0) { | ||
58 | /* Adjusts device to be the real root device, | ||
59 | * or leaves device alone if it can't find it */ | ||
60 | device = find_real_root_device_name(device); | ||
61 | if(device==NULL) | ||
62 | return FALSE; | ||
63 | } | ||
64 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 54 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
65 | printf("%-20s %9s ", device, | 55 | unsigned long df_disp_hr = KILOBYTE; |
66 | make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr)); | ||
67 | |||
68 | printf("%9s ", | ||
69 | make_human_readable_str( (s.f_blocks - s.f_bfree), s.f_bsize, df_disp_hr)); | ||
70 | |||
71 | printf("%9s %3ld%% %s\n", | ||
72 | make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr), | ||
73 | blocks_percent_used, mount_point); | ||
74 | #else | ||
75 | printf("%-20s %9ld %9ld %9ld %3ld%% %s\n", | ||
76 | device, | ||
77 | (long) (s.f_blocks * (s.f_bsize / (double)KILOBYTE)), | ||
78 | (long) ((s.f_blocks - s.f_bfree)*(s.f_bsize/(double)KILOBYTE)), | ||
79 | (long) (s.f_bavail * (s.f_bsize / (double)KILOBYTE)), | ||
80 | blocks_percent_used, mount_point); | ||
81 | #endif | 56 | #endif |
82 | } | ||
83 | |||
84 | return TRUE; | ||
85 | } | ||
86 | |||
87 | extern int df_main(int argc, char **argv) | ||
88 | { | ||
89 | int status = EXIT_SUCCESS; | 57 | int status = EXIT_SUCCESS; |
90 | int opt = 0; | 58 | int opt; |
91 | int i = 0; | 59 | FILE *mount_table; |
92 | char disp_units_hdr[80] = "1k-blocks"; /* default display is kilobytes */ | 60 | struct mntent *mount_entry; |
61 | struct statfs s; | ||
62 | static const char hdr_1k[] = "1k-blocks"; /* default display is kilobytes */; | ||
63 | const char *disp_units_hdr = hdr_1k; | ||
93 | 64 | ||
94 | while ((opt = getopt(argc, argv, "k" | 65 | while ((opt = getopt(argc, argv, "k" |
95 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 66 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
@@ -101,52 +72,106 @@ extern int df_main(int argc, char **argv) | |||
101 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 72 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
102 | case 'h': | 73 | case 'h': |
103 | df_disp_hr = 0; | 74 | df_disp_hr = 0; |
104 | strcpy(disp_units_hdr, " Size"); | 75 | disp_units_hdr = " Size"; |
105 | break; | 76 | break; |
106 | case 'm': | 77 | case 'm': |
107 | df_disp_hr = MEGABYTE; | 78 | df_disp_hr = MEGABYTE; |
108 | strcpy(disp_units_hdr, "1M-blocks"); | 79 | disp_units_hdr = "1M-blocks"; |
109 | break; | 80 | break; |
110 | #endif | 81 | #endif |
111 | case 'k': | 82 | case 'k': |
112 | /* default display is kilobytes */ | 83 | /* default display is kilobytes */ |
84 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||
85 | df_disp_hr = KILOBYTE; | ||
86 | disp_units_hdr = hdr_1k; | ||
87 | #endif | ||
113 | break; | 88 | break; |
114 | default: | 89 | default: |
115 | show_usage(); | 90 | bb_show_usage(); |
116 | } | 91 | } |
117 | } | 92 | } |
118 | 93 | ||
119 | printf("%-20s %-14s %s %s %s %s\n", "Filesystem", disp_units_hdr, | 94 | bb_printf("Filesystem%11s%-15sUsed Available Use%% Mounted on\n", |
120 | "Used", "Available", "Use%", "Mounted on"); | 95 | "", disp_units_hdr); |
121 | 96 | ||
122 | if(optind < argc) { | 97 | mount_table = NULL; |
123 | struct mntent *mount_entry; | 98 | argv += optind; |
124 | for(i = optind; i < argc; i++) | 99 | if (optind >= argc) { |
125 | { | 100 | if (!(mount_table = setmntent(bb_path_mtab_file, "r"))) { |
126 | if ((mount_entry = find_mount_point(argv[i], mtab_file)) == 0) { | 101 | bb_perror_msg_and_die(bb_path_mtab_file); |
127 | error_msg("%s: can't find mount point.", argv[i]); | ||
128 | status = EXIT_FAILURE; | ||
129 | } else if (!do_df(mount_entry->mnt_fsname, mount_entry->mnt_dir)) | ||
130 | status = EXIT_FAILURE; | ||
131 | } | 102 | } |
132 | } else { | 103 | } |
133 | FILE *mount_table; | ||
134 | struct mntent *mount_entry; | ||
135 | 104 | ||
136 | mount_table = setmntent(mtab_file, "r"); | 105 | do { |
137 | if (mount_table == 0) { | 106 | const char *device; |
138 | perror_msg("%s", mtab_file); | 107 | const char *mount_point; |
139 | return EXIT_FAILURE; | ||
140 | } | ||
141 | 108 | ||
142 | while ((mount_entry = getmntent(mount_table))) { | 109 | if (mount_table) { |
143 | if (!do_df(mount_entry->mnt_fsname, mount_entry->mnt_dir)) | 110 | if (!(mount_entry = getmntent(mount_table))) { |
111 | endmntent(mount_table); | ||
112 | break; | ||
113 | } | ||
114 | } else { | ||
115 | if (!(mount_point = *argv++)) { | ||
116 | break; | ||
117 | } | ||
118 | if (!(mount_entry = find_mount_point(mount_point, bb_path_mtab_file))) { | ||
119 | bb_error_msg("%s: can't find mount point.", mount_point); | ||
120 | SET_ERROR: | ||
144 | status = EXIT_FAILURE; | 121 | status = EXIT_FAILURE; |
122 | continue; | ||
123 | } | ||
145 | } | 124 | } |
146 | endmntent(mount_table); | ||
147 | } | ||
148 | 125 | ||
149 | return status; | 126 | device = mount_entry->mnt_fsname; |
127 | mount_point = mount_entry->mnt_dir; | ||
128 | |||
129 | if (statfs(mount_point, &s) != 0) { | ||
130 | bb_perror_msg("%s", mount_point); | ||
131 | goto SET_ERROR; | ||
132 | } | ||
133 | |||
134 | if ((s.f_blocks > 0) || !mount_table){ | ||
135 | blocks_used = s.f_blocks - s.f_bfree; | ||
136 | blocks_percent_used = 0; | ||
137 | if (blocks_used + s.f_bavail) { | ||
138 | blocks_percent_used = (((long long) blocks_used) * 100 | ||
139 | + (blocks_used + s.f_bavail)/2 | ||
140 | ) / (blocks_used + s.f_bavail); | ||
141 | } | ||
142 | |||
143 | if (strcmp(device, "/dev/root") == 0) { | ||
144 | /* Adjusts device to be the real root device, | ||
145 | * or leaves device alone if it can't find it */ | ||
146 | if ((device = find_real_root_device_name(device)) != NULL) { | ||
147 | goto SET_ERROR; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||
152 | bb_printf("%-21s%9s ", device, | ||
153 | make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr)); | ||
154 | |||
155 | bb_printf("%9s ", | ||
156 | make_human_readable_str( (s.f_blocks - s.f_bfree), | ||
157 | s.f_bsize, df_disp_hr)); | ||
158 | |||
159 | bb_printf("%9s %3ld%% %s\n", | ||
160 | make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr), | ||
161 | blocks_percent_used, mount_point); | ||
162 | #else | ||
163 | bb_printf("%-21s%9ld %9ld %9ld %3ld%% %s\n", | ||
164 | device, | ||
165 | kscale(s.f_blocks, s.f_bsize), | ||
166 | kscale(s.f_blocks-s.f_bfree, s.f_bsize), | ||
167 | kscale(s.f_bavail, s.f_bsize), | ||
168 | blocks_percent_used, mount_point); | ||
169 | #endif | ||
170 | } | ||
171 | |||
172 | } while (1); | ||
173 | |||
174 | bb_fflush_stdout_and_exit(status); | ||
150 | } | 175 | } |
151 | 176 | ||
152 | /* | 177 | /* |
diff --git a/coreutils/dirname.c b/coreutils/dirname.c index 387233789..4c6115e66 100644 --- a/coreutils/dirname.c +++ b/coreutils/dirname.c | |||
@@ -21,20 +21,20 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* getopt not needed */ | 24 | /* BB_AUDIT SUSv3 compliant */ |
25 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/dirname.html */ | ||
25 | 26 | ||
26 | #include <stdio.h> | 27 | #include <stdio.h> |
27 | #include <stdlib.h> | 28 | #include <stdlib.h> |
28 | #include <string.h> | ||
29 | #include "busybox.h" | 29 | #include "busybox.h" |
30 | 30 | ||
31 | extern int dirname_main(int argc, char **argv) | 31 | extern int dirname_main(int argc, char **argv) |
32 | { | 32 | { |
33 | if ((argc < 2) || (**(argv + 1) == '-')) | 33 | if (argc != 2) { |
34 | show_usage(); | 34 | bb_show_usage(); |
35 | argv++; | 35 | } |
36 | 36 | ||
37 | puts (dirname (argv[0])); | 37 | puts(dirname(argv[1])); |
38 | 38 | ||
39 | return EXIT_SUCCESS; | 39 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); |
40 | } | 40 | } |
diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c index b1d0a9d70..c28e6a8b9 100644 --- a/coreutils/dos2unix.c +++ b/coreutils/dos2unix.c | |||
@@ -35,6 +35,10 @@ | |||
35 | #include <sys/time.h> | 35 | #include <sys/time.h> |
36 | #include "busybox.h" | 36 | #include "busybox.h" |
37 | 37 | ||
38 | #define CT_AUTO 0 | ||
39 | #define CT_UNIX2DOS 1 | ||
40 | #define CT_DOS2UNIX 2 | ||
41 | |||
38 | /* We are making a lame pseudo-random string generator here. in | 42 | /* We are making a lame pseudo-random string generator here. in |
39 | * convert(), each pass through the while loop will add more and more | 43 | * convert(), each pass through the while loop will add more and more |
40 | * stuff into value, which is _supposed_ to wrap. We don't care about | 44 | * stuff into value, which is _supposed_ to wrap. We don't care about |
@@ -55,15 +59,13 @@ static int convert(char *fn, int ConvType) | |||
55 | FILE *in = stdin, *out = stdout; | 59 | FILE *in = stdin, *out = stdout; |
56 | 60 | ||
57 | if (fn != NULL) { | 61 | if (fn != NULL) { |
58 | if ((in = wfopen(fn, "rw")) == NULL) { | 62 | in = bb_xfopen(fn, "rw"); |
59 | return -1; | ||
60 | } | ||
61 | safe_strncpy(tempFn, fn, sizeof(tempFn)); | 63 | safe_strncpy(tempFn, fn, sizeof(tempFn)); |
62 | c = strlen(tempFn); | 64 | c = strlen(tempFn); |
63 | tempFn[c] = '.'; | 65 | tempFn[c] = '.'; |
64 | while(1) { | 66 | while(1) { |
65 | if (c >=BUFSIZ) | 67 | if (c >=BUFSIZ) |
66 | error_msg_and_die("unique name not found"); | 68 | bb_error_msg_and_die("unique name not found"); |
67 | /* Get some semi random stuff to try and make a | 69 | /* Get some semi random stuff to try and make a |
68 | * random filename based (and in the same dir as) | 70 | * random filename based (and in the same dir as) |
69 | * the input file... */ | 71 | * the input file... */ |
@@ -92,7 +94,7 @@ static int convert(char *fn, int ConvType) | |||
92 | // file is alredy in DOS format so it is not necessery to touch it | 94 | // file is alredy in DOS format so it is not necessery to touch it |
93 | remove(tempFn); | 95 | remove(tempFn); |
94 | if (fclose(in) < 0 || fclose(out) < 0) { | 96 | if (fclose(in) < 0 || fclose(out) < 0) { |
95 | perror_msg(NULL); | 97 | bb_perror_nomsg(); |
96 | return -2; | 98 | return -2; |
97 | } | 99 | } |
98 | return 0; | 100 | return 0; |
@@ -106,7 +108,7 @@ static int convert(char *fn, int ConvType) | |||
106 | // file is alredy in UNIX format so it is not necessery to touch it | 108 | // file is alredy in UNIX format so it is not necessery to touch it |
107 | remove(tempFn); | 109 | remove(tempFn); |
108 | if ((fclose(in) < 0) || (fclose(out) < 0)) { | 110 | if ((fclose(in) < 0) || (fclose(out) < 0)) { |
109 | perror_msg(NULL); | 111 | bb_perror_nomsg(); |
110 | return -2; | 112 | return -2; |
111 | } | 113 | } |
112 | return 0; | 114 | return 0; |
@@ -137,7 +139,7 @@ static int convert(char *fn, int ConvType) | |||
137 | 139 | ||
138 | if (fn != NULL) { | 140 | if (fn != NULL) { |
139 | if (fclose(in) < 0 || fclose(out) < 0) { | 141 | if (fclose(in) < 0 || fclose(out) < 0) { |
140 | perror_msg(NULL); | 142 | bb_perror_nomsg(); |
141 | remove(tempFn); | 143 | remove(tempFn); |
142 | return -2; | 144 | return -2; |
143 | } | 145 | } |
@@ -146,7 +148,7 @@ static int convert(char *fn, int ConvType) | |||
146 | * should be true since we put them into the same directory | 148 | * should be true since we put them into the same directory |
147 | * so we _should_ be ok, but you never know... */ | 149 | * so we _should_ be ok, but you never know... */ |
148 | if (rename(tempFn, fn) < 0) { | 150 | if (rename(tempFn, fn) < 0) { |
149 | perror_msg("unable to rename '%s' as '%s'", tempFn, fn); | 151 | bb_perror_msg("unable to rename '%s' as '%s'", tempFn, fn); |
150 | return -1; | 152 | return -1; |
151 | } | 153 | } |
152 | } | 154 | } |
@@ -177,7 +179,7 @@ int dos2unix_main(int argc, char *argv[]) | |||
177 | ConvType = CT_DOS2UNIX; | 179 | ConvType = CT_DOS2UNIX; |
178 | break; | 180 | break; |
179 | default: | 181 | default: |
180 | show_usage(); | 182 | bb_show_usage(); |
181 | } | 183 | } |
182 | } | 184 | } |
183 | 185 | ||
diff --git a/coreutils/du.c b/coreutils/du.c index 2e49b2147..702a9aa14 100644 --- a/coreutils/du.c +++ b/coreutils/du.c | |||
@@ -22,45 +22,65 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <sys/types.h> | 25 | /* BB_AUDIT SUSv3 compliant (unless default blocksize set to 1k) */ |
26 | #include <fcntl.h> | 26 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/du.html */ |
27 | #include <dirent.h> | 27 | |
28 | #include <stdio.h> | 28 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) |
29 | * | ||
30 | * Mostly rewritten for SUSv3 compliance and to fix bugs/defects. | ||
31 | * 1) Added support for SUSv3 -a, -H, -L, gnu -c, and (busybox) -d options. | ||
32 | * The -d option allows setting of max depth (similar to gnu --max-depth). | ||
33 | * 2) Fixed incorrect size calculations for links and directories, especially | ||
34 | * when errors occurred. Calculates sizes should now match gnu du output. | ||
35 | * 3) Added error checking of output. | ||
36 | * 4) Fixed busybox bug #1284 involving long overflow with human_readable. | ||
37 | */ | ||
38 | |||
29 | #include <stdlib.h> | 39 | #include <stdlib.h> |
30 | #include <getopt.h> | 40 | #include <limits.h> |
31 | #include <string.h> | 41 | #include <unistd.h> |
32 | #include <errno.h> | 42 | #include <dirent.h> |
43 | #include <sys/stat.h> | ||
33 | #include "busybox.h" | 44 | #include "busybox.h" |
34 | 45 | ||
35 | |||
36 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 46 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
47 | # ifdef CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K | ||
37 | static unsigned long disp_hr = KILOBYTE; | 48 | static unsigned long disp_hr = KILOBYTE; |
49 | # else | ||
50 | static unsigned long disp_hr = 512; | ||
51 | # endif | ||
52 | #elif defined CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K | ||
53 | static unsigned int disp_k = 1; | ||
54 | #else | ||
55 | static unsigned int disp_k; /* bss inits to 0 */ | ||
38 | #endif | 56 | #endif |
39 | 57 | ||
40 | static int du_depth /*= 0*/; | 58 | static int max_print_depth = INT_MAX; |
41 | static int count_hardlinks /*= 0*/; | 59 | static int count_hardlinks = INT_MAX; |
42 | static int one_file_system /*= 0*/; | 60 | |
61 | static int status | ||
62 | #if EXIT_SUCCESS == 0 | ||
63 | = EXIT_SUCCESS | ||
64 | #endif | ||
65 | ; | ||
66 | static int print_files; | ||
67 | static int slink_depth; | ||
68 | static int du_depth; | ||
69 | static int one_file_system; | ||
43 | static dev_t dir_dev; | 70 | static dev_t dir_dev; |
44 | 71 | ||
45 | static void (*print) (long, char *); | ||
46 | 72 | ||
47 | static void print_normal(long size, char *filename) | 73 | static void print(long size, char *filename) |
48 | { | 74 | { |
75 | /* TODO - May not want to defer error checking here. */ | ||
49 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 76 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
50 | printf("%s\t%s\n", make_human_readable_str(size << 10, 1, disp_hr), | 77 | bb_printf("%s\t%s\n", make_human_readable_str(size, 512, disp_hr), |
51 | filename); | 78 | filename); |
52 | #else | 79 | #else |
53 | printf("%ld\t%s\n", size, filename); | 80 | bb_printf("%ld\t%s\n", size >> disp_k, filename); |
54 | #endif | 81 | #endif |
55 | } | 82 | } |
56 | 83 | ||
57 | static void print_summary(long size, char *filename) | ||
58 | { | ||
59 | if (du_depth == 1) { | ||
60 | print_normal(size, filename); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | /* tiny recursive du */ | 84 | /* tiny recursive du */ |
65 | static long du(char *filename) | 85 | static long du(char *filename) |
66 | { | 86 | { |
@@ -68,23 +88,43 @@ static long du(char *filename) | |||
68 | long sum; | 88 | long sum; |
69 | 89 | ||
70 | if ((lstat(filename, &statbuf)) != 0) { | 90 | if ((lstat(filename, &statbuf)) != 0) { |
71 | perror_msg("%s", filename); | 91 | bb_perror_msg("%s", filename); |
92 | status = EXIT_FAILURE; | ||
72 | return 0; | 93 | return 0; |
73 | } | 94 | } |
74 | if (du_depth == 0) | ||
75 | dir_dev = statbuf.st_dev; | ||
76 | else if (one_file_system && dir_dev != statbuf.st_dev) | ||
77 | return 0; | ||
78 | 95 | ||
79 | du_depth++; | 96 | if (one_file_system) { |
80 | sum = (statbuf.st_blocks >> 1); | 97 | if (du_depth == 0) { |
98 | dir_dev = statbuf.st_dev; | ||
99 | } else if (dir_dev != statbuf.st_dev) { | ||
100 | return 0; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | sum = statbuf.st_blocks; | ||
81 | 105 | ||
82 | /* Don't add in stuff pointed to by symbolic links */ | ||
83 | if (S_ISLNK(statbuf.st_mode)) { | 106 | if (S_ISLNK(statbuf.st_mode)) { |
84 | sum = 0L; | 107 | if (slink_depth > du_depth) { /* -H or -L */ |
85 | if (du_depth == 1) { | 108 | if ((stat(filename, &statbuf)) != 0) { |
109 | bb_perror_msg("%s", filename); | ||
110 | status = EXIT_FAILURE; | ||
111 | return 0; | ||
112 | } | ||
113 | sum = statbuf.st_blocks; | ||
114 | if (slink_depth == 1) { | ||
115 | slink_depth = INT_MAX; /* Convert -H to -L. */ | ||
116 | } | ||
86 | } | 117 | } |
87 | } | 118 | } |
119 | |||
120 | if (statbuf.st_nlink > count_hardlinks) { | ||
121 | /* Add files/directories with links only once */ | ||
122 | if (is_in_ino_dev_hashtable(&statbuf, NULL)) { | ||
123 | return 0; | ||
124 | } | ||
125 | add_to_ino_dev_hashtable(&statbuf, NULL); | ||
126 | } | ||
127 | |||
88 | if (S_ISDIR(statbuf.st_mode)) { | 128 | if (S_ISDIR(statbuf.st_mode)) { |
89 | DIR *dir; | 129 | DIR *dir; |
90 | struct dirent *entry; | 130 | struct dirent *entry; |
@@ -92,8 +132,9 @@ static long du(char *filename) | |||
92 | 132 | ||
93 | dir = opendir(filename); | 133 | dir = opendir(filename); |
94 | if (!dir) { | 134 | if (!dir) { |
95 | du_depth--; | 135 | bb_perror_msg("%s", filename); |
96 | return 0; | 136 | status = EXIT_FAILURE; |
137 | return sum; | ||
97 | } | 138 | } |
98 | 139 | ||
99 | newfile = last_char_is(filename, '/'); | 140 | newfile = last_char_is(filename, '/'); |
@@ -103,54 +144,86 @@ static long du(char *filename) | |||
103 | while ((entry = readdir(dir))) { | 144 | while ((entry = readdir(dir))) { |
104 | char *name = entry->d_name; | 145 | char *name = entry->d_name; |
105 | 146 | ||
106 | if ((strcmp(name, "..") == 0) | 147 | if ((name[0] == '.') && (!name[1] || (name[1] == '.' && !name[2]))) { |
107 | || (strcmp(name, ".") == 0)) { | ||
108 | continue; | 148 | continue; |
109 | } | 149 | } |
110 | newfile = concat_path_file(filename, name); | 150 | newfile = concat_path_file(filename, name); |
151 | ++du_depth; | ||
111 | sum += du(newfile); | 152 | sum += du(newfile); |
153 | --du_depth; | ||
112 | free(newfile); | 154 | free(newfile); |
113 | } | 155 | } |
114 | closedir(dir); | 156 | closedir(dir); |
157 | } else if (du_depth > print_files) { | ||
158 | return sum; | ||
159 | } | ||
160 | if (du_depth <= max_print_depth) { | ||
115 | print(sum, filename); | 161 | print(sum, filename); |
116 | } else if (statbuf.st_nlink > 1 && !count_hardlinks) { | ||
117 | /* Add files with hard links only once */ | ||
118 | if (is_in_ino_dev_hashtable(&statbuf, NULL)) { | ||
119 | sum = 0L; | ||
120 | if (du_depth == 1) | ||
121 | print(sum, filename); | ||
122 | } else { | ||
123 | add_to_ino_dev_hashtable(&statbuf, NULL); | ||
124 | } | ||
125 | } | 162 | } |
126 | du_depth--; | ||
127 | return sum; | 163 | return sum; |
128 | } | 164 | } |
129 | 165 | ||
130 | int du_main(int argc, char **argv) | 166 | int du_main(int argc, char **argv) |
131 | { | 167 | { |
132 | int status = EXIT_SUCCESS; | 168 | long total; |
133 | int i; | 169 | int slink_depth_save; |
170 | int print_final_total = 0; | ||
134 | int c; | 171 | int c; |
135 | 172 | ||
136 | /* default behaviour */ | 173 | #ifdef CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K |
137 | print = print_normal; | 174 | if (getenv("POSIXLY_CORRECT")) { /* TODO - a new libbb function? */ |
175 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||
176 | disp_hr = 512; | ||
177 | #else | ||
178 | disp_k = 0; | ||
179 | #endif | ||
180 | } | ||
181 | #endif | ||
182 | |||
183 | /* Note: SUSv3 specifies that -a and -s options can not be used together | ||
184 | * in strictly conforming applications. However, it also says that some | ||
185 | * du implementations may produce output when -a and -s are used together. | ||
186 | * gnu du exits with an error code in this case. We choose to simply | ||
187 | * ignore -a. This is consistent with -s being equivalent to -d 0. | ||
188 | */ | ||
138 | 189 | ||
139 | /* parse argv[] */ | 190 | while ((c = getopt(argc, argv, "aHkLsx" "d:" "lc" |
140 | while ((c = getopt(argc, argv, "slx" | ||
141 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 191 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
142 | "hm" | 192 | "hm" |
143 | #endif | 193 | #endif |
144 | "k")) != EOF) { | 194 | )) > 0) { |
145 | switch (c) { | 195 | switch (c) { |
196 | case 'a': | ||
197 | print_files = INT_MAX; | ||
198 | break; | ||
199 | case 'H': | ||
200 | slink_depth = 1; | ||
201 | break; | ||
202 | case 'k': | ||
203 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||
204 | disp_hr = KILOBYTE; | ||
205 | #elif !defined CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K | ||
206 | disp_k = 1; | ||
207 | #endif | ||
208 | break; | ||
209 | case 'L': | ||
210 | slink_depth = INT_MAX; | ||
211 | break; | ||
146 | case 's': | 212 | case 's': |
147 | print = print_summary; | 213 | max_print_depth = 0; |
214 | break; | ||
215 | case 'x': | ||
216 | one_file_system = 1; | ||
217 | break; | ||
218 | |||
219 | case 'd': | ||
220 | max_print_depth = bb_xgetularg10_bnd(optarg, 0, INT_MAX); | ||
148 | break; | 221 | break; |
149 | case 'l': | 222 | case 'l': |
150 | count_hardlinks = 1; | 223 | count_hardlinks = 1; |
151 | break; | 224 | break; |
152 | case 'x': | 225 | case 'c': |
153 | one_file_system = 1; | 226 | print_final_total = 1; |
154 | break; | 227 | break; |
155 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 228 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
156 | case 'h': | 229 | case 'h': |
@@ -160,37 +233,31 @@ int du_main(int argc, char **argv) | |||
160 | disp_hr = MEGABYTE; | 233 | disp_hr = MEGABYTE; |
161 | break; | 234 | break; |
162 | #endif | 235 | #endif |
163 | case 'k': | ||
164 | break; | ||
165 | default: | 236 | default: |
166 | show_usage(); | 237 | bb_show_usage(); |
167 | } | 238 | } |
168 | } | 239 | } |
169 | 240 | ||
170 | /* go through remaining args (if any) */ | 241 | /* go through remaining args (if any) */ |
242 | argv += optind; | ||
171 | if (optind >= argc) { | 243 | if (optind >= argc) { |
172 | if (du(".") == 0) | 244 | *--argv = "."; |
173 | status = EXIT_FAILURE; | 245 | if (slink_depth == 1) { |
174 | } else { | 246 | slink_depth = 0; |
175 | long sum; | ||
176 | |||
177 | for (i = optind; i < argc; i++) { | ||
178 | sum = du(argv[i]); | ||
179 | if (is_directory(argv[i], FALSE, NULL) == FALSE) { | ||
180 | print_normal(sum, argv[i]); | ||
181 | } | ||
182 | reset_ino_dev_hashtable(); | ||
183 | } | 247 | } |
184 | } | 248 | } |
185 | 249 | ||
186 | return status; | 250 | slink_depth_save = slink_depth; |
187 | } | 251 | total = 0; |
252 | do { | ||
253 | total += du(*argv); | ||
254 | slink_depth = slink_depth_save; | ||
255 | } while (*++argv); | ||
256 | reset_ino_dev_hashtable(); | ||
188 | 257 | ||
189 | /* $Id: du.c,v 1.55 2002/08/23 07:28:45 aaronl Exp $ */ | 258 | if (print_final_total) { |
190 | /* | 259 | print(total, "total"); |
191 | Local Variables: | 260 | } |
192 | c-file-style: "linux" | 261 | |
193 | c-basic-offset: 4 | 262 | bb_fflush_stdout_and_exit(status); |
194 | tab-width: 4 | 263 | } |
195 | End: | ||
196 | */ | ||
diff --git a/coreutils/echo.c b/coreutils/echo.c index 31c031528..b600a1fbd 100644 --- a/coreutils/echo.c +++ b/coreutils/echo.c | |||
@@ -22,94 +22,107 @@ | |||
22 | * Original copyright notice is retained at the end of this file. | 22 | * Original copyright notice is retained at the end of this file. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | /* BB_AUDIT SUSv3 compliant -- unless configured as fancy echo. */ | ||
26 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/echo.html */ | ||
27 | |||
28 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
29 | * | ||
30 | * Because of behavioral differences, implemented configureable SUSv3 | ||
31 | * or 'fancy' gnu-ish behaviors. Also, reduced size and fixed bugs. | ||
32 | * 1) In handling '\c' escape, the previous version only suppressed the | ||
33 | * trailing newline. SUSv3 specifies _no_ output after '\c'. | ||
34 | * 2) SUSv3 specifies that octal escapes are of the form \0{#{#{#}}}. | ||
35 | * The previous version version did not allow 4-digit octals. | ||
36 | */ | ||
37 | |||
25 | #include <stdio.h> | 38 | #include <stdio.h> |
26 | #include <string.h> | 39 | #include <string.h> |
27 | #include <stdlib.h> | 40 | #include <stdlib.h> |
28 | #include "busybox.h" | 41 | #include "busybox.h" |
29 | 42 | ||
30 | extern int | 43 | extern int echo_main(int argc, char** argv) |
31 | echo_main(int argc, char** argv) | ||
32 | { | 44 | { |
33 | int nflag = 0; | 45 | #ifndef CONFIG_FEATURE_FANCY_ECHO |
46 | #define eflag '\\' | ||
47 | ++argv; | ||
48 | #else | ||
49 | const char *p; | ||
50 | int nflag = 1; | ||
34 | int eflag = 0; | 51 | int eflag = 0; |
35 | 52 | ||
36 | /* Skip argv[0]. */ | 53 | while (*++argv && (**argv == '-')) { |
37 | argc--; | 54 | /* If it appears that we are handling options, then make sure |
38 | argv++; | ||
39 | |||
40 | while (argc > 0 && *argv[0] == '-') | ||
41 | { | ||
42 | register char *temp; | ||
43 | register int ix; | ||
44 | |||
45 | /* | ||
46 | * If it appears that we are handling options, then make sure | ||
47 | * that all of the options specified are actually valid. | 55 | * that all of the options specified are actually valid. |
48 | * Otherwise, the string should just be echoed. | 56 | * Otherwise, the string should just be echoed. |
49 | */ | 57 | */ |
50 | temp = argv[0] + 1; | 58 | |
51 | 59 | if (!*(p = *argv + 1)) { /* A single '-', so echo it. */ | |
52 | for (ix = 0; temp[ix]; ix++) | ||
53 | { | ||
54 | if (strrchr("neE", temp[ix]) == 0) | ||
55 | goto just_echo; | ||
56 | } | ||
57 | |||
58 | if (!*temp) | ||
59 | goto just_echo; | 60 | goto just_echo; |
61 | } | ||
60 | 62 | ||
61 | /* | 63 | do { |
62 | * All of the options in temp are valid options to echo. | 64 | if (strrchr("neE", *p) == 0) { |
63 | * Handle them. | ||
64 | */ | ||
65 | while (*temp) | ||
66 | { | ||
67 | if (*temp == 'n') | ||
68 | nflag = 1; | ||
69 | else if (*temp == 'e') | ||
70 | eflag = 1; | ||
71 | else if (*temp == 'E') | ||
72 | eflag = 0; | ||
73 | else | ||
74 | goto just_echo; | 65 | goto just_echo; |
66 | } | ||
67 | } while (*++p); | ||
75 | 68 | ||
76 | temp++; | 69 | /* All of the options in this arg are valid, so handle them. */ |
77 | } | 70 | p = *argv + 1; |
78 | argc--; | 71 | do { |
79 | argv++; | 72 | if (*p == 'n') { |
73 | nflag = 0; | ||
74 | } else if (*p == 'e') { | ||
75 | eflag = '\\'; | ||
76 | } else { | ||
77 | eflag = 0; | ||
78 | } | ||
79 | } while (*++p); | ||
80 | } | 80 | } |
81 | 81 | ||
82 | just_echo: | 82 | just_echo: |
83 | while (argc > 0) { | 83 | #endif |
84 | const char *arg = argv[0]; | 84 | while (*argv) { |
85 | register int c; | 85 | register int c; |
86 | 86 | ||
87 | while ((c = *arg++)) { | 87 | while ((c = *(*argv)++)) { |
88 | 88 | if (c == eflag) { /* Check for escape seq. */ | |
89 | /* Check for escape sequence. */ | 89 | if (**argv == 'c') { |
90 | if (c == '\\' && eflag && *arg) { | 90 | /* '\c' means cancel newline and |
91 | if (*arg == 'c') { | 91 | * ignore all subsequent chars. */ |
92 | /* '\c' means cancel newline. */ | 92 | goto DONE; |
93 | nflag = 1; | 93 | } |
94 | arg++; | 94 | #ifndef CONFIG_FEATURE_FANCY_ECHO |
95 | continue; | 95 | /* SUSv3 specifies that octal escapes must begin with '0'. */ |
96 | } else { | 96 | if (((unsigned int)(**argv - '1')) >= 7) |
97 | c = process_escape_sequence(&arg); | 97 | #endif |
98 | { | ||
99 | /* Since SUSv3 mandates a first digit of 0, 4-digit octals | ||
100 | * of the form \0### are accepted. */ | ||
101 | if ((**argv == '0') && (((unsigned int)(argv[0][1] - '0')) < 8)) { | ||
102 | (*argv)++; | ||
103 | } | ||
104 | /* bb_process_escape_sequence can handle nul correctly */ | ||
105 | c = bb_process_escape_sequence((const char **) argv); | ||
98 | } | 106 | } |
99 | } | 107 | } |
100 | |||
101 | putchar(c); | 108 | putchar(c); |
102 | } | 109 | } |
103 | argc--; | 110 | |
104 | argv++; | 111 | if (*++argv) { |
105 | if (argc > 0) | ||
106 | putchar(' '); | 112 | putchar(' '); |
113 | } | ||
107 | } | 114 | } |
108 | if (!nflag) | 115 | |
116 | #ifdef CONFIG_FEATURE_FANCY_ECHO | ||
117 | if (nflag) { | ||
109 | putchar('\n'); | 118 | putchar('\n'); |
110 | fflush(stdout); | 119 | } |
120 | #else | ||
121 | putchar('\n'); | ||
122 | #endif | ||
111 | 123 | ||
112 | return EXIT_SUCCESS; | 124 | DONE: |
125 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); | ||
113 | } | 126 | } |
114 | 127 | ||
115 | /*- | 128 | /*- |
diff --git a/coreutils/env.c b/coreutils/env.c index 8bb690b72..db13b3aed 100644 --- a/coreutils/env.c +++ b/coreutils/env.c | |||
@@ -24,50 +24,66 @@ | |||
24 | * Modified for BusyBox by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> | 24 | * Modified for BusyBox by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> |
25 | */ | 25 | */ |
26 | 26 | ||
27 | /* BB_AUDIT SUSv3 compliant */ | ||
28 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/env.html */ | ||
29 | |||
30 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
31 | * | ||
32 | * Fixed bug involving exit return codes if execvp fails. Also added | ||
33 | * output error checking. | ||
34 | */ | ||
35 | |||
27 | #include <stdio.h> | 36 | #include <stdio.h> |
28 | #include <string.h> | 37 | #include <string.h> |
29 | #include <getopt.h> | ||
30 | #include <stdlib.h> | 38 | #include <stdlib.h> |
39 | #include <errno.h> | ||
31 | #include <unistd.h> | 40 | #include <unistd.h> |
32 | #include "busybox.h" | 41 | #include "busybox.h" |
33 | 42 | ||
34 | extern int env_main(int argc, char** argv) | 43 | extern int env_main(int argc, char** argv) |
35 | { | 44 | { |
36 | char **ep, *p; | 45 | char **ep, *p; |
37 | char *cleanenv[1]; | 46 | char *cleanenv[1] = { NULL }; |
38 | int ignore_environment = 0; | ||
39 | int ch; | 47 | int ch; |
40 | 48 | ||
41 | while ((ch = getopt(argc, argv, "+iu:")) != -1) { | 49 | while ((ch = getopt(argc, argv, "iu:")) > 0) { |
42 | switch(ch) { | 50 | switch(ch) { |
43 | case 'i': | 51 | case 'i': |
44 | ignore_environment = 1; | 52 | environ = cleanenv; |
45 | break; | 53 | break; |
46 | case 'u': | 54 | case 'u': |
47 | unsetenv(optarg); | 55 | unsetenv(optarg); |
48 | break; | 56 | break; |
49 | default: | 57 | default: |
50 | show_usage(); | 58 | bb_show_usage(); |
51 | } | 59 | } |
52 | } | 60 | } |
53 | if (optind != argc && !strcmp(argv[optind], "-")) { | 61 | |
54 | ignore_environment = 1; | 62 | argv += optind; |
55 | argv++; | 63 | |
56 | } | 64 | if (*argv && (argv[0][0] == '-') && !argv[0][1]) { |
57 | if (ignore_environment) { | ||
58 | environ = cleanenv; | 65 | environ = cleanenv; |
59 | cleanenv[0] = NULL; | 66 | ++argv; |
60 | } | 67 | } |
61 | for (argv += optind; *argv && (p = strchr(*argv, '=')); ++argv) | 68 | |
62 | if (putenv(*argv) < 0) | 69 | while (*argv && ((p = strchr(*argv, '=')) != NULL)) { |
63 | perror_msg_and_die("%s", *argv); | 70 | if (putenv(*argv) < 0) { |
71 | bb_perror_msg_and_die("putenv"); | ||
72 | } | ||
73 | ++argv; | ||
74 | } | ||
75 | |||
64 | if (*argv) { | 76 | if (*argv) { |
65 | execvp(*argv, argv); | 77 | execvp(*argv, argv); |
66 | perror_msg_and_die("%s", *argv); | 78 | bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ |
79 | return (errno == ENOENT) ? 127 : 126; /* SUSv3-mandated exit codes. */ | ||
67 | } | 80 | } |
68 | for (ep = environ; *ep; ep++) | 81 | |
82 | for (ep = environ; *ep; ep++) { | ||
69 | puts(*ep); | 83 | puts(*ep); |
70 | return 0; | 84 | } |
85 | |||
86 | bb_fflush_stdout_and_exit(0); | ||
71 | } | 87 | } |
72 | 88 | ||
73 | /* | 89 | /* |
diff --git a/coreutils/expr.c b/coreutils/expr.c index 55ae3a969..ecba825d5 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c | |||
@@ -78,14 +78,14 @@ int expr_main (int argc, char **argv) | |||
78 | VALUE *v; | 78 | VALUE *v; |
79 | 79 | ||
80 | if (argc == 1) { | 80 | if (argc == 1) { |
81 | error_msg_and_die("too few arguments"); | 81 | bb_error_msg_and_die("too few arguments"); |
82 | } | 82 | } |
83 | 83 | ||
84 | args = argv + 1; | 84 | args = argv + 1; |
85 | 85 | ||
86 | v = eval (); | 86 | v = eval (); |
87 | if (*args) | 87 | if (*args) |
88 | error_msg_and_die ("syntax error"); | 88 | bb_error_msg_and_die ("syntax error"); |
89 | 89 | ||
90 | if (v->type == integer) | 90 | if (v->type == integer) |
91 | printf ("%d\n", v->u.i); | 91 | printf ("%d\n", v->u.i); |
@@ -147,7 +147,7 @@ static int null (VALUE *v) | |||
147 | static void tostring (VALUE *v) | 147 | static void tostring (VALUE *v) |
148 | { | 148 | { |
149 | if (v->type == integer) { | 149 | if (v->type == integer) { |
150 | bb_asprintf (&(v->u.s), "%d", v->u.i); | 150 | bb_xasprintf (&(v->u.s), "%d", v->u.i); |
151 | v->type = string; | 151 | v->type = string; |
152 | } | 152 | } |
153 | } | 153 | } |
@@ -216,7 +216,7 @@ static \ | |||
216 | int name (VALUE *l, VALUE *r) \ | 216 | int name (VALUE *l, VALUE *r) \ |
217 | { \ | 217 | { \ |
218 | if (!toarith (l) || !toarith (r)) \ | 218 | if (!toarith (l) || !toarith (r)) \ |
219 | error_msg_and_die ("non-numeric argument"); \ | 219 | bb_error_msg_and_die ("non-numeric argument"); \ |
220 | return l->u.i op r->u.i; \ | 220 | return l->u.i op r->u.i; \ |
221 | } | 221 | } |
222 | 222 | ||
@@ -224,9 +224,9 @@ int name (VALUE *l, VALUE *r) \ | |||
224 | static int name (VALUE *l, VALUE *r) \ | 224 | static int name (VALUE *l, VALUE *r) \ |
225 | { \ | 225 | { \ |
226 | if (!toarith (l) || !toarith (r)) \ | 226 | if (!toarith (l) || !toarith (r)) \ |
227 | error_msg_and_die ( "non-numeric argument"); \ | 227 | bb_error_msg_and_die ( "non-numeric argument"); \ |
228 | if (r->u.i == 0) \ | 228 | if (r->u.i == 0) \ |
229 | error_msg_and_die ( "division by zero"); \ | 229 | bb_error_msg_and_die ( "division by zero"); \ |
230 | return l->u.i op r->u.i; \ | 230 | return l->u.i op r->u.i; \ |
231 | } | 231 | } |
232 | 232 | ||
@@ -270,7 +270,7 @@ of a basic regular expression is not portable; it is being ignored", | |||
270 | re_syntax_options = RE_SYNTAX_POSIX_BASIC; | 270 | re_syntax_options = RE_SYNTAX_POSIX_BASIC; |
271 | errmsg = re_compile_pattern (pv->u.s, len, &re_buffer); | 271 | errmsg = re_compile_pattern (pv->u.s, len, &re_buffer); |
272 | if (errmsg) { | 272 | if (errmsg) { |
273 | error_msg_and_die("%s", errmsg); | 273 | bb_error_msg_and_die("%s", errmsg); |
274 | } | 274 | } |
275 | 275 | ||
276 | len = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs); | 276 | len = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs); |
@@ -301,19 +301,19 @@ static VALUE *eval7 (void) | |||
301 | VALUE *v; | 301 | VALUE *v; |
302 | 302 | ||
303 | if (!*args) | 303 | if (!*args) |
304 | error_msg_and_die ( "syntax error"); | 304 | bb_error_msg_and_die ( "syntax error"); |
305 | 305 | ||
306 | if (nextarg ("(")) { | 306 | if (nextarg ("(")) { |
307 | args++; | 307 | args++; |
308 | v = eval (); | 308 | v = eval (); |
309 | if (!nextarg (")")) | 309 | if (!nextarg (")")) |
310 | error_msg_and_die ( "syntax error"); | 310 | bb_error_msg_and_die ( "syntax error"); |
311 | args++; | 311 | args++; |
312 | return v; | 312 | return v; |
313 | } | 313 | } |
314 | 314 | ||
315 | if (nextarg (")")) | 315 | if (nextarg (")")) |
316 | error_msg_and_die ( "syntax error"); | 316 | bb_error_msg_and_die ( "syntax error"); |
317 | 317 | ||
318 | return str_value (*args++); | 318 | return str_value (*args++); |
319 | } | 319 | } |
@@ -327,7 +327,7 @@ static VALUE *eval6 (void) | |||
327 | if (nextarg ("quote")) { | 327 | if (nextarg ("quote")) { |
328 | args++; | 328 | args++; |
329 | if (!*args) | 329 | if (!*args) |
330 | error_msg_and_die ( "syntax error"); | 330 | bb_error_msg_and_die ( "syntax error"); |
331 | return str_value (*args++); | 331 | return str_value (*args++); |
332 | } | 332 | } |
333 | else if (nextarg ("length")) { | 333 | else if (nextarg ("length")) { |
@@ -373,7 +373,7 @@ static VALUE *eval6 (void) | |||
373 | else { | 373 | else { |
374 | v = xmalloc (sizeof(VALUE)); | 374 | v = xmalloc (sizeof(VALUE)); |
375 | v->type = string; | 375 | v->type = string; |
376 | v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i); | 376 | v->u.s = bb_xstrndup(l->u.s + i1->u.i - 1, i2->u.i); |
377 | } | 377 | } |
378 | freev (l); | 378 | freev (l); |
379 | freev (i1); | 379 | freev (i1); |
diff --git a/coreutils/false.c b/coreutils/false.c index 96b18498a..c17de7693 100644 --- a/coreutils/false.c +++ b/coreutils/false.c | |||
@@ -21,7 +21,8 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* getopt not needed */ | 24 | /* BB_AUDIT SUSv3 compliant */ |
25 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/false.html */ | ||
25 | 26 | ||
26 | #include <stdlib.h> | 27 | #include <stdlib.h> |
27 | #include "busybox.h" | 28 | #include "busybox.h" |
diff --git a/coreutils/head.c b/coreutils/head.c index ad21e1b95..dab4de11b 100644 --- a/coreutils/head.c +++ b/coreutils/head.c | |||
@@ -1,9 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini head implementation for busybox | 3 | * head implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1999 by Lineo, inc. and John Beppu | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org> | ||
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -21,82 +20,119 @@ | |||
21 | * | 20 | * |
22 | */ | 21 | */ |
23 | 22 | ||
23 | /* BB_AUDIT SUSv3 compliant */ | ||
24 | /* BB_AUDIT GNU compatible -c, -q, and -v options in 'fancy' configuration. */ | ||
25 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/head.html */ | ||
26 | |||
24 | #include <stdio.h> | 27 | #include <stdio.h> |
25 | #include <getopt.h> | ||
26 | #include <stdlib.h> | 28 | #include <stdlib.h> |
27 | #include <string.h> | 29 | #include <limits.h> |
28 | #include <ctype.h> | 30 | #include <ctype.h> |
31 | #include <unistd.h> | ||
29 | #include "busybox.h" | 32 | #include "busybox.h" |
30 | 33 | ||
31 | static int head(int len, FILE *fp) | 34 | static const char head_opts[] = |
32 | { | 35 | "n:" |
33 | int i; | 36 | #ifdef CONFIG_FEATURE_FANCY_HEAD |
34 | char *input; | 37 | "c:qv" |
38 | #endif | ||
39 | ; | ||
35 | 40 | ||
36 | for (i = 0; i < len; i++) { | 41 | static const char header_fmt_str[] = "\n==> %s <==\n"; |
37 | if ((input = get_line_from_file(fp)) == NULL) | ||
38 | break; | ||
39 | fputs(input, stdout); | ||
40 | free(input); | ||
41 | } | ||
42 | return 0; | ||
43 | } | ||
44 | 42 | ||
45 | /* BusyBoxed head(1) */ | ||
46 | int head_main(int argc, char **argv) | 43 | int head_main(int argc, char **argv) |
47 | { | 44 | { |
45 | unsigned long count = 10; | ||
46 | unsigned long i; | ||
47 | #ifdef CONFIG_FEATURE_FANCY_HEAD | ||
48 | int count_bytes = 0; | ||
49 | int header_threshhold = 1; | ||
50 | #endif | ||
51 | |||
48 | FILE *fp; | 52 | FILE *fp; |
49 | int need_headers, opt, len = 10, status = EXIT_SUCCESS; | 53 | const char *fmt; |
54 | char *p; | ||
55 | int opt; | ||
56 | int c; | ||
57 | int retval = EXIT_SUCCESS; | ||
50 | 58 | ||
51 | if (( argc >= 2 ) && ( argv [1][0] == '-' ) && isdigit ( argv [1][1] )) { | 59 | /* Allow legacy syntax of an initial numeric option without -n. */ |
52 | len = atoi ( &argv [1][1] ); | 60 | if ((argc > 1) && (argv[1][0] == '-') |
53 | optind = 2; | 61 | /* && (isdigit)(argv[1][1]) */ |
62 | && (((unsigned int)(argv[1][1] - '0')) <= 9) | ||
63 | ) { | ||
64 | --argc; | ||
65 | ++argv; | ||
66 | p = (*argv) + 1; | ||
67 | goto GET_COUNT; | ||
54 | } | 68 | } |
55 | 69 | ||
56 | /* parse argv[] */ | 70 | while ((opt = getopt(argc, argv, head_opts)) > 0) { |
57 | while ((opt = getopt(argc, argv, "n:")) > 0) { | 71 | switch(opt) { |
58 | switch (opt) { | 72 | #ifdef CONFIG_FEATURE_FANCY_HEAD |
59 | case 'n': | 73 | case 'q': |
60 | len = atoi(optarg); | 74 | header_threshhold = INT_MAX; |
61 | if (len >= 0) | 75 | break; |
76 | case 'v': | ||
77 | header_threshhold = -1; | ||
62 | break; | 78 | break; |
63 | /* fallthrough */ | 79 | case 'c': |
64 | default: | 80 | count_bytes = 1; |
65 | show_usage(); | 81 | /* fall through */ |
82 | #endif | ||
83 | case 'n': | ||
84 | p = optarg; | ||
85 | GET_COUNT: | ||
86 | count = bb_xgetularg10(p); | ||
87 | break; | ||
88 | default: | ||
89 | bb_show_usage(); | ||
66 | } | 90 | } |
67 | } | 91 | } |
68 | 92 | ||
69 | /* get rest of argv[] or stdin if nothing's left */ | 93 | argv += optind; |
70 | if (argv[optind] == NULL) { | 94 | if (!*argv) { |
71 | head(len, stdin); | 95 | *--argv = "-"; |
72 | return status; | 96 | } |
73 | } | ||
74 | 97 | ||
75 | need_headers = optind != (argc - 1); | 98 | fmt = header_fmt_str + 1; |
76 | while (argv[optind]) { | 99 | #ifdef CONFIG_FEATURE_FANCY_HEAD |
77 | if (strcmp(argv[optind], "-") == 0) { | 100 | if (argc - optind <= header_threshhold) { |
78 | fp = stdin; | 101 | header_threshhold = 0; |
79 | argv[optind] = "standard input"; | 102 | } |
80 | } else { | 103 | #else |
81 | if ((fp = wfopen(argv[optind], "r")) == NULL) | 104 | if (argc <= optind + 1) { |
82 | status = EXIT_FAILURE; | 105 | fmt += 11; |
83 | } | 106 | } |
84 | if (fp) { | 107 | /* Now define some things here to avoid #ifdefs in the code below. |
85 | if (need_headers) { | 108 | * These should optimize out of the if conditions below. */ |
86 | printf("==> %s <==\n", argv[optind]); | 109 | #define header_threshhold 1 |
110 | #define count_bytes 0 | ||
111 | #endif | ||
112 | |||
113 | do { | ||
114 | if ((fp = bb_wfopen_input(*argv)) != NULL) { | ||
115 | if (fp == stdin) { | ||
116 | *argv = (char *) bb_msg_standard_input; | ||
87 | } | 117 | } |
88 | head(len, fp); | 118 | if (header_threshhold) { |
89 | if (ferror(fp)) { | 119 | bb_printf(fmt, *argv); |
90 | perror_msg("%s", argv[optind]); | ||
91 | status = EXIT_FAILURE; | ||
92 | } | 120 | } |
93 | if (optind < argc - 1) | 121 | i = count; |
94 | putchar('\n'); | 122 | while (i && ((c = getc(fp)) != EOF)) { |
95 | if (fp != stdin) | 123 | if (count_bytes || (c == '\n')) { |
96 | fclose(fp); | 124 | --i; |
125 | } | ||
126 | putchar(c); | ||
127 | } | ||
128 | if (bb_fclose_nonstdin(fp)) { | ||
129 | bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ | ||
130 | retval = EXIT_FAILURE; | ||
131 | } | ||
132 | bb_xferror_stdout(); | ||
97 | } | 133 | } |
98 | optind++; | 134 | fmt = header_fmt_str; |
99 | } | 135 | } while (*++argv); |
100 | 136 | ||
101 | return status; | 137 | bb_fflush_stdout_and_exit(retval); |
102 | } | 138 | } |
diff --git a/coreutils/hostid.c b/coreutils/hostid.c index 68a2cc659..917dc223e 100644 --- a/coreutils/hostid.c +++ b/coreutils/hostid.c | |||
@@ -20,13 +20,19 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <stdio.h> | 23 | /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ |
24 | |||
24 | #include <stdlib.h> | 25 | #include <stdlib.h> |
25 | #include <unistd.h> | 26 | #include <unistd.h> |
26 | #include "busybox.h" | 27 | #include "busybox.h" |
27 | 28 | ||
28 | extern int hostid_main(int argc, char **argv) | 29 | extern int hostid_main(int argc, char **argv) |
29 | { | 30 | { |
30 | printf("%lx\n", gethostid()); | 31 | if (argc > 1) { |
31 | return EXIT_SUCCESS; | 32 | bb_show_usage(); |
33 | } | ||
34 | |||
35 | bb_printf("%lx\n", gethostid()); | ||
36 | |||
37 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); | ||
32 | } | 38 | } |
diff --git a/coreutils/id.c b/coreutils/id.c index c7f61532d..9b2d60dc7 100644 --- a/coreutils/id.c +++ b/coreutils/id.c | |||
@@ -20,6 +20,8 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */ | ||
24 | |||
23 | #include "busybox.h" | 25 | #include "busybox.h" |
24 | #include <stdio.h> | 26 | #include <stdio.h> |
25 | #include <unistd.h> | 27 | #include <unistd.h> |
@@ -27,70 +29,58 @@ | |||
27 | #include <string.h> | 29 | #include <string.h> |
28 | #include <sys/types.h> | 30 | #include <sys/types.h> |
29 | 31 | ||
32 | #define NO_GROUP 1 | ||
33 | #define NO_USER 2 | ||
34 | #define PRINT_REAL 4 | ||
35 | #define NAME_NOT_NUMBER 8 | ||
36 | |||
30 | extern int id_main(int argc, char **argv) | 37 | extern int id_main(int argc, char **argv) |
31 | { | 38 | { |
32 | int no_user = 0, no_group = 0, print_real = 0; | ||
33 | int name_not_number = 0; | ||
34 | char user[9], group[9]; | 39 | char user[9], group[9]; |
35 | long gid; | ||
36 | long pwnam, grnam; | 40 | long pwnam, grnam; |
37 | int opt; | 41 | int uid, gid; |
42 | int flags; | ||
38 | 43 | ||
39 | gid = 0; | 44 | flags = bb_getopt_ulflags(argc, argv, "ugrn"); |
40 | 45 | ||
41 | while ((opt = getopt(argc, argv, "ugrn")) > 0) { | 46 | if (((flags & (NO_USER | NO_GROUP)) == (NO_USER | NO_GROUP)) |
42 | switch (opt) { | 47 | || (argc > optind + 1) |
43 | case 'u': | 48 | ) { |
44 | no_group++; | 49 | bb_show_usage(); |
45 | break; | ||
46 | case 'g': | ||
47 | no_user++; | ||
48 | break; | ||
49 | case 'r': | ||
50 | print_real++; | ||
51 | break; | ||
52 | case 'n': | ||
53 | name_not_number++; | ||
54 | break; | ||
55 | default: | ||
56 | show_usage(); | ||
57 | } | ||
58 | } | 50 | } |
59 | 51 | ||
60 | if (no_user && no_group) show_usage(); | ||
61 | |||
62 | if (argv[optind] == NULL) { | 52 | if (argv[optind] == NULL) { |
63 | if (print_real) { | 53 | if (flags & PRINT_REAL) { |
64 | my_getpwuid(user, getuid()); | 54 | uid = getuid(); |
65 | my_getgrgid(group, getgid()); | 55 | gid = getgid(); |
66 | } else { | 56 | } else { |
67 | my_getpwuid(user, geteuid()); | 57 | uid = geteuid(); |
68 | my_getgrgid(group, getegid()); | 58 | gid = getegid(); |
69 | } | 59 | } |
60 | my_getpwuid(user, uid); | ||
70 | } else { | 61 | } else { |
71 | safe_strncpy(user, argv[optind], sizeof(user)); | 62 | safe_strncpy(user, argv[optind], sizeof(user)); |
72 | gid = my_getpwnamegid(user); | 63 | gid = my_getpwnamegid(user); |
73 | my_getgrgid(group, gid); | ||
74 | } | 64 | } |
65 | my_getgrgid(group, gid); | ||
75 | 66 | ||
76 | pwnam=my_getpwnam(user); | 67 | pwnam=my_getpwnam(user); |
77 | grnam=my_getgrnam(group); | 68 | grnam=my_getgrnam(group); |
78 | 69 | ||
79 | if (no_group) { | 70 | if (flags & (NO_GROUP | NO_USER)) { |
80 | if(name_not_number) | 71 | char *s = group; |
81 | puts(user); | 72 | if (flags & NO_GROUP) { |
82 | else | 73 | s = user; |
83 | printf("%ld\n", pwnam); | 74 | grnam = pwnam; |
84 | } else if (no_user) { | 75 | } |
85 | if(name_not_number) | 76 | if (flags & NAME_NOT_NUMBER) { |
86 | puts(group); | 77 | puts(s); |
87 | else | 78 | } else { |
88 | printf("%ld\n", grnam); | 79 | printf("%ld\n", grnam); |
80 | } | ||
89 | } else { | 81 | } else { |
90 | printf("uid=%ld(%s) gid=%ld(%s)\n", pwnam, user, grnam, group); | 82 | printf("uid=%ld(%s) gid=%ld(%s)\n", pwnam, user, grnam, group); |
91 | } | 83 | } |
92 | return(0); | ||
93 | } | ||
94 | 84 | ||
95 | 85 | bb_fflush_stdout_and_exit(0); | |
96 | /* END CODE */ | 86 | } |
diff --git a/coreutils/length.c b/coreutils/length.c index 73becd28a..bce43ab3f 100644 --- a/coreutils/length.c +++ b/coreutils/length.c | |||
@@ -1,4 +1,7 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | |||
3 | /* BB_AUDIT SUSv3 N/A -- Apparently a busybox (obsolete?) extension. */ | ||
4 | |||
2 | #include <stdlib.h> | 5 | #include <stdlib.h> |
3 | #include <string.h> | 6 | #include <string.h> |
4 | #include <stdio.h> | 7 | #include <stdio.h> |
@@ -6,8 +9,11 @@ | |||
6 | 9 | ||
7 | extern int length_main(int argc, char **argv) | 10 | extern int length_main(int argc, char **argv) |
8 | { | 11 | { |
9 | if (argc != 2 || **(argv + 1) == '-') | 12 | if ((argc != 2) || (**(++argv) == '-')) { |
10 | show_usage(); | 13 | bb_show_usage(); |
11 | printf("%lu\n", (long)strlen(argv[1])); | 14 | } |
12 | return EXIT_SUCCESS; | 15 | |
16 | bb_printf("%lu\n", (unsigned long)strlen(*argv)); | ||
17 | |||
18 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); | ||
13 | } | 19 | } |
diff --git a/coreutils/libcoreutils/Makefile b/coreutils/libcoreutils/Makefile new file mode 100644 index 000000000..59ec24ed9 --- /dev/null +++ b/coreutils/libcoreutils/Makefile | |||
@@ -0,0 +1,30 @@ | |||
1 | # Makefile for busybox | ||
2 | # | ||
3 | # Copyright (C) 1999-2002 Erik Andersen <andersee@debian.org> | ||
4 | # | ||
5 | # This program is free software; you can redistribute it and/or modify | ||
6 | # it under the terms of the GNU General Public License as published by | ||
7 | # the Free Software Foundation; either version 2 of the License, or | ||
8 | # (at your option) any later version. | ||
9 | # | ||
10 | # This program is distributed in the hope that it will be useful, | ||
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | # General Public License for more details. | ||
14 | # | ||
15 | # You should have received a copy of the GNU General Public License | ||
16 | # along with this program; if not, write to the Free Software | ||
17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | # | ||
19 | |||
20 | TOPDIR:= ../../ | ||
21 | LIBCOREUTILS_DIR:=./ | ||
22 | include $(TOPDIR).config | ||
23 | include $(TOPDIR)Rules.mak | ||
24 | include Makefile.in | ||
25 | all: $(libraries-y) | ||
26 | -include $(TOPDIR).depend | ||
27 | |||
28 | clean: | ||
29 | rm -f *.o *.a $(AR_TARGET) | ||
30 | |||
diff --git a/coreutils/libcoreutils/Makefile.in b/coreutils/libcoreutils/Makefile.in new file mode 100644 index 000000000..47391dd49 --- /dev/null +++ b/coreutils/libcoreutils/Makefile.in | |||
@@ -0,0 +1,32 @@ | |||
1 | # Makefile for busybox | ||
2 | # | ||
3 | # Copyright (C) 1999-2002 Erik Andersen <andersee@debian.org> | ||
4 | # | ||
5 | # This program is free software; you can redistribute it and/or modify | ||
6 | # it under the terms of the GNU General Public License as published by | ||
7 | # the Free Software Foundation; either version 2 of the License, or | ||
8 | # (at your option) any later version. | ||
9 | # | ||
10 | # This program is distributed in the hope that it will be useful, | ||
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | # General Public License for more details. | ||
14 | # | ||
15 | # You should have received a copy of the GNU General Public License | ||
16 | # along with this program; if not, write to the Free Software | ||
17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | # | ||
19 | |||
20 | LIBCOREUTILS_AR:=libcoreutils.a | ||
21 | ifndef $(LIBCOREUTILS_DIR) | ||
22 | LIBCOREUTILS_DIR:=$(TOPDIR)coreutils/libcoreutils/ | ||
23 | endif | ||
24 | |||
25 | LIBCOREUTILS_SRC:= cp_mv_stat.c getopt_mk_fifo_nod.c xgetoptfile_sort_uniq.c | ||
26 | |||
27 | LIBCOREUTILS_OBJS=$(patsubst %.c,$(LIBCOREUTILS_DIR)%.o, $(LIBCOREUTILS_SRC)) | ||
28 | |||
29 | libraries-y+=$(LIBCOREUTILS_DIR)$(LIBCOREUTILS_AR) | ||
30 | |||
31 | $(LIBCOREUTILS_DIR)$(LIBCOREUTILS_AR): $(LIBCOREUTILS_OBJS) | ||
32 | $(AR) -ro $@ $(LIBCOREUTILS_OBJS) | ||
diff --git a/coreutils/libcoreutils/coreutils.h b/coreutils/libcoreutils/coreutils.h new file mode 100644 index 000000000..eabca8204 --- /dev/null +++ b/coreutils/libcoreutils/coreutils.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef COREUTILS_H | ||
2 | #define COREUTILS_H 1 | ||
3 | |||
4 | typedef int (*stat_func)(const char *fn, struct stat *ps); | ||
5 | |||
6 | extern int cp_mv_stat2(const char *fn, struct stat *fn_stat, stat_func sf); | ||
7 | extern int cp_mv_stat(const char *fn, struct stat *fn_stat); | ||
8 | |||
9 | extern mode_t getopt_mk_fifo_nod(int argc, char **argv); | ||
10 | extern FILE *xgetoptfile_sort_uniq(char **argv, const char *mode); | ||
11 | |||
12 | #endif | ||
diff --git a/coreutils/libcoreutils/cp_mv_stat.c b/coreutils/libcoreutils/cp_mv_stat.c new file mode 100644 index 000000000..5a70b0221 --- /dev/null +++ b/coreutils/libcoreutils/cp_mv_stat.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * coreutils utility routine | ||
4 | * | ||
5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <errno.h> | ||
24 | #include <sys/stat.h> | ||
25 | #include "libbb.h" | ||
26 | #include "coreutils.h" | ||
27 | |||
28 | extern int cp_mv_stat2(const char *fn, struct stat *fn_stat, stat_func sf) | ||
29 | { | ||
30 | if (sf(fn, fn_stat) < 0) { | ||
31 | if (errno != ENOENT) { | ||
32 | bb_perror_msg("unable to stat `%s'", fn); | ||
33 | return -1; | ||
34 | } | ||
35 | return 0; | ||
36 | } else if (S_ISDIR(fn_stat->st_mode)) { | ||
37 | return 3; | ||
38 | } | ||
39 | return 1; | ||
40 | } | ||
41 | |||
42 | extern int cp_mv_stat(const char *fn, struct stat *fn_stat) | ||
43 | { | ||
44 | return cp_mv_stat2(fn, fn_stat, stat); | ||
45 | } | ||
diff --git a/coreutils/libcoreutils/getopt_mk_fifo_nod.c b/coreutils/libcoreutils/getopt_mk_fifo_nod.c new file mode 100644 index 000000000..0872bdcf0 --- /dev/null +++ b/coreutils/libcoreutils/getopt_mk_fifo_nod.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * coreutils utility routine | ||
4 | * | ||
5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <sys/types.h> | ||
24 | #include <sys/stat.h> | ||
25 | #include <unistd.h> | ||
26 | #include "libbb.h" | ||
27 | #include "coreutils.h" | ||
28 | |||
29 | extern mode_t getopt_mk_fifo_nod(int argc, char **argv) | ||
30 | { | ||
31 | mode_t mode = 0666; | ||
32 | int opt; | ||
33 | |||
34 | while ((opt = getopt(argc, argv, "m:")) > 0) { | ||
35 | if (opt == 'm') { | ||
36 | mode = 0666; | ||
37 | if (bb_parse_mode(optarg, &mode)) { | ||
38 | umask(0); | ||
39 | continue; | ||
40 | } | ||
41 | } | ||
42 | bb_show_usage(); | ||
43 | } | ||
44 | return mode; | ||
45 | } | ||
diff --git a/coreutils/libcoreutils/xgetoptfile_sort_uniq.c b/coreutils/libcoreutils/xgetoptfile_sort_uniq.c new file mode 100644 index 000000000..a63daf97b --- /dev/null +++ b/coreutils/libcoreutils/xgetoptfile_sort_uniq.c | |||
@@ -0,0 +1,38 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * coreutils utility routine | ||
4 | * | ||
5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <unistd.h> | ||
25 | #include "libbb.h" | ||
26 | #include "coreutils.h" | ||
27 | |||
28 | extern FILE *xgetoptfile_sort_uniq(char **argv, const char *mode) | ||
29 | { | ||
30 | const char *n; | ||
31 | |||
32 | if ((n = *argv) != NULL) { | ||
33 | if ((*n != '-') || n[1]) { | ||
34 | return bb_xfopen(n, mode); | ||
35 | } | ||
36 | } | ||
37 | return (*mode == 'r') ? stdin : stdout; | ||
38 | } | ||
diff --git a/coreutils/ln.c b/coreutils/ln.c index 427ffcc6e..2edece104 100644 --- a/coreutils/ln.c +++ b/coreutils/ln.c | |||
@@ -21,113 +21,86 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <stdio.h> | 24 | /* BB_AUDIT SUSv3 compliant */ |
25 | #include <dirent.h> | 25 | /* BB_AUDIT GNU options missing: -b, -d, -F, -i, -S, and -v. */ |
26 | #include <string.h> | 26 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/ln.html */ |
27 | |||
28 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
29 | * | ||
30 | * Fixed bug involving -n option. Essentially, -n was always in effect. | ||
31 | */ | ||
32 | |||
27 | #include <stdlib.h> | 33 | #include <stdlib.h> |
28 | #include <errno.h> | ||
29 | #include <unistd.h> | 34 | #include <unistd.h> |
30 | #include "busybox.h" | 35 | #include "busybox.h" |
31 | 36 | ||
37 | #define LN_SYMLINK 1 | ||
38 | #define LN_FORCE 2 | ||
39 | #define LN_NODEREFERENCE 4 | ||
32 | 40 | ||
33 | static const int LN_SYMLINK = 1; | 41 | extern int ln_main(int argc, char **argv) |
34 | static const int LN_FORCE = 2; | ||
35 | static const int LN_NODEREFERENCE = 4; | ||
36 | |||
37 | /* | ||
38 | * linkDestName is where the link points to, | ||
39 | * linkSrcName is the name of the link to be created. | ||
40 | */ | ||
41 | static int fs_link(const char *link_destname, const char *link_srcname, | ||
42 | const int flag) | ||
43 | { | 42 | { |
44 | int status; | 43 | int status = EXIT_SUCCESS; |
45 | int src_is_dir; | 44 | int flag; |
46 | char *src_name = 0; | 45 | char *last; |
46 | char *src_name; | ||
47 | const char *src; | 47 | const char *src; |
48 | int (*link_func)(const char *, const char *); | ||
48 | 49 | ||
49 | if (link_destname==NULL) | 50 | flag = bb_getopt_ulflags(argc, argv, "sfn"); |
50 | return(FALSE); | 51 | |
51 | 52 | if (argc == optind) { | |
52 | if (link_srcname==NULL) | 53 | bb_show_usage(); |
53 | src = link_destname; | ||
54 | else | ||
55 | src = link_srcname; | ||
56 | |||
57 | if (flag&LN_NODEREFERENCE) | ||
58 | src_is_dir = is_directory(src, TRUE, NULL); | ||
59 | else | ||
60 | src_is_dir = is_directory(src, FALSE, NULL); | ||
61 | |||
62 | if ((src_is_dir==TRUE)&&((flag&LN_NODEREFERENCE)==0)) { | ||
63 | char* srcdir_name; | ||
64 | |||
65 | srcdir_name = xstrdup(link_destname); | ||
66 | src_name = concat_path_file(src, get_last_path_component(srcdir_name)); | ||
67 | src = src_name; | ||
68 | free(srcdir_name); | ||
69 | } | 54 | } |
70 | 55 | ||
71 | if (flag&LN_FORCE) | 56 | last = argv[argc - 1]; |
72 | unlink(src); | 57 | argv += optind; |
73 | 58 | ||
74 | if (flag&LN_SYMLINK) | 59 | if (argc == optind + 1) { |
75 | status = symlink(link_destname, src); | 60 | *--argv = last; |
76 | else | 61 | last = bb_get_last_path_component(bb_xstrdup(last)); |
77 | status = link(link_destname, src); | ||
78 | |||
79 | if (status != 0) { | ||
80 | perror_msg(src); | ||
81 | status = FALSE; | ||
82 | } else { | ||
83 | status = TRUE; | ||
84 | } | 62 | } |
85 | free(src_name); | ||
86 | return status; | ||
87 | } | ||
88 | 63 | ||
89 | extern int ln_main(int argc, char **argv) | 64 | do { |
90 | { | 65 | src_name = 0; |
91 | int status = EXIT_SUCCESS; | 66 | src = last; |
92 | int flag = 0; | 67 | |
93 | int opt; | 68 | if (is_directory(src, |
94 | 69 | (flag & LN_NODEREFERENCE) ^ LN_NODEREFERENCE, | |
95 | /* Parse any options */ | 70 | NULL)) { |
96 | while ((opt=getopt(argc, argv, "sfn")) != -1) { | 71 | src_name = bb_xstrdup(*argv); |
97 | switch(opt) { | 72 | src = concat_path_file(src, bb_get_last_path_component(src_name)); |
98 | case 's': | 73 | free(src_name); |
99 | flag |= LN_SYMLINK; | 74 | src_name = (char *)src; |
100 | break; | ||
101 | case 'f': | ||
102 | flag |= LN_FORCE; | ||
103 | break; | ||
104 | case 'n': | ||
105 | flag |= LN_NODEREFERENCE; | ||
106 | break; | ||
107 | default: | ||
108 | show_usage(); | ||
109 | } | 75 | } |
110 | } | 76 | |
111 | if (optind > (argc-1)) { | 77 | if (flag & LN_FORCE) { |
112 | show_usage(); | 78 | unlink(src); |
113 | } | 79 | } |
114 | if (optind == (argc-1)) { | 80 | |
115 | if (fs_link(argv[optind], | 81 | link_func = link; |
116 | get_last_path_component(argv[optind]), flag)==FALSE) | 82 | if (flag & LN_SYMLINK) { |
117 | status = EXIT_FAILURE; | 83 | link_func = symlink; |
118 | } | 84 | } |
119 | while(optind<(argc-1)) { | 85 | |
120 | if (fs_link(argv[optind], argv[argc-1], flag)==FALSE) | 86 | if (link_func(*argv, src) != 0) { |
121 | status = EXIT_FAILURE; | 87 | bb_perror_msg(src); |
122 | optind++; | 88 | status = EXIT_FAILURE;; |
123 | } | 89 | } |
90 | |||
91 | free(src_name); | ||
92 | |||
93 | } while ((++argv)[1]); | ||
94 | |||
124 | return status; | 95 | return status; |
125 | } | 96 | } |
126 | 97 | ||
127 | /* | 98 | |
128 | Local Variables: | 99 | |
129 | c-file-style: "linux" | 100 | |
130 | c-basic-offset: 4 | 101 | |
131 | tab-width: 4 | 102 | |
132 | End: | 103 | |
133 | */ | 104 | |
105 | |||
106 | |||
diff --git a/coreutils/logname.c b/coreutils/logname.c index 3e10fba6f..9cedff027 100644 --- a/coreutils/logname.c +++ b/coreutils/logname.c | |||
@@ -20,6 +20,19 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* BB_AUDIT SUSv3 compliant */ | ||
24 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/logname.html */ | ||
25 | |||
26 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
27 | * | ||
28 | * SUSv3 specifies the string used is that returned from getlogin(). | ||
29 | * The previous implementation used getpwuid() for geteuid(), which | ||
30 | * is _not_ the same. Erik apparently made this change almost 3 years | ||
31 | * ago to avoid failing when no utmp was available. However, the | ||
32 | * correct course of action wrt SUSv3 for a failing getlogin() is | ||
33 | * a dianostic message and an error return. | ||
34 | */ | ||
35 | |||
23 | #include <stdio.h> | 36 | #include <stdio.h> |
24 | #include <stdlib.h> | 37 | #include <stdlib.h> |
25 | #include <unistd.h> | 38 | #include <unistd.h> |
@@ -27,14 +40,16 @@ | |||
27 | 40 | ||
28 | extern int logname_main(int argc, char **argv) | 41 | extern int logname_main(int argc, char **argv) |
29 | { | 42 | { |
30 | char user[9]; | 43 | const char *p; |
31 | 44 | ||
32 | if (argc > 1) | 45 | if (argc > 1) { |
33 | show_usage(); | 46 | bb_show_usage(); |
47 | } | ||
34 | 48 | ||
35 | if (my_getpwuid(user, geteuid())) { | 49 | if ((p = getlogin()) != NULL) { |
36 | puts(user); | 50 | puts(p); |
37 | return EXIT_SUCCESS; | 51 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); |
38 | } | 52 | } |
39 | error_msg_and_die("no login name"); | 53 | |
54 | bb_perror_msg_and_die("getlogin"); | ||
40 | } | 55 | } |
diff --git a/coreutils/ls.c b/coreutils/ls.c index 64ec0fee6..4a4956611 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -73,58 +73,76 @@ enum { | |||
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | /* what is the overall style of the listing */ | 75 | /* what is the overall style of the listing */ |
76 | enum { | 76 | #define STYLE_AUTO (0) |
77 | STYLE_AUTO = 0, | 77 | #define STYLE_COLUMNS (1U<<21) /* fill columns */ |
78 | STYLE_LONG = 1, /* one record per line, extended info */ | 78 | #define STYLE_LONG (2U<<21) /* one record per line, extended info */ |
79 | STYLE_SINGLE = 2, /* one record per line */ | 79 | #define STYLE_SINGLE (3U<<21) /* one record per line */ |
80 | STYLE_COLUMNS = 3 /* fill columns */ | 80 | |
81 | }; | 81 | #define STYLE_MASK STYLE_SINGLE |
82 | #define STYLE_ONE_RECORD_FLAG STYLE_LONG | ||
82 | 83 | ||
83 | /* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */ | 84 | /* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */ |
84 | /* what file information will be listed */ | 85 | /* what file information will be listed */ |
85 | #define LIST_INO (1<<0) | 86 | #define LIST_INO (1U<<0) |
86 | #define LIST_BLOCKS (1<<1) | 87 | #define LIST_BLOCKS (1U<<1) |
87 | #define LIST_MODEBITS (1<<2) | 88 | #define LIST_MODEBITS (1U<<2) |
88 | #define LIST_NLINKS (1<<3) | 89 | #define LIST_NLINKS (1U<<3) |
89 | #define LIST_ID_NAME (1<<4) | 90 | #define LIST_ID_NAME (1U<<4) |
90 | #define LIST_ID_NUMERIC (1<<5) | 91 | #define LIST_ID_NUMERIC (1U<<5) |
91 | #define LIST_SIZE (1<<6) | 92 | #define LIST_SIZE (1U<<6) |
92 | #define LIST_DEV (1<<7) | 93 | #define LIST_DEV (1U<<7) |
93 | #define LIST_DATE_TIME (1<<8) | 94 | #define LIST_DATE_TIME (1U<<8) |
94 | #define LIST_FULLTIME (1<<9) | 95 | #define LIST_FULLTIME (1U<<9) |
95 | #define LIST_FILENAME (1<<10) | 96 | #define LIST_FILENAME (1U<<10) |
96 | #define LIST_SYMLINK (1<<11) | 97 | #define LIST_SYMLINK (1U<<11) |
97 | #define LIST_FILETYPE (1<<12) | 98 | #define LIST_FILETYPE (1U<<12) |
98 | #define LIST_EXEC (1<<13) | 99 | #define LIST_EXEC (1U<<13) |
100 | |||
101 | #define LIST_MASK ((LIST_EXEC << 1) - 1) | ||
99 | 102 | ||
100 | /* what files will be displayed */ | 103 | /* what files will be displayed */ |
101 | #define DISP_NORMAL (0) /* show normal filenames */ | 104 | /* TODO -- We may be able to make DISP_NORMAL 0 to save a bit slot. */ |
102 | #define DISP_DIRNAME (1<<0) /* 2 or more items? label directories */ | 105 | #define DISP_NORMAL (1U<<14) /* show normal filenames */ |
103 | #define DISP_HIDDEN (1<<1) /* show filenames starting with . */ | 106 | #define DISP_DIRNAME (1U<<15) /* 2 or more items? label directories */ |
104 | #define DISP_DOT (1<<2) /* show . and .. */ | 107 | #define DISP_HIDDEN (1U<<16) /* show filenames starting with . */ |
105 | #define DISP_NOLIST (1<<3) /* show directory as itself, not contents */ | 108 | #define DISP_DOT (1U<<17) /* show . and .. */ |
106 | #define DISP_RECURSIVE (1<<4) /* show directory and everything below it */ | 109 | #define DISP_NOLIST (1U<<18) /* show directory as itself, not contents */ |
107 | #define DISP_ROWS (1<<5) /* print across rows */ | 110 | #define DISP_RECURSIVE (1U<<19) /* show directory and everything below it */ |
111 | #define DISP_ROWS (1U<<20) /* print across rows */ | ||
112 | |||
113 | #define DISP_MASK (((DISP_ROWS << 1) - 1) & ~(DISP_NORMAL - 1)) | ||
108 | 114 | ||
109 | #ifdef CONFIG_FEATURE_LS_SORTFILES | 115 | #ifdef CONFIG_FEATURE_LS_SORTFILES |
110 | /* how will the files be sorted */ | 116 | /* how will the files be sorted */ |
111 | static const int SORT_FORWARD = 0; /* sort in reverse order */ | 117 | #define SORT_ORDER_FORWARD 0 /* sort in reverse order */ |
112 | static const int SORT_REVERSE = 1; /* sort in reverse order */ | 118 | #define SORT_ORDER_REVERSE (1U<<27) /* sort in reverse order */ |
113 | static const int SORT_NAME = 2; /* sort by file name */ | 119 | |
114 | static const int SORT_SIZE = 3; /* sort by file size */ | 120 | #define SORT_NAME 0 /* sort by file name */ |
115 | static const int SORT_ATIME = 4; /* sort by last access time */ | 121 | #define SORT_SIZE (1U<<28) /* sort by file size */ |
116 | static const int SORT_CTIME = 5; /* sort by last change time */ | 122 | #define SORT_ATIME (2U<<28) /* sort by last access time */ |
117 | static const int SORT_MTIME = 6; /* sort by last modification time */ | 123 | #define SORT_CTIME (3U<<28) /* sort by last change time */ |
118 | static const int SORT_VERSION = 7; /* sort by version */ | 124 | #define SORT_MTIME (4U<<28) /* sort by last modification time */ |
119 | static const int SORT_EXT = 8; /* sort by file name extension */ | 125 | #define SORT_VERSION (5U<<28) /* sort by version */ |
120 | static const int SORT_DIR = 9; /* sort by file or directory */ | 126 | #define SORT_EXT (6U<<28) /* sort by file name extension */ |
127 | #define SORT_DIR (7U<<28) /* sort by file or directory */ | ||
128 | |||
129 | #define SORT_MASK (7U<<28) | ||
121 | #endif | 130 | #endif |
122 | 131 | ||
123 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS | 132 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS |
124 | /* which of the three times will be used */ | 133 | /* which of the three times will be used */ |
125 | static const int TIME_MOD = 0; | 134 | #define TIME_MOD 0 |
126 | static const int TIME_CHANGE = 1; | 135 | #define TIME_CHANGE (1U<<23) |
127 | static const int TIME_ACCESS = 2; | 136 | #define TIME_ACCESS (1U<<24) |
137 | |||
138 | #define TIME_MASK (3U<<23) | ||
139 | #endif | ||
140 | |||
141 | #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS | ||
142 | #define FOLLOW_LINKS (1U<<25) | ||
143 | #endif | ||
144 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||
145 | #define LS_DISP_HR (1U<<26) | ||
128 | #endif | 146 | #endif |
129 | 147 | ||
130 | #define LIST_SHORT (LIST_FILENAME) | 148 | #define LIST_SHORT (LIST_FILENAME) |
@@ -133,9 +151,9 @@ static const int TIME_ACCESS = 2; | |||
133 | LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK) | 151 | LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK) |
134 | #define LIST_ILONG (LIST_INO | LIST_LONG) | 152 | #define LIST_ILONG (LIST_INO | LIST_LONG) |
135 | 153 | ||
136 | static const int SPLIT_DIR = 0; | 154 | #define SPLIT_DIR 1 |
137 | static const int SPLIT_FILE = 1; | 155 | #define SPLIT_FILE 0 |
138 | static const int SPLIT_SUBDIR = 2; | 156 | #define SPLIT_SUBDIR 2 |
139 | 157 | ||
140 | #define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) | 158 | #define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) |
141 | #define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) | 159 | #define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) |
@@ -169,20 +187,7 @@ static struct dnode **list_dir(const char *); | |||
169 | static struct dnode **dnalloc(int); | 187 | static struct dnode **dnalloc(int); |
170 | static int list_single(struct dnode *); | 188 | static int list_single(struct dnode *); |
171 | 189 | ||
172 | static unsigned int disp_opts; | 190 | static unsigned int all_fmt; |
173 | static unsigned int style_fmt; | ||
174 | static unsigned int list_fmt; | ||
175 | |||
176 | #ifdef CONFIG_FEATURE_LS_SORTFILES | ||
177 | static unsigned int sort_opts; | ||
178 | static unsigned int sort_order; | ||
179 | #endif | ||
180 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS | ||
181 | static unsigned int time_fmt; | ||
182 | #endif | ||
183 | #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS | ||
184 | static unsigned int follow_links = FALSE; | ||
185 | #endif | ||
186 | 191 | ||
187 | #ifdef CONFIG_FEATURE_AUTOWIDTH | 192 | #ifdef CONFIG_FEATURE_AUTOWIDTH |
188 | static unsigned short terminal_width = TERMINAL_WIDTH; | 193 | static unsigned short terminal_width = TERMINAL_WIDTH; |
@@ -194,26 +199,22 @@ static unsigned short tabstops = COLUMN_GAP; | |||
194 | 199 | ||
195 | static int status = EXIT_SUCCESS; | 200 | static int status = EXIT_SUCCESS; |
196 | 201 | ||
197 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||
198 | static unsigned long ls_disp_hr = 0; | ||
199 | #endif | ||
200 | |||
201 | static struct dnode *my_stat(char *fullname, char *name) | 202 | static struct dnode *my_stat(char *fullname, char *name) |
202 | { | 203 | { |
203 | struct stat dstat; | 204 | struct stat dstat; |
204 | struct dnode *cur; | 205 | struct dnode *cur; |
205 | 206 | ||
206 | #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS | 207 | #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS |
207 | if (follow_links) { | 208 | if (all_fmt & FOLLOW_LINKS) { |
208 | if (stat(fullname, &dstat)) { | 209 | if (stat(fullname, &dstat)) { |
209 | perror_msg("%s", fullname); | 210 | bb_perror_msg("%s", fullname); |
210 | status = EXIT_FAILURE; | 211 | status = EXIT_FAILURE; |
211 | return 0; | 212 | return 0; |
212 | } | 213 | } |
213 | } else | 214 | } else |
214 | #endif | 215 | #endif |
215 | if (lstat(fullname, &dstat)) { | 216 | if (lstat(fullname, &dstat)) { |
216 | perror_msg("%s", fullname); | 217 | bb_perror_msg("%s", fullname); |
217 | status = EXIT_FAILURE; | 218 | status = EXIT_FAILURE; |
218 | return 0; | 219 | return 0; |
219 | } | 220 | } |
@@ -253,9 +254,9 @@ static char bgcolor(mode_t mode) | |||
253 | #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined(CONFIG_FEATURE_LS_COLOR) | 254 | #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined(CONFIG_FEATURE_LS_COLOR) |
254 | static char append_char(mode_t mode) | 255 | static char append_char(mode_t mode) |
255 | { | 256 | { |
256 | if (!(list_fmt & LIST_FILETYPE)) | 257 | if (!(all_fmt & LIST_FILETYPE)) |
257 | return '\0'; | 258 | return '\0'; |
258 | if ((list_fmt & LIST_EXEC) && S_ISREG(mode) | 259 | if ((all_fmt & LIST_EXEC) && S_ISREG(mode) |
259 | && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) | 260 | && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) |
260 | return '*'; | 261 | return '*'; |
261 | return APPCHAR(mode); | 262 | return APPCHAR(mode); |
@@ -263,13 +264,11 @@ static char append_char(mode_t mode) | |||
263 | #endif | 264 | #endif |
264 | 265 | ||
265 | /*----------------------------------------------------------------------*/ | 266 | /*----------------------------------------------------------------------*/ |
266 | static int is_subdir(struct dnode *dn) | ||
267 | { | ||
268 | return (S_ISDIR(dn->dstat.st_mode) && strcmp(dn->name, ".") != 0 && | ||
269 | strcmp(dn->name, "..") != 0); | ||
270 | } | ||
271 | 267 | ||
272 | static int countdirs(struct dnode **dn, int nfiles) | 268 | #define countdirs(A,B) count_dirs((A), (B), 1) |
269 | #define countsubdirs(A,B) count_dirs((A), (B), 0) | ||
270 | |||
271 | static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs) | ||
273 | { | 272 | { |
274 | int i, dirs; | 273 | int i, dirs; |
275 | 274 | ||
@@ -277,25 +276,17 @@ static int countdirs(struct dnode **dn, int nfiles) | |||
277 | return (0); | 276 | return (0); |
278 | dirs = 0; | 277 | dirs = 0; |
279 | for (i = 0; i < nfiles; i++) { | 278 | for (i = 0; i < nfiles; i++) { |
280 | if (S_ISDIR(dn[i]->dstat.st_mode)) | 279 | if (S_ISDIR(dn[i]->dstat.st_mode) |
280 | && (notsubdirs | ||
281 | || ((dn[i]->name[0] != '.') | ||
282 | || (dn[i]->name[1] | ||
283 | && ((dn[i]->name[1] != '.') | ||
284 | || dn[i]->name[2]))))) | ||
281 | dirs++; | 285 | dirs++; |
282 | } | 286 | } |
283 | return (dirs); | 287 | return (dirs); |
284 | } | 288 | } |
285 | 289 | ||
286 | static int countsubdirs(struct dnode **dn, int nfiles) | ||
287 | { | ||
288 | int i, subdirs; | ||
289 | |||
290 | if (dn == NULL || nfiles < 1) | ||
291 | return 0; | ||
292 | subdirs = 0; | ||
293 | for (i = 0; i < nfiles; i++) | ||
294 | if (is_subdir(dn[i])) | ||
295 | subdirs++; | ||
296 | return subdirs; | ||
297 | } | ||
298 | |||
299 | static int countfiles(struct dnode **dnp) | 290 | static int countfiles(struct dnode **dnp) |
300 | { | 291 | { |
301 | int nfiles; | 292 | int nfiles; |
@@ -364,18 +355,18 @@ static struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which) | |||
364 | 355 | ||
365 | /* copy the entrys into the file or dir array */ | 356 | /* copy the entrys into the file or dir array */ |
366 | for (d = i = 0; i < nfiles; i++) { | 357 | for (d = i = 0; i < nfiles; i++) { |
367 | if (which == SPLIT_DIR) { | 358 | if (S_ISDIR(dn[i]->dstat.st_mode)) { |
368 | if (S_ISDIR(dn[i]->dstat.st_mode)) { | 359 | if (which & (SPLIT_DIR|SPLIT_SUBDIR)) { |
369 | dnp[d++] = dn[i]; | 360 | if ((which & SPLIT_DIR) |
370 | } /* else skip the file */ | 361 | || ((dn[i]->name[0] != '.') |
371 | } else if (which == SPLIT_SUBDIR) { | 362 | || (dn[i]->name[1] |
372 | if (is_subdir(dn[i])) { | 363 | && ((dn[i]->name[1] != '.') |
373 | dnp[d++] = dn[i]; | 364 | || dn[i]->name[2])))) { |
374 | } /* else skip the file or dir */ | 365 | dnp[d++] = dn[i]; |
375 | } else { | 366 | } |
376 | if (!(S_ISDIR(dn[i]->dstat.st_mode))) { | 367 | } |
377 | dnp[d++] = dn[i]; | 368 | } else if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) { |
378 | } /* else skip the dir */ | 369 | dnp[d++] = dn[i]; |
379 | } | 370 | } |
380 | } | 371 | } |
381 | return (dnp); | 372 | return (dnp); |
@@ -385,29 +376,24 @@ static struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which) | |||
385 | #ifdef CONFIG_FEATURE_LS_SORTFILES | 376 | #ifdef CONFIG_FEATURE_LS_SORTFILES |
386 | static int sortcmp(struct dnode *d1, struct dnode *d2) | 377 | static int sortcmp(struct dnode *d1, struct dnode *d2) |
387 | { | 378 | { |
388 | int cmp, dif; | 379 | unsigned int sort_opts = all_fmt & SORT_MASK; |
380 | int dif; | ||
389 | 381 | ||
390 | cmp = 0; | 382 | dif = 0; /* assume SORT_NAME */ |
391 | if (sort_opts == SORT_SIZE) { | 383 | if (sort_opts == SORT_SIZE) { |
392 | dif = (int) (d1->dstat.st_size - d2->dstat.st_size); | 384 | dif = (int) (d2->dstat.st_size - d1->dstat.st_size); |
393 | } else if (sort_opts == SORT_ATIME) { | 385 | } else if (sort_opts == SORT_ATIME) { |
394 | dif = (int) (d1->dstat.st_atime - d2->dstat.st_atime); | 386 | dif = (int) (d2->dstat.st_atime - d1->dstat.st_atime); |
395 | } else if (sort_opts == SORT_CTIME) { | 387 | } else if (sort_opts == SORT_CTIME) { |
396 | dif = (int) (d1->dstat.st_ctime - d2->dstat.st_ctime); | 388 | dif = (int) (d2->dstat.st_ctime - d1->dstat.st_ctime); |
397 | } else if (sort_opts == SORT_MTIME) { | 389 | } else if (sort_opts == SORT_MTIME) { |
398 | dif = (int) (d1->dstat.st_mtime - d2->dstat.st_mtime); | 390 | dif = (int) (d2->dstat.st_mtime - d1->dstat.st_mtime); |
399 | } else if (sort_opts == SORT_DIR) { | 391 | } else if (sort_opts == SORT_DIR) { |
400 | dif = S_ISDIR(d1->dstat.st_mode) - S_ISDIR(d2->dstat.st_mode); | 392 | dif = S_ISDIR(d2->dstat.st_mode) - S_ISDIR(d1->dstat.st_mode); |
401 | /* } else if (sort_opts == SORT_VERSION) { */ | 393 | /* } else if (sort_opts == SORT_VERSION) { */ |
402 | /* } else if (sort_opts == SORT_EXT) { */ | 394 | /* } else if (sort_opts == SORT_EXT) { */ |
403 | } else { /* assume SORT_NAME */ | ||
404 | dif = 0; | ||
405 | } | 395 | } |
406 | 396 | ||
407 | if (dif > 0) | ||
408 | cmp = -1; | ||
409 | if (dif < 0) | ||
410 | cmp = 1; | ||
411 | if (dif == 0) { | 397 | if (dif == 0) { |
412 | /* sort by name- may be a tie_breaker for time or size cmp */ | 398 | /* sort by name- may be a tie_breaker for time or size cmp */ |
413 | #ifdef CONFIG_LOCALE_SUPPORT | 399 | #ifdef CONFIG_LOCALE_SUPPORT |
@@ -415,16 +401,12 @@ static int sortcmp(struct dnode *d1, struct dnode *d2) | |||
415 | #else | 401 | #else |
416 | dif = strcmp(d1->name, d2->name); | 402 | dif = strcmp(d1->name, d2->name); |
417 | #endif | 403 | #endif |
418 | if (dif > 0) | ||
419 | cmp = 1; | ||
420 | if (dif < 0) | ||
421 | cmp = -1; | ||
422 | } | 404 | } |
423 | 405 | ||
424 | if (sort_order == SORT_REVERSE) { | 406 | if (all_fmt & SORT_ORDER_REVERSE) { |
425 | cmp = -1 * cmp; | 407 | dif = -dif; |
426 | } | 408 | } |
427 | return (cmp); | 409 | return (dif); |
428 | } | 410 | } |
429 | 411 | ||
430 | /*----------------------------------------------------------------------*/ | 412 | /*----------------------------------------------------------------------*/ |
@@ -463,20 +445,17 @@ static void showfiles(struct dnode **dn, int nfiles) | |||
463 | if (dn == NULL || nfiles < 1) | 445 | if (dn == NULL || nfiles < 1) |
464 | return; | 446 | return; |
465 | 447 | ||
466 | switch (style_fmt) { | 448 | if (all_fmt & STYLE_ONE_RECORD_FLAG) { |
467 | case STYLE_LONG: /* one record per line, extended info */ | ||
468 | case STYLE_SINGLE: /* one record per line */ | ||
469 | ncols = 1; | 449 | ncols = 1; |
470 | break; | 450 | } else { |
471 | default: | 451 | /* find the longest file name- use that as the column width */ |
472 | /* find the longest file name- use that as the column width */ | 452 | for (i = 0; i < nfiles; i++) { |
473 | for (i = 0; i < nfiles; i++) { | ||
474 | int len = strlen(dn[i]->name) + | 453 | int len = strlen(dn[i]->name) + |
475 | ((list_fmt & LIST_INO) ? 8 : 0) + | 454 | ((all_fmt & LIST_INO) ? 8 : 0) + |
476 | ((list_fmt & LIST_BLOCKS) ? 5 : 0); | 455 | ((all_fmt & LIST_BLOCKS) ? 5 : 0); |
477 | if (column_width < len) | 456 | if (column_width < len) |
478 | column_width = len; | 457 | column_width = len; |
479 | } | 458 | } |
480 | column_width += tabstops; | 459 | column_width += tabstops; |
481 | ncols = (int) (terminal_width / column_width); | 460 | ncols = (int) (terminal_width / column_width); |
482 | } | 461 | } |
@@ -494,7 +473,7 @@ static void showfiles(struct dnode **dn, int nfiles) | |||
494 | for (nc = 0; nc < ncols; nc++) { | 473 | for (nc = 0; nc < ncols; nc++) { |
495 | /* reach into the array based on the column and row */ | 474 | /* reach into the array based on the column and row */ |
496 | i = (nc * nrows) + row; /* assume display by column */ | 475 | i = (nc * nrows) + row; /* assume display by column */ |
497 | if (disp_opts & DISP_ROWS) | 476 | if (all_fmt & DISP_ROWS) |
498 | i = (row * ncols) + nc; /* display across row */ | 477 | i = (row * ncols) + nc; /* display across row */ |
499 | if (i < nfiles) { | 478 | if (i < nfiles) { |
500 | if (column > 0) { | 479 | if (column > 0) { |
@@ -528,7 +507,7 @@ static void showdirs(struct dnode **dn, int ndirs) | |||
528 | return; | 507 | return; |
529 | 508 | ||
530 | for (i = 0; i < ndirs; i++) { | 509 | for (i = 0; i < ndirs; i++) { |
531 | if (disp_opts & (DISP_DIRNAME | DISP_RECURSIVE)) { | 510 | if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { |
532 | printf("\n%s:\n", dn[i]->fullname); | 511 | printf("\n%s:\n", dn[i]->fullname); |
533 | } | 512 | } |
534 | subdnp = list_dir(dn[i]->fullname); | 513 | subdnp = list_dir(dn[i]->fullname); |
@@ -540,7 +519,7 @@ static void showdirs(struct dnode **dn, int ndirs) | |||
540 | #endif | 519 | #endif |
541 | showfiles(subdnp, nfiles); | 520 | showfiles(subdnp, nfiles); |
542 | #ifdef CONFIG_FEATURE_LS_RECURSIVE | 521 | #ifdef CONFIG_FEATURE_LS_RECURSIVE |
543 | if (disp_opts & DISP_RECURSIVE) { | 522 | if (all_fmt & DISP_RECURSIVE) { |
544 | /* recursive- list the sub-dirs */ | 523 | /* recursive- list the sub-dirs */ |
545 | dnd = splitdnarray(subdnp, nfiles, SPLIT_SUBDIR); | 524 | dnd = splitdnarray(subdnp, nfiles, SPLIT_SUBDIR); |
546 | dndirs = countsubdirs(subdnp, nfiles); | 525 | dndirs = countsubdirs(subdnp, nfiles); |
@@ -573,7 +552,7 @@ static struct dnode **list_dir(const char *path) | |||
573 | nfiles = 0; | 552 | nfiles = 0; |
574 | dir = opendir(path); | 553 | dir = opendir(path); |
575 | if (dir == NULL) { | 554 | if (dir == NULL) { |
576 | perror_msg("%s", path); | 555 | bb_perror_msg("%s", path); |
577 | status = EXIT_FAILURE; | 556 | status = EXIT_FAILURE; |
578 | return (NULL); /* could not open the dir */ | 557 | return (NULL); /* could not open the dir */ |
579 | } | 558 | } |
@@ -585,9 +564,9 @@ static struct dnode **list_dir(const char *path) | |||
585 | if ((entry->d_name[1] == 0 || ( | 564 | if ((entry->d_name[1] == 0 || ( |
586 | entry->d_name[1] == '.' | 565 | entry->d_name[1] == '.' |
587 | && entry->d_name[2] == 0)) | 566 | && entry->d_name[2] == 0)) |
588 | && !(disp_opts & DISP_DOT)) | 567 | && !(all_fmt & DISP_DOT)) |
589 | continue; | 568 | continue; |
590 | if (!(disp_opts & DISP_HIDDEN)) | 569 | if (!(all_fmt & DISP_HIDDEN)) |
591 | continue; | 570 | continue; |
592 | } | 571 | } |
593 | fullname = concat_path_file(path, entry->d_name); | 572 | fullname = concat_path_file(path, entry->d_name); |
@@ -636,9 +615,9 @@ static int list_single(struct dnode *dn) | |||
636 | 615 | ||
637 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS | 616 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS |
638 | ttime = dn->dstat.st_mtime; /* the default time */ | 617 | ttime = dn->dstat.st_mtime; /* the default time */ |
639 | if (time_fmt & TIME_ACCESS) | 618 | if (all_fmt & TIME_ACCESS) |
640 | ttime = dn->dstat.st_atime; | 619 | ttime = dn->dstat.st_atime; |
641 | if (time_fmt & TIME_CHANGE) | 620 | if (all_fmt & TIME_CHANGE) |
642 | ttime = dn->dstat.st_ctime; | 621 | ttime = dn->dstat.st_ctime; |
643 | filetime = ctime(&ttime); | 622 | filetime = ctime(&ttime); |
644 | #endif | 623 | #endif |
@@ -647,7 +626,7 @@ static int list_single(struct dnode *dn) | |||
647 | #endif | 626 | #endif |
648 | 627 | ||
649 | for (i = 0; i <= 31; i++) { | 628 | for (i = 0; i <= 31; i++) { |
650 | switch (list_fmt & (1 << i)) { | 629 | switch (all_fmt & (1 << i)) { |
651 | case LIST_INO: | 630 | case LIST_INO: |
652 | column += printf("%7ld ", (long int) dn->dstat.st_ino); | 631 | column += printf("%7ld ", (long int) dn->dstat.st_ino); |
653 | break; | 632 | break; |
@@ -659,7 +638,7 @@ static int list_single(struct dnode *dn) | |||
659 | #endif | 638 | #endif |
660 | break; | 639 | break; |
661 | case LIST_MODEBITS: | 640 | case LIST_MODEBITS: |
662 | column += printf("%-10s ", (char *) mode_string(dn->dstat.st_mode)); | 641 | column += printf("%-10s ", (char *) bb_mode_string(dn->dstat.st_mode)); |
663 | break; | 642 | break; |
664 | case LIST_NLINKS: | 643 | case LIST_NLINKS: |
665 | column += printf("%4ld ", (long) dn->dstat.st_nlink); | 644 | column += printf("%4ld ", (long) dn->dstat.st_nlink); |
@@ -683,7 +662,7 @@ static int list_single(struct dnode *dn) | |||
683 | (int) MINOR(dn->dstat.st_rdev)); | 662 | (int) MINOR(dn->dstat.st_rdev)); |
684 | } else { | 663 | } else { |
685 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 664 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
686 | if (ls_disp_hr == TRUE) { | 665 | if (all_fmt & LS_DISP_HR) { |
687 | column += printf("%9s ", | 666 | column += printf("%9s ", |
688 | make_human_readable_str(dn->dstat.st_size, 1, 0)); | 667 | make_human_readable_str(dn->dstat.st_size, 1, 0)); |
689 | } else | 668 | } else |
@@ -700,7 +679,7 @@ static int list_single(struct dnode *dn) | |||
700 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS | 679 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS |
701 | case LIST_FULLTIME: | 680 | case LIST_FULLTIME: |
702 | case LIST_DATE_TIME: | 681 | case LIST_DATE_TIME: |
703 | if (list_fmt & LIST_FULLTIME) { | 682 | if (all_fmt & LIST_FULLTIME) { |
704 | printf("%24.24s ", filetime); | 683 | printf("%24.24s ", filetime); |
705 | column += 25; | 684 | column += 25; |
706 | break; | 685 | break; |
@@ -774,47 +753,8 @@ static int list_single(struct dnode *dn) | |||
774 | } | 753 | } |
775 | 754 | ||
776 | /*----------------------------------------------------------------------*/ | 755 | /*----------------------------------------------------------------------*/ |
777 | extern int ls_main(int argc, char **argv) | ||
778 | { | ||
779 | struct dnode **dnf, **dnd; | ||
780 | int dnfiles, dndirs; | ||
781 | struct dnode *dn, *cur, **dnp; | ||
782 | int i, nfiles; | ||
783 | int opt; | ||
784 | int oi, ac; | ||
785 | char **av; | ||
786 | |||
787 | #ifdef CONFIG_FEATURE_AUTOWIDTH | ||
788 | struct winsize win = { 0, 0, 0, 0 }; | ||
789 | #endif | ||
790 | |||
791 | disp_opts = DISP_NORMAL; | ||
792 | style_fmt = STYLE_AUTO; | ||
793 | list_fmt = LIST_SHORT; | ||
794 | #ifdef CONFIG_FEATURE_LS_SORTFILES | ||
795 | sort_opts = SORT_NAME; | ||
796 | sort_order = SORT_FORWARD; | ||
797 | #endif | ||
798 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS | ||
799 | time_fmt = TIME_MOD; | ||
800 | #endif | ||
801 | #ifdef CONFIG_FEATURE_AUTOWIDTH | ||
802 | ioctl(fileno(stdout), TIOCGWINSZ, &win); | ||
803 | if (win.ws_col > 0) | ||
804 | terminal_width = win.ws_col - 1; | ||
805 | #endif | ||
806 | nfiles = 0; | ||
807 | 756 | ||
808 | #ifdef CONFIG_FEATURE_LS_COLOR | 757 | static const char ls_opts[] = "1AaCdgilnsx" |
809 | if (isatty(fileno(stdout))) | ||
810 | show_color = 1; | ||
811 | #endif | ||
812 | |||
813 | /* process options */ | ||
814 | while ((opt = getopt(argc, argv, "1AaCdgilnsx" | ||
815 | #ifdef CONFIG_FEATURE_AUTOWIDTH | ||
816 | "T:w:" | ||
817 | #endif | ||
818 | #ifdef CONFIG_FEATURE_LS_FILETYPES | 758 | #ifdef CONFIG_FEATURE_LS_FILETYPES |
819 | "Fp" | 759 | "Fp" |
820 | #endif | 760 | #endif |
@@ -825,7 +765,7 @@ extern int ls_main(int argc, char **argv) | |||
825 | "rSvX" | 765 | "rSvX" |
826 | #endif | 766 | #endif |
827 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS | 767 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS |
828 | "cetu" | 768 | "ecut" |
829 | #endif | 769 | #endif |
830 | #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS | 770 | #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS |
831 | "L" | 771 | "L" |
@@ -833,141 +773,180 @@ extern int ls_main(int argc, char **argv) | |||
833 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 773 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
834 | "h" | 774 | "h" |
835 | #endif | 775 | #endif |
836 | "k")) > 0) { | 776 | "k" |
837 | switch (opt) { | 777 | #ifdef CONFIG_FEATURE_AUTOWIDTH |
838 | case '1': | 778 | "T:w:" |
839 | style_fmt = STYLE_SINGLE; | ||
840 | list_fmt = LIST_SHORT; | ||
841 | break; | ||
842 | case 'A': | ||
843 | disp_opts |= DISP_HIDDEN; | ||
844 | break; | ||
845 | case 'a': | ||
846 | disp_opts |= DISP_HIDDEN | DISP_DOT; | ||
847 | break; | ||
848 | case 'C': | ||
849 | style_fmt = STYLE_COLUMNS; | ||
850 | list_fmt = LIST_SHORT; | ||
851 | break; | ||
852 | case 'd': | ||
853 | disp_opts |= DISP_NOLIST; | ||
854 | break; | ||
855 | case 'g': /* ignore -- for ftp servers */ | ||
856 | break; | ||
857 | case 'i': | ||
858 | list_fmt |= LIST_INO; | ||
859 | break; | ||
860 | case 'l': | ||
861 | style_fmt = STYLE_LONG; | ||
862 | list_fmt |= LIST_LONG; | ||
863 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||
864 | ls_disp_hr = FALSE; | ||
865 | #endif | 779 | #endif |
866 | break; | 780 | ; |
867 | case 'n': | 781 | |
868 | list_fmt |= LIST_ID_NUMERIC; | 782 | #define LIST_MASK_TRIGGER LIST_SHORT |
869 | break; | 783 | #define STYLE_MASK_TRIGGER STYLE_MASK |
870 | case 's': | 784 | #define SORT_MASK_TRIGGER SORT_MASK |
871 | list_fmt |= LIST_BLOCKS; | 785 | #define DISP_MASK_TRIGGER DISP_ROWS |
872 | break; | 786 | #define TIME_MASK_TRIGGER TIME_MASK |
873 | case 'x': | 787 | |
874 | disp_opts = DISP_ROWS; | 788 | static const unsigned opt_flags[] = { |
875 | break; | 789 | LIST_SHORT | STYLE_SINGLE, /* 1 */ |
790 | DISP_HIDDEN, /* A */ | ||
791 | DISP_HIDDEN | DISP_DOT, /* a */ | ||
792 | LIST_SHORT | STYLE_COLUMNS, /* C */ | ||
793 | DISP_NOLIST, /* d */ | ||
794 | 0, /* g - ingored */ | ||
795 | LIST_INO, /* i */ | ||
796 | LIST_LONG | STYLE_LONG, /* l - remember LS_DISP_HR in mask! */ | ||
797 | LIST_ID_NUMERIC, /* n */ | ||
798 | LIST_BLOCKS, /* s */ | ||
799 | DISP_ROWS, /* x */ | ||
876 | #ifdef CONFIG_FEATURE_LS_FILETYPES | 800 | #ifdef CONFIG_FEATURE_LS_FILETYPES |
877 | case 'F': | 801 | LIST_FILETYPE | LIST_EXEC, /* F */ |
878 | list_fmt |= LIST_FILETYPE | LIST_EXEC; | 802 | LIST_FILETYPE, /* p */ |
879 | break; | ||
880 | case 'p': | ||
881 | list_fmt |= LIST_FILETYPE; | ||
882 | break; | ||
883 | #endif | 803 | #endif |
884 | #ifdef CONFIG_FEATURE_LS_RECURSIVE | 804 | #ifdef CONFIG_FEATURE_LS_RECURSIVE |
885 | case 'R': | 805 | DISP_RECURSIVE, /* R */ |
886 | disp_opts |= DISP_RECURSIVE; | ||
887 | break; | ||
888 | #endif | 806 | #endif |
889 | #ifdef CONFIG_FEATURE_LS_SORTFILES | 807 | #ifdef CONFIG_FEATURE_LS_SORTFILES |
890 | case 'r': | 808 | SORT_ORDER_REVERSE, /* r */ |
891 | sort_order |= SORT_REVERSE; | 809 | SORT_SIZE, /* S */ |
892 | break; | 810 | SORT_VERSION, /* v */ |
893 | case 'S': | 811 | SORT_EXT, /* v */ |
894 | sort_opts = SORT_SIZE; | ||
895 | break; | ||
896 | case 'v': | ||
897 | sort_opts = SORT_VERSION; | ||
898 | break; | ||
899 | case 'X': | ||
900 | sort_opts = SORT_EXT; | ||
901 | break; | ||
902 | #endif | 812 | #endif |
903 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS | 813 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS |
904 | case 'e': | 814 | LIST_FULLTIME, /* e */ |
905 | list_fmt |= LIST_FULLTIME; | ||
906 | break; | ||
907 | case 'c': | ||
908 | time_fmt = TIME_CHANGE; | ||
909 | #ifdef CONFIG_FEATURE_LS_SORTFILES | 815 | #ifdef CONFIG_FEATURE_LS_SORTFILES |
910 | sort_opts = SORT_CTIME; | 816 | TIME_CHANGE | SORT_CTIME, /* c */ |
817 | #else | ||
818 | TIME_CHANGE, /* c */ | ||
911 | #endif | 819 | #endif |
912 | break; | ||
913 | case 'u': | ||
914 | time_fmt = TIME_ACCESS; | ||
915 | #ifdef CONFIG_FEATURE_LS_SORTFILES | 820 | #ifdef CONFIG_FEATURE_LS_SORTFILES |
916 | sort_opts = SORT_ATIME; | 821 | TIME_ACCESS | SORT_ATIME, /* u */ |
822 | #else | ||
823 | TIME_ACCESS, /* u */ | ||
917 | #endif | 824 | #endif |
918 | break; | ||
919 | case 't': | ||
920 | #ifdef CONFIG_FEATURE_LS_SORTFILES | 825 | #ifdef CONFIG_FEATURE_LS_SORTFILES |
921 | sort_opts = SORT_MTIME; | 826 | SORT_MTIME, /* t */ |
827 | #else | ||
828 | 0, /* t - ignored -- is this correct? */ | ||
922 | #endif | 829 | #endif |
923 | break; | ||
924 | #endif | 830 | #endif |
925 | #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS | 831 | #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS |
926 | case 'L': | 832 | FOLLOW_LINKS, /* L */ |
927 | follow_links = TRUE; | 833 | #endif |
928 | break; | 834 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
835 | LS_DISP_HR, /* h */ | ||
836 | #endif | ||
837 | 0, /* k - ingored */ | ||
838 | }; | ||
839 | |||
840 | |||
841 | /*----------------------------------------------------------------------*/ | ||
842 | |||
843 | extern int ls_main(int argc, char **argv) | ||
844 | { | ||
845 | struct dnode **dnf, **dnd; | ||
846 | int dnfiles, dndirs; | ||
847 | struct dnode *dn, *cur, **dnp; | ||
848 | int i, nfiles; | ||
849 | int opt; | ||
850 | int oi, ac; | ||
851 | char **av; | ||
852 | |||
853 | #ifdef CONFIG_FEATURE_AUTOWIDTH | ||
854 | struct winsize win = { 0, 0, 0, 0 }; | ||
855 | #endif | ||
856 | |||
857 | all_fmt = LIST_SHORT | DISP_NORMAL | STYLE_AUTO | ||
858 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS | ||
859 | | TIME_MOD | ||
860 | #endif | ||
861 | #ifdef CONFIG_FEATURE_LS_SORTFILES | ||
862 | | SORT_NAME | SORT_ORDER_FORWARD | ||
863 | #endif | ||
864 | ; | ||
865 | #ifdef CONFIG_FEATURE_AUTOWIDTH | ||
866 | ioctl(fileno(stdout), TIOCGWINSZ, &win); | ||
867 | if (win.ws_col > 0) | ||
868 | terminal_width = win.ws_col - 1; | ||
869 | #endif | ||
870 | nfiles = 0; | ||
871 | |||
872 | #ifdef CONFIG_FEATURE_LS_COLOR | ||
873 | if (isatty(fileno(stdout))) | ||
874 | show_color = 1; | ||
929 | #endif | 875 | #endif |
876 | |||
877 | /* process options */ | ||
878 | while ((opt = getopt(argc, argv, ls_opts)) > 0) { | ||
930 | #ifdef CONFIG_FEATURE_AUTOWIDTH | 879 | #ifdef CONFIG_FEATURE_AUTOWIDTH |
931 | case 'T': | 880 | if (opt == 'T') { |
932 | tabstops = atoi(optarg); | 881 | tabstops = atoi(optarg); |
933 | break; | 882 | continue; |
934 | case 'w': | 883 | } |
884 | if (opt == 'w') { | ||
935 | terminal_width = atoi(optarg); | 885 | terminal_width = atoi(optarg); |
936 | break; | 886 | continue; |
887 | } | ||
888 | if (opt == ':') { | ||
889 | goto print_usage_message; | ||
890 | } | ||
937 | #endif | 891 | #endif |
892 | { | ||
893 | unsigned int flags; | ||
894 | const char *p = strchr(ls_opts, opt); | ||
895 | if (!p) { /* shouldn't be necessary */ | ||
896 | goto print_usage_message; | ||
897 | } | ||
898 | flags = opt_flags[(int)(p - ls_opts)]; | ||
899 | if (flags & LIST_MASK_TRIGGER) { | ||
900 | all_fmt &= ~LIST_MASK; | ||
901 | } | ||
902 | if (flags & STYLE_MASK_TRIGGER) { | ||
903 | all_fmt &= ~STYLE_MASK; | ||
904 | } | ||
905 | if (flags & SORT_MASK_TRIGGER) { | ||
906 | all_fmt &= ~SORT_MASK; | ||
907 | } | ||
908 | if (flags & DISP_MASK_TRIGGER) { | ||
909 | all_fmt &= ~DISP_MASK; | ||
910 | } | ||
911 | if (flags & TIME_MASK_TRIGGER) { | ||
912 | all_fmt &= ~TIME_MASK; | ||
913 | } | ||
938 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 914 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
939 | case 'h': | 915 | if (opt == 'l') { |
940 | ls_disp_hr = TRUE; | 916 | all_fmt &= ~LS_DISP_HR; |
941 | break; | 917 | } |
942 | #endif | 918 | #endif |
943 | case 'k': | 919 | all_fmt |= flags; |
944 | break; | ||
945 | default: | ||
946 | goto print_usage_message; | ||
947 | } | 920 | } |
948 | } | 921 | } |
949 | 922 | ||
923 | |||
950 | /* sort out which command line options take precedence */ | 924 | /* sort out which command line options take precedence */ |
951 | #ifdef CONFIG_FEATURE_LS_RECURSIVE | 925 | #ifdef CONFIG_FEATURE_LS_RECURSIVE |
952 | if (disp_opts & DISP_NOLIST) | 926 | if (all_fmt & DISP_NOLIST) |
953 | disp_opts &= ~DISP_RECURSIVE; /* no recurse if listing only dir */ | 927 | all_fmt &= ~DISP_RECURSIVE; /* no recurse if listing only dir */ |
954 | #endif | 928 | #endif |
955 | #if defined (CONFIG_FEATURE_LS_TIMESTAMPS) && defined (CONFIG_FEATURE_LS_SORTFILES) | 929 | #if defined (CONFIG_FEATURE_LS_TIMESTAMPS) && defined (CONFIG_FEATURE_LS_SORTFILES) |
956 | if (time_fmt & TIME_CHANGE) | 930 | if (all_fmt & TIME_CHANGE) |
957 | sort_opts = SORT_CTIME; | 931 | all_fmt = (all_fmt & ~SORT_MASK) | SORT_CTIME; |
958 | if (time_fmt & TIME_ACCESS) | 932 | if (all_fmt & TIME_ACCESS) |
959 | sort_opts = SORT_ATIME; | 933 | all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME; |
960 | #endif | 934 | #endif |
961 | if (style_fmt != STYLE_LONG) /* only for long list */ | 935 | if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */ |
962 | list_fmt &= ~(LIST_ID_NUMERIC|LIST_FULLTIME|LIST_ID_NAME|LIST_ID_NUMERIC); | 936 | all_fmt &= ~(LIST_ID_NUMERIC|LIST_FULLTIME|LIST_ID_NAME|LIST_ID_NUMERIC); |
963 | #ifdef CONFIG_FEATURE_LS_USERNAME | 937 | #ifdef CONFIG_FEATURE_LS_USERNAME |
964 | if (style_fmt == STYLE_LONG && (list_fmt & LIST_ID_NUMERIC)) | 938 | if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC)) |
965 | list_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */ | 939 | all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */ |
966 | #endif | 940 | #endif |
967 | 941 | ||
968 | /* choose a display format */ | 942 | /* choose a display format */ |
969 | if (style_fmt == STYLE_AUTO) | 943 | if ((all_fmt & STYLE_MASK) == STYLE_AUTO) |
970 | style_fmt = isatty(fileno(stdout)) ? STYLE_COLUMNS : STYLE_SINGLE; | 944 | #if STYLE_AUTO != 0 |
945 | all_fmt = (all_fmt & ~STYLE_MASK) | ||
946 | | (isatty(fileno(stdout)) ? STYLE_COLUMNS : STYLE_SINGLE); | ||
947 | #else | ||
948 | all_fmt |= (isatty(fileno(stdout)) ? STYLE_COLUMNS : STYLE_SINGLE); | ||
949 | #endif | ||
971 | 950 | ||
972 | /* | 951 | /* |
973 | * when there are no cmd line args we have to supply a default "." arg. | 952 | * when there are no cmd line args we have to supply a default "." arg. |
@@ -979,7 +958,7 @@ extern int ls_main(int argc, char **argv) | |||
979 | ac = argc - optind; /* how many cmd line args are left */ | 958 | ac = argc - optind; /* how many cmd line args are left */ |
980 | if (ac < 1) { | 959 | if (ac < 1) { |
981 | av = (char **) xcalloc((size_t) 1, (size_t) (sizeof(char *))); | 960 | av = (char **) xcalloc((size_t) 1, (size_t) (sizeof(char *))); |
982 | av[0] = xstrdup("."); | 961 | av[0] = bb_xstrdup("."); |
983 | ac = 1; | 962 | ac = 1; |
984 | } else { | 963 | } else { |
985 | av = (char **) xcalloc((size_t) ac, (size_t) (sizeof(char *))); | 964 | av = (char **) xcalloc((size_t) ac, (size_t) (sizeof(char *))); |
@@ -990,12 +969,12 @@ extern int ls_main(int argc, char **argv) | |||
990 | 969 | ||
991 | /* now, everything is in the av array */ | 970 | /* now, everything is in the av array */ |
992 | if (ac > 1) | 971 | if (ac > 1) |
993 | disp_opts |= DISP_DIRNAME; /* 2 or more items? label directories */ | 972 | all_fmt |= DISP_DIRNAME; /* 2 or more items? label directories */ |
994 | 973 | ||
995 | /* stuff the command line file names into an dnode array */ | 974 | /* stuff the command line file names into an dnode array */ |
996 | dn = NULL; | 975 | dn = NULL; |
997 | for (oi = 0; oi < ac; oi++) { | 976 | for (oi = 0; oi < ac; oi++) { |
998 | char *fullname = xstrdup(av[oi]); | 977 | char *fullname = bb_xstrdup(av[oi]); |
999 | 978 | ||
1000 | cur = my_stat(fullname, fullname); | 979 | cur = my_stat(fullname, fullname); |
1001 | if (!cur) | 980 | if (!cur) |
@@ -1015,7 +994,7 @@ extern int ls_main(int argc, char **argv) | |||
1015 | } | 994 | } |
1016 | 995 | ||
1017 | 996 | ||
1018 | if (disp_opts & DISP_NOLIST) { | 997 | if (all_fmt & DISP_NOLIST) { |
1019 | #ifdef CONFIG_FEATURE_LS_SORTFILES | 998 | #ifdef CONFIG_FEATURE_LS_SORTFILES |
1020 | shellsort(dnp, nfiles); | 999 | shellsort(dnp, nfiles); |
1021 | #endif | 1000 | #endif |
@@ -1042,5 +1021,5 @@ extern int ls_main(int argc, char **argv) | |||
1042 | return (status); | 1021 | return (status); |
1043 | 1022 | ||
1044 | print_usage_message: | 1023 | print_usage_message: |
1045 | show_usage(); | 1024 | bb_show_usage(); |
1046 | } | 1025 | } |
diff --git a/coreutils/md5sum.c b/coreutils/md5sum.c index f5be4486c..c1480cd32 100644 --- a/coreutils/md5sum.c +++ b/coreutils/md5sum.c | |||
@@ -770,13 +770,13 @@ static int md5_file(const char *filename, | |||
770 | have_read_stdin = 1; | 770 | have_read_stdin = 1; |
771 | fp = stdin; | 771 | fp = stdin; |
772 | } else { | 772 | } else { |
773 | fp = wfopen(filename, "r"); | 773 | fp = bb_wfopen(filename, "r"); |
774 | if (fp == NULL) | 774 | if (fp == NULL) |
775 | return FALSE; | 775 | return FALSE; |
776 | } | 776 | } |
777 | 777 | ||
778 | if (md5_stream(fp, md5_result)) { | 778 | if (md5_stream(fp, md5_result)) { |
779 | perror_msg("%s", filename); | 779 | bb_perror_msg("%s", filename); |
780 | 780 | ||
781 | if (fp != stdin) | 781 | if (fp != stdin) |
782 | fclose(fp); | 782 | fclose(fp); |
@@ -784,7 +784,7 @@ static int md5_file(const char *filename, | |||
784 | } | 784 | } |
785 | 785 | ||
786 | if (fp != stdin && fclose(fp) == EOF) { | 786 | if (fp != stdin && fclose(fp) == EOF) { |
787 | perror_msg("%s", filename); | 787 | bb_perror_msg("%s", filename); |
788 | return FALSE; | 788 | return FALSE; |
789 | } | 789 | } |
790 | 790 | ||
@@ -805,7 +805,7 @@ static int md5_check(const char *checkfile_name) | |||
805 | have_read_stdin = 1; | 805 | have_read_stdin = 1; |
806 | checkfile_stream = stdin; | 806 | checkfile_stream = stdin; |
807 | } else { | 807 | } else { |
808 | checkfile_stream = wfopen(checkfile_name, "r"); | 808 | checkfile_stream = bb_wfopen(checkfile_name, "r"); |
809 | if (checkfile_stream == NULL) | 809 | if (checkfile_stream == NULL) |
810 | return FALSE; | 810 | return FALSE; |
811 | } | 811 | } |
@@ -836,7 +836,7 @@ static int md5_check(const char *checkfile_name) | |||
836 | if (split_3(line, line_length, &md5num, &filename) | 836 | if (split_3(line, line_length, &md5num, &filename) |
837 | || !hex_digits(md5num)) { | 837 | || !hex_digits(md5num)) { |
838 | if (warn) { | 838 | if (warn) { |
839 | error_msg("%s: %lu: improperly formatted MD5 checksum line", | 839 | bb_error_msg("%s: %lu: improperly formatted MD5 checksum line", |
840 | checkfile_name, (unsigned long) line_number); | 840 | checkfile_name, (unsigned long) line_number); |
841 | } | 841 | } |
842 | } else { | 842 | } else { |
@@ -881,18 +881,18 @@ static int md5_check(const char *checkfile_name) | |||
881 | while (!feof(checkfile_stream) && !ferror(checkfile_stream)); | 881 | while (!feof(checkfile_stream) && !ferror(checkfile_stream)); |
882 | 882 | ||
883 | if (ferror(checkfile_stream)) { | 883 | if (ferror(checkfile_stream)) { |
884 | error_msg("%s: read error", checkfile_name); | 884 | bb_error_msg("%s: read error", checkfile_name); |
885 | return FALSE; | 885 | return FALSE; |
886 | } | 886 | } |
887 | 887 | ||
888 | if (checkfile_stream != stdin && fclose(checkfile_stream) == EOF) { | 888 | if (checkfile_stream != stdin && fclose(checkfile_stream) == EOF) { |
889 | perror_msg("md5sum: %s", checkfile_name); | 889 | bb_perror_msg("md5sum: %s", checkfile_name); |
890 | return FALSE; | 890 | return FALSE; |
891 | } | 891 | } |
892 | 892 | ||
893 | if (n_properly_formated_lines == 0) { | 893 | if (n_properly_formated_lines == 0) { |
894 | /* Warn if no tests are found. */ | 894 | /* Warn if no tests are found. */ |
895 | error_msg("%s: no properly formatted MD5 checksum lines found", | 895 | bb_error_msg("%s: no properly formatted MD5 checksum lines found", |
896 | checkfile_name); | 896 | checkfile_name); |
897 | return FALSE; | 897 | return FALSE; |
898 | } else { | 898 | } else { |
@@ -901,13 +901,13 @@ static int md5_check(const char *checkfile_name) | |||
901 | - n_open_or_read_failures); | 901 | - n_open_or_read_failures); |
902 | 902 | ||
903 | if (n_open_or_read_failures > 0) { | 903 | if (n_open_or_read_failures > 0) { |
904 | error_msg("WARNING: %d of %d listed files could not be read", | 904 | bb_error_msg("WARNING: %d of %d listed files could not be read", |
905 | n_open_or_read_failures, n_properly_formated_lines); | 905 | n_open_or_read_failures, n_properly_formated_lines); |
906 | return FALSE; | 906 | return FALSE; |
907 | } | 907 | } |
908 | 908 | ||
909 | if (n_mismatched_checksums > 0) { | 909 | if (n_mismatched_checksums > 0) { |
910 | error_msg("WARNING: %d of %d computed checksums did NOT match", | 910 | bb_error_msg("WARNING: %d of %d computed checksums did NOT match", |
911 | n_mismatched_checksums, n_computed_checkums); | 911 | n_mismatched_checksums, n_computed_checkums); |
912 | return FALSE; | 912 | return FALSE; |
913 | } | 913 | } |
@@ -965,31 +965,31 @@ int md5sum_main(int argc, | |||
965 | break; | 965 | break; |
966 | 966 | ||
967 | default: | 967 | default: |
968 | show_usage(); | 968 | bb_show_usage(); |
969 | } | 969 | } |
970 | } | 970 | } |
971 | 971 | ||
972 | if (file_type_specified && do_check) { | 972 | if (file_type_specified && do_check) { |
973 | error_msg_and_die("the -b and -t options are meaningless when verifying checksums"); | 973 | bb_error_msg_and_die("the -b and -t options are meaningless when verifying checksums"); |
974 | } | 974 | } |
975 | 975 | ||
976 | if (n_strings > 0 && do_check) { | 976 | if (n_strings > 0 && do_check) { |
977 | error_msg_and_die("the -g and -c options are mutually exclusive"); | 977 | bb_error_msg_and_die("the -g and -c options are mutually exclusive"); |
978 | } | 978 | } |
979 | 979 | ||
980 | if (status_only && !do_check) { | 980 | if (status_only && !do_check) { |
981 | error_msg_and_die("the -s option is meaningful only when verifying checksums"); | 981 | bb_error_msg_and_die("the -s option is meaningful only when verifying checksums"); |
982 | } | 982 | } |
983 | 983 | ||
984 | if (warn && !do_check) { | 984 | if (warn && !do_check) { |
985 | error_msg_and_die("the -w option is meaningful only when verifying checksums"); | 985 | bb_error_msg_and_die("the -w option is meaningful only when verifying checksums"); |
986 | } | 986 | } |
987 | 987 | ||
988 | if (n_strings > 0) { | 988 | if (n_strings > 0) { |
989 | size_t i; | 989 | size_t i; |
990 | 990 | ||
991 | if (optind < argc) { | 991 | if (optind < argc) { |
992 | error_msg_and_die("no files may be specified when using -g"); | 992 | bb_error_msg_and_die("no files may be specified when using -g"); |
993 | } | 993 | } |
994 | for (i = 0; i < n_strings; ++i) { | 994 | for (i = 0; i < n_strings; ++i) { |
995 | size_t cnt; | 995 | size_t cnt; |
@@ -1002,7 +1002,7 @@ int md5sum_main(int argc, | |||
1002 | } | 1002 | } |
1003 | } else if (do_check) { | 1003 | } else if (do_check) { |
1004 | if (optind + 1 < argc) { | 1004 | if (optind + 1 < argc) { |
1005 | error_msg("only one argument may be specified when using -c"); | 1005 | bb_error_msg("only one argument may be specified when using -c"); |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | err = md5_check ((optind == argc) ? "-" : argv[optind]); | 1008 | err = md5_check ((optind == argc) ? "-" : argv[optind]); |
@@ -1060,11 +1060,11 @@ int md5sum_main(int argc, | |||
1060 | } | 1060 | } |
1061 | 1061 | ||
1062 | if (fclose (stdout) == EOF) { | 1062 | if (fclose (stdout) == EOF) { |
1063 | error_msg_and_die("write error"); | 1063 | bb_error_msg_and_die("write error"); |
1064 | } | 1064 | } |
1065 | 1065 | ||
1066 | if (have_read_stdin && fclose (stdin) == EOF) { | 1066 | if (have_read_stdin && fclose (stdin) == EOF) { |
1067 | error_msg_and_die("standard input"); | 1067 | bb_error_msg_and_die(bb_msg_standard_input); |
1068 | } | 1068 | } |
1069 | 1069 | ||
1070 | if (err == 0) | 1070 | if (err == 0) |
diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c index f003db99f..b018ac181 100644 --- a/coreutils/mkdir.c +++ b/coreutils/mkdir.c | |||
@@ -20,46 +20,50 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <errno.h> | 23 | /* BB_AUDIT SUSv3 compliant */ |
24 | #include <getopt.h> | 24 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/mkdir.html */ |
25 | #include <sys/stat.h> | 25 | |
26 | #include <sys/types.h> | 26 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) |
27 | #include <fcntl.h> | 27 | * |
28 | #include <unistd.h> | 28 | * Fixed broken permission setting when -p was used; especially in |
29 | #include <stdlib.h> | 29 | * conjunction with -m. |
30 | #include <string.h> | 30 | */ |
31 | 31 | ||
32 | #include <stdlib.h> | ||
33 | #include <unistd.h> | ||
32 | #include "busybox.h" | 34 | #include "busybox.h" |
33 | 35 | ||
34 | extern int mkdir_main (int argc, char **argv) | 36 | extern int mkdir_main (int argc, char **argv) |
35 | { | 37 | { |
36 | mode_t mode = -1; | 38 | mode_t mode = (mode_t)(-1); |
39 | int status = EXIT_SUCCESS; | ||
37 | int flags = 0; | 40 | int flags = 0; |
38 | int i, opt; | 41 | int opt; |
39 | 42 | ||
40 | while ((opt = getopt (argc, argv, "m:p")) != -1) { | 43 | while ((opt = getopt (argc, argv, "m:p")) > 0) { |
41 | switch (opt) { | 44 | if (opt == 'm') { |
42 | case 'm': | ||
43 | mode = 0777; | 45 | mode = 0777; |
44 | if (!parse_mode (optarg, &mode)) { | 46 | if (!bb_parse_mode (optarg, &mode)) { |
45 | error_msg_and_die ("invalid mode `%s'", optarg); | 47 | bb_error_msg_and_die ("invalid mode `%s'", optarg); |
46 | } | 48 | } |
47 | umask(0); | 49 | } else if (opt == 'p') { |
48 | break; | ||
49 | case 'p': | ||
50 | flags |= FILEUTILS_RECUR; | 50 | flags |= FILEUTILS_RECUR; |
51 | break; | 51 | } else { |
52 | default: | 52 | bb_show_usage(); |
53 | show_usage (); | ||
54 | } | 53 | } |
55 | } | 54 | } |
56 | 55 | ||
57 | if (optind == argc) | 56 | if (optind == argc) { |
58 | show_usage (); | 57 | bb_show_usage(); |
59 | |||
60 | for (i = optind; i < argc; i++) { | ||
61 | make_directory (argv[i], mode, flags); | ||
62 | } | 58 | } |
63 | 59 | ||
64 | return(EXIT_SUCCESS); | 60 | argv += optind; |
61 | |||
62 | do { | ||
63 | if (bb_make_directory(*argv, mode, flags)) { | ||
64 | status = EXIT_FAILURE; | ||
65 | } | ||
66 | } while (*++argv); | ||
67 | |||
68 | return status; | ||
65 | } | 69 | } |
diff --git a/coreutils/mkfifo.c b/coreutils/mkfifo.c index ca217fa23..77e0e6dd8 100644 --- a/coreutils/mkfifo.c +++ b/coreutils/mkfifo.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini mkfifo implementation for busybox | 3 | * mkfifo implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -20,41 +20,32 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <stdio.h> | 23 | /* BB_AUDIT SUSv3 compliant */ |
24 | #include <sys/types.h> | 24 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/mkfifo.html */ |
25 | #include <errno.h> | 25 | |
26 | #include <stdlib.h> | 26 | #include <stdlib.h> |
27 | #include <unistd.h> | ||
28 | #include <sys/types.h> | ||
27 | #include "busybox.h" | 29 | #include "busybox.h" |
30 | #include "libcoreutils/coreutils.h" | ||
28 | 31 | ||
29 | extern int mkfifo_main(int argc, char **argv) | 32 | extern int mkfifo_main(int argc, char **argv) |
30 | { | 33 | { |
31 | char *thisarg; | 34 | mode_t mode; |
32 | mode_t mode = 0666; | 35 | int retval = EXIT_SUCCESS; |
33 | 36 | ||
34 | argc--; | 37 | mode = getopt_mk_fifo_nod(argc, argv); |
35 | argv++; | ||
36 | 38 | ||
37 | /* Parse any options */ | 39 | if (!*(argv += optind)) { |
38 | while (argc > 1) { | 40 | bb_show_usage(); |
39 | if (**argv != '-') | ||
40 | show_usage(); | ||
41 | thisarg = *argv; | ||
42 | thisarg++; | ||
43 | switch (*thisarg) { | ||
44 | case 'm': | ||
45 | argc--; | ||
46 | argv++; | ||
47 | parse_mode(*argv, &mode); | ||
48 | break; | ||
49 | default: | ||
50 | show_usage(); | ||
51 | } | ||
52 | argc--; | ||
53 | argv++; | ||
54 | } | 41 | } |
55 | if (argc < 1 || *argv[0] == '-') | 42 | |
56 | show_usage(); | 43 | do { |
57 | if (mkfifo(*argv, mode) < 0) | 44 | if (mkfifo(*argv, mode) < 0) { |
58 | perror_msg_and_die("mkfifo"); | 45 | bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ |
59 | return EXIT_SUCCESS; | 46 | retval = EXIT_FAILURE; |
47 | } | ||
48 | } while (*++argv); | ||
49 | |||
50 | return retval; | ||
60 | } | 51 | } |
diff --git a/coreutils/mknod.c b/coreutils/mknod.c index 432ec2b25..59294e9cb 100644 --- a/coreutils/mknod.c +++ b/coreutils/mknod.c | |||
@@ -1,9 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini mknod implementation for busybox | 3 | * mknod implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * Copyright (C) 1999-2002 by Erik Andersen <andersee@debian.org> | ||
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -21,73 +20,44 @@ | |||
21 | * | 20 | * |
22 | */ | 21 | */ |
23 | 22 | ||
24 | #include <stdio.h> | 23 | /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ |
25 | #include <errno.h> | 24 | |
26 | #include <fcntl.h> | ||
27 | #include <unistd.h> | ||
28 | #include <string.h> | ||
29 | #include <stdlib.h> | 25 | #include <stdlib.h> |
30 | #include <sys/types.h> | 26 | #include <string.h> |
31 | #include <sys/stat.h> | 27 | #include <sys/stat.h> |
28 | #include <unistd.h> | ||
32 | #include "busybox.h" | 29 | #include "busybox.h" |
30 | #include "libcoreutils/coreutils.h" | ||
31 | |||
32 | static const char modes_chars[] = { 'p', 'c', 'u', 'b', 0, 1, 1, 2 }; | ||
33 | static const mode_t modes_cubp[] = { S_IFIFO, S_IFCHR, S_IFBLK }; | ||
33 | 34 | ||
34 | int mknod_main(int argc, char **argv) | 35 | extern int mknod_main(int argc, char **argv) |
35 | { | 36 | { |
36 | char *thisarg; | 37 | mode_t mode; |
37 | mode_t mode = 0; | 38 | dev_t dev; |
38 | mode_t perm = 0666; | 39 | const char *name; |
39 | dev_t dev = (dev_t) 0; | 40 | |
41 | mode = getopt_mk_fifo_nod(argc, argv); | ||
42 | argv += optind; | ||
43 | argc -= optind; | ||
40 | 44 | ||
41 | argc--; | 45 | if ((argc >= 2) && ((name = strchr(modes_chars, argv[1][0])) != NULL)) { |
42 | argv++; | 46 | mode |= modes_cubp[(int)(name[4])]; |
43 | 47 | ||
44 | /* Parse any options */ | 48 | dev = 0; |
45 | while (argc > 1) { | 49 | if ((*name != 'p') && ((argc -= 2) == 0)) { |
46 | if (**argv != '-') | 50 | dev = (bb_xgetularg10_bnd(argv[2], 0, 255) << 8) |
47 | break; | 51 | + bb_xgetularg10_bnd(argv[3], 0, 255); |
48 | thisarg = *argv; | ||
49 | thisarg++; | ||
50 | switch (*thisarg) { | ||
51 | case 'm': | ||
52 | argc--; | ||
53 | argv++; | ||
54 | parse_mode(*argv, &perm); | ||
55 | umask(0); | ||
56 | break; | ||
57 | default: | ||
58 | show_usage(); | ||
59 | } | 52 | } |
60 | argc--; | 53 | |
61 | argv++; | 54 | if (argc == 2) { |
62 | } | 55 | name = *argv; |
63 | if (argc != 4 && argc != 2) { | 56 | if (mknod(name, mode, dev) == 0) { |
64 | show_usage(); | 57 | return EXIT_SUCCESS; |
65 | } | 58 | } |
66 | switch (argv[1][0]) { | 59 | bb_perror_msg_and_die("%s", name); |
67 | case 'c': | ||
68 | case 'u': | ||
69 | mode = S_IFCHR; | ||
70 | break; | ||
71 | case 'b': | ||
72 | mode = S_IFBLK; | ||
73 | break; | ||
74 | case 'p': | ||
75 | mode = S_IFIFO; | ||
76 | if (argc != 2) { | ||
77 | show_usage(); | ||
78 | } | 60 | } |
79 | break; | ||
80 | default: | ||
81 | show_usage(); | ||
82 | } | ||
83 | |||
84 | if (mode == S_IFCHR || mode == S_IFBLK) { | ||
85 | dev = (dev_t) ((atoi(argv[2]) << 8) | atoi(argv[3])); | ||
86 | } | 61 | } |
87 | 62 | bb_show_usage(); | |
88 | mode |= perm; | ||
89 | |||
90 | if (mknod(argv[0], mode, dev) != 0) | ||
91 | perror_msg_and_die("%s", argv[0]); | ||
92 | return EXIT_SUCCESS; | ||
93 | } | 63 | } |
diff --git a/coreutils/mv.c b/coreutils/mv.c index 1c4a34788..ae0ee92e4 100644 --- a/coreutils/mv.c +++ b/coreutils/mv.c | |||
@@ -2,7 +2,6 @@ | |||
2 | /* | 2 | /* |
3 | * Mini mv implementation for busybox | 3 | * Mini mv implementation for busybox |
4 | * | 4 | * |
5 | * | ||
6 | * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> | 5 | * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> |
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -21,148 +20,122 @@ | |||
21 | * | 20 | * |
22 | */ | 21 | */ |
23 | 22 | ||
23 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
24 | * | ||
25 | * Size reduction and improved error checking. | ||
26 | */ | ||
27 | |||
24 | #include <sys/types.h> | 28 | #include <sys/types.h> |
25 | #include <sys/stat.h> | 29 | #include <sys/stat.h> |
26 | #include <unistd.h> | 30 | #include <unistd.h> |
27 | #include <dirent.h> | 31 | #include <dirent.h> |
28 | #include <errno.h> | 32 | #include <errno.h> |
29 | #include <stdlib.h> | 33 | #include <stdlib.h> |
30 | |||
31 | #include "busybox.h" | 34 | #include "busybox.h" |
35 | #include "libcoreutils/coreutils.h" | ||
32 | 36 | ||
33 | static int flags; | 37 | static const char *fmt = "cannot overwrite %sdirectory with %sdirectory"; |
34 | 38 | ||
35 | static int manual_rename(const char *source, const char *dest) | 39 | extern int mv_main(int argc, char **argv) |
36 | { | 40 | { |
37 | struct stat source_stat; | 41 | struct stat source_stat; |
38 | struct stat dest_stat; | 42 | struct stat dest_stat; |
39 | int source_exists = 1; | 43 | const char *last; |
40 | int dest_exists = 1; | 44 | const char *dest; |
45 | int dest_exists; | ||
46 | int source_exists; | ||
47 | int opt; | ||
48 | int flags = 0; | ||
49 | int status = 0; | ||
41 | 50 | ||
42 | if (stat(source, &source_stat) < 0) { | 51 | while ((opt = getopt(argc, argv, "fi")) > 0) { |
43 | if (errno != ENOENT) { | 52 | flags &= ~(FILEUTILS_INTERACTIVE | FILEUTILS_FORCE); |
44 | perror_msg("unable to stat `%s'", source); | 53 | if (opt == 'i') { |
45 | return -1; | 54 | flags |= FILEUTILS_INTERACTIVE; |
55 | } else if (opt == 'f') { | ||
56 | flags |= FILEUTILS_FORCE; | ||
57 | } else { | ||
58 | bb_show_usage(); | ||
46 | } | 59 | } |
47 | source_exists = 0; | ||
48 | } | 60 | } |
49 | 61 | ||
50 | if (stat(dest, &dest_stat) < 0) { | 62 | if (optind + 2 > argc) |
51 | if (errno != ENOENT) { | 63 | bb_show_usage(); |
52 | perror_msg("unable to stat `%s'", dest); | ||
53 | return -1; | ||
54 | } | ||
55 | dest_exists = 0; | ||
56 | } | ||
57 | 64 | ||
58 | if (dest_exists) { | 65 | last = argv[argc - 1]; |
59 | if (S_ISDIR(dest_stat.st_mode) && | 66 | argv += optind; |
60 | (!source_exists || !S_ISDIR(source_stat.st_mode))) { | ||
61 | error_msg("cannot overwrite directory with non-directory"); | ||
62 | return -1; | ||
63 | } | ||
64 | 67 | ||
65 | if (!S_ISDIR(dest_stat.st_mode) && source_exists && | 68 | if (optind + 2 == argc) { |
66 | S_ISDIR(source_stat.st_mode)) { | 69 | if ((dest_exists = cp_mv_stat(last, &dest_stat)) < 0) { |
67 | error_msg("cannot overwrite non-directory with directory"); | 70 | return 1; |
68 | return -1; | ||
69 | } | 71 | } |
70 | 72 | ||
71 | if (unlink(dest) < 0) { | 73 | if (!(dest_exists & 2)) { |
72 | perror_msg("cannot remove `%s'", dest); | 74 | dest = last; |
73 | return -1; | 75 | goto DO_MOVE; |
74 | } | 76 | } |
75 | } | 77 | } |
78 | |||
79 | do { | ||
80 | dest = concat_path_file(last, | ||
81 | bb_get_last_path_component(*argv)); | ||
76 | 82 | ||
77 | if (copy_file(source, dest, | 83 | if ((dest_exists = cp_mv_stat(dest, &dest_stat)) < 0) { |
78 | FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS) < 0) | 84 | goto RET_1; |
79 | return -1; | ||
80 | |||
81 | if (remove_file(source, FILEUTILS_RECUR | FILEUTILS_FORCE) < 0) | ||
82 | return -1; | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int move_file(const char *source, const char *dest) | ||
88 | { | ||
89 | struct stat dest_stat; | ||
90 | int dest_exists = 1; | ||
91 | |||
92 | if (stat(dest, &dest_stat) < 0) { | ||
93 | if (errno != ENOENT) { | ||
94 | perror_msg("unable to stat `%s'", dest); | ||
95 | return -1; | ||
96 | } | 85 | } |
97 | dest_exists = 0; | ||
98 | } | ||
99 | 86 | ||
100 | if (dest_exists && !(flags & FILEUTILS_FORCE) && | 87 | DO_MOVE: |
88 | |||
89 | if (dest_exists && !(flags & FILEUTILS_FORCE) && | ||
101 | ((access(dest, W_OK) < 0 && isatty(0)) || | 90 | ((access(dest, W_OK) < 0 && isatty(0)) || |
102 | (flags & FILEUTILS_INTERACTIVE))) { | 91 | (flags & FILEUTILS_INTERACTIVE))) { |
103 | fprintf(stderr, "mv: overwrite `%s'? ", dest); | 92 | if (fprintf(stderr, "mv: overwrite `%s'? ", dest) < 0) { |
104 | if (!ask_confirmation()) | 93 | goto RET_1; /* Ouch! fprintf failed! */ |
105 | return 0; | 94 | } |
106 | } | 95 | if (!bb_ask_confirmation()) |
107 | 96 | goto RET_0; | |
108 | if (rename(source, dest) < 0) { | 97 | } |
109 | if (errno == EXDEV) | 98 | |
110 | return manual_rename(source, dest); | 99 | if (rename(*argv, dest) < 0) { |
111 | 100 | if (errno != EXDEV) { | |
112 | perror_msg("unable to rename `%s'", source); | 101 | bb_perror_msg("unable to rename `%s'", *argv); |
113 | return -1; | 102 | } else if ((source_exists = cp_mv_stat(*argv, &source_stat)) >= 0) { |
114 | } | 103 | if (dest_exists) { |
115 | 104 | if (dest_exists & 2) { | |
116 | return 0; | 105 | if (!(source_exists & 2)) { |
117 | } | 106 | bb_error_msg(fmt, "", "non-"); |
118 | 107 | goto RET_1; | |
119 | extern int mv_main(int argc, char **argv) | 108 | } |
120 | { | 109 | } else { |
121 | int status = 0; | 110 | if (source_exists & 2) { |
122 | int opt; | 111 | bb_error_msg(fmt, "non-", ""); |
123 | int i; | 112 | goto RET_1; |
124 | 113 | } | |
125 | while ((opt = getopt(argc, argv, "fi")) != -1) | 114 | } |
126 | switch (opt) { | 115 | if (unlink(dest) < 0) { |
127 | case 'f': | 116 | bb_perror_msg("cannot remove `%s'", dest); |
128 | flags &= ~FILEUTILS_INTERACTIVE; | 117 | goto RET_1; |
129 | flags |= FILEUTILS_FORCE; | 118 | } |
130 | break; | 119 | } |
131 | case 'i': | 120 | |
132 | flags &= ~FILEUTILS_FORCE; | 121 | if ((copy_file(*argv, dest, |
133 | flags |= FILEUTILS_INTERACTIVE; | 122 | FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS) >= 0) |
134 | break; | 123 | && (remove_file(*argv, FILEUTILS_RECUR | FILEUTILS_FORCE) >= 0) |
135 | default: | 124 | ) { |
136 | show_usage(); | 125 | goto RET_0; |
137 | } | 126 | } |
138 | 127 | ||
139 | if (optind + 2 > argc) | 128 | } |
140 | show_usage(); | 129 | RET_1: |
141 | 130 | status = 1; | |
142 | if (optind + 2 == argc) { | ||
143 | struct stat dest_stat; | ||
144 | int dest_exists = 1; | ||
145 | |||
146 | if (stat(argv[optind + 1], &dest_stat) < 0) { | ||
147 | if (errno != ENOENT) | ||
148 | perror_msg_and_die("unable to stat `%s'", argv[optind + 1]); | ||
149 | dest_exists = 0; | ||
150 | } | 131 | } |
151 | 132 | ||
152 | if (!dest_exists || !S_ISDIR(dest_stat.st_mode)) { | 133 | RET_0: |
153 | if (move_file(argv[optind], argv[optind + 1]) < 0) | 134 | if (dest != last) { |
154 | status = 1; | 135 | free((void *) dest); |
155 | return status; | ||
156 | } | 136 | } |
157 | } | 137 | |
158 | 138 | } while (*++argv != last); | |
159 | for (i = optind; i < argc - 1; i++) { | 139 | |
160 | char *dest = concat_path_file(argv[argc - 1], | 140 | exit(status); |
161 | get_last_path_component(argv[i])); | ||
162 | if (move_file(argv[i], dest) < 0) | ||
163 | status = 1; | ||
164 | free(dest); | ||
165 | } | ||
166 | |||
167 | return status; | ||
168 | } | 141 | } |
diff --git a/coreutils/od.c b/coreutils/od.c index 6187cadf2..5eaaf5024 100644 --- a/coreutils/od.c +++ b/coreutils/od.c | |||
@@ -23,22 +23,18 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <ctype.h> | 25 | #include <ctype.h> |
26 | #include <string.h> | ||
26 | #include <getopt.h> | 27 | #include <getopt.h> |
27 | #include <stdlib.h> | 28 | #include <stdlib.h> |
28 | #include "dump.h" | ||
29 | #include "busybox.h" | 29 | #include "busybox.h" |
30 | #include "dump.h" | ||
30 | 31 | ||
31 | extern FS *fshead; /* head of format strings */ | 32 | #define isdecdigit(c) (isdigit)(c) |
32 | extern int blocksize; /* data block size */ | 33 | #define ishexdigit(c) (isxdigit)(c) |
33 | extern int length; /* max bytes to read */ | ||
34 | |||
35 | #define ishexdigit(c) \ | ||
36 | ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) | ||
37 | 34 | ||
38 | static void | 35 | static void |
39 | odoffset(int argc, char ***argvp) | 36 | odoffset(int argc, char ***argvp) |
40 | { | 37 | { |
41 | extern off_t skip; | ||
42 | register char *num, *p; | 38 | register char *num, *p; |
43 | int base; | 39 | int base; |
44 | char *end; | 40 | char *end; |
@@ -62,13 +58,15 @@ odoffset(int argc, char ***argvp) | |||
62 | return; | 58 | return; |
63 | } | 59 | } |
64 | 60 | ||
65 | if (*p != '+' && (argc < 2 || | 61 | if ((*p != '+') |
66 | (!isdigit(p[0]) && (p[0] != 'x' || !ishexdigit(p[1]))))) | 62 | && (argc < 2 |
63 | || (!isdecdigit(p[0]) | ||
64 | && ((p[0] != 'x') || !ishexdigit(p[1]))))) | ||
67 | return; | 65 | return; |
68 | 66 | ||
69 | base = 0; | 67 | base = 0; |
70 | /* | 68 | /* |
71 | * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and | 69 | * bb_dump_skip over leading '+', 'x[0-9a-fA-f]' or '0x', and |
72 | * set base. | 70 | * set base. |
73 | */ | 71 | */ |
74 | if (p[0] == '+') | 72 | if (p[0] == '+') |
@@ -81,11 +79,11 @@ odoffset(int argc, char ***argvp) | |||
81 | base = 16; | 79 | base = 16; |
82 | } | 80 | } |
83 | 81 | ||
84 | /* skip over the number */ | 82 | /* bb_dump_skip over the number */ |
85 | if (base == 16) | 83 | if (base == 16) |
86 | for (num = p; ishexdigit(*p); ++p); | 84 | for (num = p; ishexdigit(*p); ++p); |
87 | else | 85 | else |
88 | for (num = p; isdigit(*p); ++p); | 86 | for (num = p; isdecdigit(*p); ++p); |
89 | 87 | ||
90 | /* check for no number */ | 88 | /* check for no number */ |
91 | if (num == p) | 89 | if (num == p) |
@@ -98,21 +96,23 @@ odoffset(int argc, char ***argvp) | |||
98 | base = 10; | 96 | base = 10; |
99 | } | 97 | } |
100 | 98 | ||
101 | skip = strtol(num, &end, base ? base : 8); | 99 | bb_dump_skip = strtol(num, &end, base ? base : 8); |
102 | 100 | ||
103 | /* if end isn't the same as p, we got a non-octal digit */ | 101 | /* if end isn't the same as p, we got a non-octal digit */ |
104 | if (end != p) | 102 | if (end != p) |
105 | skip = 0; | 103 | bb_dump_skip = 0; |
106 | else { | 104 | else { |
107 | if (*p) { | 105 | if (*p) { |
108 | if (*p == 'b') | 106 | if (*p == 'b') { |
109 | skip *= 512; | 107 | bb_dump_skip *= 512; |
110 | else if (*p == 'B') | 108 | ++p; |
111 | skip *= 1024; | 109 | } else if (*p == 'B') { |
112 | ++p; | 110 | bb_dump_skip *= 1024; |
111 | ++p; | ||
112 | } | ||
113 | } | 113 | } |
114 | if (*p) | 114 | if (*p) |
115 | skip = 0; | 115 | bb_dump_skip = 0; |
116 | else { | 116 | else { |
117 | ++*argvp; | 117 | ++*argvp; |
118 | /* | 118 | /* |
@@ -121,117 +121,76 @@ odoffset(int argc, char ***argvp) | |||
121 | * but it's easy. | 121 | * but it's easy. |
122 | */ | 122 | */ |
123 | #define TYPE_OFFSET 7 | 123 | #define TYPE_OFFSET 7 |
124 | if (base == 16) { | 124 | { |
125 | fshead->nextfu->fmt[TYPE_OFFSET] = 'x'; | 125 | char x_or_d; |
126 | fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x'; | 126 | if (base == 16) { |
127 | } else if (base == 10) { | 127 | x_or_d = 'x'; |
128 | fshead->nextfu->fmt[TYPE_OFFSET] = 'd'; | 128 | goto DO_X_OR_D; |
129 | fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd'; | 129 | } |
130 | if (base == 10) { | ||
131 | x_or_d = 'd'; | ||
132 | DO_X_OR_D: | ||
133 | bb_dump_fshead->nextfu->fmt[TYPE_OFFSET] | ||
134 | = bb_dump_fshead->nextfs->nextfu->fmt[TYPE_OFFSET] | ||
135 | = x_or_d; | ||
136 | } | ||
130 | } | 137 | } |
131 | } | 138 | } |
132 | } | 139 | } |
133 | } | 140 | } |
134 | 141 | ||
135 | static void odprecede(void) | 142 | static const char * const add_strings[] = { |
136 | { | 143 | "16/1 \"%3_u \" \"\\n\"", /* a */ |
137 | static int first = 1; | 144 | "8/2 \" %06o \" \"\\n\"", /* B, o */ |
138 | 145 | "16/1 \"%03o \" \"\\n\"", /* b */ | |
139 | if (first) { | 146 | "16/1 \"%3_c \" \"\\n\"", /* c */ |
140 | first = 0; | 147 | "8/2 \" %05u \" \"\\n\"", /* d */ |
141 | add("\"%07.7_Ao\n\""); | 148 | "4/4 \" %010u \" \"\\n\"", /* D */ |
142 | add("\"%07.7_ao \""); | 149 | "2/8 \" %21.14e \" \"\\n\"", /* e (undocumented in od), F */ |
143 | } else | 150 | "4/4 \" %14.7e \" \"\\n\"", /* f */ |
144 | add("\" \""); | 151 | "4/4 \" %08x \" \"\\n\"", /* H, X */ |
145 | } | 152 | "8/2 \" %04x \" \"\\n\"", /* h, x */ |
153 | "4/4 \" %11d \" \"\\n\"", /* I, L, l */ | ||
154 | "8/2 \" %6d \" \"\\n\"", /* i */ | ||
155 | "4/4 \" %011o \" \"\\n\"", /* O */ | ||
156 | }; | ||
157 | |||
158 | static const signed char od_opts[] = "aBbcDdeFfHhIiLlOovXx"; | ||
159 | |||
160 | static const signed char od_o2si[] = { | ||
161 | 0, 1, 2, 3, 5, | ||
162 | 4, 6, 6, 7, 8, | ||
163 | 9, 0xa, 0xb, 0xa, 0xa, | ||
164 | 0xb, 1, -1, 8, 9, | ||
165 | }; | ||
146 | 166 | ||
147 | int od_main(int argc, char **argv) | 167 | int od_main(int argc, char **argv) |
148 | { | 168 | { |
149 | int ch; | 169 | int ch; |
150 | extern enum _vflag vflag; | 170 | bb_dump_vflag = FIRST; |
151 | vflag = FIRST; | 171 | bb_dump_length = -1; |
152 | length = -1; | 172 | int first = 1; |
153 | 173 | signed char *p; | |
154 | while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF) | 174 | |
155 | switch (ch) { | 175 | while ((ch = getopt(argc, argv, od_opts)) > 0) { |
156 | case 'a': | 176 | if (((p = strchr(od_opts, ch)) != NULL) && (*p >= 0)) { |
157 | odprecede(); | 177 | if (first) { |
158 | add("16/1 \"%3_u \" \"\\n\""); | 178 | first = 0; |
159 | break; | 179 | bb_dump_add("\"%07.7_Ao\n\""); |
160 | case 'B': | 180 | bb_dump_add("\"%07.7_ao \""); |
161 | case 'o': | 181 | } else { |
162 | odprecede(); | 182 | bb_dump_add("\" \""); |
163 | add("8/2 \" %06o \" \"\\n\""); | ||
164 | break; | ||
165 | case 'b': | ||
166 | odprecede(); | ||
167 | add("16/1 \"%03o \" \"\\n\""); | ||
168 | break; | ||
169 | case 'c': | ||
170 | odprecede(); | ||
171 | add("16/1 \"%3_c \" \"\\n\""); | ||
172 | break; | ||
173 | case 'd': | ||
174 | odprecede(); | ||
175 | add("8/2 \" %05u \" \"\\n\""); | ||
176 | break; | ||
177 | case 'D': | ||
178 | odprecede(); | ||
179 | add("4/4 \" %010u \" \"\\n\""); | ||
180 | break; | ||
181 | case 'e': /* undocumented in od */ | ||
182 | case 'F': | ||
183 | odprecede(); | ||
184 | add("2/8 \" %21.14e \" \"\\n\""); | ||
185 | break; | ||
186 | |||
187 | case 'f': | ||
188 | odprecede(); | ||
189 | add("4/4 \" %14.7e \" \"\\n\""); | ||
190 | break; | ||
191 | case 'H': | ||
192 | case 'X': | ||
193 | odprecede(); | ||
194 | add("4/4 \" %08x \" \"\\n\""); | ||
195 | break; | ||
196 | case 'h': | ||
197 | case 'x': | ||
198 | odprecede(); | ||
199 | add("8/2 \" %04x \" \"\\n\""); | ||
200 | break; | ||
201 | case 'I': | ||
202 | case 'L': | ||
203 | case 'l': | ||
204 | odprecede(); | ||
205 | add("4/4 \" %11d \" \"\\n\""); | ||
206 | break; | ||
207 | case 'i': | ||
208 | odprecede(); | ||
209 | add("8/2 \" %6d \" \"\\n\""); | ||
210 | break; | ||
211 | case 'O': | ||
212 | odprecede(); | ||
213 | add("4/4 \" %011o \" \"\\n\""); | ||
214 | break; | ||
215 | case 'v': | ||
216 | vflag = ALL; | ||
217 | break; | ||
218 | case 'P': | ||
219 | case 'p': | ||
220 | case 's': | ||
221 | case 'w': | ||
222 | case '?': | ||
223 | default: | ||
224 | error_msg("od: od(1) has been deprecated for hexdump(1).\n"); | ||
225 | if (ch != '?') { | ||
226 | error_msg("od: hexdump(1) compatibility doesn't support the -%c option%s\n", | ||
227 | ch, ch == 's' ? "; see strings(1)." : "."); | ||
228 | } | 183 | } |
229 | show_usage(); | 184 | bb_dump_add(add_strings[od_o2si[(int)(p-od_opts)]]); |
185 | } else if (ch == 'v') { | ||
186 | bb_dump_vflag = ALL; | ||
187 | } else { /* P, p, s, w, or other unhandled */ | ||
188 | bb_show_usage(); | ||
230 | } | 189 | } |
231 | 190 | } | |
232 | if (!fshead) { | 191 | if (!bb_dump_fshead) { |
233 | add("\"%07.7_Ao\n\""); | 192 | bb_dump_add("\"%07.7_Ao\n\""); |
234 | add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\""); | 193 | bb_dump_add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\""); |
235 | } | 194 | } |
236 | 195 | ||
237 | argc -= optind; | 196 | argc -= optind; |
@@ -239,7 +198,7 @@ int od_main(int argc, char **argv) | |||
239 | 198 | ||
240 | odoffset(argc, &argv); | 199 | odoffset(argc, &argv); |
241 | 200 | ||
242 | return(dump(argv)); | 201 | return(bb_dump_dump(argv)); |
243 | } | 202 | } |
244 | 203 | ||
245 | /*- | 204 | /*- |
diff --git a/coreutils/printf.c b/coreutils/printf.c index d579a9b4e..9602788de 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c | |||
@@ -124,7 +124,7 @@ int printf_main(int argc, char **argv) | |||
124 | 124 | ||
125 | exit_status = 0; | 125 | exit_status = 0; |
126 | if (argc <= 1 || **(argv + 1) == '-') { | 126 | if (argc <= 1 || **(argv + 1) == '-') { |
127 | show_usage(); | 127 | bb_show_usage(); |
128 | } | 128 | } |
129 | 129 | ||
130 | format = argv[1]; | 130 | format = argv[1]; |
diff --git a/coreutils/pwd.c b/coreutils/pwd.c index 9c5d70cef..7e0dc056a 100644 --- a/coreutils/pwd.c +++ b/coreutils/pwd.c | |||
@@ -20,24 +20,18 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* getopt not needed */ | ||
24 | |||
25 | #include <stdio.h> | 23 | #include <stdio.h> |
26 | #include <dirent.h> | ||
27 | #include <errno.h> | ||
28 | #include <unistd.h> | ||
29 | #include <stdlib.h> | 24 | #include <stdlib.h> |
30 | #include "busybox.h" | 25 | #include "busybox.h" |
31 | 26 | ||
32 | extern int pwd_main(int argc, char **argv) | 27 | extern int pwd_main(int argc, char **argv) |
33 | { | 28 | { |
34 | static char *buf; | 29 | char *buf; |
35 | 30 | ||
36 | buf = xgetcwd(buf); | 31 | if ((buf = xgetcwd(NULL)) != NULL) { |
37 | |||
38 | if (buf != NULL) { | ||
39 | puts(buf); | 32 | puts(buf); |
40 | return EXIT_SUCCESS; | 33 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); |
41 | } | 34 | } |
35 | |||
42 | return EXIT_FAILURE; | 36 | return EXIT_FAILURE; |
43 | } | 37 | } |
diff --git a/coreutils/realpath.c b/coreutils/realpath.c index f89e0a274..ec98221ad 100644 --- a/coreutils/realpath.c +++ b/coreutils/realpath.c | |||
@@ -14,17 +14,26 @@ | |||
14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* BB_AUDIT SUSv3 N/A -- Apparently a busybox extension. */ | ||
18 | |||
19 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
20 | * | ||
21 | * Now does proper error checking on output and returns a failure exit code | ||
22 | * if one or more paths can not be resolved. | ||
23 | */ | ||
24 | |||
17 | #include <limits.h> | 25 | #include <limits.h> |
18 | #include <stdlib.h> | 26 | #include <stdlib.h> |
19 | |||
20 | #include "busybox.h" | 27 | #include "busybox.h" |
21 | 28 | ||
22 | int realpath_main(int argc, char **argv) | 29 | int realpath_main(int argc, char **argv) |
23 | { | 30 | { |
31 | int retval = EXIT_SUCCESS; | ||
32 | |||
24 | RESERVE_CONFIG_BUFFER(resolved_path, PATH_MAX); | 33 | RESERVE_CONFIG_BUFFER(resolved_path, PATH_MAX); |
25 | 34 | ||
26 | if (--argc == 0) { | 35 | if (--argc == 0) { |
27 | show_usage(); | 36 | bb_show_usage(); |
28 | } | 37 | } |
29 | 38 | ||
30 | do { | 39 | do { |
@@ -32,11 +41,14 @@ int realpath_main(int argc, char **argv) | |||
32 | if (realpath(*argv, resolved_path) != NULL) { | 41 | if (realpath(*argv, resolved_path) != NULL) { |
33 | puts(resolved_path); | 42 | puts(resolved_path); |
34 | } else { | 43 | } else { |
35 | perror_msg("%s", *argv); | 44 | retval = EXIT_FAILURE; |
45 | bb_perror_msg("%s", *argv); | ||
36 | } | 46 | } |
37 | } while (--argc); | 47 | } while (--argc); |
38 | 48 | ||
49 | #ifdef CONFIG_FEATURE_CLEAN_UP | ||
39 | RELEASE_CONFIG_BUFFER(resolved_path); | 50 | RELEASE_CONFIG_BUFFER(resolved_path); |
51 | #endif | ||
40 | 52 | ||
41 | return(EXIT_SUCCESS); | 53 | bb_fflush_stdout_and_exit(retval); |
42 | } | 54 | } |
diff --git a/coreutils/rm.c b/coreutils/rm.c index 51c9f4ceb..5489350e5 100644 --- a/coreutils/rm.c +++ b/coreutils/rm.c | |||
@@ -2,7 +2,6 @@ | |||
2 | /* | 2 | /* |
3 | * Mini rm implementation for busybox | 3 | * Mini rm implementation for busybox |
4 | * | 4 | * |
5 | * | ||
6 | * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu> | 5 | * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu> |
7 | * | 6 | * |
8 | * | 7 | * |
@@ -22,55 +21,51 @@ | |||
22 | * | 21 | * |
23 | */ | 22 | */ |
24 | 23 | ||
25 | #include <stdio.h> | 24 | /* BB_AUDIT SUSv3 compliant */ |
26 | #include <time.h> | 25 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/rm.html */ |
27 | #include <utime.h> | 26 | |
28 | #include <dirent.h> | 27 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) |
29 | #include <errno.h> | 28 | * |
29 | * Size reduction. | ||
30 | */ | ||
31 | |||
30 | #include <unistd.h> | 32 | #include <unistd.h> |
31 | #include <stdlib.h> | ||
32 | #include <string.h> | ||
33 | #include <getopt.h> | ||
34 | #include "busybox.h" | 33 | #include "busybox.h" |
35 | 34 | ||
36 | extern int rm_main(int argc, char **argv) | 35 | extern int rm_main(int argc, char **argv) |
37 | { | 36 | { |
38 | int status = 0; | 37 | int status = 0; |
39 | int opt; | ||
40 | int flags = 0; | 38 | int flags = 0; |
41 | int i; | 39 | int opt; |
42 | 40 | ||
43 | while ((opt = getopt(argc, argv, "fiRr")) != -1) { | 41 | while ((opt = getopt(argc, argv, "fiRr")) > 0) { |
44 | switch (opt) { | 42 | if ((opt == 'r') || (opt == 'R')) { |
45 | case 'f': | ||
46 | flags &= ~FILEUTILS_INTERACTIVE; | ||
47 | flags |= FILEUTILS_FORCE; | ||
48 | break; | ||
49 | case 'i': | ||
50 | flags &= ~FILEUTILS_FORCE; | ||
51 | flags |= FILEUTILS_INTERACTIVE; | ||
52 | break; | ||
53 | case 'R': | ||
54 | case 'r': | ||
55 | flags |= FILEUTILS_RECUR; | 43 | flags |= FILEUTILS_RECUR; |
56 | break; | 44 | } else { |
45 | flags &= ~(FILEUTILS_INTERACTIVE | FILEUTILS_FORCE); | ||
46 | if (opt == 'i') { | ||
47 | flags |= FILEUTILS_INTERACTIVE; | ||
48 | } else if (opt == 'f') { | ||
49 | flags |= FILEUTILS_FORCE; | ||
50 | } else { | ||
51 | bb_show_usage(); | ||
52 | } | ||
57 | } | 53 | } |
58 | } | 54 | } |
59 | 55 | ||
60 | if (!(flags & FILEUTILS_FORCE) && optind == argc) | 56 | if (*(argv += optind) != NULL) { |
61 | show_usage(); | 57 | do { |
62 | 58 | const char *base = bb_get_last_path_component(*argv); | |
63 | for (i = optind; i < argc; i++) { | ||
64 | char *base = get_last_path_component(argv[i]); | ||
65 | |||
66 | if (strcmp(base, ".") == 0 || strcmp(base, "..") == 0) { | ||
67 | error_msg("cannot remove `.' or `..'"); | ||
68 | status = 1; | ||
69 | continue; | ||
70 | } | ||
71 | 59 | ||
72 | if (remove_file(argv[i], flags) < 0) | 60 | if ((base[0] == '.') && (!base[1] || ((base[1] == '.') && !base[2]))) { |
61 | bb_error_msg("cannot remove `.' or `..'"); | ||
62 | } else if (remove_file(*argv, flags) >= 0) { | ||
63 | continue; | ||
64 | } | ||
73 | status = 1; | 65 | status = 1; |
66 | } while (*++argv); | ||
67 | } else if (!(flags & FILEUTILS_FORCE)) { | ||
68 | bb_show_usage(); | ||
74 | } | 69 | } |
75 | 70 | ||
76 | return status; | 71 | return status; |
diff --git a/coreutils/rmdir.c b/coreutils/rmdir.c index 83b27c9bd..3f6037170 100644 --- a/coreutils/rmdir.c +++ b/coreutils/rmdir.c | |||
@@ -1,9 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini rmdir implementation for busybox | 3 | * rmdir implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1999,2000 by Lineo, inc. and Erik Andersen | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * Copyright (C) 1999,2000,2001 by Erik Andersen <andersee@debian.org> | ||
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -21,76 +20,54 @@ | |||
21 | * | 20 | * |
22 | */ | 21 | */ |
23 | 22 | ||
24 | #include <getopt.h> | 23 | /* BB_AUDIT SUSv3 compliant */ |
25 | #include <unistd.h> | 24 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */ |
26 | #include <stdlib.h> | ||
27 | 25 | ||
26 | #include <stdlib.h> | ||
27 | #include <unistd.h> | ||
28 | #include <libgen.h> | ||
28 | #include "busybox.h" | 29 | #include "busybox.h" |
29 | 30 | ||
30 | 31 | extern int rmdir_main(int argc, char **argv) | |
31 | /* Return true if a path is composed of multiple components. */ | ||
32 | |||
33 | static int | ||
34 | multiple_components_p (const char *path) | ||
35 | { | ||
36 | const char *s = path; | ||
37 | |||
38 | while (s[0] != '\0' && s[0] != '/') | ||
39 | s++; | ||
40 | |||
41 | while (s[0] == '/') | ||
42 | s++; | ||
43 | |||
44 | return (s[0] != '\0'); | ||
45 | } | ||
46 | |||
47 | |||
48 | /* Remove a directory. Returns 0 if successful, -1 on error. */ | ||
49 | |||
50 | static int | ||
51 | remove_directory (char *path, int flags) | ||
52 | { | ||
53 | if (!(flags & FILEUTILS_RECUR)) { | ||
54 | if (rmdir (path) < 0) { | ||
55 | perror_msg ("unable to remove `%s'", path); | ||
56 | return -1; | ||
57 | } | ||
58 | } else { | ||
59 | if (remove_directory (path, 0) < 0) | ||
60 | return -1; | ||
61 | |||
62 | if (multiple_components_p (path)) | ||
63 | if (remove_directory (dirname (path), flags) < 0) | ||
64 | return -1; | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | |||
71 | extern int | ||
72 | rmdir_main (int argc, char **argv) | ||
73 | { | 32 | { |
74 | int status = EXIT_SUCCESS; | 33 | int status = EXIT_SUCCESS; |
75 | int flags = 0; | 34 | int flags; |
76 | int i, opt; | 35 | int do_dot; |
36 | char *path; | ||
77 | 37 | ||
78 | while ((opt = getopt (argc, argv, "p")) != -1) | 38 | flags = bb_getopt_ulflags(argc, argv, "p"); |
79 | switch (opt) { | ||
80 | case 'p': | ||
81 | flags |= FILEUTILS_RECUR; | ||
82 | break; | ||
83 | 39 | ||
84 | default: | 40 | argv += optind; |
85 | show_usage (); | ||
86 | } | ||
87 | 41 | ||
88 | if (optind == argc) | 42 | if (!*argv) { |
89 | show_usage(); | 43 | bb_show_usage(); |
44 | } | ||
90 | 45 | ||
91 | for (i = optind; i < argc; i++) | 46 | do { |
92 | if (remove_directory (argv[i], flags) < 0) | 47 | path = *argv; |
93 | status = EXIT_FAILURE; | 48 | |
49 | /* Record if the first char was a '.' so we can use dirname later. */ | ||
50 | do_dot = (*path == '.'); | ||
51 | |||
52 | do { | ||
53 | if (rmdir(path) < 0) { | ||
54 | bb_perror_msg("`%s'", path); /* Match gnu rmdir msg. */ | ||
55 | status = EXIT_FAILURE; | ||
56 | } else if (flags) { | ||
57 | /* Note: path was not empty or null since rmdir succeeded. */ | ||
58 | path = dirname(path); | ||
59 | /* Path is now just the parent component. Note that dirname | ||
60 | * returns "." if there are no parents. We must distinguish | ||
61 | * this from the case of the original path starting with '.'. | ||
62 | */ | ||
63 | if (do_dot || (*path != '.') || path[1]) { | ||
64 | continue; | ||
65 | } | ||
66 | } | ||
67 | break; | ||
68 | } while (1); | ||
69 | |||
70 | } while (*++argv); | ||
94 | 71 | ||
95 | return status; | 72 | return status; |
96 | } | 73 | } |
diff --git a/coreutils/sha1sum.c b/coreutils/sha1sum.c index 03009f76f..d94cb4b53 100644 --- a/coreutils/sha1sum.c +++ b/coreutils/sha1sum.c | |||
@@ -187,7 +187,7 @@ extern int authenticate(const int argc, char **argv, void (*hash_ptr)(FILE *stre | |||
187 | break; | 187 | break; |
188 | #endif | 188 | #endif |
189 | default: | 189 | default: |
190 | show_usage(); | 190 | bb_show_usage(); |
191 | } | 191 | } |
192 | } | 192 | } |
193 | 193 | ||
@@ -204,7 +204,7 @@ extern int authenticate(const int argc, char **argv, void (*hash_ptr)(FILE *stre | |||
204 | hash_ptr(stdin, hashval); | 204 | hash_ptr(stdin, hashval); |
205 | print_hash(hash_length, hashval, NULL); | 205 | print_hash(hash_length, hashval, NULL); |
206 | } else { | 206 | } else { |
207 | FILE *stream = xfopen(argv[i], "r"); | 207 | FILE *stream = bb_xfopen(argv[i], "r"); |
208 | hash_ptr(stream, hashval); | 208 | hash_ptr(stream, hashval); |
209 | fclose(stream); | 209 | fclose(stream); |
210 | print_hash(hash_length, hashval, argv[i]); | 210 | print_hash(hash_length, hashval, argv[i]); |
diff --git a/coreutils/sleep.c b/coreutils/sleep.c index 7bc98d8e8..506192dd3 100644 --- a/coreutils/sleep.c +++ b/coreutils/sleep.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini sleep implementation for busybox | 3 | * sleep implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -20,18 +20,67 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <stdio.h> | 23 | /* BB_AUDIT SUSv3 compliant */ |
24 | #include <unistd.h> | 24 | /* BB_AUDIT GNU issues -- fancy version matches except args must be ints. */ |
25 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/sleep.html */ | ||
26 | |||
27 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
28 | * | ||
29 | * Rewritten to do proper arg and error checking. | ||
30 | * Also, added a 'fancy' configuration to accept multiple args with | ||
31 | * time suffixes for seconds, minutes, hours, and days. | ||
32 | */ | ||
33 | |||
25 | #include <stdlib.h> | 34 | #include <stdlib.h> |
35 | #include <limits.h> | ||
36 | #include <unistd.h> | ||
26 | #include "busybox.h" | 37 | #include "busybox.h" |
27 | 38 | ||
39 | #ifdef CONFIG_FEATURE_FANCY_SLEEP | ||
40 | static const struct suffix_mult sleep_suffixes[] = { | ||
41 | { "s", 1 }, | ||
42 | { "m", 60 }, | ||
43 | { "h", 60*60 }, | ||
44 | { "d", 24*60*60 }, | ||
45 | { NULL, 0 } | ||
46 | }; | ||
47 | #endif | ||
48 | |||
28 | extern int sleep_main(int argc, char **argv) | 49 | extern int sleep_main(int argc, char **argv) |
29 | { | 50 | { |
30 | if ((argc < 2) || (**(argv + 1) == '-')) { | 51 | unsigned int duration; |
31 | show_usage(); | 52 | |
53 | #ifdef CONFIG_FEATURE_FANCY_SLEEP | ||
54 | |||
55 | if (argc < 2) { | ||
56 | bb_show_usage(); | ||
57 | } | ||
58 | |||
59 | ++argv; | ||
60 | duration = 0; | ||
61 | do { | ||
62 | duration += bb_xgetularg_bnd_sfx(*argv, 10, | ||
63 | 0, UINT_MAX-duration, | ||
64 | sleep_suffixes); | ||
65 | } while (*++argv); | ||
66 | |||
67 | #else /* CONFIG_FEATURE_FANCY_SLEEP */ | ||
68 | |||
69 | if (argc != 2) { | ||
70 | bb_show_usage(); | ||
71 | } | ||
72 | |||
73 | #if UINT_MAX == ULONG_MAX | ||
74 | duration = bb_xgetularg10(argv[1]); | ||
75 | #else | ||
76 | duration = bb_xgetularg10_bnd(argv[1], 0, UINT_MAX); | ||
77 | #endif | ||
78 | |||
79 | #endif /* CONFIG_FEATURE_FANCY_SLEEP */ | ||
80 | |||
81 | if (sleep(duration)) { | ||
82 | bb_perror_nomsg_and_die(); | ||
32 | } | 83 | } |
33 | 84 | ||
34 | if (sleep(atoi(*(++argv))) != 0) | ||
35 | perror_msg_and_die("sleep"); | ||
36 | return EXIT_SUCCESS; | 85 | return EXIT_SUCCESS; |
37 | } | 86 | } |
diff --git a/coreutils/sort.c b/coreutils/sort.c index fc12dfb01..8cc4d8886 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c | |||
@@ -2,7 +2,6 @@ | |||
2 | /* | 2 | /* |
3 | * Mini sort implementation for busybox | 3 | * Mini sort implementation for busybox |
4 | * | 4 | * |
5 | * | ||
6 | * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> | 5 | * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> |
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -21,10 +20,20 @@ | |||
21 | * | 20 | * |
22 | */ | 21 | */ |
23 | 22 | ||
24 | #include <getopt.h> | 23 | /* BB_AUDIT SUSv3 _NOT_ compliant -- a number of options are not supported. */ |
25 | #include <string.h> | 24 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html */ |
25 | |||
26 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
27 | * | ||
28 | * Now does proper error checking on i/o. Plus some space savings. | ||
29 | */ | ||
30 | |||
31 | #include <stdio.h> | ||
26 | #include <stdlib.h> | 32 | #include <stdlib.h> |
33 | #include <string.h> | ||
34 | #include <unistd.h> | ||
27 | #include "busybox.h" | 35 | #include "busybox.h" |
36 | #include "libcoreutils/coreutils.h" | ||
28 | 37 | ||
29 | static int compare_ascii(const void *x, const void *y) | 38 | static int compare_ascii(const void *x, const void *y) |
30 | { | 39 | { |
@@ -41,66 +50,51 @@ int sort_main(int argc, char **argv) | |||
41 | { | 50 | { |
42 | FILE *fp; | 51 | FILE *fp; |
43 | char *line, **lines = NULL; | 52 | char *line, **lines = NULL; |
44 | int i, opt, nlines = 0; | 53 | int i, nlines = 0, inc; |
45 | int (*compare)(const void *, const void *) = compare_ascii; | 54 | int (*compare)(const void *, const void *) = compare_ascii; |
46 | #ifdef CONFIG_FEATURE_SORT_REVERSE | ||
47 | int reverse = FALSE; | ||
48 | #endif | ||
49 | #ifdef CONFIG_FEATURE_SORT_UNIQUE | ||
50 | int unique = FALSE; | ||
51 | #endif | ||
52 | 55 | ||
53 | while ((opt = getopt(argc, argv, "nru")) != -1) { | 56 | int flags; |
54 | switch (opt) { | 57 | |
55 | case 'n': | 58 | bb_default_error_retval = 2; |
56 | compare = compare_numeric; | 59 | |
57 | break; | 60 | flags = bb_getopt_ulflags(argc, argv, "nru"); |
58 | #ifdef CONFIG_FEATURE_SORT_REVERSE | 61 | if (flags & 1) { |
59 | case 'r': | 62 | compare = compare_numeric; |
60 | reverse = TRUE; | ||
61 | break; | ||
62 | #endif | ||
63 | #ifdef CONFIG_FEATURE_SORT_UNIQUE | ||
64 | case 'u': | ||
65 | unique = TRUE; | ||
66 | break; | ||
67 | #endif | ||
68 | default: | ||
69 | show_usage(); | ||
70 | } | ||
71 | } | 63 | } |
72 | 64 | ||
73 | /* read the input */ | 65 | argv += optind; |
74 | for (i = optind; i == optind || i < argc; i++) { | 66 | if (!*argv) { |
75 | if (argv[i] == NULL) | 67 | *--argv = "-"; |
76 | fp = stdin; | 68 | } |
77 | else | ||
78 | fp = xfopen(argv[i], "r"); | ||
79 | 69 | ||
80 | while ((line = get_line_from_file(fp)) != NULL) { | 70 | do { |
71 | fp = xgetoptfile_sort_uniq(argv, "r"); | ||
72 | while ((line = bb_get_chomped_line_from_file(fp)) != NULL) { | ||
81 | lines = xrealloc(lines, sizeof(char *) * (nlines + 1)); | 73 | lines = xrealloc(lines, sizeof(char *) * (nlines + 1)); |
82 | chomp(line); | ||
83 | lines[nlines++] = line; | 74 | lines[nlines++] = line; |
84 | } | 75 | } |
85 | } | 76 | bb_xferror(fp, *argv); |
77 | bb_fclose_nonstdin(fp); | ||
78 | } while (*++argv); | ||
86 | 79 | ||
87 | /* sort it */ | 80 | /* sort it */ |
88 | qsort(lines, nlines, sizeof(char *), compare); | 81 | qsort(lines, nlines, sizeof(char *), compare); |
89 | 82 | ||
90 | /* print it */ | 83 | /* print it */ |
91 | #ifdef CONFIG_FEATURE_SORT_REVERSE | 84 | i = 0; |
92 | if (reverse) { | 85 | --nlines; |
93 | for (i = --nlines; 0 <= i; i--) | 86 | if ((inc = 1 - (flags & 2)) < 0) { /* reverse */ |
94 | #ifdef CONFIG_FEATURE_SORT_UNIQUE | 87 | i = nlines; |
95 | if((!unique) || (i == nlines) || (strcmp(lines[i + 1], lines[i]))) | 88 | } |
96 | #endif | 89 | flags &= 4; |
97 | puts(lines[i]); | 90 | |
98 | } else | 91 | while (nlines >= 0) { |
99 | #endif | 92 | if (!flags || !nlines || strcmp(lines[i+inc], lines[i])) { |
100 | for (i = 0; i < nlines; i++) | 93 | puts(lines[i]); |
101 | #ifdef CONFIG_FEATURE_SORT_UNIQUE | 94 | } |
102 | if((!unique) || (!i) || (strcmp(lines[i - 1], lines[i]))) | 95 | i += inc; |
103 | #endif | 96 | --nlines; |
104 | puts(lines[i]); | 97 | } |
105 | return EXIT_SUCCESS; | 98 | |
99 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); | ||
106 | } | 100 | } |
diff --git a/coreutils/stty.c b/coreutils/stty.c index a67a17c0f..a3a98d9ef 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c | |||
@@ -30,9 +30,9 @@ | |||
30 | 30 | ||
31 | //#define TEST | 31 | //#define TEST |
32 | 32 | ||
33 | #include <stddef.h> | ||
33 | #include <termios.h> | 34 | #include <termios.h> |
34 | #include <sys/ioctl.h> | 35 | #include <sys/ioctl.h> |
35 | #include <getopt.h> | ||
36 | 36 | ||
37 | #include <sys/param.h> | 37 | #include <sys/param.h> |
38 | #include <unistd.h> | 38 | #include <unistd.h> |
@@ -155,13 +155,10 @@ enum speed_setting { | |||
155 | input_speed, output_speed, both_speeds | 155 | input_speed, output_speed, both_speeds |
156 | }; | 156 | }; |
157 | 157 | ||
158 | /* What to output and how. */ | ||
159 | enum output_type { | ||
160 | changed, all, recoverable /* Default, -a, -g. */ | ||
161 | }; | ||
162 | |||
163 | /* Which member(s) of `struct termios' a mode uses. */ | 158 | /* Which member(s) of `struct termios' a mode uses. */ |
164 | enum mode_type { | 159 | enum mode_type { |
160 | /* Do NOT change the order or values, as mode_type_flag() | ||
161 | * depends on them. */ | ||
165 | control, input, output, local, combination | 162 | control, input, output, local, combination |
166 | }; | 163 | }; |
167 | 164 | ||
@@ -199,156 +196,159 @@ static const char stty_dec [] = "dec"; | |||
199 | /* Each mode. */ | 196 | /* Each mode. */ |
200 | struct mode_info { | 197 | struct mode_info { |
201 | const char *name; /* Name given on command line. */ | 198 | const char *name; /* Name given on command line. */ |
202 | enum mode_type type; /* Which structure element to change. */ | 199 | /* enum mode_type type; */ |
200 | char type; /* Which structure element to change. */ | ||
203 | char flags; /* Setting and display options. */ | 201 | char flags; /* Setting and display options. */ |
202 | unsigned short mask; /* Other bits to turn off for this mode. */ | ||
204 | unsigned long bits; /* Bits to set for this mode. */ | 203 | unsigned long bits; /* Bits to set for this mode. */ |
205 | unsigned long mask; /* Other bits to turn off for this mode. */ | ||
206 | }; | 204 | }; |
207 | 205 | ||
206 | #define MI_ENTRY(N,T,F,B,M) { N, T, F, M, B } | ||
207 | |||
208 | static const struct mode_info mode_info[] = { | 208 | static const struct mode_info mode_info[] = { |
209 | {"parenb", control, REV, PARENB, 0 }, | 209 | MI_ENTRY("parenb", control, REV, PARENB, 0 ), |
210 | {"parodd", control, REV, PARODD, 0 }, | 210 | MI_ENTRY("parodd", control, REV, PARODD, 0 ), |
211 | {"cs5", control, 0, CS5, CSIZE}, | 211 | MI_ENTRY("cs5", control, 0, CS5, CSIZE), |
212 | {"cs6", control, 0, CS6, CSIZE}, | 212 | MI_ENTRY("cs6", control, 0, CS6, CSIZE), |
213 | {"cs7", control, 0, CS7, CSIZE}, | 213 | MI_ENTRY("cs7", control, 0, CS7, CSIZE), |
214 | {"cs8", control, 0, CS8, CSIZE}, | 214 | MI_ENTRY("cs8", control, 0, CS8, CSIZE), |
215 | {"hupcl", control, REV, HUPCL, 0 }, | 215 | MI_ENTRY("hupcl", control, REV, HUPCL, 0 ), |
216 | {"hup", control, REV | OMIT, HUPCL, 0 }, | 216 | MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 ), |
217 | {"cstopb", control, REV, CSTOPB, 0 }, | 217 | MI_ENTRY("cstopb", control, REV, CSTOPB, 0 ), |
218 | {"cread", control, SANE_SET | REV, CREAD, 0 }, | 218 | MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 ), |
219 | {"clocal", control, REV, CLOCAL, 0 }, | 219 | MI_ENTRY("clocal", control, REV, CLOCAL, 0 ), |
220 | #ifdef CRTSCTS | 220 | #ifdef CRTSCTS |
221 | {"crtscts", control, REV, CRTSCTS, 0 }, | 221 | MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 ), |
222 | #endif | 222 | #endif |
223 | {"ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 }, | 223 | MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 ), |
224 | {"brkint", input, SANE_SET | REV, BRKINT, 0 }, | 224 | MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 ), |
225 | {"ignpar", input, REV, IGNPAR, 0 }, | 225 | MI_ENTRY("ignpar", input, REV, IGNPAR, 0 ), |
226 | {"parmrk", input, REV, PARMRK, 0 }, | 226 | MI_ENTRY("parmrk", input, REV, PARMRK, 0 ), |
227 | {"inpck", input, REV, INPCK, 0 }, | 227 | MI_ENTRY("inpck", input, REV, INPCK, 0 ), |
228 | {"istrip", input, REV, ISTRIP, 0 }, | 228 | MI_ENTRY("istrip", input, REV, ISTRIP, 0 ), |
229 | {"inlcr", input, SANE_UNSET | REV, INLCR, 0 }, | 229 | MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 ), |
230 | {"igncr", input, SANE_UNSET | REV, IGNCR, 0 }, | 230 | MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 ), |
231 | {"icrnl", input, SANE_SET | REV, ICRNL, 0 }, | 231 | MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 ), |
232 | {"ixon", input, REV, IXON, 0 }, | 232 | MI_ENTRY("ixon", input, REV, IXON, 0 ), |
233 | {"ixoff", input, SANE_UNSET | REV, IXOFF, 0 }, | 233 | MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 ), |
234 | {"tandem", input, REV | OMIT, IXOFF, 0 }, | 234 | MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 ), |
235 | #ifdef IUCLC | 235 | #ifdef IUCLC |
236 | {"iuclc", input, SANE_UNSET | REV, IUCLC, 0 }, | 236 | MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 ), |
237 | #endif | 237 | #endif |
238 | #ifdef IXANY | 238 | #ifdef IXANY |
239 | {"ixany", input, SANE_UNSET | REV, IXANY, 0 }, | 239 | MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 ), |
240 | #endif | 240 | #endif |
241 | #ifdef IMAXBEL | 241 | #ifdef IMAXBEL |
242 | {"imaxbel", input, SANE_SET | REV, IMAXBEL, 0 }, | 242 | MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 ), |
243 | #endif | 243 | #endif |
244 | {"opost", output, SANE_SET | REV, OPOST, 0 }, | 244 | MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 ), |
245 | #ifdef OLCUC | 245 | #ifdef OLCUC |
246 | {"olcuc", output, SANE_UNSET | REV, OLCUC, 0 }, | 246 | MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 ), |
247 | #endif | 247 | #endif |
248 | #ifdef OCRNL | 248 | #ifdef OCRNL |
249 | {"ocrnl", output, SANE_UNSET | REV, OCRNL, 0 }, | 249 | MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 ), |
250 | #endif | 250 | #endif |
251 | #ifdef ONLCR | 251 | #ifdef ONLCR |
252 | {"onlcr", output, SANE_SET | REV, ONLCR, 0 }, | 252 | MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 ), |
253 | #endif | 253 | #endif |
254 | #ifdef ONOCR | 254 | #ifdef ONOCR |
255 | {"onocr", output, SANE_UNSET | REV, ONOCR, 0 }, | 255 | MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 ), |
256 | #endif | 256 | #endif |
257 | #ifdef ONLRET | 257 | #ifdef ONLRET |
258 | {"onlret", output, SANE_UNSET | REV, ONLRET, 0 }, | 258 | MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 ), |
259 | #endif | 259 | #endif |
260 | #ifdef OFILL | 260 | #ifdef OFILL |
261 | {"ofill", output, SANE_UNSET | REV, OFILL, 0 }, | 261 | MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 ), |
262 | #endif | 262 | #endif |
263 | #ifdef OFDEL | 263 | #ifdef OFDEL |
264 | {"ofdel", output, SANE_UNSET | REV, OFDEL, 0 }, | 264 | MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 ), |
265 | #endif | 265 | #endif |
266 | #ifdef NLDLY | 266 | #ifdef NLDLY |
267 | {"nl1", output, SANE_UNSET, NL1, NLDLY}, | 267 | MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY), |
268 | {"nl0", output, SANE_SET, NL0, NLDLY}, | 268 | MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY), |
269 | #endif | 269 | #endif |
270 | #ifdef CRDLY | 270 | #ifdef CRDLY |
271 | {"cr3", output, SANE_UNSET, CR3, CRDLY}, | 271 | MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY), |
272 | {"cr2", output, SANE_UNSET, CR2, CRDLY}, | 272 | MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY), |
273 | {"cr1", output, SANE_UNSET, CR1, CRDLY}, | 273 | MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY), |
274 | {"cr0", output, SANE_SET, CR0, CRDLY}, | 274 | MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY), |
275 | #endif | 275 | #endif |
276 | 276 | ||
277 | #ifdef TABDLY | 277 | #ifdef TABDLY |
278 | {"tab3", output, SANE_UNSET, TAB3, TABDLY}, | 278 | MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY), |
279 | {"tab2", output, SANE_UNSET, TAB2, TABDLY}, | 279 | MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY), |
280 | {"tab1", output, SANE_UNSET, TAB1, TABDLY}, | 280 | MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY), |
281 | {"tab0", output, SANE_SET, TAB0, TABDLY}, | 281 | MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY), |
282 | #else | 282 | #else |
283 | # ifdef OXTABS | 283 | # ifdef OXTABS |
284 | {"tab3", output, SANE_UNSET, OXTABS, 0 }, | 284 | MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 ), |
285 | # endif | 285 | # endif |
286 | #endif | 286 | #endif |
287 | 287 | ||
288 | #ifdef BSDLY | 288 | #ifdef BSDLY |
289 | {"bs1", output, SANE_UNSET, BS1, BSDLY}, | 289 | MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY), |
290 | {"bs0", output, SANE_SET, BS0, BSDLY}, | 290 | MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY), |
291 | #endif | 291 | #endif |
292 | #ifdef VTDLY | 292 | #ifdef VTDLY |
293 | {"vt1", output, SANE_UNSET, VT1, VTDLY}, | 293 | MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY), |
294 | {"vt0", output, SANE_SET, VT0, VTDLY}, | 294 | MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY), |
295 | #endif | 295 | #endif |
296 | #ifdef FFDLY | 296 | #ifdef FFDLY |
297 | {"ff1", output, SANE_UNSET, FF1, FFDLY}, | 297 | MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY), |
298 | {"ff0", output, SANE_SET, FF0, FFDLY}, | 298 | MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY), |
299 | #endif | 299 | #endif |
300 | {"isig", local, SANE_SET | REV, ISIG, 0 }, | 300 | MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 ), |
301 | {"icanon", local, SANE_SET | REV, ICANON, 0 }, | 301 | MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 ), |
302 | #ifdef IEXTEN | 302 | #ifdef IEXTEN |
303 | {"iexten", local, SANE_SET | REV, IEXTEN, 0 }, | 303 | MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 ), |
304 | #endif | 304 | #endif |
305 | {"echo", local, SANE_SET | REV, ECHO, 0 }, | 305 | MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 ), |
306 | {"echoe", local, SANE_SET | REV, ECHOE, 0 }, | 306 | MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 ), |
307 | {"crterase", local, REV | OMIT, ECHOE, 0 }, | 307 | MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 ), |
308 | {"echok", local, SANE_SET | REV, ECHOK, 0 }, | 308 | MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 ), |
309 | {"echonl", local, SANE_UNSET | REV, ECHONL, 0 }, | 309 | MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 ), |
310 | {"noflsh", local, SANE_UNSET | REV, NOFLSH, 0 }, | 310 | MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 ), |
311 | #ifdef XCASE | 311 | #ifdef XCASE |
312 | {"xcase", local, SANE_UNSET | REV, XCASE, 0 }, | 312 | MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 ), |
313 | #endif | 313 | #endif |
314 | #ifdef TOSTOP | 314 | #ifdef TOSTOP |
315 | {"tostop", local, SANE_UNSET | REV, TOSTOP, 0 }, | 315 | MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 ), |
316 | #endif | 316 | #endif |
317 | #ifdef ECHOPRT | 317 | #ifdef ECHOPRT |
318 | {"echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 }, | 318 | MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 ), |
319 | {"prterase", local, REV | OMIT, ECHOPRT, 0 }, | 319 | MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 ), |
320 | #endif | 320 | #endif |
321 | #ifdef ECHOCTL | 321 | #ifdef ECHOCTL |
322 | {"echoctl", local, SANE_SET | REV, ECHOCTL, 0 }, | 322 | MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 ), |
323 | {"ctlecho", local, REV | OMIT, ECHOCTL, 0 }, | 323 | MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 ), |
324 | #endif | 324 | #endif |
325 | #ifdef ECHOKE | 325 | #ifdef ECHOKE |
326 | {"echoke", local, SANE_SET | REV, ECHOKE, 0 }, | 326 | MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 ), |
327 | {"crtkill", local, REV | OMIT, ECHOKE, 0 }, | 327 | MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 ), |
328 | #endif | 328 | #endif |
329 | {evenp, combination, REV | OMIT, 0, 0 }, | 329 | MI_ENTRY(evenp, combination, REV | OMIT, 0, 0 ), |
330 | {parity, combination, REV | OMIT, 0, 0 }, | 330 | MI_ENTRY(parity, combination, REV | OMIT, 0, 0 ), |
331 | {stty_oddp, combination, REV | OMIT, 0, 0 }, | 331 | MI_ENTRY(stty_oddp, combination, REV | OMIT, 0, 0 ), |
332 | {stty_nl, combination, REV | OMIT, 0, 0 }, | 332 | MI_ENTRY(stty_nl, combination, REV | OMIT, 0, 0 ), |
333 | {stty_ek, combination, OMIT, 0, 0 }, | 333 | MI_ENTRY(stty_ek, combination, OMIT, 0, 0 ), |
334 | {stty_sane, combination, OMIT, 0, 0 }, | 334 | MI_ENTRY(stty_sane, combination, OMIT, 0, 0 ), |
335 | {cooked, combination, REV | OMIT, 0, 0 }, | 335 | MI_ENTRY(cooked, combination, REV | OMIT, 0, 0 ), |
336 | {raw, combination, REV | OMIT, 0, 0 }, | 336 | MI_ENTRY(raw, combination, REV | OMIT, 0, 0 ), |
337 | {stty_pass8, combination, REV | OMIT, 0, 0 }, | 337 | MI_ENTRY(stty_pass8, combination, REV | OMIT, 0, 0 ), |
338 | {litout, combination, REV | OMIT, 0, 0 }, | 338 | MI_ENTRY(litout, combination, REV | OMIT, 0, 0 ), |
339 | {cbreak, combination, REV | OMIT, 0, 0 }, | 339 | MI_ENTRY(cbreak, combination, REV | OMIT, 0, 0 ), |
340 | #ifdef IXANY | 340 | #ifdef IXANY |
341 | {decctlq, combination, REV | OMIT, 0, 0 }, | 341 | MI_ENTRY(decctlq, combination, REV | OMIT, 0, 0 ), |
342 | #endif | 342 | #endif |
343 | #if defined (TABDLY) || defined (OXTABS) | 343 | #if defined (TABDLY) || defined (OXTABS) |
344 | {stty_tabs, combination, REV | OMIT, 0, 0 }, | 344 | MI_ENTRY(stty_tabs, combination, REV | OMIT, 0, 0 ), |
345 | #endif | 345 | #endif |
346 | #if defined(XCASE) && defined(IUCLC) && defined(OLCUC) | 346 | #if defined(XCASE) && defined(IUCLC) && defined(OLCUC) |
347 | {stty_lcase, combination, REV | OMIT, 0, 0 }, | 347 | MI_ENTRY(stty_lcase, combination, REV | OMIT, 0, 0 ), |
348 | {stty_LCASE, combination, REV | OMIT, 0, 0 }, | 348 | MI_ENTRY(stty_LCASE, combination, REV | OMIT, 0, 0 ), |
349 | #endif | 349 | #endif |
350 | {stty_crt, combination, OMIT, 0, 0 }, | 350 | MI_ENTRY(stty_crt, combination, OMIT, 0, 0 ), |
351 | {stty_dec, combination, OMIT, 0, 0 }, | 351 | MI_ENTRY(stty_dec, combination, OMIT, 0, 0 ), |
352 | }; | 352 | }; |
353 | 353 | ||
354 | static const int NUM_mode_info = | 354 | static const int NUM_mode_info = |
@@ -359,7 +359,7 @@ static const int NUM_mode_info = | |||
359 | struct control_info { | 359 | struct control_info { |
360 | const char *name; /* Name given on command line. */ | 360 | const char *name; /* Name given on command line. */ |
361 | unsigned char saneval; /* Value to set for `stty sane'. */ | 361 | unsigned char saneval; /* Value to set for `stty sane'. */ |
362 | int offset; /* Offset in c_cc. */ | 362 | unsigned char offset; /* Offset in c_cc. */ |
363 | }; | 363 | }; |
364 | 364 | ||
365 | /* Control characters. */ | 365 | /* Control characters. */ |
@@ -408,7 +408,6 @@ static const int NUM_control_info = | |||
408 | 408 | ||
409 | 409 | ||
410 | static const char * visible(unsigned int ch); | 410 | static const char * visible(unsigned int ch); |
411 | static unsigned long baud_to_value(speed_t speed); | ||
412 | static int recover_mode(char *arg, struct termios *mode); | 411 | static int recover_mode(char *arg, struct termios *mode); |
413 | static int screen_columns(void); | 412 | static int screen_columns(void); |
414 | static int set_mode(const struct mode_info *info, | 413 | static int set_mode(const struct mode_info *info, |
@@ -416,12 +415,11 @@ static int set_mode(const struct mode_info *info, | |||
416 | static speed_t string_to_baud(const char *arg); | 415 | static speed_t string_to_baud(const char *arg); |
417 | static tcflag_t* mode_type_flag(enum mode_type type, struct termios *mode); | 416 | static tcflag_t* mode_type_flag(enum mode_type type, struct termios *mode); |
418 | static void display_all(struct termios *mode, int fd, | 417 | static void display_all(struct termios *mode, int fd, |
419 | const char *device_name); | 418 | const char *device_name); |
420 | static void display_changed(struct termios *mode); | 419 | static void display_changed(struct termios *mode, int fd, |
421 | static void display_recoverable(struct termios *mode); | 420 | const char *device_name); |
422 | static void display_settings(enum output_type output_type, | 421 | static void display_recoverable(struct termios *mode, int fd, |
423 | struct termios *mode, int fd, | 422 | const char *device_name); |
424 | const char *device_name); | ||
425 | static void display_speed(struct termios *mode, int fancy); | 423 | static void display_speed(struct termios *mode, int fancy); |
426 | static void display_window_size(int fancy, int fd, | 424 | static void display_window_size(int fancy, int fd, |
427 | const char *device_name); | 425 | const char *device_name); |
@@ -479,7 +477,7 @@ extern int main(int argc, char **argv) | |||
479 | #endif | 477 | #endif |
480 | { | 478 | { |
481 | struct termios mode; | 479 | struct termios mode; |
482 | enum output_type output_type; | 480 | void (*output_func)(struct termios *, int, const char *); |
483 | int optc; | 481 | int optc; |
484 | int require_set_attr; | 482 | int require_set_attr; |
485 | int speed_was_set; | 483 | int speed_was_set; |
@@ -491,7 +489,7 @@ extern int main(int argc, char **argv) | |||
491 | int fd; | 489 | int fd; |
492 | const char *device_name; | 490 | const char *device_name; |
493 | 491 | ||
494 | output_type = changed; | 492 | output_func = display_changed; |
495 | verbose_output = 0; | 493 | verbose_output = 0; |
496 | recoverable_output = 0; | 494 | recoverable_output = 0; |
497 | 495 | ||
@@ -502,17 +500,17 @@ extern int main(int argc, char **argv) | |||
502 | switch (optc) { | 500 | switch (optc) { |
503 | case 'a': | 501 | case 'a': |
504 | verbose_output = 1; | 502 | verbose_output = 1; |
505 | output_type = all; | 503 | output_func = display_all; |
506 | break; | 504 | break; |
507 | 505 | ||
508 | case 'g': | 506 | case 'g': |
509 | recoverable_output = 1; | 507 | recoverable_output = 1; |
510 | output_type = recoverable; | 508 | output_func = display_recoverable; |
511 | break; | 509 | break; |
512 | 510 | ||
513 | case 'F': | 511 | case 'F': |
514 | if (file_name) | 512 | if (file_name) |
515 | error_msg_and_die("only one device may be specified"); | 513 | bb_error_msg_and_die("only one device may be specified"); |
516 | file_name = optarg; | 514 | file_name = optarg; |
517 | break; | 515 | break; |
518 | 516 | ||
@@ -529,12 +527,12 @@ extern int main(int argc, char **argv) | |||
529 | noargs = 0; | 527 | noargs = 0; |
530 | 528 | ||
531 | /* Specifying both -a and -g gets an error. */ | 529 | /* Specifying both -a and -g gets an error. */ |
532 | if (verbose_output && recoverable_output) | 530 | if (verbose_output & recoverable_output) |
533 | error_msg_and_die ("verbose and stty-readable output styles are mutually exclusive"); | 531 | bb_error_msg_and_die ("verbose and stty-readable output styles are mutually exclusive"); |
534 | 532 | ||
535 | /* Specifying any other arguments with -a or -g gets an error. */ | 533 | /* Specifying any other arguments with -a or -g gets an error. */ |
536 | if (!noargs && (verbose_output || recoverable_output)) | 534 | if (~noargs & (verbose_output | recoverable_output)) |
537 | error_msg_and_die ("modes may not be set when specifying an output style"); | 535 | bb_error_msg_and_die ("modes may not be set when specifying an output style"); |
538 | 536 | ||
539 | /* FIXME: it'd be better not to open the file until we've verified | 537 | /* FIXME: it'd be better not to open the file until we've verified |
540 | that all arguments are valid. Otherwise, we could end up doing | 538 | that all arguments are valid. Otherwise, we could end up doing |
@@ -547,26 +545,26 @@ extern int main(int argc, char **argv) | |||
547 | device_name = file_name; | 545 | device_name = file_name; |
548 | fd = open(device_name, O_RDONLY | O_NONBLOCK); | 546 | fd = open(device_name, O_RDONLY | O_NONBLOCK); |
549 | if (fd < 0) | 547 | if (fd < 0) |
550 | perror_msg_and_die("%s", device_name); | 548 | bb_perror_msg_and_die("%s", device_name); |
551 | if ((fdflags = fcntl(fd, F_GETFL)) == -1 | 549 | if ((fdflags = fcntl(fd, F_GETFL)) == -1 |
552 | || fcntl(fd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) | 550 | || fcntl(fd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) |
553 | perror_msg_and_die("%s: couldn't reset non-blocking mode", | 551 | bb_perror_msg_and_die("%s: couldn't reset non-blocking mode", |
554 | device_name); | 552 | device_name); |
555 | } else { | 553 | } else { |
556 | fd = 0; | 554 | fd = 0; |
557 | device_name = "standard input"; | 555 | device_name = bb_msg_standard_input; |
558 | } | 556 | } |
559 | 557 | ||
560 | /* Initialize to all zeroes so there is no risk memcmp will report a | 558 | /* Initialize to all zeroes so there is no risk memcmp will report a |
561 | spurious difference in an uninitialized portion of the structure. */ | 559 | spurious difference in an uninitialized portion of the structure. */ |
562 | memset(&mode, 0, sizeof(mode)); | 560 | memset(&mode, 0, sizeof(mode)); |
563 | if (tcgetattr(fd, &mode)) | 561 | if (tcgetattr(fd, &mode)) |
564 | perror_msg_and_die("%s", device_name); | 562 | bb_perror_msg_and_die("%s", device_name); |
565 | 563 | ||
566 | if (verbose_output || recoverable_output || noargs) { | 564 | if (verbose_output | recoverable_output | noargs) { |
567 | max_col = screen_columns(); | 565 | max_col = screen_columns(); |
568 | current_col = 0; | 566 | current_col = 0; |
569 | display_settings(output_type, &mode, fd, device_name); | 567 | output_func(&mode, fd, device_name); |
570 | return EXIT_SUCCESS; | 568 | return EXIT_SUCCESS; |
571 | } | 569 | } |
572 | 570 | ||
@@ -610,13 +608,13 @@ extern int main(int argc, char **argv) | |||
610 | } | 608 | } |
611 | 609 | ||
612 | if (match_found == 0 && reversed) | 610 | if (match_found == 0 && reversed) |
613 | error_msg_and_die("invalid argument `%s'", --argv[k]); | 611 | bb_error_msg_and_die("invalid argument `%s'", --argv[k]); |
614 | 612 | ||
615 | if (match_found == 0) | 613 | if (match_found == 0) |
616 | for (i = 0; i < NUM_control_info; ++i) | 614 | for (i = 0; i < NUM_control_info; ++i) |
617 | if (STREQ(argv[k], control_info[i].name)) { | 615 | if (STREQ(argv[k], control_info[i].name)) { |
618 | if (k == argc - 1) | 616 | if (k == argc - 1) |
619 | error_msg_and_die("missing argument to `%s'", argv[k]); | 617 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
620 | match_found = 1; | 618 | match_found = 1; |
621 | ++k; | 619 | ++k; |
622 | set_control_char(&control_info[i], argv[k], &mode); | 620 | set_control_char(&control_info[i], argv[k], &mode); |
@@ -627,14 +625,14 @@ extern int main(int argc, char **argv) | |||
627 | if (match_found == 0) { | 625 | if (match_found == 0) { |
628 | if (STREQ(argv[k], "ispeed")) { | 626 | if (STREQ(argv[k], "ispeed")) { |
629 | if (k == argc - 1) | 627 | if (k == argc - 1) |
630 | error_msg_and_die("missing argument to `%s'", argv[k]); | 628 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
631 | ++k; | 629 | ++k; |
632 | set_speed(input_speed, argv[k], &mode); | 630 | set_speed(input_speed, argv[k], &mode); |
633 | speed_was_set = 1; | 631 | speed_was_set = 1; |
634 | require_set_attr = 1; | 632 | require_set_attr = 1; |
635 | } else if (STREQ(argv[k], "ospeed")) { | 633 | } else if (STREQ(argv[k], "ospeed")) { |
636 | if (k == argc - 1) | 634 | if (k == argc - 1) |
637 | error_msg_and_die("missing argument to `%s'", argv[k]); | 635 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
638 | ++k; | 636 | ++k; |
639 | set_speed(output_speed, argv[k], &mode); | 637 | set_speed(output_speed, argv[k], &mode); |
640 | speed_was_set = 1; | 638 | speed_was_set = 1; |
@@ -643,16 +641,16 @@ extern int main(int argc, char **argv) | |||
643 | #ifdef TIOCGWINSZ | 641 | #ifdef TIOCGWINSZ |
644 | else if (STREQ(argv[k], "rows")) { | 642 | else if (STREQ(argv[k], "rows")) { |
645 | if (k == argc - 1) | 643 | if (k == argc - 1) |
646 | error_msg_and_die("missing argument to `%s'", argv[k]); | 644 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
647 | ++k; | 645 | ++k; |
648 | set_window_size((int) parse_number(argv[k], stty_suffixes), | 646 | set_window_size((int) bb_xparse_number(argv[k], stty_suffixes), |
649 | -1, fd, device_name); | 647 | -1, fd, device_name); |
650 | } else if (STREQ(argv[k], "cols") || STREQ(argv[k], "columns")) { | 648 | } else if (STREQ(argv[k], "cols") || STREQ(argv[k], "columns")) { |
651 | if (k == argc - 1) | 649 | if (k == argc - 1) |
652 | error_msg_and_die("missing argument to `%s'", argv[k]); | 650 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
653 | ++k; | 651 | ++k; |
654 | set_window_size(-1, | 652 | set_window_size(-1, |
655 | (int) parse_number(argv[k], stty_suffixes), | 653 | (int) bb_xparse_number(argv[k], stty_suffixes), |
656 | fd, device_name); | 654 | fd, device_name); |
657 | } else if (STREQ(argv[k], "size")) { | 655 | } else if (STREQ(argv[k], "size")) { |
658 | max_col = screen_columns(); | 656 | max_col = screen_columns(); |
@@ -663,9 +661,9 @@ extern int main(int argc, char **argv) | |||
663 | #ifdef HAVE_C_LINE | 661 | #ifdef HAVE_C_LINE |
664 | else if (STREQ(argv[k], "line")) { | 662 | else if (STREQ(argv[k], "line")) { |
665 | if (k == argc - 1) | 663 | if (k == argc - 1) |
666 | error_msg_and_die("missing argument to `%s'", argv[k]); | 664 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
667 | ++k; | 665 | ++k; |
668 | mode.c_line = parse_number(argv[k], stty_suffixes); | 666 | mode.c_line = bb_xparse_number(argv[k], stty_suffixes); |
669 | require_set_attr = 1; | 667 | require_set_attr = 1; |
670 | } | 668 | } |
671 | #endif | 669 | #endif |
@@ -679,7 +677,7 @@ extern int main(int argc, char **argv) | |||
679 | speed_was_set = 1; | 677 | speed_was_set = 1; |
680 | require_set_attr = 1; | 678 | require_set_attr = 1; |
681 | } else | 679 | } else |
682 | error_msg_and_die("invalid argument `%s'", argv[k]); | 680 | bb_error_msg_and_die("invalid argument `%s'", argv[k]); |
683 | } | 681 | } |
684 | } | 682 | } |
685 | 683 | ||
@@ -687,7 +685,7 @@ extern int main(int argc, char **argv) | |||
687 | struct termios new_mode; | 685 | struct termios new_mode; |
688 | 686 | ||
689 | if (tcsetattr(fd, TCSADRAIN, &mode)) | 687 | if (tcsetattr(fd, TCSADRAIN, &mode)) |
690 | perror_msg_and_die("%s", device_name); | 688 | bb_perror_msg_and_die("%s", device_name); |
691 | 689 | ||
692 | /* POSIX (according to Zlotnick's book) tcsetattr returns zero if | 690 | /* POSIX (according to Zlotnick's book) tcsetattr returns zero if |
693 | it performs *any* of the requested operations. This means it | 691 | it performs *any* of the requested operations. This means it |
@@ -700,7 +698,7 @@ extern int main(int argc, char **argv) | |||
700 | spurious difference in an uninitialized portion of the structure. */ | 698 | spurious difference in an uninitialized portion of the structure. */ |
701 | memset(&new_mode, 0, sizeof(new_mode)); | 699 | memset(&new_mode, 0, sizeof(new_mode)); |
702 | if (tcgetattr(fd, &new_mode)) | 700 | if (tcgetattr(fd, &new_mode)) |
703 | perror_msg_and_die("%s", device_name); | 701 | bb_perror_msg_and_die("%s", device_name); |
704 | 702 | ||
705 | /* Normally, one shouldn't use memcmp to compare structures that | 703 | /* Normally, one shouldn't use memcmp to compare structures that |
706 | may have `holes' containing uninitialized data, but we have been | 704 | may have `holes' containing uninitialized data, but we have been |
@@ -723,7 +721,7 @@ extern int main(int argc, char **argv) | |||
723 | new_mode.c_cflag &= (~CIBAUD); | 721 | new_mode.c_cflag &= (~CIBAUD); |
724 | if (speed_was_set || memcmp(&mode, &new_mode, sizeof(mode)) != 0) | 722 | if (speed_was_set || memcmp(&mode, &new_mode, sizeof(mode)) != 0) |
725 | #endif | 723 | #endif |
726 | error_msg_and_die ("%s: unable to perform all requested operations", | 724 | bb_error_msg_and_die ("%s: unable to perform all requested operations", |
727 | device_name); | 725 | device_name); |
728 | } | 726 | } |
729 | } | 727 | } |
@@ -896,9 +894,9 @@ set_mode(const struct mode_info *info, int reversed, struct termios *mode) | |||
896 | #endif | 894 | #endif |
897 | } | 895 | } |
898 | } else if (reversed) | 896 | } else if (reversed) |
899 | *bitsp = *bitsp & ~info->mask & ~info->bits; | 897 | *bitsp = *bitsp & ~((unsigned long)info->mask) & ~info->bits; |
900 | else | 898 | else |
901 | *bitsp = (*bitsp & ~info->mask) | info->bits; | 899 | *bitsp = (*bitsp & ~((unsigned long)info->mask)) | info->bits; |
902 | 900 | ||
903 | return 1; | 901 | return 1; |
904 | } | 902 | } |
@@ -910,7 +908,7 @@ set_control_char(const struct control_info *info, const char *arg, | |||
910 | unsigned char value; | 908 | unsigned char value; |
911 | 909 | ||
912 | if (info->name == stty_min || info->name == stty_time) | 910 | if (info->name == stty_min || info->name == stty_time) |
913 | value = parse_number(arg, stty_suffixes); | 911 | value = bb_xparse_number(arg, stty_suffixes); |
914 | else if (arg[0] == '\0' || arg[1] == '\0') | 912 | else if (arg[0] == '\0' || arg[1] == '\0') |
915 | value = arg[0]; | 913 | value = arg[0]; |
916 | else if (STREQ(arg, "^-") || STREQ(arg, "undef")) | 914 | else if (STREQ(arg, "^-") || STREQ(arg, "undef")) |
@@ -921,7 +919,7 @@ set_control_char(const struct control_info *info, const char *arg, | |||
921 | else | 919 | else |
922 | value = arg[1] & ~0140; /* Non-letters get weird results. */ | 920 | value = arg[1] & ~0140; /* Non-letters get weird results. */ |
923 | } else | 921 | } else |
924 | value = parse_number(arg, stty_suffixes); | 922 | value = bb_xparse_number(arg, stty_suffixes); |
925 | mode->c_cc[info->offset] = value; | 923 | mode->c_cc[info->offset] = value; |
926 | } | 924 | } |
927 | 925 | ||
@@ -931,10 +929,13 @@ set_speed(enum speed_setting type, const char *arg, struct termios *mode) | |||
931 | speed_t baud; | 929 | speed_t baud; |
932 | 930 | ||
933 | baud = string_to_baud(arg); | 931 | baud = string_to_baud(arg); |
934 | if (type == input_speed || type == both_speeds) | 932 | |
933 | if (type != output_speed) { /* either input or both */ | ||
935 | cfsetispeed(mode, baud); | 934 | cfsetispeed(mode, baud); |
936 | if (type == output_speed || type == both_speeds) | 935 | } |
936 | if (type != input_speed) { /* either output or both */ | ||
937 | cfsetospeed(mode, baud); | 937 | cfsetospeed(mode, baud); |
938 | } | ||
938 | } | 939 | } |
939 | 940 | ||
940 | #ifdef TIOCGWINSZ | 941 | #ifdef TIOCGWINSZ |
@@ -953,7 +954,7 @@ set_window_size(int rows, int cols, int fd, const char *device_name) | |||
953 | 954 | ||
954 | if (get_win_size(fd, &win)) { | 955 | if (get_win_size(fd, &win)) { |
955 | if (errno != EINVAL) | 956 | if (errno != EINVAL) |
956 | perror_msg_and_die("%s", device_name); | 957 | bb_perror_msg_and_die("%s", device_name); |
957 | memset(&win, 0, sizeof(win)); | 958 | memset(&win, 0, sizeof(win)); |
958 | } | 959 | } |
959 | 960 | ||
@@ -975,32 +976,28 @@ set_window_size(int rows, int cols, int fd, const char *device_name) | |||
975 | ttysz.ts_lines = win.ws_row; | 976 | ttysz.ts_lines = win.ws_row; |
976 | ttysz.ts_cols = win.ws_col; | 977 | ttysz.ts_cols = win.ws_col; |
977 | 978 | ||
978 | win.ws_row = 1; | 979 | win.ws_row = win.ws_col = 1; |
979 | win.ws_col = 1; | ||
980 | |||
981 | if (ioctl(fd, TIOCSWINSZ, (char *) &win)) | ||
982 | perror_msg_and_die("%s", device_name); | ||
983 | 980 | ||
984 | if (ioctl(fd, TIOCSSIZE, (char *) &ttysz)) | 981 | if ((ioctl(fd, TIOCSWINSZ, (char *) &win) != 0) |
985 | perror_msg_and_die("%s", device_name); | 982 | || (ioctl(fd, TIOCSSIZE, (char *) &ttysz) != 0)) { |
983 | bb_perror_msg_and_die("%s", device_name); | ||
986 | return; | 984 | return; |
987 | } | 985 | } |
988 | # endif | 986 | # endif |
989 | 987 | ||
990 | if (ioctl(fd, TIOCSWINSZ, (char *) &win)) | 988 | if (ioctl(fd, TIOCSWINSZ, (char *) &win)) |
991 | perror_msg_and_die("%s", device_name); | 989 | bb_perror_msg_and_die("%s", device_name); |
992 | } | 990 | } |
993 | 991 | ||
994 | static void display_window_size(int fancy, int fd, const char *device_name) | 992 | static void display_window_size(int fancy, int fd, const char *device_name) |
995 | { | 993 | { |
994 | const char *fmt_str = "%s" "\0" "%s: no size information for this device"; | ||
996 | struct winsize win; | 995 | struct winsize win; |
997 | 996 | ||
998 | if (get_win_size(fd, &win)) { | 997 | if (get_win_size(fd, &win)) { |
999 | if (errno != EINVAL) | 998 | if ((errno != EINVAL) || ((fmt_str += 2), !fancy)) { |
1000 | perror_msg_and_die("%s", device_name); | 999 | bb_perror_msg_and_die(fmt_str, device_name); |
1001 | if (!fancy) | 1000 | } |
1002 | perror_msg_and_die("%s: no size information for this device", | ||
1003 | device_name); | ||
1004 | } else { | 1001 | } else { |
1005 | wrapf(fancy ? "rows %d; columns %d;" : "%d %d\n", | 1002 | wrapf(fancy ? "rows %d; columns %d;" : "%d %d\n", |
1006 | win.ws_row, win.ws_col); | 1003 | win.ws_row, win.ws_col); |
@@ -1012,6 +1009,9 @@ static void display_window_size(int fancy, int fd, const char *device_name) | |||
1012 | 1009 | ||
1013 | static int screen_columns(void) | 1010 | static int screen_columns(void) |
1014 | { | 1011 | { |
1012 | int columns; | ||
1013 | const char *s; | ||
1014 | |||
1015 | #ifdef TIOCGWINSZ | 1015 | #ifdef TIOCGWINSZ |
1016 | struct winsize win; | 1016 | struct winsize win; |
1017 | 1017 | ||
@@ -1025,51 +1025,29 @@ static int screen_columns(void) | |||
1025 | return win.ws_col; | 1025 | return win.ws_col; |
1026 | #endif | 1026 | #endif |
1027 | 1027 | ||
1028 | if (getenv("COLUMNS")) | 1028 | columns = 80; |
1029 | return atoi(getenv("COLUMNS")); | 1029 | if ((s = getenv("COLUMNS"))) { |
1030 | return 80; | 1030 | columns = atoi(s); |
1031 | } | ||
1032 | |||
1033 | static tcflag_t *mode_type_flag(enum mode_type type, struct termios *mode) | ||
1034 | { | ||
1035 | switch (type) { | ||
1036 | case control: | ||
1037 | return &mode->c_cflag; | ||
1038 | |||
1039 | case input: | ||
1040 | return &mode->c_iflag; | ||
1041 | |||
1042 | case output: | ||
1043 | return &mode->c_oflag; | ||
1044 | |||
1045 | case local: | ||
1046 | return &mode->c_lflag; | ||
1047 | |||
1048 | default: /* combination: */ | ||
1049 | return NULL; | ||
1050 | } | 1031 | } |
1032 | return columns; | ||
1051 | } | 1033 | } |
1052 | 1034 | ||
1053 | static void | 1035 | static tcflag_t *mode_type_flag(enum mode_type type, struct termios *mode) |
1054 | display_settings(enum output_type output_type, struct termios *mode, | ||
1055 | int fd, const char *device_name) | ||
1056 | { | 1036 | { |
1057 | switch (output_type) { | 1037 | static const unsigned char tcflag_offsets[] = { |
1058 | case changed: | 1038 | offsetof(struct termios, c_cflag), /* control */ |
1059 | display_changed(mode); | 1039 | offsetof(struct termios, c_iflag), /* input */ |
1060 | break; | 1040 | offsetof(struct termios, c_oflag), /* output */ |
1061 | 1041 | offsetof(struct termios, c_lflag) /* local */ | |
1062 | case all: | 1042 | }; |
1063 | display_all(mode, fd, device_name); | 1043 | |
1064 | break; | 1044 | if (((unsigned int) type) <= local) { |
1065 | 1045 | return (tcflag_t *)(((char *) mode) + tcflag_offsets[(int)type]); | |
1066 | case recoverable: | ||
1067 | display_recoverable(mode); | ||
1068 | break; | ||
1069 | } | 1046 | } |
1047 | return NULL; | ||
1070 | } | 1048 | } |
1071 | 1049 | ||
1072 | static void display_changed(struct termios *mode) | 1050 | static void display_changed(struct termios *mode, int fd, const char *device_name) |
1073 | { | 1051 | { |
1074 | int i; | 1052 | int i; |
1075 | int empty_line; | 1053 | int empty_line; |
@@ -1206,18 +1184,25 @@ display_all(struct termios *mode, int fd, const char *device_name) | |||
1206 | 1184 | ||
1207 | static void display_speed(struct termios *mode, int fancy) | 1185 | static void display_speed(struct termios *mode, int fancy) |
1208 | { | 1186 | { |
1209 | if (cfgetispeed(mode) == 0 || cfgetispeed(mode) == cfgetospeed(mode)) | 1187 | unsigned long ispeed, ospeed; |
1210 | wrapf(fancy ? "speed %lu baud;" : "%lu\n", | 1188 | const char *fmt_str = |
1211 | baud_to_value(cfgetospeed(mode))); | 1189 | "%lu %lu\n\0" "ispeed %lu baud; ospeed %lu baud;\0" |
1212 | else | 1190 | "%lu\n\0" "\0\0\0\0" "speed %lu baud;"; |
1213 | wrapf(fancy ? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n", | 1191 | |
1214 | baud_to_value(cfgetispeed(mode)), | 1192 | ospeed = ispeed = cfgetispeed(mode); |
1215 | baud_to_value(cfgetospeed(mode))); | 1193 | if (ispeed == 0 || ispeed == (ospeed = cfgetospeed(mode))) { |
1194 | ispeed = ospeed; /* in case ispeed was 0 */ | ||
1195 | fmt_str += 43; | ||
1196 | } | ||
1197 | if (fancy) { | ||
1198 | fmt_str += 9; | ||
1199 | } | ||
1200 | wrapf(fmt_str, bb_baud_to_value(ispeed), bb_baud_to_value(ospeed)); | ||
1216 | if (!fancy) | 1201 | if (!fancy) |
1217 | current_col = 0; | 1202 | current_col = 0; |
1218 | } | 1203 | } |
1219 | 1204 | ||
1220 | static void display_recoverable(struct termios *mode) | 1205 | static void display_recoverable(struct termios *mode, int fd, const char *device_name) |
1221 | { | 1206 | { |
1222 | int i; | 1207 | int i; |
1223 | 1208 | ||
@@ -1259,62 +1244,9 @@ static int recover_mode(char *arg, struct termios *mode) | |||
1259 | return 1; | 1244 | return 1; |
1260 | } | 1245 | } |
1261 | 1246 | ||
1262 | struct speed_map { | ||
1263 | speed_t speed; /* Internal form. */ | ||
1264 | unsigned long value; /* Numeric value. */ | ||
1265 | }; | ||
1266 | |||
1267 | static const struct speed_map speeds[] = { | ||
1268 | {B0, 0}, | ||
1269 | {B50, 50}, | ||
1270 | {B75, 75}, | ||
1271 | {B110, 110}, | ||
1272 | {B134, 134}, | ||
1273 | {B150, 150}, | ||
1274 | {B200, 200}, | ||
1275 | {B300, 300}, | ||
1276 | {B600, 600}, | ||
1277 | {B1200, 1200}, | ||
1278 | {B1800, 1800}, | ||
1279 | {B2400, 2400}, | ||
1280 | {B4800, 4800}, | ||
1281 | {B9600, 9600}, | ||
1282 | {B19200, 19200}, | ||
1283 | {B38400, 38400}, | ||
1284 | #ifdef B57600 | ||
1285 | {B57600, 57600}, | ||
1286 | #endif | ||
1287 | #ifdef B115200 | ||
1288 | {B115200, 115200}, | ||
1289 | #endif | ||
1290 | #ifdef B230400 | ||
1291 | {B230400, 230400}, | ||
1292 | #endif | ||
1293 | #ifdef B460800 | ||
1294 | {B460800, 460800}, | ||
1295 | #endif | ||
1296 | }; | ||
1297 | |||
1298 | static const int NUM_SPEEDS = (sizeof(speeds) / sizeof(struct speed_map)); | ||
1299 | |||
1300 | static speed_t string_to_baud(const char *arg) | 1247 | static speed_t string_to_baud(const char *arg) |
1301 | { | 1248 | { |
1302 | int i; | 1249 | return bb_value_to_baud(bb_xparse_number(arg, 0)); |
1303 | |||
1304 | for (i = 0; i < NUM_SPEEDS; ++i) | ||
1305 | if (parse_number(arg, 0) == speeds[i].value) | ||
1306 | return speeds[i].speed; | ||
1307 | return (speed_t) - 1; | ||
1308 | } | ||
1309 | |||
1310 | static unsigned long baud_to_value(speed_t speed) | ||
1311 | { | ||
1312 | int i; | ||
1313 | |||
1314 | for (i = 0; i < NUM_SPEEDS; ++i) | ||
1315 | if (speed == speeds[i].speed) | ||
1316 | return speeds[i].value; | ||
1317 | return 0; | ||
1318 | } | 1250 | } |
1319 | 1251 | ||
1320 | static void sane_mode(struct termios *mode) | 1252 | static void sane_mode(struct termios *mode) |
@@ -1333,10 +1265,12 @@ static void sane_mode(struct termios *mode) | |||
1333 | for (i = 0; i < NUM_mode_info; ++i) { | 1265 | for (i = 0; i < NUM_mode_info; ++i) { |
1334 | if (mode_info[i].flags & SANE_SET) { | 1266 | if (mode_info[i].flags & SANE_SET) { |
1335 | bitsp = mode_type_flag(mode_info[i].type, mode); | 1267 | bitsp = mode_type_flag(mode_info[i].type, mode); |
1336 | *bitsp = (*bitsp & ~mode_info[i].mask) | mode_info[i].bits; | 1268 | *bitsp = (*bitsp & ~((unsigned long)mode_info[i].mask)) |
1269 | | mode_info[i].bits; | ||
1337 | } else if (mode_info[i].flags & SANE_UNSET) { | 1270 | } else if (mode_info[i].flags & SANE_UNSET) { |
1338 | bitsp = mode_type_flag(mode_info[i].type, mode); | 1271 | bitsp = mode_type_flag(mode_info[i].type, mode); |
1339 | *bitsp = *bitsp & ~mode_info[i].mask & ~mode_info[i].bits; | 1272 | *bitsp = *bitsp & ~((unsigned long)mode_info[i].mask) |
1273 | & ~mode_info[i].bits; | ||
1340 | } | 1274 | } |
1341 | } | 1275 | } |
1342 | } | 1276 | } |
@@ -1349,47 +1283,32 @@ static const char *visible(unsigned int ch) | |||
1349 | static char buf[10]; | 1283 | static char buf[10]; |
1350 | char *bpout = buf; | 1284 | char *bpout = buf; |
1351 | 1285 | ||
1352 | if (ch == _POSIX_VDISABLE) | 1286 | if (ch == _POSIX_VDISABLE) { |
1353 | return "<undef>"; | 1287 | return "<undef>"; |
1288 | } | ||
1354 | 1289 | ||
1355 | if (ch >= 32) { | 1290 | if (ch >= 128) { |
1356 | if (ch < 127) | 1291 | ch -= 128; |
1357 | *bpout++ = ch; | 1292 | *bpout++ = 'M'; |
1358 | else if (ch == 127) { | 1293 | *bpout++ = '-'; |
1359 | *bpout++ = '^'; | 1294 | } |
1360 | *bpout++ = '?'; | 1295 | |
1361 | } else { | 1296 | if (ch < 32) { |
1362 | *bpout++ = 'M', *bpout++ = '-'; | ||
1363 | if (ch >= 128 + 32) { | ||
1364 | if (ch < 128 + 127) | ||
1365 | *bpout++ = ch - 128; | ||
1366 | else { | ||
1367 | *bpout++ = '^'; | ||
1368 | *bpout++ = '?'; | ||
1369 | } | ||
1370 | } else { | ||
1371 | *bpout++ = '^'; | ||
1372 | *bpout++ = ch - 128 + 64; | ||
1373 | } | ||
1374 | } | ||
1375 | } else { | ||
1376 | *bpout++ = '^'; | 1297 | *bpout++ = '^'; |
1377 | *bpout++ = ch + 64; | 1298 | *bpout++ = ch + 64; |
1299 | } else if (ch < 127) { | ||
1300 | *bpout++ = ch; | ||
1301 | } else { | ||
1302 | *bpout++ = '^'; | ||
1303 | *bpout++ = '?'; | ||
1378 | } | 1304 | } |
1305 | |||
1379 | *bpout = '\0'; | 1306 | *bpout = '\0'; |
1380 | return (const char *) buf; | 1307 | return (const char *) buf; |
1381 | } | 1308 | } |
1382 | 1309 | ||
1383 | #ifdef TEST | 1310 | #ifdef TEST |
1384 | 1311 | ||
1385 | const char *applet_name = "stty"; | 1312 | const char *bb_applet_name = "stty"; |
1386 | 1313 | ||
1387 | #endif | 1314 | #endif |
1388 | |||
1389 | /* | ||
1390 | Local Variables: | ||
1391 | c-file-style: "linux" | ||
1392 | c-basic-offset: 4 | ||
1393 | tab-width: 4 | ||
1394 | End: | ||
1395 | */ | ||
diff --git a/coreutils/sync.c b/coreutils/sync.c index d58168065..84746311f 100644 --- a/coreutils/sync.c +++ b/coreutils/sync.c | |||
@@ -20,15 +20,17 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <stdio.h> | 23 | /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ |
24 | |||
24 | #include <stdlib.h> | 25 | #include <stdlib.h> |
25 | #include <unistd.h> | 26 | #include <unistd.h> |
26 | #include "busybox.h" | 27 | #include "busybox.h" |
27 | 28 | ||
28 | extern int sync_main(int argc, char **argv) | 29 | extern int sync_main(int argc, char **argv) |
29 | { | 30 | { |
30 | if (argc > 1 && **(argv + 1) == '-') | 31 | bb_warn_ignoring_args(argc - 1); |
31 | show_usage(); | 32 | |
32 | sync(); | 33 | sync(); |
34 | |||
33 | return(EXIT_SUCCESS); | 35 | return(EXIT_SUCCESS); |
34 | } | 36 | } |
diff --git a/coreutils/tail.c b/coreutils/tail.c index 1703eefc6..8e0adf5b5 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c | |||
@@ -2,7 +2,6 @@ | |||
2 | /* | 2 | /* |
3 | * Mini tail implementation for busybox | 3 | * Mini tail implementation for busybox |
4 | * | 4 | * |
5 | * | ||
6 | * Copyright (C) 2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu> | 5 | * Copyright (C) 2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu> |
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -21,14 +20,30 @@ | |||
21 | * | 20 | * |
22 | */ | 21 | */ |
23 | 22 | ||
23 | /* BB_AUDIT SUSv3 compliant (need fancy for -c) */ | ||
24 | /* BB_AUDIT GNU compatible -c, -q, and -v options in 'fancy' configuration. */ | ||
25 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/tail.html */ | ||
24 | 26 | ||
25 | #include <fcntl.h> | 27 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) |
26 | #include <getopt.h> | 28 | * |
29 | * Pretty much rewritten to fix numerous bugs and reduce realloc() calls. | ||
30 | * Bugs fixed (although I may have forgotten one or two... it was pretty bad) | ||
31 | * 1) mixing printf/write without fflush()ing stdout | ||
32 | * 2) no check that any open files are present | ||
33 | * 3) optstring had -q taking an arg | ||
34 | * 4) no error checking on write in some cases, and a warning even then | ||
35 | * 5) q and s interaction bug | ||
36 | * 6) no check for lseek error | ||
37 | * 7) lseek attempted when count==0 even if arg was +0 (from top) | ||
38 | */ | ||
39 | |||
40 | #include <stdio.h> | ||
41 | #include <stdlib.h> | ||
27 | #include <string.h> | 42 | #include <string.h> |
28 | #include <ctype.h> | 43 | #include <ctype.h> |
29 | #include <stdlib.h> | ||
30 | #include <unistd.h> | 44 | #include <unistd.h> |
31 | #include <sys/types.h> | 45 | #include <fcntl.h> |
46 | #include <sys/stat.h> | ||
32 | #include "busybox.h" | 47 | #include "busybox.h" |
33 | 48 | ||
34 | static const struct suffix_mult tail_suffixes[] = { | 49 | static const struct suffix_mult tail_suffixes[] = { |
@@ -38,234 +53,287 @@ static const struct suffix_mult tail_suffixes[] = { | |||
38 | { NULL, 0 } | 53 | { NULL, 0 } |
39 | }; | 54 | }; |
40 | 55 | ||
41 | static const int BYTES = 0; | 56 | static int status |
42 | static const int LINES = 1; | 57 | #if EXIT_SUCCESS != 0 |
43 | 58 | = EXIT_SUCCESS /* If it is 0 (paranoid check), let bss initialize it. */ | |
44 | static char *tailbuf; | 59 | #endif |
45 | static int taillen; | 60 | ; |
46 | static int newline; | ||
47 | 61 | ||
48 | static void tailbuf_append(char *buf, int len) | 62 | static void tail_xprint_header(const char *fmt, const char *filename) |
49 | { | 63 | { |
50 | tailbuf = xrealloc(tailbuf, taillen + len); | 64 | /* If we get an output error, there is really no sense in continuing. */ |
51 | memcpy(tailbuf + taillen, buf, len); | 65 | if (dprintf(STDOUT_FILENO, fmt, filename) < 0) { |
52 | taillen += len; | 66 | bb_perror_nomsg_and_die(); |
67 | } | ||
53 | } | 68 | } |
54 | 69 | ||
55 | static void tailbuf_trunc(void) | 70 | /* len should probably be size_t */ |
71 | static void tail_xbb_full_write(const char *buf, size_t len) | ||
56 | { | 72 | { |
57 | char *s; | 73 | /* If we get a write error, there is really no sense in continuing. */ |
58 | s = memchr(tailbuf, '\n', taillen); | 74 | if (bb_full_write(STDOUT_FILENO, buf, len) < 0) { |
59 | memmove(tailbuf, s + 1, taillen - ((s + 1) - tailbuf)); | 75 | bb_perror_nomsg_and_die(); |
60 | taillen -= (s + 1) - tailbuf; | 76 | } |
61 | newline = 0; | ||
62 | } | 77 | } |
63 | 78 | ||
64 | int tail_main(int argc, char **argv) | 79 | static ssize_t tail_read(int fd, char *buf, size_t count) |
65 | { | 80 | { |
66 | int from_top = 0, units = LINES, count = 10, sleep_period = 1; | 81 | ssize_t r; |
67 | int show_headers = 0, hide_headers = 0, follow = 0; | 82 | |
68 | int *fds, nfiles = 0, status = EXIT_SUCCESS, nread, nwrite, seen = 0; | 83 | if ((r = safe_read(fd, buf, count)) < 0) { |
69 | char *s, *start, *end, buf[BUFSIZ]; | 84 | bb_perror_msg("read"); |
70 | int i, opt; | 85 | status = EXIT_FAILURE; |
71 | |||
72 | if (argc >= 2) { | ||
73 | int line_num; | ||
74 | switch (argv[1][0]) { | ||
75 | case '+': | ||
76 | from_top = 1; | ||
77 | /* FALLS THROUGH */ | ||
78 | case '-': | ||
79 | line_num = atoi(&argv[1][1]); | ||
80 | if (line_num != 0) { | ||
81 | optind = 2; | ||
82 | count = line_num; | ||
83 | } | ||
84 | break; | ||
85 | } | ||
86 | } | 86 | } |
87 | 87 | ||
88 | return r; | ||
89 | } | ||
90 | |||
91 | static const char tail_opts[] = | ||
92 | "fn:" | ||
93 | #ifdef CONFIG_FEATURE_FANCY_TAIL | ||
94 | "c:qs:v" | ||
95 | #endif | ||
96 | ; | ||
97 | |||
98 | static const char header_fmt[] = "\n==> %s <==\n"; | ||
99 | |||
100 | int tail_main(int argc, char **argv) | ||
101 | { | ||
102 | long count = 10; | ||
103 | unsigned int sleep_period = 1; | ||
104 | int from_top = 0; | ||
105 | int follow = 0; | ||
106 | int header_threshhold = 1; | ||
88 | #ifdef CONFIG_FEATURE_FANCY_TAIL | 107 | #ifdef CONFIG_FEATURE_FANCY_TAIL |
89 | while ((opt = getopt(argc, argv, "c:fn:q:s:v")) > 0) { | 108 | int count_bytes = 0; |
90 | #else | ||
91 | while ((opt = getopt(argc, argv, "fn:")) > 0) { | ||
92 | #endif | 109 | #endif |
110 | |||
111 | char *tailbuf; | ||
112 | size_t tailbufsize; | ||
113 | int taillen = 0; | ||
114 | int newline = 0; | ||
115 | |||
116 | int *fds, nfiles, nread, nwrite, seen, i, opt; | ||
117 | char *s, *buf; | ||
118 | const char *fmt; | ||
119 | |||
120 | /* Allow legacy syntax of an initial numeric option without -n. */ | ||
121 | if ((argv[1][0] == '+') | ||
122 | || ((argv[1][0] == '-') | ||
123 | /* && (isdigit)(argv[1][1]) */ | ||
124 | && (((unsigned int)(argv[1][1] - '0')) <= 9)) | ||
125 | ) { | ||
126 | optind = 2; | ||
127 | optarg = argv[1]; | ||
128 | goto GET_COUNT; | ||
129 | } | ||
130 | |||
131 | while ((opt = getopt(argc, argv, tail_opts)) > 0) { | ||
93 | switch (opt) { | 132 | switch (opt) { |
94 | case 'f': | 133 | case 'f': |
95 | follow = 1; | 134 | follow = 1; |
96 | break; | 135 | break; |
97 | #ifdef CONFIG_FEATURE_FANCY_TAIL | 136 | #ifdef CONFIG_FEATURE_FANCY_TAIL |
98 | case 'c': | 137 | case 'c': |
99 | units = BYTES; | 138 | count_bytes = 1; |
100 | /* FALLS THROUGH */ | 139 | /* FALLS THROUGH */ |
101 | #endif | 140 | #endif |
102 | case 'n': | 141 | case 'n': |
103 | count = parse_number(optarg, tail_suffixes); | 142 | GET_COUNT: |
104 | if (count < 0) | 143 | count = bb_xgetlarg10_sfx(optarg, tail_suffixes); |
105 | count = -count; | 144 | /* Note: Leading whitespace is an error trapped above. */ |
106 | if (optarg[0] == '+') | 145 | if (*optarg == '+') { |
107 | from_top = 1; | 146 | from_top = 1; |
147 | } else { | ||
148 | from_top = 0; | ||
149 | } | ||
150 | if (count < 0) { | ||
151 | count = -count; | ||
152 | } | ||
108 | break; | 153 | break; |
109 | #ifdef CONFIG_FEATURE_FANCY_TAIL | 154 | #ifdef CONFIG_FEATURE_FANCY_TAIL |
110 | case 'q': | 155 | case 'q': |
111 | hide_headers = 1; | 156 | header_threshhold = INT_MAX; |
112 | break; | 157 | break; |
113 | case 's': | 158 | case 's': |
114 | sleep_period = parse_number(optarg, 0); | 159 | sleep_period =bb_xgetularg10_bnd(optarg, 0, UINT_MAX); |
115 | break; | 160 | break; |
116 | case 'v': | 161 | case 'v': |
117 | show_headers = 1; | 162 | header_threshhold = 0; |
118 | break; | 163 | break; |
119 | #endif | 164 | #endif |
120 | default: | 165 | default: |
121 | show_usage(); | 166 | bb_show_usage(); |
122 | } | 167 | } |
123 | } | 168 | } |
124 | 169 | ||
125 | /* open all the files */ | 170 | /* open all the files */ |
126 | fds = (int *)xmalloc(sizeof(int) * (argc - optind + 1)); | 171 | fds = (int *)xmalloc(sizeof(int) * (argc - optind + 1)); |
127 | if (argc == optind) { | 172 | |
128 | fds[nfiles++] = STDIN_FILENO; | 173 | argv += optind; |
129 | argv[optind] = "standard input"; | 174 | nfiles = i = 0; |
130 | } else { | 175 | |
131 | for (i = optind; i < argc; i++) { | 176 | if ((argc -= optind) == 0) { |
132 | if (strcmp(argv[i], "-") == 0) { | 177 | struct stat statbuf; |
133 | fds[nfiles++] = STDIN_FILENO; | 178 | |
134 | argv[i] = "standard input"; | 179 | if (!fstat(STDIN_FILENO, &statbuf) && S_ISFIFO(statbuf.st_mode)) { |
135 | } else if ((fds[nfiles++] = open(argv[i], O_RDONLY)) < 0) { | 180 | follow = 0; |
136 | perror_msg("%s", argv[i]); | ||
137 | status = EXIT_FAILURE; | ||
138 | } | ||
139 | } | 181 | } |
182 | /* --argv; */ | ||
183 | *argv = (char *) bb_msg_standard_input; | ||
184 | goto DO_STDIN; | ||
185 | } | ||
186 | |||
187 | do { | ||
188 | if ((argv[i][0] == '-') && !argv[i][1]) { | ||
189 | DO_STDIN: | ||
190 | fds[nfiles] = STDIN_FILENO; | ||
191 | } else if ((fds[nfiles] = open(argv[i], O_RDONLY)) < 0) { | ||
192 | bb_perror_msg("%s", argv[i]); | ||
193 | status = EXIT_FAILURE; | ||
194 | continue; | ||
195 | } | ||
196 | argv[nfiles] = argv[i]; | ||
197 | ++nfiles; | ||
198 | } while (++i < argc); | ||
199 | |||
200 | if (!nfiles) { | ||
201 | bb_error_msg_and_die("no files"); | ||
140 | } | 202 | } |
141 | 203 | ||
204 | tailbufsize = BUFSIZ; | ||
142 | #ifdef CONFIG_FEATURE_FANCY_TAIL | 205 | #ifdef CONFIG_FEATURE_FANCY_TAIL |
143 | /* tail the files */ | 206 | /* tail the files */ |
144 | if (!from_top && units == BYTES) | 207 | if (from_top < count_bytes) { /* Each is 0 or 1, so true iff 0 < 1. */ |
145 | tailbuf = xmalloc(count); | 208 | /* Hence, !from_top && count_bytes */ |
209 | if (tailbufsize < count) { | ||
210 | tailbufsize = count + BUFSIZ; | ||
211 | } | ||
212 | } | ||
146 | #endif | 213 | #endif |
214 | buf = tailbuf = xmalloc(tailbufsize); | ||
147 | 215 | ||
148 | for (i = 0; i < nfiles; i++) { | 216 | fmt = header_fmt + 1; /* Skip header leading newline on first output. */ |
149 | if (fds[i] == -1) | 217 | i = 0; |
150 | continue; | 218 | do { |
151 | if (!count) { | 219 | /* Be careful. It would be possible to optimize the count-bytes |
152 | lseek(fds[i], 0, SEEK_END); | 220 | * case if the file is seekable. If you do though, remember that |
221 | * starting file position may not be the beginning of the file. | ||
222 | * Beware of backing up too far. See example in wc.c. | ||
223 | */ | ||
224 | if ((!(count|from_top)) && (lseek(fds[i], 0, SEEK_END) >= 0)) { | ||
153 | continue; | 225 | continue; |
154 | } | 226 | } |
155 | seen = 0; | 227 | |
156 | if (show_headers || (!hide_headers && nfiles > 1)) | 228 | if (nfiles > header_threshhold) { |
157 | printf("%s==> %s <==\n", i == 0 ? "" : "\n", argv[optind + i]); | 229 | tail_xprint_header(fmt, argv[i]); |
158 | while ((nread = safe_read(fds[i], buf, sizeof(buf))) > 0) { | 230 | fmt = header_fmt; |
231 | } | ||
232 | |||
233 | buf = tailbuf; | ||
234 | taillen = 0; | ||
235 | seen = 1; | ||
236 | |||
237 | while ((nread = tail_read(fds[i], buf, tailbufsize-taillen)) > 0) { | ||
159 | if (from_top) { | 238 | if (from_top) { |
239 | nwrite = nread; | ||
240 | if (seen < count) { | ||
160 | #ifdef CONFIG_FEATURE_FANCY_TAIL | 241 | #ifdef CONFIG_FEATURE_FANCY_TAIL |
161 | if (units == BYTES) { | 242 | if (count_bytes) { |
162 | if (count - 1 <= seen) | 243 | nwrite -= (count - seen); |
163 | nwrite = nread; | 244 | seen = count; |
164 | else if (count - 1 <= seen + nread) | 245 | } else |
165 | nwrite = nread + seen - (count - 1); | ||
166 | else | ||
167 | nwrite = 0; | ||
168 | seen += nread; | ||
169 | } else { | ||
170 | #else | ||
171 | { | ||
172 | #endif | 246 | #endif |
173 | if (count - 1 <= seen) | 247 | { |
174 | nwrite = nread; | 248 | s = buf; |
175 | else { | 249 | do { |
176 | nwrite = 0; | 250 | --nwrite; |
177 | for (s = memchr(buf, '\n', nread); s != NULL; | 251 | if ((*s++ == '\n') && (++seen == count)) { |
178 | s = memchr(s+1, '\n', nread - (s + 1 - buf))) { | ||
179 | if (count - 1 <= ++seen) { | ||
180 | nwrite = nread - (s + 1 - buf); | ||
181 | break; | 252 | break; |
182 | } | 253 | } |
183 | } | 254 | } while (nwrite); |
184 | } | 255 | } |
185 | } | 256 | } |
186 | if (full_write(STDOUT_FILENO, buf + nread - nwrite, | 257 | tail_xbb_full_write(buf + nread - nwrite, nwrite); |
187 | nwrite) < 0) { | 258 | } else if (count) { |
188 | perror_msg("write"); | ||
189 | status = EXIT_FAILURE; | ||
190 | break; | ||
191 | } | ||
192 | } else { | ||
193 | #ifdef CONFIG_FEATURE_FANCY_TAIL | 259 | #ifdef CONFIG_FEATURE_FANCY_TAIL |
194 | if (units == BYTES) { | 260 | if (count_bytes) { |
195 | if (nread < count) { | 261 | taillen += nread; |
196 | memmove(tailbuf, tailbuf + nread, count - nread); | 262 | if (taillen > count) { |
197 | memcpy(tailbuf + count - nread, buf, nread); | 263 | memmove(tailbuf, tailbuf + taillen - count, count); |
198 | } else { | 264 | taillen = count; |
199 | memcpy(tailbuf, buf + nread - count, count); | ||
200 | } | 265 | } |
201 | seen += nread; | 266 | } else |
202 | } else { | ||
203 | #else | ||
204 | { | ||
205 | #endif | 267 | #endif |
206 | for (start = buf, end = memchr(buf, '\n', nread); | 268 | { |
207 | end != NULL; start = end+1, | 269 | int k = nread; |
208 | end = memchr(start, '\n', nread - (start - buf))) { | 270 | int nbuf = 0; |
209 | if (newline && count <= seen) | 271 | |
210 | tailbuf_trunc(); | 272 | while (k) { |
211 | tailbuf_append(start, end - start + 1); | 273 | --k; |
212 | seen++; | 274 | if (buf[k] == '\n') { |
213 | newline = 1; | 275 | ++nbuf; |
276 | } | ||
214 | } | 277 | } |
215 | if (newline && count <= seen && nread - (start - buf) > 0) | ||
216 | tailbuf_trunc(); | ||
217 | tailbuf_append(start, nread - (start - buf)); | ||
218 | } | ||
219 | } | ||
220 | } | ||
221 | 278 | ||
222 | if (nread < 0) { | 279 | if (newline + nbuf < count) { |
223 | perror_msg("read"); | 280 | newline += nbuf; |
224 | status = EXIT_FAILURE; | 281 | taillen += nread; |
225 | } | ||
226 | 282 | ||
227 | #ifdef CONFIG_FEATURE_FANCY_TAIL | 283 | } else { |
228 | if (!from_top && units == BYTES) { | 284 | int extra = 0; |
229 | if (count < seen) | 285 | if (buf[nread-1] != '\n') { |
230 | seen = count; | 286 | extra = 1; |
231 | if (full_write(STDOUT_FILENO, tailbuf + count - seen, seen) < 0) { | 287 | } |
232 | perror_msg("write"); | 288 | |
233 | status = EXIT_FAILURE; | 289 | k = newline + nbuf + extra - count; |
290 | s = tailbuf; | ||
291 | while (k) { | ||
292 | if (*s == '\n') { | ||
293 | --k; | ||
294 | } | ||
295 | ++s; | ||
296 | } | ||
297 | |||
298 | taillen += nread - (s - tailbuf); | ||
299 | memmove(tailbuf, s, taillen); | ||
300 | newline = count - extra; | ||
301 | } | ||
302 | if (tailbufsize < taillen + BUFSIZ) { | ||
303 | tailbufsize = taillen + BUFSIZ; | ||
304 | tailbuf = xrealloc(tailbuf, tailbufsize); | ||
305 | } | ||
306 | } | ||
307 | buf = tailbuf + taillen; | ||
234 | } | 308 | } |
235 | } | 309 | } |
236 | #endif | ||
237 | 310 | ||
238 | if (!from_top && units == LINES) { | 311 | if (!from_top) { |
239 | if (full_write(STDOUT_FILENO, tailbuf, taillen) < 0) { | 312 | tail_xbb_full_write(tailbuf, taillen); |
240 | perror_msg("write"); | ||
241 | status = EXIT_FAILURE; | ||
242 | } | ||
243 | } | 313 | } |
244 | 314 | ||
245 | taillen = 0; | 315 | taillen = 0; |
246 | } | 316 | } while (++i < nfiles); |
247 | |||
248 | while (follow) { | ||
249 | sleep(sleep_period); | ||
250 | 317 | ||
251 | for (i = 0; i < nfiles; i++) { | 318 | buf = xrealloc(tailbuf, BUFSIZ); |
252 | if (fds[i] == -1) | ||
253 | continue; | ||
254 | 319 | ||
255 | if ((nread = safe_read(fds[i], buf, sizeof(buf))) > 0) { | 320 | fmt = NULL; |
256 | if (show_headers || (!hide_headers && nfiles > 1)) | ||
257 | printf("\n==> %s <==\n", argv[optind + i]); | ||
258 | 321 | ||
259 | do { | 322 | while (follow) { |
260 | full_write(STDOUT_FILENO, buf, nread); | 323 | sleep(sleep_period); |
261 | } while ((nread = safe_read(fds[i], buf, sizeof(buf))) > 0); | 324 | i = 0; |
325 | do { | ||
326 | if (nfiles > header_threshhold) { | ||
327 | fmt = header_fmt; | ||
262 | } | 328 | } |
263 | 329 | while ((nread = tail_read(fds[i], buf, sizeof(buf))) > 0) { | |
264 | if (nread < 0) { | 330 | if (fmt) { |
265 | perror_msg("read"); | 331 | tail_xprint_header(fmt, argv[i]); |
266 | status = EXIT_FAILURE; | 332 | fmt = NULL; |
333 | } | ||
334 | tail_xbb_full_write(buf, nread); | ||
267 | } | 335 | } |
268 | } | 336 | } while (++i < nfiles); |
269 | } | 337 | } |
270 | 338 | ||
271 | return status; | 339 | return status; |
diff --git a/coreutils/tee.c b/coreutils/tee.c index 1c145426a..7e86f2e29 100644 --- a/coreutils/tee.c +++ b/coreutils/tee.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini tee implementation for busybox | 3 | * tee implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 2000,2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu> | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -20,47 +20,96 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include "busybox.h" | 23 | /* BB_AUDIT SUSv3 compliant */ |
24 | #include <getopt.h> | 24 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */ |
25 | |||
25 | #include <stdio.h> | 26 | #include <stdio.h> |
27 | #include <stdlib.h> | ||
28 | #include <signal.h> | ||
29 | #include <unistd.h> | ||
30 | #include "busybox.h" | ||
26 | 31 | ||
27 | int | 32 | int tee_main(int argc, char **argv) |
28 | tee_main(int argc, char **argv) | ||
29 | { | 33 | { |
30 | char *mode = "w"; | 34 | const char *mode = "w\0a"; |
31 | int c, i, status = 0, nfiles = 0; | ||
32 | FILE **files; | 35 | FILE **files; |
36 | FILE **p; | ||
37 | char **filenames; | ||
38 | int flags; | ||
39 | int retval = EXIT_SUCCESS; | ||
40 | #ifdef CONFIG_FEATURE_TEE_USE_BLOCK_IO | ||
41 | size_t c; | ||
42 | RESERVE_CONFIG_BUFFER(buf, BUFSIZ); | ||
43 | #else | ||
44 | int c; | ||
45 | #endif | ||
46 | |||
47 | flags = bb_getopt_ulflags(argc, argv, "ia"); /* 'a' must be 2nd */ | ||
48 | |||
49 | mode += (flags & 2); /* Since 'a' is the 2nd option... */ | ||
50 | |||
51 | if (flags & 1) { | ||
52 | signal(SIGINT, SIG_IGN); /* TODO - switch to sigaction.*/ | ||
53 | } | ||
54 | |||
55 | /* gnu tee ignores SIGPIPE in case one of the output files is a pipe | ||
56 | * that doesn't consume all its input. Good idea... */ | ||
57 | signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction.*/ | ||
33 | 58 | ||
34 | while ((c = getopt(argc, argv, "a")) != EOF) { | 59 | /* Allocate an array of FILE *'s, with one extra for a sentinal. */ |
35 | switch (c) { | 60 | p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2)); |
36 | case 'a': | 61 | *p = stdout; |
37 | mode = "a"; | 62 | argv += optind - 1; |
38 | break; | 63 | filenames = argv - 1; |
39 | default: | 64 | *filenames = (char *) bb_msg_standard_input; /* for later */ |
40 | show_usage(); | 65 | goto GOT_NEW_FILE; |
66 | |||
67 | do { | ||
68 | if ((*p = bb_wfopen(*argv, mode)) == NULL) { | ||
69 | retval = EXIT_FAILURE; | ||
70 | continue; | ||
71 | } | ||
72 | filenames[(int)(p - files)] = *argv; | ||
73 | GOT_NEW_FILE: | ||
74 | setbuf(*p, NULL); /* tee must not buffer output. */ | ||
75 | ++p; | ||
76 | } while (*++argv); | ||
77 | |||
78 | *p = NULL; /* Store the sentinal value. */ | ||
79 | |||
80 | #ifdef CONFIG_FEATURE_TEE_USE_BLOCK_IO | ||
81 | while ((c = fread(buf, 1, BUFSIZ, stdin)) != 0) { | ||
82 | for (p=files ; *p ; p++) { | ||
83 | fwrite(buf, 1, c, *p); | ||
41 | } | 84 | } |
42 | } | 85 | } |
43 | 86 | ||
44 | files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 1)); | 87 | #ifdef CONFIG_FEATURE_CLEAN_UP |
45 | files[nfiles++] = stdout; | 88 | RELEASE_CONFIG_BUFFER(buf); |
46 | while (optind < argc) { | 89 | #endif |
47 | if ((files[nfiles++] = wfopen(argv[optind++], mode)) == NULL) { | 90 | |
48 | nfiles--; | 91 | #else |
49 | status = 1; | 92 | while ((c = getchar()) != EOF) { |
93 | for (p=files ; *p ; p++) { | ||
94 | putc(c, *p); | ||
50 | } | 95 | } |
51 | } | 96 | } |
97 | #endif | ||
52 | 98 | ||
53 | while ((c = getchar()) != EOF) | 99 | /* Now we need to check for i/o errors on stdin and the various |
54 | for (i = 0; i < nfiles; i++) | 100 | * output files. Since we know that the first entry in the output |
55 | putc(c, files[i]); | 101 | * file table is stdout, we can save one "if ferror" test by |
102 | * setting the first entry to stdin and checking stdout error | ||
103 | * status with bb_fflush_stdout_and_exit()... although fflush()ing | ||
104 | * is unnecessary here. */ | ||
56 | 105 | ||
57 | return status; | 106 | p = files; |
58 | } | 107 | *p = stdin; |
108 | do { /* Now check for (input and) output errors. */ | ||
109 | /* Checking ferror should be sufficient, but we may want to fclose. | ||
110 | * If we do, remember not to close stdin! */ | ||
111 | bb_xferror(*p, filenames[(int)(p - files)]); | ||
112 | } while (*++p); | ||
59 | 113 | ||
60 | /* | 114 | bb_fflush_stdout_and_exit(retval); |
61 | Local Variables: | 115 | } |
62 | c-file-style: "linux" | ||
63 | c-basic-offset: 4 | ||
64 | tab-width: 4 | ||
65 | End: | ||
66 | */ | ||
diff --git a/coreutils/test.c b/coreutils/test.c index 83e31ea5c..0bce66e6f 100644 --- a/coreutils/test.c +++ b/coreutils/test.c | |||
@@ -180,9 +180,9 @@ extern int test_main(int argc, char **argv) | |||
180 | { | 180 | { |
181 | int res; | 181 | int res; |
182 | 182 | ||
183 | if (strcmp(applet_name, "[") == 0) { | 183 | if (strcmp(bb_applet_name, "[") == 0) { |
184 | if (strcmp(argv[--argc], "]")) | 184 | if (strcmp(argv[--argc], "]")) |
185 | error_msg_and_die("missing ]"); | 185 | bb_error_msg_and_die("missing ]"); |
186 | argv[argc] = NULL; | 186 | argv[argc] = NULL; |
187 | } | 187 | } |
188 | /* Implement special cases from POSIX.2, section 4.62.4 */ | 188 | /* Implement special cases from POSIX.2, section 4.62.4 */ |
@@ -226,9 +226,9 @@ extern int test_main(int argc, char **argv) | |||
226 | static void syntax(const char *op, const char *msg) | 226 | static void syntax(const char *op, const char *msg) |
227 | { | 227 | { |
228 | if (op && *op) { | 228 | if (op && *op) { |
229 | error_msg_and_die("%s: %s", op, msg); | 229 | bb_error_msg_and_die("%s: %s", op, msg); |
230 | } else { | 230 | } else { |
231 | error_msg_and_die("%s", msg); | 231 | bb_error_msg_and_die("%s", msg); |
232 | } | 232 | } |
233 | } | 233 | } |
234 | 234 | ||
@@ -450,13 +450,13 @@ static int getn(const char *s) | |||
450 | r = strtol(s, &p, 10); | 450 | r = strtol(s, &p, 10); |
451 | 451 | ||
452 | if (errno != 0) | 452 | if (errno != 0) |
453 | error_msg_and_die("%s: out of range", s); | 453 | bb_error_msg_and_die("%s: out of range", s); |
454 | 454 | ||
455 | while (isspace(*p)) | 455 | while (isspace(*p)) |
456 | p++; | 456 | p++; |
457 | 457 | ||
458 | if (*p) | 458 | if (*p) |
459 | error_msg_and_die("%s: bad number", s); | 459 | bb_error_msg_and_die("%s: bad number", s); |
460 | 460 | ||
461 | return (int) r; | 461 | return (int) r; |
462 | } | 462 | } |
diff --git a/coreutils/touch.c b/coreutils/touch.c index f1c6dc484..c66f26e0d 100644 --- a/coreutils/touch.c +++ b/coreutils/touch.c | |||
@@ -21,6 +21,16 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* BB_AUDIT SUSv3 _NOT_ compliant -- options -a, -m, -r, -t not supported. */ | ||
25 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/touch.html */ | ||
26 | |||
27 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
28 | * | ||
29 | * Previous version called open() and then utime(). While this will be | ||
30 | * be necessary to implement -r and -t, it currently only makes things bigger. | ||
31 | * Also, exiting on a failure was a bug. All args should be processed. | ||
32 | */ | ||
33 | |||
24 | #include <stdio.h> | 34 | #include <stdio.h> |
25 | #include <sys/types.h> | 35 | #include <sys/types.h> |
26 | #include <fcntl.h> | 36 | #include <fcntl.h> |
@@ -33,44 +43,35 @@ | |||
33 | extern int touch_main(int argc, char **argv) | 43 | extern int touch_main(int argc, char **argv) |
34 | { | 44 | { |
35 | int fd; | 45 | int fd; |
36 | int create = TRUE; | 46 | int flags; |
47 | int status = EXIT_SUCCESS; | ||
37 | 48 | ||
38 | /* Parse options */ | 49 | flags = bb_getopt_ulflags(argc, argv, "c"); |
39 | while (--argc > 0 && **(++argv) == '-') { | 50 | |
40 | while (*(++(*argv))) { | 51 | argv += optind; |
41 | switch (**argv) { | ||
42 | case 'c': | ||
43 | create = FALSE; | ||
44 | break; | ||
45 | default: | ||
46 | show_usage(); | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | 52 | ||
51 | if (argc < 1) { | 53 | if (!*argv) { |
52 | show_usage(); | 54 | bb_show_usage(); |
53 | } | 55 | } |
54 | 56 | ||
55 | while (argc > 0) { | 57 | do { |
56 | fd = open(*argv, create ? O_RDWR | O_CREAT : O_RDWR, | ||
57 | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); | ||
58 | if (fd < 0) { | ||
59 | if (! create && errno == ENOENT) { | ||
60 | argc--; | ||
61 | argv++; | ||
62 | continue; | ||
63 | } else { | ||
64 | perror_msg_and_die("%s", *argv); | ||
65 | } | ||
66 | } | ||
67 | close(fd); | ||
68 | if (utime(*argv, NULL)) { | 58 | if (utime(*argv, NULL)) { |
69 | perror_msg_and_die("%s", *argv); | 59 | if (errno == ENOENT) { /* no such file*/ |
60 | if (flags & 1) { /* Creation is disabled, so ignore. */ | ||
61 | continue; | ||
62 | } | ||
63 | /* Try to create the file. */ | ||
64 | fd = open(*argv, O_RDWR | O_CREAT, | ||
65 | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | ||
66 | ); | ||
67 | if ((fd >= 0) && !close(fd)) { | ||
68 | continue; | ||
69 | } | ||
70 | } | ||
71 | status = EXIT_FAILURE; | ||
72 | bb_perror_msg("%s", *argv); | ||
70 | } | 73 | } |
71 | argc--; | 74 | } while (*++argv); |
72 | argv++; | ||
73 | } | ||
74 | 75 | ||
75 | return EXIT_SUCCESS; | 76 | return status; |
76 | } | 77 | } |
diff --git a/coreutils/tr.c b/coreutils/tr.c index e2a4ef6c5..a00e36134 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c | |||
@@ -54,7 +54,7 @@ static void convert(void) | |||
54 | if (in_index == read_chars) { | 54 | if (in_index == read_chars) { |
55 | if ((read_chars = read(0, (char *) pinput, BUFSIZ)) <= 0) { | 55 | if ((read_chars = read(0, (char *) pinput, BUFSIZ)) <= 0) { |
56 | if (write(1, (char *) poutput, out_index) != out_index) | 56 | if (write(1, (char *) poutput, out_index) != out_index) |
57 | error_msg("%s", write_error); | 57 | bb_error_msg(bb_msg_write_error); |
58 | exit(0); | 58 | exit(0); |
59 | } | 59 | } |
60 | in_index = 0; | 60 | in_index = 0; |
@@ -68,7 +68,7 @@ static void convert(void) | |||
68 | poutput[out_index++] = last = coded; | 68 | poutput[out_index++] = last = coded; |
69 | if (out_index == BUFSIZ) { | 69 | if (out_index == BUFSIZ) { |
70 | if (write(1, (char *) poutput, out_index) != out_index) | 70 | if (write(1, (char *) poutput, out_index) != out_index) |
71 | error_msg_and_die("%s", write_error); | 71 | bb_error_msg_and_die(bb_msg_write_error); |
72 | out_index = 0; | 72 | out_index = 0; |
73 | } | 73 | } |
74 | } | 74 | } |
@@ -102,7 +102,7 @@ static unsigned int expand(const char *arg, register unsigned char *buffer) | |||
102 | while (*arg) { | 102 | while (*arg) { |
103 | if (*arg == '\\') { | 103 | if (*arg == '\\') { |
104 | arg++; | 104 | arg++; |
105 | *buffer++ = process_escape_sequence(&arg); | 105 | *buffer++ = bb_process_escape_sequence(&arg); |
106 | } else if (*(arg+1) == '-') { | 106 | } else if (*(arg+1) == '-') { |
107 | ac = *(arg+2); | 107 | ac = *(arg+2); |
108 | if(ac == 0) { | 108 | if(ac == 0) { |
@@ -181,7 +181,7 @@ extern int tr_main(int argc, char **argv) | |||
181 | sq_fl = TRUE; | 181 | sq_fl = TRUE; |
182 | break; | 182 | break; |
183 | default: | 183 | default: |
184 | show_usage(); | 184 | bb_show_usage(); |
185 | } | 185 | } |
186 | } | 186 | } |
187 | idx++; | 187 | idx++; |
@@ -197,7 +197,7 @@ extern int tr_main(int argc, char **argv) | |||
197 | input_length = complement(input, input_length); | 197 | input_length = complement(input, input_length); |
198 | if (argv[idx] != NULL) { | 198 | if (argv[idx] != NULL) { |
199 | if (*argv[idx] == '\0') | 199 | if (*argv[idx] == '\0') |
200 | error_msg_and_die("STRING2 cannot be empty"); | 200 | bb_error_msg_and_die("STRING2 cannot be empty"); |
201 | output_length = expand(argv[idx], output); | 201 | output_length = expand(argv[idx], output); |
202 | map(input, input_length, output, output_length); | 202 | map(input, input_length, output, output_length); |
203 | } | 203 | } |
diff --git a/coreutils/true.c b/coreutils/true.c index 9644aad4a..0fbe1023d 100644 --- a/coreutils/true.c +++ b/coreutils/true.c | |||
@@ -21,7 +21,8 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* getopt not needed */ | 24 | /* BB_AUDIT SUSv3 compliant */ |
25 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/true.html */ | ||
25 | 26 | ||
26 | #include <stdlib.h> | 27 | #include <stdlib.h> |
27 | #include "busybox.h" | 28 | #include "busybox.h" |
diff --git a/coreutils/tty.c b/coreutils/tty.c index 4510c2996..cd2c784fd 100644 --- a/coreutils/tty.c +++ b/coreutils/tty.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini tty implementation for busybox | 3 | * tty implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 2000 Edward Betts <edward@debian.org>. | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -20,25 +20,39 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* BB_AUDIT SUSv3 compliant */ | ||
24 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/tty.html */ | ||
25 | |||
23 | #include <stdio.h> | 26 | #include <stdio.h> |
24 | #include <stdlib.h> | 27 | #include <stdlib.h> |
25 | #include <unistd.h> | 28 | #include <unistd.h> |
26 | #include <sys/types.h> | ||
27 | #include "busybox.h" | 29 | #include "busybox.h" |
28 | 30 | ||
29 | extern int tty_main(int argc, char **argv) | 31 | extern int tty_main(int argc, char **argv) |
30 | { | 32 | { |
31 | char *tty; | 33 | const char *s; |
32 | 34 | int silent; /* Note: No longer relevant in SUSv3. */ | |
33 | if (argc > 1) { | 35 | int retval; |
34 | if (argv[1][0] != '-' || argv[1][1] != 's') | 36 | |
35 | show_usage(); | 37 | bb_default_error_retval = 2; /* SUSv3 requires > 1 for error. */ |
36 | } else { | 38 | |
37 | tty = ttyname(0); | 39 | silent = bb_getopt_ulflags(argc, argv, "s"); |
38 | if (tty) | 40 | |
39 | puts(tty); | 41 | /* gnu tty outputs a warning that it is ignoring all args. */ |
40 | else | 42 | bb_warn_ignoring_args(argc - optind); |
41 | puts("not a tty"); | 43 | |
44 | retval = 0; | ||
45 | |||
46 | if ((s = ttyname(0)) == NULL) { | ||
47 | /* According to SUSv3, ttyname can on fail with EBADF or ENOTTY. | ||
48 | * We know the file descriptor is good, so failure means not a tty. */ | ||
49 | s = "not a tty"; | ||
50 | retval = 1; | ||
51 | } | ||
52 | |||
53 | if (!silent) { | ||
54 | puts(s); | ||
42 | } | 55 | } |
43 | return(isatty(0) ? EXIT_SUCCESS : EXIT_FAILURE); | 56 | |
57 | bb_fflush_stdout_and_exit(retval); | ||
44 | } | 58 | } |
diff --git a/coreutils/uname.c b/coreutils/uname.c index df4f14ea0..a3e52e39f 100644 --- a/coreutils/uname.c +++ b/coreutils/uname.c | |||
@@ -16,6 +16,9 @@ | |||
16 | along with this program; if not, write to the Free Software Foundation, | 16 | along with this program; if not, write to the Free Software Foundation, |
17 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | 17 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
18 | 18 | ||
19 | /* BB_AUDIT SUSv3 compliant */ | ||
20 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/uname.html */ | ||
21 | |||
19 | /* Option Example | 22 | /* Option Example |
20 | 23 | ||
21 | -s, --sysname SunOS | 24 | -s, --sysname SunOS |
@@ -33,13 +36,18 @@ | |||
33 | 36 | ||
34 | /* Further size reductions by Glenn McGrath and Manuel Novoa III. */ | 37 | /* Further size reductions by Glenn McGrath and Manuel Novoa III. */ |
35 | 38 | ||
39 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
40 | * | ||
41 | * Now does proper error checking on i/o. Plus some further space savings. | ||
42 | */ | ||
43 | |||
36 | #include <stdio.h> | 44 | #include <stdio.h> |
37 | #include <stdlib.h> | 45 | #include <stdlib.h> |
38 | #include <stddef.h> | 46 | #include <stddef.h> |
39 | #include <string.h> | 47 | #include <string.h> |
48 | #include <unistd.h> | ||
40 | #include <sys/types.h> | 49 | #include <sys/types.h> |
41 | #include <sys/utsname.h> | 50 | #include <sys/utsname.h> |
42 | #include <getopt.h> | ||
43 | #include "busybox.h" | 51 | #include "busybox.h" |
44 | 52 | ||
45 | typedef struct { | 53 | typedef struct { |
@@ -48,7 +56,6 @@ typedef struct { | |||
48 | } uname_info_t; | 56 | } uname_info_t; |
49 | 57 | ||
50 | static const char options[] = "snrvmpa"; | 58 | static const char options[] = "snrvmpa"; |
51 | static const char flags[] = "\x01\x02\x04\x08\x10\x20\x3f"; | ||
52 | static const unsigned short int utsname_offset[] = { | 59 | static const unsigned short int utsname_offset[] = { |
53 | offsetof(uname_info_t,name.sysname), | 60 | offsetof(uname_info_t,name.sysname), |
54 | offsetof(uname_info_t,name.nodename), | 61 | offsetof(uname_info_t,name.nodename), |
@@ -61,29 +68,28 @@ static const unsigned short int utsname_offset[] = { | |||
61 | int uname_main(int argc, char **argv) | 68 | int uname_main(int argc, char **argv) |
62 | { | 69 | { |
63 | uname_info_t uname_info; | 70 | uname_info_t uname_info; |
64 | |||
65 | #if defined(__sparc__) && defined(__linux__) | 71 | #if defined(__sparc__) && defined(__linux__) |
66 | char *fake_sparc = getenv("FAKE_SPARC"); | 72 | char *fake_sparc = getenv("FAKE_SPARC"); |
67 | #endif | 73 | #endif |
68 | |||
69 | const unsigned short int *delta; | 74 | const unsigned short int *delta; |
70 | int opt; | 75 | char toprint; |
71 | char toprint = 0; | ||
72 | 76 | ||
73 | while ((opt = getopt(argc, argv, options)) != -1) { | 77 | toprint = bb_getopt_ulflags(argc, argv, options); |
74 | const char *p = strchr(options,opt); | 78 | |
75 | if (p == NULL) { | 79 | if (argc != optind) { |
76 | show_usage(); | 80 | bb_show_usage(); |
77 | } | 81 | } |
78 | toprint |= flags[(int)(p-options)]; | 82 | |
83 | if (toprint & (1 << 6)) { | ||
84 | toprint = 0x3f; | ||
79 | } | 85 | } |
80 | 86 | ||
81 | if (toprint == 0) { | 87 | if (toprint == 0) { |
82 | toprint = flags[0]; /* sysname */ | 88 | toprint = 1; /* sysname */ |
83 | } | 89 | } |
84 | 90 | ||
85 | if (uname(&uname_info.name) == -1) { | 91 | if (uname(&uname_info.name) == -1) { |
86 | error_msg_and_die("cannot get system name"); | 92 | bb_error_msg_and_die("cannot get system name"); |
87 | } | 93 | } |
88 | 94 | ||
89 | #if defined(__sparc__) && defined(__linux__) | 95 | #if defined(__sparc__) && defined(__linux__) |
@@ -99,7 +105,7 @@ int uname_main(int argc, char **argv) | |||
99 | delta=utsname_offset; | 105 | delta=utsname_offset; |
100 | do { | 106 | do { |
101 | if (toprint & 1) { | 107 | if (toprint & 1) { |
102 | printf(((char *)(&uname_info)) + *delta); | 108 | bb_printf(((char *)(&uname_info)) + *delta); |
103 | if (toprint > 1) { | 109 | if (toprint > 1) { |
104 | putchar(' '); | 110 | putchar(' '); |
105 | } | 111 | } |
@@ -108,5 +114,5 @@ int uname_main(int argc, char **argv) | |||
108 | } while (toprint >>= 1); | 114 | } while (toprint >>= 1); |
109 | putchar('\n'); | 115 | putchar('\n'); |
110 | 116 | ||
111 | return EXIT_SUCCESS; | 117 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); |
112 | } | 118 | } |
diff --git a/coreutils/uniq.c b/coreutils/uniq.c index cb63c4277..90686c9af 100644 --- a/coreutils/uniq.c +++ b/coreutils/uniq.c | |||
@@ -1,10 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini uniq implementation for busybox | 3 | * uniq implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1999 by Lineo, inc. and John Beppu | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org> | ||
7 | * Rewritten by Matt Kraai <kraai@alumni.carnegiemellon.edu> | ||
8 | * | 6 | * |
9 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -22,67 +20,93 @@ | |||
22 | * | 20 | * |
23 | */ | 21 | */ |
24 | 22 | ||
23 | /* BB_AUDIT SUSv3 compliant */ | ||
24 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/uniq.html */ | ||
25 | |||
25 | #include <stdio.h> | 26 | #include <stdio.h> |
26 | #include <string.h> | ||
27 | #include <getopt.h> | ||
28 | #include <errno.h> | ||
29 | #include <stdlib.h> | 27 | #include <stdlib.h> |
28 | #include <string.h> | ||
29 | #include <ctype.h> | ||
30 | #include <unistd.h> | ||
30 | #include "busybox.h" | 31 | #include "busybox.h" |
32 | #include "libcoreutils/coreutils.h" | ||
31 | 33 | ||
32 | static int print_count; | 34 | static const char uniq_opts[] = "f:s:cdu\0\7\3\5\1\2\4"; |
33 | static int print_uniq = 1; | ||
34 | static int print_duplicates = 1; | ||
35 | |||
36 | static void print_line(char *line, int count, FILE *fp) | ||
37 | { | ||
38 | if ((print_duplicates && count > 1) || (print_uniq && count == 1)) { | ||
39 | if (print_count) | ||
40 | fprintf(fp, "%7d\t%s", count, line); | ||
41 | else | ||
42 | fputs(line, fp); | ||
43 | } | ||
44 | } | ||
45 | 35 | ||
46 | int uniq_main(int argc, char **argv) | 36 | int uniq_main(int argc, char **argv) |
47 | { | 37 | { |
48 | FILE *in = stdin, *out = stdout; | 38 | FILE *in, *out; |
49 | char *lastline = NULL, *input; | 39 | /* Note: Ignore the warning about dups and e0 possibly being uninitialized. |
50 | int opt, count = 0; | 40 | * They will be initialized on the fist pass of the loop (since s0 is NULL). */ |
41 | unsigned long dups, skip_fields, skip_chars, i; | ||
42 | const char *s0, *e0, *s1, *e1, *input_filename; | ||
43 | int opt; | ||
44 | int uniq_flags = 6; /* -u */ | ||
51 | 45 | ||
52 | /* parse argv[] */ | 46 | skip_fields = skip_chars = 0; |
53 | while ((opt = getopt(argc, argv, "cdu")) > 0) { | 47 | |
54 | switch (opt) { | 48 | while ((opt = getopt(argc, argv, uniq_opts)) > 0) { |
55 | case 'c': | 49 | if (opt == 'f') { |
56 | print_count = 1; | 50 | skip_fields = bb_xgetularg10(optarg); |
57 | break; | 51 | } else if (opt == 's') { |
58 | case 'd': | 52 | skip_chars = bb_xgetularg10(optarg); |
59 | print_duplicates = 1; | 53 | } else if ((s0 = strchr(uniq_opts, opt)) != NULL) { |
60 | print_uniq = 0; | 54 | uniq_flags &= s0[4]; |
61 | break; | 55 | uniq_flags |= s0[7]; |
62 | case 'u': | 56 | } else { |
63 | print_duplicates = 0; | 57 | bb_show_usage(); |
64 | print_uniq = 1; | ||
65 | break; | ||
66 | } | 58 | } |
67 | } | 59 | } |
68 | 60 | ||
69 | if (argv[optind] != NULL) { | 61 | input_filename = *(argv += optind); |
70 | in = xfopen(argv[optind], "r"); | 62 | |
71 | if (argv[optind+1] != NULL) | 63 | in = xgetoptfile_sort_uniq(argv, "r"); |
72 | out = xfopen(argv[optind+1], "w"); | 64 | if (*argv) { |
65 | ++argv; | ||
73 | } | 66 | } |
67 | out = xgetoptfile_sort_uniq(argv, "w"); | ||
68 | if (*argv && argv[1]) { | ||
69 | bb_show_usage(); | ||
70 | } | ||
71 | |||
72 | s0 = NULL; | ||
74 | 73 | ||
75 | while ((input = get_line_from_file(in)) != NULL) { | 74 | /* gnu uniq ignores newlines */ |
76 | if (lastline == NULL || strcmp(input, lastline) != 0) { | 75 | while ((s1 = bb_get_chomped_line_from_file(in)) != NULL) { |
77 | print_line(lastline, count, out); | 76 | e1 = s1; |
78 | free(lastline); | 77 | for (i=skip_fields ; i ; i--) { |
79 | lastline = input; | 78 | e1 = bb_skip_whitespace(e1); |
80 | count = 0; | 79 | while (*e1 && !isspace(*e1)) { |
80 | ++e1; | ||
81 | } | ||
82 | } | ||
83 | for (i = skip_chars ; *e1 && i ; i--) { | ||
84 | ++e1; | ||
85 | } | ||
86 | if (s0) { | ||
87 | if (strcmp(e0, e1) == 0) { | ||
88 | ++dups; /* Note: Testing for overflow seems excessive. */ | ||
89 | continue; | ||
90 | } | ||
91 | DO_LAST: | ||
92 | if ((dups && (uniq_flags & 2)) || (!dups && (uniq_flags & 4))) { | ||
93 | bb_fprintf(out, "\0%7d\t" + (uniq_flags & 1), dups + 1); | ||
94 | bb_fprintf(out, "%s\n", s0); | ||
95 | } | ||
96 | free((void *)s0); | ||
81 | } | 97 | } |
82 | count++; | 98 | |
99 | s0 = s1; | ||
100 | e0 = e1; | ||
101 | dups = 0; | ||
102 | } | ||
103 | |||
104 | if (s0) { | ||
105 | e1 = NULL; | ||
106 | goto DO_LAST; | ||
83 | } | 107 | } |
84 | print_line(lastline, count, out); | ||
85 | free(lastline); | ||
86 | 108 | ||
87 | return EXIT_SUCCESS; | 109 | bb_xferror(in, input_filename); |
110 | |||
111 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); | ||
88 | } | 112 | } |
diff --git a/coreutils/usleep.c b/coreutils/usleep.c index ac268b485..f570f2734 100644 --- a/coreutils/usleep.c +++ b/coreutils/usleep.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini usleep implementation for busybox | 3 | * usleep implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -20,18 +20,22 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* getopt not needed */ | 23 | /* BB_AUDIT SUSv3 N/A -- Apparently a busybox extension. */ |
24 | 24 | ||
25 | #include <stdlib.h> | 25 | #include <stdlib.h> |
26 | #include <limits.h> | ||
26 | #include <unistd.h> | 27 | #include <unistd.h> |
27 | #include "busybox.h" | 28 | #include "busybox.h" |
28 | 29 | ||
29 | extern int usleep_main(int argc, char **argv) | 30 | extern int usleep_main(int argc, char **argv) |
30 | { | 31 | { |
31 | if ((argc < 2) || (**(argv + 1) == '-')) { | 32 | if (argc != 2) { |
32 | show_usage(); | 33 | bb_show_usage(); |
34 | } | ||
35 | |||
36 | if (usleep(bb_xgetularg10_bnd(argv[1], 0, UINT_MAX))) { | ||
37 | bb_perror_nomsg_and_die(); | ||
33 | } | 38 | } |
34 | 39 | ||
35 | usleep(atoi(*(++argv))); /* return void */ | ||
36 | return EXIT_SUCCESS; | 40 | return EXIT_SUCCESS; |
37 | } | 41 | } |
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c index a5ac002e9..4f9270c18 100644 --- a/coreutils/uudecode.c +++ b/coreutils/uudecode.c | |||
@@ -46,7 +46,7 @@ static int read_stduu (const char *inname) | |||
46 | char *p; | 46 | char *p; |
47 | 47 | ||
48 | if (fgets (buf, sizeof(buf), stdin) == NULL) { | 48 | if (fgets (buf, sizeof(buf), stdin) == NULL) { |
49 | error_msg("%s: Short file", inname); | 49 | bb_error_msg("%s: Short file", inname); |
50 | return FALSE; | 50 | return FALSE; |
51 | } | 51 | } |
52 | p = buf; | 52 | p = buf; |
@@ -81,7 +81,7 @@ static int read_stduu (const char *inname) | |||
81 | 81 | ||
82 | if (fgets (buf, sizeof(buf), stdin) == NULL | 82 | if (fgets (buf, sizeof(buf), stdin) == NULL |
83 | || strcmp (buf, "end\n")) { | 83 | || strcmp (buf, "end\n")) { |
84 | error_msg("%s: No `end' line", inname); | 84 | bb_error_msg("%s: No `end' line", inname); |
85 | return FALSE; | 85 | return FALSE; |
86 | } | 86 | } |
87 | 87 | ||
@@ -131,7 +131,7 @@ static int read_base64 (const char *inname) | |||
131 | unsigned char *p; | 131 | unsigned char *p; |
132 | 132 | ||
133 | if (fgets (buf, sizeof(buf), stdin) == NULL) { | 133 | if (fgets (buf, sizeof(buf), stdin) == NULL) { |
134 | error_msg("%s: Short file", inname); | 134 | bb_error_msg("%s: Short file", inname); |
135 | return FALSE; | 135 | return FALSE; |
136 | } | 136 | } |
137 | p = buf; | 137 | p = buf; |
@@ -139,7 +139,7 @@ static int read_base64 (const char *inname) | |||
139 | if (memcmp (buf, "====", 4) == 0) | 139 | if (memcmp (buf, "====", 4) == 0) |
140 | break; | 140 | break; |
141 | if (last_data != 0) { | 141 | if (last_data != 0) { |
142 | error_msg("%s: data following `=' padding character", inname); | 142 | bb_error_msg("%s: data following `=' padding character", inname); |
143 | return FALSE; | 143 | return FALSE; |
144 | } | 144 | } |
145 | 145 | ||
@@ -161,14 +161,14 @@ static int read_base64 (const char *inname) | |||
161 | 161 | ||
162 | while ((b64_tab[*p] & '\100') != 0) | 162 | while ((b64_tab[*p] & '\100') != 0) |
163 | if (*p == '\n' || *p++ == '=') { | 163 | if (*p == '\n' || *p++ == '=') { |
164 | error_msg("%s: illegal line", inname); | 164 | bb_error_msg("%s: illegal line", inname); |
165 | return FALSE; | 165 | return FALSE; |
166 | } | 166 | } |
167 | c2 = b64_tab[*p++]; | 167 | c2 = b64_tab[*p++]; |
168 | 168 | ||
169 | while (b64_tab[*p] == '\177') | 169 | while (b64_tab[*p] == '\177') |
170 | if (*p++ == '\n') { | 170 | if (*p++ == '\n') { |
171 | error_msg("%s: illegal line", inname); | 171 | bb_error_msg("%s: illegal line", inname); |
172 | return FALSE; | 172 | return FALSE; |
173 | } | 173 | } |
174 | if (*p == '=') { | 174 | if (*p == '=') { |
@@ -180,7 +180,7 @@ static int read_base64 (const char *inname) | |||
180 | 180 | ||
181 | while (b64_tab[*p] == '\177') | 181 | while (b64_tab[*p] == '\177') |
182 | if (*p++ == '\n') { | 182 | if (*p++ == '\n') { |
183 | error_msg("%s: illegal line", inname); | 183 | bb_error_msg("%s: illegal line", inname); |
184 | return FALSE; | 184 | return FALSE; |
185 | } | 185 | } |
186 | putchar (c1 << 2 | c2 >> 4); | 186 | putchar (c1 << 2 | c2 >> 4); |
@@ -213,7 +213,7 @@ static int decode (const char *inname, | |||
213 | 213 | ||
214 | while (1) { | 214 | while (1) { |
215 | if (fgets (buf, sizeof (buf), stdin) == NULL) { | 215 | if (fgets (buf, sizeof (buf), stdin) == NULL) { |
216 | error_msg("%s: No `begin' line", inname); | 216 | bb_error_msg("%s: No `begin' line", inname); |
217 | return FALSE; | 217 | return FALSE; |
218 | } | 218 | } |
219 | 219 | ||
@@ -239,13 +239,13 @@ static int decode (const char *inname, | |||
239 | while (*p != '/') | 239 | while (*p != '/') |
240 | ++p; | 240 | ++p; |
241 | if (*p == '\0') { | 241 | if (*p == '\0') { |
242 | error_msg("%s: Illegal ~user", inname); | 242 | bb_error_msg("%s: Illegal ~user", inname); |
243 | return FALSE; | 243 | return FALSE; |
244 | } | 244 | } |
245 | *p++ = '\0'; | 245 | *p++ = '\0'; |
246 | pw = getpwnam (buf + 1); | 246 | pw = getpwnam (buf + 1); |
247 | if (pw == NULL) { | 247 | if (pw == NULL) { |
248 | error_msg("%s: No user `%s'", inname, buf + 1); | 248 | bb_error_msg("%s: No user `%s'", inname, buf + 1); |
249 | return FALSE; | 249 | return FALSE; |
250 | } | 250 | } |
251 | outname = concat_path_file(pw->pw_dir, p); | 251 | outname = concat_path_file(pw->pw_dir, p); |
@@ -258,7 +258,7 @@ static int decode (const char *inname, | |||
258 | && (freopen (outname, "w", stdout) == NULL | 258 | && (freopen (outname, "w", stdout) == NULL |
259 | || chmod (outname, mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | 259 | || chmod (outname, mode & (S_IRWXU | S_IRWXG | S_IRWXO)) |
260 | )) { | 260 | )) { |
261 | perror_msg("%s", outname); /* */ | 261 | bb_perror_msg("%s", outname); /* */ |
262 | if (dofre) | 262 | if (dofre) |
263 | free(outname); | 263 | free(outname); |
264 | return FALSE; | 264 | return FALSE; |
@@ -295,7 +295,7 @@ int uudecode_main (int argc, | |||
295 | break; | 295 | break; |
296 | 296 | ||
297 | default: | 297 | default: |
298 | show_usage(); | 298 | bb_show_usage(); |
299 | } | 299 | } |
300 | } | 300 | } |
301 | 301 | ||
@@ -308,7 +308,7 @@ int uudecode_main (int argc, | |||
308 | if (decode (argv[optind], outname) != 0) | 308 | if (decode (argv[optind], outname) != 0) |
309 | exit_status = FALSE; | 309 | exit_status = FALSE; |
310 | } else { | 310 | } else { |
311 | perror_msg("%s", argv[optind]); | 311 | bb_perror_msg("%s", argv[optind]); |
312 | exit_status = EXIT_FAILURE; | 312 | exit_status = EXIT_FAILURE; |
313 | } | 313 | } |
314 | optind++; | 314 | optind++; |
diff --git a/coreutils/uuencode.c b/coreutils/uuencode.c index 49b2d9189..fd3326d80 100644 --- a/coreutils/uuencode.c +++ b/coreutils/uuencode.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include "busybox.h" | 29 | #include "busybox.h" |
30 | 30 | ||
31 | /* Conversion table. for base 64 */ | 31 | /* Conversion table. for base 64 */ |
32 | static char tbl_base64[65] = { | 32 | static const char tbl_base64[65] = { |
33 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', | 33 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', |
34 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', | 34 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', |
35 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', | 35 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', |
@@ -41,7 +41,7 @@ static char tbl_base64[65] = { | |||
41 | '=' /* termination character */ | 41 | '=' /* termination character */ |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static char tbl_std[65] = { | 44 | static const char tbl_std[65] = { |
45 | '`', '!', '"', '#', '$', '%', '&', '\'', | 45 | '`', '!', '"', '#', '$', '%', '&', '\'', |
46 | '(', ')', '*', '+', ',', '-', '.', '/', | 46 | '(', ')', '*', '+', ',', '-', '.', '/', |
47 | '0', '1', '2', '3', '4', '5', '6', '7', | 47 | '0', '1', '2', '3', '4', '5', '6', '7', |
@@ -92,40 +92,36 @@ int uuencode_main(int argc, char **argv) | |||
92 | int write_size = dst_buf_size; | 92 | int write_size = dst_buf_size; |
93 | struct stat stat_buf; | 93 | struct stat stat_buf; |
94 | FILE *src_stream = stdin; | 94 | FILE *src_stream = stdin; |
95 | char *tbl = tbl_std; | 95 | const char *tbl; |
96 | size_t size; | 96 | size_t size; |
97 | mode_t mode; | 97 | mode_t mode; |
98 | int opt; | ||
99 | RESERVE_CONFIG_BUFFER(src_buf, SRC_BUF_SIZE + 1); | 98 | RESERVE_CONFIG_BUFFER(src_buf, SRC_BUF_SIZE + 1); |
100 | RESERVE_CONFIG_BUFFER(dst_buf, DST_BUF_SIZE + 1); | 99 | RESERVE_CONFIG_BUFFER(dst_buf, DST_BUF_SIZE + 1); |
101 | 100 | ||
102 | while ((opt = getopt(argc, argv, "m")) != -1) { | 101 | tbl = tbl_std; |
103 | switch (opt) { | 102 | if (bb_getopt_ulflags(argc, argv, "m") & 1) { |
104 | case 'm': | 103 | tbl = tbl_base64; |
105 | tbl = tbl_base64; | ||
106 | break; | ||
107 | default: | ||
108 | show_usage(); | ||
109 | } | ||
110 | } | 104 | } |
111 | 105 | ||
112 | switch (argc - optind) { | 106 | switch (argc - optind) { |
113 | case 2: | 107 | case 2: |
114 | src_stream = xfopen(argv[optind], "r"); | 108 | src_stream = bb_xfopen(argv[optind], "r"); |
115 | stat(argv[optind], &stat_buf); | 109 | if (stat(argv[optind], &stat_buf) < 0) { |
110 | bb_perror_msg_and_die("stat"); | ||
111 | } | ||
116 | mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); | 112 | mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); |
117 | if (src_stream == stdout) { | 113 | if (src_stream == stdout) { |
118 | printf("NULL\n"); | 114 | puts("NULL"); |
119 | } | 115 | } |
120 | break; | 116 | break; |
121 | case 1: | 117 | case 1: |
122 | mode = 0666 & ~umask(0666); | 118 | mode = 0666 & ~umask(0666); |
123 | break; | 119 | break; |
124 | default: | 120 | default: |
125 | show_usage(); | 121 | bb_show_usage(); |
126 | } | 122 | } |
127 | 123 | ||
128 | printf("begin%s %o %s", tbl == tbl_std ? "" : "-base64", mode, argv[argc - 1]); | 124 | bb_printf("begin%s %o %s", tbl == tbl_std ? "" : "-base64", mode, argv[argc - 1]); |
129 | 125 | ||
130 | while ((size = fread(src_buf, 1, src_buf_size, src_stream)) > 0) { | 126 | while ((size = fread(src_buf, 1, src_buf_size, src_stream)) > 0) { |
131 | if (size != src_buf_size) { | 127 | if (size != src_buf_size) { |
@@ -142,10 +138,12 @@ int uuencode_main(int argc, char **argv) | |||
142 | putchar(tbl[size]); | 138 | putchar(tbl[size]); |
143 | } | 139 | } |
144 | if (fwrite(dst_buf, 1, write_size, stdout) != write_size) { | 140 | if (fwrite(dst_buf, 1, write_size, stdout) != write_size) { |
145 | perror("Couldnt finish writing"); | 141 | bb_perror_msg_and_die(bb_msg_write_error); |
146 | } | 142 | } |
147 | } | 143 | } |
148 | printf(tbl == tbl_std ? "\n`\nend\n" : "\n====\n"); | 144 | bb_printf(tbl == tbl_std ? "\n`\nend\n" : "\n====\n"); |
145 | |||
146 | bb_xferror(src_stream, "source"); /* TODO - Fix this! */ | ||
149 | 147 | ||
150 | return(EXIT_SUCCESS); | 148 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); |
151 | } | 149 | } |
diff --git a/coreutils/watch.c b/coreutils/watch.c index c275f3bb3..f9f40189e 100644 --- a/coreutils/watch.c +++ b/coreutils/watch.c | |||
@@ -20,67 +20,76 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* getopt not needed */ | 23 | /* BB_AUDIT SUSv3 N/A */ |
24 | /* BB_AUDIT GNU defects -- only option -n is supported. */ | ||
25 | |||
26 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
27 | * | ||
28 | * Removed dependency on date_main(), added proper error checking, and | ||
29 | * reduced size. | ||
30 | */ | ||
24 | 31 | ||
25 | #include <stdio.h> | 32 | #include <stdio.h> |
26 | #include <errno.h> | ||
27 | #include <unistd.h> | ||
28 | #include <stdlib.h> | 33 | #include <stdlib.h> |
29 | #include <string.h> | 34 | #include <string.h> |
35 | #include <limits.h> | ||
36 | #include <time.h> | ||
37 | #include <assert.h> | ||
38 | #include <unistd.h> | ||
30 | #include <sys/wait.h> | 39 | #include <sys/wait.h> |
31 | #include "busybox.h" | 40 | #include "busybox.h" |
32 | 41 | ||
33 | extern int watch_main(int argc, char **argv) | 42 | extern int watch_main(int argc, char **argv) |
34 | { | 43 | { |
35 | const char date_argv[2][10] = { "date", "" }; | ||
36 | const int header_len = 40; | 44 | const int header_len = 40; |
37 | char header[header_len + 1]; | 45 | time_t t; |
38 | int period = 2; | ||
39 | char **cargv; | ||
40 | int cargc; | ||
41 | pid_t pid; | 46 | pid_t pid; |
47 | unsigned period = 2; | ||
42 | int old_stdout; | 48 | int old_stdout; |
43 | int i; | 49 | int len, len2; |
50 | char **watched_argv; | ||
51 | char header[header_len + 1]; | ||
44 | 52 | ||
45 | if (argc < 2) { | 53 | if (argc < 2) { |
46 | show_usage(); | 54 | bb_show_usage(); |
47 | } else { | ||
48 | cargv = argv + 1; | ||
49 | cargc = argc - 1; | ||
50 | |||
51 | /* don't use getopt, because it permutes the arguments */ | ||
52 | if (argc >= 3 && !strcmp(argv[1], "-n")) { | ||
53 | period = strtol(argv[2], NULL, 10); | ||
54 | if (period < 1) | ||
55 | show_usage(); | ||
56 | cargv += 2; | ||
57 | cargc -= 2; | ||
58 | } | ||
59 | } | 55 | } |
60 | 56 | ||
61 | 57 | /* don't use getopt, because it permutes the arguments */ | |
62 | /* create header */ | 58 | ++argv; |
63 | snprintf(header, header_len, "Every %ds: ", period); | 59 | if ((argc > 3) && !strcmp(*argv, "-n") |
64 | for (i = 0; i < cargc && (strlen(header) + strlen(cargv[i]) < header_len); | 60 | ) { |
65 | i++) { | 61 | period = bb_xgetularg10_bnd(argv[1], 1, UINT_MAX); |
66 | strcat(header, cargv[i]); | 62 | argv += 2; |
67 | strcat(header, " "); | ||
68 | } | 63 | } |
64 | watched_argv = argv; | ||
69 | 65 | ||
70 | /* fill with blanks */ | 66 | /* create header */ |
71 | for (i = strlen(header); i < header_len; i++) | ||
72 | header[i] = ' '; | ||
73 | 67 | ||
74 | header[header_len - 1] = '\0'; | 68 | len = snprintf(header, header_len, "Every %ds:", period); |
69 | /* Don't bother checking for len < 0, as it should never happen. | ||
70 | * But, just to be prepared... */ | ||
71 | assert(len >= 0); | ||
72 | do { | ||
73 | len2 = strlen(*argv); | ||
74 | if (len + len2 >= header_len-1) { | ||
75 | break; | ||
76 | } | ||
77 | header[len] = ' '; | ||
78 | memcpy(header+len+1, *argv, len2); | ||
79 | len += len2+1; | ||
80 | } while (*++argv); | ||
75 | 81 | ||
82 | header[len] = 0; | ||
76 | 83 | ||
77 | /* thanks to lye, who showed me how to redirect stdin/stdout */ | 84 | /* thanks to lye, who showed me how to redirect stdin/stdout */ |
78 | old_stdout = dup(1); | 85 | old_stdout = dup(1); |
79 | 86 | ||
80 | while (1) { | 87 | while (1) { |
81 | printf("\033[H\033[J%s", header); | 88 | time(&t); |
82 | date_main(1, (char **) date_argv); | 89 | /* Use dprintf to avoid fflush()ing stdout. */ |
83 | printf("\n"); | 90 | if (dprintf(1, "\033[H\033[J%-*s%s\n", header_len, header, ctime(&t)) < 0) { |
91 | bb_perror_msg_and_die("printf"); | ||
92 | } | ||
84 | 93 | ||
85 | pid = vfork(); /* vfork, because of ucLinux */ | 94 | pid = vfork(); /* vfork, because of ucLinux */ |
86 | if (pid > 0) { | 95 | if (pid > 0) { |
@@ -91,13 +100,11 @@ extern int watch_main(int argc, char **argv) | |||
91 | //child | 100 | //child |
92 | close(1); | 101 | close(1); |
93 | dup(old_stdout); | 102 | dup(old_stdout); |
94 | if (execvp(*cargv, cargv)) | 103 | if (execvp(*watched_argv, watched_argv)) { |
95 | error_msg_and_die("Couldn't run command\n"); | 104 | bb_error_msg_and_die("Couldn't run command\n"); |
105 | } | ||
96 | } else { | 106 | } else { |
97 | error_msg_and_die("Couldn't vfork\n"); | 107 | bb_error_msg_and_die("Couldn't vfork\n"); |
98 | } | 108 | } |
99 | } | 109 | } |
100 | |||
101 | |||
102 | return EXIT_SUCCESS; | ||
103 | } | 110 | } |
diff --git a/coreutils/wc.c b/coreutils/wc.c index 8e3b5bbf4..779901524 100644 --- a/coreutils/wc.c +++ b/coreutils/wc.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini wc implementation for busybox | 3 | * wc implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 2000 Edward Betts <edward@debian.org> | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -20,159 +20,208 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* BB_AUDIT SUSv3 _NOT_ compliant -- option -m is not currently supported. */ | ||
24 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/wc.html */ | ||
25 | |||
26 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
27 | * | ||
28 | * Rewritten to fix a number of problems and do some size optimizations. | ||
29 | * Problems in the previous busybox implementation (besides bloat) included: | ||
30 | * 1) broken 'wc -c' optimization (read note below) | ||
31 | * 2) broken handling of '-' args | ||
32 | * 3) no checking of ferror on EOF returns | ||
33 | * 4) isprint() wasn't considered when word counting. | ||
34 | * | ||
35 | * TODO: | ||
36 | * | ||
37 | * When locale support is enabled, count multibyte chars in the '-m' case. | ||
38 | * | ||
39 | * NOTES: | ||
40 | * | ||
41 | * The previous busybox wc attempted an optimization using stat for the | ||
42 | * case of counting chars only. I omitted that because it was broken. | ||
43 | * It didn't take into account the possibility of input coming from a | ||
44 | * pipe, or input from a file with file pointer not at the beginning. | ||
45 | * | ||
46 | * To implement such a speed optimization correctly, not only do you | ||
47 | * need the size, but also the file position. Note also that the | ||
48 | * file position may be past the end of file. Consider the example | ||
49 | * (adapted from example in gnu wc.c) | ||
50 | * | ||
51 | * echo hello > /tmp/testfile && | ||
52 | * (dd ibs=1k skip=1 count=0 &> /dev/null ; wc -c) < /tmp/testfile | ||
53 | * | ||
54 | * for which 'wc -c' should output '0'. | ||
55 | */ | ||
56 | |||
23 | #include <stdio.h> | 57 | #include <stdio.h> |
24 | #include <getopt.h> | ||
25 | #include <string.h> | ||
26 | #include <stdlib.h> | 58 | #include <stdlib.h> |
59 | #include <string.h> | ||
60 | #include <unistd.h> | ||
27 | #include "busybox.h" | 61 | #include "busybox.h" |
28 | 62 | ||
29 | enum print_e { | 63 | #ifdef CONFIG_LOCALE_SUPPORT |
30 | print_lines = 1, | 64 | #include <locale.h> |
31 | print_words = 2, | 65 | #include <ctype.h> |
32 | print_chars = 4, | 66 | #define isspace_given_isprint(c) isspace(c) |
33 | print_length = 8 | 67 | #else |
68 | #undef isspace | ||
69 | #undef isprint | ||
70 | #define isspace(c) ((((c) == ' ') || (((unsigned int)((c) - 9)) <= (13 - 9)))) | ||
71 | #define isprint(c) (((unsigned int)((c) - 0x20)) <= (0x7e - 0x20)) | ||
72 | #define isspace_given_isprint(c) ((c) == ' ') | ||
73 | #endif | ||
74 | |||
75 | enum { | ||
76 | WC_LINES = 0, | ||
77 | WC_WORDS = 1, | ||
78 | WC_CHARS = 2, | ||
79 | WC_LENGTH = 3 | ||
34 | }; | 80 | }; |
35 | 81 | ||
36 | static unsigned int total_lines = 0; | 82 | /* Note: If this changes, remember to change the initialization of |
37 | static unsigned int total_words = 0; | 83 | * 'name' in wc_main. It needs to point to the terminating nul. */ |
38 | static unsigned int total_chars = 0; | 84 | static const char wc_opts[] = "lwcL"; /* READ THE WARNING ABOVE! */ |
39 | static unsigned int max_length = 0; | ||
40 | static char print_type = 0; | ||
41 | 85 | ||
42 | static void print_counts(const unsigned int lines, const unsigned int words, | 86 | enum { |
43 | const unsigned int chars, const unsigned int length, const char *name) | 87 | OP_INC_LINE = 1, /* OP_INC_LINE must be 1. */ |
44 | { | 88 | OP_SPACE = 2, |
45 | int output = 0; | 89 | OP_NEWLINE = 4, |
90 | OP_TAB = 8, | ||
91 | OP_NUL = 16, | ||
92 | }; | ||
46 | 93 | ||
47 | if (print_type & print_lines) { | 94 | /* Note: If fmt_str changes, the offsets to 's' in the OUTPUT section |
48 | printf("%7d", lines); | 95 | * will need to be updated. */ |
49 | output++; | 96 | static const char fmt_str[] = " %7u\0 %s\n"; |
50 | } | 97 | static const char total_str[] = "total"; |
51 | if (print_type & print_words) { | ||
52 | if (output++) | ||
53 | putchar(' '); | ||
54 | printf("%7d", words); | ||
55 | } | ||
56 | if (print_type & print_chars) { | ||
57 | if (output++) | ||
58 | putchar(' '); | ||
59 | printf("%7d", chars); | ||
60 | } | ||
61 | if (print_type & print_length) { | ||
62 | if (output++) | ||
63 | putchar(' '); | ||
64 | printf("%7d", length); | ||
65 | } | ||
66 | if (*name) { | ||
67 | printf(" %s", name); | ||
68 | } | ||
69 | putchar('\n'); | ||
70 | } | ||
71 | 98 | ||
72 | static void wc_file(FILE * file, const char *name) | 99 | int wc_main(int argc, char **argv) |
73 | { | 100 | { |
74 | unsigned int lines = 0; | 101 | FILE *fp; |
75 | unsigned int words = 0; | 102 | const char *s; |
76 | unsigned int chars = 0; | 103 | unsigned int *pcounts; |
77 | unsigned int length = 0; | 104 | unsigned int counts[4]; |
78 | unsigned int linepos = 0; | 105 | unsigned int totals[4]; |
79 | char in_word = 0; | 106 | unsigned int linepos; |
107 | unsigned int u; | ||
108 | int num_files = 0; | ||
80 | int c; | 109 | int c; |
81 | 110 | char status = EXIT_SUCCESS; | |
82 | while ((c = getc(file)) != EOF) { | 111 | char in_word; |
83 | chars++; | 112 | char print_type; |
84 | switch (c) { | 113 | |
85 | case '\n': | 114 | print_type = bb_getopt_ulflags(argc, argv, wc_opts); |
86 | lines++; | 115 | |
87 | case '\r': | 116 | if (print_type == 0) { |
88 | case '\f': | 117 | print_type = (1 << WC_LINES) | (1 << WC_WORDS) | (1 << WC_CHARS); |
89 | if (linepos > length) | ||
90 | length = linepos; | ||
91 | linepos = 0; | ||
92 | goto word_separator; | ||
93 | case '\t': | ||
94 | linepos += 8 - (linepos % 8); | ||
95 | goto word_separator; | ||
96 | case ' ': | ||
97 | linepos++; | ||
98 | case '\v': | ||
99 | word_separator: | ||
100 | if (in_word) { | ||
101 | in_word = 0; | ||
102 | words++; | ||
103 | } | ||
104 | break; | ||
105 | default: | ||
106 | linepos++; | ||
107 | in_word = 1; | ||
108 | break; | ||
109 | } | ||
110 | } | ||
111 | if (linepos > length) { | ||
112 | length = linepos; | ||
113 | } | ||
114 | if (in_word) { | ||
115 | words++; | ||
116 | } | 118 | } |
117 | print_counts(lines, words, chars, length, name); | 119 | |
118 | total_lines += lines; | 120 | argv += optind; |
119 | total_words += words; | 121 | if (!*argv) { |
120 | total_chars += chars; | 122 | *--argv = (char *) bb_msg_standard_input; |
121 | if (length > max_length) { | ||
122 | max_length = length; | ||
123 | } | 123 | } |
124 | } | 124 | |
125 | 125 | memset(totals, 0, sizeof(totals)); | |
126 | int wc_main(int argc, char **argv) | 126 | |
127 | { | 127 | pcounts = counts; |
128 | int opt; | 128 | |
129 | 129 | do { | |
130 | while ((opt = getopt(argc, argv, "clLw")) > 0) { | 130 | ++num_files; |
131 | switch (opt) { | 131 | if (!(fp = bb_wfopen_input(*argv))) { |
132 | case 'c': | 132 | status = EXIT_FAILURE; |
133 | print_type |= print_chars; | 133 | continue; |
134 | break; | ||
135 | case 'l': | ||
136 | print_type |= print_lines; | ||
137 | break; | ||
138 | case 'L': | ||
139 | print_type |= print_length; | ||
140 | break; | ||
141 | case 'w': | ||
142 | print_type |= print_words; | ||
143 | break; | ||
144 | default: | ||
145 | show_usage(); | ||
146 | } | 134 | } |
147 | } | 135 | |
148 | 136 | memset(counts, 0, sizeof(counts)); | |
149 | if (print_type == 0) { | 137 | linepos = 0; |
150 | print_type = print_lines | print_words | print_chars; | 138 | in_word = 0; |
151 | } | 139 | |
152 | 140 | do { | |
153 | if (argv[optind] == NULL || strcmp(argv[optind], "-") == 0) { | 141 | ++counts[WC_CHARS]; |
154 | wc_file(stdin, ""); | 142 | c = getc(fp); |
155 | } else { | 143 | if (isprint(c)) { |
156 | unsigned short num_files_counted = 0; | 144 | ++linepos; |
157 | while (optind < argc) { | 145 | if (!isspace_given_isprint(c)) { |
158 | if (print_type == print_chars) { | 146 | in_word = 1; |
159 | struct stat statbuf; | 147 | continue; |
160 | stat(argv[optind], &statbuf); | 148 | } |
161 | print_counts(0, 0, statbuf.st_size, 0, argv[optind]); | 149 | } else if (((unsigned int)(c - 9)) <= 4) { |
162 | total_chars += statbuf.st_size; | 150 | /* \t 9 |
151 | * \n 10 | ||
152 | * \v 11 | ||
153 | * \f 12 | ||
154 | * \r 13 | ||
155 | */ | ||
156 | if (c == '\t') { | ||
157 | linepos = (linepos | 7) + 1; | ||
158 | } else { /* '\n', '\r', '\f', or '\v' */ | ||
159 | DO_EOF: | ||
160 | if (linepos > counts[WC_LENGTH]) { | ||
161 | counts[WC_LENGTH] = linepos; | ||
162 | } | ||
163 | if (c == '\n') { | ||
164 | ++counts[WC_LINES]; | ||
165 | } | ||
166 | if (c != '\v') { | ||
167 | linepos = 0; | ||
168 | } | ||
169 | } | ||
170 | } else if (c == EOF) { | ||
171 | if (ferror(fp)) { | ||
172 | bb_perror_msg("%s", *argv); | ||
173 | status = EXIT_FAILURE; | ||
174 | } | ||
175 | --counts[WC_CHARS]; | ||
176 | goto DO_EOF; /* Treat an EOF as '\r'. */ | ||
163 | } else { | 177 | } else { |
164 | FILE *file; | 178 | continue; |
165 | file = xfopen(argv[optind], "r"); | 179 | } |
166 | wc_file(file, argv[optind]); | 180 | |
167 | fclose(file); | 181 | counts[WC_WORDS] += in_word; |
182 | in_word = 0; | ||
183 | if (c == EOF) { | ||
184 | break; | ||
168 | } | 185 | } |
169 | optind++; | 186 | } while (1); |
170 | num_files_counted++; | 187 | |
188 | if (totals[WC_LENGTH] < counts[WC_LENGTH]) { | ||
189 | totals[WC_LENGTH] = counts[WC_LENGTH]; | ||
171 | } | 190 | } |
172 | if (num_files_counted > 1) { | 191 | totals[WC_LENGTH] -= counts[WC_LENGTH]; |
173 | print_counts(total_lines, total_words, total_chars, max_length, "total"); | 192 | |
193 | bb_fclose_nonstdin(fp); | ||
194 | |||
195 | OUTPUT: | ||
196 | s = fmt_str + 1; /* Skip the leading space on 1st pass. */ | ||
197 | u = 0; | ||
198 | do { | ||
199 | if (print_type & (1 << u)) { | ||
200 | bb_printf(s, pcounts[u]); | ||
201 | s = fmt_str; /* Ok... restore the leading space. */ | ||
202 | } | ||
203 | totals[u] += pcounts[u]; | ||
204 | } while (++u < 4); | ||
205 | |||
206 | s += 8; /* Set the format to the empty string. */ | ||
207 | |||
208 | if (*argv != bb_msg_standard_input) { | ||
209 | s -= 3; /* We have a name, so do %s conversion. */ | ||
174 | } | 210 | } |
211 | bb_printf(s, *argv); | ||
212 | |||
213 | } while (*++argv); | ||
214 | |||
215 | /* If more than one file was processed, we want the totals. To save some | ||
216 | * space, we set the pcounts ptr to the totals array. This has the side | ||
217 | * effect of trashing the totals array after outputting it, but that's | ||
218 | * irrelavent since we no longer need it. */ | ||
219 | if (num_files > 1) { | ||
220 | num_files = 0; /* Make sure we don't get here again. */ | ||
221 | *--argv = (char *) total_str; | ||
222 | pcounts = totals; | ||
223 | goto OUTPUT; | ||
175 | } | 224 | } |
176 | 225 | ||
177 | return(EXIT_SUCCESS); | 226 | bb_fflush_stdout_and_exit(status); |
178 | } | 227 | } |
diff --git a/coreutils/who.c b/coreutils/who.c index 3da7ed1c7..1bf552056 100644 --- a/coreutils/who.c +++ b/coreutils/who.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <errno.h> | 23 | #include <errno.h> |
24 | #include <string.h> | 24 | #include <string.h> |
25 | #include <time.h> | 25 | #include <time.h> |
26 | #include <busybox.h> | 26 | #include "busybox.h" |
27 | 27 | ||
28 | extern int who_main(int argc, char **argv) | 28 | extern int who_main(int argc, char **argv) |
29 | { | 29 | { |
@@ -33,7 +33,7 @@ extern int who_main(int argc, char **argv) | |||
33 | time_t now, idle; | 33 | time_t now, idle; |
34 | 34 | ||
35 | if (argc > 1) | 35 | if (argc > 1) |
36 | show_usage(); | 36 | bb_show_usage(); |
37 | 37 | ||
38 | setutent(); | 38 | setutent(); |
39 | devlen = sizeof("/dev/") - 1; | 39 | devlen = sizeof("/dev/") - 1; |
@@ -81,5 +81,3 @@ extern int who_main(int argc, char **argv) | |||
81 | 81 | ||
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | |||
85 | |||
diff --git a/coreutils/whoami.c b/coreutils/whoami.c index a9d6ecf26..f93034d3a 100644 --- a/coreutils/whoami.c +++ b/coreutils/whoami.c | |||
@@ -20,7 +20,7 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* getopt not needed */ | 23 | /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ |
24 | 24 | ||
25 | #include <stdio.h> | 25 | #include <stdio.h> |
26 | #include <stdlib.h> | 26 | #include <stdlib.h> |
@@ -30,14 +30,15 @@ | |||
30 | extern int whoami_main(int argc, char **argv) | 30 | extern int whoami_main(int argc, char **argv) |
31 | { | 31 | { |
32 | char user[9]; | 32 | char user[9]; |
33 | uid_t uid = geteuid(); | 33 | uid_t uid; |
34 | 34 | ||
35 | if (argc > 1) | 35 | if (argc > 1) |
36 | show_usage(); | 36 | bb_show_usage(); |
37 | 37 | ||
38 | uid = geteuid(); | ||
38 | if (my_getpwuid(user, uid)) { | 39 | if (my_getpwuid(user, uid)) { |
39 | puts(user); | 40 | puts(user); |
40 | return EXIT_SUCCESS; | 41 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); |
41 | } | 42 | } |
42 | error_msg_and_die("cannot find username for UID %u", (unsigned) uid); | 43 | bb_error_msg_and_die("cannot find username for UID %u", (unsigned) uid); |
43 | } | 44 | } |
diff --git a/coreutils/yes.c b/coreutils/yes.c index 7d9596d0b..74f7571cf 100644 --- a/coreutils/yes.c +++ b/coreutils/yes.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini yes implementation for busybox | 3 | * yes implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 2000 Edward Betts <edward@debian.org>. | 5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -20,7 +20,12 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* getopt not needed */ | 23 | /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ |
24 | |||
25 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
26 | * | ||
27 | * Size reductions and removed redundant applet name prefix from error messages. | ||
28 | */ | ||
24 | 29 | ||
25 | #include <stdio.h> | 30 | #include <stdio.h> |
26 | #include <stdlib.h> | 31 | #include <stdlib.h> |
@@ -28,26 +33,24 @@ | |||
28 | 33 | ||
29 | extern int yes_main(int argc, char **argv) | 34 | extern int yes_main(int argc, char **argv) |
30 | { | 35 | { |
31 | int i; | 36 | static const char fmt_str[] = " %s"; |
32 | 37 | const char *fmt; | |
33 | if (argc >= 2 && *argv[1] == '-') | 38 | char **first_arg; |
34 | show_usage(); | ||
35 | 39 | ||
36 | if (argc == 1) { | 40 | *argv = "y"; |
37 | while (1) | 41 | if (argc != 1) { |
38 | if (puts("y") == EOF) { | 42 | ++argv; |
39 | perror("yes"); | ||
40 | return EXIT_FAILURE; | ||
41 | } | ||
42 | } | 43 | } |
43 | 44 | ||
44 | while (1) | 45 | first_arg = argv; |
45 | for (i = 1; i < argc; i++) | 46 | do { |
46 | if (fputs(argv[i], stdout) == EOF | 47 | fmt = fmt_str + 1; |
47 | || putchar(i == argc - 1 ? '\n' : ' ') == EOF) { | 48 | do { |
48 | perror("yes"); | 49 | bb_printf(fmt, *argv); |
49 | return EXIT_FAILURE; | 50 | fmt = fmt_str; |
50 | } | 51 | } while (*++argv); |
52 | argv = first_arg; | ||
53 | } while (putchar('\n') != EOF); | ||
51 | 54 | ||
52 | return EXIT_SUCCESS; | 55 | bb_perror_nomsg_and_die(); |
53 | } | 56 | } |