show.c revision 1556
11556Srgrimes/*- 21556Srgrimes * Copyright (c) 1991, 1993 31556Srgrimes * The Regents of the University of California. All rights reserved. 41556Srgrimes * 51556Srgrimes * This code is derived from software contributed to Berkeley by 61556Srgrimes * Kenneth Almquist. 71556Srgrimes * 81556Srgrimes * Redistribution and use in source and binary forms, with or without 91556Srgrimes * modification, are permitted provided that the following conditions 101556Srgrimes * are met: 111556Srgrimes * 1. Redistributions of source code must retain the above copyright 121556Srgrimes * notice, this list of conditions and the following disclaimer. 131556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141556Srgrimes * notice, this list of conditions and the following disclaimer in the 151556Srgrimes * documentation and/or other materials provided with the distribution. 161556Srgrimes * 3. All advertising materials mentioning features or use of this software 171556Srgrimes * must display the following acknowledgement: 181556Srgrimes * This product includes software developed by the University of 191556Srgrimes * California, Berkeley and its contributors. 201556Srgrimes * 4. Neither the name of the University nor the names of its contributors 211556Srgrimes * may be used to endorse or promote products derived from this software 221556Srgrimes * without specific prior written permission. 231556Srgrimes * 241556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341556Srgrimes * SUCH DAMAGE. 351556Srgrimes */ 361556Srgrimes 371556Srgrimes#ifndef lint 381556Srgrimesstatic char sccsid[] = "@(#)show.c 8.1 (Berkeley) 5/31/93"; 391556Srgrimes#endif /* not lint */ 401556Srgrimes 411556Srgrimes#include <stdio.h> 421556Srgrimes#include "shell.h" 431556Srgrimes#include "parser.h" 441556Srgrimes#include "nodes.h" 451556Srgrimes#include "mystring.h" 461556Srgrimes 471556Srgrimes 481556Srgrimes#ifdef DEBUG 491556Srgrimesstatic shtree(), shcmd(), sharg(), indent(); 501556Srgrimes 511556Srgrimes 521556Srgrimesshowtree(n) 531556Srgrimes union node *n; 541556Srgrimes { 551556Srgrimes trputs("showtree called\n"); 561556Srgrimes shtree(n, 1, NULL, stdout); 571556Srgrimes} 581556Srgrimes 591556Srgrimes 601556Srgrimesstatic 611556Srgrimesshtree(n, ind, pfx, fp) 621556Srgrimes union node *n; 631556Srgrimes char *pfx; 641556Srgrimes FILE *fp; 651556Srgrimes { 661556Srgrimes struct nodelist *lp; 671556Srgrimes char *s; 681556Srgrimes 691556Srgrimes indent(ind, pfx, fp); 701556Srgrimes switch(n->type) { 711556Srgrimes case NSEMI: 721556Srgrimes s = "; "; 731556Srgrimes goto binop; 741556Srgrimes case NAND: 751556Srgrimes s = " && "; 761556Srgrimes goto binop; 771556Srgrimes case NOR: 781556Srgrimes s = " || "; 791556Srgrimesbinop: 801556Srgrimes shtree(n->nbinary.ch1, ind, NULL, fp); 811556Srgrimes /* if (ind < 0) */ 821556Srgrimes fputs(s, fp); 831556Srgrimes shtree(n->nbinary.ch2, ind, NULL, fp); 841556Srgrimes break; 851556Srgrimes case NCMD: 861556Srgrimes shcmd(n, fp); 871556Srgrimes if (ind >= 0) 881556Srgrimes putc('\n', fp); 891556Srgrimes break; 901556Srgrimes case NPIPE: 911556Srgrimes for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { 921556Srgrimes shcmd(lp->n, fp); 931556Srgrimes if (lp->next) 941556Srgrimes fputs(" | ", fp); 951556Srgrimes } 961556Srgrimes if (n->npipe.backgnd) 971556Srgrimes fputs(" &", fp); 981556Srgrimes if (ind >= 0) 991556Srgrimes putc('\n', fp); 1001556Srgrimes break; 1011556Srgrimes default: 1021556Srgrimes fprintf(fp, "<node type %d>", n->type); 1031556Srgrimes if (ind >= 0) 1041556Srgrimes putc('\n', fp); 1051556Srgrimes break; 1061556Srgrimes } 1071556Srgrimes} 1081556Srgrimes 1091556Srgrimes 1101556Srgrimes 1111556Srgrimesstatic 1121556Srgrimesshcmd(cmd, fp) 1131556Srgrimes union node *cmd; 1141556Srgrimes FILE *fp; 1151556Srgrimes { 1161556Srgrimes union node *np; 1171556Srgrimes int first; 1181556Srgrimes char *s; 1191556Srgrimes int dftfd; 1201556Srgrimes 1211556Srgrimes first = 1; 1221556Srgrimes for (np = cmd->ncmd.args ; np ; np = np->narg.next) { 1231556Srgrimes if (! first) 1241556Srgrimes putchar(' '); 1251556Srgrimes sharg(np, fp); 1261556Srgrimes first = 0; 1271556Srgrimes } 1281556Srgrimes for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { 1291556Srgrimes if (! first) 1301556Srgrimes putchar(' '); 1311556Srgrimes switch (np->nfile.type) { 1321556Srgrimes case NTO: s = ">"; dftfd = 1; break; 1331556Srgrimes case NAPPEND: s = ">>"; dftfd = 1; break; 1341556Srgrimes case NTOFD: s = ">&"; dftfd = 1; break; 1351556Srgrimes case NFROM: s = "<"; dftfd = 0; break; 1361556Srgrimes case NFROMFD: s = "<&"; dftfd = 0; break; 1371556Srgrimes } 1381556Srgrimes if (np->nfile.fd != dftfd) 1391556Srgrimes fprintf(fp, "%d", np->nfile.fd); 1401556Srgrimes fputs(s, fp); 1411556Srgrimes if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) { 1421556Srgrimes fprintf(fp, "%d", np->ndup.dupfd); 1431556Srgrimes } else { 1441556Srgrimes sharg(np->nfile.fname, fp); 1451556Srgrimes } 1461556Srgrimes first = 0; 1471556Srgrimes } 1481556Srgrimes} 1491556Srgrimes 1501556Srgrimes 1511556Srgrimes 1521556Srgrimesstatic 1531556Srgrimessharg(arg, fp) 1541556Srgrimes union node *arg; 1551556Srgrimes FILE *fp; 1561556Srgrimes { 1571556Srgrimes char *p; 1581556Srgrimes struct nodelist *bqlist; 1591556Srgrimes int subtype; 1601556Srgrimes 1611556Srgrimes if (arg->type != NARG) { 1621556Srgrimes printf("<node type %d>\n", arg->type); 1631556Srgrimes fflush(stdout); 1641556Srgrimes abort(); 1651556Srgrimes } 1661556Srgrimes bqlist = arg->narg.backquote; 1671556Srgrimes for (p = arg->narg.text ; *p ; p++) { 1681556Srgrimes switch (*p) { 1691556Srgrimes case CTLESC: 1701556Srgrimes putc(*++p, fp); 1711556Srgrimes break; 1721556Srgrimes case CTLVAR: 1731556Srgrimes putc('$', fp); 1741556Srgrimes putc('{', fp); 1751556Srgrimes subtype = *++p; 1761556Srgrimes while (*p != '=') 1771556Srgrimes putc(*p++, fp); 1781556Srgrimes if (subtype & VSNUL) 1791556Srgrimes putc(':', fp); 1801556Srgrimes switch (subtype & VSTYPE) { 1811556Srgrimes case VSNORMAL: 1821556Srgrimes putc('}', fp); 1831556Srgrimes break; 1841556Srgrimes case VSMINUS: 1851556Srgrimes putc('-', fp); 1861556Srgrimes break; 1871556Srgrimes case VSPLUS: 1881556Srgrimes putc('+', fp); 1891556Srgrimes break; 1901556Srgrimes case VSQUESTION: 1911556Srgrimes putc('?', fp); 1921556Srgrimes break; 1931556Srgrimes case VSASSIGN: 1941556Srgrimes putc('=', fp); 1951556Srgrimes break; 1961556Srgrimes default: 1971556Srgrimes printf("<subtype %d>", subtype); 1981556Srgrimes } 1991556Srgrimes break; 2001556Srgrimes case CTLENDVAR: 2011556Srgrimes putc('}', fp); 2021556Srgrimes break; 2031556Srgrimes case CTLBACKQ: 2041556Srgrimes case CTLBACKQ|CTLQUOTE: 2051556Srgrimes putc('$', fp); 2061556Srgrimes putc('(', fp); 2071556Srgrimes shtree(bqlist->n, -1, NULL, fp); 2081556Srgrimes putc(')', fp); 2091556Srgrimes break; 2101556Srgrimes default: 2111556Srgrimes putc(*p, fp); 2121556Srgrimes break; 2131556Srgrimes } 2141556Srgrimes } 2151556Srgrimes} 2161556Srgrimes 2171556Srgrimes 2181556Srgrimesstatic 2191556Srgrimesindent(amount, pfx, fp) 2201556Srgrimes char *pfx; 2211556Srgrimes FILE *fp; 2221556Srgrimes { 2231556Srgrimes int i; 2241556Srgrimes 2251556Srgrimes for (i = 0 ; i < amount ; i++) { 2261556Srgrimes if (pfx && i == amount - 1) 2271556Srgrimes fputs(pfx, fp); 2281556Srgrimes putc('\t', fp); 2291556Srgrimes } 2301556Srgrimes} 2311556Srgrimes#endif 2321556Srgrimes 2331556Srgrimes 2341556Srgrimes 2351556Srgrimes/* 2361556Srgrimes * Debugging stuff. 2371556Srgrimes */ 2381556Srgrimes 2391556Srgrimes 2401556SrgrimesFILE *tracefile; 2411556Srgrimes 2421556Srgrimes#if DEBUG == 2 2431556Srgrimesint debug = 1; 2441556Srgrimes#else 2451556Srgrimesint debug = 0; 2461556Srgrimes#endif 2471556Srgrimes 2481556Srgrimes 2491556Srgrimestrputc(c) { 2501556Srgrimes#ifdef DEBUG 2511556Srgrimes if (tracefile == NULL) 2521556Srgrimes return; 2531556Srgrimes putc(c, tracefile); 2541556Srgrimes if (c == '\n') 2551556Srgrimes fflush(tracefile); 2561556Srgrimes#endif 2571556Srgrimes} 2581556Srgrimes 2591556Srgrimes 2601556Srgrimestrace(fmt, a1, a2, a3, a4, a5, a6, a7, a8) 2611556Srgrimes char *fmt; 2621556Srgrimes { 2631556Srgrimes#ifdef DEBUG 2641556Srgrimes if (tracefile == NULL) 2651556Srgrimes return; 2661556Srgrimes fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8); 2671556Srgrimes if (strchr(fmt, '\n')) 2681556Srgrimes fflush(tracefile); 2691556Srgrimes#endif 2701556Srgrimes} 2711556Srgrimes 2721556Srgrimes 2731556Srgrimestrputs(s) 2741556Srgrimes char *s; 2751556Srgrimes { 2761556Srgrimes#ifdef DEBUG 2771556Srgrimes if (tracefile == NULL) 2781556Srgrimes return; 2791556Srgrimes fputs(s, tracefile); 2801556Srgrimes if (strchr(s, '\n')) 2811556Srgrimes fflush(tracefile); 2821556Srgrimes#endif 2831556Srgrimes} 2841556Srgrimes 2851556Srgrimes 2861556Srgrimestrstring(s) 2871556Srgrimes char *s; 2881556Srgrimes { 2891556Srgrimes register char *p; 2901556Srgrimes char c; 2911556Srgrimes 2921556Srgrimes#ifdef DEBUG 2931556Srgrimes if (tracefile == NULL) 2941556Srgrimes return; 2951556Srgrimes putc('"', tracefile); 2961556Srgrimes for (p = s ; *p ; p++) { 2971556Srgrimes switch (*p) { 2981556Srgrimes case '\n': c = 'n'; goto backslash; 2991556Srgrimes case '\t': c = 't'; goto backslash; 3001556Srgrimes case '\r': c = 'r'; goto backslash; 3011556Srgrimes case '"': c = '"'; goto backslash; 3021556Srgrimes case '\\': c = '\\'; goto backslash; 3031556Srgrimes case CTLESC: c = 'e'; goto backslash; 3041556Srgrimes case CTLVAR: c = 'v'; goto backslash; 3051556Srgrimes case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; 3061556Srgrimes case CTLBACKQ: c = 'q'; goto backslash; 3071556Srgrimes case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; 3081556Srgrimesbackslash: putc('\\', tracefile); 3091556Srgrimes putc(c, tracefile); 3101556Srgrimes break; 3111556Srgrimes default: 3121556Srgrimes if (*p >= ' ' && *p <= '~') 3131556Srgrimes putc(*p, tracefile); 3141556Srgrimes else { 3151556Srgrimes putc('\\', tracefile); 3161556Srgrimes putc(*p >> 6 & 03, tracefile); 3171556Srgrimes putc(*p >> 3 & 07, tracefile); 3181556Srgrimes putc(*p & 07, tracefile); 3191556Srgrimes } 3201556Srgrimes break; 3211556Srgrimes } 3221556Srgrimes } 3231556Srgrimes putc('"', tracefile); 3241556Srgrimes#endif 3251556Srgrimes} 3261556Srgrimes 3271556Srgrimes 3281556Srgrimestrargs(ap) 3291556Srgrimes char **ap; 3301556Srgrimes { 3311556Srgrimes#ifdef DEBUG 3321556Srgrimes if (tracefile == NULL) 3331556Srgrimes return; 3341556Srgrimes while (*ap) { 3351556Srgrimes trstring(*ap++); 3361556Srgrimes if (*ap) 3371556Srgrimes putc(' ', tracefile); 3381556Srgrimes else 3391556Srgrimes putc('\n', tracefile); 3401556Srgrimes } 3411556Srgrimes fflush(tracefile); 3421556Srgrimes#endif 3431556Srgrimes} 3441556Srgrimes 3451556Srgrimes 3461556Srgrimesopentrace() { 3471556Srgrimes char s[100]; 3481556Srgrimes char *p; 3491556Srgrimes char *getenv(); 3501556Srgrimes int flags; 3511556Srgrimes 3521556Srgrimes#ifdef DEBUG 3531556Srgrimes if (!debug) 3541556Srgrimes return; 3551556Srgrimes#ifdef not_this_way 3561556Srgrimes if ((p = getenv("HOME")) == NULL) { 3571556Srgrimes if (geteuid() == 0) 3581556Srgrimes p = "/"; 3591556Srgrimes else 3601556Srgrimes p = "/tmp"; 3611556Srgrimes } 3621556Srgrimes scopy(p, s); 3631556Srgrimes strcat(s, "/trace"); 3641556Srgrimes#else 3651556Srgrimes scopy("./trace", s); 3661556Srgrimes#endif /* not_this_way */ 3671556Srgrimes if ((tracefile = fopen(s, "a")) == NULL) { 3681556Srgrimes fprintf(stderr, "Can't open %s\n", s); 3691556Srgrimes return; 3701556Srgrimes } 3711556Srgrimes#ifdef O_APPEND 3721556Srgrimes if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0) 3731556Srgrimes fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND); 3741556Srgrimes#endif 3751556Srgrimes fputs("\nTracing started.\n", tracefile); 3761556Srgrimes fflush(tracefile); 3771556Srgrimes#endif /* DEBUG */ 3781556Srgrimes} 379