show.c revision 99110
150477Speter/*- 233548Sjkh * Copyright (c) 1991, 1993 32893Sdfr * The Regents of the University of California. All rights reserved. 42893Sdfr * 533548Sjkh * This code is derived from software contributed to Berkeley by 633548Sjkh * Kenneth Almquist. 72893Sdfr * 82893Sdfr * Redistribution and use in source and binary forms, with or without 92893Sdfr * modification, are permitted provided that the following conditions 102893Sdfr * are met: 112893Sdfr * 1. Redistributions of source code must retain the above copyright 122893Sdfr * notice, this list of conditions and the following disclaimer. 132893Sdfr * 2. Redistributions in binary form must reproduce the above copyright 142893Sdfr * notice, this list of conditions and the following disclaimer in the 152893Sdfr * documentation and/or other materials provided with the distribution. 162893Sdfr * 3. All advertising materials mentioning features or use of this software 172893Sdfr * must display the following acknowledgement: 182893Sdfr * This product includes software developed by the University of 192893Sdfr * California, Berkeley and its contributors. 202893Sdfr * 4. Neither the name of the University nor the names of its contributors 212893Sdfr * may be used to endorse or promote products derived from this software 222893Sdfr * without specific prior written permission. 232893Sdfr * 242893Sdfr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 252893Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 262893Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 272893Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 282893Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 292893Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 302893Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 312893Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 322893Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 332893Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 342893Sdfr * SUCH DAMAGE. 35139776Simp */ 362893Sdfr 378876Srgrimes#ifndef lint 382893Sdfr#if 0 392893Sdfrstatic char sccsid[] = "@(#)show.c 8.3 (Berkeley) 5/4/95"; 408876Srgrimes#endif 412893Sdfr#endif /* not lint */ 428876Srgrimes#include <sys/cdefs.h> 432893Sdfr__FBSDID("$FreeBSD: head/bin/sh/show.c 99110 2002-06-30 05:15:05Z obrien $"); 442893Sdfr 452893Sdfr#include <stdio.h> 462893Sdfr#include <stdarg.h> 478876Srgrimes#include <errno.h> 482893Sdfr 492893Sdfr#include "shell.h" 502893Sdfr#include "parser.h" 512893Sdfr#include "nodes.h" 522893Sdfr#include "mystring.h" 53171754Sbde#include "show.h" 5440651Sbde 55177785Skib 56171754Sbde#ifdef DEBUG 57171754Sbdestatic void shtree(union node *, int, char *, FILE*); 58171748Sbdestatic void shcmd(union node *, FILE *); 59171754Sbdestatic void sharg(union node *, FILE *); 60171754Sbdestatic void indent(int, char *, FILE *); 61171748Sbdestatic void trstring(char *); 622893Sdfr 63164033Srwatson 642893Sdfrvoid 65171754Sbdeshowtree(union node *n) 662893Sdfr{ 672893Sdfr trputs("showtree called\n"); 68171754Sbde shtree(n, 1, NULL, stdout); 69171754Sbde} 70171754Sbde 71171754Sbde 7277162Srustatic void 7377162Srushtree(union node *n, int ind, char *pfx, FILE *fp) 7477162Sru{ 7577162Sru struct nodelist *lp; 76171754Sbde char *s; 772893Sdfr 78204470Skib if (n == NULL) 79204470Skib return; 80172757Sbde 81138471Sphk indent(ind, pfx, fp); 82172798Sbde switch(n->type) { 83172757Sbde case NSEMI: 84172757Sbde s = "; "; 85172757Sbde goto binop; 86172757Sbde case NAND: 87172757Sbde s = " && "; 88138471Sphk goto binop; 89138471Sphk case NOR: 90138471Sphk s = " || "; 9156674Snyanbinop: 9256674Snyan shtree(n->nbinary.ch1, ind, NULL, fp); 9356674Snyan /* if (ind < 0) */ 9456674Snyan fputs(s, fp); 9556674Snyan shtree(n->nbinary.ch2, ind, NULL, fp); 9656674Snyan break; 9756674Snyan case NCMD: 9856674Snyan shcmd(n, fp); 9956674Snyan if (ind >= 0) 10056674Snyan putc('\n', fp); 10156674Snyan break; 102151897Srwatson case NPIPE: 103151897Srwatson for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { 10430309Sphk shcmd(lp->n, fp); 105171757Sbde if (lp->next) 106120492Sfjoe fputs(" | ", fp); 107138471Sphk } 108183754Sattilio if (n->npipe.backgnd) 109170188Strhodes fputs(" &", fp); 110138471Sphk if (ind >= 0) 111101777Sphk putc('\n', fp); 112101777Sphk break; 113101777Sphk default: 114101777Sphk fprintf(fp, "<node type %d>", n->type); 11512338Sbde if (ind >= 0) 116134345Stjr putc('\n', fp); 117134345Stjr break; 118134345Stjr } 11933548Sjkh} 120166558Srodrigc 12133548Sjkh 12233548Sjkh 123138471Sphkstatic void 124138471Sphkshcmd(union node *cmd, FILE *fp) 12533548Sjkh{ 126138471Sphk union node *np; 127138471Sphk int first; 128138471Sphk char *s; 129138471Sphk int dftfd; 130138471Sphk 131138471Sphk first = 1; 132138471Sphk for (np = cmd->ncmd.args ; np ; np = np->narg.next) { 133138471Sphk if (! first) 134138471Sphk putchar(' '); 135138471Sphk sharg(np, fp); 136138471Sphk first = 0; 137138471Sphk } 138138471Sphk for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { 139138471Sphk if (! first) 140138471Sphk putchar(' '); 141138471Sphk switch (np->nfile.type) { 142134345Stjr case NTO: s = ">"; dftfd = 1; break; 143134345Stjr case NAPPEND: s = ">>"; dftfd = 1; break; 144134345Stjr case NTOFD: s = ">&"; dftfd = 1; break; 145134345Stjr case NCLOBBER: s = ">|"; dftfd = 1; break; 146134345Stjr case NFROM: s = "<"; dftfd = 0; break; 147134345Stjr case NFROMTO: s = "<>"; dftfd = 0; break; 148134345Stjr case NFROMFD: s = "<&"; dftfd = 0; break; 149134345Stjr default: s = "*error*"; dftfd = 0; break; 150134345Stjr } 151134345Stjr if (np->nfile.fd != dftfd) 152138471Sphk fprintf(fp, "%d", np->nfile.fd); 153138471Sphk fputs(s, fp); 154138471Sphk if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) { 155138471Sphk fprintf(fp, "%d", np->ndup.dupfd); 156138471Sphk } else { 157138471Sphk sharg(np->nfile.fname, fp); 158138471Sphk } 159138471Sphk first = 0; 160138471Sphk } 161138471Sphk} 162152595Srodrigc 163152595Srodrigc 164138471Sphk 165138471Sphkstatic void 166152595Srodrigcsharg(union node *arg, FILE *fp) 167152595Srodrigc{ 168138471Sphk char *p; 169138471Sphk struct nodelist *bqlist; 17033548Sjkh int subtype; 171152610Srodrigc 172152610Srodrigc if (arg->type != NARG) { 173152610Srodrigc printf("<node type %d>\n", arg->type); 174138471Sphk fflush(stdout); 175138471Sphk abort(); 17633548Sjkh } 17733548Sjkh bqlist = arg->narg.backquote; 17833548Sjkh for (p = arg->narg.text ; *p ; p++) { 17933548Sjkh switch (*p) { 18033548Sjkh case CTLESC: 18133548Sjkh putc(*++p, fp); 18233548Sjkh break; 18333548Sjkh case CTLVAR: 18433548Sjkh putc('$', fp); 18533548Sjkh putc('{', fp); 18633548Sjkh subtype = *++p; 18733548Sjkh if (subtype == VSLENGTH) 188144058Sjeff putc('#', fp); 189191990Sattilio 19033548Sjkh while (*p != '=') 191171757Sbde putc(*p++, fp); 192171757Sbde 19333548Sjkh if (subtype & VSNUL) 19433548Sjkh putc(':', fp); 19533548Sjkh 19633548Sjkh switch (subtype & VSTYPE) { 19733548Sjkh case VSNORMAL: 19833548Sjkh putc('}', fp); 199138471Sphk break; 200191990Sattilio case VSMINUS: 201138471Sphk putc('-', fp); 202138471Sphk break; 203138471Sphk case VSPLUS: 204138471Sphk putc('+', fp); 205138471Sphk break; 206138471Sphk case VSQUESTION: 207138471Sphk putc('?', fp); 208138471Sphk break; 209138471Sphk case VSASSIGN: 210138471Sphk putc('=', fp); 211138471Sphk break; 212138471Sphk case VSTRIMLEFT: 213138471Sphk putc('#', fp); 214138471Sphk break; 215138471Sphk case VSTRIMLEFTMAX: 216138471Sphk putc('#', fp); 217138471Sphk putc('#', fp); 218171757Sbde break; 219171757Sbde case VSTRIMRIGHT: 220171757Sbde putc('%', fp); 221171757Sbde break; 222138471Sphk case VSTRIMRIGHTMAX: 223171757Sbde putc('%', fp); 224171757Sbde putc('%', fp); 225171757Sbde break; 226138471Sphk case VSLENGTH: 227138471Sphk break; 228138471Sphk default: 229138471Sphk printf("<subtype %d>", subtype); 230138471Sphk } 231138471Sphk break; 2322893Sdfr case CTLENDVAR: 2338876Srgrimes putc('}', fp); 2342893Sdfr break; 2358876Srgrimes case CTLBACKQ: 2362893Sdfr case CTLBACKQ|CTLQUOTE: 23712144Sphk putc('$', fp); 238191990Sattilio putc('(', fp); 2392893Sdfr shtree(bqlist->n, -1, NULL, fp); 2402893Sdfr putc(')', fp); 241191990Sattilio break; 24233548Sjkh default: 24333548Sjkh putc(*p, fp); 244132902Sphk break; 245138689Sphk } 246184413Strasz } 247138471Sphk} 2482893Sdfr 249191990Sattilio 250138471Sphkstatic void 251138471Sphkindent(int amount, char *pfx, FILE *fp) 252138471Sphk{ 2532893Sdfr int i; 25433548Sjkh 25533548Sjkh for (i = 0 ; i < amount ; i++) { 2562893Sdfr if (pfx && i == amount - 1) 2572893Sdfr fputs(pfx, fp); 25833548Sjkh putc('\t', fp); 259158924Srodrigc } 260165022Srodrigc} 261165022Srodrigc 262165022Srodrigc 263165022Srodrigc/* 264165022Srodrigc * Debugging stuff. 265165022Srodrigc */ 266165022Srodrigc 267138689Sphk 268165022SrodrigcFILE *tracefile; 269138689Sphk 270137036Sphk#if DEBUG == 2 271138471Sphkint debug = 1; 272191990Sattilio#else 273133287Sphkint debug = 0; 274133287Sphk#endif 2752893Sdfr 2762893Sdfr 2772893Sdfrvoid 278132023Salfredtrputc(int c) 279138471Sphk{ 280138471Sphk if (tracefile == NULL) 281172883Sdelphij return; 282172883Sdelphij putc(c, tracefile); 283172883Sdelphij if (c == '\n') 284172883Sdelphij fflush(tracefile); 285172883Sdelphij} 286172883Sdelphij 287172883Sdelphij 288172883Sdelphijvoid 289172883Sdelphijsh_trace(const char *fmt, ...) 290172883Sdelphij{ 291172883Sdelphij va_list va; 292172883Sdelphij va_start(va, fmt); 293137036Sphk if (tracefile != NULL) { 294137036Sphk (void) vfprintf(tracefile, fmt, va); 295171551Sbde if (strchr(fmt, '\n')) 296137036Sphk (void) fflush(tracefile); 297137036Sphk } 298172883Sdelphij va_end(va); 299172883Sdelphij} 300171551Sbde 301172883Sdelphij 302171551Sbdevoid 303172883Sdelphijtrputs(char *s) 304172883Sdelphij{ 305172883Sdelphij if (tracefile == NULL) 306172883Sdelphij return; 307172883Sdelphij fputs(s, tracefile); 308172883Sdelphij if (strchr(s, '\n')) 309172883Sdelphij fflush(tracefile); 310172883Sdelphij} 311172883Sdelphij 312138471Sphk 313138471Sphkstatic void 31433548Sjkhtrstring(char *s) 31533548Sjkh{ 31633548Sjkh char *p; 31733548Sjkh char c; 318164033Srwatson 319175202Sattilio if (tracefile == NULL) 320164033Srwatson return; 321171757Sbde putc('"', tracefile); 322164033Srwatson for (p = s ; *p ; p++) { 323164033Srwatson switch (*p) { 324164033Srwatson case '\n': c = 'n'; goto backslash; 325175294Sattilio case '\t': c = 't'; goto backslash; 326164033Srwatson case '\r': c = 'r'; goto backslash; 32733548Sjkh case '"': c = '"'; goto backslash; 328175294Sattilio case '\\': c = '\\'; goto backslash; 329137036Sphk case CTLESC: c = 'e'; goto backslash; 330137036Sphk case CTLVAR: c = 'v'; goto backslash; 331137036Sphk case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; 332137036Sphk case CTLBACKQ: c = 'q'; goto backslash; 333137036Sphk case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; 334137036Sphkbackslash: putc('\\', tracefile); 335137036Sphk putc(c, tracefile); 336123963Sbde break; 337172883Sdelphij default: 338172883Sdelphij if (*p >= ' ' && *p <= '~') 339172883Sdelphij putc(*p, tracefile); 340172883Sdelphij else { 341172883Sdelphij putc('\\', tracefile); 342165836Srodrigc putc(*p >> 6 & 03, tracefile); 343123963Sbde putc(*p >> 3 & 07, tracefile); 344123873Strhodes putc(*p & 07, tracefile); 345123873Strhodes } 346172883Sdelphij break; 34733548Sjkh } 3482893Sdfr } 3492893Sdfr putc('"', tracefile); 35033548Sjkh} 351125796Sbde 3522893Sdfr 353138471Sphkvoid 354138471Sphktrargs(char **ap) 355149720Sssouhlal{ 356132902Sphk if (tracefile == NULL) 35733548Sjkh return; 35833548Sjkh while (*ap) { 359132902Sphk trstring(*ap++); 360132902Sphk if (*ap) 3618876Srgrimes putc(' ', tracefile); 36255756Sphk else 363149720Sssouhlal putc('\n', tracefile); 36455756Sphk } 3652893Sdfr fflush(tracefile); 3662893Sdfr} 36733548Sjkh 36833548Sjkh 3692893Sdfrvoid 370184413Straszopentrace(void) 371164033Srwatson{ 372184413Strasz char s[100]; 373184413Strasz char *getenv(); 374164033Srwatson#ifdef O_APPEND 375164033Srwatson int flags; 376164033Srwatson#endif 377164033Srwatson 378164033Srwatson if (!debug) 37933548Sjkh return; 38033548Sjkh#ifdef not_this_way 381183754Sattilio { 38233548Sjkh char *p; 38333548Sjkh if ((p = getenv("HOME")) == NULL) { 38433548Sjkh if (geteuid() == 0) 38533548Sjkh p = "/"; 386204589Skib else 3872893Sdfr p = "/tmp"; 388204589Skib } 3892893Sdfr scopy(p, s); 3902893Sdfr strcat(s, "/trace"); 3912893Sdfr } 39233548Sjkh#else 39333548Sjkh scopy("./trace", s); 39433548Sjkh#endif /* not_this_way */ 395138471Sphk if ((tracefile = fopen(s, "a")) == NULL) { 39633548Sjkh fprintf(stderr, "Can't open %s: %s\n", s, strerror(errno)); 397134345Stjr return; 398191990Sattilio } 3992893Sdfr#ifdef O_APPEND 4002893Sdfr if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0) 401171757Sbde fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND); 402138471Sphk#endif 4032893Sdfr fputs("\nTracing started.\n", tracefile); 404138471Sphk fflush(tracefile); 4052893Sdfr} 40633548Sjkh#endif /* DEBUG */ 4072893Sdfr