147144Sbostic /*- 2*60712Sbostic * Copyright (c) 1991, 1993 3*60712Sbostic * The Regents of the University of California. All rights reserved. 447144Sbostic * 547144Sbostic * This code is derived from software contributed to Berkeley by 647144Sbostic * Kenneth Almquist. 747144Sbostic * 860711Sbostic * %sccs.include.redist.c% 947144Sbostic */ 1047144Sbostic 1147144Sbostic #ifndef lint 12*60712Sbostic static char sccsid[] = "@(#)show.c 8.1 (Berkeley) 05/31/93"; 1347144Sbostic #endif /* not lint */ 1447144Sbostic 1547144Sbostic #include <stdio.h> 1647144Sbostic #include "shell.h" 1747144Sbostic #include "parser.h" 1847144Sbostic #include "nodes.h" 1947144Sbostic #include "mystring.h" 2047144Sbostic 2147144Sbostic 2247144Sbostic #ifdef DEBUG 2347144Sbostic static shtree(), shcmd(), sharg(), indent(); 2447144Sbostic 2547144Sbostic 2647144Sbostic showtree(n) 2747144Sbostic union node *n; 2847144Sbostic { 2947144Sbostic trputs("showtree called\n"); 3047144Sbostic shtree(n, 1, NULL, stdout); 3147144Sbostic } 3247144Sbostic 3347144Sbostic 3447144Sbostic static 3547144Sbostic shtree(n, ind, pfx, fp) 3647144Sbostic union node *n; 3747144Sbostic char *pfx; 3847144Sbostic FILE *fp; 3947144Sbostic { 4047144Sbostic struct nodelist *lp; 4147144Sbostic char *s; 4247144Sbostic 4347144Sbostic indent(ind, pfx, fp); 4447144Sbostic switch(n->type) { 4547144Sbostic case NSEMI: 4647144Sbostic s = "; "; 4747144Sbostic goto binop; 4847144Sbostic case NAND: 4947144Sbostic s = " && "; 5047144Sbostic goto binop; 5147144Sbostic case NOR: 5247144Sbostic s = " || "; 5347144Sbostic binop: 5447144Sbostic shtree(n->nbinary.ch1, ind, NULL, fp); 5547144Sbostic /* if (ind < 0) */ 5647144Sbostic fputs(s, fp); 5747144Sbostic shtree(n->nbinary.ch2, ind, NULL, fp); 5847144Sbostic break; 5947144Sbostic case NCMD: 6047144Sbostic shcmd(n, fp); 6147144Sbostic if (ind >= 0) 6247144Sbostic putc('\n', fp); 6347144Sbostic break; 6447144Sbostic case NPIPE: 6547144Sbostic for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { 6647144Sbostic shcmd(lp->n, fp); 6747144Sbostic if (lp->next) 6847144Sbostic fputs(" | ", fp); 6947144Sbostic } 7047144Sbostic if (n->npipe.backgnd) 7147144Sbostic fputs(" &", fp); 7247144Sbostic if (ind >= 0) 7347144Sbostic putc('\n', fp); 7447144Sbostic break; 7547144Sbostic default: 7647144Sbostic fprintf(fp, "<node type %d>", n->type); 7747144Sbostic if (ind >= 0) 7847144Sbostic putc('\n', fp); 7947144Sbostic break; 8047144Sbostic } 8147144Sbostic } 8247144Sbostic 8347144Sbostic 8447144Sbostic 8547144Sbostic static 8647144Sbostic shcmd(cmd, fp) 8747144Sbostic union node *cmd; 8847144Sbostic FILE *fp; 8947144Sbostic { 9047144Sbostic union node *np; 9147144Sbostic int first; 9247144Sbostic char *s; 9347144Sbostic int dftfd; 9447144Sbostic 9547144Sbostic first = 1; 9647144Sbostic for (np = cmd->ncmd.args ; np ; np = np->narg.next) { 9747144Sbostic if (! first) 9847144Sbostic putchar(' '); 9947144Sbostic sharg(np, fp); 10047144Sbostic first = 0; 10147144Sbostic } 10247144Sbostic for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { 10347144Sbostic if (! first) 10447144Sbostic putchar(' '); 10547144Sbostic switch (np->nfile.type) { 10647144Sbostic case NTO: s = ">"; dftfd = 1; break; 10747144Sbostic case NAPPEND: s = ">>"; dftfd = 1; break; 10847144Sbostic case NTOFD: s = ">&"; dftfd = 1; break; 10947144Sbostic case NFROM: s = "<"; dftfd = 0; break; 11047144Sbostic case NFROMFD: s = "<&"; dftfd = 0; break; 11147144Sbostic } 11247144Sbostic if (np->nfile.fd != dftfd) 11347144Sbostic fprintf(fp, "%d", np->nfile.fd); 11447144Sbostic fputs(s, fp); 11547144Sbostic if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) { 11647144Sbostic fprintf(fp, "%d", np->ndup.dupfd); 11747144Sbostic } else { 11847144Sbostic sharg(np->nfile.fname, fp); 11947144Sbostic } 12047144Sbostic first = 0; 12147144Sbostic } 12247144Sbostic } 12347144Sbostic 12447144Sbostic 12547144Sbostic 12647144Sbostic static 12747144Sbostic sharg(arg, fp) 12847144Sbostic union node *arg; 12947144Sbostic FILE *fp; 13047144Sbostic { 13147144Sbostic char *p; 13247144Sbostic struct nodelist *bqlist; 13347144Sbostic int subtype; 13447144Sbostic 13547144Sbostic if (arg->type != NARG) { 13647144Sbostic printf("<node type %d>\n", arg->type); 13747144Sbostic fflush(stdout); 13847144Sbostic abort(); 13947144Sbostic } 14047144Sbostic bqlist = arg->narg.backquote; 14147144Sbostic for (p = arg->narg.text ; *p ; p++) { 14247144Sbostic switch (*p) { 14347144Sbostic case CTLESC: 14447144Sbostic putc(*++p, fp); 14547144Sbostic break; 14647144Sbostic case CTLVAR: 14747144Sbostic putc('$', fp); 14847144Sbostic putc('{', fp); 14947144Sbostic subtype = *++p; 15047144Sbostic while (*p != '=') 15147144Sbostic putc(*p++, fp); 15247144Sbostic if (subtype & VSNUL) 15347144Sbostic putc(':', fp); 15447144Sbostic switch (subtype & VSTYPE) { 15547144Sbostic case VSNORMAL: 15647144Sbostic putc('}', fp); 15747144Sbostic break; 15847144Sbostic case VSMINUS: 15947144Sbostic putc('-', fp); 16047144Sbostic break; 16147144Sbostic case VSPLUS: 16247144Sbostic putc('+', fp); 16347144Sbostic break; 16447144Sbostic case VSQUESTION: 16547144Sbostic putc('?', fp); 16647144Sbostic break; 16747144Sbostic case VSASSIGN: 16847144Sbostic putc('=', fp); 16947144Sbostic break; 17047144Sbostic default: 17147144Sbostic printf("<subtype %d>", subtype); 17247144Sbostic } 17347144Sbostic break; 17447144Sbostic case CTLENDVAR: 17547144Sbostic putc('}', fp); 17647144Sbostic break; 17747144Sbostic case CTLBACKQ: 17847144Sbostic case CTLBACKQ|CTLQUOTE: 17947144Sbostic putc('$', fp); 18047144Sbostic putc('(', fp); 18147144Sbostic shtree(bqlist->n, -1, NULL, fp); 18247144Sbostic putc(')', fp); 18347144Sbostic break; 18447144Sbostic default: 18547144Sbostic putc(*p, fp); 18647144Sbostic break; 18747144Sbostic } 18847144Sbostic } 18947144Sbostic } 19047144Sbostic 19147144Sbostic 19247144Sbostic static 19347144Sbostic indent(amount, pfx, fp) 19447144Sbostic char *pfx; 19547144Sbostic FILE *fp; 19647144Sbostic { 19747144Sbostic int i; 19847144Sbostic 19947144Sbostic for (i = 0 ; i < amount ; i++) { 20047144Sbostic if (pfx && i == amount - 1) 20147144Sbostic fputs(pfx, fp); 20247144Sbostic putc('\t', fp); 20347144Sbostic } 20447144Sbostic } 20547144Sbostic #endif 20647144Sbostic 20747144Sbostic 20847144Sbostic 20947144Sbostic /* 21047144Sbostic * Debugging stuff. 21147144Sbostic */ 21247144Sbostic 21347144Sbostic 21447144Sbostic FILE *tracefile; 21547144Sbostic 21647983Smarc #if DEBUG == 2 21747983Smarc int debug = 1; 21847983Smarc #else 21947983Smarc int debug = 0; 22047983Smarc #endif 22147144Sbostic 22247144Sbostic 22347144Sbostic trputc(c) { 22447144Sbostic #ifdef DEBUG 22547144Sbostic if (tracefile == NULL) 22647144Sbostic return; 22747144Sbostic putc(c, tracefile); 22847144Sbostic if (c == '\n') 22947144Sbostic fflush(tracefile); 23047144Sbostic #endif 23147144Sbostic } 23247144Sbostic 23347144Sbostic 23447144Sbostic trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8) 23547144Sbostic char *fmt; 23647144Sbostic { 23747144Sbostic #ifdef DEBUG 23847144Sbostic if (tracefile == NULL) 23947144Sbostic return; 24047144Sbostic fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8); 24147144Sbostic if (strchr(fmt, '\n')) 24247144Sbostic fflush(tracefile); 24347144Sbostic #endif 24447144Sbostic } 24547144Sbostic 24647144Sbostic 24747144Sbostic trputs(s) 24847144Sbostic char *s; 24947144Sbostic { 25047144Sbostic #ifdef DEBUG 25147144Sbostic if (tracefile == NULL) 25247144Sbostic return; 25347144Sbostic fputs(s, tracefile); 25447144Sbostic if (strchr(s, '\n')) 25547144Sbostic fflush(tracefile); 25647144Sbostic #endif 25747144Sbostic } 25847144Sbostic 25947144Sbostic 26047144Sbostic trstring(s) 26147144Sbostic char *s; 26247144Sbostic { 26347144Sbostic register char *p; 26447144Sbostic char c; 26547144Sbostic 26647144Sbostic #ifdef DEBUG 26747144Sbostic if (tracefile == NULL) 26847144Sbostic return; 26947144Sbostic putc('"', tracefile); 27047144Sbostic for (p = s ; *p ; p++) { 27147144Sbostic switch (*p) { 27247144Sbostic case '\n': c = 'n'; goto backslash; 27347144Sbostic case '\t': c = 't'; goto backslash; 27447144Sbostic case '\r': c = 'r'; goto backslash; 27547144Sbostic case '"': c = '"'; goto backslash; 27647144Sbostic case '\\': c = '\\'; goto backslash; 27747144Sbostic case CTLESC: c = 'e'; goto backslash; 27847144Sbostic case CTLVAR: c = 'v'; goto backslash; 27947144Sbostic case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; 28047144Sbostic case CTLBACKQ: c = 'q'; goto backslash; 28147144Sbostic case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; 28247144Sbostic backslash: putc('\\', tracefile); 28347144Sbostic putc(c, tracefile); 28447144Sbostic break; 28547144Sbostic default: 28647144Sbostic if (*p >= ' ' && *p <= '~') 28747144Sbostic putc(*p, tracefile); 28847144Sbostic else { 28947144Sbostic putc('\\', tracefile); 29047144Sbostic putc(*p >> 6 & 03, tracefile); 29147144Sbostic putc(*p >> 3 & 07, tracefile); 29247144Sbostic putc(*p & 07, tracefile); 29347144Sbostic } 29447144Sbostic break; 29547144Sbostic } 29647144Sbostic } 29747144Sbostic putc('"', tracefile); 29847144Sbostic #endif 29947144Sbostic } 30047144Sbostic 30147144Sbostic 30247144Sbostic trargs(ap) 30347144Sbostic char **ap; 30447144Sbostic { 30547144Sbostic #ifdef DEBUG 30647144Sbostic if (tracefile == NULL) 30747144Sbostic return; 30847144Sbostic while (*ap) { 30947144Sbostic trstring(*ap++); 31047144Sbostic if (*ap) 31147144Sbostic putc(' ', tracefile); 31247144Sbostic else 31347144Sbostic putc('\n', tracefile); 31447144Sbostic } 31547144Sbostic fflush(tracefile); 31647144Sbostic #endif 31747144Sbostic } 31847144Sbostic 31947144Sbostic 32047144Sbostic opentrace() { 32147144Sbostic char s[100]; 32247144Sbostic char *p; 32347144Sbostic char *getenv(); 32447144Sbostic int flags; 32547144Sbostic 32647144Sbostic #ifdef DEBUG 32747983Smarc if (!debug) 32847983Smarc return; 32955226Smarc #ifdef not_this_way 33047983Smarc if ((p = getenv("HOME")) == NULL) { 33155226Smarc if (geteuid() == 0) 33247983Smarc p = "/"; 33347983Smarc else 33447983Smarc p = "/tmp"; 33547983Smarc } 33647144Sbostic scopy(p, s); 33747144Sbostic strcat(s, "/trace"); 33855226Smarc #else 33955226Smarc scopy("./trace", s); 34055226Smarc #endif /* not_this_way */ 34147144Sbostic if ((tracefile = fopen(s, "a")) == NULL) { 34247144Sbostic fprintf(stderr, "Can't open %s\n", s); 34347983Smarc return; 34447144Sbostic } 34547144Sbostic #ifdef O_APPEND 34647144Sbostic if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0) 34747144Sbostic fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND); 34847144Sbostic #endif 34947144Sbostic fputs("\nTracing started.\n", tracefile); 35047144Sbostic fflush(tracefile); 35155226Smarc #endif /* DEBUG */ 35247144Sbostic } 353