Contents of /trunk/mkinitrd-magellan/klibc/usr/dash/show.c
Parent Directory | Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 8034 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 8034 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | /*- |
2 | * Copyright (c) 1991, 1993 |
3 | * The Regents of the University of California. All rights reserved. |
4 | * Copyright (c) 1997-2005 |
5 | * Herbert Xu <herbert@gondor.apana.org.au>. All rights reserved. |
6 | * |
7 | * This code is derived from software contributed to Berkeley by |
8 | * Kenneth Almquist. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
18 | * 3. Neither the name of the University nor the names of its contributors |
19 | * may be used to endorse or promote products derived from this software |
20 | * without specific prior written permission. |
21 | * |
22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
32 | * SUCH DAMAGE. |
33 | */ |
34 | |
35 | #include <stdio.h> |
36 | #include <stdarg.h> |
37 | |
38 | #include "shell.h" |
39 | #include "parser.h" |
40 | #include "nodes.h" |
41 | #include "mystring.h" |
42 | #include "show.h" |
43 | #include "options.h" |
44 | |
45 | |
46 | #ifdef DEBUG |
47 | static void shtree(union node *, int, char *, FILE*); |
48 | static void shcmd(union node *, FILE *); |
49 | static void sharg(union node *, FILE *); |
50 | static void indent(int, char *, FILE *); |
51 | static void trstring(char *); |
52 | |
53 | |
54 | void |
55 | showtree(union node *n) |
56 | { |
57 | trputs("showtree called\n"); |
58 | shtree(n, 1, NULL, stdout); |
59 | } |
60 | |
61 | |
62 | static void |
63 | shtree(union node *n, int ind, char *pfx, FILE *fp) |
64 | { |
65 | struct nodelist *lp; |
66 | const char *s; |
67 | |
68 | if (n == NULL) |
69 | return; |
70 | |
71 | indent(ind, pfx, fp); |
72 | switch(n->type) { |
73 | case NSEMI: |
74 | s = "; "; |
75 | goto binop; |
76 | case NAND: |
77 | s = " && "; |
78 | goto binop; |
79 | case NOR: |
80 | s = " || "; |
81 | binop: |
82 | shtree(n->nbinary.ch1, ind, NULL, fp); |
83 | /* if (ind < 0) */ |
84 | fputs(s, fp); |
85 | shtree(n->nbinary.ch2, ind, NULL, fp); |
86 | break; |
87 | case NCMD: |
88 | shcmd(n, fp); |
89 | if (ind >= 0) |
90 | putc('\n', fp); |
91 | break; |
92 | case NPIPE: |
93 | for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { |
94 | shcmd(lp->n, fp); |
95 | if (lp->next) |
96 | fputs(" | ", fp); |
97 | } |
98 | if (n->npipe.backgnd) |
99 | fputs(" &", fp); |
100 | if (ind >= 0) |
101 | putc('\n', fp); |
102 | break; |
103 | default: |
104 | fprintf(fp, "<node type %d>", n->type); |
105 | if (ind >= 0) |
106 | putc('\n', fp); |
107 | break; |
108 | } |
109 | } |
110 | |
111 | |
112 | |
113 | static void |
114 | shcmd(union node *cmd, FILE *fp) |
115 | { |
116 | union node *np; |
117 | int first; |
118 | const char *s; |
119 | int dftfd; |
120 | |
121 | first = 1; |
122 | for (np = cmd->ncmd.args ; np ; np = np->narg.next) { |
123 | if (! first) |
124 | putchar(' '); |
125 | sharg(np, fp); |
126 | first = 0; |
127 | } |
128 | for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { |
129 | if (! first) |
130 | putchar(' '); |
131 | switch (np->nfile.type) { |
132 | case NTO: s = ">"; dftfd = 1; break; |
133 | case NCLOBBER: s = ">|"; dftfd = 1; break; |
134 | case NAPPEND: s = ">>"; dftfd = 1; break; |
135 | case NTOFD: s = ">&"; dftfd = 1; break; |
136 | case NFROM: s = "<"; dftfd = 0; break; |
137 | case NFROMFD: s = "<&"; dftfd = 0; break; |
138 | case NFROMTO: s = "<>"; dftfd = 0; break; |
139 | default: s = "*error*"; dftfd = 0; break; |
140 | } |
141 | if (np->nfile.fd != dftfd) |
142 | fprintf(fp, "%d", np->nfile.fd); |
143 | fputs(s, fp); |
144 | if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) { |
145 | fprintf(fp, "%d", np->ndup.dupfd); |
146 | } else { |
147 | sharg(np->nfile.fname, fp); |
148 | } |
149 | first = 0; |
150 | } |
151 | } |
152 | |
153 | |
154 | |
155 | static void |
156 | sharg(union node *arg, FILE *fp) |
157 | { |
158 | char *p; |
159 | struct nodelist *bqlist; |
160 | int subtype; |
161 | |
162 | if (arg->type != NARG) { |
163 | printf("<node type %d>\n", arg->type); |
164 | abort(); |
165 | } |
166 | bqlist = arg->narg.backquote; |
167 | for (p = arg->narg.text ; *p ; p++) { |
168 | switch ((signed char)*p) { |
169 | case CTLESC: |
170 | putc(*++p, fp); |
171 | break; |
172 | case CTLVAR: |
173 | putc('$', fp); |
174 | putc('{', fp); |
175 | subtype = *++p; |
176 | if (subtype == VSLENGTH) |
177 | putc('#', fp); |
178 | |
179 | while (*p != '=') |
180 | putc(*p++, fp); |
181 | |
182 | if (subtype & VSNUL) |
183 | putc(':', fp); |
184 | |
185 | switch (subtype & VSTYPE) { |
186 | case VSNORMAL: |
187 | putc('}', fp); |
188 | break; |
189 | case VSMINUS: |
190 | putc('-', fp); |
191 | break; |
192 | case VSPLUS: |
193 | putc('+', fp); |
194 | break; |
195 | case VSQUESTION: |
196 | putc('?', fp); |
197 | break; |
198 | case VSASSIGN: |
199 | putc('=', fp); |
200 | break; |
201 | case VSTRIMLEFT: |
202 | putc('#', fp); |
203 | break; |
204 | case VSTRIMLEFTMAX: |
205 | putc('#', fp); |
206 | putc('#', fp); |
207 | break; |
208 | case VSTRIMRIGHT: |
209 | putc('%', fp); |
210 | break; |
211 | case VSTRIMRIGHTMAX: |
212 | putc('%', fp); |
213 | putc('%', fp); |
214 | break; |
215 | case VSLENGTH: |
216 | break; |
217 | default: |
218 | printf("<subtype %d>", subtype); |
219 | } |
220 | break; |
221 | case CTLENDVAR: |
222 | putc('}', fp); |
223 | break; |
224 | case CTLBACKQ: |
225 | case CTLBACKQ|CTLQUOTE: |
226 | putc('$', fp); |
227 | putc('(', fp); |
228 | shtree(bqlist->n, -1, NULL, fp); |
229 | putc(')', fp); |
230 | break; |
231 | default: |
232 | putc(*p, fp); |
233 | break; |
234 | } |
235 | } |
236 | } |
237 | |
238 | |
239 | static void |
240 | indent(int amount, char *pfx, FILE *fp) |
241 | { |
242 | int i; |
243 | |
244 | for (i = 0 ; i < amount ; i++) { |
245 | if (pfx && i == amount - 1) |
246 | fputs(pfx, fp); |
247 | putc('\t', fp); |
248 | } |
249 | } |
250 | |
251 | |
252 | |
253 | /* |
254 | * Debugging stuff. |
255 | */ |
256 | |
257 | |
258 | FILE *tracefile; |
259 | |
260 | |
261 | void |
262 | trputc(int c) |
263 | { |
264 | if (debug != 1) |
265 | return; |
266 | putc(c, tracefile); |
267 | } |
268 | |
269 | void |
270 | trace(const char *fmt, ...) |
271 | { |
272 | va_list va; |
273 | |
274 | if (debug != 1) |
275 | return; |
276 | va_start(va, fmt); |
277 | (void) vfprintf(tracefile, fmt, va); |
278 | va_end(va); |
279 | } |
280 | |
281 | void |
282 | tracev(const char *fmt, va_list va) |
283 | { |
284 | if (debug != 1) |
285 | return; |
286 | (void) vfprintf(tracefile, fmt, va); |
287 | } |
288 | |
289 | |
290 | void |
291 | trputs(const char *s) |
292 | { |
293 | if (debug != 1) |
294 | return; |
295 | fputs(s, tracefile); |
296 | } |
297 | |
298 | |
299 | static void |
300 | trstring(char *s) |
301 | { |
302 | char *p; |
303 | char c; |
304 | |
305 | if (debug != 1) |
306 | return; |
307 | putc('"', tracefile); |
308 | for (p = s ; *p ; p++) { |
309 | switch ((signed char)*p) { |
310 | case '\n': c = 'n'; goto backslash; |
311 | case '\t': c = 't'; goto backslash; |
312 | case '\r': c = 'r'; goto backslash; |
313 | case '"': c = '"'; goto backslash; |
314 | case '\\': c = '\\'; goto backslash; |
315 | case CTLESC: c = 'e'; goto backslash; |
316 | case CTLVAR: c = 'v'; goto backslash; |
317 | case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; |
318 | case CTLBACKQ: c = 'q'; goto backslash; |
319 | case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; |
320 | backslash: putc('\\', tracefile); |
321 | putc(c, tracefile); |
322 | break; |
323 | default: |
324 | if (*p >= ' ' && *p <= '~') |
325 | putc(*p, tracefile); |
326 | else { |
327 | putc('\\', tracefile); |
328 | putc(*p >> 6 & 03, tracefile); |
329 | putc(*p >> 3 & 07, tracefile); |
330 | putc(*p & 07, tracefile); |
331 | } |
332 | break; |
333 | } |
334 | } |
335 | putc('"', tracefile); |
336 | } |
337 | |
338 | |
339 | void |
340 | trargs(char **ap) |
341 | { |
342 | if (debug != 1) |
343 | return; |
344 | while (*ap) { |
345 | trstring(*ap++); |
346 | if (*ap) |
347 | putc(' ', tracefile); |
348 | else |
349 | putc('\n', tracefile); |
350 | } |
351 | } |
352 | |
353 | |
354 | void |
355 | opentrace(void) |
356 | { |
357 | char s[100]; |
358 | #ifdef O_APPEND |
359 | int flags; |
360 | #endif |
361 | |
362 | if (debug != 1) { |
363 | if (tracefile) |
364 | fflush(tracefile); |
365 | /* leave open because libedit might be using it */ |
366 | return; |
367 | } |
368 | #ifdef not_this_way |
369 | { |
370 | char *p; |
371 | if ((p = getenv(homestr)) == NULL) { |
372 | if (geteuid() == 0) |
373 | p = "/"; |
374 | else |
375 | p = "/tmp"; |
376 | } |
377 | scopy(p, s); |
378 | strcat(s, "/trace"); |
379 | } |
380 | #else |
381 | scopy("./trace", s); |
382 | #endif /* not_this_way */ |
383 | if (tracefile) { |
384 | if (!freopen(s, "a", tracefile)) { |
385 | fprintf(stderr, "Can't re-open %s\n", s); |
386 | debug = 0; |
387 | return; |
388 | } |
389 | } else { |
390 | if ((tracefile = fopen(s, "a")) == NULL) { |
391 | fprintf(stderr, "Can't open %s\n", s); |
392 | debug = 0; |
393 | return; |
394 | } |
395 | } |
396 | #ifdef O_APPEND |
397 | if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0) |
398 | fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND); |
399 | #endif |
400 | setlinebuf(tracefile); |
401 | fputs("\nTracing started.\n", tracefile); |
402 | } |
403 | #endif /* DEBUG */ |