diff options
-rw-r--r-- | Changelog | 5 | ||||
-rw-r--r-- | coreutils/ls.c | 26 | ||||
-rw-r--r-- | dmesg.c | 18 | ||||
-rw-r--r-- | editors/sed.c | 338 | ||||
-rw-r--r-- | ls.c | 26 | ||||
-rw-r--r-- | sed.c | 338 | ||||
-rw-r--r-- | util-linux/dmesg.c | 18 |
7 files changed, 569 insertions, 200 deletions
@@ -17,6 +17,11 @@ | |||
17 | them so they should now work as expected. | 17 | them so they should now work as expected. |
18 | * New app: loadacm contributed by Peter Novodvorsky <petya@logic.ru> | 18 | * New app: loadacm contributed by Peter Novodvorsky <petya@logic.ru> |
19 | for loading application character maps for working with Unicode fonts. | 19 | for loading application character maps for working with Unicode fonts. |
20 | * sed now supports addresses (numeric or regexp, with negation) and | ||
21 | has an append command, thanks to Marco Pantaleoni <panta@prosa.it> | ||
22 | * Fixed dmesg. It wasn't parsing its options (-n or -s) properly. | ||
23 | * Some cosmetic fixes to ls output formatting to make it behave more | ||
24 | like GNU ls. | ||
20 | 25 | ||
21 | 26 | ||
22 | -Erik Andersen | 27 | -Erik Andersen |
diff --git a/coreutils/ls.c b/coreutils/ls.c index 571c962c7..862da4368 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -193,11 +193,13 @@ static void list_single(const char *name, struct stat *info, const char *fullnam | |||
193 | fputs(" ", stdout); | 193 | fputs(" ", stdout); |
194 | #ifdef BB_FEATURE_LS_USERNAME | 194 | #ifdef BB_FEATURE_LS_USERNAME |
195 | if (!(opts & DISP_NUMERIC)) { | 195 | if (!(opts & DISP_NUMERIC)) { |
196 | scratch[0]='\0'; | 196 | memset ( scratch, 0, sizeof (scratch)); |
197 | my_getpwuid( scratch, info->st_uid); | 197 | my_getpwuid( scratch, info->st_uid); |
198 | scratch[8]='\0'; | 198 | if (*scratch) { |
199 | if (*scratch) | 199 | fputs(scratch, stdout); |
200 | wr(scratch,8); | 200 | if ( strlen( scratch) <= 8 ) |
201 | wr(" ", 8-strlen( scratch)); | ||
202 | } | ||
201 | else { | 203 | else { |
202 | writenum((long) info->st_uid,(short)8); | 204 | writenum((long) info->st_uid,(short)8); |
203 | fputs(" ", stdout); | 205 | fputs(" ", stdout); |
@@ -208,20 +210,21 @@ static void list_single(const char *name, struct stat *info, const char *fullnam | |||
208 | writenum((long) info->st_uid,(short)8); | 210 | writenum((long) info->st_uid,(short)8); |
209 | fputs(" ", stdout); | 211 | fputs(" ", stdout); |
210 | } | 212 | } |
211 | tab(16); | ||
212 | #ifdef BB_FEATURE_LS_USERNAME | 213 | #ifdef BB_FEATURE_LS_USERNAME |
213 | if (!(opts & DISP_NUMERIC)) { | 214 | if (!(opts & DISP_NUMERIC)) { |
214 | scratch[0]='\0'; | 215 | memset ( scratch, 0, sizeof (scratch)); |
215 | my_getgrgid( scratch, info->st_gid); | 216 | my_getgrgid( scratch, info->st_gid); |
216 | scratch[8]='\0'; | 217 | if (*scratch) { |
217 | if (*scratch) | 218 | fputs(scratch, stdout); |
218 | wr(scratch,8); | 219 | if ( strlen( scratch) <= 8 ) |
220 | wr(" ", 8-strlen( scratch)); | ||
221 | } | ||
219 | else | 222 | else |
220 | writenum((long) info->st_gid,(short)8); | 223 | writenum((long) info->st_gid,(short)8); |
221 | } else | 224 | } else |
222 | #endif | 225 | #endif |
223 | writenum((long) info->st_gid,(short)8); | 226 | writenum((long) info->st_gid,(short)8); |
224 | tab(17); | 227 | //tab(26); |
225 | if (S_ISBLK(mode) || S_ISCHR(mode)) { | 228 | if (S_ISBLK(mode) || S_ISCHR(mode)) { |
226 | writenum((long)MAJOR(info->st_rdev),(short)3); | 229 | writenum((long)MAJOR(info->st_rdev),(short)3); |
227 | fputs(", ", stdout); | 230 | fputs(", ", stdout); |
@@ -230,6 +233,7 @@ static void list_single(const char *name, struct stat *info, const char *fullnam | |||
230 | else | 233 | else |
231 | writenum((long)info->st_size,(short)8); | 234 | writenum((long)info->st_size,(short)8); |
232 | fputs(" ", stdout); | 235 | fputs(" ", stdout); |
236 | //tab(32); | ||
233 | #ifdef BB_FEATURE_LS_TIMESTAMPS | 237 | #ifdef BB_FEATURE_LS_TIMESTAMPS |
234 | { | 238 | { |
235 | time_t cal; | 239 | time_t cal; |
@@ -44,10 +44,15 @@ int dmesg_main( int argc, char** argv ) | |||
44 | int level = 0; | 44 | int level = 0; |
45 | int lastc; | 45 | int lastc; |
46 | int cmd = 3; | 46 | int cmd = 3; |
47 | int stopDoingThat; | ||
48 | |||
49 | argc--; | ||
50 | argv++; | ||
47 | 51 | ||
48 | /* Parse any options */ | 52 | /* Parse any options */ |
49 | while (argc && **argv == '-') { | 53 | while (argc && **argv == '-') { |
50 | while (*++(*argv)) | 54 | stopDoingThat = FALSE; |
55 | while (stopDoingThat == FALSE && *++(*argv)) { | ||
51 | switch (**argv) { | 56 | switch (**argv) { |
52 | case 'c': | 57 | case 'c': |
53 | cmd = 4; | 58 | cmd = 4; |
@@ -57,19 +62,22 @@ int dmesg_main( int argc, char** argv ) | |||
57 | if (--argc == 0) | 62 | if (--argc == 0) |
58 | goto end; | 63 | goto end; |
59 | level = atoi (*(++argv)); | 64 | level = atoi (*(++argv)); |
60 | --argc; | 65 | if (--argc > 0) |
61 | ++argv; | 66 | ++argv; |
67 | stopDoingThat = TRUE; | ||
62 | break; | 68 | break; |
63 | case 's': | 69 | case 's': |
64 | if (--argc == 0) | 70 | if (--argc == 0) |
65 | goto end; | 71 | goto end; |
66 | bufsize = atoi (*(++argv)); | 72 | bufsize = atoi (*(++argv)); |
67 | --argc; | 73 | if (--argc > 0) |
68 | ++argv; | 74 | ++argv; |
75 | stopDoingThat = TRUE; | ||
69 | break; | 76 | break; |
70 | default: | 77 | default: |
71 | goto end; | 78 | goto end; |
72 | } | 79 | } |
80 | } | ||
73 | } | 81 | } |
74 | 82 | ||
75 | if (argc > 1) { | 83 | if (argc > 1) { |
diff --git a/editors/sed.c b/editors/sed.c index 4dfc0246c..8e5f695c4 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -5,6 +5,11 @@ | |||
5 | * Copyright (C) 1999 by Lineo, inc. | 5 | * Copyright (C) 1999 by Lineo, inc. |
6 | * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> | 6 | * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> |
7 | * | 7 | * |
8 | * Modifications for addresses and append command have been | ||
9 | * written by Marco Pantaleoni <panta@prosa.it>, <panta@elasticworld.org> | ||
10 | * and are: | ||
11 | * Copyright (C) 1999 Marco Pantaleoni. | ||
12 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 14 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 15 | * the Free Software Foundation; either version 2 of the License, or |
@@ -31,48 +36,144 @@ | |||
31 | #include <time.h> | 36 | #include <time.h> |
32 | #include <ctype.h> | 37 | #include <ctype.h> |
33 | 38 | ||
34 | static const char sed_usage[] = | 39 | static const char sed_usage[] = |
35 | "sed [-n] [-e script] [file...]\n\n" | 40 | "sed [-n] -e script [file...]\n\n" |
36 | "Allowed sed scripts come in the following form:\n" | 41 | "Allowed sed scripts come in the following form:\n" |
37 | "\t's/regexp/replacement/[gp]'\n" | 42 | "\t'ADDR [!] COMMAND'\n\n" |
38 | "which attempt to match regexp against the pattern space\n" | 43 | "\twhere address ADDR can be:\n" |
39 | "and if successful replaces the matched portion with replacement.\n\n" | 44 | "\t NUMBER Match specified line number\n" |
40 | "Options:\n" | 45 | "\t $ Match last line\n" |
41 | "-e\tadd the script to the commands to be executed\n" | 46 | "\t /REGEXP/ Match specified regexp\n" |
42 | "-n\tsuppress automatic printing of pattern space\n\n" | 47 | "\t (! inverts the meaning of the match)\n\n" |
48 | "\tand COMMAND can be:\n" | ||
49 | "\t s/regexp/replacement/[gp]\n" | ||
50 | "\t which attempt to match regexp against the pattern space\n" | ||
51 | "\t and if successful replaces the matched portion with replacement.\n\n" | ||
52 | "\t aTEXT\n" | ||
53 | "\t which appends TEXT after the pattern space\n" | ||
54 | "Options:\n" | ||
55 | "-e\tadd the script to the commands to be executed\n" | ||
56 | "-n\tsuppress automatic printing of pattern space\n\n" | ||
43 | #if defined BB_REGEXP | 57 | #if defined BB_REGEXP |
44 | "This version of sed matches full regular expresions.\n"; | 58 | "This version of sed matches full regular expresions.\n"; |
45 | #else | 59 | #else |
46 | "This version of sed matches strings (not full regular expresions).\n"; | 60 | "This version of sed matches strings (not full regular expresions).\n"; |
47 | #endif | 61 | #endif |
48 | |||
49 | 62 | ||
50 | static void do_sed(FILE *fp, char *needle, char *newNeedle, int ignoreCase, int printFlag, int quietFlag) | 63 | /* Flags & variables */ |
64 | |||
65 | typedef enum { f_none, f_replace, f_append } sed_function; | ||
66 | |||
67 | #define NO_LINE -2 | ||
68 | #define LAST_LINE -1 | ||
69 | static int addr_line = NO_LINE; | ||
70 | static char *addr_pattern = NULL; | ||
71 | static int negated = 0; | ||
72 | |||
73 | #define SKIPSPACES(p) do { while (isspace(*(p))) (p)++; } while (0) | ||
74 | |||
75 | #define BUFSIZE 1024 | ||
76 | |||
77 | static inline int at_last(FILE * fp) | ||
51 | { | 78 | { |
52 | int foundOne=FALSE; | 79 | int res = 0; |
53 | char haystack[1024]; | ||
54 | 80 | ||
55 | while (fgets (haystack, 1023, fp)) { | 81 | if (feof(fp)) |
56 | foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); | 82 | return 1; |
57 | if (foundOne==TRUE && printFlag==TRUE) { | 83 | else { |
58 | fprintf(stdout, haystack); | 84 | char ch; |
85 | if ((ch = fgetc(fp)) == EOF) | ||
86 | res++; | ||
87 | ungetc(ch, fp); | ||
88 | } | ||
89 | return res; | ||
90 | } | ||
91 | |||
92 | static void do_sed_repl(FILE * fp, char *needle, char *newNeedle, | ||
93 | int ignoreCase, int printFlag, int quietFlag) | ||
94 | { | ||
95 | int foundOne = FALSE; | ||
96 | char haystack[BUFSIZE]; | ||
97 | int line = 1, doit; | ||
98 | |||
99 | while (fgets(haystack, BUFSIZE - 1, fp)) { | ||
100 | doit = 0; | ||
101 | if (addr_pattern) { | ||
102 | doit = !find_match(haystack, addr_pattern, FALSE); | ||
103 | } else if (addr_line == NO_LINE) | ||
104 | doit = 1; | ||
105 | else if (addr_line == LAST_LINE) { | ||
106 | if (at_last(fp)) | ||
107 | doit = 1; | ||
108 | } else { | ||
109 | if (line == addr_line) | ||
110 | doit = 1; | ||
111 | } | ||
112 | if (negated) | ||
113 | doit = 1 - doit; | ||
114 | if (doit) { | ||
115 | foundOne = | ||
116 | replace_match(haystack, needle, newNeedle, ignoreCase); | ||
117 | |||
118 | if (foundOne == TRUE && printFlag == TRUE) { | ||
119 | fprintf(stdout, haystack); | ||
120 | } | ||
59 | } | 121 | } |
60 | if (quietFlag==FALSE) { | 122 | |
123 | if (quietFlag == FALSE) { | ||
61 | fprintf(stdout, haystack); | 124 | fprintf(stdout, haystack); |
62 | } | 125 | } |
126 | |||
127 | line++; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static void do_sed_append(FILE * fp, char *appendline, int quietFlag) | ||
132 | { | ||
133 | char buffer[BUFSIZE]; | ||
134 | int line = 1, doit; | ||
135 | |||
136 | while (fgets(buffer, BUFSIZE - 1, fp)) { | ||
137 | doit = 0; | ||
138 | if (addr_pattern) { | ||
139 | doit = !find_match(buffer, addr_pattern, FALSE); | ||
140 | } else if (addr_line == NO_LINE) | ||
141 | doit = 1; | ||
142 | else if (addr_line == LAST_LINE) { | ||
143 | if (at_last(fp)) | ||
144 | doit = 1; | ||
145 | } else { | ||
146 | if (line == addr_line) | ||
147 | doit = 1; | ||
148 | } | ||
149 | if (negated) | ||
150 | doit = 1 - doit; | ||
151 | if (quietFlag == FALSE) { | ||
152 | fprintf(stdout, buffer); | ||
153 | } | ||
154 | if (doit) { | ||
155 | fputs(appendline, stdout); | ||
156 | fputc('\n', stdout); | ||
157 | } | ||
158 | |||
159 | line++; | ||
63 | } | 160 | } |
64 | } | 161 | } |
65 | 162 | ||
66 | extern int sed_main (int argc, char **argv) | 163 | extern int sed_main(int argc, char **argv) |
67 | { | 164 | { |
68 | FILE *fp; | 165 | FILE *fp; |
69 | char *needle=NULL, *newNeedle=NULL; | 166 | char *needle = NULL, *newNeedle = NULL; |
70 | char *name; | 167 | char *name; |
71 | char *cp; | 168 | char *cp; |
72 | int ignoreCase=FALSE; | 169 | int ignoreCase = FALSE; |
73 | int printFlag=FALSE; | 170 | int printFlag = FALSE; |
74 | int quietFlag=FALSE; | 171 | int quietFlag = FALSE; |
75 | int stopNow; | 172 | int stopNow; |
173 | char *line_s = NULL, saved; | ||
174 | char *appendline = NULL; | ||
175 | char *pos; | ||
176 | sed_function sed_f = f_none; | ||
76 | 177 | ||
77 | argc--; | 178 | argc--; |
78 | argv++; | 179 | argv++; |
@@ -83,68 +184,119 @@ extern int sed_main (int argc, char **argv) | |||
83 | if (**argv == '-') { | 184 | if (**argv == '-') { |
84 | argc--; | 185 | argc--; |
85 | cp = *argv++; | 186 | cp = *argv++; |
86 | stopNow=FALSE; | 187 | stopNow = FALSE; |
87 | 188 | ||
88 | while (*++cp && stopNow==FALSE) { | 189 | while (*++cp && stopNow == FALSE) { |
89 | switch (*cp) { | 190 | switch (*cp) { |
90 | case 'n': | 191 | case 'n': |
91 | quietFlag = TRUE; | 192 | quietFlag = TRUE; |
92 | break; | 193 | break; |
93 | case 'e': | 194 | case 'e': |
94 | if (*(cp+1)==0 && --argc < 0) { | 195 | if (*(cp + 1) == 0 && --argc < 0) { |
95 | usage( sed_usage); | 196 | usage(sed_usage); |
96 | } | 197 | } |
97 | if ( *++cp != 's') | 198 | if (*++cp != 's') |
98 | cp = *argv++; | 199 | cp = *argv++; |
99 | while( *cp ) { | 200 | |
100 | if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') { | 201 | /* Read address if present */ |
101 | char* pos=needle=cp+2; | 202 | SKIPSPACES(cp); |
102 | for(;;) { | 203 | if (*cp == '$') { |
103 | pos = strchr(pos, '/'); | 204 | addr_line = LAST_LINE; |
104 | if (pos==NULL) { | 205 | cp++; |
105 | usage( sed_usage); | 206 | } else { |
106 | } | 207 | if (isdigit(*cp)) { /* LINE ADDRESS */ |
107 | if (*(pos-1) == '\\') { | 208 | line_s = cp; |
108 | pos++; | 209 | while (isdigit(*cp)) |
109 | continue; | 210 | cp++; |
110 | } | 211 | if (cp > line_s) { |
111 | break; | 212 | /* numeric line */ |
213 | saved = *cp; | ||
214 | *cp = '\0'; | ||
215 | addr_line = atoi(line_s); | ||
216 | *cp = saved; | ||
112 | } | 217 | } |
113 | *pos=0; | 218 | } else if (*cp == '/') { /* PATTERN ADDRESS */ |
114 | newNeedle=++pos; | 219 | pos = addr_pattern = cp + 1; |
115 | for(;;) { | 220 | pos = strchr(pos, '/'); |
116 | pos = strchr(pos, '/'); | 221 | if (!pos) |
117 | if (pos==NULL) { | 222 | usage(sed_usage); |
118 | usage( sed_usage); | 223 | *pos = '\0'; |
119 | } | 224 | cp = pos + 1; |
120 | if (*(pos-1) == '\\') { | 225 | } |
121 | pos++; | 226 | } |
122 | continue; | 227 | |
123 | } | 228 | SKIPSPACES(cp); |
124 | break; | 229 | if (*cp == '!') { |
230 | negated++; | ||
231 | cp++; | ||
232 | } | ||
233 | |||
234 | /* Read command */ | ||
235 | |||
236 | SKIPSPACES(cp); | ||
237 | switch (*cp) { | ||
238 | case 's': /* REPLACE */ | ||
239 | if (strlen(cp) <= 3 || *(cp + 1) != '/') | ||
240 | break; | ||
241 | sed_f = f_replace; | ||
242 | |||
243 | pos = needle = cp + 2; | ||
244 | |||
245 | for (;;) { | ||
246 | pos = strchr(pos, '/'); | ||
247 | if (pos == NULL) { | ||
248 | usage(sed_usage); | ||
249 | } | ||
250 | if (*(pos - 1) == '\\') { | ||
251 | pos++; | ||
252 | continue; | ||
125 | } | 253 | } |
126 | *pos=0; | 254 | break; |
127 | if (pos+2 != 0) { | 255 | } |
128 | while (*++pos) { | 256 | *pos = 0; |
129 | switch (*pos) { | 257 | newNeedle = ++pos; |
130 | case 'i': | 258 | for (;;) { |
131 | ignoreCase=TRUE; | 259 | pos = strchr(pos, '/'); |
132 | break; | 260 | if (pos == NULL) { |
133 | case 'p': | 261 | usage(sed_usage); |
134 | printFlag=TRUE; | 262 | } |
135 | break; | 263 | if (*(pos - 1) == '\\') { |
136 | case 'g': | 264 | pos++; |
137 | break; | 265 | continue; |
138 | default: | 266 | } |
139 | usage( sed_usage); | 267 | break; |
140 | } | 268 | } |
269 | *pos = 0; | ||
270 | if (pos + 2 != 0) { | ||
271 | while (*++pos) { | ||
272 | switch (*pos) { | ||
273 | case 'i': | ||
274 | ignoreCase = TRUE; | ||
275 | break; | ||
276 | case 'p': | ||
277 | printFlag = TRUE; | ||
278 | break; | ||
279 | case 'g': | ||
280 | break; | ||
281 | default: | ||
282 | usage(sed_usage); | ||
141 | } | 283 | } |
142 | } | 284 | } |
143 | } | 285 | } |
144 | cp++; | 286 | cp = pos; |
287 | /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */ | ||
288 | break; | ||
289 | |||
290 | case 'a': /* APPEND */ | ||
291 | if (strlen(cp) < 2) | ||
292 | break; | ||
293 | sed_f = f_append; | ||
294 | appendline = ++cp; | ||
295 | /* fprintf(stderr, "append '%s'\n", appendline); */ | ||
296 | break; | ||
145 | } | 297 | } |
146 | //fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); | 298 | |
147 | stopNow=TRUE; | 299 | stopNow = TRUE; |
148 | break; | 300 | break; |
149 | 301 | ||
150 | default: | 302 | default: |
@@ -153,30 +305,48 @@ extern int sed_main (int argc, char **argv) | |||
153 | } | 305 | } |
154 | } | 306 | } |
155 | 307 | ||
156 | if (argc==0) { | 308 | if (argc == 0) { |
157 | do_sed( stdin, needle, newNeedle, ignoreCase, printFlag, quietFlag); | 309 | switch (sed_f) { |
310 | case f_none: | ||
311 | break; | ||
312 | case f_replace: | ||
313 | do_sed_repl(stdin, needle, newNeedle, ignoreCase, printFlag, | ||
314 | quietFlag); | ||
315 | break; | ||
316 | case f_append: | ||
317 | do_sed_append(stdin, appendline, quietFlag); | ||
318 | break; | ||
319 | } | ||
158 | } else { | 320 | } else { |
159 | while (argc-- > 0) { | 321 | while (argc-- > 0) { |
160 | name = *argv++; | 322 | name = *argv++; |
161 | 323 | ||
162 | fp = fopen (name, "r"); | 324 | fp = fopen(name, "r"); |
163 | if (fp == NULL) { | 325 | if (fp == NULL) { |
164 | perror (name); | 326 | perror(name); |
165 | continue; | 327 | continue; |
166 | } | 328 | } |
167 | 329 | ||
168 | do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag); | 330 | switch (sed_f) { |
331 | case f_none: | ||
332 | break; | ||
333 | case f_replace: | ||
334 | do_sed_repl(fp, needle, newNeedle, ignoreCase, printFlag, | ||
335 | quietFlag); | ||
336 | break; | ||
337 | case f_append: | ||
338 | do_sed_append(fp, appendline, quietFlag); | ||
339 | break; | ||
340 | } | ||
169 | 341 | ||
170 | if (ferror (fp)) | 342 | if (ferror(fp)) |
171 | perror (name); | 343 | perror(name); |
172 | 344 | ||
173 | fclose (fp); | 345 | fclose(fp); |
174 | } | 346 | } |
175 | } | 347 | } |
176 | exit( TRUE); | 348 | exit(TRUE); |
177 | } | 349 | } |
178 | 350 | ||
179 | 351 | ||
180 | /* END CODE */ | 352 | /* END CODE */ |
181 | |||
182 | |||
@@ -193,11 +193,13 @@ static void list_single(const char *name, struct stat *info, const char *fullnam | |||
193 | fputs(" ", stdout); | 193 | fputs(" ", stdout); |
194 | #ifdef BB_FEATURE_LS_USERNAME | 194 | #ifdef BB_FEATURE_LS_USERNAME |
195 | if (!(opts & DISP_NUMERIC)) { | 195 | if (!(opts & DISP_NUMERIC)) { |
196 | scratch[0]='\0'; | 196 | memset ( scratch, 0, sizeof (scratch)); |
197 | my_getpwuid( scratch, info->st_uid); | 197 | my_getpwuid( scratch, info->st_uid); |
198 | scratch[8]='\0'; | 198 | if (*scratch) { |
199 | if (*scratch) | 199 | fputs(scratch, stdout); |
200 | wr(scratch,8); | 200 | if ( strlen( scratch) <= 8 ) |
201 | wr(" ", 8-strlen( scratch)); | ||
202 | } | ||
201 | else { | 203 | else { |
202 | writenum((long) info->st_uid,(short)8); | 204 | writenum((long) info->st_uid,(short)8); |
203 | fputs(" ", stdout); | 205 | fputs(" ", stdout); |
@@ -208,20 +210,21 @@ static void list_single(const char *name, struct stat *info, const char *fullnam | |||
208 | writenum((long) info->st_uid,(short)8); | 210 | writenum((long) info->st_uid,(short)8); |
209 | fputs(" ", stdout); | 211 | fputs(" ", stdout); |
210 | } | 212 | } |
211 | tab(16); | ||
212 | #ifdef BB_FEATURE_LS_USERNAME | 213 | #ifdef BB_FEATURE_LS_USERNAME |
213 | if (!(opts & DISP_NUMERIC)) { | 214 | if (!(opts & DISP_NUMERIC)) { |
214 | scratch[0]='\0'; | 215 | memset ( scratch, 0, sizeof (scratch)); |
215 | my_getgrgid( scratch, info->st_gid); | 216 | my_getgrgid( scratch, info->st_gid); |
216 | scratch[8]='\0'; | 217 | if (*scratch) { |
217 | if (*scratch) | 218 | fputs(scratch, stdout); |
218 | wr(scratch,8); | 219 | if ( strlen( scratch) <= 8 ) |
220 | wr(" ", 8-strlen( scratch)); | ||
221 | } | ||
219 | else | 222 | else |
220 | writenum((long) info->st_gid,(short)8); | 223 | writenum((long) info->st_gid,(short)8); |
221 | } else | 224 | } else |
222 | #endif | 225 | #endif |
223 | writenum((long) info->st_gid,(short)8); | 226 | writenum((long) info->st_gid,(short)8); |
224 | tab(17); | 227 | //tab(26); |
225 | if (S_ISBLK(mode) || S_ISCHR(mode)) { | 228 | if (S_ISBLK(mode) || S_ISCHR(mode)) { |
226 | writenum((long)MAJOR(info->st_rdev),(short)3); | 229 | writenum((long)MAJOR(info->st_rdev),(short)3); |
227 | fputs(", ", stdout); | 230 | fputs(", ", stdout); |
@@ -230,6 +233,7 @@ static void list_single(const char *name, struct stat *info, const char *fullnam | |||
230 | else | 233 | else |
231 | writenum((long)info->st_size,(short)8); | 234 | writenum((long)info->st_size,(short)8); |
232 | fputs(" ", stdout); | 235 | fputs(" ", stdout); |
236 | //tab(32); | ||
233 | #ifdef BB_FEATURE_LS_TIMESTAMPS | 237 | #ifdef BB_FEATURE_LS_TIMESTAMPS |
234 | { | 238 | { |
235 | time_t cal; | 239 | time_t cal; |
@@ -5,6 +5,11 @@ | |||
5 | * Copyright (C) 1999 by Lineo, inc. | 5 | * Copyright (C) 1999 by Lineo, inc. |
6 | * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> | 6 | * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> |
7 | * | 7 | * |
8 | * Modifications for addresses and append command have been | ||
9 | * written by Marco Pantaleoni <panta@prosa.it>, <panta@elasticworld.org> | ||
10 | * and are: | ||
11 | * Copyright (C) 1999 Marco Pantaleoni. | ||
12 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 14 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 15 | * the Free Software Foundation; either version 2 of the License, or |
@@ -31,48 +36,144 @@ | |||
31 | #include <time.h> | 36 | #include <time.h> |
32 | #include <ctype.h> | 37 | #include <ctype.h> |
33 | 38 | ||
34 | static const char sed_usage[] = | 39 | static const char sed_usage[] = |
35 | "sed [-n] [-e script] [file...]\n\n" | 40 | "sed [-n] -e script [file...]\n\n" |
36 | "Allowed sed scripts come in the following form:\n" | 41 | "Allowed sed scripts come in the following form:\n" |
37 | "\t's/regexp/replacement/[gp]'\n" | 42 | "\t'ADDR [!] COMMAND'\n\n" |
38 | "which attempt to match regexp against the pattern space\n" | 43 | "\twhere address ADDR can be:\n" |
39 | "and if successful replaces the matched portion with replacement.\n\n" | 44 | "\t NUMBER Match specified line number\n" |
40 | "Options:\n" | 45 | "\t $ Match last line\n" |
41 | "-e\tadd the script to the commands to be executed\n" | 46 | "\t /REGEXP/ Match specified regexp\n" |
42 | "-n\tsuppress automatic printing of pattern space\n\n" | 47 | "\t (! inverts the meaning of the match)\n\n" |
48 | "\tand COMMAND can be:\n" | ||
49 | "\t s/regexp/replacement/[gp]\n" | ||
50 | "\t which attempt to match regexp against the pattern space\n" | ||
51 | "\t and if successful replaces the matched portion with replacement.\n\n" | ||
52 | "\t aTEXT\n" | ||
53 | "\t which appends TEXT after the pattern space\n" | ||
54 | "Options:\n" | ||
55 | "-e\tadd the script to the commands to be executed\n" | ||
56 | "-n\tsuppress automatic printing of pattern space\n\n" | ||
43 | #if defined BB_REGEXP | 57 | #if defined BB_REGEXP |
44 | "This version of sed matches full regular expresions.\n"; | 58 | "This version of sed matches full regular expresions.\n"; |
45 | #else | 59 | #else |
46 | "This version of sed matches strings (not full regular expresions).\n"; | 60 | "This version of sed matches strings (not full regular expresions).\n"; |
47 | #endif | 61 | #endif |
48 | |||
49 | 62 | ||
50 | static void do_sed(FILE *fp, char *needle, char *newNeedle, int ignoreCase, int printFlag, int quietFlag) | 63 | /* Flags & variables */ |
64 | |||
65 | typedef enum { f_none, f_replace, f_append } sed_function; | ||
66 | |||
67 | #define NO_LINE -2 | ||
68 | #define LAST_LINE -1 | ||
69 | static int addr_line = NO_LINE; | ||
70 | static char *addr_pattern = NULL; | ||
71 | static int negated = 0; | ||
72 | |||
73 | #define SKIPSPACES(p) do { while (isspace(*(p))) (p)++; } while (0) | ||
74 | |||
75 | #define BUFSIZE 1024 | ||
76 | |||
77 | static inline int at_last(FILE * fp) | ||
51 | { | 78 | { |
52 | int foundOne=FALSE; | 79 | int res = 0; |
53 | char haystack[1024]; | ||
54 | 80 | ||
55 | while (fgets (haystack, 1023, fp)) { | 81 | if (feof(fp)) |
56 | foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); | 82 | return 1; |
57 | if (foundOne==TRUE && printFlag==TRUE) { | 83 | else { |
58 | fprintf(stdout, haystack); | 84 | char ch; |
85 | if ((ch = fgetc(fp)) == EOF) | ||
86 | res++; | ||
87 | ungetc(ch, fp); | ||
88 | } | ||
89 | return res; | ||
90 | } | ||
91 | |||
92 | static void do_sed_repl(FILE * fp, char *needle, char *newNeedle, | ||
93 | int ignoreCase, int printFlag, int quietFlag) | ||
94 | { | ||
95 | int foundOne = FALSE; | ||
96 | char haystack[BUFSIZE]; | ||
97 | int line = 1, doit; | ||
98 | |||
99 | while (fgets(haystack, BUFSIZE - 1, fp)) { | ||
100 | doit = 0; | ||
101 | if (addr_pattern) { | ||
102 | doit = !find_match(haystack, addr_pattern, FALSE); | ||
103 | } else if (addr_line == NO_LINE) | ||
104 | doit = 1; | ||
105 | else if (addr_line == LAST_LINE) { | ||
106 | if (at_last(fp)) | ||
107 | doit = 1; | ||
108 | } else { | ||
109 | if (line == addr_line) | ||
110 | doit = 1; | ||
111 | } | ||
112 | if (negated) | ||
113 | doit = 1 - doit; | ||
114 | if (doit) { | ||
115 | foundOne = | ||
116 | replace_match(haystack, needle, newNeedle, ignoreCase); | ||
117 | |||
118 | if (foundOne == TRUE && printFlag == TRUE) { | ||
119 | fprintf(stdout, haystack); | ||
120 | } | ||
59 | } | 121 | } |
60 | if (quietFlag==FALSE) { | 122 | |
123 | if (quietFlag == FALSE) { | ||
61 | fprintf(stdout, haystack); | 124 | fprintf(stdout, haystack); |
62 | } | 125 | } |
126 | |||
127 | line++; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static void do_sed_append(FILE * fp, char *appendline, int quietFlag) | ||
132 | { | ||
133 | char buffer[BUFSIZE]; | ||
134 | int line = 1, doit; | ||
135 | |||
136 | while (fgets(buffer, BUFSIZE - 1, fp)) { | ||
137 | doit = 0; | ||
138 | if (addr_pattern) { | ||
139 | doit = !find_match(buffer, addr_pattern, FALSE); | ||
140 | } else if (addr_line == NO_LINE) | ||
141 | doit = 1; | ||
142 | else if (addr_line == LAST_LINE) { | ||
143 | if (at_last(fp)) | ||
144 | doit = 1; | ||
145 | } else { | ||
146 | if (line == addr_line) | ||
147 | doit = 1; | ||
148 | } | ||
149 | if (negated) | ||
150 | doit = 1 - doit; | ||
151 | if (quietFlag == FALSE) { | ||
152 | fprintf(stdout, buffer); | ||
153 | } | ||
154 | if (doit) { | ||
155 | fputs(appendline, stdout); | ||
156 | fputc('\n', stdout); | ||
157 | } | ||
158 | |||
159 | line++; | ||
63 | } | 160 | } |
64 | } | 161 | } |
65 | 162 | ||
66 | extern int sed_main (int argc, char **argv) | 163 | extern int sed_main(int argc, char **argv) |
67 | { | 164 | { |
68 | FILE *fp; | 165 | FILE *fp; |
69 | char *needle=NULL, *newNeedle=NULL; | 166 | char *needle = NULL, *newNeedle = NULL; |
70 | char *name; | 167 | char *name; |
71 | char *cp; | 168 | char *cp; |
72 | int ignoreCase=FALSE; | 169 | int ignoreCase = FALSE; |
73 | int printFlag=FALSE; | 170 | int printFlag = FALSE; |
74 | int quietFlag=FALSE; | 171 | int quietFlag = FALSE; |
75 | int stopNow; | 172 | int stopNow; |
173 | char *line_s = NULL, saved; | ||
174 | char *appendline = NULL; | ||
175 | char *pos; | ||
176 | sed_function sed_f = f_none; | ||
76 | 177 | ||
77 | argc--; | 178 | argc--; |
78 | argv++; | 179 | argv++; |
@@ -83,68 +184,119 @@ extern int sed_main (int argc, char **argv) | |||
83 | if (**argv == '-') { | 184 | if (**argv == '-') { |
84 | argc--; | 185 | argc--; |
85 | cp = *argv++; | 186 | cp = *argv++; |
86 | stopNow=FALSE; | 187 | stopNow = FALSE; |
87 | 188 | ||
88 | while (*++cp && stopNow==FALSE) { | 189 | while (*++cp && stopNow == FALSE) { |
89 | switch (*cp) { | 190 | switch (*cp) { |
90 | case 'n': | 191 | case 'n': |
91 | quietFlag = TRUE; | 192 | quietFlag = TRUE; |
92 | break; | 193 | break; |
93 | case 'e': | 194 | case 'e': |
94 | if (*(cp+1)==0 && --argc < 0) { | 195 | if (*(cp + 1) == 0 && --argc < 0) { |
95 | usage( sed_usage); | 196 | usage(sed_usage); |
96 | } | 197 | } |
97 | if ( *++cp != 's') | 198 | if (*++cp != 's') |
98 | cp = *argv++; | 199 | cp = *argv++; |
99 | while( *cp ) { | 200 | |
100 | if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') { | 201 | /* Read address if present */ |
101 | char* pos=needle=cp+2; | 202 | SKIPSPACES(cp); |
102 | for(;;) { | 203 | if (*cp == '$') { |
103 | pos = strchr(pos, '/'); | 204 | addr_line = LAST_LINE; |
104 | if (pos==NULL) { | 205 | cp++; |
105 | usage( sed_usage); | 206 | } else { |
106 | } | 207 | if (isdigit(*cp)) { /* LINE ADDRESS */ |
107 | if (*(pos-1) == '\\') { | 208 | line_s = cp; |
108 | pos++; | 209 | while (isdigit(*cp)) |
109 | continue; | 210 | cp++; |
110 | } | 211 | if (cp > line_s) { |
111 | break; | 212 | /* numeric line */ |
213 | saved = *cp; | ||
214 | *cp = '\0'; | ||
215 | addr_line = atoi(line_s); | ||
216 | *cp = saved; | ||
112 | } | 217 | } |
113 | *pos=0; | 218 | } else if (*cp == '/') { /* PATTERN ADDRESS */ |
114 | newNeedle=++pos; | 219 | pos = addr_pattern = cp + 1; |
115 | for(;;) { | 220 | pos = strchr(pos, '/'); |
116 | pos = strchr(pos, '/'); | 221 | if (!pos) |
117 | if (pos==NULL) { | 222 | usage(sed_usage); |
118 | usage( sed_usage); | 223 | *pos = '\0'; |
119 | } | 224 | cp = pos + 1; |
120 | if (*(pos-1) == '\\') { | 225 | } |
121 | pos++; | 226 | } |
122 | continue; | 227 | |
123 | } | 228 | SKIPSPACES(cp); |
124 | break; | 229 | if (*cp == '!') { |
230 | negated++; | ||
231 | cp++; | ||
232 | } | ||
233 | |||
234 | /* Read command */ | ||
235 | |||
236 | SKIPSPACES(cp); | ||
237 | switch (*cp) { | ||
238 | case 's': /* REPLACE */ | ||
239 | if (strlen(cp) <= 3 || *(cp + 1) != '/') | ||
240 | break; | ||
241 | sed_f = f_replace; | ||
242 | |||
243 | pos = needle = cp + 2; | ||
244 | |||
245 | for (;;) { | ||
246 | pos = strchr(pos, '/'); | ||
247 | if (pos == NULL) { | ||
248 | usage(sed_usage); | ||
249 | } | ||
250 | if (*(pos - 1) == '\\') { | ||
251 | pos++; | ||
252 | continue; | ||
125 | } | 253 | } |
126 | *pos=0; | 254 | break; |
127 | if (pos+2 != 0) { | 255 | } |
128 | while (*++pos) { | 256 | *pos = 0; |
129 | switch (*pos) { | 257 | newNeedle = ++pos; |
130 | case 'i': | 258 | for (;;) { |
131 | ignoreCase=TRUE; | 259 | pos = strchr(pos, '/'); |
132 | break; | 260 | if (pos == NULL) { |
133 | case 'p': | 261 | usage(sed_usage); |
134 | printFlag=TRUE; | 262 | } |
135 | break; | 263 | if (*(pos - 1) == '\\') { |
136 | case 'g': | 264 | pos++; |
137 | break; | 265 | continue; |
138 | default: | 266 | } |
139 | usage( sed_usage); | 267 | break; |
140 | } | 268 | } |
269 | *pos = 0; | ||
270 | if (pos + 2 != 0) { | ||
271 | while (*++pos) { | ||
272 | switch (*pos) { | ||
273 | case 'i': | ||
274 | ignoreCase = TRUE; | ||
275 | break; | ||
276 | case 'p': | ||
277 | printFlag = TRUE; | ||
278 | break; | ||
279 | case 'g': | ||
280 | break; | ||
281 | default: | ||
282 | usage(sed_usage); | ||
141 | } | 283 | } |
142 | } | 284 | } |
143 | } | 285 | } |
144 | cp++; | 286 | cp = pos; |
287 | /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */ | ||
288 | break; | ||
289 | |||
290 | case 'a': /* APPEND */ | ||
291 | if (strlen(cp) < 2) | ||
292 | break; | ||
293 | sed_f = f_append; | ||
294 | appendline = ++cp; | ||
295 | /* fprintf(stderr, "append '%s'\n", appendline); */ | ||
296 | break; | ||
145 | } | 297 | } |
146 | //fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); | 298 | |
147 | stopNow=TRUE; | 299 | stopNow = TRUE; |
148 | break; | 300 | break; |
149 | 301 | ||
150 | default: | 302 | default: |
@@ -153,30 +305,48 @@ extern int sed_main (int argc, char **argv) | |||
153 | } | 305 | } |
154 | } | 306 | } |
155 | 307 | ||
156 | if (argc==0) { | 308 | if (argc == 0) { |
157 | do_sed( stdin, needle, newNeedle, ignoreCase, printFlag, quietFlag); | 309 | switch (sed_f) { |
310 | case f_none: | ||
311 | break; | ||
312 | case f_replace: | ||
313 | do_sed_repl(stdin, needle, newNeedle, ignoreCase, printFlag, | ||
314 | quietFlag); | ||
315 | break; | ||
316 | case f_append: | ||
317 | do_sed_append(stdin, appendline, quietFlag); | ||
318 | break; | ||
319 | } | ||
158 | } else { | 320 | } else { |
159 | while (argc-- > 0) { | 321 | while (argc-- > 0) { |
160 | name = *argv++; | 322 | name = *argv++; |
161 | 323 | ||
162 | fp = fopen (name, "r"); | 324 | fp = fopen(name, "r"); |
163 | if (fp == NULL) { | 325 | if (fp == NULL) { |
164 | perror (name); | 326 | perror(name); |
165 | continue; | 327 | continue; |
166 | } | 328 | } |
167 | 329 | ||
168 | do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag); | 330 | switch (sed_f) { |
331 | case f_none: | ||
332 | break; | ||
333 | case f_replace: | ||
334 | do_sed_repl(fp, needle, newNeedle, ignoreCase, printFlag, | ||
335 | quietFlag); | ||
336 | break; | ||
337 | case f_append: | ||
338 | do_sed_append(fp, appendline, quietFlag); | ||
339 | break; | ||
340 | } | ||
169 | 341 | ||
170 | if (ferror (fp)) | 342 | if (ferror(fp)) |
171 | perror (name); | 343 | perror(name); |
172 | 344 | ||
173 | fclose (fp); | 345 | fclose(fp); |
174 | } | 346 | } |
175 | } | 347 | } |
176 | exit( TRUE); | 348 | exit(TRUE); |
177 | } | 349 | } |
178 | 350 | ||
179 | 351 | ||
180 | /* END CODE */ | 352 | /* END CODE */ |
181 | |||
182 | |||
diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c index aa26f5836..e38fd5555 100644 --- a/util-linux/dmesg.c +++ b/util-linux/dmesg.c | |||
@@ -44,10 +44,15 @@ int dmesg_main( int argc, char** argv ) | |||
44 | int level = 0; | 44 | int level = 0; |
45 | int lastc; | 45 | int lastc; |
46 | int cmd = 3; | 46 | int cmd = 3; |
47 | int stopDoingThat; | ||
48 | |||
49 | argc--; | ||
50 | argv++; | ||
47 | 51 | ||
48 | /* Parse any options */ | 52 | /* Parse any options */ |
49 | while (argc && **argv == '-') { | 53 | while (argc && **argv == '-') { |
50 | while (*++(*argv)) | 54 | stopDoingThat = FALSE; |
55 | while (stopDoingThat == FALSE && *++(*argv)) { | ||
51 | switch (**argv) { | 56 | switch (**argv) { |
52 | case 'c': | 57 | case 'c': |
53 | cmd = 4; | 58 | cmd = 4; |
@@ -57,19 +62,22 @@ int dmesg_main( int argc, char** argv ) | |||
57 | if (--argc == 0) | 62 | if (--argc == 0) |
58 | goto end; | 63 | goto end; |
59 | level = atoi (*(++argv)); | 64 | level = atoi (*(++argv)); |
60 | --argc; | 65 | if (--argc > 0) |
61 | ++argv; | 66 | ++argv; |
67 | stopDoingThat = TRUE; | ||
62 | break; | 68 | break; |
63 | case 's': | 69 | case 's': |
64 | if (--argc == 0) | 70 | if (--argc == 0) |
65 | goto end; | 71 | goto end; |
66 | bufsize = atoi (*(++argv)); | 72 | bufsize = atoi (*(++argv)); |
67 | --argc; | 73 | if (--argc > 0) |
68 | ++argv; | 74 | ++argv; |
75 | stopDoingThat = TRUE; | ||
69 | break; | 76 | break; |
70 | default: | 77 | default: |
71 | goto end; | 78 | goto end; |
72 | } | 79 | } |
80 | } | ||
73 | } | 81 | } |
74 | 82 | ||
75 | if (argc > 1) { | 83 | if (argc > 1) { |