diff options
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/cat.c | 54 | ||||
-rw-r--r-- | coreutils/chroot.c | 57 | ||||
-rw-r--r-- | coreutils/date.c | 451 | ||||
-rw-r--r-- | coreutils/dd.c | 284 | ||||
-rw-r--r-- | coreutils/df.c | 119 | ||||
-rw-r--r-- | coreutils/du.c | 185 | ||||
-rw-r--r-- | coreutils/head.c | 134 | ||||
-rw-r--r-- | coreutils/hostid.c | 8 | ||||
-rw-r--r-- | coreutils/length.c | 14 | ||||
-rw-r--r-- | coreutils/ln.c | 150 | ||||
-rw-r--r-- | coreutils/logname.c | 22 | ||||
-rw-r--r-- | coreutils/ls.c | 297 | ||||
-rw-r--r-- | coreutils/mkdir.c | 133 | ||||
-rw-r--r-- | coreutils/mkfifo.c | 64 | ||||
-rw-r--r-- | coreutils/mknod.c | 39 | ||||
-rw-r--r-- | coreutils/printf.c | 632 | ||||
-rw-r--r-- | coreutils/pwd.c | 12 | ||||
-rw-r--r-- | coreutils/rm.c | 102 | ||||
-rw-r--r-- | coreutils/rmdir.c | 20 | ||||
-rw-r--r-- | coreutils/sleep.c | 19 | ||||
-rw-r--r-- | coreutils/sort.c | 385 | ||||
-rw-r--r-- | coreutils/sync.c | 13 | ||||
-rw-r--r-- | coreutils/tail.c | 1789 | ||||
-rw-r--r-- | coreutils/tee.c | 129 | ||||
-rw-r--r-- | coreutils/touch.c | 79 | ||||
-rw-r--r-- | coreutils/tty.c | 25 | ||||
-rw-r--r-- | coreutils/uname.c | 139 | ||||
-rw-r--r-- | coreutils/uniq.c | 225 | ||||
-rw-r--r-- | coreutils/wc.c | 127 | ||||
-rw-r--r-- | coreutils/whoami.c | 27 | ||||
-rw-r--r-- | coreutils/yes.c | 14 |
31 files changed, 2841 insertions, 2907 deletions
diff --git a/coreutils/cat.c b/coreutils/cat.c index 0d32efe84..86f85fe8e 100644 --- a/coreutils/cat.c +++ b/coreutils/cat.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini Cat implementation for busybox | 3 | * Mini Cat implementation for busybox |
3 | * | 4 | * |
@@ -24,36 +25,37 @@ | |||
24 | #include <stdio.h> | 25 | #include <stdio.h> |
25 | 26 | ||
26 | 27 | ||
27 | static void print_file( FILE *file) | 28 | static void print_file(FILE * file) |
28 | { | 29 | { |
29 | int c; | 30 | int c; |
30 | while ((c = getc(file)) != EOF) | 31 | |
31 | putc(c, stdout); | 32 | while ((c = getc(file)) != EOF) |
32 | fclose(file); | 33 | putc(c, stdout); |
33 | fflush(stdout); | 34 | fclose(file); |
35 | fflush(stdout); | ||
34 | } | 36 | } |
35 | 37 | ||
36 | extern int cat_main(int argc, char **argv) | 38 | extern int cat_main(int argc, char **argv) |
37 | { | 39 | { |
38 | FILE *file; | 40 | FILE *file; |
39 | 41 | ||
40 | if (argc==1) { | 42 | if (argc == 1) { |
41 | print_file( stdin); | 43 | print_file(stdin); |
42 | exit( TRUE); | 44 | exit(TRUE); |
43 | } | 45 | } |
44 | 46 | ||
45 | if ( **(argv+1) == '-' ) { | 47 | if (**(argv + 1) == '-') { |
46 | usage ("cat [file ...]\n"); | 48 | usage("cat [file ...]\n"); |
47 | } | 49 | } |
48 | argc--; | 50 | argc--; |
49 | 51 | ||
50 | while (argc-- > 0 && *(argv++) != '\0' && strlen(*argv) ) { | 52 | while (argc-- > 0 && *(argv++) != '\0' && strlen(*argv)) { |
51 | file = fopen(*argv, "r"); | 53 | file = fopen(*argv, "r"); |
52 | if (file == NULL) { | 54 | if (file == NULL) { |
53 | perror(*argv); | 55 | perror(*argv); |
54 | exit(FALSE); | 56 | exit(FALSE); |
57 | } | ||
58 | print_file(file); | ||
55 | } | 59 | } |
56 | print_file( file); | 60 | exit(TRUE); |
57 | } | ||
58 | exit(TRUE); | ||
59 | } | 61 | } |
diff --git a/coreutils/chroot.c b/coreutils/chroot.c index 16524d92e..6a01be603 100644 --- a/coreutils/chroot.c +++ b/coreutils/chroot.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini chroot implementation for busybox | 3 | * Mini chroot implementation for busybox |
3 | * | 4 | * |
@@ -28,39 +29,39 @@ | |||
28 | 29 | ||
29 | 30 | ||
30 | static const char chroot_usage[] = "chroot NEWROOT [COMMAND...]\n\n" | 31 | static const char chroot_usage[] = "chroot NEWROOT [COMMAND...]\n\n" |
31 | "Run COMMAND with root directory set to NEWROOT.\n"; | 32 | |
33 | "Run COMMAND with root directory set to NEWROOT.\n"; | ||
32 | 34 | ||
33 | 35 | ||
34 | 36 | ||
35 | int chroot_main(int argc, char **argv) | 37 | int chroot_main(int argc, char **argv) |
36 | { | 38 | { |
37 | if ( (argc < 2) || (**(argv+1) == '-') ) { | 39 | if ((argc < 2) || (**(argv + 1) == '-')) { |
38 | usage( chroot_usage); | 40 | usage(chroot_usage); |
39 | } | 41 | } |
40 | argc--; | 42 | argc--; |
41 | argv++; | 43 | argv++; |
42 | 44 | ||
43 | if (chroot (*argv) || (chdir ("/"))) { | 45 | if (chroot(*argv) || (chdir("/"))) { |
44 | fprintf(stderr, "chroot: cannot change root directory to %s: %s\n", | 46 | fprintf(stderr, "chroot: cannot change root directory to %s: %s\n", |
45 | *argv, strerror(errno)); | 47 | *argv, strerror(errno)); |
46 | exit( FALSE); | 48 | exit(FALSE); |
47 | } | 49 | } |
48 | 50 | ||
49 | argc--; | 51 | argc--; |
50 | argv++; | 52 | argv++; |
51 | if (argc >= 1) { | 53 | if (argc >= 1) { |
52 | fprintf(stderr, "command: %s\n", *argv); | 54 | fprintf(stderr, "command: %s\n", *argv); |
53 | execvp (*argv, argv); | 55 | execvp(*argv, argv); |
54 | } | 56 | } else { |
55 | else { | 57 | char *prog; |
56 | char *prog; | ||
57 | prog = getenv ("SHELL"); | ||
58 | if (!prog) | ||
59 | prog = "/bin/sh"; | ||
60 | execlp (prog, prog, NULL); | ||
61 | } | ||
62 | fprintf(stderr, "chroot: cannot execute %s: %s\n", | ||
63 | *argv, strerror(errno)); | ||
64 | exit( FALSE); | ||
65 | } | ||
66 | 58 | ||
59 | prog = getenv("SHELL"); | ||
60 | if (!prog) | ||
61 | prog = "/bin/sh"; | ||
62 | execlp(prog, prog, NULL); | ||
63 | } | ||
64 | fprintf(stderr, "chroot: cannot execute %s: %s\n", | ||
65 | *argv, strerror(errno)); | ||
66 | exit(FALSE); | ||
67 | } | ||
diff --git a/coreutils/date.c b/coreutils/date.c index a3528921d..b4c3e7153 100644 --- a/coreutils/date.c +++ b/coreutils/date.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini date implementation for busybox | 3 | * Mini date implementation for busybox |
3 | * | 4 | * |
@@ -38,12 +39,13 @@ | |||
38 | an RFC 822 complient date output for shell scripting | 39 | an RFC 822 complient date output for shell scripting |
39 | mail commands */ | 40 | mail commands */ |
40 | 41 | ||
41 | static const char date_usage[] = "date [OPTION]... [+FORMAT]\n" | 42 | static const char date_usage[] = "date [OPTION]... [+FORMAT]\n" |
42 | " or: date [OPTION] [MMDDhhmm[[CC]YY][.ss]]\n\n" | 43 | " or: date [OPTION] [MMDDhhmm[[CC]YY][.ss]]\n\n" |
43 | "Display the current time in the given FORMAT, or set the system date.\n" | 44 | "Display the current time in the given FORMAT, or set the system date.\n" |
44 | "\nOptions:\n\t-R\t\toutput RFC-822 compliant date string\n" | 45 | "\nOptions:\n\t-R\t\toutput RFC-822 compliant date string\n" |
45 | "\t-s\t\tset time described by STRING\n" | 46 | "\t-s\t\tset time described by STRING\n" |
46 | "\t-u\t\tprint or set Coordinated Universal Time\n"; | 47 | |
48 | "\t-u\t\tprint or set Coordinated Universal Time\n"; | ||
47 | 49 | ||
48 | 50 | ||
49 | /* Input parsing code is always bulky - used heavy duty libc stuff as | 51 | /* Input parsing code is always bulky - used heavy duty libc stuff as |
@@ -51,240 +53,233 @@ static const char date_usage[] = "date [OPTION]... [+FORMAT]\n" | |||
51 | 53 | ||
52 | /* Default input handling to save suprising some people */ | 54 | /* Default input handling to save suprising some people */ |
53 | 55 | ||
54 | struct tm * | 56 | struct tm *date_conv_time(struct tm *tm_time, const char *t_string) |
55 | date_conv_time(struct tm *tm_time, const char *t_string) { | 57 | { |
56 | int nr; | 58 | int nr; |
57 | 59 | ||
58 | nr = sscanf(t_string, "%2d%2d%2d%2d%d", | 60 | nr = sscanf(t_string, "%2d%2d%2d%2d%d", |
59 | &(tm_time->tm_mon), | 61 | &(tm_time->tm_mon), |
60 | &(tm_time->tm_mday), | 62 | &(tm_time->tm_mday), |
61 | &(tm_time->tm_hour), | 63 | &(tm_time->tm_hour), |
62 | &(tm_time->tm_min), | 64 | &(tm_time->tm_min), &(tm_time->tm_year)); |
63 | &(tm_time->tm_year)); | 65 | |
64 | 66 | if (nr < 4 || nr > 5) { | |
65 | if(nr < 4 || nr > 5) { | 67 | fprintf(stderr, invalid_date, "date", t_string); |
66 | fprintf(stderr, invalid_date, "date", t_string); | 68 | exit(FALSE); |
67 | exit( FALSE); | 69 | } |
68 | } | 70 | |
69 | 71 | /* correct for century - minor Y2K problem here? */ | |
70 | /* correct for century - minor Y2K problem here? */ | 72 | if (tm_time->tm_year >= 1900) |
71 | if(tm_time->tm_year >= 1900) | 73 | tm_time->tm_year -= 1900; |
72 | tm_time->tm_year -= 1900; | 74 | /* adjust date */ |
73 | /* adjust date */ | 75 | tm_time->tm_mon -= 1; |
74 | tm_time->tm_mon -= 1; | 76 | |
75 | 77 | return (tm_time); | |
76 | return(tm_time); | ||
77 | 78 | ||
78 | } | 79 | } |
79 | 80 | ||
80 | 81 | ||
81 | /* The new stuff for LRP */ | 82 | /* The new stuff for LRP */ |
82 | 83 | ||
83 | struct tm * | 84 | struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string) |
84 | date_conv_ftime(struct tm *tm_time, const char *t_string) { | 85 | { |
85 | struct tm itm_time, jtm_time, ktm_time, \ | 86 | struct tm itm_time, jtm_time, ktm_time, ltm_time, mtm_time, ntm_time; |
86 | ltm_time, mtm_time, ntm_time; | 87 | |
87 | 88 | itm_time = *tm_time; | |
88 | itm_time = *tm_time; | 89 | jtm_time = *tm_time; |
89 | jtm_time = *tm_time; | 90 | ktm_time = *tm_time; |
90 | ktm_time = *tm_time; | 91 | ltm_time = *tm_time; |
91 | ltm_time = *tm_time; | 92 | mtm_time = *tm_time; |
92 | mtm_time = *tm_time; | 93 | ntm_time = *tm_time; |
93 | ntm_time = *tm_time; | 94 | |
94 | 95 | /* Parse input and assign appropriately to tm_time */ | |
95 | /* Parse input and assign appropriately to tm_time */ | 96 | |
96 | 97 | if (sscanf(t_string, "%d:%d:%d", | |
97 | if(sscanf(t_string, "%d:%d:%d", | 98 | &itm_time.tm_hour, &itm_time.tm_min, &itm_time.tm_sec) == 3) { |
98 | &itm_time.tm_hour, | 99 | |
99 | &itm_time.tm_min, | 100 | *tm_time = itm_time; |
100 | &itm_time.tm_sec) == 3 ) { | 101 | return (tm_time); |
101 | 102 | ||
102 | *tm_time = itm_time; | 103 | } else if (sscanf(t_string, "%d:%d", |
103 | return(tm_time); | 104 | &jtm_time.tm_hour, &jtm_time.tm_min) == 2) { |
104 | 105 | ||
105 | } else if (sscanf(t_string, "%d:%d", | 106 | *tm_time = jtm_time; |
106 | &jtm_time.tm_hour, | 107 | return (tm_time); |
107 | &jtm_time.tm_min) == 2) { | 108 | |
108 | 109 | } else if (sscanf(t_string, "%d.%d-%d:%d:%d", | |
109 | *tm_time = jtm_time; | 110 | &ktm_time.tm_mon, |
110 | return(tm_time); | 111 | &ktm_time.tm_mday, |
111 | 112 | &ktm_time.tm_hour, | |
112 | } else if (sscanf(t_string, "%d.%d-%d:%d:%d", | 113 | &ktm_time.tm_min, &ktm_time.tm_sec) == 5) { |
113 | &ktm_time.tm_mon, | 114 | |
114 | &ktm_time.tm_mday, | 115 | ktm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ |
115 | &ktm_time.tm_hour, | 116 | *tm_time = ktm_time; |
116 | &ktm_time.tm_min, | 117 | return (tm_time); |
117 | &ktm_time.tm_sec) == 5) { | 118 | |
118 | 119 | } else if (sscanf(t_string, "%d.%d-%d:%d", | |
119 | ktm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | 120 | <m_time.tm_mon, |
120 | *tm_time = ktm_time; | 121 | <m_time.tm_mday, |
121 | return(tm_time); | 122 | <m_time.tm_hour, <m_time.tm_min) == 4) { |
122 | 123 | ||
123 | } else if (sscanf(t_string, "%d.%d-%d:%d", | 124 | ltm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ |
124 | <m_time.tm_mon, | 125 | *tm_time = ltm_time; |
125 | <m_time.tm_mday, | 126 | return (tm_time); |
126 | <m_time.tm_hour, | 127 | |
127 | <m_time.tm_min) == 4) { | 128 | } else if (sscanf(t_string, "%d.%d.%d-%d:%d:%d", |
128 | 129 | &mtm_time.tm_year, | |
129 | ltm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | 130 | &mtm_time.tm_mon, |
130 | *tm_time = ltm_time; | 131 | &mtm_time.tm_mday, |
131 | return(tm_time); | 132 | &mtm_time.tm_hour, |
132 | 133 | &mtm_time.tm_min, &mtm_time.tm_sec) == 6) { | |
133 | } else if (sscanf(t_string, "%d.%d.%d-%d:%d:%d", | 134 | |
134 | &mtm_time.tm_year, | 135 | mtm_time.tm_year -= 1900; /* Adjust years */ |
135 | &mtm_time.tm_mon, | 136 | mtm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ |
136 | &mtm_time.tm_mday, | 137 | *tm_time = mtm_time; |
137 | &mtm_time.tm_hour, | 138 | return (tm_time); |
138 | &mtm_time.tm_min, | 139 | |
139 | &mtm_time.tm_sec) == 6) { | 140 | } else if (sscanf(t_string, "%d.%d.%d-%d:%d", |
140 | 141 | &ntm_time.tm_year, | |
141 | mtm_time.tm_year -= 1900; /* Adjust years */ | 142 | &ntm_time.tm_mon, |
142 | mtm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | 143 | &ntm_time.tm_mday, |
143 | *tm_time = mtm_time; | 144 | &ntm_time.tm_hour, &ntm_time.tm_min) == 5) { |
144 | return(tm_time); | 145 | ntm_time.tm_year -= 1900; /* Adjust years */ |
145 | 146 | ntm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | |
146 | } else if (sscanf(t_string, "%d.%d.%d-%d:%d", | 147 | *tm_time = ntm_time; |
147 | &ntm_time.tm_year, | 148 | return (tm_time); |
148 | &ntm_time.tm_mon, | 149 | |
149 | &ntm_time.tm_mday, | 150 | } |
150 | &ntm_time.tm_hour, | 151 | |
151 | &ntm_time.tm_min) == 5) { | 152 | fprintf(stderr, invalid_date, "date", t_string); |
152 | ntm_time.tm_year -= 1900; /* Adjust years */ | 153 | |
153 | ntm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | 154 | exit(FALSE); |
154 | *tm_time = ntm_time; | ||
155 | return(tm_time); | ||
156 | |||
157 | } | ||
158 | |||
159 | fprintf(stderr, invalid_date, "date", t_string); | ||
160 | |||
161 | exit( FALSE); | ||
162 | 155 | ||
163 | } | 156 | } |
164 | 157 | ||
165 | 158 | ||
166 | int | 159 | int date_main(int argc, char **argv) |
167 | date_main(int argc, char * * argv) | ||
168 | { | 160 | { |
169 | char *date_str = NULL; | 161 | char *date_str = NULL; |
170 | char *date_fmt = NULL; | 162 | char *date_fmt = NULL; |
171 | char *t_buff; | 163 | char *t_buff; |
172 | int i; | 164 | int i; |
173 | int set_time = 0; | 165 | int set_time = 0; |
174 | int rfc822 = 0; | 166 | int rfc822 = 0; |
175 | int utc = 0; | 167 | int utc = 0; |
176 | int use_arg = 0; | 168 | int use_arg = 0; |
177 | time_t tm; | 169 | time_t tm; |
178 | struct tm tm_time; | 170 | struct tm tm_time; |
179 | 171 | ||
180 | /* Interpret command line args */ | 172 | /* Interpret command line args */ |
181 | i = --argc; | 173 | i = --argc; |
182 | argv++; | 174 | argv++; |
183 | while (i > 0 && **argv) { | 175 | while (i > 0 && **argv) { |
184 | if (**argv == '-') { | 176 | if (**argv == '-') { |
185 | while (i>0 && *++(*argv)) switch (**argv) { | 177 | while (i > 0 && *++(*argv)) |
186 | case 'R': | 178 | switch (**argv) { |
187 | rfc822 = 1; | 179 | case 'R': |
188 | break; | 180 | rfc822 = 1; |
189 | case 's': | 181 | break; |
190 | set_time = 1; | 182 | case 's': |
191 | if(date_str != NULL) usage ( date_usage); | 183 | set_time = 1; |
192 | date_str = optarg; | 184 | if (date_str != NULL) |
193 | break; | 185 | usage(date_usage); |
194 | case 'u': | 186 | date_str = optarg; |
195 | utc = 1; | 187 | break; |
196 | if (putenv ("TZ=UTC0") != 0) { | 188 | case 'u': |
197 | fprintf(stderr, memory_exhausted, "date"); | 189 | utc = 1; |
198 | exit( FALSE); | 190 | if (putenv("TZ=UTC0") != 0) { |
191 | fprintf(stderr, memory_exhausted, "date"); | ||
192 | exit(FALSE); | ||
193 | } | ||
194 | /* Look ma, no break. Don't fix it either. */ | ||
195 | case 'd': | ||
196 | use_arg = 1; | ||
197 | if (date_str != NULL) | ||
198 | usage(date_usage); | ||
199 | date_str = optarg; | ||
200 | break; | ||
201 | case '-': | ||
202 | usage(date_usage); | ||
203 | } | ||
204 | } else { | ||
205 | if ((date_fmt == NULL) && (strcmp(*argv, "+") == 0)) | ||
206 | date_fmt = *argv; | ||
207 | else if (date_str == NULL) { | ||
208 | set_time = 1; | ||
209 | date_str = *argv; | ||
210 | } else { | ||
211 | usage(date_usage); | ||
212 | } | ||
199 | } | 213 | } |
200 | /* Look ma, no break. Don't fix it either. */ | 214 | i--; |
201 | case 'd': | 215 | argv++; |
202 | use_arg = 1; | ||
203 | if(date_str != NULL) usage ( date_usage); | ||
204 | date_str = optarg; | ||
205 | break; | ||
206 | case '-': | ||
207 | usage ( date_usage); | ||
208 | } | ||
209 | } else { | ||
210 | if ( (date_fmt == NULL) && (strcmp(*argv, "+")==0) ) | ||
211 | date_fmt=*argv; | ||
212 | else if (date_str == NULL) { | ||
213 | set_time = 1; | ||
214 | date_str=*argv; | ||
215 | } else { | ||
216 | usage ( date_usage); | ||
217 | } | ||
218 | } | 216 | } |
219 | i--; | 217 | |
220 | argv++; | 218 | |
221 | } | 219 | /* Now we have parsed all the information except the date format |
222 | 220 | which depends on whether the clock is being set or read */ | |
223 | 221 | ||
224 | /* Now we have parsed all the information except the date format | 222 | time(&tm); |
225 | which depends on whether the clock is being set or read */ | 223 | memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); |
226 | 224 | /* Zero out fields - take her back to midnight! */ | |
227 | time(&tm); | 225 | if (date_str != NULL) { |
228 | memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); | 226 | tm_time.tm_sec = 0; |
229 | /* Zero out fields - take her back to midnight!*/ | 227 | tm_time.tm_min = 0; |
230 | if(date_str != NULL) { | 228 | tm_time.tm_hour = 0; |
231 | tm_time.tm_sec = 0; | 229 | } |
232 | tm_time.tm_min = 0; | 230 | |
233 | tm_time.tm_hour = 0; | 231 | /* Process any date input to UNIX time since 1 Jan 1970 */ |
234 | } | 232 | if (date_str != NULL) { |
235 | 233 | ||
236 | /* Process any date input to UNIX time since 1 Jan 1970 */ | 234 | if (strchr(date_str, ':') != NULL) { |
237 | if(date_str != NULL) { | 235 | date_conv_ftime(&tm_time, date_str); |
238 | 236 | } else { | |
239 | if(strchr(date_str, ':') != NULL) { | 237 | date_conv_time(&tm_time, date_str); |
240 | date_conv_ftime(&tm_time, date_str); | 238 | } |
241 | } else { | 239 | |
242 | date_conv_time(&tm_time, date_str); | 240 | /* Correct any day of week and day of year etc fields */ |
243 | } | 241 | tm = mktime(&tm_time); |
244 | 242 | if (tm < 0) { | |
245 | /* Correct any day of week and day of year etc fields */ | 243 | fprintf(stderr, invalid_date, "date", date_str); |
246 | tm = mktime(&tm_time); | 244 | exit(FALSE); |
247 | if (tm < 0 ) { | 245 | } |
248 | fprintf(stderr, invalid_date, "date", date_str); | 246 | |
249 | exit( FALSE); | 247 | /* if setting time, set it */ |
250 | } | 248 | if (set_time) { |
251 | 249 | if (stime(&tm) < 0) { | |
252 | /* if setting time, set it */ | 250 | fprintf(stderr, "date: can't set date.\n"); |
253 | if(set_time) { | 251 | exit(FALSE); |
254 | if( stime(&tm) < 0) { | 252 | } |
255 | fprintf(stderr, "date: can't set date.\n"); | 253 | } |
256 | exit( FALSE); | 254 | } |
257 | } | 255 | |
258 | } | 256 | /* Display output */ |
259 | } | 257 | |
260 | 258 | /* Deal with format string */ | |
261 | /* Display output */ | 259 | if (date_fmt == NULL) { |
262 | 260 | date_fmt = (rfc822 | |
263 | /* Deal with format string */ | 261 | ? (utc |
264 | if(date_fmt == NULL) { | 262 | ? "%a, %_d %b %Y %H:%M:%S GMT" |
265 | date_fmt = (rfc822 | 263 | : "%a, %_d %b %Y %H:%M:%S %z") |
266 | ? (utc | 264 | : "%a %b %e %H:%M:%S %Z %Y"); |
267 | ? "%a, %_d %b %Y %H:%M:%S GMT" | 265 | |
268 | : "%a, %_d %b %Y %H:%M:%S %z") | 266 | } else if (*date_fmt == '\0') { |
269 | : "%a %b %e %H:%M:%S %Z %Y"); | 267 | /* Imitate what GNU 'date' does with NO format string! */ |
270 | 268 | printf("\n"); | |
271 | } else if ( *date_fmt == '\0' ) { | 269 | exit(TRUE); |
272 | /* Imitate what GNU 'date' does with NO format string! */ | 270 | } |
273 | printf ("\n"); | 271 | |
274 | exit( TRUE); | 272 | /* Handle special conversions */ |
275 | } | 273 | |
276 | 274 | if (strncmp(date_fmt, "%f", 2) == 0) { | |
277 | /* Handle special conversions */ | 275 | date_fmt = "%Y.%m.%d-%H:%M:%S"; |
278 | 276 | } | |
279 | if( strncmp( date_fmt, "%f", 2) == 0 ) { | 277 | |
280 | date_fmt = "%Y.%m.%d-%H:%M:%S"; | 278 | /* Print OUTPUT (after ALL that!) */ |
281 | } | 279 | t_buff = malloc(201); |
282 | 280 | strftime(t_buff, 200, date_fmt, &tm_time); | |
283 | /* Print OUTPUT (after ALL that!) */ | 281 | printf("%s\n", t_buff); |
284 | t_buff = malloc(201); | 282 | |
285 | strftime(t_buff, 200, date_fmt, &tm_time); | 283 | exit(TRUE); |
286 | printf("%s\n", t_buff); | ||
287 | |||
288 | exit( TRUE); | ||
289 | 284 | ||
290 | } | 285 | } |
diff --git a/coreutils/dd.c b/coreutils/dd.c index 3e1024a60..0d5b3e8ab 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini dd implementation for busybox | 3 | * Mini dd implementation for busybox |
3 | * | 4 | * |
@@ -40,164 +41,159 @@ typedef unsigned long long int uintmax_t; | |||
40 | #endif | 41 | #endif |
41 | 42 | ||
42 | static const char dd_usage[] = | 43 | static const char dd_usage[] = |
43 | "dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n]\n\n" | 44 | "dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n]\n\n" |
44 | "Copy a file, converting and formatting according to options\n\n" | 45 | "Copy a file, converting and formatting according to options\n\n" |
45 | "\tif=FILE\tread from FILE instead of stdin\n" | 46 | "\tif=FILE\tread from FILE instead of stdin\n" |
46 | "\tof=FILE\twrite to FILE instead of stdout\n" | 47 | "\tof=FILE\twrite to FILE instead of stdout\n" |
47 | "\tbs=n\tread and write n bytes at a time\n" | 48 | "\tbs=n\tread and write n bytes at a time\n" |
48 | "\tcount=n\tcopy only n input blocks\n" | 49 | "\tcount=n\tcopy only n input blocks\n" |
49 | "\tskip=n\tskip n input blocks\n" | 50 | "\tskip=n\tskip n input blocks\n" |
50 | "\tseek=n\tskip n output blocks\n" | 51 | "\tseek=n\tskip n output blocks\n" |
51 | "\n" | ||
52 | "Numbers may be suffixed by w (x2), k (x1024), b (x512), or M (x1024^2)\n"; | ||
53 | 52 | ||
53 | "\n" | ||
54 | "Numbers may be suffixed by w (x2), k (x1024), b (x512), or M (x1024^2)\n"; | ||
54 | 55 | ||
55 | 56 | ||
56 | extern int dd_main (int argc, char **argv) | 57 | |
58 | extern int dd_main(int argc, char **argv) | ||
57 | { | 59 | { |
58 | const char *inFile = NULL; | 60 | const char *inFile = NULL; |
59 | const char *outFile = NULL; | 61 | const char *outFile = NULL; |
60 | char *cp; | 62 | char *cp; |
61 | int inFd; | 63 | int inFd; |
62 | int outFd; | 64 | int outFd; |
63 | int inCc = 0; | 65 | int inCc = 0; |
64 | int outCc; | 66 | int outCc; |
65 | long blockSize = 512; | 67 | long blockSize = 512; |
66 | uintmax_t skipBlocks = 0; | 68 | uintmax_t skipBlocks = 0; |
67 | uintmax_t seekBlocks = 0; | 69 | uintmax_t seekBlocks = 0; |
68 | uintmax_t count = (uintmax_t)-1; | 70 | uintmax_t count = (uintmax_t) - 1; |
69 | uintmax_t intotal; | 71 | uintmax_t intotal; |
70 | uintmax_t outTotal; | 72 | uintmax_t outTotal; |
71 | unsigned char *buf; | 73 | unsigned char *buf; |
72 | 74 | ||
73 | argc--; | 75 | argc--; |
74 | argv++; | 76 | argv++; |
75 | |||
76 | /* Parse any options */ | ||
77 | while (argc) { | ||
78 | if (inFile == NULL && (strncmp(*argv, "if", 2) == 0)) | ||
79 | inFile=((strchr(*argv, '='))+1); | ||
80 | else if (outFile == NULL && (strncmp(*argv, "of", 2) == 0)) | ||
81 | outFile=((strchr(*argv, '='))+1); | ||
82 | else if (strncmp("count", *argv, 5) == 0) { | ||
83 | count = getNum ((strchr(*argv, '='))+1); | ||
84 | if (count <= 0) { | ||
85 | fprintf (stderr, "Bad count value %s\n", *argv); | ||
86 | goto usage; | ||
87 | } | ||
88 | } | ||
89 | else if (strncmp(*argv, "bs", 2) == 0) { | ||
90 | blockSize = getNum ((strchr(*argv, '='))+1); | ||
91 | if (blockSize <= 0) { | ||
92 | fprintf (stderr, "Bad block size value %s\n", *argv); | ||
93 | goto usage; | ||
94 | } | ||
95 | } | ||
96 | else if (strncmp(*argv, "skip", 4) == 0) { | ||
97 | skipBlocks = getNum ((strchr(*argv, '='))+1); | ||
98 | if (skipBlocks <= 0) { | ||
99 | fprintf (stderr, "Bad skip value %s\n", *argv); | ||
100 | goto usage; | ||
101 | } | ||
102 | 77 | ||
78 | /* Parse any options */ | ||
79 | while (argc) { | ||
80 | if (inFile == NULL && (strncmp(*argv, "if", 2) == 0)) | ||
81 | inFile = ((strchr(*argv, '=')) + 1); | ||
82 | else if (outFile == NULL && (strncmp(*argv, "of", 2) == 0)) | ||
83 | outFile = ((strchr(*argv, '=')) + 1); | ||
84 | else if (strncmp("count", *argv, 5) == 0) { | ||
85 | count = getNum((strchr(*argv, '=')) + 1); | ||
86 | if (count <= 0) { | ||
87 | fprintf(stderr, "Bad count value %s\n", *argv); | ||
88 | goto usage; | ||
89 | } | ||
90 | } else if (strncmp(*argv, "bs", 2) == 0) { | ||
91 | blockSize = getNum((strchr(*argv, '=')) + 1); | ||
92 | if (blockSize <= 0) { | ||
93 | fprintf(stderr, "Bad block size value %s\n", *argv); | ||
94 | goto usage; | ||
95 | } | ||
96 | } else if (strncmp(*argv, "skip", 4) == 0) { | ||
97 | skipBlocks = getNum((strchr(*argv, '=')) + 1); | ||
98 | if (skipBlocks <= 0) { | ||
99 | fprintf(stderr, "Bad skip value %s\n", *argv); | ||
100 | goto usage; | ||
101 | } | ||
102 | |||
103 | } else if (strncmp(*argv, "seek", 4) == 0) { | ||
104 | seekBlocks = getNum((strchr(*argv, '=')) + 1); | ||
105 | if (seekBlocks <= 0) { | ||
106 | fprintf(stderr, "Bad seek value %s\n", *argv); | ||
107 | goto usage; | ||
108 | } | ||
109 | |||
110 | } else { | ||
111 | goto usage; | ||
112 | } | ||
113 | argc--; | ||
114 | argv++; | ||
103 | } | 115 | } |
104 | else if (strncmp(*argv, "seek", 4) == 0) { | ||
105 | seekBlocks = getNum ((strchr(*argv, '='))+1); | ||
106 | if (seekBlocks <= 0) { | ||
107 | fprintf (stderr, "Bad seek value %s\n", *argv); | ||
108 | goto usage; | ||
109 | } | ||
110 | 116 | ||
117 | buf = malloc(blockSize); | ||
118 | if (buf == NULL) { | ||
119 | fprintf(stderr, "Cannot allocate buffer\n"); | ||
120 | exit(FALSE); | ||
111 | } | 121 | } |
112 | else { | 122 | |
113 | goto usage; | 123 | intotal = 0; |
124 | outTotal = 0; | ||
125 | |||
126 | if (inFile == NULL) | ||
127 | inFd = fileno(stdin); | ||
128 | else | ||
129 | inFd = open(inFile, 0); | ||
130 | |||
131 | if (inFd < 0) { | ||
132 | perror(inFile); | ||
133 | free(buf); | ||
134 | exit(FALSE); | ||
114 | } | 135 | } |
115 | argc--; | 136 | |
116 | argv++; | 137 | if (outFile == NULL) |
117 | } | 138 | outFd = fileno(stdout); |
118 | 139 | else | |
119 | buf = malloc (blockSize); | 140 | outFd = open(outFile, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
120 | if (buf == NULL) { | 141 | |
121 | fprintf (stderr, "Cannot allocate buffer\n"); | 142 | if (outFd < 0) { |
122 | exit( FALSE); | 143 | perror(outFile); |
123 | } | 144 | close(inFd); |
124 | 145 | free(buf); | |
125 | intotal = 0; | 146 | exit(FALSE); |
126 | outTotal = 0; | ||
127 | |||
128 | if (inFile == NULL) | ||
129 | inFd = fileno(stdin); | ||
130 | else | ||
131 | inFd = open (inFile, 0); | ||
132 | |||
133 | if (inFd < 0) { | ||
134 | perror (inFile); | ||
135 | free (buf); | ||
136 | exit( FALSE); | ||
137 | } | ||
138 | |||
139 | if (outFile == NULL) | ||
140 | outFd = fileno(stdout); | ||
141 | else | ||
142 | outFd = open(outFile, O_WRONLY | O_CREAT | O_TRUNC, 0666); | ||
143 | |||
144 | if (outFd < 0) { | ||
145 | perror (outFile); | ||
146 | close (inFd); | ||
147 | free (buf); | ||
148 | exit( FALSE); | ||
149 | } | ||
150 | |||
151 | lseek(inFd, skipBlocks*blockSize, SEEK_SET); | ||
152 | lseek(outFd, seekBlocks*blockSize, SEEK_SET); | ||
153 | // | ||
154 | //TODO: Convert to using fullRead & fullWrite | ||
155 | // from utility.c | ||
156 | // -Erik | ||
157 | while (outTotal < count * blockSize) { | ||
158 | inCc = read (inFd, buf, blockSize); | ||
159 | if (inCc < 0) { | ||
160 | perror (inFile); | ||
161 | goto cleanup; | ||
162 | } else if (inCc == 0) { | ||
163 | goto cleanup; | ||
164 | } | 147 | } |
165 | intotal += inCc; | 148 | |
166 | cp = buf; | 149 | lseek(inFd, skipBlocks * blockSize, SEEK_SET); |
167 | 150 | lseek(outFd, seekBlocks * blockSize, SEEK_SET); | |
168 | while (intotal > outTotal) { | 151 | // |
169 | if (outTotal + inCc > count * blockSize) | 152 | //TODO: Convert to using fullRead & fullWrite |
170 | inCc = count * blockSize - outTotal; | 153 | // from utility.c |
171 | outCc = write (outFd, cp, inCc); | 154 | // -Erik |
172 | if (outCc < 0) { | 155 | while (outTotal < count * blockSize) { |
173 | perror (outFile); | 156 | inCc = read(inFd, buf, blockSize); |
174 | goto cleanup; | 157 | if (inCc < 0) { |
175 | } else if (outCc == 0) { | 158 | perror(inFile); |
176 | goto cleanup; | 159 | goto cleanup; |
177 | } | 160 | } else if (inCc == 0) { |
178 | 161 | goto cleanup; | |
179 | inCc -= outCc; | 162 | } |
180 | cp += outCc; | 163 | intotal += inCc; |
181 | outTotal += outCc; | 164 | cp = buf; |
165 | |||
166 | while (intotal > outTotal) { | ||
167 | if (outTotal + inCc > count * blockSize) | ||
168 | inCc = count * blockSize - outTotal; | ||
169 | outCc = write(outFd, cp, inCc); | ||
170 | if (outCc < 0) { | ||
171 | perror(outFile); | ||
172 | goto cleanup; | ||
173 | } else if (outCc == 0) { | ||
174 | goto cleanup; | ||
175 | } | ||
176 | |||
177 | inCc -= outCc; | ||
178 | cp += outCc; | ||
179 | outTotal += outCc; | ||
180 | } | ||
182 | } | 181 | } |
183 | } | ||
184 | 182 | ||
185 | if (inCc < 0) | 183 | if (inCc < 0) |
186 | perror (inFile); | 184 | perror(inFile); |
187 | 185 | ||
188 | cleanup: | 186 | cleanup: |
189 | close (inFd); | 187 | close(inFd); |
190 | close (outFd); | 188 | close(outFd); |
191 | free (buf); | 189 | free(buf); |
192 | 190 | ||
193 | printf ("%ld+%d records in\n", (long)(intotal / blockSize), | 191 | printf("%ld+%d records in\n", (long) (intotal / blockSize), |
194 | (intotal % blockSize) != 0); | 192 | (intotal % blockSize) != 0); |
195 | printf ("%ld+%d records out\n", (long)(outTotal / blockSize), | 193 | printf("%ld+%d records out\n", (long) (outTotal / blockSize), |
196 | (outTotal % blockSize) != 0); | 194 | (outTotal % blockSize) != 0); |
197 | exit( TRUE); | 195 | exit(TRUE); |
198 | usage: | 196 | usage: |
199 | 197 | ||
200 | usage( dd_usage); | 198 | usage(dd_usage); |
201 | } | 199 | } |
202 | |||
203 | |||
diff --git a/coreutils/df.c b/coreutils/df.c index 24c94a246..43d5d26e7 100644 --- a/coreutils/df.c +++ b/coreutils/df.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini df implementation for busybox | 3 | * Mini df implementation for busybox |
3 | * | 4 | * |
@@ -29,81 +30,81 @@ | |||
29 | #include <fstab.h> | 30 | #include <fstab.h> |
30 | 31 | ||
31 | static const char df_usage[] = "df [filesystem ...]\n" | 32 | static const char df_usage[] = "df [filesystem ...]\n" |
32 | "\n" "\tPrint the filesystem space used and space available.\n"; | ||
33 | 33 | ||
34 | extern const char mtab_file[]; /* Defined in utility.c */ | 34 | "\n" "\tPrint the filesystem space used and space available.\n"; |
35 | |||
36 | extern const char mtab_file[]; /* Defined in utility.c */ | ||
35 | 37 | ||
36 | static int df(char *device, const char *mountPoint) | 38 | static int df(char *device, const char *mountPoint) |
37 | { | 39 | { |
38 | struct statfs s; | 40 | struct statfs s; |
39 | long blocks_used; | 41 | long blocks_used; |
40 | long blocks_percent_used; | 42 | long blocks_percent_used; |
41 | struct fstab* fstabItem; | 43 | struct fstab *fstabItem; |
42 | |||
43 | if (statfs(mountPoint, &s) != 0) { | ||
44 | perror(mountPoint); | ||
45 | return FALSE; | ||
46 | } | ||
47 | 44 | ||
48 | if (s.f_blocks > 0) { | 45 | if (statfs(mountPoint, &s) != 0) { |
49 | blocks_used = s.f_blocks - s.f_bfree; | 46 | perror(mountPoint); |
50 | blocks_percent_used = (long) | 47 | return FALSE; |
51 | (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); | ||
52 | /* Note that if /etc/fstab is missing, libc can't fix up /dev/root for us */ | ||
53 | if (strcmp (device, "/dev/root") == 0) { | ||
54 | fstabItem = getfsfile ("/"); | ||
55 | if (fstabItem != NULL) | ||
56 | device = fstabItem->fs_spec; | ||
57 | } | 48 | } |
58 | printf("%-20s %9ld %9ld %9ld %3ld%% %s\n", | ||
59 | device, | ||
60 | (long) (s.f_blocks * (s.f_bsize / 1024.0)), | ||
61 | (long) ((s.f_blocks - s.f_bfree) * (s.f_bsize / 1024.0)), | ||
62 | (long) (s.f_bavail * (s.f_bsize / 1024.0)), | ||
63 | blocks_percent_used, mountPoint); | ||
64 | 49 | ||
65 | } | 50 | if (s.f_blocks > 0) { |
51 | blocks_used = s.f_blocks - s.f_bfree; | ||
52 | blocks_percent_used = (long) | ||
53 | (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); | ||
54 | /* Note that if /etc/fstab is missing, libc can't fix up /dev/root for us */ | ||
55 | if (strcmp(device, "/dev/root") == 0) { | ||
56 | fstabItem = getfsfile("/"); | ||
57 | if (fstabItem != NULL) | ||
58 | device = fstabItem->fs_spec; | ||
59 | } | ||
60 | printf("%-20s %9ld %9ld %9ld %3ld%% %s\n", | ||
61 | device, | ||
62 | (long) (s.f_blocks * (s.f_bsize / 1024.0)), | ||
63 | (long) ((s.f_blocks - s.f_bfree) * (s.f_bsize / 1024.0)), | ||
64 | (long) (s.f_bavail * (s.f_bsize / 1024.0)), | ||
65 | blocks_percent_used, mountPoint); | ||
66 | |||
67 | } | ||
66 | 68 | ||
67 | return TRUE; | 69 | return TRUE; |
68 | } | 70 | } |
69 | 71 | ||
70 | extern int df_main(int argc, char **argv) | 72 | extern int df_main(int argc, char **argv) |
71 | { | 73 | { |
72 | printf("%-20s %-14s %s %s %s %s\n", "Filesystem", | 74 | printf("%-20s %-14s %s %s %s %s\n", "Filesystem", |
73 | "1k-blocks", "Used", "Available", "Use%", "Mounted on"); | 75 | "1k-blocks", "Used", "Available", "Use%", "Mounted on"); |
74 | 76 | ||
75 | if (argc > 1) { | 77 | if (argc > 1) { |
76 | struct mntent *mountEntry; | 78 | struct mntent *mountEntry; |
77 | int status; | 79 | int status; |
78 | 80 | ||
79 | while (argc > 1) { | 81 | while (argc > 1) { |
80 | if ((mountEntry = findMountPoint(argv[1], mtab_file)) == | 82 | if ((mountEntry = findMountPoint(argv[1], mtab_file)) == 0) { |
81 | 0) { | 83 | fprintf(stderr, "%s: can't find mount point.\n", argv[1]); |
82 | fprintf(stderr, "%s: can't find mount point.\n", argv[1]); | 84 | exit(FALSE); |
83 | exit( FALSE); | 85 | } |
84 | } | 86 | status = df(mountEntry->mnt_fsname, mountEntry->mnt_dir); |
85 | status = df(mountEntry->mnt_fsname, mountEntry->mnt_dir); | 87 | if (status != 0) |
86 | if (status != 0) | 88 | exit(status); |
87 | exit( status); | 89 | argc--; |
88 | argc--; | 90 | argv++; |
89 | argv++; | 91 | } |
90 | } | 92 | exit(TRUE); |
91 | exit( TRUE); | 93 | } else { |
92 | } else { | 94 | FILE *mountTable; |
93 | FILE *mountTable; | 95 | struct mntent *mountEntry; |
94 | struct mntent *mountEntry; | ||
95 | 96 | ||
96 | mountTable = setmntent(mtab_file, "r"); | 97 | mountTable = setmntent(mtab_file, "r"); |
97 | if (mountTable == 0) { | 98 | if (mountTable == 0) { |
98 | perror(mtab_file); | 99 | perror(mtab_file); |
99 | exit(FALSE); | 100 | exit(FALSE); |
100 | } | 101 | } |
101 | 102 | ||
102 | while ((mountEntry = getmntent(mountTable))) { | 103 | while ((mountEntry = getmntent(mountTable))) { |
103 | df(mountEntry->mnt_fsname, mountEntry->mnt_dir); | 104 | df(mountEntry->mnt_fsname, mountEntry->mnt_dir); |
105 | } | ||
106 | endmntent(mountTable); | ||
104 | } | 107 | } |
105 | endmntent(mountTable); | ||
106 | } | ||
107 | 108 | ||
108 | exit( TRUE); | 109 | exit(TRUE); |
109 | } | 110 | } |
diff --git a/coreutils/du.c b/coreutils/du.c index e2cf3f7c0..7151e3a9c 100644 --- a/coreutils/du.c +++ b/coreutils/du.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini du implementation for busybox | 3 | * Mini du implementation for busybox |
3 | * | 4 | * |
@@ -31,119 +32,121 @@ | |||
31 | #include <dirent.h> | 32 | #include <dirent.h> |
32 | #include <stdio.h> | 33 | #include <stdio.h> |
33 | #include <errno.h> | 34 | #include <errno.h> |
34 | #include <sys/param.h> /* for PATH_MAX */ | 35 | #include <sys/param.h> /* for PATH_MAX */ |
35 | 36 | ||
36 | typedef void (Display)(long, char *); | 37 | typedef void (Display) (long, char *); |
37 | 38 | ||
38 | static const char du_usage[] = | 39 | static const char du_usage[] = |
39 | "du [OPTION]... [FILE]...\n\n" | ||
40 | "\t-s\tdisplay only a total for each argument\n" | ||
41 | ; | ||
42 | 40 | ||
43 | static int du_depth = 0; | 41 | "du [OPTION]... [FILE]...\n\n" |
42 | "\t-s\tdisplay only a total for each argument\n"; | ||
44 | 43 | ||
45 | static Display *print; | 44 | static int du_depth = 0; |
46 | 45 | ||
47 | static void | 46 | static Display *print; |
48 | print_normal(long size, char *filename) | 47 | |
48 | static void print_normal(long size, char *filename) | ||
49 | { | 49 | { |
50 | fprintf(stdout, "%-7ld %s\n", size, filename); | 50 | fprintf(stdout, "%-7ld %s\n", size, filename); |
51 | } | 51 | } |
52 | 52 | ||
53 | static void | 53 | static void print_summary(long size, char *filename) |
54 | print_summary(long size, char *filename) | ||
55 | { | 54 | { |
56 | if (du_depth == 1) { | 55 | if (du_depth == 1) { |
57 | print_normal(size, filename); | 56 | print_normal(size, filename); |
58 | } | 57 | } |
59 | } | 58 | } |
60 | 59 | ||
61 | 60 | ||
62 | /* tiny recursive du */ | 61 | /* tiny recursive du */ |
63 | static long | 62 | static long du(char *filename) |
64 | du(char *filename) | ||
65 | { | 63 | { |
66 | struct stat statbuf; | 64 | struct stat statbuf; |
67 | long sum; | 65 | long sum; |
68 | 66 | ||
69 | if ((lstat(filename, &statbuf)) != 0) { | 67 | if ((lstat(filename, &statbuf)) != 0) { |
70 | fprintf(stdout, "du: %s: %s\n", filename, strerror(errno)); | 68 | fprintf(stdout, "du: %s: %s\n", filename, strerror(errno)); |
71 | return 0; | 69 | return 0; |
72 | } | ||
73 | |||
74 | du_depth++; | ||
75 | sum = statbuf.st_blocks; | ||
76 | |||
77 | if (S_ISDIR(statbuf.st_mode)) { | ||
78 | DIR *dir; | ||
79 | struct dirent *entry; | ||
80 | |||
81 | dir = opendir(filename); | ||
82 | if (!dir) { return 0; } | ||
83 | while ((entry = readdir(dir))) { | ||
84 | char newfile[PATH_MAX + 1]; | ||
85 | char *name = entry->d_name; | ||
86 | |||
87 | if ( (strcmp(name, "..") == 0) | ||
88 | || (strcmp(name, ".") == 0)) | ||
89 | { continue; } | ||
90 | |||
91 | if (strlen(filename) + strlen(name) + 1 > PATH_MAX) { | ||
92 | fprintf(stderr, name_too_long, "du"); | ||
93 | return 0; | ||
94 | } | ||
95 | sprintf(newfile, "%s/%s", filename, name); | ||
96 | |||
97 | sum += du(newfile); | ||
98 | } | 70 | } |
99 | closedir(dir); | 71 | |
100 | print(sum, filename); | 72 | du_depth++; |
101 | } | 73 | sum = statbuf.st_blocks; |
102 | du_depth--; | 74 | |
103 | return sum; | 75 | if (S_ISDIR(statbuf.st_mode)) { |
76 | DIR *dir; | ||
77 | struct dirent *entry; | ||
78 | |||
79 | dir = opendir(filename); | ||
80 | if (!dir) { | ||
81 | return 0; | ||
82 | } | ||
83 | while ((entry = readdir(dir))) { | ||
84 | char newfile[PATH_MAX + 1]; | ||
85 | char *name = entry->d_name; | ||
86 | |||
87 | if ((strcmp(name, "..") == 0) | ||
88 | || (strcmp(name, ".") == 0)) { | ||
89 | continue; | ||
90 | } | ||
91 | |||
92 | if (strlen(filename) + strlen(name) + 1 > PATH_MAX) { | ||
93 | fprintf(stderr, name_too_long, "du"); | ||
94 | return 0; | ||
95 | } | ||
96 | sprintf(newfile, "%s/%s", filename, name); | ||
97 | |||
98 | sum += du(newfile); | ||
99 | } | ||
100 | closedir(dir); | ||
101 | print(sum, filename); | ||
102 | } | ||
103 | du_depth--; | ||
104 | return sum; | ||
104 | } | 105 | } |
105 | 106 | ||
106 | int | 107 | int du_main(int argc, char **argv) |
107 | du_main(int argc, char **argv) | ||
108 | { | 108 | { |
109 | int i; | 109 | int i; |
110 | char opt; | 110 | char opt; |
111 | 111 | ||
112 | /* default behaviour */ | 112 | /* default behaviour */ |
113 | print = print_normal; | 113 | print = print_normal; |
114 | 114 | ||
115 | /* parse argv[] */ | 115 | /* parse argv[] */ |
116 | for (i = 1; i < argc; i++) { | 116 | for (i = 1; i < argc; i++) { |
117 | if (argv[i][0] == '-') { | 117 | if (argv[i][0] == '-') { |
118 | opt = argv[i][1]; | 118 | opt = argv[i][1]; |
119 | switch (opt) { | 119 | switch (opt) { |
120 | case 's': | 120 | case 's': |
121 | print = print_summary; | 121 | print = print_summary; |
122 | break; | 122 | break; |
123 | case 'h': | 123 | case 'h': |
124 | usage(du_usage); | 124 | usage(du_usage); |
125 | break; | 125 | break; |
126 | default: | 126 | default: |
127 | fprintf(stderr, "du: invalid option -- %c\n", opt); | 127 | fprintf(stderr, "du: invalid option -- %c\n", opt); |
128 | usage(du_usage); | 128 | usage(du_usage); |
129 | } | 129 | } |
130 | } else { | 130 | } else { |
131 | break; | 131 | break; |
132 | } | ||
132 | } | 133 | } |
133 | } | ||
134 | 134 | ||
135 | /* go through remaining args (if any) */ | 135 | /* go through remaining args (if any) */ |
136 | if (i >= argc) { | 136 | if (i >= argc) { |
137 | du("."); | 137 | du("."); |
138 | } else { | 138 | } else { |
139 | long sum; | 139 | long sum; |
140 | for ( ; i < argc; i++) { | 140 | |
141 | sum = du(argv[i]); | 141 | for (; i < argc; i++) { |
142 | if ((sum) && (isDirectory(argv[i], FALSE))) { print_normal(sum, argv[i]); } | 142 | sum = du(argv[i]); |
143 | if ((sum) && (isDirectory(argv[i], FALSE))) { | ||
144 | print_normal(sum, argv[i]); | ||
145 | } | ||
146 | } | ||
143 | } | 147 | } |
144 | } | ||
145 | 148 | ||
146 | exit(0); | 149 | exit(0); |
147 | } | 150 | } |
148 | 151 | ||
149 | /* $Id: du.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */ | 152 | /* $Id: du.c,v 1.11 2000/02/08 19:58:47 erik Exp $ */ |
diff --git a/coreutils/head.c b/coreutils/head.c index b80d06580..82a73de2a 100644 --- a/coreutils/head.c +++ b/coreutils/head.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini head implementation for busybox | 3 | * Mini head implementation for busybox |
3 | * | 4 | * |
@@ -26,83 +27,86 @@ | |||
26 | #include <stdio.h> | 27 | #include <stdio.h> |
27 | 28 | ||
28 | const char head_usage[] = | 29 | const char head_usage[] = |
29 | "head [OPTION] [FILE]...\n\n" | 30 | "head [OPTION] [FILE]...\n\n" |
30 | "Print first 10 lines of each FILE to standard output.\n" | 31 | "Print first 10 lines of each FILE to standard output.\n" |
31 | "With more than one FILE, precede each with a header giving the\n" | 32 | "With more than one FILE, precede each with a header giving the\n" |
32 | "file name. With no FILE, or when FILE is -, read standard input.\n\n" | 33 | "file name. With no FILE, or when FILE is -, read standard input.\n\n" |
33 | "Options:\n" | ||
34 | "\t-n NUM\t\tPrint first NUM lines instead of first 10\n"; | ||
35 | 34 | ||
36 | int | 35 | "Options:\n" "\t-n NUM\t\tPrint first NUM lines instead of first 10\n"; |
37 | head(int len, FILE *src) | 36 | |
37 | int head(int len, FILE * src) | ||
38 | { | 38 | { |
39 | int i; | 39 | int i; |
40 | char buffer[1024]; | 40 | char buffer[1024]; |
41 | 41 | ||
42 | for (i = 0; i < len; i++) { | 42 | for (i = 0; i < len; i++) { |
43 | fgets(buffer, 1024, src); | 43 | fgets(buffer, 1024, src); |
44 | if (feof(src)) { break; } | 44 | if (feof(src)) { |
45 | fputs(buffer, stdout); | 45 | break; |
46 | } | 46 | } |
47 | return 0; | 47 | fputs(buffer, stdout); |
48 | } | ||
49 | return 0; | ||
48 | } | 50 | } |
49 | 51 | ||
50 | /* BusyBoxed head(1) */ | 52 | /* BusyBoxed head(1) */ |
51 | int | 53 | int head_main(int argc, char **argv) |
52 | head_main(int argc, char **argv) | ||
53 | { | 54 | { |
54 | char opt; | 55 | char opt; |
55 | int len = 10, tmplen, i; | 56 | int len = 10, tmplen, i; |
56 | 57 | ||
57 | /* parse argv[] */ | 58 | /* parse argv[] */ |
58 | for (i = 1; i < argc; i++) { | 59 | for (i = 1; i < argc; i++) { |
59 | if (argv[i][0] == '-') { | 60 | if (argv[i][0] == '-') { |
60 | opt = argv[i][1]; | 61 | opt = argv[i][1]; |
61 | switch (opt) { | 62 | switch (opt) { |
62 | case 'n': | 63 | case 'n': |
63 | tmplen = 0; | 64 | tmplen = 0; |
64 | if (++i < argc) | 65 | if (++i < argc) |
65 | tmplen = atoi(argv[i]); | 66 | tmplen = atoi(argv[i]); |
66 | if (tmplen < 1) | 67 | if (tmplen < 1) |
67 | usage(head_usage); | 68 | usage(head_usage); |
68 | len = tmplen; | 69 | len = tmplen; |
69 | break; | 70 | break; |
70 | case '-': | 71 | case '-': |
71 | case 'h': | 72 | case 'h': |
72 | usage(head_usage); | 73 | usage(head_usage); |
73 | default: | 74 | default: |
74 | fprintf(stderr, "head: invalid option -- %c\n", opt); | 75 | fprintf(stderr, "head: invalid option -- %c\n", opt); |
75 | usage(head_usage); | 76 | usage(head_usage); |
76 | } | 77 | } |
77 | } else { | 78 | } else { |
78 | break; | 79 | break; |
80 | } | ||
79 | } | 81 | } |
80 | } | ||
81 | 82 | ||
82 | /* get rest of argv[] or stdin if nothing's left */ | 83 | /* get rest of argv[] or stdin if nothing's left */ |
83 | if (i >= argc) { | 84 | if (i >= argc) { |
84 | head(len, stdin); | 85 | head(len, stdin); |
85 | 86 | ||
86 | } else { | 87 | } else { |
87 | int need_headers = ((argc - i) > 1); | 88 | int need_headers = ((argc - i) > 1); |
88 | for ( ; i < argc; i++) { | 89 | |
89 | FILE *src; | 90 | for (; i < argc; i++) { |
90 | src = fopen(argv[i], "r"); | 91 | FILE *src; |
91 | if (!src) { | 92 | |
92 | fprintf(stderr,"head: %s: %s\n", argv[i], strerror(errno)); | 93 | src = fopen(argv[i], "r"); |
93 | } else { | 94 | if (!src) { |
94 | /* emulating GNU behaviour */ | 95 | fprintf(stderr, "head: %s: %s\n", argv[i], |
95 | if (need_headers) { | 96 | strerror(errno)); |
96 | fprintf(stdout, "==> %s <==\n", argv[i]); | 97 | } else { |
97 | } | 98 | /* emulating GNU behaviour */ |
98 | head(len, src); | 99 | if (need_headers) { |
99 | if (i < argc - 1) { | 100 | fprintf(stdout, "==> %s <==\n", argv[i]); |
100 | fprintf(stdout, "\n"); | 101 | } |
102 | head(len, src); | ||
103 | if (i < argc - 1) { | ||
104 | fprintf(stdout, "\n"); | ||
105 | } | ||
106 | } | ||
101 | } | 107 | } |
102 | } | ||
103 | } | 108 | } |
104 | } | 109 | exit(0); |
105 | exit(0); | ||
106 | } | 110 | } |
107 | 111 | ||
108 | /* $Id: head.c,v 1.7 2000/02/07 05:29:42 erik Exp $ */ | 112 | /* $Id: head.c,v 1.8 2000/02/08 19:58:47 erik Exp $ */ |
diff --git a/coreutils/hostid.c b/coreutils/hostid.c index f8d5862ae..9e503e598 100644 --- a/coreutils/hostid.c +++ b/coreutils/hostid.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini hostid implementation for busybox | 3 | * Mini hostid implementation for busybox |
3 | * | 4 | * |
@@ -22,7 +23,8 @@ | |||
22 | #include "internal.h" | 23 | #include "internal.h" |
23 | #include <stdio.h> | 24 | #include <stdio.h> |
24 | 25 | ||
25 | extern int hostid_main(int argc, char **argv) { | 26 | extern int hostid_main(int argc, char **argv) |
26 | printf ("%lx\n", gethostid()); | 27 | { |
27 | exit( TRUE); | 28 | printf("%lx\n", gethostid()); |
29 | exit(TRUE); | ||
28 | } | 30 | } |
diff --git a/coreutils/length.c b/coreutils/length.c index 2c83cdfd2..00e5a171b 100644 --- a/coreutils/length.c +++ b/coreutils/length.c | |||
@@ -1,14 +1,14 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | #include "internal.h" | 2 | #include "internal.h" |
2 | #include <stdlib.h> | 3 | #include <stdlib.h> |
3 | #include <string.h> | 4 | #include <string.h> |
4 | #include <stdio.h> | 5 | #include <stdio.h> |
5 | 6 | ||
6 | extern int | 7 | extern int length_main(int argc, char **argv) |
7 | length_main(int argc, char * * argv) | ||
8 | { | 8 | { |
9 | if ( argc != 2 || **(argv+1) == '-' ) { | 9 | if (argc != 2 || **(argv + 1) == '-') { |
10 | usage("length string\n"); | 10 | usage("length string\n"); |
11 | } | 11 | } |
12 | printf("%d\n", strlen(argv[1])); | 12 | printf("%d\n", strlen(argv[1])); |
13 | return( TRUE); | 13 | return (TRUE); |
14 | } | 14 | } |
diff --git a/coreutils/ln.c b/coreutils/ln.c index f20b340ea..bc51cb0d5 100644 --- a/coreutils/ln.c +++ b/coreutils/ln.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini ln implementation for busybox | 3 | * Mini ln implementation for busybox |
3 | * | 4 | * |
@@ -30,15 +31,16 @@ | |||
30 | #include <stdio.h> | 31 | #include <stdio.h> |
31 | #include <dirent.h> | 32 | #include <dirent.h> |
32 | #include <errno.h> | 33 | #include <errno.h> |
33 | #include <sys/param.h> /* for PATH_MAX */ | 34 | #include <sys/param.h> /* for PATH_MAX */ |
34 | 35 | ||
35 | static const char ln_usage[] = | 36 | static const char ln_usage[] = |
36 | "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n" | 37 | "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n" |
37 | "Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n" | 38 | "Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n" |
38 | "Options:\n" | 39 | "Options:\n" |
39 | "\t-s\tmake symbolic links instead of hard links\n" | 40 | "\t-s\tmake symbolic links instead of hard links\n" |
40 | "\t-f\tremove existing destination files\n" | 41 | |
41 | "\t-n\tno dereference symlinks - treat like normal file\n"; | 42 | "\t-f\tremove existing destination files\n" |
43 | "\t-n\tno dereference symlinks - treat like normal file\n"; | ||
42 | 44 | ||
43 | static int symlinkFlag = FALSE; | 45 | static int symlinkFlag = FALSE; |
44 | static int removeoldFlag = FALSE; | 46 | static int removeoldFlag = FALSE; |
@@ -46,83 +48,83 @@ static int followLinks = TRUE; | |||
46 | 48 | ||
47 | extern int ln_main(int argc, char **argv) | 49 | extern int ln_main(int argc, char **argv) |
48 | { | 50 | { |
49 | char *linkName; | 51 | char *linkName; |
50 | int linkIntoDirFlag; | 52 | int linkIntoDirFlag; |
51 | 53 | ||
52 | if (argc < 3) { | 54 | if (argc < 3) { |
53 | usage (ln_usage); | 55 | usage(ln_usage); |
54 | } | 56 | } |
55 | argc--; | ||
56 | argv++; | ||
57 | |||
58 | /* Parse any options */ | ||
59 | while (**argv == '-') { | ||
60 | while (*++(*argv)) | ||
61 | switch (**argv) { | ||
62 | case 's': | ||
63 | symlinkFlag = TRUE; | ||
64 | break; | ||
65 | case 'f': | ||
66 | removeoldFlag = TRUE; | ||
67 | break; | ||
68 | case 'n': | ||
69 | followLinks = FALSE; | ||
70 | break; | ||
71 | default: | ||
72 | usage (ln_usage); | ||
73 | } | ||
74 | argc--; | 57 | argc--; |
75 | argv++; | 58 | argv++; |
76 | } | ||
77 | |||
78 | linkName = argv[argc - 1]; | ||
79 | |||
80 | if (strlen(linkName) > PATH_MAX) { | ||
81 | fprintf(stderr, name_too_long, "ln"); | ||
82 | exit FALSE; | ||
83 | } | ||
84 | 59 | ||
85 | linkIntoDirFlag = isDirectory(linkName, TRUE); | 60 | /* Parse any options */ |
86 | 61 | while (**argv == '-') { | |
87 | if ((argc > 3) && !linkIntoDirFlag) { | 62 | while (*++(*argv)) |
88 | fprintf(stderr, not_a_directory, "ln", linkName); | 63 | switch (**argv) { |
89 | exit FALSE; | 64 | case 's': |
90 | } | 65 | symlinkFlag = TRUE; |
66 | break; | ||
67 | case 'f': | ||
68 | removeoldFlag = TRUE; | ||
69 | break; | ||
70 | case 'n': | ||
71 | followLinks = FALSE; | ||
72 | break; | ||
73 | default: | ||
74 | usage(ln_usage); | ||
75 | } | ||
76 | argc--; | ||
77 | argv++; | ||
78 | } | ||
91 | 79 | ||
92 | while (argc-- >= 2) { | 80 | linkName = argv[argc - 1]; |
93 | char srcName[PATH_MAX + 1]; | ||
94 | int nChars, status; | ||
95 | 81 | ||
96 | if (strlen(*argv) > PATH_MAX) { | 82 | if (strlen(linkName) > PATH_MAX) { |
97 | fprintf(stderr, name_too_long, "ln"); | 83 | fprintf(stderr, name_too_long, "ln"); |
98 | exit FALSE; | 84 | exit FALSE; |
99 | } | 85 | } |
100 | 86 | ||
101 | if (followLinks == FALSE) { | 87 | linkIntoDirFlag = isDirectory(linkName, TRUE); |
102 | strcpy(srcName, *argv); | ||
103 | } else { | ||
104 | /* Warning! This can silently truncate if > PATH_MAX, but | ||
105 | I don't think that there can be one > PATH_MAX anyway. */ | ||
106 | nChars = readlink(*argv, srcName, PATH_MAX); | ||
107 | srcName[nChars] = '\0'; | ||
108 | } | ||
109 | 88 | ||
110 | if (removeoldFlag == TRUE) { | 89 | if ((argc > 3) && !linkIntoDirFlag) { |
111 | status = ( unlink(linkName) && errno != ENOENT ); | 90 | fprintf(stderr, not_a_directory, "ln", linkName); |
112 | if (status != 0) { | ||
113 | perror(linkName); | ||
114 | exit FALSE; | 91 | exit FALSE; |
115 | } | ||
116 | } | 92 | } |
117 | 93 | ||
118 | if (symlinkFlag == TRUE) | 94 | while (argc-- >= 2) { |
119 | status = symlink(*argv, linkName); | 95 | char srcName[PATH_MAX + 1]; |
120 | else | 96 | int nChars, status; |
121 | status = link(*argv, linkName); | 97 | |
122 | if (status != 0) { | 98 | if (strlen(*argv) > PATH_MAX) { |
123 | perror(linkName); | 99 | fprintf(stderr, name_too_long, "ln"); |
124 | exit FALSE; | 100 | exit FALSE; |
101 | } | ||
102 | |||
103 | if (followLinks == FALSE) { | ||
104 | strcpy(srcName, *argv); | ||
105 | } else { | ||
106 | /* Warning! This can silently truncate if > PATH_MAX, but | ||
107 | I don't think that there can be one > PATH_MAX anyway. */ | ||
108 | nChars = readlink(*argv, srcName, PATH_MAX); | ||
109 | srcName[nChars] = '\0'; | ||
110 | } | ||
111 | |||
112 | if (removeoldFlag == TRUE) { | ||
113 | status = (unlink(linkName) && errno != ENOENT); | ||
114 | if (status != 0) { | ||
115 | perror(linkName); | ||
116 | exit FALSE; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | if (symlinkFlag == TRUE) | ||
121 | status = symlink(*argv, linkName); | ||
122 | else | ||
123 | status = link(*argv, linkName); | ||
124 | if (status != 0) { | ||
125 | perror(linkName); | ||
126 | exit FALSE; | ||
127 | } | ||
125 | } | 128 | } |
126 | } | 129 | exit TRUE; |
127 | exit TRUE; | ||
128 | } | 130 | } |
diff --git a/coreutils/logname.c b/coreutils/logname.c index 5c8275ab4..182f40ed2 100644 --- a/coreutils/logname.c +++ b/coreutils/logname.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini logname implementation for busybox | 3 | * Mini logname implementation for busybox |
3 | * | 4 | * |
@@ -23,18 +24,21 @@ | |||
23 | #include <stdio.h> | 24 | #include <stdio.h> |
24 | 25 | ||
25 | static const char logname_usage[] = "logname\n\n" | 26 | static const char logname_usage[] = "logname\n\n" |
26 | "Print the name of the current user.\n"; | ||
27 | 27 | ||
28 | extern int logname_main(int argc, char **argv) { | 28 | "Print the name of the current user.\n"; |
29 | |||
30 | extern int logname_main(int argc, char **argv) | ||
31 | { | ||
29 | char *cp; | 32 | char *cp; |
30 | 33 | ||
31 | if (argc > 1) usage (logname_usage); | 34 | if (argc > 1) |
35 | usage(logname_usage); | ||
32 | 36 | ||
33 | cp = getlogin (); | 37 | cp = getlogin(); |
34 | if (cp) { | 38 | if (cp) { |
35 | puts (cp); | 39 | puts(cp); |
36 | exit (TRUE); | 40 | exit(TRUE); |
37 | } | 41 | } |
38 | fprintf (stderr, "%s: no login name\n", argv[0]); | 42 | fprintf(stderr, "%s: no login name\n", argv[0]); |
39 | exit (FALSE); | 43 | exit(FALSE); |
40 | } | 44 | } |
diff --git a/coreutils/ls.c b/coreutils/ls.c index 450ea1814..f23c1e086 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * tiny-ls.c version 0.1.0: A minimalist 'ls' | 3 | * tiny-ls.c version 0.1.0: A minimalist 'ls' |
3 | * Copyright (C) 1996 Brian Candler <B.Candler@pobox.com> | 4 | * Copyright (C) 1996 Brian Candler <B.Candler@pobox.com> |
@@ -40,18 +41,18 @@ | |||
40 | * 1. requires lstat (BSD) - how do you do it without? | 41 | * 1. requires lstat (BSD) - how do you do it without? |
41 | */ | 42 | */ |
42 | 43 | ||
43 | #define TERMINAL_WIDTH 80 /* use 79 if your terminal has linefold bug */ | 44 | #define TERMINAL_WIDTH 80 /* use 79 if your terminal has linefold bug */ |
44 | #define COLUMN_WIDTH 14 /* default if AUTOWIDTH not defined */ | 45 | #define COLUMN_WIDTH 14 /* default if AUTOWIDTH not defined */ |
45 | #define COLUMN_GAP 2 /* includes the file type char, if present */ | 46 | #define COLUMN_GAP 2 /* includes the file type char, if present */ |
46 | #define HAS_REWINDDIR | 47 | #define HAS_REWINDDIR |
47 | 48 | ||
48 | /************************************************************************/ | 49 | /************************************************************************/ |
49 | 50 | ||
50 | #include "internal.h" | 51 | #include "internal.h" |
51 | #if !defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) | 52 | #if !defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) |
52 | # include <linux/types.h> | 53 | # include <linux/types.h> |
53 | #else | 54 | #else |
54 | # include <sys/types.h> | 55 | # include <sys/types.h> |
55 | #endif | 56 | #endif |
56 | #include <sys/stat.h> | 57 | #include <sys/stat.h> |
57 | #include <stdio.h> | 58 | #include <stdio.h> |
@@ -75,28 +76,28 @@ | |||
75 | #endif | 76 | #endif |
76 | 77 | ||
77 | #define FMT_AUTO 0 | 78 | #define FMT_AUTO 0 |
78 | #define FMT_LONG 1 /* one record per line, extended info */ | 79 | #define FMT_LONG 1 /* one record per line, extended info */ |
79 | #define FMT_SINGLE 2 /* one record per line */ | 80 | #define FMT_SINGLE 2 /* one record per line */ |
80 | #define FMT_ROWS 3 /* print across rows */ | 81 | #define FMT_ROWS 3 /* print across rows */ |
81 | #define FMT_COLUMNS 3 /* fill columns (same, since we don't sort) */ | 82 | #define FMT_COLUMNS 3 /* fill columns (same, since we don't sort) */ |
82 | 83 | ||
83 | #define TIME_MOD 0 | 84 | #define TIME_MOD 0 |
84 | #define TIME_CHANGE 1 | 85 | #define TIME_CHANGE 1 |
85 | #define TIME_ACCESS 2 | 86 | #define TIME_ACCESS 2 |
86 | 87 | ||
87 | #define DISP_FTYPE 1 /* show character for file type */ | 88 | #define DISP_FTYPE 1 /* show character for file type */ |
88 | #define DISP_EXEC 2 /* show '*' if regular executable file */ | 89 | #define DISP_EXEC 2 /* show '*' if regular executable file */ |
89 | #define DISP_HIDDEN 4 /* show files starting . (except . and ..) */ | 90 | #define DISP_HIDDEN 4 /* show files starting . (except . and ..) */ |
90 | #define DISP_DOT 8 /* show . and .. */ | 91 | #define DISP_DOT 8 /* show . and .. */ |
91 | #define DISP_NUMERIC 16 /* numeric uid and gid */ | 92 | #define DISP_NUMERIC 16 /* numeric uid and gid */ |
92 | #define DISP_FULLTIME 32 /* show extended time display */ | 93 | #define DISP_FULLTIME 32 /* show extended time display */ |
93 | #define DIR_NOLIST 64 /* show directory as itself, not contents */ | 94 | #define DIR_NOLIST 64 /* show directory as itself, not contents */ |
94 | #define DISP_DIRNAME 128 /* show directory name (for internal use) */ | 95 | #define DISP_DIRNAME 128 /* show directory name (for internal use) */ |
95 | #define DIR_RECURSE 256 /* -R (not yet implemented) */ | 96 | #define DIR_RECURSE 256 /* -R (not yet implemented) */ |
96 | 97 | ||
97 | static unsigned char display_fmt = FMT_AUTO; | 98 | static unsigned char display_fmt = FMT_AUTO; |
98 | static unsigned short opts = 0; | 99 | static unsigned short opts = 0; |
99 | static unsigned short column = 0; | 100 | static unsigned short column = 0; |
100 | 101 | ||
101 | #ifdef BB_FEATURE_AUTOWIDTH | 102 | #ifdef BB_FEATURE_AUTOWIDTH |
102 | static unsigned short terminal_width = 0, column_width = 0; | 103 | static unsigned short terminal_width = 0, column_width = 0; |
@@ -113,13 +114,14 @@ static unsigned char time_fmt = TIME_MOD; | |||
113 | 114 | ||
114 | static void writenum(long val, short minwidth) | 115 | static void writenum(long val, short minwidth) |
115 | { | 116 | { |
116 | char scratch[128]; | 117 | char scratch[128]; |
117 | 118 | ||
118 | char *p = scratch + sizeof(scratch); | 119 | char *p = scratch + sizeof(scratch); |
119 | short len = 0; | 120 | short len = 0; |
120 | short neg = (val < 0); | 121 | short neg = (val < 0); |
121 | 122 | ||
122 | if (neg) val = -val; | 123 | if (neg) |
124 | val = -val; | ||
123 | do | 125 | do |
124 | *--p = (val % 10) + '0', len++, val /= 10; | 126 | *--p = (val % 10) + '0', len++, val /= 10; |
125 | while (val); | 127 | while (val); |
@@ -142,8 +144,9 @@ static void newline(void) | |||
142 | static void tab(short col) | 144 | static void tab(short col) |
143 | { | 145 | { |
144 | static const char spaces[] = " "; | 146 | static const char spaces[] = " "; |
145 | #define nspaces ((sizeof spaces)-1) /* null terminator! */ | 147 | |
146 | 148 | #define nspaces ((sizeof spaces)-1) /* null terminator! */ | |
149 | |||
147 | short n = col - column; | 150 | short n = col - column; |
148 | 151 | ||
149 | if (n > 0) { | 152 | if (n > 0) { |
@@ -155,7 +158,7 @@ static void tab(short col) | |||
155 | /* must be 1...(sizeof spaces) left */ | 158 | /* must be 1...(sizeof spaces) left */ |
156 | wr(spaces, n); | 159 | wr(spaces, n); |
157 | } | 160 | } |
158 | #undef nspaces | 161 | #undef nspaces |
159 | } | 162 | } |
160 | 163 | ||
161 | #ifdef BB_FEATURE_LS_FILETYPES | 164 | #ifdef BB_FEATURE_LS_FILETYPES |
@@ -163,8 +166,8 @@ static char append_char(mode_t mode) | |||
163 | { | 166 | { |
164 | if (!(opts & DISP_FTYPE)) | 167 | if (!(opts & DISP_FTYPE)) |
165 | return '\0'; | 168 | return '\0'; |
166 | if ((opts & DISP_EXEC) && S_ISREG(mode) && (mode & (S_IXUSR|S_IXGRP|S_IXOTH))) | 169 | if ((opts & DISP_EXEC) && S_ISREG(mode) |
167 | return '*'; | 170 | && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return '*'; |
168 | return APPCHAR(mode); | 171 | return APPCHAR(mode); |
169 | } | 172 | } |
170 | #endif | 173 | #endif |
@@ -176,89 +179,93 @@ static char append_char(mode_t mode) | |||
176 | ** | 179 | ** |
177 | **/ | 180 | **/ |
178 | 181 | ||
179 | static void list_single(const char *name, struct stat *info, const char *fullname) | 182 | static void list_single(const char *name, struct stat *info, |
183 | const char *fullname) | ||
180 | { | 184 | { |
181 | char scratch[PATH_MAX + 1]; | 185 | char scratch[PATH_MAX + 1]; |
182 | short len = strlen(name); | 186 | short len = strlen(name); |
187 | |||
183 | #ifdef BB_FEATURE_LS_FILETYPES | 188 | #ifdef BB_FEATURE_LS_FILETYPES |
184 | char append = append_char(info->st_mode); | 189 | char append = append_char(info->st_mode); |
185 | #endif | 190 | #endif |
186 | 191 | ||
187 | if (display_fmt == FMT_LONG) { | 192 | if (display_fmt == FMT_LONG) { |
188 | mode_t mode = info->st_mode; | 193 | mode_t mode = info->st_mode; |
194 | |||
189 | newline(); | 195 | newline(); |
190 | wr(modeString(mode), 10); | 196 | wr(modeString(mode), 10); |
191 | column=10; | 197 | column = 10; |
192 | writenum((long)info->st_nlink,(short)5); | 198 | writenum((long) info->st_nlink, (short) 5); |
193 | fputs(" ", stdout); | 199 | fputs(" ", stdout); |
194 | #ifdef BB_FEATURE_LS_USERNAME | 200 | #ifdef BB_FEATURE_LS_USERNAME |
195 | if (!(opts & DISP_NUMERIC)) { | 201 | if (!(opts & DISP_NUMERIC)) { |
196 | memset ( scratch, 0, sizeof (scratch)); | 202 | memset(scratch, 0, sizeof(scratch)); |
197 | my_getpwuid( scratch, info->st_uid); | 203 | my_getpwuid(scratch, info->st_uid); |
198 | if (*scratch) { | 204 | if (*scratch) { |
199 | fputs(scratch, stdout); | 205 | fputs(scratch, stdout); |
200 | if ( strlen( scratch) <= 8 ) | 206 | if (strlen(scratch) <= 8) |
201 | wr(" ", 9-strlen( scratch)); | 207 | wr(" ", 9 - strlen(scratch)); |
202 | } | 208 | } else { |
203 | else { | 209 | writenum((long) info->st_uid, (short) 8); |
204 | writenum((long) info->st_uid,(short)8); | ||
205 | fputs(" ", stdout); | 210 | fputs(" ", stdout); |
206 | } | 211 | } |
207 | } else | 212 | } else |
208 | #endif | 213 | #endif |
209 | { | 214 | { |
210 | writenum((long) info->st_uid,(short)8); | 215 | writenum((long) info->st_uid, (short) 8); |
211 | fputs(" ", stdout); | 216 | fputs(" ", stdout); |
212 | } | 217 | } |
213 | #ifdef BB_FEATURE_LS_USERNAME | 218 | #ifdef BB_FEATURE_LS_USERNAME |
214 | if (!(opts & DISP_NUMERIC)) { | 219 | if (!(opts & DISP_NUMERIC)) { |
215 | memset ( scratch, 0, sizeof (scratch)); | 220 | memset(scratch, 0, sizeof(scratch)); |
216 | my_getgrgid( scratch, info->st_gid); | 221 | my_getgrgid(scratch, info->st_gid); |
217 | if (*scratch) { | 222 | if (*scratch) { |
218 | fputs(scratch, stdout); | 223 | fputs(scratch, stdout); |
219 | if ( strlen( scratch) <= 8 ) | 224 | if (strlen(scratch) <= 8) |
220 | wr(" ", 8-strlen( scratch)); | 225 | wr(" ", 8 - strlen(scratch)); |
221 | } | 226 | } else |
222 | else | 227 | writenum((long) info->st_gid, (short) 8); |
223 | writenum((long) info->st_gid,(short)8); | ||
224 | } else | 228 | } else |
225 | #endif | 229 | #endif |
226 | writenum((long) info->st_gid,(short)8); | 230 | writenum((long) info->st_gid, (short) 8); |
227 | //tab(26); | 231 | //tab(26); |
228 | if (S_ISBLK(mode) || S_ISCHR(mode)) { | 232 | if (S_ISBLK(mode) || S_ISCHR(mode)) { |
229 | writenum((long)MAJOR(info->st_rdev),(short)3); | 233 | writenum((long) MAJOR(info->st_rdev), (short) 3); |
230 | fputs(", ", stdout); | 234 | fputs(", ", stdout); |
231 | writenum((long)MINOR(info->st_rdev),(short)3); | 235 | writenum((long) MINOR(info->st_rdev), (short) 3); |
232 | } | 236 | } else |
233 | else | 237 | writenum((long) info->st_size, (short) 8); |
234 | writenum((long)info->st_size,(short)8); | ||
235 | fputs(" ", stdout); | 238 | fputs(" ", stdout); |
236 | //tab(32); | 239 | //tab(32); |
237 | #ifdef BB_FEATURE_LS_TIMESTAMPS | 240 | #ifdef BB_FEATURE_LS_TIMESTAMPS |
238 | { | 241 | { |
239 | time_t cal; | 242 | time_t cal; |
240 | char *string; | 243 | char *string; |
241 | 244 | ||
242 | switch(time_fmt) { | 245 | switch (time_fmt) { |
243 | case TIME_CHANGE: | 246 | case TIME_CHANGE: |
244 | cal=info->st_ctime; break; | 247 | cal = info->st_ctime; |
248 | break; | ||
245 | case TIME_ACCESS: | 249 | case TIME_ACCESS: |
246 | cal=info->st_atime; break; | 250 | cal = info->st_atime; |
251 | break; | ||
247 | default: | 252 | default: |
248 | cal=info->st_mtime; break; | 253 | cal = info->st_mtime; |
254 | break; | ||
249 | } | 255 | } |
250 | string=ctime(&cal); | 256 | string = ctime(&cal); |
251 | if (opts & DISP_FULLTIME) | 257 | if (opts & DISP_FULLTIME) |
252 | wr(string,24); | 258 | wr(string, 24); |
253 | else { | 259 | else { |
254 | time_t age = time(NULL) - cal; | 260 | time_t age = time(NULL) - cal; |
255 | wr(string+4,7); /* mmm_dd_ */ | 261 | |
256 | if(age < 3600L*24*365/2 && age > -15*60) | 262 | wr(string + 4, 7); /* mmm_dd_ */ |
263 | if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) | ||
257 | /* hh:mm if less than 6 months old */ | 264 | /* hh:mm if less than 6 months old */ |
258 | wr(string+11,5); | 265 | wr(string + 11, 5); |
259 | else | 266 | else |
260 | /* _yyyy otherwise */ | 267 | /* _yyyy otherwise */ |
261 | wr(string+19,5); | 268 | wr(string + 19, 5); |
262 | } | 269 | } |
263 | wr(" ", 1); | 270 | wr(" ", 1); |
264 | } | 271 | } |
@@ -269,7 +276,8 @@ static void list_single(const char *name, struct stat *info, const char *fullnam | |||
269 | if (S_ISLNK(mode)) { | 276 | if (S_ISLNK(mode)) { |
270 | wr(" -> ", 4); | 277 | wr(" -> ", 4); |
271 | len = readlink(fullname, scratch, sizeof scratch); | 278 | len = readlink(fullname, scratch, sizeof scratch); |
272 | if (len > 0) fwrite(scratch, 1, len, stdout); | 279 | if (len > 0) |
280 | fwrite(scratch, 1, len, stdout); | ||
273 | #ifdef BB_FEATURE_LS_FILETYPES | 281 | #ifdef BB_FEATURE_LS_FILETYPES |
274 | /* show type of destination */ | 282 | /* show type of destination */ |
275 | if (opts & DISP_FTYPE) { | 283 | if (opts & DISP_FTYPE) { |
@@ -287,18 +295,17 @@ static void list_single(const char *name, struct stat *info, const char *fullnam | |||
287 | #endif | 295 | #endif |
288 | } else { | 296 | } else { |
289 | static short nexttab = 0; | 297 | static short nexttab = 0; |
290 | 298 | ||
291 | /* sort out column alignment */ | 299 | /* sort out column alignment */ |
292 | if (column == 0) | 300 | if (column == 0); /* nothing to do */ |
293 | ; /* nothing to do */ | ||
294 | else if (display_fmt == FMT_SINGLE) | 301 | else if (display_fmt == FMT_SINGLE) |
295 | newline(); | 302 | newline(); |
296 | else { | 303 | else { |
297 | if (nexttab + column_width > terminal_width | 304 | if (nexttab + column_width > terminal_width |
298 | #ifndef BB_FEATURE_AUTOWIDTH | 305 | #ifndef BB_FEATURE_AUTOWIDTH |
299 | || nexttab + len >= terminal_width | 306 | || nexttab + len >= terminal_width |
300 | #endif | 307 | #endif |
301 | ) | 308 | ) |
302 | newline(); | 309 | newline(); |
303 | else | 310 | else |
304 | tab(nexttab); | 311 | tab(nexttab); |
@@ -336,32 +343,33 @@ static int list_item(const char *name) | |||
336 | struct stat info; | 343 | struct stat info; |
337 | DIR *dir; | 344 | DIR *dir; |
338 | struct dirent *entry; | 345 | struct dirent *entry; |
339 | char fullname[MAXNAMLEN+1], *fnend; | 346 | char fullname[MAXNAMLEN + 1], *fnend; |
340 | 347 | ||
341 | if (lstat(name, &info)) | 348 | if (lstat(name, &info)) |
342 | goto listerr; | 349 | goto listerr; |
343 | 350 | ||
344 | if (!S_ISDIR(info.st_mode) || | 351 | if (!S_ISDIR(info.st_mode) || (opts & DIR_NOLIST)) { |
345 | (opts & DIR_NOLIST)) { | ||
346 | list_single(name, &info, name); | 352 | list_single(name, &info, name); |
347 | return 0; | 353 | return 0; |
348 | } | 354 | } |
349 | 355 | ||
350 | /* Otherwise, it's a directory we want to list the contents of */ | 356 | /* Otherwise, it's a directory we want to list the contents of */ |
351 | 357 | ||
352 | if (opts & DISP_DIRNAME) { /* identify the directory */ | 358 | if (opts & DISP_DIRNAME) { /* identify the directory */ |
353 | if (column) | 359 | if (column) |
354 | wr("\n\n", 2), column = 0; | 360 | wr("\n\n", 2), column = 0; |
355 | wr(name, strlen(name)); | 361 | wr(name, strlen(name)); |
356 | wr(":\n", 2); | 362 | wr(":\n", 2); |
357 | } | 363 | } |
358 | 364 | ||
359 | dir = opendir(name); | 365 | dir = opendir(name); |
360 | if (!dir) goto listerr; | 366 | if (!dir) |
367 | goto listerr; | ||
361 | #ifdef BB_FEATURE_AUTOWIDTH | 368 | #ifdef BB_FEATURE_AUTOWIDTH |
362 | column_width = 0; | 369 | column_width = 0; |
363 | while ((entry = readdir(dir)) != NULL) { | 370 | while ((entry = readdir(dir)) != NULL) { |
364 | short w = strlen(entry->d_name); | 371 | short w = strlen(entry->d_name); |
372 | |||
365 | if (column_width < w) | 373 | if (column_width < w) |
366 | column_width = w; | 374 | column_width = w; |
367 | } | 375 | } |
@@ -370,39 +378,40 @@ static int list_item(const char *name) | |||
370 | #else | 378 | #else |
371 | closedir(dir); | 379 | closedir(dir); |
372 | dir = opendir(name); | 380 | dir = opendir(name); |
373 | if (!dir) goto listerr; | 381 | if (!dir) |
382 | goto listerr; | ||
374 | #endif | 383 | #endif |
375 | #endif | 384 | #endif |
376 | 385 | ||
377 | /* List the contents */ | 386 | /* List the contents */ |
378 | 387 | ||
379 | strcpy(fullname,name); /* *** ignore '.' by itself */ | 388 | strcpy(fullname, name); /* *** ignore '.' by itself */ |
380 | fnend=fullname+strlen(fullname); | 389 | fnend = fullname + strlen(fullname); |
381 | if (fnend[-1] != '/') | 390 | if (fnend[-1] != '/') |
382 | *fnend++ = '/'; | 391 | *fnend++ = '/'; |
383 | 392 | ||
384 | while ((entry = readdir(dir)) != NULL) { | 393 | while ((entry = readdir(dir)) != NULL) { |
385 | const char *en=entry->d_name; | 394 | const char *en = entry->d_name; |
395 | |||
386 | if (en[0] == '.') { | 396 | if (en[0] == '.') { |
387 | if (!en[1] || (en[1] == '.' && !en[2])) { /* . or .. */ | 397 | if (!en[1] || (en[1] == '.' && !en[2])) { /* . or .. */ |
388 | if (!(opts & DISP_DOT)) | 398 | if (!(opts & DISP_DOT)) |
389 | continue; | 399 | continue; |
390 | } | 400 | } else if (!(opts & DISP_HIDDEN)) |
391 | else if (!(opts & DISP_HIDDEN)) | ||
392 | continue; | 401 | continue; |
393 | } | 402 | } |
394 | /* FIXME: avoid stat if not required */ | 403 | /* FIXME: avoid stat if not required */ |
395 | strcpy(fnend, entry->d_name); | 404 | strcpy(fnend, entry->d_name); |
396 | if (lstat(fullname, &info)) | 405 | if (lstat(fullname, &info)) |
397 | goto direrr; /* (shouldn't fail) */ | 406 | goto direrr; /* (shouldn't fail) */ |
398 | list_single(entry->d_name, &info, fullname); | 407 | list_single(entry->d_name, &info, fullname); |
399 | } | 408 | } |
400 | closedir(dir); | 409 | closedir(dir); |
401 | return 0; | 410 | return 0; |
402 | 411 | ||
403 | direrr: | 412 | direrr: |
404 | closedir(dir); | 413 | closedir(dir); |
405 | listerr: | 414 | listerr: |
406 | newline(); | 415 | newline(); |
407 | perror(name); | 416 | perror(name); |
408 | return 1; | 417 | return 1; |
@@ -432,50 +441,79 @@ static const char ls_usage[] = "ls [-1a" | |||
432 | #endif | 441 | #endif |
433 | "] [filenames...]\n"; | 442 | "] [filenames...]\n"; |
434 | 443 | ||
435 | extern int | 444 | extern int ls_main(int argc, char **argv) |
436 | ls_main(int argc, char * * argv) | ||
437 | { | 445 | { |
438 | int argi=1, i; | 446 | int argi = 1, i; |
439 | 447 | ||
440 | /* process options */ | 448 | /* process options */ |
441 | while (argi < argc && argv[argi][0] == '-') { | 449 | while (argi < argc && argv[argi][0] == '-') { |
442 | const char *p = &argv[argi][1]; | 450 | const char *p = &argv[argi][1]; |
443 | 451 | ||
444 | if (!*p) goto print_usage_message; /* "-" by itself not allowed */ | 452 | if (!*p) |
453 | goto print_usage_message; /* "-" by itself not allowed */ | ||
445 | if (*p == '-') { | 454 | if (*p == '-') { |
446 | if (!p[1]) { /* "--" forces end of options */ | 455 | if (!p[1]) { /* "--" forces end of options */ |
447 | argi++; | 456 | argi++; |
448 | break; | 457 | break; |
449 | } | 458 | } |
450 | /* it's a long option name - we don't support them */ | 459 | /* it's a long option name - we don't support them */ |
451 | goto print_usage_message; | 460 | goto print_usage_message; |
452 | } | 461 | } |
453 | 462 | ||
454 | while (*p) | 463 | while (*p) |
455 | switch (*p++) { | 464 | switch (*p++) { |
456 | case 'l': display_fmt = FMT_LONG; break; | 465 | case 'l': |
457 | case '1': display_fmt = FMT_SINGLE; break; | 466 | display_fmt = FMT_LONG; |
458 | case 'x': display_fmt = FMT_ROWS; break; | 467 | break; |
459 | case 'C': display_fmt = FMT_COLUMNS; break; | 468 | case '1': |
469 | display_fmt = FMT_SINGLE; | ||
470 | break; | ||
471 | case 'x': | ||
472 | display_fmt = FMT_ROWS; | ||
473 | break; | ||
474 | case 'C': | ||
475 | display_fmt = FMT_COLUMNS; | ||
476 | break; | ||
460 | #ifdef BB_FEATURE_LS_FILETYPES | 477 | #ifdef BB_FEATURE_LS_FILETYPES |
461 | case 'p': opts |= DISP_FTYPE; break; | 478 | case 'p': |
462 | case 'F': opts |= DISP_FTYPE|DISP_EXEC; break; | 479 | opts |= DISP_FTYPE; |
480 | break; | ||
481 | case 'F': | ||
482 | opts |= DISP_FTYPE | DISP_EXEC; | ||
483 | break; | ||
463 | #endif | 484 | #endif |
464 | case 'A': opts |= DISP_HIDDEN; break; | 485 | case 'A': |
465 | case 'a': opts |= DISP_HIDDEN|DISP_DOT; break; | 486 | opts |= DISP_HIDDEN; |
466 | case 'n': opts |= DISP_NUMERIC; break; | 487 | break; |
467 | case 'd': opts |= DIR_NOLIST; break; | 488 | case 'a': |
489 | opts |= DISP_HIDDEN | DISP_DOT; | ||
490 | break; | ||
491 | case 'n': | ||
492 | opts |= DISP_NUMERIC; | ||
493 | break; | ||
494 | case 'd': | ||
495 | opts |= DIR_NOLIST; | ||
496 | break; | ||
468 | #ifdef FEATURE_RECURSIVE | 497 | #ifdef FEATURE_RECURSIVE |
469 | case 'R': opts |= DIR_RECURSE; break; | 498 | case 'R': |
499 | opts |= DIR_RECURSE; | ||
500 | break; | ||
470 | #endif | 501 | #endif |
471 | #ifdef BB_FEATURE_LS_TIMESTAMPS | 502 | #ifdef BB_FEATURE_LS_TIMESTAMPS |
472 | case 'u': time_fmt = TIME_ACCESS; break; | 503 | case 'u': |
473 | case 'c': time_fmt = TIME_CHANGE; break; | 504 | time_fmt = TIME_ACCESS; |
474 | case 'e': opts |= DISP_FULLTIME; break; | 505 | break; |
506 | case 'c': | ||
507 | time_fmt = TIME_CHANGE; | ||
508 | break; | ||
509 | case 'e': | ||
510 | opts |= DISP_FULLTIME; | ||
511 | break; | ||
475 | #endif | 512 | #endif |
476 | default: goto print_usage_message; | 513 | default: |
514 | goto print_usage_message; | ||
477 | } | 515 | } |
478 | 516 | ||
479 | argi++; | 517 | argi++; |
480 | } | 518 | } |
481 | 519 | ||
@@ -483,29 +521,30 @@ ls_main(int argc, char * * argv) | |||
483 | if (display_fmt == FMT_AUTO) | 521 | if (display_fmt == FMT_AUTO) |
484 | display_fmt = isatty(fileno(stdout)) ? FMT_COLUMNS : FMT_SINGLE; | 522 | display_fmt = isatty(fileno(stdout)) ? FMT_COLUMNS : FMT_SINGLE; |
485 | if (argi < argc - 1) | 523 | if (argi < argc - 1) |
486 | opts |= DISP_DIRNAME; /* 2 or more items? label directories */ | 524 | opts |= DISP_DIRNAME; /* 2 or more items? label directories */ |
487 | #ifdef BB_FEATURE_AUTOWIDTH | 525 | #ifdef BB_FEATURE_AUTOWIDTH |
488 | /* could add a -w option and/or TIOCGWINSZ call */ | 526 | /* could add a -w option and/or TIOCGWINSZ call */ |
489 | if (terminal_width < 1) terminal_width = TERMINAL_WIDTH; | 527 | if (terminal_width < 1) |
490 | 528 | terminal_width = TERMINAL_WIDTH; | |
529 | |||
491 | for (i = argi; i < argc; i++) { | 530 | for (i = argi; i < argc; i++) { |
492 | int len = strlen(argv[i]); | 531 | int len = strlen(argv[i]); |
532 | |||
493 | if (column_width < len) | 533 | if (column_width < len) |
494 | column_width = len; | 534 | column_width = len; |
495 | } | 535 | } |
496 | #endif | 536 | #endif |
497 | 537 | ||
498 | /* process files specified, or current directory if none */ | 538 | /* process files specified, or current directory if none */ |
499 | i=0; | 539 | i = 0; |
500 | if (argi == argc) | 540 | if (argi == argc) |
501 | i = list_item("."); | 541 | i = list_item("."); |
502 | while (argi < argc) | 542 | while (argi < argc) |
503 | i |= list_item(argv[argi++]); | 543 | i |= list_item(argv[argi++]); |
504 | newline(); | 544 | newline(); |
505 | exit( i); | 545 | exit(i); |
506 | 546 | ||
507 | print_usage_message: | 547 | print_usage_message: |
508 | usage (ls_usage); | 548 | usage(ls_usage); |
509 | exit( FALSE); | 549 | exit(FALSE); |
510 | } | 550 | } |
511 | |||
diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c index 8e3f51bfb..70fdbdfb5 100644 --- a/coreutils/mkdir.c +++ b/coreutils/mkdir.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini mkdir implementation for busybox | 3 | * Mini mkdir implementation for busybox |
3 | * | 4 | * |
@@ -28,14 +29,15 @@ | |||
28 | 29 | ||
29 | #include <stdio.h> | 30 | #include <stdio.h> |
30 | #include <errno.h> | 31 | #include <errno.h> |
31 | #include <sys/param.h> /* for PATH_MAX */ | 32 | #include <sys/param.h> /* for PATH_MAX */ |
32 | 33 | ||
33 | static const char mkdir_usage[] = | 34 | static const char mkdir_usage[] = |
34 | "mkdir [OPTION] DIRECTORY...\n\n" | 35 | "mkdir [OPTION] DIRECTORY...\n\n" |
35 | "Create the DIRECTORY(ies), if they do not already exist\n\n" | 36 | "Create the DIRECTORY(ies), if they do not already exist\n\n" |
36 | "Options:\n" | 37 | "Options:\n" |
37 | "\t-m\tset permission mode (as in chmod), not rwxrwxrwx - umask\n" | 38 | |
38 | "\t-p\tno error if existing, make parent directories as needed\n"; | 39 | "\t-m\tset permission mode (as in chmod), not rwxrwxrwx - umask\n" |
40 | "\t-p\tno error if existing, make parent directories as needed\n"; | ||
39 | 41 | ||
40 | 42 | ||
41 | static int parentFlag = FALSE; | 43 | static int parentFlag = FALSE; |
@@ -44,71 +46,70 @@ static mode_t mode = 0777; | |||
44 | 46 | ||
45 | extern int mkdir_main(int argc, char **argv) | 47 | extern int mkdir_main(int argc, char **argv) |
46 | { | 48 | { |
47 | int i = FALSE; | 49 | int i = FALSE; |
48 | argc--; | ||
49 | argv++; | ||
50 | 50 | ||
51 | /* Parse any options */ | ||
52 | while (argc > 0 && **argv == '-') { | ||
53 | while (i == FALSE && *++(*argv)) { | ||
54 | switch (**argv) { | ||
55 | case 'm': | ||
56 | if (--argc == 0) | ||
57 | usage( mkdir_usage); | ||
58 | /* Find the specified modes */ | ||
59 | mode = 0; | ||
60 | if (parse_mode(*(++argv), &mode) == FALSE ) { | ||
61 | fprintf(stderr, "Unknown mode: %s\n", *argv); | ||
62 | exit FALSE; | ||
63 | } | ||
64 | /* Set the umask for this process so it doesn't | ||
65 | * screw up whatever the user just entered. */ | ||
66 | umask(0); | ||
67 | i = TRUE; | ||
68 | break; | ||
69 | case 'p': | ||
70 | parentFlag = TRUE; | ||
71 | break; | ||
72 | default: | ||
73 | usage( mkdir_usage); | ||
74 | } | ||
75 | } | ||
76 | argc--; | 51 | argc--; |
77 | argv++; | 52 | argv++; |
78 | } | ||
79 | |||
80 | if (argc < 1) { | ||
81 | usage( mkdir_usage); | ||
82 | } | ||
83 | 53 | ||
84 | while (argc > 0) { | 54 | /* Parse any options */ |
85 | int status; | 55 | while (argc > 0 && **argv == '-') { |
86 | struct stat statBuf; | 56 | while (i == FALSE && *++(*argv)) { |
87 | char buf[PATH_MAX + 1]; | 57 | switch (**argv) { |
88 | if (strlen(*argv) > PATH_MAX - 1) { | 58 | case 'm': |
89 | fprintf(stderr, name_too_long, "mkdir"); | 59 | if (--argc == 0) |
90 | exit FALSE; | 60 | usage(mkdir_usage); |
91 | } | 61 | /* Find the specified modes */ |
92 | strcpy (buf, *argv); | 62 | mode = 0; |
93 | status = stat(buf, &statBuf); | 63 | if (parse_mode(*(++argv), &mode) == FALSE) { |
94 | if (parentFlag == FALSE && status != -1 && errno != ENOENT) { | 64 | fprintf(stderr, "Unknown mode: %s\n", *argv); |
95 | fprintf(stderr, "%s: File exists\n", buf); | 65 | exit FALSE; |
96 | exit FALSE; | 66 | } |
97 | } | 67 | /* Set the umask for this process so it doesn't |
98 | if (parentFlag == TRUE) { | 68 | * screw up whatever the user just entered. */ |
99 | strcat( buf, "/"); | 69 | umask(0); |
100 | createPath(buf, mode); | 70 | i = TRUE; |
71 | break; | ||
72 | case 'p': | ||
73 | parentFlag = TRUE; | ||
74 | break; | ||
75 | default: | ||
76 | usage(mkdir_usage); | ||
77 | } | ||
78 | } | ||
79 | argc--; | ||
80 | argv++; | ||
101 | } | 81 | } |
102 | else { | 82 | |
103 | if (mkdir (buf, mode) != 0 && parentFlag == FALSE) { | 83 | if (argc < 1) { |
104 | perror(buf); | 84 | usage(mkdir_usage); |
105 | exit FALSE; | ||
106 | } | ||
107 | } | 85 | } |
108 | argc--; | ||
109 | argv++; | ||
110 | } | ||
111 | exit TRUE; | ||
112 | } | ||
113 | 86 | ||
87 | while (argc > 0) { | ||
88 | int status; | ||
89 | struct stat statBuf; | ||
90 | char buf[PATH_MAX + 1]; | ||
114 | 91 | ||
92 | if (strlen(*argv) > PATH_MAX - 1) { | ||
93 | fprintf(stderr, name_too_long, "mkdir"); | ||
94 | exit FALSE; | ||
95 | } | ||
96 | strcpy(buf, *argv); | ||
97 | status = stat(buf, &statBuf); | ||
98 | if (parentFlag == FALSE && status != -1 && errno != ENOENT) { | ||
99 | fprintf(stderr, "%s: File exists\n", buf); | ||
100 | exit FALSE; | ||
101 | } | ||
102 | if (parentFlag == TRUE) { | ||
103 | strcat(buf, "/"); | ||
104 | createPath(buf, mode); | ||
105 | } else { | ||
106 | if (mkdir(buf, mode) != 0 && parentFlag == FALSE) { | ||
107 | perror(buf); | ||
108 | exit FALSE; | ||
109 | } | ||
110 | } | ||
111 | argc--; | ||
112 | argv++; | ||
113 | } | ||
114 | exit TRUE; | ||
115 | } | ||
diff --git a/coreutils/mkfifo.c b/coreutils/mkfifo.c index 676592ac7..c74402d4c 100644 --- a/coreutils/mkfifo.c +++ b/coreutils/mkfifo.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini mkfifo implementation for busybox | 3 | * Mini mkfifo implementation for busybox |
3 | * | 4 | * |
@@ -26,36 +27,43 @@ | |||
26 | #include <errno.h> | 27 | #include <errno.h> |
27 | 28 | ||
28 | static const char mkfifo_usage[] = "mkfifo [OPTIONS] name\n\n" | 29 | static const char mkfifo_usage[] = "mkfifo [OPTIONS] name\n\n" |
29 | "Create the named fifo\n\n" | 30 | "Create the named fifo\n\n" |
30 | "Options:\n" | 31 | |
31 | "\t-m\tcreate the fifo with the specified mode; default = a=rw-umask\n"; | 32 | "Options:\n" |
33 | "\t-m\tcreate the fifo with the specified mode; default = a=rw-umask\n"; | ||
32 | 34 | ||
33 | extern int mkfifo_main(int argc, char **argv) | 35 | extern int mkfifo_main(int argc, char **argv) |
34 | { | 36 | { |
35 | char *thisarg; | 37 | char *thisarg; |
36 | mode_t mode = 0666; | 38 | mode_t mode = 0666; |
37 | argc--; | 39 | |
38 | argv++; | 40 | argc--; |
41 | argv++; | ||
39 | 42 | ||
40 | /* Parse any options */ | 43 | /* Parse any options */ |
41 | while (argc > 1) { | 44 | while (argc > 1) { |
42 | if (**argv != '-') usage(mkfifo_usage); | 45 | if (**argv != '-') |
43 | thisarg = *argv; thisarg++; | 46 | usage(mkfifo_usage); |
44 | switch (*thisarg) { | 47 | thisarg = *argv; |
45 | case 'm': | 48 | thisarg++; |
46 | argc--; argv++; | 49 | switch (*thisarg) { |
47 | parse_mode(*argv, &mode); | 50 | case 'm': |
48 | break; | 51 | argc--; |
49 | default: | 52 | argv++; |
50 | usage (mkfifo_usage); | 53 | parse_mode(*argv, &mode); |
51 | } | 54 | break; |
52 | argc--; argv++; | 55 | default: |
53 | } | 56 | usage(mkfifo_usage); |
54 | if (argc < 1) usage (mkfifo_usage); | 57 | } |
55 | if (mkfifo(*argv, mode) < 0) { | 58 | argc--; |
56 | perror("mkfifo"); | 59 | argv++; |
57 | exit(255); | 60 | } |
58 | } else { | 61 | if (argc < 1) |
59 | exit(TRUE); | 62 | usage(mkfifo_usage); |
60 | } | 63 | if (mkfifo(*argv, mode) < 0) { |
64 | perror("mkfifo"); | ||
65 | exit(255); | ||
66 | } else { | ||
67 | exit(TRUE); | ||
68 | } | ||
61 | } | 69 | } |
diff --git a/coreutils/mknod.c b/coreutils/mknod.c index 5822cd3ad..b11a81f2a 100644 --- a/coreutils/mknod.c +++ b/coreutils/mknod.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini mknod implementation for busybox | 3 | * Mini mknod implementation for busybox |
3 | * | 4 | * |
@@ -28,22 +29,22 @@ | |||
28 | #include <unistd.h> | 29 | #include <unistd.h> |
29 | 30 | ||
30 | static const char mknod_usage[] = "mknod NAME TYPE MAJOR MINOR\n\n" | 31 | static const char mknod_usage[] = "mknod NAME TYPE MAJOR MINOR\n\n" |
31 | "Make block or character special files.\n\n" | 32 | "Make block or character special files.\n\n" |
32 | "TYPEs include:\n" | 33 | "TYPEs include:\n" |
33 | "\tb:\tMake a block (buffered) device.\n" | 34 | "\tb:\tMake a block (buffered) device.\n" |
34 | "\tc or u:\tMake a character (un-buffered) device.\n" | ||
35 | "\tp:\tMake a named pipe. Major and minor are ignored for named pipes.\n"; | ||
36 | 35 | ||
37 | int | 36 | "\tc or u:\tMake a character (un-buffered) device.\n" |
38 | mknod_main(int argc, char** argv) | 37 | "\tp:\tMake a named pipe. Major and minor are ignored for named pipes.\n"; |
38 | |||
39 | int mknod_main(int argc, char **argv) | ||
39 | { | 40 | { |
40 | mode_t mode = 0; | 41 | mode_t mode = 0; |
41 | dev_t dev = 0; | 42 | dev_t dev = 0; |
42 | 43 | ||
43 | if ( argc != 5 || **(argv+1) == '-' ) { | 44 | if (argc != 5 || **(argv + 1) == '-') { |
44 | usage (mknod_usage); | 45 | usage(mknod_usage); |
45 | } | 46 | } |
46 | switch(argv[2][0]) { | 47 | switch (argv[2][0]) { |
47 | case 'c': | 48 | case 'c': |
48 | case 'u': | 49 | case 'u': |
49 | mode = S_IFCHR; | 50 | mode = S_IFCHR; |
@@ -55,21 +56,21 @@ mknod_main(int argc, char** argv) | |||
55 | mode = S_IFIFO; | 56 | mode = S_IFIFO; |
56 | break; | 57 | break; |
57 | default: | 58 | default: |
58 | usage (mknod_usage); | 59 | usage(mknod_usage); |
59 | } | 60 | } |
60 | 61 | ||
61 | if ( mode == S_IFCHR || mode == S_IFBLK ) { | 62 | if (mode == S_IFCHR || mode == S_IFBLK) { |
62 | dev = (atoi(argv[3]) << 8) | atoi(argv[4]); | 63 | dev = (atoi(argv[3]) << 8) | atoi(argv[4]); |
63 | if ( argc != 5 ) { | 64 | if (argc != 5) { |
64 | usage (mknod_usage); | 65 | usage(mknod_usage); |
65 | } | 66 | } |
66 | } | 67 | } |
67 | 68 | ||
68 | mode |= 0666; | 69 | mode |= 0666; |
69 | 70 | ||
70 | if ( mknod(argv[1], mode, dev) != 0 ) { | 71 | if (mknod(argv[1], mode, dev) != 0) { |
71 | perror(argv[1]); | 72 | perror(argv[1]); |
72 | return( FALSE); | 73 | return (FALSE); |
73 | } | 74 | } |
74 | return( TRUE); | 75 | return (TRUE); |
75 | } | 76 | } |
diff --git a/coreutils/printf.c b/coreutils/printf.c index 5fd5ea303..41ab2e442 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* printf - format and print data | 2 | /* printf - format and print data |
2 | Copyright (C) 90, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. | 3 | Copyright (C) 90, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. |
3 | 4 | ||
@@ -42,7 +43,7 @@ | |||
42 | to convert all of the given arguments. | 43 | to convert all of the given arguments. |
43 | 44 | ||
44 | David MacKenzie <djm@gnu.ai.mit.edu> */ | 45 | David MacKenzie <djm@gnu.ai.mit.edu> */ |
45 | 46 | ||
46 | 47 | ||
47 | // 19990508 Busy Boxed! Dave Cinege | 48 | // 19990508 Busy Boxed! Dave Cinege |
48 | 49 | ||
@@ -84,11 +85,11 @@ | |||
84 | #if !defined(S_ISSOCK) && defined(S_IFSOCK) | 85 | #if !defined(S_ISSOCK) && defined(S_IFSOCK) |
85 | # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) | 86 | # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) |
86 | #endif | 87 | #endif |
87 | #if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */ | 88 | #if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */ |
88 | # define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) | 89 | # define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) |
89 | # define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) | 90 | # define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) |
90 | #endif | 91 | #endif |
91 | #if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */ | 92 | #if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */ |
92 | # define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) | 93 | # define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) |
93 | #endif | 94 | #endif |
94 | 95 | ||
@@ -121,407 +122,358 @@ | |||
121 | #define hextobin(c) ((c)>='a'&&(c)<='f' ? (c)-'a'+10 : (c)>='A'&&(c)<='F' ? (c)-'A'+10 : (c)-'0') | 122 | #define hextobin(c) ((c)>='a'&&(c)<='f' ? (c)-'a'+10 : (c)>='A'&&(c)<='F' ? (c)-'A'+10 : (c)-'0') |
122 | #define octtobin(c) ((c) - '0') | 123 | #define octtobin(c) ((c) - '0') |
123 | 124 | ||
124 | static double xstrtod __P ((char *s)); | 125 | static double xstrtod __P((char *s)); |
125 | static int print_esc __P ((char *escstart)); | 126 | static int print_esc __P((char *escstart)); |
126 | static int print_formatted __P ((char *format, int argc, char **argv)); | 127 | static int print_formatted __P((char *format, int argc, char **argv)); |
127 | static long xstrtol __P ((char *s)); | 128 | static long xstrtol __P((char *s)); |
128 | static unsigned long xstrtoul __P ((char *s)); | 129 | static unsigned long xstrtoul __P((char *s)); |
129 | static void print_direc __P ((char *start, size_t length, int field_width, int precision, char *argument)); | 130 | static void print_direc |
130 | static void print_esc_char __P ((int c)); | 131 | __P( |
131 | static void print_esc_string __P ((char *str)); | 132 | |
132 | static void verify __P ((char *s, char *end)); | 133 | (char *start, size_t length, int field_width, int precision, |
134 | char *argument)); | ||
135 | static void print_esc_char __P((int c)); | ||
136 | static void print_esc_string __P((char *str)); | ||
137 | static void verify __P((char *s, char *end)); | ||
133 | 138 | ||
134 | /* The value to return to the calling program. */ | 139 | /* The value to return to the calling program. */ |
135 | static int exit_status; | 140 | static int exit_status; |
136 | 141 | ||
137 | static const char printf_usage[] = "printf format [argument...]\n"; | 142 | static const char printf_usage[] = "printf format [argument...]\n"; |
138 | 143 | ||
139 | int | 144 | int printf_main(int argc, char **argv) |
140 | printf_main(int argc, char** argv) | ||
141 | { | 145 | { |
142 | char *format; | 146 | char *format; |
143 | int args_used; | 147 | int args_used; |
144 | 148 | ||
145 | exit_status = 0; | 149 | exit_status = 0; |
146 | if ( argc <= 1 || **(argv+1) == '-' ) { | 150 | if (argc <= 1 || **(argv + 1) == '-') { |
147 | usage (printf_usage); | 151 | usage(printf_usage); |
148 | } | 152 | } |
149 | 153 | ||
150 | format = argv[1]; | 154 | format = argv[1]; |
151 | argc -= 2; | 155 | argc -= 2; |
152 | argv += 2; | 156 | argv += 2; |
153 | 157 | ||
154 | do | 158 | do { |
155 | { | 159 | args_used = print_formatted(format, argc, argv); |
156 | args_used = print_formatted (format, argc, argv); | 160 | argc -= args_used; |
157 | argc -= args_used; | 161 | argv += args_used; |
158 | argv += args_used; | 162 | } |
159 | } | 163 | while (args_used > 0 && argc > 0); |
160 | while (args_used > 0 && argc > 0); | ||
161 | 164 | ||
162 | /* | 165 | /* |
163 | if (argc > 0) | 166 | if (argc > 0) |
164 | fprintf(stderr, "excess args ignored"); | 167 | fprintf(stderr, "excess args ignored"); |
165 | */ | 168 | */ |
166 | 169 | ||
167 | exit (exit_status); | 170 | exit(exit_status); |
168 | } | 171 | } |
169 | 172 | ||
170 | /* Print the text in FORMAT, using ARGV (with ARGC elements) for | 173 | /* Print the text in FORMAT, using ARGV (with ARGC elements) for |
171 | arguments to any `%' directives. | 174 | arguments to any `%' directives. |
172 | Return the number of elements of ARGV used. */ | 175 | Return the number of elements of ARGV used. */ |
173 | 176 | ||
174 | static int | 177 | static int print_formatted(char *format, int argc, char **argv) |
175 | print_formatted (char *format, int argc, char **argv) | ||
176 | { | 178 | { |
177 | int save_argc = argc; /* Preserve original value. */ | 179 | int save_argc = argc; /* Preserve original value. */ |
178 | char *f; /* Pointer into `format'. */ | 180 | char *f; /* Pointer into `format'. */ |
179 | char *direc_start; /* Start of % directive. */ | 181 | char *direc_start; /* Start of % directive. */ |
180 | size_t direc_length; /* Length of % directive. */ | 182 | size_t direc_length; /* Length of % directive. */ |
181 | int field_width; /* Arg to first '*', or -1 if none. */ | 183 | int field_width; /* Arg to first '*', or -1 if none. */ |
182 | int precision; /* Arg to second '*', or -1 if none. */ | 184 | int precision; /* Arg to second '*', or -1 if none. */ |
183 | 185 | ||
184 | for (f = format; *f; ++f) | 186 | for (f = format; *f; ++f) { |
185 | { | 187 | switch (*f) { |
186 | switch (*f) | 188 | case '%': |
187 | { | 189 | direc_start = f++; |
188 | case '%': | 190 | direc_length = 1; |
189 | direc_start = f++; | 191 | field_width = precision = -1; |
190 | direc_length = 1; | 192 | if (*f == '%') { |
191 | field_width = precision = -1; | 193 | putchar('%'); |
192 | if (*f == '%') | 194 | break; |
193 | { | 195 | } |
194 | putchar ('%'); | 196 | if (*f == 'b') { |
195 | break; | 197 | if (argc > 0) { |
196 | } | 198 | print_esc_string(*argv); |
197 | if (*f == 'b') | 199 | ++argv; |
198 | { | 200 | --argc; |
199 | if (argc > 0) | 201 | } |
200 | { | 202 | break; |
201 | print_esc_string (*argv); | 203 | } |
202 | ++argv; | 204 | if (strchr("-+ #", *f)) { |
203 | --argc; | 205 | ++f; |
204 | } | 206 | ++direc_length; |
205 | break; | 207 | } |
206 | } | 208 | if (*f == '*') { |
207 | if (strchr ("-+ #", *f)) | 209 | ++f; |
208 | { | 210 | ++direc_length; |
209 | ++f; | 211 | if (argc > 0) { |
210 | ++direc_length; | 212 | field_width = xstrtoul(*argv); |
211 | } | 213 | ++argv; |
212 | if (*f == '*') | 214 | --argc; |
213 | { | 215 | } else |
214 | ++f; | 216 | field_width = 0; |
215 | ++direc_length; | 217 | } else |
216 | if (argc > 0) | 218 | while (ISDIGIT(*f)) { |
217 | { | 219 | ++f; |
218 | field_width = xstrtoul (*argv); | 220 | ++direc_length; |
219 | ++argv; | 221 | } |
220 | --argc; | 222 | if (*f == '.') { |
223 | ++f; | ||
224 | ++direc_length; | ||
225 | if (*f == '*') { | ||
226 | ++f; | ||
227 | ++direc_length; | ||
228 | if (argc > 0) { | ||
229 | precision = xstrtoul(*argv); | ||
230 | ++argv; | ||
231 | --argc; | ||
232 | } else | ||
233 | precision = 0; | ||
234 | } else | ||
235 | while (ISDIGIT(*f)) { | ||
236 | ++f; | ||
237 | ++direc_length; | ||
238 | } | ||
239 | } | ||
240 | if (*f == 'l' || *f == 'L' || *f == 'h') { | ||
241 | ++f; | ||
242 | ++direc_length; | ||
243 | } | ||
244 | /* | ||
245 | if (!strchr ("diouxXfeEgGcs", *f)) | ||
246 | fprintf(stderr, "%%%c: invalid directive", *f); | ||
247 | */ | ||
248 | ++direc_length; | ||
249 | if (argc > 0) { | ||
250 | print_direc(direc_start, direc_length, field_width, | ||
251 | precision, *argv); | ||
252 | ++argv; | ||
253 | --argc; | ||
254 | } else | ||
255 | print_direc(direc_start, direc_length, field_width, | ||
256 | precision, ""); | ||
257 | break; | ||
258 | |||
259 | case '\\': | ||
260 | f += print_esc(f); | ||
261 | break; | ||
262 | |||
263 | default: | ||
264 | putchar(*f); | ||
221 | } | 265 | } |
222 | else | ||
223 | field_width = 0; | ||
224 | } | ||
225 | else | ||
226 | while (ISDIGIT (*f)) | ||
227 | { | ||
228 | ++f; | ||
229 | ++direc_length; | ||
230 | } | ||
231 | if (*f == '.') | ||
232 | { | ||
233 | ++f; | ||
234 | ++direc_length; | ||
235 | if (*f == '*') | ||
236 | { | ||
237 | ++f; | ||
238 | ++direc_length; | ||
239 | if (argc > 0) | ||
240 | { | ||
241 | precision = xstrtoul (*argv); | ||
242 | ++argv; | ||
243 | --argc; | ||
244 | } | ||
245 | else | ||
246 | precision = 0; | ||
247 | } | ||
248 | else | ||
249 | while (ISDIGIT (*f)) | ||
250 | { | ||
251 | ++f; | ||
252 | ++direc_length; | ||
253 | } | ||
254 | } | ||
255 | if (*f == 'l' || *f == 'L' || *f == 'h') | ||
256 | { | ||
257 | ++f; | ||
258 | ++direc_length; | ||
259 | } | ||
260 | /* | ||
261 | if (!strchr ("diouxXfeEgGcs", *f)) | ||
262 | fprintf(stderr, "%%%c: invalid directive", *f); | ||
263 | */ | ||
264 | ++direc_length; | ||
265 | if (argc > 0) | ||
266 | { | ||
267 | print_direc (direc_start, direc_length, field_width, | ||
268 | precision, *argv); | ||
269 | ++argv; | ||
270 | --argc; | ||
271 | } | ||
272 | else | ||
273 | print_direc (direc_start, direc_length, field_width, | ||
274 | precision, ""); | ||
275 | break; | ||
276 | |||
277 | case '\\': | ||
278 | f += print_esc (f); | ||
279 | break; | ||
280 | |||
281 | default: | ||
282 | putchar (*f); | ||
283 | } | 266 | } |
284 | } | ||
285 | 267 | ||
286 | return save_argc - argc; | 268 | return save_argc - argc; |
287 | } | 269 | } |
288 | 270 | ||
289 | /* Print a \ escape sequence starting at ESCSTART. | 271 | /* Print a \ escape sequence starting at ESCSTART. |
290 | Return the number of characters in the escape sequence | 272 | Return the number of characters in the escape sequence |
291 | besides the backslash. */ | 273 | besides the backslash. */ |
292 | 274 | ||
293 | static int | 275 | static int print_esc(char *escstart) |
294 | print_esc (char *escstart) | ||
295 | { | 276 | { |
296 | register char *p = escstart + 1; | 277 | register char *p = escstart + 1; |
297 | int esc_value = 0; /* Value of \nnn escape. */ | 278 | int esc_value = 0; /* Value of \nnn escape. */ |
298 | int esc_length; /* Length of \nnn escape. */ | 279 | int esc_length; /* Length of \nnn escape. */ |
299 | 280 | ||
300 | /* \0ooo and \xhhh escapes have maximum length of 3 chars. */ | 281 | /* \0ooo and \xhhh escapes have maximum length of 3 chars. */ |
301 | if (*p == 'x') | 282 | if (*p == 'x') { |
302 | { | 283 | for (esc_length = 0, ++p; |
303 | for (esc_length = 0, ++p; | 284 | esc_length < 3 && ISXDIGIT(*p); ++esc_length, ++p) |
304 | esc_length < 3 && ISXDIGIT (*p); | 285 | esc_value = esc_value * 16 + hextobin(*p); |
305 | ++esc_length, ++p) | ||
306 | esc_value = esc_value * 16 + hextobin (*p); | ||
307 | /* if (esc_length == 0) | 286 | /* if (esc_length == 0) |
308 | fprintf(stderr, "missing hex in esc"); | 287 | fprintf(stderr, "missing hex in esc"); |
309 | */ | 288 | */ |
310 | putchar (esc_value); | 289 | putchar(esc_value); |
311 | } | 290 | } else if (*p == '0') { |
312 | else if (*p == '0') | 291 | for (esc_length = 0, ++p; |
313 | { | 292 | esc_length < 3 && isodigit(*p); ++esc_length, ++p) |
314 | for (esc_length = 0, ++p; | 293 | esc_value = esc_value * 8 + octtobin(*p); |
315 | esc_length < 3 && isodigit (*p); | 294 | putchar(esc_value); |
316 | ++esc_length, ++p) | 295 | } else if (strchr("\"\\abcfnrtv", *p)) |
317 | esc_value = esc_value * 8 + octtobin (*p); | 296 | print_esc_char(*p++); |
318 | putchar (esc_value); | ||
319 | } | ||
320 | else if (strchr ("\"\\abcfnrtv", *p)) | ||
321 | print_esc_char (*p++); | ||
322 | /* else | 297 | /* else |
323 | fprintf(stderr, "\\%c: invalid esc", *p); | 298 | fprintf(stderr, "\\%c: invalid esc", *p); |
324 | */ | 299 | */ |
325 | return p - escstart - 1; | 300 | return p - escstart - 1; |
326 | } | 301 | } |
327 | 302 | ||
328 | /* Output a single-character \ escape. */ | 303 | /* Output a single-character \ escape. */ |
329 | 304 | ||
330 | static void | 305 | static void print_esc_char(int c) |
331 | print_esc_char (int c) | ||
332 | { | 306 | { |
333 | switch (c) | 307 | switch (c) { |
334 | { | 308 | case 'a': /* Alert. */ |
335 | case 'a': /* Alert. */ | 309 | putchar(7); |
336 | putchar (7); | 310 | break; |
337 | break; | 311 | case 'b': /* Backspace. */ |
338 | case 'b': /* Backspace. */ | 312 | putchar(8); |
339 | putchar (8); | 313 | break; |
340 | break; | 314 | case 'c': /* Cancel the rest of the output. */ |
341 | case 'c': /* Cancel the rest of the output. */ | 315 | exit(0); |
342 | exit (0); | 316 | break; |
343 | break; | 317 | case 'f': /* Form feed. */ |
344 | case 'f': /* Form feed. */ | 318 | putchar(12); |
345 | putchar (12); | 319 | break; |
346 | break; | 320 | case 'n': /* New line. */ |
347 | case 'n': /* New line. */ | 321 | putchar(10); |
348 | putchar (10); | 322 | break; |
349 | break; | 323 | case 'r': /* Carriage return. */ |
350 | case 'r': /* Carriage return. */ | 324 | putchar(13); |
351 | putchar (13); | 325 | break; |
352 | break; | 326 | case 't': /* Horizontal tab. */ |
353 | case 't': /* Horizontal tab. */ | 327 | putchar(9); |
354 | putchar (9); | 328 | break; |
355 | break; | 329 | case 'v': /* Vertical tab. */ |
356 | case 'v': /* Vertical tab. */ | 330 | putchar(11); |
357 | putchar (11); | 331 | break; |
358 | break; | 332 | default: |
359 | default: | 333 | putchar(c); |
360 | putchar (c); | 334 | break; |
361 | break; | 335 | } |
362 | } | ||
363 | } | 336 | } |
364 | 337 | ||
365 | /* Print string STR, evaluating \ escapes. */ | 338 | /* Print string STR, evaluating \ escapes. */ |
366 | 339 | ||
367 | static void | 340 | static void print_esc_string(char *str) |
368 | print_esc_string (char *str) | ||
369 | { | 341 | { |
370 | for (; *str; str++) | 342 | for (; *str; str++) |
371 | if (*str == '\\') | 343 | if (*str == '\\') |
372 | str += print_esc (str); | 344 | str += print_esc(str); |
373 | else | 345 | else |
374 | putchar (*str); | 346 | putchar(*str); |
375 | } | 347 | } |
376 | 348 | ||
377 | static void | 349 | static void |
378 | print_direc (char *start, size_t length, int field_width, int precision, char *argument) | 350 | print_direc(char *start, size_t length, int field_width, int precision, |
351 | char *argument) | ||
379 | { | 352 | { |
380 | char *p; /* Null-terminated copy of % directive. */ | 353 | char *p; /* Null-terminated copy of % directive. */ |
381 | 354 | ||
382 | p = xmalloc ((unsigned) (length + 1)); | 355 | p = xmalloc((unsigned) (length + 1)); |
383 | strncpy (p, start, length); | 356 | strncpy(p, start, length); |
384 | p[length] = 0; | 357 | p[length] = 0; |
385 | 358 | ||
386 | switch (p[length - 1]) | 359 | switch (p[length - 1]) { |
387 | { | 360 | case 'd': |
388 | case 'd': | 361 | case 'i': |
389 | case 'i': | 362 | if (field_width < 0) { |
390 | if (field_width < 0) | 363 | if (precision < 0) |
391 | { | 364 | printf(p, xstrtol(argument)); |
392 | if (precision < 0) | 365 | else |
393 | printf (p, xstrtol (argument)); | 366 | printf(p, precision, xstrtol(argument)); |
394 | else | 367 | } else { |
395 | printf (p, precision, xstrtol (argument)); | 368 | if (precision < 0) |
396 | } | 369 | printf(p, field_width, xstrtol(argument)); |
397 | else | 370 | else |
398 | { | 371 | printf(p, field_width, precision, xstrtol(argument)); |
399 | if (precision < 0) | 372 | } |
400 | printf (p, field_width, xstrtol (argument)); | 373 | break; |
401 | else | 374 | |
402 | printf (p, field_width, precision, xstrtol (argument)); | 375 | case 'o': |
403 | } | 376 | case 'u': |
404 | break; | 377 | case 'x': |
405 | 378 | case 'X': | |
406 | case 'o': | 379 | if (field_width < 0) { |
407 | case 'u': | 380 | if (precision < 0) |
408 | case 'x': | 381 | printf(p, xstrtoul(argument)); |
409 | case 'X': | 382 | else |
410 | if (field_width < 0) | 383 | printf(p, precision, xstrtoul(argument)); |
411 | { | 384 | } else { |
412 | if (precision < 0) | 385 | if (precision < 0) |
413 | printf (p, xstrtoul (argument)); | 386 | printf(p, field_width, xstrtoul(argument)); |
414 | else | 387 | else |
415 | printf (p, precision, xstrtoul (argument)); | 388 | printf(p, field_width, precision, xstrtoul(argument)); |
416 | } | 389 | } |
417 | else | 390 | break; |
418 | { | 391 | |
419 | if (precision < 0) | 392 | case 'f': |
420 | printf (p, field_width, xstrtoul (argument)); | 393 | case 'e': |
421 | else | 394 | case 'E': |
422 | printf (p, field_width, precision, xstrtoul (argument)); | 395 | case 'g': |
423 | } | 396 | case 'G': |
424 | break; | 397 | if (field_width < 0) { |
425 | 398 | if (precision < 0) | |
426 | case 'f': | 399 | printf(p, xstrtod(argument)); |
427 | case 'e': | 400 | else |
428 | case 'E': | 401 | printf(p, precision, xstrtod(argument)); |
429 | case 'g': | 402 | } else { |
430 | case 'G': | 403 | if (precision < 0) |
431 | if (field_width < 0) | 404 | printf(p, field_width, xstrtod(argument)); |
432 | { | 405 | else |
433 | if (precision < 0) | 406 | printf(p, field_width, precision, xstrtod(argument)); |
434 | printf (p, xstrtod (argument)); | 407 | } |
435 | else | 408 | break; |
436 | printf (p, precision, xstrtod (argument)); | 409 | |
437 | } | 410 | case 'c': |
438 | else | 411 | printf(p, *argument); |
439 | { | 412 | break; |
440 | if (precision < 0) | 413 | |
441 | printf (p, field_width, xstrtod (argument)); | 414 | case 's': |
442 | else | 415 | if (field_width < 0) { |
443 | printf (p, field_width, precision, xstrtod (argument)); | 416 | if (precision < 0) |
444 | } | 417 | printf(p, argument); |
445 | break; | 418 | else |
446 | 419 | printf(p, precision, argument); | |
447 | case 'c': | 420 | } else { |
448 | printf (p, *argument); | 421 | if (precision < 0) |
449 | break; | 422 | printf(p, field_width, argument); |
450 | 423 | else | |
451 | case 's': | 424 | printf(p, field_width, precision, argument); |
452 | if (field_width < 0) | 425 | } |
453 | { | 426 | break; |
454 | if (precision < 0) | ||
455 | printf (p, argument); | ||
456 | else | ||
457 | printf (p, precision, argument); | ||
458 | } | ||
459 | else | ||
460 | { | ||
461 | if (precision < 0) | ||
462 | printf (p, field_width, argument); | ||
463 | else | ||
464 | printf (p, field_width, precision, argument); | ||
465 | } | 427 | } |
466 | break; | ||
467 | } | ||
468 | 428 | ||
469 | free (p); | 429 | free(p); |
470 | } | 430 | } |
471 | 431 | ||
472 | static unsigned long | 432 | static unsigned long xstrtoul(char *s) |
473 | xstrtoul (char *s) | ||
474 | { | 433 | { |
475 | char *end; | 434 | char *end; |
476 | unsigned long val; | 435 | unsigned long val; |
477 | 436 | ||
478 | errno = 0; | 437 | errno = 0; |
479 | val = strtoul (s, &end, 0); | 438 | val = strtoul(s, &end, 0); |
480 | verify (s, end); | 439 | verify(s, end); |
481 | return val; | 440 | return val; |
482 | } | 441 | } |
483 | 442 | ||
484 | static long | 443 | static long xstrtol(char *s) |
485 | xstrtol (char *s) | ||
486 | { | 444 | { |
487 | char *end; | 445 | char *end; |
488 | long val; | 446 | long val; |
489 | 447 | ||
490 | errno = 0; | 448 | errno = 0; |
491 | val = strtol (s, &end, 0); | 449 | val = strtol(s, &end, 0); |
492 | verify (s, end); | 450 | verify(s, end); |
493 | return val; | 451 | return val; |
494 | } | 452 | } |
495 | 453 | ||
496 | static double | 454 | static double xstrtod(char *s) |
497 | xstrtod (char *s) | ||
498 | { | 455 | { |
499 | char *end; | 456 | char *end; |
500 | double val; | 457 | double val; |
501 | 458 | ||
502 | errno = 0; | 459 | errno = 0; |
503 | val = strtod (s, &end); | 460 | val = strtod(s, &end); |
504 | verify (s, end); | 461 | verify(s, end); |
505 | return val; | 462 | return val; |
506 | } | 463 | } |
507 | 464 | ||
508 | static void | 465 | static void verify(char *s, char *end) |
509 | verify (char *s, char *end) | ||
510 | { | 466 | { |
511 | if (errno) | 467 | if (errno) { |
512 | { | 468 | fprintf(stderr, "%s", s); |
513 | fprintf(stderr, "%s", s); | 469 | exit_status = 1; |
514 | exit_status = 1; | 470 | } else if (*end) { |
515 | } | 471 | /* |
516 | else if (*end) | 472 | if (s == end) |
517 | { | 473 | fprintf(stderr, "%s: expected numeric", s); |
518 | /* | 474 | else |
519 | if (s == end) | 475 | fprintf(stderr, "%s: not completely converted", s); |
520 | fprintf(stderr, "%s: expected numeric", s); | 476 | */ |
521 | else | 477 | exit_status = 1; |
522 | fprintf(stderr, "%s: not completely converted", s); | 478 | } |
523 | */ | ||
524 | exit_status = 1; | ||
525 | } | ||
526 | } | 479 | } |
527 | |||
diff --git a/coreutils/pwd.c b/coreutils/pwd.c index bacabd77a..00163178b 100644 --- a/coreutils/pwd.c +++ b/coreutils/pwd.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini pwd implementation for busybox | 3 | * Mini pwd implementation for busybox |
3 | * | 4 | * |
@@ -25,16 +26,15 @@ | |||
25 | #include <dirent.h> | 26 | #include <dirent.h> |
26 | #include <sys/param.h> | 27 | #include <sys/param.h> |
27 | 28 | ||
28 | extern int | 29 | extern int pwd_main(int argc, char **argv) |
29 | pwd_main(int argc, char * * argv) | ||
30 | { | 30 | { |
31 | char buf[PATH_MAX + 1]; | 31 | char buf[PATH_MAX + 1]; |
32 | 32 | ||
33 | if ( getcwd(buf, sizeof(buf)) == NULL ) { | 33 | if (getcwd(buf, sizeof(buf)) == NULL) { |
34 | perror("get working directory"); | 34 | perror("get working directory"); |
35 | exit( FALSE); | 35 | exit(FALSE); |
36 | } | 36 | } |
37 | 37 | ||
38 | printf("%s\n", buf); | 38 | printf("%s\n", buf); |
39 | exit( TRUE); | 39 | exit(TRUE); |
40 | } | 40 | } |
diff --git a/coreutils/rm.c b/coreutils/rm.c index ee434fb39..41afedaf9 100644 --- a/coreutils/rm.c +++ b/coreutils/rm.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini rm implementation for busybox | 3 | * Mini rm implementation for busybox |
3 | * | 4 | * |
@@ -28,11 +29,12 @@ | |||
28 | #include <dirent.h> | 29 | #include <dirent.h> |
29 | #include <errno.h> | 30 | #include <errno.h> |
30 | 31 | ||
31 | static const char* rm_usage = "rm [OPTION]... FILE...\n\n" | 32 | static const char *rm_usage = "rm [OPTION]... FILE...\n\n" |
32 | "Remove (unlink) the FILE(s).\n\n" | 33 | "Remove (unlink) the FILE(s).\n\n" |
33 | "Options:\n" | 34 | "Options:\n" |
34 | "\t-f\t\tremove existing destinations, never prompt\n" | 35 | |
35 | "\t-r or -R\tremove the contents of directories recursively\n"; | 36 | "\t-f\t\tremove existing destinations, never prompt\n" |
37 | "\t-r or -R\tremove the contents of directories recursively\n"; | ||
36 | 38 | ||
37 | 39 | ||
38 | static int recursiveFlag = FALSE; | 40 | static int recursiveFlag = FALSE; |
@@ -40,63 +42,63 @@ static int forceFlag = FALSE; | |||
40 | static const char *srcName; | 42 | static const char *srcName; |
41 | 43 | ||
42 | 44 | ||
43 | static int fileAction(const char *fileName, struct stat* statbuf) | 45 | static int fileAction(const char *fileName, struct stat *statbuf) |
44 | { | 46 | { |
45 | if (unlink( fileName) < 0 ) { | 47 | if (unlink(fileName) < 0) { |
46 | perror( fileName); | 48 | perror(fileName); |
47 | return ( FALSE); | 49 | return (FALSE); |
48 | } | 50 | } |
49 | return ( TRUE); | 51 | return (TRUE); |
50 | } | 52 | } |
51 | 53 | ||
52 | static int dirAction(const char *fileName, struct stat* statbuf) | 54 | static int dirAction(const char *fileName, struct stat *statbuf) |
53 | { | 55 | { |
54 | if (rmdir( fileName) < 0 ) { | 56 | if (rmdir(fileName) < 0) { |
55 | perror( fileName); | 57 | perror(fileName); |
56 | return ( FALSE); | 58 | return (FALSE); |
57 | } | 59 | } |
58 | return ( TRUE); | 60 | return (TRUE); |
59 | } | 61 | } |
60 | 62 | ||
61 | extern int rm_main(int argc, char **argv) | 63 | extern int rm_main(int argc, char **argv) |
62 | { | 64 | { |
63 | struct stat statbuf; | 65 | struct stat statbuf; |
64 | 66 | ||
65 | if (argc < 2) { | 67 | if (argc < 2) { |
66 | usage( rm_usage); | 68 | usage(rm_usage); |
67 | } | 69 | } |
68 | argc--; | ||
69 | argv++; | ||
70 | |||
71 | /* Parse any options */ | ||
72 | while (**argv == '-') { | ||
73 | while (*++(*argv)) | ||
74 | switch (**argv) { | ||
75 | case 'R': | ||
76 | case 'r': | ||
77 | recursiveFlag = TRUE; | ||
78 | break; | ||
79 | case 'f': | ||
80 | forceFlag = TRUE; | ||
81 | break; | ||
82 | default: | ||
83 | usage( rm_usage); | ||
84 | } | ||
85 | argc--; | 70 | argc--; |
86 | argv++; | 71 | argv++; |
87 | } | ||
88 | 72 | ||
89 | while (argc-- > 0) { | 73 | /* Parse any options */ |
90 | srcName = *(argv++); | 74 | while (**argv == '-') { |
91 | if (forceFlag == TRUE && lstat(srcName, &statbuf) != 0 && errno == ENOENT) { | 75 | while (*++(*argv)) |
92 | /* do not reports errors for non-existent files if -f, just skip them */ | 76 | switch (**argv) { |
77 | case 'R': | ||
78 | case 'r': | ||
79 | recursiveFlag = TRUE; | ||
80 | break; | ||
81 | case 'f': | ||
82 | forceFlag = TRUE; | ||
83 | break; | ||
84 | default: | ||
85 | usage(rm_usage); | ||
86 | } | ||
87 | argc--; | ||
88 | argv++; | ||
93 | } | 89 | } |
94 | else { | 90 | |
95 | if (recursiveAction( srcName, recursiveFlag, FALSE, | 91 | while (argc-- > 0) { |
96 | TRUE, fileAction, dirAction) == FALSE) { | 92 | srcName = *(argv++); |
97 | exit( FALSE); | 93 | if (forceFlag == TRUE && lstat(srcName, &statbuf) != 0 |
98 | } | 94 | && errno == ENOENT) { |
95 | /* do not reports errors for non-existent files if -f, just skip them */ | ||
96 | } else { | ||
97 | if (recursiveAction(srcName, recursiveFlag, FALSE, | ||
98 | TRUE, fileAction, dirAction) == FALSE) { | ||
99 | exit(FALSE); | ||
100 | } | ||
101 | } | ||
99 | } | 102 | } |
100 | } | 103 | exit(TRUE); |
101 | exit( TRUE); | ||
102 | } | 104 | } |
diff --git a/coreutils/rmdir.c b/coreutils/rmdir.c index 013fef1a4..f49569749 100644 --- a/coreutils/rmdir.c +++ b/coreutils/rmdir.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini rmdir implementation for busybox | 3 | * Mini rmdir implementation for busybox |
3 | * | 4 | * |
@@ -28,15 +29,16 @@ | |||
28 | 29 | ||
29 | extern int rmdir_main(int argc, char **argv) | 30 | extern int rmdir_main(int argc, char **argv) |
30 | { | 31 | { |
31 | if ( argc==1 || **(argv+1) == '-' ) { | 32 | if (argc == 1 || **(argv + 1) == '-') { |
32 | usage( "rmdir [OPTION]... DIRECTORY...\n\nRemove the DIRECTORY(ies), if they are empty.\n"); | 33 | usage |
33 | } | 34 | ("rmdir [OPTION]... DIRECTORY...\n\nRemove the DIRECTORY(ies), if they are empty.\n"); |
35 | } | ||
34 | 36 | ||
35 | while (--argc > 0) { | 37 | while (--argc > 0) { |
36 | if ( rmdir(*(++argv)) == -1 ) { | 38 | if (rmdir(*(++argv)) == -1) { |
37 | fprintf(stderr, "%s: %s\n", *argv, strerror(errno)); | 39 | fprintf(stderr, "%s: %s\n", *argv, strerror(errno)); |
38 | exit(FALSE); | 40 | exit(FALSE); |
41 | } | ||
39 | } | 42 | } |
40 | } | 43 | exit(TRUE); |
41 | exit(TRUE); | ||
42 | } | 44 | } |
diff --git a/coreutils/sleep.c b/coreutils/sleep.c index bfbb78f61..9687b8446 100644 --- a/coreutils/sleep.c +++ b/coreutils/sleep.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini sleep implementation for busybox | 3 | * Mini sleep implementation for busybox |
3 | * | 4 | * |
@@ -23,19 +24,17 @@ | |||
23 | #include "internal.h" | 24 | #include "internal.h" |
24 | #include <stdio.h> | 25 | #include <stdio.h> |
25 | 26 | ||
26 | const char sleep_usage[] = "sleep N\n\n" | 27 | const char sleep_usage[] = "sleep N\n\n" "Pause for N seconds.\n"; |
27 | "Pause for N seconds.\n"; | ||
28 | 28 | ||
29 | extern int | 29 | extern int sleep_main(int argc, char **argv) |
30 | sleep_main(int argc, char * * argv) | ||
31 | { | 30 | { |
32 | if ( (argc < 2) || (**(argv+1) == '-') ) { | 31 | if ((argc < 2) || (**(argv + 1) == '-')) { |
33 | usage( sleep_usage ); | 32 | usage(sleep_usage); |
34 | } | 33 | } |
35 | 34 | ||
36 | if ( sleep(atoi(*(++argv))) != 0 ) { | 35 | if (sleep(atoi(*(++argv))) != 0) { |
37 | perror( "sleep"); | 36 | perror("sleep"); |
38 | exit (FALSE); | 37 | exit(FALSE); |
39 | } else | 38 | } else |
40 | exit (TRUE); | 39 | exit(TRUE); |
41 | } | 40 | } |
diff --git a/coreutils/sort.c b/coreutils/sort.c index d529ce722..609c5e08c 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini sort implementation for busybox | 3 | * Mini sort implementation for busybox |
3 | * | 4 | * |
@@ -28,29 +29,27 @@ | |||
28 | #include <stdio.h> | 29 | #include <stdio.h> |
29 | #include <errno.h> | 30 | #include <errno.h> |
30 | 31 | ||
31 | static const char sort_usage[] = | 32 | static const char sort_usage[] = "sort [OPTION]... [FILE]...\n\n"; |
32 | "sort [OPTION]... [FILE]...\n\n" | ||
33 | ; | ||
34 | 33 | ||
35 | /* typedefs _______________________________________________________________ */ | 34 | /* typedefs _______________________________________________________________ */ |
36 | 35 | ||
37 | /* line node */ | 36 | /* line node */ |
38 | typedef struct Line { | 37 | typedef struct Line { |
39 | char *data; /* line data */ | 38 | char *data; /* line data */ |
40 | struct Line *next; /* pointer to next line node */ | 39 | struct Line *next; /* pointer to next line node */ |
41 | } Line; | 40 | } Line; |
42 | 41 | ||
43 | /* singly-linked list of lines */ | 42 | /* singly-linked list of lines */ |
44 | typedef struct { | 43 | typedef struct { |
45 | int len; /* number of Lines */ | 44 | int len; /* number of Lines */ |
46 | Line **sorted; /* array fed to qsort */ | 45 | Line **sorted; /* array fed to qsort */ |
47 | 46 | ||
48 | Line *head; /* head of List */ | 47 | Line *head; /* head of List */ |
49 | Line *current; /* current Line */ | 48 | Line *current; /* current Line */ |
50 | } List; | 49 | } List; |
51 | 50 | ||
52 | /* comparison function */ | 51 | /* comparison function */ |
53 | typedef int (Compare)(const void *, const void *); | 52 | typedef int (Compare) (const void *, const void *); |
54 | 53 | ||
55 | 54 | ||
56 | /* methods ________________________________________________________________ */ | 55 | /* methods ________________________________________________________________ */ |
@@ -58,175 +57,176 @@ typedef int (Compare)(const void *, const void *); | |||
58 | static const int max = 1024; | 57 | static const int max = 1024; |
59 | 58 | ||
60 | /* mallocate Line */ | 59 | /* mallocate Line */ |
61 | static Line * | 60 | static Line *line_alloc() |
62 | line_alloc() | ||
63 | { | 61 | { |
64 | Line *self; | 62 | Line *self; |
65 | self = malloc(1 * sizeof(Line)); | 63 | |
66 | return self; | 64 | self = malloc(1 * sizeof(Line)); |
65 | return self; | ||
67 | } | 66 | } |
68 | 67 | ||
69 | /* Initialize Line with string */ | 68 | /* Initialize Line with string */ |
70 | static Line * | 69 | static Line *line_init(Line * self, const char *string) |
71 | line_init(Line *self, const char *string) | ||
72 | { | 70 | { |
73 | self->data = malloc((strlen(string) + 1) * sizeof(char)); | 71 | self->data = malloc((strlen(string) + 1) * sizeof(char)); |
74 | if (self->data == NULL) { return NULL; } | 72 | |
75 | strcpy(self->data, string); | 73 | if (self->data == NULL) { |
76 | self->next = NULL; | 74 | return NULL; |
77 | return self; | 75 | } |
76 | strcpy(self->data, string); | ||
77 | self->next = NULL; | ||
78 | return self; | ||
78 | } | 79 | } |
79 | 80 | ||
80 | /* Construct Line from FILE* */ | 81 | /* Construct Line from FILE* */ |
81 | static Line * | 82 | static Line *line_newFromFile(FILE * src) |
82 | line_newFromFile(FILE *src) | ||
83 | { | 83 | { |
84 | char buffer[max]; | 84 | char buffer[max]; |
85 | Line *self; | 85 | Line *self; |
86 | 86 | ||
87 | if (fgets(buffer, max, src)) { | 87 | if (fgets(buffer, max, src)) { |
88 | self = line_alloc(); | 88 | self = line_alloc(); |
89 | if (self == NULL) { return NULL; } | 89 | if (self == NULL) { |
90 | line_init(self, buffer); | 90 | return NULL; |
91 | return self; | 91 | } |
92 | } | 92 | line_init(self, buffer); |
93 | return NULL; | 93 | return self; |
94 | } | ||
95 | return NULL; | ||
94 | } | 96 | } |
95 | 97 | ||
96 | /* Line destructor */ | 98 | /* Line destructor */ |
97 | static Line * | 99 | static Line *line_release(Line * self) |
98 | line_release(Line *self) | ||
99 | { | 100 | { |
100 | if (self->data) { | 101 | if (self->data) { |
101 | free(self->data); | 102 | free(self->data); |
102 | free(self); | 103 | free(self); |
103 | } | 104 | } |
104 | return self; | 105 | return self; |
105 | } | 106 | } |
106 | 107 | ||
107 | 108 | ||
108 | /* Comparison */ | 109 | /* Comparison */ |
109 | 110 | ||
110 | /* ascii order */ | 111 | /* ascii order */ |
111 | static int | 112 | static int compare_ascii(const void *a, const void *b) |
112 | compare_ascii(const void *a, const void *b) | ||
113 | { | 113 | { |
114 | Line **doh; | 114 | Line **doh; |
115 | Line *x, *y; | 115 | Line *x, *y; |
116 | 116 | ||
117 | doh = (Line **) a; | 117 | doh = (Line **) a; |
118 | x = *doh; | 118 | x = *doh; |
119 | doh = (Line **) b; | 119 | doh = (Line **) b; |
120 | y = *doh; | 120 | y = *doh; |
121 | 121 | ||
122 | // fprintf(stdout, "> %p: %s< %p: %s", x, x->data, y, y->data); | 122 | // fprintf(stdout, "> %p: %s< %p: %s", x, x->data, y, y->data); |
123 | return strcmp(x->data, y->data); | 123 | return strcmp(x->data, y->data); |
124 | } | 124 | } |
125 | 125 | ||
126 | /* numeric order */ | 126 | /* numeric order */ |
127 | static int | 127 | static int compare_numeric(const void *a, const void *b) |
128 | compare_numeric(const void *a, const void *b) | ||
129 | { | 128 | { |
130 | Line **doh; | 129 | Line **doh; |
131 | Line *x, *y; | 130 | Line *x, *y; |
132 | int xint, yint; | 131 | int xint, yint; |
133 | 132 | ||
134 | doh = (Line **) a; | 133 | doh = (Line **) a; |
135 | x = *doh; | 134 | x = *doh; |
136 | doh = (Line **) b; | 135 | doh = (Line **) b; |
137 | y = *doh; | 136 | y = *doh; |
138 | 137 | ||
139 | xint = strtoul(x->data, NULL, 10); | 138 | xint = strtoul(x->data, NULL, 10); |
140 | yint = strtoul(y->data, NULL, 10); | 139 | yint = strtoul(y->data, NULL, 10); |
141 | 140 | ||
142 | return (xint - yint); | 141 | return (xint - yint); |
143 | } | 142 | } |
144 | 143 | ||
145 | 144 | ||
146 | /* List */ | 145 | /* List */ |
147 | 146 | ||
148 | /* */ | 147 | /* */ |
149 | static List * | 148 | static List *list_init(List * self) |
150 | list_init(List *self) | ||
151 | { | 149 | { |
152 | self->len = 0; | 150 | self->len = 0; |
153 | self->sorted = NULL; | 151 | self->sorted = NULL; |
154 | self->head = NULL; | 152 | self->head = NULL; |
155 | self->current = NULL; | 153 | self->current = NULL; |
156 | return self; | 154 | return self; |
157 | } | 155 | } |
158 | 156 | ||
159 | /* for simplicity, the List gains ownership of the line */ | 157 | /* for simplicity, the List gains ownership of the line */ |
160 | static List * | 158 | static List *list_insert(List * self, Line * line) |
161 | list_insert(List *self, Line *line) | ||
162 | { | 159 | { |
163 | if (line == NULL) { return NULL; } | 160 | if (line == NULL) { |
164 | 161 | return NULL; | |
165 | /* first insertion */ | 162 | } |
166 | if (self->head == NULL) { | 163 | |
167 | self->head = line; | 164 | /* first insertion */ |
168 | self->current = line; | 165 | if (self->head == NULL) { |
169 | 166 | self->head = line; | |
170 | /* all subsequent insertions */ | 167 | self->current = line; |
171 | } else { | 168 | |
172 | self->current->next = line; | 169 | /* all subsequent insertions */ |
173 | self->current = line; | 170 | } else { |
174 | } | 171 | self->current->next = line; |
175 | self->len++; | 172 | self->current = line; |
176 | return self; | 173 | } |
174 | self->len++; | ||
175 | return self; | ||
177 | } | 176 | } |
178 | 177 | ||
179 | /* order the list according to compare() */ | 178 | /* order the list according to compare() */ |
180 | static List * | 179 | static List *list_sort(List * self, Compare * compare) |
181 | list_sort(List *self, Compare *compare) | ||
182 | { | 180 | { |
183 | int i; | 181 | int i; |
184 | Line *line; | 182 | Line *line; |
185 | 183 | ||
186 | /* mallocate array of Line*s */ | 184 | /* mallocate array of Line*s */ |
187 | self->sorted = (Line **) malloc(self->len * sizeof(Line*)); | 185 | self->sorted = (Line **) malloc(self->len * sizeof(Line *)); |
188 | if (self->sorted == NULL) { return NULL; } | 186 | if (self->sorted == NULL) { |
189 | 187 | return NULL; | |
190 | /* fill array w/ List's contents */ | 188 | } |
191 | i = 0; | 189 | |
192 | line = self->head; | 190 | /* fill array w/ List's contents */ |
193 | while (line) { | 191 | i = 0; |
194 | self->sorted[i++] = line; | 192 | line = self->head; |
195 | line = line->next; | 193 | while (line) { |
196 | } | 194 | self->sorted[i++] = line; |
197 | 195 | line = line->next; | |
198 | /* apply qsort */ | 196 | } |
199 | qsort(self->sorted, self->len, sizeof(Line*), compare); | 197 | |
200 | return self; | 198 | /* apply qsort */ |
199 | qsort(self->sorted, self->len, sizeof(Line *), compare); | ||
200 | return self; | ||
201 | } | 201 | } |
202 | 202 | ||
203 | /* precondition: list must be sorted */ | 203 | /* precondition: list must be sorted */ |
204 | static List * | 204 | static List *list_writeToFile(List * self, FILE * dst) |
205 | list_writeToFile(List *self, FILE* dst) | ||
206 | { | 205 | { |
207 | int i; | 206 | int i; |
208 | Line **line = self->sorted; | 207 | Line **line = self->sorted; |
209 | 208 | ||
210 | if (self->sorted == NULL) { return NULL; } | 209 | if (self->sorted == NULL) { |
211 | for (i = 0; i < self->len; i++) { | 210 | return NULL; |
212 | fprintf(dst, "%s", line[i]->data); | 211 | } |
213 | } | 212 | for (i = 0; i < self->len; i++) { |
214 | return self; | 213 | fprintf(dst, "%s", line[i]->data); |
214 | } | ||
215 | return self; | ||
215 | } | 216 | } |
216 | 217 | ||
217 | /* deallocate */ | 218 | /* deallocate */ |
218 | static void | 219 | static void list_release(List * self) |
219 | list_release(List *self) | ||
220 | { | 220 | { |
221 | Line *i; | 221 | Line *i; |
222 | Line *die; | 222 | Line *die; |
223 | 223 | ||
224 | i = self->head; | 224 | i = self->head; |
225 | while (i) { | 225 | while (i) { |
226 | die = i; | 226 | die = i; |
227 | i = die->next; | 227 | i = die->next; |
228 | line_release(die); | 228 | line_release(die); |
229 | } | 229 | } |
230 | } | 230 | } |
231 | 231 | ||
232 | 232 | ||
@@ -237,76 +237,77 @@ list_release(List *self) | |||
237 | * and finally print it | 237 | * and finally print it |
238 | */ | 238 | */ |
239 | 239 | ||
240 | int | 240 | int sort_main(int argc, char **argv) |
241 | sort_main(int argc, char **argv) | ||
242 | { | 241 | { |
243 | int i; | 242 | int i; |
244 | char opt; | 243 | char opt; |
245 | List list; | 244 | List list; |
246 | Line *l; | 245 | Line *l; |
247 | Compare *compare; | 246 | Compare *compare; |
248 | 247 | ||
249 | /* init */ | 248 | /* init */ |
250 | compare = compare_ascii; | 249 | compare = compare_ascii; |
251 | list_init(&list); | 250 | list_init(&list); |
252 | 251 | ||
253 | /* parse argv[] */ | 252 | /* parse argv[] */ |
254 | for (i = 1; i < argc; i++) { | 253 | for (i = 1; i < argc; i++) { |
255 | if (argv[i][0] == '-') { | 254 | if (argv[i][0] == '-') { |
256 | opt = argv[i][1]; | 255 | opt = argv[i][1]; |
257 | switch (opt) { | 256 | switch (opt) { |
258 | case 'g': | 257 | case 'g': |
259 | /* what's the diff between -g && -n? */ | 258 | /* what's the diff between -g && -n? */ |
260 | compare = compare_numeric; | 259 | compare = compare_numeric; |
261 | break; | 260 | break; |
262 | case 'h': | 261 | case 'h': |
263 | usage(sort_usage); | 262 | usage(sort_usage); |
264 | break; | 263 | break; |
265 | case 'n': | 264 | case 'n': |
266 | /* what's the diff between -g && -n? */ | 265 | /* what's the diff between -g && -n? */ |
267 | compare = compare_numeric; | 266 | compare = compare_numeric; |
268 | break; | 267 | break; |
269 | case 'r': | 268 | case 'r': |
270 | /* reverse */ | 269 | /* reverse */ |
271 | break; | 270 | break; |
272 | default: | 271 | default: |
273 | fprintf(stderr, "sort: invalid option -- %c\n", opt); | 272 | fprintf(stderr, "sort: invalid option -- %c\n", opt); |
274 | usage(sort_usage); | 273 | usage(sort_usage); |
275 | } | 274 | } |
276 | } else { | 275 | } else { |
277 | break; | 276 | break; |
277 | } | ||
278 | } | 278 | } |
279 | } | ||
280 | 279 | ||
281 | /* this could be factored better */ | 280 | /* this could be factored better */ |
282 | 281 | ||
283 | /* work w/ stdin */ | 282 | /* work w/ stdin */ |
284 | if (i >= argc) { | 283 | if (i >= argc) { |
285 | while ( (l = line_newFromFile(stdin))) { | 284 | while ((l = line_newFromFile(stdin))) { |
286 | list_insert(&list, l); | 285 | list_insert(&list, l); |
287 | } | 286 | } |
288 | list_sort(&list, compare); | 287 | list_sort(&list, compare); |
289 | list_writeToFile(&list, stdout); | 288 | list_writeToFile(&list, stdout); |
290 | list_release(&list); | 289 | list_release(&list); |
291 | 290 | ||
292 | /* work w/ what's left in argv[] */ | 291 | /* work w/ what's left in argv[] */ |
293 | } else { | 292 | } else { |
294 | FILE *src; | 293 | FILE *src; |
295 | 294 | ||
296 | for ( ; i < argc; i++) { | 295 | for (; i < argc; i++) { |
297 | src = fopen(argv[i], "r"); | 296 | src = fopen(argv[i], "r"); |
298 | if (src == NULL) { break; } | 297 | if (src == NULL) { |
299 | while ( (l = line_newFromFile(src))) { | 298 | break; |
300 | list_insert(&list, l); | 299 | } |
301 | } | 300 | while ((l = line_newFromFile(src))) { |
302 | fclose(src); | 301 | list_insert(&list, l); |
302 | } | ||
303 | fclose(src); | ||
304 | } | ||
305 | list_sort(&list, compare); | ||
306 | list_writeToFile(&list, stdout); | ||
307 | list_release(&list); | ||
303 | } | 308 | } |
304 | list_sort(&list, compare); | ||
305 | list_writeToFile(&list, stdout); | ||
306 | list_release(&list); | ||
307 | } | ||
308 | 309 | ||
309 | exit(0); | 310 | exit(0); |
310 | } | 311 | } |
311 | 312 | ||
312 | /* $Id: sort.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */ | 313 | /* $Id: sort.c,v 1.11 2000/02/08 19:58:47 erik Exp $ */ |
diff --git a/coreutils/sync.c b/coreutils/sync.c index 145ed1eda..f8160c8dc 100644 --- a/coreutils/sync.c +++ b/coreutils/sync.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini sync implementation for busybox | 3 | * Mini sync implementation for busybox |
3 | * | 4 | * |
@@ -23,12 +24,10 @@ | |||
23 | #include "internal.h" | 24 | #include "internal.h" |
24 | #include <stdio.h> | 25 | #include <stdio.h> |
25 | 26 | ||
26 | extern int | 27 | extern int sync_main(int argc, char **argv) |
27 | sync_main(int argc, char * * argv) | ||
28 | { | 28 | { |
29 | if ( argc>1 && **(argv+1) == '-' ) { | 29 | if (argc > 1 && **(argv + 1) == '-') { |
30 | usage( "sync\n\nWrite all buffered filesystem blocks to disk.\n"); | 30 | usage("sync\n\nWrite all buffered filesystem blocks to disk.\n"); |
31 | } | 31 | } |
32 | exit( sync()); | 32 | exit(sync()); |
33 | } | 33 | } |
34 | |||
diff --git a/coreutils/tail.c b/coreutils/tail.c index 0ab8f11b0..31705afa2 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | #include "internal.h" | 2 | #include "internal.h" |
2 | /* This file contains _two_ implementations of tail. One is | 3 | /* This file contains _two_ implementations of tail. One is |
3 | * a bit more full featured, but costs 6k. The other (i.e. the | 4 | * a bit more full featured, but costs 6k. The other (i.e. the |
@@ -68,22 +69,23 @@ static int forever; | |||
68 | static int print_headers; | 69 | static int print_headers; |
69 | 70 | ||
70 | const char tail_usage[] = | 71 | const char tail_usage[] = |
71 | "tail [OPTION] [FILE]...\n\n" | 72 | "tail [OPTION] [FILE]...\n\n" |
72 | "Print last 10 lines of each FILE to standard output.\n" | 73 | "Print last 10 lines of each FILE to standard output.\n" |
73 | "With more than one FILE, precede each with a header giving the\n" | 74 | "With more than one FILE, precede each with a header giving the\n" |
74 | "file name. With no FILE, or when FILE is -, read standard input.\n\n" | 75 | "file name. With no FILE, or when FILE is -, read standard input.\n\n" |
75 | "Options:\n" | 76 | "Options:\n" |
76 | "\t-n NUM\t\tPrint last NUM lines instead of first 10\n" | 77 | "\t-n NUM\t\tPrint last NUM lines instead of first 10\n" |
77 | "\t-f\t\tOutput data as the file grows. This version\n" | 78 | |
78 | "\t\t\tof 'tail -f' supports only one file at a time.\n"; | 79 | "\t-f\t\tOutput data as the file grows. This version\n" |
80 | "\t\t\tof 'tail -f' supports only one file at a time.\n"; | ||
79 | 81 | ||
80 | 82 | ||
81 | static void write_header(const char *filename) | 83 | static void write_header(const char *filename) |
82 | { | 84 | { |
83 | static int first_file = 1; | 85 | static int first_file = 1; |
84 | 86 | ||
85 | printf("%s==> %s <==\n", (first_file ? "" : "\n"), filename); | 87 | printf("%s==> %s <==\n", (first_file ? "" : "\n"), filename); |
86 | first_file = 0; | 88 | first_file = 0; |
87 | } | 89 | } |
88 | 90 | ||
89 | /* Print the last N_LINES lines from the end of file FD. | 91 | /* Print the last N_LINES lines from the end of file FD. |
@@ -97,57 +99,57 @@ static void write_header(const char *filename) | |||
97 | static int | 99 | static int |
98 | file_lines(const char *filename, int fd, long int n_lines, off_t pos) | 100 | file_lines(const char *filename, int fd, long int n_lines, off_t pos) |
99 | { | 101 | { |
100 | char buffer[BUFSIZ]; | 102 | char buffer[BUFSIZ]; |
101 | int bytes_read; | 103 | int bytes_read; |
102 | int i; /* Index into `buffer' for scanning. */ | 104 | int i; /* Index into `buffer' for scanning. */ |
103 | |||
104 | if (n_lines == 0) | ||
105 | return 0; | ||
106 | 105 | ||
107 | /* Set `bytes_read' to the size of the last, probably partial, buffer; | 106 | if (n_lines == 0) |
108 | 0 < `bytes_read' <= `BUFSIZ'. */ | ||
109 | bytes_read = pos % BUFSIZ; | ||
110 | if (bytes_read == 0) | ||
111 | bytes_read = BUFSIZ; | ||
112 | /* Make `pos' a multiple of `BUFSIZ' (0 if the file is short), so that all | ||
113 | reads will be on block boundaries, which might increase efficiency. */ | ||
114 | pos -= bytes_read; | ||
115 | lseek(fd, pos, SEEK_SET); | ||
116 | bytes_read = fullRead(fd, buffer, bytes_read); | ||
117 | if (bytes_read == -1) | ||
118 | error("read error"); | ||
119 | |||
120 | /* Count the incomplete line on files that don't end with a newline. */ | ||
121 | if (bytes_read && buffer[bytes_read - 1] != '\n') | ||
122 | --n_lines; | ||
123 | |||
124 | do { | ||
125 | /* Scan backward, counting the newlines in this bufferfull. */ | ||
126 | for (i = bytes_read - 1; i >= 0; i--) { | ||
127 | /* Have we counted the requested number of newlines yet? */ | ||
128 | if (buffer[i] == '\n' && n_lines-- == 0) { | ||
129 | /* If this newline wasn't the last character in the buffer, | ||
130 | print the text after it. */ | ||
131 | if (i != bytes_read - 1) | ||
132 | XWRITE(STDOUT_FILENO, &buffer[i + 1], | ||
133 | bytes_read - (i + 1)); | ||
134 | return 0; | 107 | return 0; |
135 | } | 108 | |
136 | } | 109 | /* Set `bytes_read' to the size of the last, probably partial, buffer; |
137 | /* Not enough newlines in that bufferfull. */ | 110 | 0 < `bytes_read' <= `BUFSIZ'. */ |
138 | if (pos == 0) { | 111 | bytes_read = pos % BUFSIZ; |
139 | /* Not enough lines in the file; print the entire file. */ | 112 | if (bytes_read == 0) |
140 | lseek(fd, (off_t) 0, SEEK_SET); | 113 | bytes_read = BUFSIZ; |
141 | return 0; | 114 | /* Make `pos' a multiple of `BUFSIZ' (0 if the file is short), so that all |
142 | } | 115 | reads will be on block boundaries, which might increase efficiency. */ |
143 | pos -= BUFSIZ; | 116 | pos -= bytes_read; |
144 | lseek(fd, pos, SEEK_SET); | 117 | lseek(fd, pos, SEEK_SET); |
145 | } | 118 | bytes_read = fullRead(fd, buffer, bytes_read); |
146 | while ((bytes_read = fullRead(fd, buffer, BUFSIZ)) > 0); | 119 | if (bytes_read == -1) |
147 | if (bytes_read == -1) | 120 | error("read error"); |
148 | error("read error"); | 121 | |
122 | /* Count the incomplete line on files that don't end with a newline. */ | ||
123 | if (bytes_read && buffer[bytes_read - 1] != '\n') | ||
124 | --n_lines; | ||
125 | |||
126 | do { | ||
127 | /* Scan backward, counting the newlines in this bufferfull. */ | ||
128 | for (i = bytes_read - 1; i >= 0; i--) { | ||
129 | /* Have we counted the requested number of newlines yet? */ | ||
130 | if (buffer[i] == '\n' && n_lines-- == 0) { | ||
131 | /* If this newline wasn't the last character in the buffer, | ||
132 | print the text after it. */ | ||
133 | if (i != bytes_read - 1) | ||
134 | XWRITE(STDOUT_FILENO, &buffer[i + 1], | ||
135 | bytes_read - (i + 1)); | ||
136 | return 0; | ||
137 | } | ||
138 | } | ||
139 | /* Not enough newlines in that bufferfull. */ | ||
140 | if (pos == 0) { | ||
141 | /* Not enough lines in the file; print the entire file. */ | ||
142 | lseek(fd, (off_t) 0, SEEK_SET); | ||
143 | return 0; | ||
144 | } | ||
145 | pos -= BUFSIZ; | ||
146 | lseek(fd, pos, SEEK_SET); | ||
147 | } | ||
148 | while ((bytes_read = fullRead(fd, buffer, BUFSIZ)) > 0); | ||
149 | if (bytes_read == -1) | ||
150 | error("read error"); | ||
149 | 151 | ||
150 | return 0; | 152 | return 0; |
151 | } | 153 | } |
152 | 154 | ||
153 | /* Print the last N_LINES lines from the end of the standard input, | 155 | /* Print the last N_LINES lines from the end of the standard input, |
@@ -157,100 +159,100 @@ file_lines(const char *filename, int fd, long int n_lines, off_t pos) | |||
157 | 159 | ||
158 | static int pipe_lines(const char *filename, int fd, long int n_lines) | 160 | static int pipe_lines(const char *filename, int fd, long int n_lines) |
159 | { | 161 | { |
160 | struct linebuffer { | 162 | struct linebuffer { |
161 | int nbytes, nlines; | 163 | int nbytes, nlines; |
162 | char buffer[BUFSIZ]; | 164 | char buffer[BUFSIZ]; |
163 | struct linebuffer *next; | 165 | struct linebuffer *next; |
164 | }; | 166 | }; |
165 | typedef struct linebuffer LBUFFER; | 167 | typedef struct linebuffer LBUFFER; |
166 | LBUFFER *first, *last, *tmp; | 168 | LBUFFER *first, *last, *tmp; |
167 | int i; /* Index into buffers. */ | 169 | int i; /* Index into buffers. */ |
168 | int total_lines = 0; /* Total number of newlines in all buffers. */ | 170 | int total_lines = 0; /* Total number of newlines in all buffers. */ |
169 | int errors = 0; | 171 | int errors = 0; |
170 | 172 | ||
171 | first = last = (LBUFFER *) xmalloc(sizeof(LBUFFER)); | 173 | first = last = (LBUFFER *) xmalloc(sizeof(LBUFFER)); |
172 | first->nbytes = first->nlines = 0; | 174 | first->nbytes = first->nlines = 0; |
173 | first->next = NULL; | 175 | first->next = NULL; |
174 | tmp = (LBUFFER *) xmalloc(sizeof(LBUFFER)); | 176 | tmp = (LBUFFER *) xmalloc(sizeof(LBUFFER)); |
175 | 177 | ||
176 | /* Input is always read into a fresh buffer. */ | 178 | /* Input is always read into a fresh buffer. */ |
177 | while ((tmp->nbytes = fullRead(fd, tmp->buffer, BUFSIZ)) > 0) { | 179 | while ((tmp->nbytes = fullRead(fd, tmp->buffer, BUFSIZ)) > 0) { |
178 | tmp->nlines = 0; | 180 | tmp->nlines = 0; |
179 | tmp->next = NULL; | 181 | tmp->next = NULL; |
180 | 182 | ||
181 | /* Count the number of newlines just read. */ | 183 | /* Count the number of newlines just read. */ |
182 | for (i = 0; i < tmp->nbytes; i++) | 184 | for (i = 0; i < tmp->nbytes; i++) |
183 | if (tmp->buffer[i] == '\n') | 185 | if (tmp->buffer[i] == '\n') |
184 | ++tmp->nlines; | 186 | ++tmp->nlines; |
185 | total_lines += tmp->nlines; | 187 | total_lines += tmp->nlines; |
186 | 188 | ||
187 | /* If there is enough room in the last buffer read, just append the new | 189 | /* If there is enough room in the last buffer read, just append the new |
188 | one to it. This is because when reading from a pipe, `nbytes' can | 190 | one to it. This is because when reading from a pipe, `nbytes' can |
189 | often be very small. */ | 191 | often be very small. */ |
190 | if (tmp->nbytes + last->nbytes < BUFSIZ) { | 192 | if (tmp->nbytes + last->nbytes < BUFSIZ) { |
191 | memcpy(&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes); | 193 | memcpy(&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes); |
192 | last->nbytes += tmp->nbytes; | 194 | last->nbytes += tmp->nbytes; |
193 | last->nlines += tmp->nlines; | 195 | last->nlines += tmp->nlines; |
194 | } else { | 196 | } else { |
195 | /* If there's not enough room, link the new buffer onto the end of | 197 | /* If there's not enough room, link the new buffer onto the end of |
196 | the list, then either free up the oldest buffer for the next | 198 | the list, then either free up the oldest buffer for the next |
197 | read if that would leave enough lines, or else malloc a new one. | 199 | read if that would leave enough lines, or else malloc a new one. |
198 | Some compaction mechanism is possible but probably not | 200 | Some compaction mechanism is possible but probably not |
199 | worthwhile. */ | 201 | worthwhile. */ |
200 | last = last->next = tmp; | 202 | last = last->next = tmp; |
201 | if (total_lines - first->nlines > n_lines) { | 203 | if (total_lines - first->nlines > n_lines) { |
202 | tmp = first; | 204 | tmp = first; |
203 | total_lines -= first->nlines; | 205 | total_lines -= first->nlines; |
204 | first = first->next; | 206 | first = first->next; |
205 | } else | 207 | } else |
206 | tmp = (LBUFFER *) xmalloc(sizeof(LBUFFER)); | 208 | tmp = (LBUFFER *) xmalloc(sizeof(LBUFFER)); |
209 | } | ||
207 | } | 210 | } |
208 | } | 211 | if (tmp->nbytes == -1) |
209 | if (tmp->nbytes == -1) | 212 | error("read error"); |
210 | error("read error"); | 213 | |
211 | 214 | free((char *) tmp); | |
212 | free((char *) tmp); | 215 | |
213 | 216 | /* This prevents a core dump when the pipe contains no newlines. */ | |
214 | /* This prevents a core dump when the pipe contains no newlines. */ | 217 | if (n_lines == 0) |
215 | if (n_lines == 0) | 218 | goto free_lbuffers; |
216 | goto free_lbuffers; | 219 | |
217 | 220 | /* Count the incomplete line on files that don't end with a newline. */ | |
218 | /* Count the incomplete line on files that don't end with a newline. */ | 221 | if (last->buffer[last->nbytes - 1] != '\n') { |
219 | if (last->buffer[last->nbytes - 1] != '\n') { | 222 | ++last->nlines; |
220 | ++last->nlines; | 223 | ++total_lines; |
221 | ++total_lines; | 224 | } |
222 | } | 225 | |
223 | 226 | /* Run through the list, printing lines. First, skip over unneeded | |
224 | /* Run through the list, printing lines. First, skip over unneeded | 227 | buffers. */ |
225 | buffers. */ | 228 | for (tmp = first; total_lines - tmp->nlines > n_lines; tmp = tmp->next) |
226 | for (tmp = first; total_lines - tmp->nlines > n_lines; tmp = tmp->next) | 229 | total_lines -= tmp->nlines; |
227 | total_lines -= tmp->nlines; | 230 | |
228 | 231 | /* Find the correct beginning, then print the rest of the file. */ | |
229 | /* Find the correct beginning, then print the rest of the file. */ | 232 | if (total_lines > n_lines) { |
230 | if (total_lines > n_lines) { | 233 | char *cp; |
231 | char *cp; | 234 | |
232 | 235 | /* Skip `total_lines' - `n_lines' newlines. We made sure that | |
233 | /* Skip `total_lines' - `n_lines' newlines. We made sure that | 236 | `total_lines' - `n_lines' <= `tmp->nlines'. */ |
234 | `total_lines' - `n_lines' <= `tmp->nlines'. */ | 237 | cp = tmp->buffer; |
235 | cp = tmp->buffer; | 238 | for (i = total_lines - n_lines; i; --i) |
236 | for (i = total_lines - n_lines; i; --i) | 239 | while (*cp++ != '\n') |
237 | while (*cp++ != '\n') | 240 | /* Do nothing. */ ; |
238 | /* Do nothing. */ ; | 241 | i = cp - tmp->buffer; |
239 | i = cp - tmp->buffer; | 242 | } else |
240 | } else | 243 | i = 0; |
241 | i = 0; | 244 | XWRITE(STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i); |
242 | XWRITE(STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i); | 245 | |
243 | 246 | for (tmp = tmp->next; tmp; tmp = tmp->next) | |
244 | for (tmp = tmp->next; tmp; tmp = tmp->next) | 247 | XWRITE(STDOUT_FILENO, tmp->buffer, tmp->nbytes); |
245 | XWRITE(STDOUT_FILENO, tmp->buffer, tmp->nbytes); | ||
246 | 248 | ||
247 | free_lbuffers: | 249 | free_lbuffers: |
248 | while (first) { | 250 | while (first) { |
249 | tmp = first->next; | 251 | tmp = first->next; |
250 | free((char *) first); | 252 | free((char *) first); |
251 | first = tmp; | 253 | first = tmp; |
252 | } | 254 | } |
253 | return errors; | 255 | return errors; |
254 | } | 256 | } |
255 | 257 | ||
256 | /* Display file FILENAME from the current position in FD to the end. | 258 | /* Display file FILENAME from the current position in FD to the end. |
@@ -259,25 +261,25 @@ static int pipe_lines(const char *filename, int fd, long int n_lines) | |||
259 | 261 | ||
260 | static long dump_remainder(const char *filename, int fd) | 262 | static long dump_remainder(const char *filename, int fd) |
261 | { | 263 | { |
262 | char buffer[BUFSIZ]; | 264 | char buffer[BUFSIZ]; |
263 | int bytes_read; | 265 | int bytes_read; |
264 | long total; | 266 | long total; |
265 | 267 | ||
266 | total = 0; | 268 | total = 0; |
267 | output: | 269 | output: |
268 | while ((bytes_read = fullRead(fd, buffer, BUFSIZ)) > 0) { | 270 | while ((bytes_read = fullRead(fd, buffer, BUFSIZ)) > 0) { |
269 | XWRITE(STDOUT_FILENO, buffer, bytes_read); | 271 | XWRITE(STDOUT_FILENO, buffer, bytes_read); |
270 | total += bytes_read; | 272 | total += bytes_read; |
271 | } | 273 | } |
272 | if (bytes_read == -1) | 274 | if (bytes_read == -1) |
273 | error("read error"); | 275 | error("read error"); |
274 | if (forever) { | 276 | if (forever) { |
275 | fflush(stdout); | 277 | fflush(stdout); |
276 | sleep(1); | 278 | sleep(1); |
277 | goto output; | 279 | goto output; |
278 | } | 280 | } |
279 | 281 | ||
280 | return total; | 282 | return total; |
281 | } | 283 | } |
282 | 284 | ||
283 | /* Output the last N_LINES lines of file FILENAME open for reading in FD. | 285 | /* Output the last N_LINES lines of file FILENAME open for reading in FD. |
@@ -285,31 +287,31 @@ static long dump_remainder(const char *filename, int fd) | |||
285 | 287 | ||
286 | static int tail_lines(const char *filename, int fd, long int n_lines) | 288 | static int tail_lines(const char *filename, int fd, long int n_lines) |
287 | { | 289 | { |
288 | struct stat stats; | 290 | struct stat stats; |
289 | off_t length; | 291 | off_t length; |
290 | 292 | ||
291 | if (print_headers) | 293 | if (print_headers) |
292 | write_header(filename); | 294 | write_header(filename); |
293 | 295 | ||
294 | if (fstat(fd, &stats)) | 296 | if (fstat(fd, &stats)) |
295 | error("fstat error"); | 297 | error("fstat error"); |
296 | 298 | ||
297 | /* Use file_lines only if FD refers to a regular file with | 299 | /* Use file_lines only if FD refers to a regular file with |
298 | its file pointer positioned at beginning of file. */ | 300 | its file pointer positioned at beginning of file. */ |
299 | /* FIXME: adding the lseek conjunct is a kludge. | 301 | /* FIXME: adding the lseek conjunct is a kludge. |
300 | Once there's a reasonable test suite, fix the true culprit: | 302 | Once there's a reasonable test suite, fix the true culprit: |
301 | file_lines. file_lines shouldn't presume that the input | 303 | file_lines. file_lines shouldn't presume that the input |
302 | file pointer is initially positioned to beginning of file. */ | 304 | file pointer is initially positioned to beginning of file. */ |
303 | if (S_ISREG(stats.st_mode) | 305 | if (S_ISREG(stats.st_mode) |
304 | && lseek(fd, (off_t) 0, SEEK_CUR) == (off_t) 0) { | 306 | && lseek(fd, (off_t) 0, SEEK_CUR) == (off_t) 0) { |
305 | length = lseek(fd, (off_t) 0, SEEK_END); | 307 | length = lseek(fd, (off_t) 0, SEEK_END); |
306 | if (length != 0 && file_lines(filename, fd, n_lines, length)) | 308 | if (length != 0 && file_lines(filename, fd, n_lines, length)) |
307 | return 1; | 309 | return 1; |
308 | dump_remainder(filename, fd); | 310 | dump_remainder(filename, fd); |
309 | } else | 311 | } else |
310 | return pipe_lines(filename, fd, n_lines); | 312 | return pipe_lines(filename, fd, n_lines); |
311 | 313 | ||
312 | return 0; | 314 | return 0; |
313 | } | 315 | } |
314 | 316 | ||
315 | /* Display the last N_UNITS lines of file FILENAME. | 317 | /* Display the last N_UNITS lines of file FILENAME. |
@@ -318,78 +320,78 @@ static int tail_lines(const char *filename, int fd, long int n_lines) | |||
318 | 320 | ||
319 | static int tail_file(const char *filename, off_t n_units) | 321 | static int tail_file(const char *filename, off_t n_units) |
320 | { | 322 | { |
321 | int fd, errors; | 323 | int fd, errors; |
322 | 324 | ||
323 | if (!strcmp(filename, "-")) { | 325 | if (!strcmp(filename, "-")) { |
324 | filename = "standard input"; | 326 | filename = "standard input"; |
325 | errors = tail_lines(filename, 0, (long) n_units); | 327 | errors = tail_lines(filename, 0, (long) n_units); |
326 | } else { | 328 | } else { |
327 | /* Not standard input. */ | 329 | /* Not standard input. */ |
328 | fd = open(filename, O_RDONLY); | 330 | fd = open(filename, O_RDONLY); |
329 | if (fd == -1) | 331 | if (fd == -1) |
330 | error("open error"); | 332 | error("open error"); |
331 | 333 | ||
332 | errors = tail_lines(filename, fd, (long) n_units); | 334 | errors = tail_lines(filename, fd, (long) n_units); |
333 | close(fd); | 335 | close(fd); |
334 | } | 336 | } |
335 | 337 | ||
336 | return errors; | 338 | return errors; |
337 | } | 339 | } |
338 | 340 | ||
339 | extern int tail_main(int argc, char **argv) | 341 | extern int tail_main(int argc, char **argv) |
340 | { | 342 | { |
341 | int exit_status = 0; | 343 | int exit_status = 0; |
342 | int n_units = DEFAULT_N_LINES; | 344 | int n_units = DEFAULT_N_LINES; |
343 | int n_tmp, i; | 345 | int n_tmp, i; |
344 | char opt; | 346 | char opt; |
345 | 347 | ||
346 | forever = print_headers = 0; | 348 | forever = print_headers = 0; |
347 | 349 | ||
348 | /* parse argv[] */ | 350 | /* parse argv[] */ |
349 | for (i = 1; i < argc; i++) { | 351 | for (i = 1; i < argc; i++) { |
350 | if (argv[i][0] == '-') { | 352 | if (argv[i][0] == '-') { |
351 | opt = argv[i][1]; | 353 | opt = argv[i][1]; |
352 | switch (opt) { | 354 | switch (opt) { |
353 | case 'f': | 355 | case 'f': |
354 | forever = 1; | 356 | forever = 1; |
355 | break; | 357 | break; |
356 | case 'n': | 358 | case 'n': |
357 | n_tmp = 0; | 359 | n_tmp = 0; |
358 | if (++i < argc) | 360 | if (++i < argc) |
359 | n_tmp = atoi(argv[i]); | 361 | n_tmp = atoi(argv[i]); |
360 | if (n_tmp < 1) | 362 | if (n_tmp < 1) |
361 | usage(tail_usage); | 363 | usage(tail_usage); |
362 | n_units = n_tmp; | 364 | n_units = n_tmp; |
363 | break; | 365 | break; |
364 | case '-': | 366 | case '-': |
365 | case 'h': | 367 | case 'h': |
366 | usage(tail_usage); | 368 | usage(tail_usage); |
367 | default: | 369 | default: |
368 | fprintf(stderr, "tail: invalid option -- %c\n", opt); | 370 | fprintf(stderr, "tail: invalid option -- %c\n", opt); |
369 | usage(tail_usage); | 371 | usage(tail_usage); |
370 | } | 372 | } |
371 | } else { | 373 | } else { |
372 | break; | 374 | break; |
375 | } | ||
373 | } | 376 | } |
374 | } | ||
375 | 377 | ||
376 | if (i + 1 < argc) { | 378 | if (i + 1 < argc) { |
377 | if (forever) { | 379 | if (forever) { |
378 | fprintf(stderr, | 380 | fprintf(stderr, |
379 | "tail: option -f is invalid with multiple files\n"); | 381 | "tail: option -f is invalid with multiple files\n"); |
380 | usage(tail_usage); | 382 | usage(tail_usage); |
383 | } | ||
384 | print_headers = 1; | ||
381 | } | 385 | } |
382 | print_headers = 1; | ||
383 | } | ||
384 | 386 | ||
385 | if (i >= argc) { | 387 | if (i >= argc) { |
386 | exit_status |= tail_file("-", n_units); | 388 | exit_status |= tail_file("-", n_units); |
387 | } else { | 389 | } else { |
388 | for (; i < argc; i++) | 390 | for (; i < argc; i++) |
389 | exit_status |= tail_file(argv[i], n_units); | 391 | exit_status |= tail_file(argv[i], n_units); |
390 | } | 392 | } |
391 | 393 | ||
392 | exit(exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE); | 394 | exit(exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE); |
393 | } | 395 | } |
394 | 396 | ||
395 | 397 | ||
@@ -441,15 +443,15 @@ extern int tail_main(int argc, char **argv) | |||
441 | #define NDEBUG 1 | 443 | #define NDEBUG 1 |
442 | 444 | ||
443 | 445 | ||
444 | static void detailed_error(int i, int errnum, char* fmt, ...) | 446 | static void detailed_error(int i, int errnum, char *fmt, ...) |
445 | { | 447 | { |
446 | va_list arguments; | 448 | va_list arguments; |
447 | 449 | ||
448 | va_start(arguments, fmt); | 450 | va_start(arguments, fmt); |
449 | vfprintf(stderr, fmt, arguments); | 451 | vfprintf(stderr, fmt, arguments); |
450 | fprintf(stderr, "\n%s\n", strerror( errnum)); | 452 | fprintf(stderr, "\n%s\n", strerror(errnum)); |
451 | va_end(arguments); | 453 | va_end(arguments); |
452 | exit(i); | 454 | exit(i); |
453 | } | 455 | } |
454 | 456 | ||
455 | 457 | ||
@@ -494,9 +496,8 @@ static int from_start; | |||
494 | static int print_headers; | 496 | static int print_headers; |
495 | 497 | ||
496 | /* When to print the filename banners. */ | 498 | /* When to print the filename banners. */ |
497 | enum header_mode | 499 | enum header_mode { |
498 | { | 500 | multiple_files, always, never |
499 | multiple_files, always, never | ||
500 | }; | 501 | }; |
501 | 502 | ||
502 | /* The name this program was run with. */ | 503 | /* The name this program was run with. */ |
@@ -506,8 +507,7 @@ char *program_name; | |||
506 | static int have_read_stdin; | 507 | static int have_read_stdin; |
507 | 508 | ||
508 | 509 | ||
509 | static const char tail_usage[] = | 510 | static const char tail_usage[] = "tail [OPTION]... [FILE]...\n\ |
510 | "tail [OPTION]... [FILE]...\n\ | ||
511 | \n\ | 511 | \n\ |
512 | Print last 10 lines of each FILE to standard output.\n\ | 512 | Print last 10 lines of each FILE to standard output.\n\ |
513 | With more than one FILE, precede each with a header giving the file name.\n\ | 513 | With more than one FILE, precede each with a header giving the file name.\n\ |
@@ -524,15 +524,13 @@ If the first character of N (bytes or lines) is a `+', output begins with \n\ | |||
524 | the Nth item from the start of each file, otherwise, print the last N items\n\ | 524 | the Nth item from the start of each file, otherwise, print the last N items\n\ |
525 | in the file. N bytes may be suffixed by k (x1024), b (x512), or m (1024^2).\n\n"; | 525 | in the file. N bytes may be suffixed by k (x1024), b (x512), or m (1024^2).\n\n"; |
526 | 526 | ||
527 | static void | 527 | static void write_header(const char *filename, const char *comment) |
528 | write_header (const char *filename, const char *comment) | ||
529 | { | 528 | { |
530 | static int first_file = 1; | 529 | static int first_file = 1; |
531 | 530 | ||
532 | printf ("%s==> %s%s%s <==\n", (first_file ? "" : "\n"), filename, | 531 | printf("%s==> %s%s%s <==\n", (first_file ? "" : "\n"), filename, |
533 | (comment ? ": " : ""), | 532 | (comment ? ": " : ""), (comment ? comment : "")); |
534 | (comment ? comment : "")); | 533 | first_file = 0; |
535 | first_file = 0; | ||
536 | } | 534 | } |
537 | 535 | ||
538 | /* Print the last N_LINES lines from the end of file FD. | 536 | /* Print the last N_LINES lines from the end of file FD. |
@@ -544,67 +542,62 @@ write_header (const char *filename, const char *comment) | |||
544 | Return 0 if successful, 1 if an error occurred. */ | 542 | Return 0 if successful, 1 if an error occurred. */ |
545 | 543 | ||
546 | static int | 544 | static int |
547 | file_lines (const char *filename, int fd, long int n_lines, off_t pos) | 545 | file_lines(const char *filename, int fd, long int n_lines, off_t pos) |
548 | { | 546 | { |
549 | char buffer[BUFSIZ]; | 547 | char buffer[BUFSIZ]; |
550 | int bytes_read; | 548 | int bytes_read; |
551 | int i; /* Index into `buffer' for scanning. */ | 549 | int i; /* Index into `buffer' for scanning. */ |
552 | 550 | ||
553 | if (n_lines == 0) | 551 | if (n_lines == 0) |
554 | return 0; | 552 | return 0; |
555 | 553 | ||
556 | /* Set `bytes_read' to the size of the last, probably partial, buffer; | 554 | /* Set `bytes_read' to the size of the last, probably partial, buffer; |
557 | 0 < `bytes_read' <= `BUFSIZ'. */ | 555 | 0 < `bytes_read' <= `BUFSIZ'. */ |
558 | bytes_read = pos % BUFSIZ; | 556 | bytes_read = pos % BUFSIZ; |
559 | if (bytes_read == 0) | 557 | if (bytes_read == 0) |
560 | bytes_read = BUFSIZ; | 558 | bytes_read = BUFSIZ; |
561 | /* Make `pos' a multiple of `BUFSIZ' (0 if the file is short), so that all | 559 | /* Make `pos' a multiple of `BUFSIZ' (0 if the file is short), so that all |
562 | reads will be on block boundaries, which might increase efficiency. */ | 560 | reads will be on block boundaries, which might increase efficiency. */ |
563 | pos -= bytes_read; | 561 | pos -= bytes_read; |
564 | lseek (fd, pos, SEEK_SET); | 562 | lseek(fd, pos, SEEK_SET); |
565 | bytes_read = fullRead (fd, buffer, bytes_read); | 563 | bytes_read = fullRead(fd, buffer, bytes_read); |
566 | if (bytes_read == -1) | 564 | if (bytes_read == -1) { |
567 | { | 565 | detailed_error(0, errno, "%s", filename); |
568 | detailed_error (0, errno, "%s", filename); | 566 | return 1; |
569 | return 1; | 567 | } |
570 | } | 568 | |
571 | 569 | /* Count the incomplete line on files that don't end with a newline. */ | |
572 | /* Count the incomplete line on files that don't end with a newline. */ | 570 | if (bytes_read && buffer[bytes_read - 1] != '\n') |
573 | if (bytes_read && buffer[bytes_read - 1] != '\n') | 571 | --n_lines; |
574 | --n_lines; | 572 | |
575 | 573 | do { | |
576 | do | 574 | /* Scan backward, counting the newlines in this bufferfull. */ |
577 | { | 575 | for (i = bytes_read - 1; i >= 0; i--) { |
578 | /* Scan backward, counting the newlines in this bufferfull. */ | 576 | /* Have we counted the requested number of newlines yet? */ |
579 | for (i = bytes_read - 1; i >= 0; i--) | 577 | if (buffer[i] == '\n' && n_lines-- == 0) { |
580 | { | 578 | /* If this newline wasn't the last character in the buffer, |
581 | /* Have we counted the requested number of newlines yet? */ | 579 | print the text after it. */ |
582 | if (buffer[i] == '\n' && n_lines-- == 0) | 580 | if (i != bytes_read - 1) |
583 | { | 581 | XWRITE(STDOUT_FILENO, &buffer[i + 1], |
584 | /* If this newline wasn't the last character in the buffer, | 582 | bytes_read - (i + 1)); |
585 | print the text after it. */ | 583 | return 0; |
586 | if (i != bytes_read - 1) | 584 | } |
587 | XWRITE (STDOUT_FILENO, &buffer[i + 1], bytes_read - (i + 1)); | 585 | } |
588 | return 0; | 586 | /* Not enough newlines in that bufferfull. */ |
589 | } | 587 | if (pos == 0) { |
588 | /* Not enough lines in the file; print the entire file. */ | ||
589 | lseek(fd, (off_t) 0, SEEK_SET); | ||
590 | return 0; | ||
591 | } | ||
592 | pos -= BUFSIZ; | ||
593 | lseek(fd, pos, SEEK_SET); | ||
590 | } | 594 | } |
591 | /* Not enough newlines in that bufferfull. */ | 595 | while ((bytes_read = fullRead(fd, buffer, BUFSIZ)) > 0); |
592 | if (pos == 0) | 596 | if (bytes_read == -1) { |
593 | { | 597 | detailed_error(0, errno, "%s", filename); |
594 | /* Not enough lines in the file; print the entire file. */ | 598 | return 1; |
595 | lseek (fd, (off_t) 0, SEEK_SET); | ||
596 | return 0; | ||
597 | } | 599 | } |
598 | pos -= BUFSIZ; | 600 | return 0; |
599 | lseek (fd, pos, SEEK_SET); | ||
600 | } | ||
601 | while ((bytes_read = fullRead (fd, buffer, BUFSIZ)) > 0); | ||
602 | if (bytes_read == -1) | ||
603 | { | ||
604 | detailed_error (0, errno, "%s", filename); | ||
605 | return 1; | ||
606 | } | ||
607 | return 0; | ||
608 | } | 601 | } |
609 | 602 | ||
610 | /* Print the last N_LINES lines from the end of the standard input, | 603 | /* Print the last N_LINES lines from the end of the standard input, |
@@ -612,301 +605,264 @@ file_lines (const char *filename, int fd, long int n_lines, off_t pos) | |||
612 | Buffer the text as a linked list of LBUFFERs, adding them as needed. | 605 | Buffer the text as a linked list of LBUFFERs, adding them as needed. |
613 | Return 0 if successful, 1 if an error occured. */ | 606 | Return 0 if successful, 1 if an error occured. */ |
614 | 607 | ||
615 | static int | 608 | static int pipe_lines(const char *filename, int fd, long int n_lines) |
616 | pipe_lines (const char *filename, int fd, long int n_lines) | ||
617 | { | 609 | { |
618 | struct linebuffer | 610 | struct linebuffer { |
619 | { | 611 | int nbytes, nlines; |
620 | int nbytes, nlines; | 612 | char buffer[BUFSIZ]; |
621 | char buffer[BUFSIZ]; | 613 | struct linebuffer *next; |
622 | struct linebuffer *next; | 614 | }; |
623 | }; | 615 | typedef struct linebuffer LBUFFER; |
624 | typedef struct linebuffer LBUFFER; | 616 | LBUFFER *first, *last, *tmp; |
625 | LBUFFER *first, *last, *tmp; | 617 | int i; /* Index into buffers. */ |
626 | int i; /* Index into buffers. */ | 618 | int total_lines = 0; /* Total number of newlines in all buffers. */ |
627 | int total_lines = 0; /* Total number of newlines in all buffers. */ | 619 | int errors = 0; |
628 | int errors = 0; | 620 | |
629 | 621 | first = last = (LBUFFER *) xmalloc(sizeof(LBUFFER)); | |
630 | first = last = (LBUFFER *) xmalloc (sizeof (LBUFFER)); | 622 | first->nbytes = first->nlines = 0; |
631 | first->nbytes = first->nlines = 0; | 623 | first->next = NULL; |
632 | first->next = NULL; | 624 | tmp = (LBUFFER *) xmalloc(sizeof(LBUFFER)); |
633 | tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER)); | 625 | |
634 | 626 | /* Input is always read into a fresh buffer. */ | |
635 | /* Input is always read into a fresh buffer. */ | 627 | while ((tmp->nbytes = fullRead(fd, tmp->buffer, BUFSIZ)) > 0) { |
636 | while ((tmp->nbytes = fullRead (fd, tmp->buffer, BUFSIZ)) > 0) | 628 | tmp->nlines = 0; |
637 | { | 629 | tmp->next = NULL; |
638 | tmp->nlines = 0; | 630 | |
639 | tmp->next = NULL; | 631 | /* Count the number of newlines just read. */ |
640 | 632 | for (i = 0; i < tmp->nbytes; i++) | |
641 | /* Count the number of newlines just read. */ | 633 | if (tmp->buffer[i] == '\n') |
642 | for (i = 0; i < tmp->nbytes; i++) | 634 | ++tmp->nlines; |
643 | if (tmp->buffer[i] == '\n') | 635 | total_lines += tmp->nlines; |
644 | ++tmp->nlines; | 636 | |
645 | total_lines += tmp->nlines; | 637 | /* If there is enough room in the last buffer read, just append the new |
646 | 638 | one to it. This is because when reading from a pipe, `nbytes' can | |
647 | /* If there is enough room in the last buffer read, just append the new | 639 | often be very small. */ |
648 | one to it. This is because when reading from a pipe, `nbytes' can | 640 | if (tmp->nbytes + last->nbytes < BUFSIZ) { |
649 | often be very small. */ | 641 | memcpy(&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes); |
650 | if (tmp->nbytes + last->nbytes < BUFSIZ) | 642 | last->nbytes += tmp->nbytes; |
651 | { | 643 | last->nlines += tmp->nlines; |
652 | memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes); | 644 | } else { |
653 | last->nbytes += tmp->nbytes; | 645 | /* If there's not enough room, link the new buffer onto the end of |
654 | last->nlines += tmp->nlines; | 646 | the list, then either free up the oldest buffer for the next |
647 | read if that would leave enough lines, or else malloc a new one. | ||
648 | Some compaction mechanism is possible but probably not | ||
649 | worthwhile. */ | ||
650 | last = last->next = tmp; | ||
651 | if (total_lines - first->nlines > n_lines) { | ||
652 | tmp = first; | ||
653 | total_lines -= first->nlines; | ||
654 | first = first->next; | ||
655 | } else | ||
656 | tmp = (LBUFFER *) xmalloc(sizeof(LBUFFER)); | ||
657 | } | ||
658 | } | ||
659 | if (tmp->nbytes == -1) { | ||
660 | detailed_error(0, errno, "%s", filename); | ||
661 | errors = 1; | ||
662 | free((char *) tmp); | ||
663 | goto free_lbuffers; | ||
655 | } | 664 | } |
656 | else | 665 | |
657 | { | 666 | free((char *) tmp); |
658 | /* If there's not enough room, link the new buffer onto the end of | 667 | |
659 | the list, then either free up the oldest buffer for the next | 668 | /* This prevents a core dump when the pipe contains no newlines. */ |
660 | read if that would leave enough lines, or else malloc a new one. | 669 | if (n_lines == 0) |
661 | Some compaction mechanism is possible but probably not | 670 | goto free_lbuffers; |
662 | worthwhile. */ | 671 | |
663 | last = last->next = tmp; | 672 | /* Count the incomplete line on files that don't end with a newline. */ |
664 | if (total_lines - first->nlines > n_lines) | 673 | if (last->buffer[last->nbytes - 1] != '\n') { |
665 | { | 674 | ++last->nlines; |
666 | tmp = first; | 675 | ++total_lines; |
667 | total_lines -= first->nlines; | 676 | } |
668 | first = first->next; | 677 | |
669 | } | 678 | /* Run through the list, printing lines. First, skip over unneeded |
670 | else | 679 | buffers. */ |
671 | tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER)); | 680 | for (tmp = first; total_lines - tmp->nlines > n_lines; tmp = tmp->next) |
681 | total_lines -= tmp->nlines; | ||
682 | |||
683 | /* Find the correct beginning, then print the rest of the file. */ | ||
684 | if (total_lines > n_lines) { | ||
685 | char *cp; | ||
686 | |||
687 | /* Skip `total_lines' - `n_lines' newlines. We made sure that | ||
688 | `total_lines' - `n_lines' <= `tmp->nlines'. */ | ||
689 | cp = tmp->buffer; | ||
690 | for (i = total_lines - n_lines; i; --i) | ||
691 | while (*cp++ != '\n') | ||
692 | /* Do nothing. */ ; | ||
693 | i = cp - tmp->buffer; | ||
694 | } else | ||
695 | i = 0; | ||
696 | XWRITE(STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i); | ||
697 | |||
698 | for (tmp = tmp->next; tmp; tmp = tmp->next) | ||
699 | XWRITE(STDOUT_FILENO, tmp->buffer, tmp->nbytes); | ||
700 | |||
701 | free_lbuffers: | ||
702 | while (first) { | ||
703 | tmp = first->next; | ||
704 | free((char *) first); | ||
705 | first = tmp; | ||
672 | } | 706 | } |
673 | } | 707 | return errors; |
674 | if (tmp->nbytes == -1) | ||
675 | { | ||
676 | detailed_error (0, errno, "%s", filename); | ||
677 | errors = 1; | ||
678 | free ((char *) tmp); | ||
679 | goto free_lbuffers; | ||
680 | } | ||
681 | |||
682 | free ((char *) tmp); | ||
683 | |||
684 | /* This prevents a core dump when the pipe contains no newlines. */ | ||
685 | if (n_lines == 0) | ||
686 | goto free_lbuffers; | ||
687 | |||
688 | /* Count the incomplete line on files that don't end with a newline. */ | ||
689 | if (last->buffer[last->nbytes - 1] != '\n') | ||
690 | { | ||
691 | ++last->nlines; | ||
692 | ++total_lines; | ||
693 | } | ||
694 | |||
695 | /* Run through the list, printing lines. First, skip over unneeded | ||
696 | buffers. */ | ||
697 | for (tmp = first; total_lines - tmp->nlines > n_lines; tmp = tmp->next) | ||
698 | total_lines -= tmp->nlines; | ||
699 | |||
700 | /* Find the correct beginning, then print the rest of the file. */ | ||
701 | if (total_lines > n_lines) | ||
702 | { | ||
703 | char *cp; | ||
704 | |||
705 | /* Skip `total_lines' - `n_lines' newlines. We made sure that | ||
706 | `total_lines' - `n_lines' <= `tmp->nlines'. */ | ||
707 | cp = tmp->buffer; | ||
708 | for (i = total_lines - n_lines; i; --i) | ||
709 | while (*cp++ != '\n') | ||
710 | /* Do nothing. */ ; | ||
711 | i = cp - tmp->buffer; | ||
712 | } | ||
713 | else | ||
714 | i = 0; | ||
715 | XWRITE (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i); | ||
716 | |||
717 | for (tmp = tmp->next; tmp; tmp = tmp->next) | ||
718 | XWRITE (STDOUT_FILENO, tmp->buffer, tmp->nbytes); | ||
719 | |||
720 | free_lbuffers: | ||
721 | while (first) | ||
722 | { | ||
723 | tmp = first->next; | ||
724 | free ((char *) first); | ||
725 | first = tmp; | ||
726 | } | ||
727 | return errors; | ||
728 | } | 708 | } |
729 | 709 | ||
730 | /* Print the last N_BYTES characters from the end of pipe FD. | 710 | /* Print the last N_BYTES characters from the end of pipe FD. |
731 | This is a stripped down version of pipe_lines. | 711 | This is a stripped down version of pipe_lines. |
732 | Return 0 if successful, 1 if an error occurred. */ | 712 | Return 0 if successful, 1 if an error occurred. */ |
733 | 713 | ||
734 | static int | 714 | static int pipe_bytes(const char *filename, int fd, off_t n_bytes) |
735 | pipe_bytes (const char *filename, int fd, off_t n_bytes) | ||
736 | { | 715 | { |
737 | struct charbuffer | 716 | struct charbuffer { |
738 | { | 717 | int nbytes; |
739 | int nbytes; | 718 | char buffer[BUFSIZ]; |
740 | char buffer[BUFSIZ]; | 719 | struct charbuffer *next; |
741 | struct charbuffer *next; | 720 | }; |
742 | }; | 721 | typedef struct charbuffer CBUFFER; |
743 | typedef struct charbuffer CBUFFER; | 722 | CBUFFER *first, *last, *tmp; |
744 | CBUFFER *first, *last, *tmp; | 723 | int i; /* Index into buffers. */ |
745 | int i; /* Index into buffers. */ | 724 | int total_bytes = 0; /* Total characters in all buffers. */ |
746 | int total_bytes = 0; /* Total characters in all buffers. */ | 725 | int errors = 0; |
747 | int errors = 0; | 726 | |
748 | 727 | first = last = (CBUFFER *) xmalloc(sizeof(CBUFFER)); | |
749 | first = last = (CBUFFER *) xmalloc (sizeof (CBUFFER)); | 728 | first->nbytes = 0; |
750 | first->nbytes = 0; | 729 | first->next = NULL; |
751 | first->next = NULL; | 730 | tmp = (CBUFFER *) xmalloc(sizeof(CBUFFER)); |
752 | tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER)); | 731 | |
753 | 732 | /* Input is always read into a fresh buffer. */ | |
754 | /* Input is always read into a fresh buffer. */ | 733 | while ((tmp->nbytes = fullRead(fd, tmp->buffer, BUFSIZ)) > 0) { |
755 | while ((tmp->nbytes = fullRead (fd, tmp->buffer, BUFSIZ)) > 0) | 734 | tmp->next = NULL; |
756 | { | 735 | |
757 | tmp->next = NULL; | 736 | total_bytes += tmp->nbytes; |
758 | 737 | /* If there is enough room in the last buffer read, just append the new | |
759 | total_bytes += tmp->nbytes; | 738 | one to it. This is because when reading from a pipe, `nbytes' can |
760 | /* If there is enough room in the last buffer read, just append the new | 739 | often be very small. */ |
761 | one to it. This is because when reading from a pipe, `nbytes' can | 740 | if (tmp->nbytes + last->nbytes < BUFSIZ) { |
762 | often be very small. */ | 741 | memcpy(&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes); |
763 | if (tmp->nbytes + last->nbytes < BUFSIZ) | 742 | last->nbytes += tmp->nbytes; |
764 | { | 743 | } else { |
765 | memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes); | 744 | /* If there's not enough room, link the new buffer onto the end of |
766 | last->nbytes += tmp->nbytes; | 745 | the list, then either free up the oldest buffer for the next |
746 | read if that would leave enough characters, or else malloc a new | ||
747 | one. Some compaction mechanism is possible but probably not | ||
748 | worthwhile. */ | ||
749 | last = last->next = tmp; | ||
750 | if (total_bytes - first->nbytes > n_bytes) { | ||
751 | tmp = first; | ||
752 | total_bytes -= first->nbytes; | ||
753 | first = first->next; | ||
754 | } else { | ||
755 | tmp = (CBUFFER *) xmalloc(sizeof(CBUFFER)); | ||
756 | } | ||
757 | } | ||
767 | } | 758 | } |
768 | else | 759 | if (tmp->nbytes == -1) { |
769 | { | 760 | detailed_error(0, errno, "%s", filename); |
770 | /* If there's not enough room, link the new buffer onto the end of | 761 | errors = 1; |
771 | the list, then either free up the oldest buffer for the next | 762 | free((char *) tmp); |
772 | read if that would leave enough characters, or else malloc a new | 763 | goto free_cbuffers; |
773 | one. Some compaction mechanism is possible but probably not | 764 | } |
774 | worthwhile. */ | 765 | |
775 | last = last->next = tmp; | 766 | free((char *) tmp); |
776 | if (total_bytes - first->nbytes > n_bytes) | 767 | |
777 | { | 768 | /* Run through the list, printing characters. First, skip over unneeded |
778 | tmp = first; | 769 | buffers. */ |
779 | total_bytes -= first->nbytes; | 770 | for (tmp = first; total_bytes - tmp->nbytes > n_bytes; tmp = tmp->next) |
780 | first = first->next; | 771 | total_bytes -= tmp->nbytes; |
781 | } | 772 | |
782 | else | 773 | /* Find the correct beginning, then print the rest of the file. |
783 | { | 774 | We made sure that `total_bytes' - `n_bytes' <= `tmp->nbytes'. */ |
784 | tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER)); | 775 | if (total_bytes > n_bytes) |
785 | } | 776 | i = total_bytes - n_bytes; |
777 | else | ||
778 | i = 0; | ||
779 | XWRITE(STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i); | ||
780 | |||
781 | for (tmp = tmp->next; tmp; tmp = tmp->next) | ||
782 | XWRITE(STDOUT_FILENO, tmp->buffer, tmp->nbytes); | ||
783 | |||
784 | free_cbuffers: | ||
785 | while (first) { | ||
786 | tmp = first->next; | ||
787 | free((char *) first); | ||
788 | first = tmp; | ||
786 | } | 789 | } |
787 | } | 790 | return errors; |
788 | if (tmp->nbytes == -1) | ||
789 | { | ||
790 | detailed_error (0, errno, "%s", filename); | ||
791 | errors = 1; | ||
792 | free ((char *) tmp); | ||
793 | goto free_cbuffers; | ||
794 | } | ||
795 | |||
796 | free ((char *) tmp); | ||
797 | |||
798 | /* Run through the list, printing characters. First, skip over unneeded | ||
799 | buffers. */ | ||
800 | for (tmp = first; total_bytes - tmp->nbytes > n_bytes; tmp = tmp->next) | ||
801 | total_bytes -= tmp->nbytes; | ||
802 | |||
803 | /* Find the correct beginning, then print the rest of the file. | ||
804 | We made sure that `total_bytes' - `n_bytes' <= `tmp->nbytes'. */ | ||
805 | if (total_bytes > n_bytes) | ||
806 | i = total_bytes - n_bytes; | ||
807 | else | ||
808 | i = 0; | ||
809 | XWRITE (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i); | ||
810 | |||
811 | for (tmp = tmp->next; tmp; tmp = tmp->next) | ||
812 | XWRITE (STDOUT_FILENO, tmp->buffer, tmp->nbytes); | ||
813 | |||
814 | free_cbuffers: | ||
815 | while (first) | ||
816 | { | ||
817 | tmp = first->next; | ||
818 | free ((char *) first); | ||
819 | first = tmp; | ||
820 | } | ||
821 | return errors; | ||
822 | } | 791 | } |
823 | 792 | ||
824 | /* Skip N_BYTES characters from the start of pipe FD, and print | 793 | /* Skip N_BYTES characters from the start of pipe FD, and print |
825 | any extra characters that were read beyond that. | 794 | any extra characters that were read beyond that. |
826 | Return 1 on error, 0 if ok. */ | 795 | Return 1 on error, 0 if ok. */ |
827 | 796 | ||
828 | static int | 797 | static int start_bytes(const char *filename, int fd, off_t n_bytes) |
829 | start_bytes (const char *filename, int fd, off_t n_bytes) | ||
830 | { | 798 | { |
831 | char buffer[BUFSIZ]; | 799 | char buffer[BUFSIZ]; |
832 | int bytes_read = 0; | 800 | int bytes_read = 0; |
833 | 801 | ||
834 | while (n_bytes > 0 && (bytes_read = fullRead (fd, buffer, BUFSIZ)) > 0) | 802 | while (n_bytes > 0 && (bytes_read = fullRead(fd, buffer, BUFSIZ)) > 0) |
835 | n_bytes -= bytes_read; | 803 | n_bytes -= bytes_read; |
836 | if (bytes_read == -1) | 804 | if (bytes_read == -1) { |
837 | { | 805 | detailed_error(0, errno, "%s", filename); |
838 | detailed_error (0, errno, "%s", filename); | 806 | return 1; |
839 | return 1; | 807 | } else if (n_bytes < 0) |
840 | } | 808 | XWRITE(STDOUT_FILENO, &buffer[bytes_read + n_bytes], -n_bytes); |
841 | else if (n_bytes < 0) | 809 | return 0; |
842 | XWRITE (STDOUT_FILENO, &buffer[bytes_read + n_bytes], -n_bytes); | ||
843 | return 0; | ||
844 | } | 810 | } |
845 | 811 | ||
846 | /* Skip N_LINES lines at the start of file or pipe FD, and print | 812 | /* Skip N_LINES lines at the start of file or pipe FD, and print |
847 | any extra characters that were read beyond that. | 813 | any extra characters that were read beyond that. |
848 | Return 1 on error, 0 if ok. */ | 814 | Return 1 on error, 0 if ok. */ |
849 | 815 | ||
850 | static int | 816 | static int start_lines(const char *filename, int fd, long int n_lines) |
851 | start_lines (const char *filename, int fd, long int n_lines) | ||
852 | { | 817 | { |
853 | char buffer[BUFSIZ]; | 818 | char buffer[BUFSIZ]; |
854 | int bytes_read = 0; | 819 | int bytes_read = 0; |
855 | int bytes_to_skip = 0; | 820 | int bytes_to_skip = 0; |
856 | 821 | ||
857 | while (n_lines && (bytes_read = fullRead (fd, buffer, BUFSIZ)) > 0) | 822 | while (n_lines && (bytes_read = fullRead(fd, buffer, BUFSIZ)) > 0) { |
858 | { | 823 | bytes_to_skip = 0; |
859 | bytes_to_skip = 0; | 824 | while (bytes_to_skip < bytes_read) |
860 | while (bytes_to_skip < bytes_read) | 825 | if (buffer[bytes_to_skip++] == '\n' && --n_lines == 0) |
861 | if (buffer[bytes_to_skip++] == '\n' && --n_lines == 0) | 826 | break; |
862 | break; | 827 | } |
863 | } | 828 | if (bytes_read == -1) { |
864 | if (bytes_read == -1) | 829 | detailed_error(0, errno, "%s", filename); |
865 | { | 830 | return 1; |
866 | detailed_error (0, errno, "%s", filename); | 831 | } else if (bytes_to_skip < bytes_read) { |
867 | return 1; | 832 | XWRITE(STDOUT_FILENO, &buffer[bytes_to_skip], |
868 | } | 833 | bytes_read - bytes_to_skip); |
869 | else if (bytes_to_skip < bytes_read) | 834 | } |
870 | { | 835 | return 0; |
871 | XWRITE (STDOUT_FILENO, &buffer[bytes_to_skip], | ||
872 | bytes_read - bytes_to_skip); | ||
873 | } | ||
874 | return 0; | ||
875 | } | 836 | } |
876 | 837 | ||
877 | /* Display file FILENAME from the current position in FD to the end. | 838 | /* Display file FILENAME from the current position in FD to the end. |
878 | If `forever' is nonzero, keep reading from the end of the file | 839 | If `forever' is nonzero, keep reading from the end of the file |
879 | until killed. Return the number of bytes read from the file. */ | 840 | until killed. Return the number of bytes read from the file. */ |
880 | 841 | ||
881 | static long | 842 | static long dump_remainder(const char *filename, int fd) |
882 | dump_remainder (const char *filename, int fd) | ||
883 | { | 843 | { |
884 | char buffer[BUFSIZ]; | 844 | char buffer[BUFSIZ]; |
885 | int bytes_read; | 845 | int bytes_read; |
886 | long total; | 846 | long total; |
887 | 847 | ||
888 | total = 0; | 848 | total = 0; |
889 | output: | 849 | output: |
890 | while ((bytes_read = fullRead (fd, buffer, BUFSIZ)) > 0) | 850 | while ((bytes_read = fullRead(fd, buffer, BUFSIZ)) > 0) { |
891 | { | 851 | XWRITE(STDOUT_FILENO, buffer, bytes_read); |
892 | XWRITE (STDOUT_FILENO, buffer, bytes_read); | 852 | total += bytes_read; |
893 | total += bytes_read; | 853 | } |
894 | } | 854 | if (bytes_read == -1) |
895 | if (bytes_read == -1) | 855 | detailed_error(EXIT_FAILURE, errno, "%s", filename); |
896 | detailed_error (EXIT_FAILURE, errno, "%s", filename); | 856 | if (forever) { |
897 | if (forever) | 857 | fflush(stdout); |
898 | { | 858 | sleep(1); |
899 | fflush (stdout); | 859 | goto output; |
900 | sleep (1); | 860 | } else { |
901 | goto output; | 861 | if (forever_multiple) |
902 | } | 862 | fflush(stdout); |
903 | else | 863 | } |
904 | { | 864 | |
905 | if (forever_multiple) | 865 | return total; |
906 | fflush (stdout); | ||
907 | } | ||
908 | |||
909 | return total; | ||
910 | } | 866 | } |
911 | 867 | ||
912 | /* Tail NFILES (>1) files forever until killed. The file names are in | 868 | /* Tail NFILES (>1) files forever until killed. The file names are in |
@@ -916,186 +872,161 @@ output: | |||
916 | none of them have changed size in one iteration, we sleep for a | 872 | none of them have changed size in one iteration, we sleep for a |
917 | second and try again. We do this until the user interrupts us. */ | 873 | second and try again. We do this until the user interrupts us. */ |
918 | 874 | ||
919 | static void | 875 | static void tail_forever(char **names, int nfiles) |
920 | tail_forever (char **names, int nfiles) | ||
921 | { | 876 | { |
922 | int last; | 877 | int last; |
923 | 878 | ||
924 | last = -1; | 879 | last = -1; |
925 | 880 | ||
926 | while (1) | 881 | while (1) { |
927 | { | 882 | int i; |
928 | int i; | 883 | int changed; |
929 | int changed; | 884 | |
930 | 885 | changed = 0; | |
931 | changed = 0; | 886 | for (i = 0; i < nfiles; i++) { |
932 | for (i = 0; i < nfiles; i++) | 887 | struct stat stats; |
933 | { | 888 | |
934 | struct stat stats; | 889 | if (file_descs[i] < 0) |
935 | 890 | continue; | |
936 | if (file_descs[i] < 0) | 891 | if (fstat(file_descs[i], &stats) < 0) { |
937 | continue; | 892 | detailed_error(0, errno, "%s", names[i]); |
938 | if (fstat (file_descs[i], &stats) < 0) | 893 | file_descs[i] = -1; |
939 | { | 894 | continue; |
940 | detailed_error (0, errno, "%s", names[i]); | 895 | } |
941 | file_descs[i] = -1; | 896 | if (stats.st_size == file_sizes[i]) |
942 | continue; | 897 | continue; |
943 | } | 898 | |
944 | if (stats.st_size == file_sizes[i]) | 899 | /* This file has changed size. Print out what we can, and |
945 | continue; | 900 | then keep looping. */ |
946 | 901 | ||
947 | /* This file has changed size. Print out what we can, and | 902 | changed = 1; |
948 | then keep looping. */ | 903 | |
949 | 904 | if (stats.st_size < file_sizes[i]) { | |
950 | changed = 1; | 905 | write_header(names[i], "file truncated"); |
951 | 906 | last = i; | |
952 | if (stats.st_size < file_sizes[i]) | 907 | lseek(file_descs[i], stats.st_size, SEEK_SET); |
953 | { | 908 | file_sizes[i] = stats.st_size; |
954 | write_header (names[i], "file truncated"); | 909 | continue; |
955 | last = i; | 910 | } |
956 | lseek (file_descs[i], stats.st_size, SEEK_SET); | 911 | |
957 | file_sizes[i] = stats.st_size; | 912 | if (i != last) { |
958 | continue; | 913 | if (print_headers) |
959 | } | 914 | write_header(names[i], NULL); |
960 | 915 | last = i; | |
961 | if (i != last) | 916 | } |
962 | { | 917 | file_sizes[i] += dump_remainder(names[i], file_descs[i]); |
963 | if (print_headers) | 918 | } |
964 | write_header (names[i], NULL); | ||
965 | last = i; | ||
966 | } | ||
967 | file_sizes[i] += dump_remainder (names[i], file_descs[i]); | ||
968 | } | ||
969 | 919 | ||
970 | /* If none of the files changed size, sleep. */ | 920 | /* If none of the files changed size, sleep. */ |
971 | if (! changed) | 921 | if (!changed) |
972 | sleep (1); | 922 | sleep(1); |
973 | } | 923 | } |
974 | } | 924 | } |
975 | 925 | ||
976 | /* Output the last N_BYTES bytes of file FILENAME open for reading in FD. | 926 | /* Output the last N_BYTES bytes of file FILENAME open for reading in FD. |
977 | Return 0 if successful, 1 if an error occurred. */ | 927 | Return 0 if successful, 1 if an error occurred. */ |
978 | 928 | ||
979 | static int | 929 | static int tail_bytes(const char *filename, int fd, off_t n_bytes) |
980 | tail_bytes (const char *filename, int fd, off_t n_bytes) | ||
981 | { | 930 | { |
982 | struct stat stats; | 931 | struct stat stats; |
983 | 932 | ||
984 | /* FIXME: resolve this like in dd.c. */ | 933 | /* FIXME: resolve this like in dd.c. */ |
985 | /* Use fstat instead of checking for errno == ESPIPE because | 934 | /* Use fstat instead of checking for errno == ESPIPE because |
986 | lseek doesn't work on some special files but doesn't return an | 935 | lseek doesn't work on some special files but doesn't return an |
987 | error, either. */ | 936 | error, either. */ |
988 | if (fstat (fd, &stats)) | 937 | if (fstat(fd, &stats)) { |
989 | { | 938 | detailed_error(0, errno, "%s", filename); |
990 | detailed_error (0, errno, "%s", filename); | 939 | return 1; |
991 | return 1; | 940 | } |
992 | } | 941 | |
993 | 942 | if (from_start) { | |
994 | if (from_start) | 943 | if (S_ISREG(stats.st_mode)) |
995 | { | 944 | lseek(fd, n_bytes, SEEK_CUR); |
996 | if (S_ISREG (stats.st_mode)) | 945 | else if (start_bytes(filename, fd, n_bytes)) |
997 | lseek (fd, n_bytes, SEEK_CUR); | 946 | return 1; |
998 | else if (start_bytes (filename, fd, n_bytes)) | 947 | dump_remainder(filename, fd); |
999 | return 1; | 948 | } else { |
1000 | dump_remainder (filename, fd); | 949 | if (S_ISREG(stats.st_mode)) { |
1001 | } | 950 | off_t current_pos, end_pos; |
1002 | else | 951 | size_t bytes_remaining; |
1003 | { | 952 | |
1004 | if (S_ISREG (stats.st_mode)) | 953 | if ((current_pos = lseek(fd, (off_t) 0, SEEK_CUR)) != -1 |
1005 | { | 954 | && (end_pos = lseek(fd, (off_t) 0, SEEK_END)) != -1) { |
1006 | off_t current_pos, end_pos; | 955 | off_t diff; |
1007 | size_t bytes_remaining; | 956 | |
1008 | 957 | /* Be careful here. The current position may actually be | |
1009 | if ((current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) != -1 | 958 | beyond the end of the file. */ |
1010 | && (end_pos = lseek (fd, (off_t) 0, SEEK_END)) != -1) | 959 | bytes_remaining = (diff = |
1011 | { | 960 | end_pos - current_pos) < 0 ? 0 : diff; |
1012 | off_t diff; | 961 | } else { |
1013 | /* Be careful here. The current position may actually be | 962 | detailed_error(0, errno, "%s", filename); |
1014 | beyond the end of the file. */ | 963 | return 1; |
1015 | bytes_remaining = (diff = end_pos - current_pos) < 0 ? 0 : diff; | 964 | } |
1016 | } | 965 | |
1017 | else | 966 | if (bytes_remaining <= n_bytes) { |
1018 | { | 967 | /* From the current position to end of file, there are no |
1019 | detailed_error (0, errno, "%s", filename); | 968 | more bytes than have been requested. So reposition the |
1020 | return 1; | 969 | file pointer to the incoming current position and print |
1021 | } | 970 | everything after that. */ |
1022 | 971 | lseek(fd, current_pos, SEEK_SET); | |
1023 | if (bytes_remaining <= n_bytes) | 972 | } else { |
1024 | { | 973 | /* There are more bytes remaining than were requested. |
1025 | /* From the current position to end of file, there are no | 974 | Back up. */ |
1026 | more bytes than have been requested. So reposition the | 975 | lseek(fd, -n_bytes, SEEK_END); |
1027 | file pointer to the incoming current position and print | 976 | } |
1028 | everything after that. */ | 977 | dump_remainder(filename, fd); |
1029 | lseek (fd, current_pos, SEEK_SET); | 978 | } else |
1030 | } | 979 | return pipe_bytes(filename, fd, n_bytes); |
1031 | else | ||
1032 | { | ||
1033 | /* There are more bytes remaining than were requested. | ||
1034 | Back up. */ | ||
1035 | lseek (fd, -n_bytes, SEEK_END); | ||
1036 | } | ||
1037 | dump_remainder (filename, fd); | ||
1038 | } | 980 | } |
1039 | else | 981 | return 0; |
1040 | return pipe_bytes (filename, fd, n_bytes); | ||
1041 | } | ||
1042 | return 0; | ||
1043 | } | 982 | } |
1044 | 983 | ||
1045 | /* Output the last N_LINES lines of file FILENAME open for reading in FD. | 984 | /* Output the last N_LINES lines of file FILENAME open for reading in FD. |
1046 | Return 0 if successful, 1 if an error occurred. */ | 985 | Return 0 if successful, 1 if an error occurred. */ |
1047 | 986 | ||
1048 | static int | 987 | static int tail_lines(const char *filename, int fd, long int n_lines) |
1049 | tail_lines (const char *filename, int fd, long int n_lines) | ||
1050 | { | 988 | { |
1051 | struct stat stats; | 989 | struct stat stats; |
1052 | off_t length; | 990 | off_t length; |
1053 | 991 | ||
1054 | if (fstat (fd, &stats)) | 992 | if (fstat(fd, &stats)) { |
1055 | { | 993 | detailed_error(0, errno, "%s", filename); |
1056 | detailed_error (0, errno, "%s", filename); | 994 | return 1; |
1057 | return 1; | 995 | } |
1058 | } | 996 | |
1059 | 997 | if (from_start) { | |
1060 | if (from_start) | 998 | if (start_lines(filename, fd, n_lines)) |
1061 | { | 999 | return 1; |
1062 | if (start_lines (filename, fd, n_lines)) | 1000 | dump_remainder(filename, fd); |
1063 | return 1; | 1001 | } else { |
1064 | dump_remainder (filename, fd); | 1002 | /* Use file_lines only if FD refers to a regular file with |
1065 | } | 1003 | its file pointer positioned at beginning of file. */ |
1066 | else | 1004 | /* FIXME: adding the lseek conjunct is a kludge. |
1067 | { | 1005 | Once there's a reasonable test suite, fix the true culprit: |
1068 | /* Use file_lines only if FD refers to a regular file with | 1006 | file_lines. file_lines shouldn't presume that the input |
1069 | its file pointer positioned at beginning of file. */ | 1007 | file pointer is initially positioned to beginning of file. */ |
1070 | /* FIXME: adding the lseek conjunct is a kludge. | 1008 | if (S_ISREG(stats.st_mode) |
1071 | Once there's a reasonable test suite, fix the true culprit: | 1009 | && lseek(fd, (off_t) 0, SEEK_CUR) == (off_t) 0) { |
1072 | file_lines. file_lines shouldn't presume that the input | 1010 | length = lseek(fd, (off_t) 0, SEEK_END); |
1073 | file pointer is initially positioned to beginning of file. */ | 1011 | if (length != 0 && file_lines(filename, fd, n_lines, length)) |
1074 | if (S_ISREG (stats.st_mode) | 1012 | return 1; |
1075 | && lseek (fd, (off_t) 0, SEEK_CUR) == (off_t) 0) | 1013 | dump_remainder(filename, fd); |
1076 | { | 1014 | } else |
1077 | length = lseek (fd, (off_t) 0, SEEK_END); | 1015 | return pipe_lines(filename, fd, n_lines); |
1078 | if (length != 0 && file_lines (filename, fd, n_lines, length)) | ||
1079 | return 1; | ||
1080 | dump_remainder (filename, fd); | ||
1081 | } | 1016 | } |
1082 | else | 1017 | return 0; |
1083 | return pipe_lines (filename, fd, n_lines); | ||
1084 | } | ||
1085 | return 0; | ||
1086 | } | 1018 | } |
1087 | 1019 | ||
1088 | /* Display the last N_UNITS units of file FILENAME, open for reading | 1020 | /* Display the last N_UNITS units of file FILENAME, open for reading |
1089 | in FD. | 1021 | in FD. |
1090 | Return 0 if successful, 1 if an error occurred. */ | 1022 | Return 0 if successful, 1 if an error occurred. */ |
1091 | 1023 | ||
1092 | static int | 1024 | static int tail(const char *filename, int fd, off_t n_units) |
1093 | tail (const char *filename, int fd, off_t n_units) | ||
1094 | { | 1025 | { |
1095 | if (count_lines) | 1026 | if (count_lines) |
1096 | return tail_lines (filename, fd, (long) n_units); | 1027 | return tail_lines(filename, fd, (long) n_units); |
1097 | else | 1028 | else |
1098 | return tail_bytes (filename, fd, n_units); | 1029 | return tail_bytes(filename, fd, n_units); |
1099 | } | 1030 | } |
1100 | 1031 | ||
1101 | /* Display the last N_UNITS units of file FILENAME. | 1032 | /* Display the last N_UNITS units of file FILENAME. |
@@ -1103,207 +1034,183 @@ tail (const char *filename, int fd, off_t n_units) | |||
1103 | FILENUM is this file's index in the list of files the user gave. | 1034 | FILENUM is this file's index in the list of files the user gave. |
1104 | Return 0 if successful, 1 if an error occurred. */ | 1035 | Return 0 if successful, 1 if an error occurred. */ |
1105 | 1036 | ||
1106 | static int | 1037 | static int tail_file(const char *filename, off_t n_units, int filenum) |
1107 | tail_file (const char *filename, off_t n_units, int filenum) | ||
1108 | { | 1038 | { |
1109 | int fd, errors; | 1039 | int fd, errors; |
1110 | struct stat stats; | 1040 | struct stat stats; |
1111 | 1041 | ||
1112 | if (!strcmp (filename, "-")) | 1042 | if (!strcmp(filename, "-")) { |
1113 | { | 1043 | have_read_stdin = 1; |
1114 | have_read_stdin = 1; | 1044 | filename = "standard input"; |
1115 | filename = "standard input"; | 1045 | if (print_headers) |
1116 | if (print_headers) | 1046 | write_header(filename, NULL); |
1117 | write_header (filename, NULL); | 1047 | errors = tail(filename, 0, n_units); |
1118 | errors = tail (filename, 0, n_units); | 1048 | if (forever_multiple) { |
1119 | if (forever_multiple) | 1049 | if (fstat(0, &stats) < 0) { |
1120 | { | 1050 | detailed_error(0, errno, "standard input"); |
1121 | if (fstat (0, &stats) < 0) | 1051 | errors = 1; |
1122 | { | 1052 | } else if (!S_ISREG(stats.st_mode)) { |
1123 | detailed_error (0, errno, "standard input"); | 1053 | detailed_error(0, 0, |
1124 | errors = 1; | 1054 | "standard input: cannot follow end of non-regular file"); |
1125 | } | 1055 | errors = 1; |
1126 | else if (!S_ISREG (stats.st_mode)) | 1056 | } |
1127 | { | 1057 | if (errors) |
1128 | detailed_error (0, 0, | 1058 | file_descs[filenum] = -1; |
1129 | "standard input: cannot follow end of non-regular file"); | 1059 | else { |
1130 | errors = 1; | 1060 | file_descs[filenum] = 0; |
1131 | } | 1061 | file_sizes[filenum] = stats.st_size; |
1132 | if (errors) | 1062 | } |
1133 | file_descs[filenum] = -1; | ||
1134 | else | ||
1135 | { | ||
1136 | file_descs[filenum] = 0; | ||
1137 | file_sizes[filenum] = stats.st_size; | ||
1138 | } | ||
1139 | } | ||
1140 | } | ||
1141 | else | ||
1142 | { | ||
1143 | /* Not standard input. */ | ||
1144 | fd = open (filename, O_RDONLY); | ||
1145 | if (fd == -1) | ||
1146 | { | ||
1147 | if (forever_multiple) | ||
1148 | file_descs[filenum] = -1; | ||
1149 | detailed_error (0, errno, "%s", filename); | ||
1150 | errors = 1; | ||
1151 | } | ||
1152 | else | ||
1153 | { | ||
1154 | if (print_headers) | ||
1155 | write_header (filename, NULL); | ||
1156 | errors = tail (filename, fd, n_units); | ||
1157 | if (forever_multiple) | ||
1158 | { | ||
1159 | if (fstat (fd, &stats) < 0) | ||
1160 | { | ||
1161 | detailed_error (0, errno, "%s", filename); | ||
1162 | errors = 1; | ||
1163 | } | ||
1164 | else if (!S_ISREG (stats.st_mode)) | ||
1165 | { | ||
1166 | detailed_error (0, 0, "%s: cannot follow end of non-regular file", | ||
1167 | filename); | ||
1168 | errors = 1; | ||
1169 | } | ||
1170 | if (errors) | ||
1171 | { | ||
1172 | close (fd); | ||
1173 | file_descs[filenum] = -1; | ||
1174 | } | ||
1175 | else | ||
1176 | { | ||
1177 | file_descs[filenum] = fd; | ||
1178 | file_sizes[filenum] = stats.st_size; | ||
1179 | } | 1063 | } |
1180 | } | 1064 | } else { |
1181 | else | 1065 | /* Not standard input. */ |
1182 | { | 1066 | fd = open(filename, O_RDONLY); |
1183 | if (close (fd)) | 1067 | if (fd == -1) { |
1184 | { | 1068 | if (forever_multiple) |
1185 | detailed_error (0, errno, "%s", filename); | 1069 | file_descs[filenum] = -1; |
1186 | errors = 1; | 1070 | detailed_error(0, errno, "%s", filename); |
1071 | errors = 1; | ||
1072 | } else { | ||
1073 | if (print_headers) | ||
1074 | write_header(filename, NULL); | ||
1075 | errors = tail(filename, fd, n_units); | ||
1076 | if (forever_multiple) { | ||
1077 | if (fstat(fd, &stats) < 0) { | ||
1078 | detailed_error(0, errno, "%s", filename); | ||
1079 | errors = 1; | ||
1080 | } else if (!S_ISREG(stats.st_mode)) { | ||
1081 | detailed_error(0, 0, | ||
1082 | "%s: cannot follow end of non-regular file", | ||
1083 | filename); | ||
1084 | errors = 1; | ||
1085 | } | ||
1086 | if (errors) { | ||
1087 | close(fd); | ||
1088 | file_descs[filenum] = -1; | ||
1089 | } else { | ||
1090 | file_descs[filenum] = fd; | ||
1091 | file_sizes[filenum] = stats.st_size; | ||
1092 | } | ||
1093 | } else { | ||
1094 | if (close(fd)) { | ||
1095 | detailed_error(0, errno, "%s", filename); | ||
1096 | errors = 1; | ||
1097 | } | ||
1098 | } | ||
1187 | } | 1099 | } |
1188 | } | ||
1189 | } | 1100 | } |
1190 | } | ||
1191 | 1101 | ||
1192 | return errors; | 1102 | return errors; |
1193 | } | 1103 | } |
1194 | 1104 | ||
1195 | extern int | 1105 | extern int tail_main(int argc, char **argv) |
1196 | tail_main (int argc, char **argv) | ||
1197 | { | 1106 | { |
1198 | int stopit = 0; | 1107 | int stopit = 0; |
1199 | enum header_mode header_mode = multiple_files; | 1108 | enum header_mode header_mode = multiple_files; |
1200 | int exit_status = 0; | 1109 | int exit_status = 0; |
1201 | /* If from_start, the number of items to skip before printing; otherwise, | 1110 | |
1202 | the number of items at the end of the file to print. Initially, -1 | 1111 | /* If from_start, the number of items to skip before printing; otherwise, |
1203 | means the value has not been set. */ | 1112 | the number of items at the end of the file to print. Initially, -1 |
1204 | off_t n_units = -1; | 1113 | means the value has not been set. */ |
1205 | int n_files; | 1114 | off_t n_units = -1; |
1206 | char **file; | 1115 | int n_files; |
1207 | 1116 | char **file; | |
1208 | program_name = argv[0]; | 1117 | |
1209 | have_read_stdin = 0; | 1118 | program_name = argv[0]; |
1210 | count_lines = 1; | 1119 | have_read_stdin = 0; |
1211 | forever = forever_multiple = from_start = print_headers = 0; | 1120 | count_lines = 1; |
1212 | 1121 | forever = forever_multiple = from_start = print_headers = 0; | |
1213 | /* Parse any options */ | 1122 | |
1214 | //fprintf(stderr, "argc=%d, argv=%s\n", argc, *argv); | 1123 | /* Parse any options */ |
1215 | while (--argc > 0 && ( **(++argv) == '-' || **argv == '+' )) { | 1124 | //fprintf(stderr, "argc=%d, argv=%s\n", argc, *argv); |
1216 | if (**argv == '+') { | 1125 | while (--argc > 0 && (**(++argv) == '-' || **argv == '+')) { |
1217 | from_start = 1; | 1126 | if (**argv == '+') { |
1127 | from_start = 1; | ||
1128 | } | ||
1129 | stopit = 0; | ||
1130 | while (stopit == 0 && *(++(*argv))) { | ||
1131 | switch (**argv) { | ||
1132 | case 'c': | ||
1133 | count_lines = 0; | ||
1134 | |||
1135 | if (--argc < 1) { | ||
1136 | usage(tail_usage); | ||
1137 | } | ||
1138 | n_units = getNum(*(++argv)); | ||
1139 | stopit = 1; | ||
1140 | break; | ||
1141 | |||
1142 | case 'f': | ||
1143 | forever = 1; | ||
1144 | break; | ||
1145 | |||
1146 | case 'n': | ||
1147 | count_lines = 1; | ||
1148 | |||
1149 | if (--argc < 1) { | ||
1150 | usage(tail_usage); | ||
1151 | } | ||
1152 | n_units = atol(*(++argv)); | ||
1153 | stopit = 1; | ||
1154 | break; | ||
1155 | |||
1156 | case 'q': | ||
1157 | header_mode = never; | ||
1158 | break; | ||
1159 | |||
1160 | case 'v': | ||
1161 | header_mode = always; | ||
1162 | break; | ||
1163 | |||
1164 | default: | ||
1165 | usage(tail_usage); | ||
1166 | } | ||
1167 | } | ||
1168 | } | ||
1169 | |||
1170 | |||
1171 | if (n_units == -1) | ||
1172 | n_units = DEFAULT_N_LINES; | ||
1173 | |||
1174 | /* To start printing with item N_UNITS from the start of the file, skip | ||
1175 | N_UNITS - 1 items. `tail +0' is actually meaningless, but for Unix | ||
1176 | compatibility it's treated the same as `tail +1'. */ | ||
1177 | if (from_start) { | ||
1178 | if (n_units) | ||
1179 | --n_units; | ||
1218 | } | 1180 | } |
1219 | stopit = 0; | 1181 | |
1220 | while (stopit == 0 && *(++(*argv))) { | 1182 | n_files = argc; |
1221 | switch (**argv) { | 1183 | file = argv; |
1222 | case 'c': | 1184 | |
1223 | count_lines = 0; | 1185 | if (n_files > 1 && forever) { |
1224 | 1186 | forever_multiple = 1; | |
1225 | if (--argc < 1) { | 1187 | forever = 0; |
1226 | usage(tail_usage); | 1188 | file_descs = (int *) xmalloc(n_files * sizeof(int)); |
1227 | } | 1189 | |
1228 | n_units = getNum(*(++argv)); | 1190 | file_sizes = (off_t *) xmalloc(n_files * sizeof(off_t)); |
1229 | stopit = 1; | ||
1230 | break; | ||
1231 | |||
1232 | case 'f': | ||
1233 | forever = 1; | ||
1234 | break; | ||
1235 | |||
1236 | case 'n': | ||
1237 | count_lines = 1; | ||
1238 | |||
1239 | if (--argc < 1) { | ||
1240 | usage(tail_usage); | ||
1241 | } | ||
1242 | n_units = atol(*(++argv)); | ||
1243 | stopit = 1; | ||
1244 | break; | ||
1245 | |||
1246 | case 'q': | ||
1247 | header_mode = never; | ||
1248 | break; | ||
1249 | |||
1250 | case 'v': | ||
1251 | header_mode = always; | ||
1252 | break; | ||
1253 | |||
1254 | default: | ||
1255 | usage (tail_usage); | ||
1256 | } | ||
1257 | } | 1191 | } |
1258 | } | 1192 | |
1259 | 1193 | if (header_mode == always | |
1260 | 1194 | || (header_mode == multiple_files && n_files > 1)) | |
1261 | if (n_units == -1) | 1195 | print_headers = 1; |
1262 | n_units = DEFAULT_N_LINES; | 1196 | |
1263 | 1197 | if (n_files == 0) { | |
1264 | /* To start printing with item N_UNITS from the start of the file, skip | 1198 | exit_status |= tail_file("-", n_units, 0); |
1265 | N_UNITS - 1 items. `tail +0' is actually meaningless, but for Unix | 1199 | } else { |
1266 | compatibility it's treated the same as `tail +1'. */ | 1200 | int i; |
1267 | if (from_start) | 1201 | |
1268 | { | 1202 | for (i = 0; i < n_files; i++) |
1269 | if (n_units) | 1203 | exit_status |= tail_file(file[i], n_units, i); |
1270 | --n_units; | 1204 | |
1271 | } | 1205 | if (forever_multiple) |
1272 | 1206 | tail_forever(file, n_files); | |
1273 | n_files = argc; | 1207 | } |
1274 | file = argv; | 1208 | |
1275 | 1209 | if (have_read_stdin && close(0) < 0) | |
1276 | if (n_files > 1 && forever) | 1210 | detailed_error(EXIT_FAILURE, errno, "-"); |
1277 | { | 1211 | if (fclose(stdout) == EOF) |
1278 | forever_multiple = 1; | 1212 | detailed_error(EXIT_FAILURE, errno, "write error"); |
1279 | forever = 0; | 1213 | exit(exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE); |
1280 | file_descs = (int *) xmalloc (n_files * sizeof (int)); | ||
1281 | file_sizes = (off_t *) xmalloc (n_files * sizeof (off_t)); | ||
1282 | } | ||
1283 | |||
1284 | if (header_mode == always | ||
1285 | || (header_mode == multiple_files && n_files > 1)) | ||
1286 | print_headers = 1; | ||
1287 | |||
1288 | if (n_files == 0) | ||
1289 | { | ||
1290 | exit_status |= tail_file ("-", n_units, 0); | ||
1291 | } | ||
1292 | else | ||
1293 | { | ||
1294 | int i; | ||
1295 | for (i = 0; i < n_files; i++) | ||
1296 | exit_status |= tail_file (file[i], n_units, i); | ||
1297 | |||
1298 | if (forever_multiple) | ||
1299 | tail_forever (file, n_files); | ||
1300 | } | ||
1301 | |||
1302 | if (have_read_stdin && close (0) < 0) | ||
1303 | detailed_error (EXIT_FAILURE, errno, "-"); | ||
1304 | if (fclose (stdout) == EOF) | ||
1305 | detailed_error (EXIT_FAILURE, errno, "write error"); | ||
1306 | exit (exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE); | ||
1307 | } | 1214 | } |
1308 | 1215 | ||
1309 | 1216 | ||
diff --git a/coreutils/tee.c b/coreutils/tee.c index 4c5c691c6..2f746f96d 100644 --- a/coreutils/tee.c +++ b/coreutils/tee.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini tee implementation for busybox | 3 | * Mini tee implementation for busybox |
3 | * | 4 | * |
@@ -25,102 +26,100 @@ | |||
25 | #include <stdio.h> | 26 | #include <stdio.h> |
26 | 27 | ||
27 | static const char tee_usage[] = | 28 | static const char tee_usage[] = |
28 | "tee [OPTION]... [FILE]...\n\n" | 29 | "tee [OPTION]... [FILE]...\n\n" |
29 | "Copy standard input to each FILE, and also to standard output.\n\n" | 30 | "Copy standard input to each FILE, and also to standard output.\n\n" |
30 | "Options:\n" | 31 | "Options:\n" "\t-a\tappend to the given FILEs, do not overwrite\n" |
31 | "\t-a\tappend to the given FILEs, do not overwrite\n" | ||
32 | #if 0 | 32 | #if 0 |
33 | "\t-i\tignore interrupt signals\n" | 33 | "\t-i\tignore interrupt signals\n" |
34 | #endif | 34 | #endif |
35 | ; | 35 | ; |
36 | 36 | ||
37 | 37 | ||
38 | /* FileList _______________________________________________________________ */ | 38 | /* FileList _______________________________________________________________ */ |
39 | 39 | ||
40 | #define FL_MAX 1024 | 40 | #define FL_MAX 1024 |
41 | static FILE *FileList[FL_MAX]; | 41 | static FILE *FileList[FL_MAX]; |
42 | static int FL_end; | 42 | static int FL_end; |
43 | |||
44 | typedef void (FL_Function) (FILE * file, char c); | ||
43 | 45 | ||
44 | typedef void (FL_Function)(FILE *file, char c); | ||
45 | |||
46 | 46 | ||
47 | /* apply a function to everything in FileList */ | 47 | /* apply a function to everything in FileList */ |
48 | static void | 48 | static void FL_apply(FL_Function * f, char c) |
49 | FL_apply(FL_Function *f, char c) | ||
50 | { | 49 | { |
51 | int i; | 50 | int i; |
52 | for (i = 0; i <= FL_end; i++) { | 51 | |
53 | f(FileList[i], c); | 52 | for (i = 0; i <= FL_end; i++) { |
54 | } | 53 | f(FileList[i], c); |
54 | } | ||
55 | } | 55 | } |
56 | 56 | ||
57 | /* FL_Function for writing to files*/ | 57 | /* FL_Function for writing to files*/ |
58 | static void | 58 | static void tee_fwrite(FILE * file, char c) |
59 | tee_fwrite(FILE *file, char c) | ||
60 | { | 59 | { |
61 | fputc(c, file); | 60 | fputc(c, file); |
62 | } | 61 | } |
63 | 62 | ||
64 | /* FL_Function for closing files */ | 63 | /* FL_Function for closing files */ |
65 | static void | 64 | static void tee_fclose(FILE * file, char c) |
66 | tee_fclose(FILE *file, char c) | ||
67 | { | 65 | { |
68 | fclose(file); | 66 | fclose(file); |
69 | } | 67 | } |
70 | 68 | ||
71 | /* ________________________________________________________________________ */ | 69 | /* ________________________________________________________________________ */ |
72 | 70 | ||
73 | /* BusyBoxed tee(1) */ | 71 | /* BusyBoxed tee(1) */ |
74 | int | 72 | int tee_main(int argc, char **argv) |
75 | tee_main(int argc, char **argv) | ||
76 | { | 73 | { |
77 | int i; | 74 | int i; |
78 | char c; | 75 | char c; |
79 | char opt; | 76 | char opt; |
80 | char opt_fopen[2] = "w"; | 77 | char opt_fopen[2] = "w"; |
81 | FILE *file; | 78 | FILE *file; |
82 | 79 | ||
83 | /* parse argv[] */ | 80 | /* parse argv[] */ |
84 | for (i = 1; i < argc; i++) { | 81 | for (i = 1; i < argc; i++) { |
85 | if (argv[i][0] == '-') { | 82 | if (argv[i][0] == '-') { |
86 | opt = argv[i][1]; | 83 | opt = argv[i][1]; |
87 | switch (opt) { | 84 | switch (opt) { |
88 | case 'a': | 85 | case 'a': |
89 | opt_fopen[0] = 'a'; | 86 | opt_fopen[0] = 'a'; |
90 | break; | 87 | break; |
91 | #if 0 | 88 | #if 0 |
92 | case 'i': | 89 | case 'i': |
93 | fprintf(stderr, "ignore interrupt not implemented\n"); | 90 | fprintf(stderr, "ignore interrupt not implemented\n"); |
94 | break; | 91 | break; |
95 | #endif | 92 | #endif |
96 | default: | 93 | default: |
97 | usage(tee_usage); | 94 | usage(tee_usage); |
98 | } | 95 | } |
99 | } else { | 96 | } else { |
100 | break; | 97 | break; |
98 | } | ||
101 | } | 99 | } |
102 | } | 100 | |
103 | 101 | /* init FILE pointers */ | |
104 | /* init FILE pointers */ | 102 | FL_end = 0; |
105 | FL_end = 0; | 103 | FileList[0] = stdout; |
106 | FileList[0] = stdout; | 104 | for (; i < argc; i++) { |
107 | for ( ; i < argc; i++) { | 105 | /* add a file to FileList */ |
108 | /* add a file to FileList */ | 106 | file = fopen(argv[i], opt_fopen); |
109 | file = fopen(argv[i], opt_fopen); | 107 | if (!file) { |
110 | if (!file) { continue; } | 108 | continue; |
111 | if (FL_end < FL_MAX) { | 109 | } |
112 | FileList[++FL_end] = file; | 110 | if (FL_end < FL_MAX) { |
111 | FileList[++FL_end] = file; | ||
112 | } | ||
113 | } | 113 | } |
114 | } | ||
115 | 114 | ||
116 | /* read and redirect */ | 115 | /* read and redirect */ |
117 | while ((c = (char) getchar()) && (!feof(stdin))) { | 116 | while ((c = (char) getchar()) && (!feof(stdin))) { |
118 | FL_apply(tee_fwrite, c); | 117 | FL_apply(tee_fwrite, c); |
119 | } | 118 | } |
120 | 119 | ||
121 | /* clean up */ | 120 | /* clean up */ |
122 | FL_apply(tee_fclose, 0); | 121 | FL_apply(tee_fclose, 0); |
123 | exit(0); | 122 | exit(0); |
124 | } | 123 | } |
125 | 124 | ||
126 | /* $Id: tee.c,v 1.5 2000/02/07 05:29:42 erik Exp $ */ | 125 | /* $Id: tee.c,v 1.6 2000/02/08 19:58:47 erik Exp $ */ |
diff --git a/coreutils/touch.c b/coreutils/touch.c index d2d3e9484..a0f21acdd 100644 --- a/coreutils/touch.c +++ b/coreutils/touch.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini touch implementation for busybox | 3 | * Mini touch implementation for busybox |
3 | * | 4 | * |
@@ -31,56 +32,50 @@ | |||
31 | 32 | ||
32 | 33 | ||
33 | static const char touch_usage[] = "touch [-c] file [file ...]\n\n" | 34 | static const char touch_usage[] = "touch [-c] file [file ...]\n\n" |
34 | "Update the last-modified date on the given file[s].\n"; | ||
35 | 35 | ||
36 | "Update the last-modified date on the given file[s].\n"; | ||
36 | 37 | ||
37 | 38 | ||
38 | extern int | ||
39 | touch_main(int argc, char **argv) | ||
40 | { | ||
41 | int fd; | ||
42 | int create=TRUE; | ||
43 | 39 | ||
44 | if (argc < 2) { | 40 | extern int touch_main(int argc, char **argv) |
45 | usage( touch_usage); | 41 | { |
46 | } | 42 | int fd; |
47 | argc--; | 43 | int create = TRUE; |
48 | argv++; | ||
49 | 44 | ||
50 | /* Parse options */ | 45 | if (argc < 2) { |
51 | while (**argv == '-') { | 46 | usage(touch_usage); |
52 | while (*++(*argv)) switch (**argv) { | ||
53 | case 'c': | ||
54 | create = FALSE; | ||
55 | break; | ||
56 | default: | ||
57 | usage( touch_usage); | ||
58 | exit( FALSE); | ||
59 | } | 47 | } |
60 | argc--; | 48 | argc--; |
61 | argv++; | 49 | argv++; |
62 | } | ||
63 | 50 | ||
64 | fd = open (*argv, (create==FALSE)? O_RDWR : O_RDWR | O_CREAT, 0644); | 51 | /* Parse options */ |
65 | if (fd < 0 ) { | 52 | while (**argv == '-') { |
66 | if (create==FALSE && errno == ENOENT) | 53 | while (*++(*argv)) |
67 | exit( TRUE); | 54 | switch (**argv) { |
68 | else { | 55 | case 'c': |
69 | perror("touch"); | 56 | create = FALSE; |
70 | exit( FALSE); | 57 | break; |
58 | default: | ||
59 | usage(touch_usage); | ||
60 | exit(FALSE); | ||
61 | } | ||
62 | argc--; | ||
63 | argv++; | ||
71 | } | 64 | } |
72 | } | ||
73 | close( fd); | ||
74 | if (utime (*argv, NULL)) { | ||
75 | perror("touch"); | ||
76 | exit( FALSE); | ||
77 | } | ||
78 | else | ||
79 | exit( TRUE); | ||
80 | } | ||
81 | |||
82 | |||
83 | |||
84 | |||
85 | |||
86 | 65 | ||
66 | fd = open(*argv, (create == FALSE) ? O_RDWR : O_RDWR | O_CREAT, 0644); | ||
67 | if (fd < 0) { | ||
68 | if (create == FALSE && errno == ENOENT) | ||
69 | exit(TRUE); | ||
70 | else { | ||
71 | perror("touch"); | ||
72 | exit(FALSE); | ||
73 | } | ||
74 | } | ||
75 | close(fd); | ||
76 | if (utime(*argv, NULL)) { | ||
77 | perror("touch"); | ||
78 | exit(FALSE); | ||
79 | } else | ||
80 | exit(TRUE); | ||
81 | } | ||
diff --git a/coreutils/tty.c b/coreutils/tty.c index 83abaffb5..8ac1c1fcd 100644 --- a/coreutils/tty.c +++ b/coreutils/tty.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini tty implementation for busybox | 3 | * Mini tty implementation for busybox |
3 | * | 4 | * |
@@ -24,19 +25,23 @@ | |||
24 | #include <sys/types.h> | 25 | #include <sys/types.h> |
25 | 26 | ||
26 | static const char tty_usage[] = "tty\n\n" | 27 | static const char tty_usage[] = "tty\n\n" |
27 | "Print the file name of the terminal connected to standard input.\n" | 28 | "Print the file name of the terminal connected to standard input.\n" |
28 | "\t-s\tprint nothing, only return an exit status\n"; | ||
29 | 29 | ||
30 | extern int tty_main(int argc, char **argv) { | 30 | "\t-s\tprint nothing, only return an exit status\n"; |
31 | |||
32 | extern int tty_main(int argc, char **argv) | ||
33 | { | ||
31 | char *tty; | 34 | char *tty; |
32 | 35 | ||
33 | if (argc > 1) { | 36 | if (argc > 1) { |
34 | if (argv[1][0] != '-' || argv[1][1] != 's') usage (tty_usage); | 37 | if (argv[1][0] != '-' || argv[1][1] != 's') |
35 | } | 38 | usage(tty_usage); |
36 | else { | 39 | } else { |
37 | tty = ttyname (0); | 40 | tty = ttyname(0); |
38 | if (tty) puts (tty); | 41 | if (tty) |
39 | else puts ("not a tty"); | 42 | puts(tty); |
43 | else | ||
44 | puts("not a tty"); | ||
40 | } | 45 | } |
41 | exit (isatty (0) ? TRUE : FALSE); | 46 | exit(isatty(0) ? TRUE : FALSE); |
42 | } | 47 | } |
diff --git a/coreutils/uname.c b/coreutils/uname.c index 9083edb04..9a1cb808a 100644 --- a/coreutils/uname.c +++ b/coreutils/uname.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* uname -- print system information | 2 | /* uname -- print system information |
2 | Copyright (C) 1989-1999 Free Software Foundation, Inc. | 3 | Copyright (C) 1989-1999 Free Software Foundation, Inc. |
3 | 4 | ||
@@ -41,16 +42,17 @@ | |||
41 | 42 | ||
42 | 43 | ||
43 | static const char uname_usage[] = | 44 | static const char uname_usage[] = |
44 | "uname [OPTION]...\n\n" | 45 | "uname [OPTION]...\n\n" |
45 | "Print certain system information. With no OPTION, same as -s.\n\n" | 46 | "Print certain system information. With no OPTION, same as -s.\n\n" |
46 | "Options:\n" | 47 | "Options:\n" |
47 | "\t-a\tprint all information\n" | 48 | "\t-a\tprint all information\n" |
48 | "\t-m\tthe machine (hardware) type\n" | 49 | "\t-m\tthe machine (hardware) type\n" |
49 | "\t-n\tprint the machine's network node hostname\n" | 50 | "\t-n\tprint the machine's network node hostname\n" |
50 | "\t-r\tprint the operating system release\n" | 51 | "\t-r\tprint the operating system release\n" |
51 | "\t-s\tprint the operating system name\n" | 52 | "\t-s\tprint the operating system name\n" |
52 | "\t-p\tprint the host processor type\n" | 53 | |
53 | "\t-v\tprint the operating system version\n"; | 54 | "\t-p\tprint the host processor type\n" |
55 | "\t-v\tprint the operating system version\n"; | ||
54 | 56 | ||
55 | 57 | ||
56 | static void print_element(unsigned int mask, char *element); | 58 | static void print_element(unsigned int mask, char *element); |
@@ -80,77 +82,78 @@ static unsigned char toprint; | |||
80 | 82 | ||
81 | int uname_main(int argc, char **argv) | 83 | int uname_main(int argc, char **argv) |
82 | { | 84 | { |
83 | struct utsname name; | 85 | struct utsname name; |
84 | char processor[256]; | 86 | char processor[256]; |
87 | |||
85 | #if defined(__sparc__) && defined(__linux__) | 88 | #if defined(__sparc__) && defined(__linux__) |
86 | char *fake_sparc = getenv("FAKE_SPARC"); | 89 | char *fake_sparc = getenv("FAKE_SPARC"); |
87 | #endif | 90 | #endif |
88 | 91 | ||
89 | toprint = 0; | 92 | toprint = 0; |
90 | 93 | ||
91 | /* Parse any options */ | 94 | /* Parse any options */ |
92 | //fprintf(stderr, "argc=%d, argv=%s\n", argc, *argv); | 95 | //fprintf(stderr, "argc=%d, argv=%s\n", argc, *argv); |
93 | while (--argc > 0 && **(++argv) == '-') { | 96 | while (--argc > 0 && **(++argv) == '-') { |
94 | while (*(++(*argv))) { | 97 | while (*(++(*argv))) { |
95 | switch (**argv) { | 98 | switch (**argv) { |
96 | case 's': | 99 | case 's': |
97 | toprint |= PRINT_SYSNAME; | 100 | toprint |= PRINT_SYSNAME; |
98 | break; | 101 | break; |
99 | case 'n': | 102 | case 'n': |
100 | toprint |= PRINT_NODENAME; | 103 | toprint |= PRINT_NODENAME; |
101 | break; | 104 | break; |
102 | case 'r': | 105 | case 'r': |
103 | toprint |= PRINT_RELEASE; | 106 | toprint |= PRINT_RELEASE; |
104 | break; | 107 | break; |
105 | case 'v': | 108 | case 'v': |
106 | toprint |= PRINT_VERSION; | 109 | toprint |= PRINT_VERSION; |
107 | break; | 110 | break; |
108 | case 'm': | 111 | case 'm': |
109 | toprint |= PRINT_MACHINE; | 112 | toprint |= PRINT_MACHINE; |
110 | break; | 113 | break; |
111 | case 'p': | 114 | case 'p': |
112 | toprint |= PRINT_PROCESSOR; | 115 | toprint |= PRINT_PROCESSOR; |
113 | break; | 116 | break; |
114 | case 'a': | 117 | case 'a': |
115 | toprint = (PRINT_SYSNAME | PRINT_NODENAME | PRINT_RELEASE | | 118 | toprint = (PRINT_SYSNAME | PRINT_NODENAME | PRINT_RELEASE | |
116 | PRINT_PROCESSOR | PRINT_VERSION | | 119 | PRINT_PROCESSOR | PRINT_VERSION | |
117 | PRINT_MACHINE); | 120 | PRINT_MACHINE); |
118 | break; | 121 | break; |
119 | default: | 122 | default: |
120 | usage(uname_usage); | 123 | usage(uname_usage); |
121 | } | 124 | } |
125 | } | ||
122 | } | 126 | } |
123 | } | ||
124 | 127 | ||
125 | if (toprint == 0) | 128 | if (toprint == 0) |
126 | toprint = PRINT_SYSNAME; | 129 | toprint = PRINT_SYSNAME; |
127 | 130 | ||
128 | if (uname(&name) == -1) | 131 | if (uname(&name) == -1) |
129 | perror("cannot get system name"); | 132 | perror("cannot get system name"); |
130 | 133 | ||
131 | #if defined (HAVE_SYSINFO) && defined (SI_ARCHITECTURE) | 134 | #if defined (HAVE_SYSINFO) && defined (SI_ARCHITECTURE) |
132 | if (sysinfo(SI_ARCHITECTURE, processor, sizeof(processor)) == -1) | 135 | if (sysinfo(SI_ARCHITECTURE, processor, sizeof(processor)) == -1) |
133 | perror("cannot get processor type"); | 136 | perror("cannot get processor type"); |
134 | } | 137 | } |
135 | 138 | ||
136 | #else | 139 | #else |
137 | strcpy(processor, "unknown"); | 140 | strcpy(processor, "unknown"); |
138 | #endif | 141 | #endif |
139 | 142 | ||
140 | #if defined(__sparc__) && defined(__linux__) | 143 | #if defined(__sparc__) && defined(__linux__) |
141 | if (fake_sparc != NULL | 144 | if (fake_sparc != NULL |
142 | && (fake_sparc[0] == 'y' | 145 | && (fake_sparc[0] == 'y' |
143 | || fake_sparc[0] == 'Y')) strcpy(name.machine, "sparc"); | 146 | || fake_sparc[0] == 'Y')) strcpy(name.machine, "sparc"); |
144 | #endif | 147 | #endif |
145 | 148 | ||
146 | print_element(PRINT_SYSNAME, name.sysname); | 149 | print_element(PRINT_SYSNAME, name.sysname); |
147 | print_element(PRINT_NODENAME, name.nodename); | 150 | print_element(PRINT_NODENAME, name.nodename); |
148 | print_element(PRINT_RELEASE, name.release); | 151 | print_element(PRINT_RELEASE, name.release); |
149 | print_element(PRINT_VERSION, name.version); | 152 | print_element(PRINT_VERSION, name.version); |
150 | print_element(PRINT_MACHINE, name.machine); | 153 | print_element(PRINT_MACHINE, name.machine); |
151 | print_element(PRINT_PROCESSOR, processor); | 154 | print_element(PRINT_PROCESSOR, processor); |
152 | 155 | ||
153 | exit(TRUE); | 156 | exit(TRUE); |
154 | } | 157 | } |
155 | 158 | ||
156 | /* If the name element set in MASK is selected for printing in `toprint', | 159 | /* If the name element set in MASK is selected for printing in `toprint', |
@@ -159,8 +162,8 @@ int uname_main(int argc, char **argv) | |||
159 | 162 | ||
160 | static void print_element(unsigned int mask, char *element) | 163 | static void print_element(unsigned int mask, char *element) |
161 | { | 164 | { |
162 | if (toprint & mask) { | 165 | if (toprint & mask) { |
163 | toprint &= ~mask; | 166 | toprint &= ~mask; |
164 | printf("%s%c", element, toprint ? ' ' : '\n'); | 167 | printf("%s%c", element, toprint ? ' ' : '\n'); |
165 | } | 168 | } |
166 | } | 169 | } |
diff --git a/coreutils/uniq.c b/coreutils/uniq.c index 965d290c2..1e41eaacd 100644 --- a/coreutils/uniq.c +++ b/coreutils/uniq.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini uniq implementation for busybox | 3 | * Mini uniq implementation for busybox |
3 | * | 4 | * |
@@ -27,119 +28,116 @@ | |||
27 | #include <errno.h> | 28 | #include <errno.h> |
28 | 29 | ||
29 | static const char uniq_usage[] = | 30 | static const char uniq_usage[] = |
30 | "uniq [OPTION]... [INPUT [OUTPUT]]\n" | 31 | "uniq [OPTION]... [INPUT [OUTPUT]]\n" |
31 | "Discard all but one of successive identical lines from INPUT (or\n" | 32 | "Discard all but one of successive identical lines from INPUT (or\n" |
32 | "standard input), writing to OUTPUT (or standard output).\n" | 33 | "standard input), writing to OUTPUT (or standard output).\n" |
33 | "\n" | 34 | "\n" |
34 | "\t-h\tdisplay this help and exit\n" | 35 | "\t-h\tdisplay this help and exit\n" |
35 | "\n" | 36 | |
36 | "A field is a run of whitespace, then non-whitespace characters.\n" | 37 | "\n" |
37 | "Fields are skipped before chars.\n" | 38 | "A field is a run of whitespace, then non-whitespace characters.\n" |
38 | ; | 39 | "Fields are skipped before chars.\n"; |
39 | 40 | ||
40 | /* max chars in line */ | 41 | /* max chars in line */ |
41 | #define UNIQ_MAX 4096 | 42 | #define UNIQ_MAX 4096 |
42 | 43 | ||
43 | typedef void (Print)(FILE *, const char *); | 44 | typedef void (Print) (FILE *, const char *); |
44 | 45 | ||
45 | typedef int (Decide)(const char *, const char *); | 46 | typedef int (Decide) (const char *, const char *); |
46 | 47 | ||
47 | /* container for two lines to be compared */ | 48 | /* container for two lines to be compared */ |
48 | typedef struct { | 49 | typedef struct { |
49 | char *a; | 50 | char *a; |
50 | char *b; | 51 | char *b; |
51 | int recurrence; | 52 | int recurrence; |
52 | FILE *in; | 53 | FILE *in; |
53 | FILE *out; | 54 | FILE *out; |
54 | void *func; | 55 | void *func; |
55 | } Subject; | 56 | } Subject; |
56 | 57 | ||
57 | /* set up all the variables of a uniq operation */ | 58 | /* set up all the variables of a uniq operation */ |
58 | static Subject * | 59 | static Subject *subject_init(Subject * self, FILE * in, FILE * out, |
59 | subject_init(Subject *self, FILE *in, FILE *out, void *func) | 60 | void *func) |
60 | { | 61 | { |
61 | self->a = NULL; | 62 | self->a = NULL; |
62 | self->b = NULL; | 63 | self->b = NULL; |
63 | self->in = in; | 64 | self->in = in; |
64 | self->out = out; | 65 | self->out = out; |
65 | self->func = func; | 66 | self->func = func; |
66 | self->recurrence = 0; | 67 | self->recurrence = 0; |
67 | return self; | 68 | return self; |
68 | } | 69 | } |
69 | 70 | ||
70 | /* point a and b to the appropriate lines; | 71 | /* point a and b to the appropriate lines; |
71 | * count the recurrences (if any) of a string; | 72 | * count the recurrences (if any) of a string; |
72 | */ | 73 | */ |
73 | static Subject * | 74 | static Subject *subject_next(Subject * self) |
74 | subject_next(Subject *self) | ||
75 | { | 75 | { |
76 | /* tmp line holders */ | 76 | /* tmp line holders */ |
77 | static char line[2][UNIQ_MAX]; | 77 | static char line[2][UNIQ_MAX]; |
78 | static int alternator = 0; | 78 | static int alternator = 0; |
79 | 79 | ||
80 | if (fgets(line[alternator], UNIQ_MAX, self->in)) { | 80 | if (fgets(line[alternator], UNIQ_MAX, self->in)) { |
81 | self->a = self->b; | 81 | self->a = self->b; |
82 | self->b = line[alternator]; | 82 | self->b = line[alternator]; |
83 | alternator ^= 1; | 83 | alternator ^= 1; |
84 | return self; | 84 | return self; |
85 | } | 85 | } |
86 | 86 | ||
87 | return NULL; | 87 | return NULL; |
88 | } | 88 | } |
89 | 89 | ||
90 | static Subject * | 90 | static Subject *subject_last(Subject * self) |
91 | subject_last(Subject *self) | ||
92 | { | 91 | { |
93 | self->a = self->b; | 92 | self->a = self->b; |
94 | self->b = NULL; | 93 | self->b = NULL; |
95 | return self; | 94 | return self; |
96 | } | 95 | } |
97 | 96 | ||
98 | static Subject * | 97 | static Subject *subject_study(Subject * self) |
99 | subject_study(Subject *self) | ||
100 | { | 98 | { |
101 | if (self->a == NULL) { | 99 | if (self->a == NULL) { |
102 | return self; | 100 | return self; |
103 | } | 101 | } |
104 | if (self->b == NULL) { | 102 | if (self->b == NULL) { |
105 | fprintf(self->out, "%s", self->a); | 103 | fprintf(self->out, "%s", self->a); |
104 | return self; | ||
105 | } | ||
106 | if (strcmp(self->a, self->b) == 0) { | ||
107 | self->recurrence++; | ||
108 | } else { | ||
109 | fprintf(self->out, "%s", self->a); | ||
110 | self->recurrence = 0; | ||
111 | } | ||
106 | return self; | 112 | return self; |
107 | } | ||
108 | if (strcmp(self->a, self->b) == 0) { | ||
109 | self->recurrence++; | ||
110 | } else { | ||
111 | fprintf(self->out, "%s", self->a); | ||
112 | self->recurrence = 0; | ||
113 | } | ||
114 | return self; | ||
115 | } | 113 | } |
116 | 114 | ||
117 | static int | 115 | static int |
118 | set_file_pointers(int schema, FILE **in, FILE **out, char **argv) | 116 | set_file_pointers(int schema, FILE ** in, FILE ** out, char **argv) |
119 | { | 117 | { |
120 | switch (schema) { | 118 | switch (schema) { |
121 | case 0: | 119 | case 0: |
122 | *in = stdin; | 120 | *in = stdin; |
123 | *out = stdout; | 121 | *out = stdout; |
124 | break; | 122 | break; |
125 | case 1: | 123 | case 1: |
126 | *in = fopen(argv[0], "r"); | 124 | *in = fopen(argv[0], "r"); |
127 | *out = stdout; | 125 | *out = stdout; |
128 | break; | 126 | break; |
129 | case 2: | 127 | case 2: |
130 | *in = fopen(argv[0], "r"); | 128 | *in = fopen(argv[0], "r"); |
131 | *out = fopen(argv[1], "w"); | 129 | *out = fopen(argv[1], "w"); |
132 | break; | 130 | break; |
133 | } | 131 | } |
134 | if (*in == NULL) { | 132 | if (*in == NULL) { |
135 | fprintf(stderr, "uniq: %s: %s\n", argv[0], strerror(errno)); | 133 | fprintf(stderr, "uniq: %s: %s\n", argv[0], strerror(errno)); |
136 | return errno; | 134 | return errno; |
137 | } | 135 | } |
138 | if (*out == NULL) { | 136 | if (*out == NULL) { |
139 | fprintf(stderr, "uniq: %s: %s\n", argv[1], strerror(errno)); | 137 | fprintf(stderr, "uniq: %s: %s\n", argv[1], strerror(errno)); |
140 | return errno; | 138 | return errno; |
141 | } | 139 | } |
142 | return 0; | 140 | return 0; |
143 | } | 141 | } |
144 | 142 | ||
145 | 143 | ||
@@ -152,45 +150,44 @@ set_file_pointers(int schema, FILE **in, FILE **out, char **argv) | |||
152 | /* it seems like GNU/uniq only takes one or two files as an option */ | 150 | /* it seems like GNU/uniq only takes one or two files as an option */ |
153 | 151 | ||
154 | /* ________________________________________________________________________ */ | 152 | /* ________________________________________________________________________ */ |
155 | int | 153 | int uniq_main(int argc, char **argv) |
156 | uniq_main(int argc, char **argv) | ||
157 | { | 154 | { |
158 | int i; | 155 | int i; |
159 | char opt; | 156 | char opt; |
160 | FILE *in, *out; | 157 | FILE *in, *out; |
161 | Subject s; | 158 | Subject s; |
162 | 159 | ||
163 | /* parse argv[] */ | 160 | /* parse argv[] */ |
164 | for (i = 1; i < argc; i++) { | 161 | for (i = 1; i < argc; i++) { |
165 | if (argv[i][0] == '-') { | 162 | if (argv[i][0] == '-') { |
166 | opt = argv[i][1]; | 163 | opt = argv[i][1]; |
167 | switch (opt) { | 164 | switch (opt) { |
168 | case '-': | 165 | case '-': |
169 | case 'h': | 166 | case 'h': |
170 | usage(uniq_usage); | 167 | usage(uniq_usage); |
171 | default: | 168 | default: |
172 | usage(uniq_usage); | 169 | usage(uniq_usage); |
173 | } | 170 | } |
174 | } else { | 171 | } else { |
175 | break; | 172 | break; |
173 | } | ||
176 | } | 174 | } |
177 | } | ||
178 | 175 | ||
179 | /* 0 src: stdin; dst: stdout */ | 176 | /* 0 src: stdin; dst: stdout */ |
180 | /* 1 src: file; dst: stdout */ | 177 | /* 1 src: file; dst: stdout */ |
181 | /* 2 src: file; dst: file */ | 178 | /* 2 src: file; dst: file */ |
182 | if (set_file_pointers((argc - 1), &in, &out, &argv[i])) { | 179 | if (set_file_pointers((argc - 1), &in, &out, &argv[i])) { |
183 | exit(1); | 180 | exit(1); |
184 | } | 181 | } |
185 | 182 | ||
186 | subject_init(&s, in, out, NULL); | 183 | subject_init(&s, in, out, NULL); |
187 | while (subject_next(&s)) { | 184 | while (subject_next(&s)) { |
185 | subject_study(&s); | ||
186 | } | ||
187 | subject_last(&s); | ||
188 | subject_study(&s); | 188 | subject_study(&s); |
189 | } | ||
190 | subject_last(&s); | ||
191 | subject_study(&s); | ||
192 | 189 | ||
193 | exit(0); | 190 | exit(0); |
194 | } | 191 | } |
195 | 192 | ||
196 | /* $Id: uniq.c,v 1.6 2000/02/07 05:29:42 erik Exp $ */ | 193 | /* $Id: uniq.c,v 1.7 2000/02/08 19:58:47 erik Exp $ */ |
diff --git a/coreutils/wc.c b/coreutils/wc.c index e69f0d899..8004e6294 100644 --- a/coreutils/wc.c +++ b/coreutils/wc.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini wc implementation for busybox | 3 | * Mini wc implementation for busybox |
3 | * | 4 | * |
@@ -23,78 +24,82 @@ | |||
23 | #include <stdio.h> | 24 | #include <stdio.h> |
24 | 25 | ||
25 | static const char wc_usage[] = "wc [OPTION]... [FILE]...\n\n" | 26 | static const char wc_usage[] = "wc [OPTION]... [FILE]...\n\n" |
26 | "Print line, word, and byte counts for each FILE, and a total line if\n" | 27 | "Print line, word, and byte counts for each FILE, and a total line if\n" |
27 | "more than one FILE is specified. With no FILE, read standard input.\n" | 28 | "more than one FILE is specified. With no FILE, read standard input.\n" |
28 | "\t-c\tprint the byte counts\n" | 29 | "\t-c\tprint the byte counts\n" |
29 | "\t-l\tprint the newline counts\n" | 30 | "\t-l\tprint the newline counts\n" |
30 | "\t-L\tprint the length of the longest line\n" | 31 | |
31 | "\t-w\tprint the word counts\n"; | 32 | "\t-L\tprint the length of the longest line\n" |
33 | "\t-w\tprint the word counts\n"; | ||
32 | 34 | ||
33 | static int total_lines, total_words, total_chars, max_length; | 35 | static int total_lines, total_words, total_chars, max_length; |
34 | static int print_lines, print_words, print_chars, print_length; | 36 | static int print_lines, print_words, print_chars, print_length; |
35 | 37 | ||
36 | void print_counts (int lines, int words, int chars, int length, | 38 | void print_counts(int lines, int words, int chars, int length, |
37 | const char *name) { | 39 | const char *name) |
40 | { | ||
38 | char const *space = ""; | 41 | char const *space = ""; |
42 | |||
39 | if (print_lines) { | 43 | if (print_lines) { |
40 | printf ("%7d", lines); | 44 | printf("%7d", lines); |
41 | space = " "; | 45 | space = " "; |
42 | } | 46 | } |
43 | if (print_words) { | 47 | if (print_words) { |
44 | printf ("%s%7d", space, words); | 48 | printf("%s%7d", space, words); |
45 | space = " "; | 49 | space = " "; |
46 | } | 50 | } |
47 | if (print_chars) { | 51 | if (print_chars) { |
48 | printf ("%s%7d", space, chars); | 52 | printf("%s%7d", space, chars); |
49 | space = " "; | 53 | space = " "; |
50 | } | 54 | } |
51 | if (print_length) | 55 | if (print_length) |
52 | printf ("%s%7d", space, length); | 56 | printf("%s%7d", space, length); |
53 | if (*name) | 57 | if (*name) |
54 | printf (" %s", name); | 58 | printf(" %s", name); |
55 | putchar ('\n'); | 59 | putchar('\n'); |
56 | } | 60 | } |
57 | 61 | ||
58 | static void wc_file(FILE *file, const char *name) | 62 | static void wc_file(FILE * file, const char *name) |
59 | { | 63 | { |
60 | int lines, words, chars, length; | 64 | int lines, words, chars, length; |
61 | int in_word = 0, linepos = 0; | 65 | int in_word = 0, linepos = 0; |
62 | int c; | 66 | int c; |
67 | |||
63 | lines = words = chars = length = 0; | 68 | lines = words = chars = length = 0; |
64 | while ((c = getc(file)) != EOF) { | 69 | while ((c = getc(file)) != EOF) { |
65 | chars++; | 70 | chars++; |
66 | switch (c) { | 71 | switch (c) { |
67 | case '\n': | 72 | case '\n': |
68 | lines++; | 73 | lines++; |
69 | case '\r': | 74 | case '\r': |
70 | case '\f': | 75 | case '\f': |
71 | if (linepos > length) | 76 | if (linepos > length) |
72 | length = linepos; | 77 | length = linepos; |
73 | linepos = 0; | 78 | linepos = 0; |
74 | goto word_separator; | 79 | goto word_separator; |
75 | case '\t': | 80 | case '\t': |
76 | linepos += 8 - (linepos % 8); | 81 | linepos += 8 - (linepos % 8); |
77 | goto word_separator; | 82 | goto word_separator; |
78 | case ' ': | 83 | case ' ': |
79 | linepos++; | 84 | linepos++; |
80 | case '\v': | 85 | case '\v': |
81 | word_separator: | 86 | word_separator: |
82 | if (in_word) { | 87 | if (in_word) { |
83 | in_word = 0; | 88 | in_word = 0; |
84 | words++; | 89 | words++; |
85 | } | 90 | } |
86 | break; | 91 | break; |
87 | default: | 92 | default: |
88 | linepos++; | 93 | linepos++; |
89 | in_word = 1; | 94 | in_word = 1; |
90 | break; | 95 | break; |
91 | } | 96 | } |
92 | } | 97 | } |
93 | if (linepos > length) | 98 | if (linepos > length) |
94 | length = linepos; | 99 | length = linepos; |
95 | if (in_word) | 100 | if (in_word) |
96 | words++; | 101 | words++; |
97 | print_counts (lines, words, chars, length, name); | 102 | print_counts(lines, words, chars, length, name); |
98 | total_lines += lines; | 103 | total_lines += lines; |
99 | total_words += words; | 104 | total_words += words; |
100 | total_chars += chars; | 105 | total_chars += chars; |
@@ -104,28 +109,30 @@ static void wc_file(FILE *file, const char *name) | |||
104 | fflush(stdout); | 109 | fflush(stdout); |
105 | } | 110 | } |
106 | 111 | ||
107 | int wc_main(int argc, char **argv) { | 112 | int wc_main(int argc, char **argv) |
113 | { | ||
108 | FILE *file; | 114 | FILE *file; |
115 | |||
109 | total_lines = total_words = total_chars = max_length = 0; | 116 | total_lines = total_words = total_chars = max_length = 0; |
110 | print_lines = print_words = print_chars = print_length = 0; | 117 | print_lines = print_words = print_chars = print_length = 0; |
111 | 118 | ||
112 | while (--argc && **(++argv) == '-') { | 119 | while (--argc && **(++argv) == '-') { |
113 | while (*++(*argv)) | 120 | while (*++(*argv)) |
114 | switch (**argv) { | 121 | switch (**argv) { |
115 | case 'c': | 122 | case 'c': |
116 | print_chars = 1; | 123 | print_chars = 1; |
117 | break; | 124 | break; |
118 | case 'l': | 125 | case 'l': |
119 | print_lines = 1; | 126 | print_lines = 1; |
120 | break; | 127 | break; |
121 | case 'L': | 128 | case 'L': |
122 | print_length = 1; | 129 | print_length = 1; |
123 | break; | 130 | break; |
124 | case 'w': | 131 | case 'w': |
125 | print_words = 1; | 132 | print_words = 1; |
126 | break; | 133 | break; |
127 | default: | 134 | default: |
128 | usage (wc_usage); | 135 | usage(wc_usage); |
129 | } | 136 | } |
130 | } | 137 | } |
131 | 138 | ||
@@ -135,16 +142,14 @@ int wc_main(int argc, char **argv) { | |||
135 | if (argc == 0) { | 142 | if (argc == 0) { |
136 | wc_file(stdin, ""); | 143 | wc_file(stdin, ""); |
137 | exit(TRUE); | 144 | exit(TRUE); |
138 | } | 145 | } else if (argc == 1) { |
139 | else if (argc == 1) { | ||
140 | file = fopen(*argv, "r"); | 146 | file = fopen(*argv, "r"); |
141 | if (file == NULL) { | 147 | if (file == NULL) { |
142 | perror(*argv); | 148 | perror(*argv); |
143 | exit(FALSE); | 149 | exit(FALSE); |
144 | } | 150 | } |
145 | wc_file(file, *argv); | 151 | wc_file(file, *argv); |
146 | } | 152 | } else { |
147 | else { | ||
148 | while (argc-- > 0 && *argv != '\0' && strlen(*argv)) { | 153 | while (argc-- > 0 && *argv != '\0' && strlen(*argv)) { |
149 | file = fopen(*argv, "r"); | 154 | file = fopen(*argv, "r"); |
150 | if (file == NULL) { | 155 | if (file == NULL) { |
@@ -154,8 +159,8 @@ int wc_main(int argc, char **argv) { | |||
154 | wc_file(file, *argv); | 159 | wc_file(file, *argv); |
155 | argv++; | 160 | argv++; |
156 | } | 161 | } |
157 | print_counts (total_lines, total_words, total_chars, | 162 | print_counts(total_lines, total_words, total_chars, |
158 | max_length, "total"); | 163 | max_length, "total"); |
159 | } | 164 | } |
160 | exit(TRUE); | 165 | exit(TRUE); |
161 | } | 166 | } |
diff --git a/coreutils/whoami.c b/coreutils/whoami.c index 7fd5d01b2..3677c2fbc 100644 --- a/coreutils/whoami.c +++ b/coreutils/whoami.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini whoami implementation for busybox | 3 | * Mini whoami implementation for busybox |
3 | * | 4 | * |
@@ -24,21 +25,25 @@ | |||
24 | #include <pwd.h> | 25 | #include <pwd.h> |
25 | 26 | ||
26 | static const char whoami_usage[] = "whoami\n\n" | 27 | static const char whoami_usage[] = "whoami\n\n" |
27 | "Print the user name associated with the current effective user id.\n" | 28 | "Print the user name associated with the current effective user id.\n" |
28 | "Same as id -un.\n"; | ||
29 | 29 | ||
30 | extern int whoami_main(int argc, char **argv) { | 30 | "Same as id -un.\n"; |
31 | |||
32 | extern int whoami_main(int argc, char **argv) | ||
33 | { | ||
31 | struct passwd *pw; | 34 | struct passwd *pw; |
32 | uid_t uid; | 35 | uid_t uid; |
33 | 36 | ||
34 | if (argc > 1) usage (whoami_usage); | 37 | if (argc > 1) |
38 | usage(whoami_usage); | ||
35 | 39 | ||
36 | uid = geteuid (); | 40 | uid = geteuid(); |
37 | pw = getpwuid (uid); | 41 | pw = getpwuid(uid); |
38 | if (pw) { | 42 | if (pw) { |
39 | puts (pw->pw_name); | 43 | puts(pw->pw_name); |
40 | exit (TRUE); | 44 | exit(TRUE); |
41 | } | 45 | } |
42 | fprintf (stderr, "%s: cannot find username for UID %u\n", argv[0], (unsigned) uid); | 46 | fprintf(stderr, "%s: cannot find username for UID %u\n", argv[0], |
43 | exit (FALSE); | 47 | (unsigned) uid); |
48 | exit(FALSE); | ||
44 | } | 49 | } |
diff --git a/coreutils/yes.c b/coreutils/yes.c index 96d6257d0..ac67845ac 100644 --- a/coreutils/yes.c +++ b/coreutils/yes.c | |||
@@ -1,3 +1,4 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
1 | /* | 2 | /* |
2 | * Mini yes implementation for busybox | 3 | * Mini yes implementation for busybox |
3 | * | 4 | * |
@@ -22,19 +23,22 @@ | |||
22 | #include "internal.h" | 23 | #include "internal.h" |
23 | #include <stdio.h> | 24 | #include <stdio.h> |
24 | 25 | ||
25 | extern int yes_main(int argc, char **argv) { | 26 | extern int yes_main(int argc, char **argv) |
27 | { | ||
26 | int i; | 28 | int i; |
29 | |||
27 | if (argc == 1) | 30 | if (argc == 1) |
28 | while (1) | 31 | while (1) |
29 | if (puts ("y") == EOF) { | 32 | if (puts("y") == EOF) { |
30 | perror ("yes"); | 33 | perror("yes"); |
31 | exit(FALSE); | 34 | exit(FALSE); |
32 | } | 35 | } |
33 | 36 | ||
34 | while (1) | 37 | while (1) |
35 | for (i = 1; i < argc; i++) | 38 | for (i = 1; i < argc; i++) |
36 | if (fputs (argv[i], stdout) == EOF || putchar (i == argc - 1 ? '\n' : ' ') == EOF) { | 39 | if (fputs(argv[i], stdout) == EOF |
37 | perror ("yes"); | 40 | || putchar(i == argc - 1 ? '\n' : ' ') == EOF) { |
41 | perror("yes"); | ||
38 | exit(FALSE); | 42 | exit(FALSE); |
39 | } | 43 | } |
40 | exit(TRUE); | 44 | exit(TRUE); |