1 /*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Kenneth Almquist. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)show.c 8.1 (Berkeley) 05/31/93"; 13 #endif /* not lint */ 14 15 #include <stdio.h> 16 #include "shell.h" 17 #include "parser.h" 18 #include "nodes.h" 19 #include "mystring.h" 20 21 22 #ifdef DEBUG 23 static shtree(), shcmd(), sharg(), indent(); 24 25 26 showtree(n) 27 union node *n; 28 { 29 trputs("showtree called\n"); 30 shtree(n, 1, NULL, stdout); 31 } 32 33 34 static 35 shtree(n, ind, pfx, fp) 36 union node *n; 37 char *pfx; 38 FILE *fp; 39 { 40 struct nodelist *lp; 41 char *s; 42 43 indent(ind, pfx, fp); 44 switch(n->type) { 45 case NSEMI: 46 s = "; "; 47 goto binop; 48 case NAND: 49 s = " && "; 50 goto binop; 51 case NOR: 52 s = " || "; 53 binop: 54 shtree(n->nbinary.ch1, ind, NULL, fp); 55 /* if (ind < 0) */ 56 fputs(s, fp); 57 shtree(n->nbinary.ch2, ind, NULL, fp); 58 break; 59 case NCMD: 60 shcmd(n, fp); 61 if (ind >= 0) 62 putc('\n', fp); 63 break; 64 case NPIPE: 65 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { 66 shcmd(lp->n, fp); 67 if (lp->next) 68 fputs(" | ", fp); 69 } 70 if (n->npipe.backgnd) 71 fputs(" &", fp); 72 if (ind >= 0) 73 putc('\n', fp); 74 break; 75 default: 76 fprintf(fp, "<node type %d>", n->type); 77 if (ind >= 0) 78 putc('\n', fp); 79 break; 80 } 81 } 82 83 84 85 static 86 shcmd(cmd, fp) 87 union node *cmd; 88 FILE *fp; 89 { 90 union node *np; 91 int first; 92 char *s; 93 int dftfd; 94 95 first = 1; 96 for (np = cmd->ncmd.args ; np ; np = np->narg.next) { 97 if (! first) 98 putchar(' '); 99 sharg(np, fp); 100 first = 0; 101 } 102 for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { 103 if (! first) 104 putchar(' '); 105 switch (np->nfile.type) { 106 case NTO: s = ">"; dftfd = 1; break; 107 case NAPPEND: s = ">>"; dftfd = 1; break; 108 case NTOFD: s = ">&"; dftfd = 1; break; 109 case NFROM: s = "<"; dftfd = 0; break; 110 case NFROMFD: s = "<&"; dftfd = 0; break; 111 } 112 if (np->nfile.fd != dftfd) 113 fprintf(fp, "%d", np->nfile.fd); 114 fputs(s, fp); 115 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) { 116 fprintf(fp, "%d", np->ndup.dupfd); 117 } else { 118 sharg(np->nfile.fname, fp); 119 } 120 first = 0; 121 } 122 } 123 124 125 126 static 127 sharg(arg, fp) 128 union node *arg; 129 FILE *fp; 130 { 131 char *p; 132 struct nodelist *bqlist; 133 int subtype; 134 135 if (arg->type != NARG) { 136 printf("<node type %d>\n", arg->type); 137 fflush(stdout); 138 abort(); 139 } 140 bqlist = arg->narg.backquote; 141 for (p = arg->narg.text ; *p ; p++) { 142 switch (*p) { 143 case CTLESC: 144 putc(*++p, fp); 145 break; 146 case CTLVAR: 147 putc('$', fp); 148 putc('{', fp); 149 subtype = *++p; 150 while (*p != '=') 151 putc(*p++, fp); 152 if (subtype & VSNUL) 153 putc(':', fp); 154 switch (subtype & VSTYPE) { 155 case VSNORMAL: 156 putc('}', fp); 157 break; 158 case VSMINUS: 159 putc('-', fp); 160 break; 161 case VSPLUS: 162 putc('+', fp); 163 break; 164 case VSQUESTION: 165 putc('?', fp); 166 break; 167 case VSASSIGN: 168 putc('=', fp); 169 break; 170 default: 171 printf("<subtype %d>", subtype); 172 } 173 break; 174 case CTLENDVAR: 175 putc('}', fp); 176 break; 177 case CTLBACKQ: 178 case CTLBACKQ|CTLQUOTE: 179 putc('$', fp); 180 putc('(', fp); 181 shtree(bqlist->n, -1, NULL, fp); 182 putc(')', fp); 183 break; 184 default: 185 putc(*p, fp); 186 break; 187 } 188 } 189 } 190 191 192 static 193 indent(amount, pfx, fp) 194 char *pfx; 195 FILE *fp; 196 { 197 int i; 198 199 for (i = 0 ; i < amount ; i++) { 200 if (pfx && i == amount - 1) 201 fputs(pfx, fp); 202 putc('\t', fp); 203 } 204 } 205 #endif 206 207 208 209 /* 210 * Debugging stuff. 211 */ 212 213 214 FILE *tracefile; 215 216 #if DEBUG == 2 217 int debug = 1; 218 #else 219 int debug = 0; 220 #endif 221 222 223 trputc(c) { 224 #ifdef DEBUG 225 if (tracefile == NULL) 226 return; 227 putc(c, tracefile); 228 if (c == '\n') 229 fflush(tracefile); 230 #endif 231 } 232 233 234 trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8) 235 char *fmt; 236 { 237 #ifdef DEBUG 238 if (tracefile == NULL) 239 return; 240 fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8); 241 if (strchr(fmt, '\n')) 242 fflush(tracefile); 243 #endif 244 } 245 246 247 trputs(s) 248 char *s; 249 { 250 #ifdef DEBUG 251 if (tracefile == NULL) 252 return; 253 fputs(s, tracefile); 254 if (strchr(s, '\n')) 255 fflush(tracefile); 256 #endif 257 } 258 259 260 trstring(s) 261 char *s; 262 { 263 register char *p; 264 char c; 265 266 #ifdef DEBUG 267 if (tracefile == NULL) 268 return; 269 putc('"', tracefile); 270 for (p = s ; *p ; p++) { 271 switch (*p) { 272 case '\n': c = 'n'; goto backslash; 273 case '\t': c = 't'; goto backslash; 274 case '\r': c = 'r'; goto backslash; 275 case '"': c = '"'; goto backslash; 276 case '\\': c = '\\'; goto backslash; 277 case CTLESC: c = 'e'; goto backslash; 278 case CTLVAR: c = 'v'; goto backslash; 279 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; 280 case CTLBACKQ: c = 'q'; goto backslash; 281 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; 282 backslash: putc('\\', tracefile); 283 putc(c, tracefile); 284 break; 285 default: 286 if (*p >= ' ' && *p <= '~') 287 putc(*p, tracefile); 288 else { 289 putc('\\', tracefile); 290 putc(*p >> 6 & 03, tracefile); 291 putc(*p >> 3 & 07, tracefile); 292 putc(*p & 07, tracefile); 293 } 294 break; 295 } 296 } 297 putc('"', tracefile); 298 #endif 299 } 300 301 302 trargs(ap) 303 char **ap; 304 { 305 #ifdef DEBUG 306 if (tracefile == NULL) 307 return; 308 while (*ap) { 309 trstring(*ap++); 310 if (*ap) 311 putc(' ', tracefile); 312 else 313 putc('\n', tracefile); 314 } 315 fflush(tracefile); 316 #endif 317 } 318 319 320 opentrace() { 321 char s[100]; 322 char *p; 323 char *getenv(); 324 int flags; 325 326 #ifdef DEBUG 327 if (!debug) 328 return; 329 #ifdef not_this_way 330 if ((p = getenv("HOME")) == NULL) { 331 if (geteuid() == 0) 332 p = "/"; 333 else 334 p = "/tmp"; 335 } 336 scopy(p, s); 337 strcat(s, "/trace"); 338 #else 339 scopy("./trace", s); 340 #endif /* not_this_way */ 341 if ((tracefile = fopen(s, "a")) == NULL) { 342 fprintf(stderr, "Can't open %s\n", s); 343 return; 344 } 345 #ifdef O_APPEND 346 if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0) 347 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND); 348 #endif 349 fputs("\nTracing started.\n", tracefile); 350 fflush(tracefile); 351 #endif /* DEBUG */ 352 } 353