Magellan Linux

Annotation of /trunk/mkinitrd-magellan/klibc/usr/dash/show.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide 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)
-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 niro 532 /*-
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 */