1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 1995 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 7*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 8*7c478bd9Sstevel@tonic-gate 9*7c478bd9Sstevel@tonic-gate /* 10*7c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 11*7c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley Software License Agreement 12*7c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 13*7c478bd9Sstevel@tonic-gate */ 14*7c478bd9Sstevel@tonic-gate 15*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 16*7c478bd9Sstevel@tonic-gate 17*7c478bd9Sstevel@tonic-gate #include "sh.h" 18*7c478bd9Sstevel@tonic-gate #include "sh.tconst.h" 19*7c478bd9Sstevel@tonic-gate 20*7c478bd9Sstevel@tonic-gate /* 21*7c478bd9Sstevel@tonic-gate * C shell 22*7c478bd9Sstevel@tonic-gate */ 23*7c478bd9Sstevel@tonic-gate 24*7c478bd9Sstevel@tonic-gate #define IGNORE 1 /* in ignore, it means to ignore value, just parse */ 25*7c478bd9Sstevel@tonic-gate #define NOGLOB 2 /* in ignore, it means not to globone */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #define ADDOP 1 28*7c478bd9Sstevel@tonic-gate #define MULOP 2 29*7c478bd9Sstevel@tonic-gate #define EQOP 4 30*7c478bd9Sstevel@tonic-gate #define RELOP 8 31*7c478bd9Sstevel@tonic-gate #define RESTOP 16 32*7c478bd9Sstevel@tonic-gate #define ANYOP 31 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate #define EQEQ 1 35*7c478bd9Sstevel@tonic-gate #define GTR 2 36*7c478bd9Sstevel@tonic-gate #define LSS 4 37*7c478bd9Sstevel@tonic-gate #define NOTEQ 6 38*7c478bd9Sstevel@tonic-gate #define EQMATCH 7 39*7c478bd9Sstevel@tonic-gate #define NOTEQMATCH 8 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate /* 42*7c478bd9Sstevel@tonic-gate * Determine if file given by name is accessible with permissions 43*7c478bd9Sstevel@tonic-gate * given by mode. 44*7c478bd9Sstevel@tonic-gate * 45*7c478bd9Sstevel@tonic-gate * Borrowed from the Bourne sh, and modified a bit 46*7c478bd9Sstevel@tonic-gate * 47*7c478bd9Sstevel@tonic-gate * If the requested access is permitted, a value of 0 is 48*7c478bd9Sstevel@tonic-gate * returned. Otherwise, a value of -1 is returned and errno is 49*7c478bd9Sstevel@tonic-gate * set to indicate the error 50*7c478bd9Sstevel@tonic-gate */ 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate chk_access(path, mode) 53*7c478bd9Sstevel@tonic-gate register tchar *path; 54*7c478bd9Sstevel@tonic-gate mode_t mode; 55*7c478bd9Sstevel@tonic-gate { 56*7c478bd9Sstevel@tonic-gate static int flag; 57*7c478bd9Sstevel@tonic-gate static uid_t euid; 58*7c478bd9Sstevel@tonic-gate struct stat statb; 59*7c478bd9Sstevel@tonic-gate mode_t ftype; 60*7c478bd9Sstevel@tonic-gate unsigned char name[MAXPATHLEN*MB_LEN_MAX]; /* General use buffer. */ 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate /* convert tchar * to char * */ 63*7c478bd9Sstevel@tonic-gate tstostr(name, path); 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate if(flag == 0) { 66*7c478bd9Sstevel@tonic-gate euid = geteuid(); 67*7c478bd9Sstevel@tonic-gate flag = 1; 68*7c478bd9Sstevel@tonic-gate } 69*7c478bd9Sstevel@tonic-gate if (stat((char *)name, &statb) == 0) { 70*7c478bd9Sstevel@tonic-gate ftype = statb.st_mode & S_IFMT; 71*7c478bd9Sstevel@tonic-gate if(access((char *)name, 010|(mode>>6)) == 0) { 72*7c478bd9Sstevel@tonic-gate if(euid == 0) { 73*7c478bd9Sstevel@tonic-gate if (ftype != S_IFREG || mode != S_IEXEC) 74*7c478bd9Sstevel@tonic-gate return(0); 75*7c478bd9Sstevel@tonic-gate /* root can execute file as long as it has execute 76*7c478bd9Sstevel@tonic-gate permission for someone */ 77*7c478bd9Sstevel@tonic-gate if (statb.st_mode & (S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6))) 78*7c478bd9Sstevel@tonic-gate return(0); 79*7c478bd9Sstevel@tonic-gate return(-1); 80*7c478bd9Sstevel@tonic-gate } 81*7c478bd9Sstevel@tonic-gate return(0); 82*7c478bd9Sstevel@tonic-gate } 83*7c478bd9Sstevel@tonic-gate } 84*7c478bd9Sstevel@tonic-gate return(-1); 85*7c478bd9Sstevel@tonic-gate } 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate exp(vp) 88*7c478bd9Sstevel@tonic-gate register tchar ***vp; 89*7c478bd9Sstevel@tonic-gate { 90*7c478bd9Sstevel@tonic-gate #ifdef TRACE 91*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp()\n"); 92*7c478bd9Sstevel@tonic-gate #endif 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate return (exp0(vp, 0)); 95*7c478bd9Sstevel@tonic-gate } 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate exp0(vp, ignore) 98*7c478bd9Sstevel@tonic-gate register tchar ***vp; 99*7c478bd9Sstevel@tonic-gate bool ignore; 100*7c478bd9Sstevel@tonic-gate { 101*7c478bd9Sstevel@tonic-gate register int p1 = exp1(vp, ignore); 102*7c478bd9Sstevel@tonic-gate #ifdef TRACE 103*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp0()\n"); 104*7c478bd9Sstevel@tonic-gate #endif 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 107*7c478bd9Sstevel@tonic-gate etraci("exp0 p1", p1, vp); 108*7c478bd9Sstevel@tonic-gate #endif 109*7c478bd9Sstevel@tonic-gate if (**vp && eq(**vp, S_BARBAR /*"||"*/)) { 110*7c478bd9Sstevel@tonic-gate register int p2; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate (*vp)++; 113*7c478bd9Sstevel@tonic-gate p2 = exp0(vp, (ignore&IGNORE) || p1); 114*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 115*7c478bd9Sstevel@tonic-gate etraci("exp0 p2", p2, vp); 116*7c478bd9Sstevel@tonic-gate #endif 117*7c478bd9Sstevel@tonic-gate return (p1 || p2); 118*7c478bd9Sstevel@tonic-gate } 119*7c478bd9Sstevel@tonic-gate return (p1); 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate exp1(vp, ignore) 123*7c478bd9Sstevel@tonic-gate register tchar ***vp; 124*7c478bd9Sstevel@tonic-gate { 125*7c478bd9Sstevel@tonic-gate register int p1 = exp2(vp, ignore); 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate #ifdef TRACE 128*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp1()\n"); 129*7c478bd9Sstevel@tonic-gate #endif 130*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 131*7c478bd9Sstevel@tonic-gate etraci("exp1 p1", p1, vp); 132*7c478bd9Sstevel@tonic-gate #endif 133*7c478bd9Sstevel@tonic-gate if (**vp && eq(**vp, S_ANDAND /*"&&" */)) { 134*7c478bd9Sstevel@tonic-gate register int p2; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate (*vp)++; 137*7c478bd9Sstevel@tonic-gate p2 = exp1(vp, (ignore&IGNORE) || !p1); 138*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 139*7c478bd9Sstevel@tonic-gate etraci("exp1 p2", p2, vp); 140*7c478bd9Sstevel@tonic-gate #endif 141*7c478bd9Sstevel@tonic-gate return (p1 && p2); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate return (p1); 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate exp2(vp, ignore) 147*7c478bd9Sstevel@tonic-gate register tchar ***vp; 148*7c478bd9Sstevel@tonic-gate bool ignore; 149*7c478bd9Sstevel@tonic-gate { 150*7c478bd9Sstevel@tonic-gate register int p1 = exp2a(vp, ignore); 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate #ifdef TRACE 153*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp2()\n"); 154*7c478bd9Sstevel@tonic-gate #endif 155*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 156*7c478bd9Sstevel@tonic-gate etraci("exp3 p1", p1, vp); 157*7c478bd9Sstevel@tonic-gate #endif 158*7c478bd9Sstevel@tonic-gate if (**vp && eq(**vp, S_BAR /*"|" */)) { 159*7c478bd9Sstevel@tonic-gate register int p2; 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate (*vp)++; 162*7c478bd9Sstevel@tonic-gate p2 = exp2(vp, ignore); 163*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 164*7c478bd9Sstevel@tonic-gate etraci("exp3 p2", p2, vp); 165*7c478bd9Sstevel@tonic-gate #endif 166*7c478bd9Sstevel@tonic-gate return (p1 | p2); 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate return (p1); 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate exp2a(vp, ignore) 172*7c478bd9Sstevel@tonic-gate register tchar ***vp; 173*7c478bd9Sstevel@tonic-gate bool ignore; 174*7c478bd9Sstevel@tonic-gate { 175*7c478bd9Sstevel@tonic-gate register int p1 = exp2b(vp, ignore); 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate #ifdef TRACE 178*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp2a()\n"); 179*7c478bd9Sstevel@tonic-gate #endif 180*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 181*7c478bd9Sstevel@tonic-gate etraci("exp2a p1", p1, vp); 182*7c478bd9Sstevel@tonic-gate #endif 183*7c478bd9Sstevel@tonic-gate if (**vp && eq(**vp, S_HAT /*"^" */)) { 184*7c478bd9Sstevel@tonic-gate register int p2; 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate (*vp)++; 187*7c478bd9Sstevel@tonic-gate p2 = exp2a(vp, ignore); 188*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 189*7c478bd9Sstevel@tonic-gate etraci("exp2a p2", p2, vp); 190*7c478bd9Sstevel@tonic-gate #endif 191*7c478bd9Sstevel@tonic-gate return (p1 ^ p2); 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate return (p1); 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate exp2b(vp, ignore) 197*7c478bd9Sstevel@tonic-gate register tchar ***vp; 198*7c478bd9Sstevel@tonic-gate bool ignore; 199*7c478bd9Sstevel@tonic-gate { 200*7c478bd9Sstevel@tonic-gate register int p1 = exp2c(vp, ignore); 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate #ifdef TRACE 203*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp2b()\n"); 204*7c478bd9Sstevel@tonic-gate #endif 205*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 206*7c478bd9Sstevel@tonic-gate etraci("exp2b p1", p1, vp); 207*7c478bd9Sstevel@tonic-gate #endif 208*7c478bd9Sstevel@tonic-gate if (**vp && eq(**vp, S_AND /*"&"*/)) { 209*7c478bd9Sstevel@tonic-gate register int p2; 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate (*vp)++; 212*7c478bd9Sstevel@tonic-gate p2 = exp2b(vp, ignore); 213*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 214*7c478bd9Sstevel@tonic-gate etraci("exp2b p2", p2, vp); 215*7c478bd9Sstevel@tonic-gate #endif 216*7c478bd9Sstevel@tonic-gate return (p1 & p2); 217*7c478bd9Sstevel@tonic-gate } 218*7c478bd9Sstevel@tonic-gate return (p1); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate exp2c(vp, ignore) 222*7c478bd9Sstevel@tonic-gate register tchar ***vp; 223*7c478bd9Sstevel@tonic-gate bool ignore; 224*7c478bd9Sstevel@tonic-gate { 225*7c478bd9Sstevel@tonic-gate register tchar *p1 = exp3(vp, ignore); 226*7c478bd9Sstevel@tonic-gate register tchar *p2; 227*7c478bd9Sstevel@tonic-gate register int i; 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate #ifdef TRACE 230*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp2c()\n"); 231*7c478bd9Sstevel@tonic-gate #endif 232*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 233*7c478bd9Sstevel@tonic-gate etracc("exp2c p1", p1, vp); 234*7c478bd9Sstevel@tonic-gate #endif 235*7c478bd9Sstevel@tonic-gate if (i = isa(**vp, EQOP)) { 236*7c478bd9Sstevel@tonic-gate (*vp)++; 237*7c478bd9Sstevel@tonic-gate if (i == EQMATCH || i == NOTEQMATCH) 238*7c478bd9Sstevel@tonic-gate ignore |= NOGLOB; 239*7c478bd9Sstevel@tonic-gate p2 = exp3(vp, ignore); 240*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 241*7c478bd9Sstevel@tonic-gate etracc("exp2c p2", p2, vp); 242*7c478bd9Sstevel@tonic-gate #endif 243*7c478bd9Sstevel@tonic-gate if (!(ignore&IGNORE)) switch (i) { 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate case EQEQ: 246*7c478bd9Sstevel@tonic-gate i = eq(p1, p2); 247*7c478bd9Sstevel@tonic-gate break; 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate case NOTEQ: 250*7c478bd9Sstevel@tonic-gate i = !eq(p1, p2); 251*7c478bd9Sstevel@tonic-gate break; 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate case EQMATCH: 254*7c478bd9Sstevel@tonic-gate i = Gmatch(p1, p2); 255*7c478bd9Sstevel@tonic-gate break; 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate case NOTEQMATCH: 258*7c478bd9Sstevel@tonic-gate i = !Gmatch(p1, p2); 259*7c478bd9Sstevel@tonic-gate break; 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate xfree(p1), xfree(p2); 262*7c478bd9Sstevel@tonic-gate return (i); 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate i = egetn(p1); 265*7c478bd9Sstevel@tonic-gate xfree(p1); 266*7c478bd9Sstevel@tonic-gate return (i); 267*7c478bd9Sstevel@tonic-gate } 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate tchar * 270*7c478bd9Sstevel@tonic-gate exp3(vp, ignore) 271*7c478bd9Sstevel@tonic-gate register tchar ***vp; 272*7c478bd9Sstevel@tonic-gate bool ignore; 273*7c478bd9Sstevel@tonic-gate { 274*7c478bd9Sstevel@tonic-gate register tchar *p1, *p2; 275*7c478bd9Sstevel@tonic-gate register int i; 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate #ifdef TRACE 278*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp3()\n"); 279*7c478bd9Sstevel@tonic-gate #endif 280*7c478bd9Sstevel@tonic-gate p1 = exp3a(vp, ignore); 281*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 282*7c478bd9Sstevel@tonic-gate etracc("exp3 p1", p1, vp); 283*7c478bd9Sstevel@tonic-gate #endif 284*7c478bd9Sstevel@tonic-gate if (i = isa(**vp, RELOP)) { 285*7c478bd9Sstevel@tonic-gate (*vp)++; 286*7c478bd9Sstevel@tonic-gate if (**vp && eq(**vp, S_EQ /*"=" */)) 287*7c478bd9Sstevel@tonic-gate i |= 1, (*vp)++; 288*7c478bd9Sstevel@tonic-gate p2 = exp3(vp, ignore); 289*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 290*7c478bd9Sstevel@tonic-gate etracc("exp3 p2", p2, vp); 291*7c478bd9Sstevel@tonic-gate #endif 292*7c478bd9Sstevel@tonic-gate if (!(ignore&IGNORE)) switch (i) { 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate case GTR: 295*7c478bd9Sstevel@tonic-gate i = egetn(p1) > egetn(p2); 296*7c478bd9Sstevel@tonic-gate break; 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate case GTR|1: 299*7c478bd9Sstevel@tonic-gate i = egetn(p1) >= egetn(p2); 300*7c478bd9Sstevel@tonic-gate break; 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate case LSS: 303*7c478bd9Sstevel@tonic-gate i = egetn(p1) < egetn(p2); 304*7c478bd9Sstevel@tonic-gate break; 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate case LSS|1: 307*7c478bd9Sstevel@tonic-gate i = egetn(p1) <= egetn(p2); 308*7c478bd9Sstevel@tonic-gate break; 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate xfree(p1), xfree(p2); 311*7c478bd9Sstevel@tonic-gate return (putn(i)); 312*7c478bd9Sstevel@tonic-gate } 313*7c478bd9Sstevel@tonic-gate return (p1); 314*7c478bd9Sstevel@tonic-gate } 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate tchar * 317*7c478bd9Sstevel@tonic-gate exp3a(vp, ignore) 318*7c478bd9Sstevel@tonic-gate register tchar ***vp; 319*7c478bd9Sstevel@tonic-gate bool ignore; 320*7c478bd9Sstevel@tonic-gate { 321*7c478bd9Sstevel@tonic-gate register tchar *p1, *p2, *op; 322*7c478bd9Sstevel@tonic-gate register int i; 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate #ifdef TRACE 325*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp3a()\n"); 326*7c478bd9Sstevel@tonic-gate #endif 327*7c478bd9Sstevel@tonic-gate p1 = exp4(vp, ignore); 328*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 329*7c478bd9Sstevel@tonic-gate etracc("exp3a p1", p1, vp); 330*7c478bd9Sstevel@tonic-gate #endif 331*7c478bd9Sstevel@tonic-gate op = **vp; 332*7c478bd9Sstevel@tonic-gate /* if (op && any(op[0], "<>") && op[0] == op[1]) { */ 333*7c478bd9Sstevel@tonic-gate if (op && (op[0] == '<' || op[0] == '>') && op[0] == op[1]) { 334*7c478bd9Sstevel@tonic-gate (*vp)++; 335*7c478bd9Sstevel@tonic-gate p2 = exp3a(vp, ignore); 336*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 337*7c478bd9Sstevel@tonic-gate etracc("exp3a p2", p2, vp); 338*7c478bd9Sstevel@tonic-gate #endif 339*7c478bd9Sstevel@tonic-gate if (op[0] == '<') 340*7c478bd9Sstevel@tonic-gate i = egetn(p1) << egetn(p2); 341*7c478bd9Sstevel@tonic-gate else 342*7c478bd9Sstevel@tonic-gate i = egetn(p1) >> egetn(p2); 343*7c478bd9Sstevel@tonic-gate xfree(p1), xfree(p2); 344*7c478bd9Sstevel@tonic-gate return (putn(i)); 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate return (p1); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate tchar * 350*7c478bd9Sstevel@tonic-gate exp4(vp, ignore) 351*7c478bd9Sstevel@tonic-gate register tchar ***vp; 352*7c478bd9Sstevel@tonic-gate bool ignore; 353*7c478bd9Sstevel@tonic-gate { 354*7c478bd9Sstevel@tonic-gate register tchar *p1, *p2; 355*7c478bd9Sstevel@tonic-gate register int i = 0; 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate #ifdef TRACE 358*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp4()\n"); 359*7c478bd9Sstevel@tonic-gate #endif 360*7c478bd9Sstevel@tonic-gate p1 = exp5(vp, ignore); 361*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 362*7c478bd9Sstevel@tonic-gate etracc("exp4 p1", p1, vp); 363*7c478bd9Sstevel@tonic-gate #endif 364*7c478bd9Sstevel@tonic-gate if (isa(**vp, ADDOP)) { 365*7c478bd9Sstevel@tonic-gate register tchar *op = *(*vp)++; 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate p2 = exp4(vp, ignore); 368*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 369*7c478bd9Sstevel@tonic-gate etracc("exp4 p2", p2, vp); 370*7c478bd9Sstevel@tonic-gate #endif 371*7c478bd9Sstevel@tonic-gate if (!(ignore&IGNORE)) switch (op[0]) { 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate case '+': 374*7c478bd9Sstevel@tonic-gate i = egetn(p1) + egetn(p2); 375*7c478bd9Sstevel@tonic-gate break; 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate case '-': 378*7c478bd9Sstevel@tonic-gate i = egetn(p1) - egetn(p2); 379*7c478bd9Sstevel@tonic-gate break; 380*7c478bd9Sstevel@tonic-gate } 381*7c478bd9Sstevel@tonic-gate xfree(p1), xfree(p2); 382*7c478bd9Sstevel@tonic-gate return (putn(i)); 383*7c478bd9Sstevel@tonic-gate } 384*7c478bd9Sstevel@tonic-gate return (p1); 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate tchar * 388*7c478bd9Sstevel@tonic-gate exp5(vp, ignore) 389*7c478bd9Sstevel@tonic-gate register tchar ***vp; 390*7c478bd9Sstevel@tonic-gate bool ignore; 391*7c478bd9Sstevel@tonic-gate { 392*7c478bd9Sstevel@tonic-gate register tchar *p1, *p2; 393*7c478bd9Sstevel@tonic-gate register int i = 0; 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate #ifdef TRACE 396*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp5()\n"); 397*7c478bd9Sstevel@tonic-gate #endif 398*7c478bd9Sstevel@tonic-gate p1 = exp6(vp, ignore); 399*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 400*7c478bd9Sstevel@tonic-gate etracc("exp5 p1", p1, vp); 401*7c478bd9Sstevel@tonic-gate #endif 402*7c478bd9Sstevel@tonic-gate if (isa(**vp, MULOP)) { 403*7c478bd9Sstevel@tonic-gate register tchar *op = *(*vp)++; 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate p2 = exp5(vp, ignore); 406*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 407*7c478bd9Sstevel@tonic-gate etracc("exp5 p2", p2, vp); 408*7c478bd9Sstevel@tonic-gate #endif 409*7c478bd9Sstevel@tonic-gate if (!(ignore&IGNORE)) switch (op[0]) { 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate case '*': 412*7c478bd9Sstevel@tonic-gate i = egetn(p1) * egetn(p2); 413*7c478bd9Sstevel@tonic-gate break; 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate case '/': 416*7c478bd9Sstevel@tonic-gate i = egetn(p2); 417*7c478bd9Sstevel@tonic-gate if (i == 0) 418*7c478bd9Sstevel@tonic-gate error("Divide by 0"); 419*7c478bd9Sstevel@tonic-gate i = egetn(p1) / i; 420*7c478bd9Sstevel@tonic-gate break; 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate case '%': 423*7c478bd9Sstevel@tonic-gate i = egetn(p2); 424*7c478bd9Sstevel@tonic-gate if (i == 0) 425*7c478bd9Sstevel@tonic-gate error("Mod by 0"); 426*7c478bd9Sstevel@tonic-gate i = egetn(p1) % i; 427*7c478bd9Sstevel@tonic-gate break; 428*7c478bd9Sstevel@tonic-gate } 429*7c478bd9Sstevel@tonic-gate xfree(p1), xfree(p2); 430*7c478bd9Sstevel@tonic-gate return (putn(i)); 431*7c478bd9Sstevel@tonic-gate } 432*7c478bd9Sstevel@tonic-gate return (p1); 433*7c478bd9Sstevel@tonic-gate } 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate tchar * 436*7c478bd9Sstevel@tonic-gate exp6(vp, ignore) 437*7c478bd9Sstevel@tonic-gate register tchar ***vp; 438*7c478bd9Sstevel@tonic-gate { 439*7c478bd9Sstevel@tonic-gate int ccode, i; 440*7c478bd9Sstevel@tonic-gate register tchar *cp, *dp, *ep; 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate #ifdef TRACE 443*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exp6()\n"); 444*7c478bd9Sstevel@tonic-gate #endif 445*7c478bd9Sstevel@tonic-gate if (**vp == 0) 446*7c478bd9Sstevel@tonic-gate bferr("Expression syntax"); 447*7c478bd9Sstevel@tonic-gate if (eq(**vp, S_EXAS /* "!" */)) { 448*7c478bd9Sstevel@tonic-gate (*vp)++; 449*7c478bd9Sstevel@tonic-gate cp = exp6(vp, ignore); 450*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 451*7c478bd9Sstevel@tonic-gate etracc("exp6 ! cp", cp, vp); 452*7c478bd9Sstevel@tonic-gate #endif 453*7c478bd9Sstevel@tonic-gate i = egetn(cp); 454*7c478bd9Sstevel@tonic-gate xfree(cp); 455*7c478bd9Sstevel@tonic-gate return (putn(!i)); 456*7c478bd9Sstevel@tonic-gate } 457*7c478bd9Sstevel@tonic-gate if (eq(**vp, S_TIL /*"~" */)) { 458*7c478bd9Sstevel@tonic-gate (*vp)++; 459*7c478bd9Sstevel@tonic-gate cp = exp6(vp, ignore); 460*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 461*7c478bd9Sstevel@tonic-gate etracc("exp6 ~ cp", cp, vp); 462*7c478bd9Sstevel@tonic-gate #endif 463*7c478bd9Sstevel@tonic-gate i = egetn(cp); 464*7c478bd9Sstevel@tonic-gate xfree(cp); 465*7c478bd9Sstevel@tonic-gate return (putn(~i)); 466*7c478bd9Sstevel@tonic-gate } 467*7c478bd9Sstevel@tonic-gate if (eq(**vp, S_LPAR /*"(" */)) { 468*7c478bd9Sstevel@tonic-gate (*vp)++; 469*7c478bd9Sstevel@tonic-gate ccode = exp0(vp, ignore); 470*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 471*7c478bd9Sstevel@tonic-gate etraci("exp6 () ccode", ccode, vp); 472*7c478bd9Sstevel@tonic-gate #endif 473*7c478bd9Sstevel@tonic-gate if (*vp == 0 || **vp == 0 || ***vp != ')') 474*7c478bd9Sstevel@tonic-gate bferr("Expression syntax"); 475*7c478bd9Sstevel@tonic-gate (*vp)++; 476*7c478bd9Sstevel@tonic-gate return (putn(ccode)); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate if (eq(**vp, S_LBRA /* "{" */)) { 479*7c478bd9Sstevel@tonic-gate register tchar **v; 480*7c478bd9Sstevel@tonic-gate struct command faket; 481*7c478bd9Sstevel@tonic-gate tchar *fakecom[2]; 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate faket.t_dtyp = TCOM; 484*7c478bd9Sstevel@tonic-gate faket.t_dflg = 0; 485*7c478bd9Sstevel@tonic-gate faket.t_dcar = faket.t_dcdr = faket.t_dspr = (struct command *)0; 486*7c478bd9Sstevel@tonic-gate faket.t_dcom = fakecom; 487*7c478bd9Sstevel@tonic-gate fakecom[0] = S_BRAPPPBRA /*"{ ... }" */; 488*7c478bd9Sstevel@tonic-gate fakecom[1] = NOSTR; 489*7c478bd9Sstevel@tonic-gate (*vp)++; 490*7c478bd9Sstevel@tonic-gate v = *vp; 491*7c478bd9Sstevel@tonic-gate for (;;) { 492*7c478bd9Sstevel@tonic-gate if (!**vp) 493*7c478bd9Sstevel@tonic-gate bferr("Missing }"); 494*7c478bd9Sstevel@tonic-gate if (eq(*(*vp)++, S_RBRA /*"}" */)) 495*7c478bd9Sstevel@tonic-gate break; 496*7c478bd9Sstevel@tonic-gate } 497*7c478bd9Sstevel@tonic-gate if (ignore&IGNORE) 498*7c478bd9Sstevel@tonic-gate return (S_ /*""*/); 499*7c478bd9Sstevel@tonic-gate psavejob(); 500*7c478bd9Sstevel@tonic-gate if (pfork(&faket, -1) == 0) { 501*7c478bd9Sstevel@tonic-gate *--(*vp) = 0; 502*7c478bd9Sstevel@tonic-gate evalav(v); 503*7c478bd9Sstevel@tonic-gate exitstat(); 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate pwait(); 506*7c478bd9Sstevel@tonic-gate prestjob(); 507*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 508*7c478bd9Sstevel@tonic-gate etraci("exp6 {} status", egetn(value("status")), vp); 509*7c478bd9Sstevel@tonic-gate #endif 510*7c478bd9Sstevel@tonic-gate return (putn(egetn(value(S_status /*"status" */)) == 0)); 511*7c478bd9Sstevel@tonic-gate } 512*7c478bd9Sstevel@tonic-gate if (isa(**vp, ANYOP)) 513*7c478bd9Sstevel@tonic-gate return (S_ /*""*/); 514*7c478bd9Sstevel@tonic-gate cp = *(*vp)++; 515*7c478bd9Sstevel@tonic-gate if (*cp == '-' && any(cp[1], S_erwxfdzo /*"erwxfdzo" */)) { 516*7c478bd9Sstevel@tonic-gate struct stat stb; 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate if (cp[2] != '\0') 519*7c478bd9Sstevel@tonic-gate bferr("Malformed file inquiry"); 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate /* 522*7c478bd9Sstevel@tonic-gate * Detect missing file names by checking for operator 523*7c478bd9Sstevel@tonic-gate * in the file name position. However, if an operator 524*7c478bd9Sstevel@tonic-gate * name appears there, we must make sure that there's 525*7c478bd9Sstevel@tonic-gate * no file by that name (e.g., "/") before announcing 526*7c478bd9Sstevel@tonic-gate * an error. Even this check isn't quite right, since 527*7c478bd9Sstevel@tonic-gate * it doesn't take globbing into account. 528*7c478bd9Sstevel@tonic-gate */ 529*7c478bd9Sstevel@tonic-gate if (isa(**vp, ANYOP) && stat_(**vp, &stb)) 530*7c478bd9Sstevel@tonic-gate bferr("Missing file name"); 531*7c478bd9Sstevel@tonic-gate dp = *(*vp)++; 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate if (ignore&IGNORE) 534*7c478bd9Sstevel@tonic-gate return (S_ /*""*/); 535*7c478bd9Sstevel@tonic-gate ep = globone(dp); 536*7c478bd9Sstevel@tonic-gate switch (cp[1]) { 537*7c478bd9Sstevel@tonic-gate 538*7c478bd9Sstevel@tonic-gate case 'r': 539*7c478bd9Sstevel@tonic-gate i = !chk_access(ep, S_IREAD); 540*7c478bd9Sstevel@tonic-gate break; 541*7c478bd9Sstevel@tonic-gate 542*7c478bd9Sstevel@tonic-gate case 'w': 543*7c478bd9Sstevel@tonic-gate i = !chk_access(ep, S_IWRITE); 544*7c478bd9Sstevel@tonic-gate break; 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate case 'x': 547*7c478bd9Sstevel@tonic-gate i = !chk_access(ep, S_IEXEC); 548*7c478bd9Sstevel@tonic-gate break; 549*7c478bd9Sstevel@tonic-gate 550*7c478bd9Sstevel@tonic-gate default: 551*7c478bd9Sstevel@tonic-gate if (stat_(ep, &stb)) { 552*7c478bd9Sstevel@tonic-gate xfree(ep); 553*7c478bd9Sstevel@tonic-gate return (S_0 /*"0"*/); 554*7c478bd9Sstevel@tonic-gate } 555*7c478bd9Sstevel@tonic-gate switch (cp[1]) { 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate case 'f': 558*7c478bd9Sstevel@tonic-gate i = (stb.st_mode & S_IFMT) == S_IFREG; 559*7c478bd9Sstevel@tonic-gate break; 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate case 'd': 562*7c478bd9Sstevel@tonic-gate i = (stb.st_mode & S_IFMT) == S_IFDIR; 563*7c478bd9Sstevel@tonic-gate break; 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate case 'z': 566*7c478bd9Sstevel@tonic-gate i = stb.st_size == 0; 567*7c478bd9Sstevel@tonic-gate break; 568*7c478bd9Sstevel@tonic-gate 569*7c478bd9Sstevel@tonic-gate case 'e': 570*7c478bd9Sstevel@tonic-gate i = 1; 571*7c478bd9Sstevel@tonic-gate break; 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate case 'o': 574*7c478bd9Sstevel@tonic-gate i = stb.st_uid == uid; 575*7c478bd9Sstevel@tonic-gate break; 576*7c478bd9Sstevel@tonic-gate } 577*7c478bd9Sstevel@tonic-gate } 578*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 579*7c478bd9Sstevel@tonic-gate etraci("exp6 -? i", i, vp); 580*7c478bd9Sstevel@tonic-gate #endif 581*7c478bd9Sstevel@tonic-gate xfree(ep); 582*7c478bd9Sstevel@tonic-gate return (putn(i)); 583*7c478bd9Sstevel@tonic-gate } 584*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 585*7c478bd9Sstevel@tonic-gate etracc("exp6 default", cp, vp); 586*7c478bd9Sstevel@tonic-gate #endif 587*7c478bd9Sstevel@tonic-gate return (ignore&NOGLOB ? savestr(cp) : globone(cp)); 588*7c478bd9Sstevel@tonic-gate } 589*7c478bd9Sstevel@tonic-gate 590*7c478bd9Sstevel@tonic-gate evalav(v) 591*7c478bd9Sstevel@tonic-gate register tchar **v; 592*7c478bd9Sstevel@tonic-gate { 593*7c478bd9Sstevel@tonic-gate struct wordent paraml; 594*7c478bd9Sstevel@tonic-gate register struct wordent *hp = ¶ml; 595*7c478bd9Sstevel@tonic-gate struct command *t; 596*7c478bd9Sstevel@tonic-gate register struct wordent *wdp = hp; 597*7c478bd9Sstevel@tonic-gate 598*7c478bd9Sstevel@tonic-gate #ifdef TRACE 599*7c478bd9Sstevel@tonic-gate tprintf("TRACE- evalav()\n"); 600*7c478bd9Sstevel@tonic-gate #endif 601*7c478bd9Sstevel@tonic-gate set(S_status /*"status" */, S_0 /*"0"*/); 602*7c478bd9Sstevel@tonic-gate hp->prev = hp->next = hp; 603*7c478bd9Sstevel@tonic-gate hp->word = S_ /*""*/; 604*7c478bd9Sstevel@tonic-gate while (*v) { 605*7c478bd9Sstevel@tonic-gate register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp); 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate new->prev = wdp; 608*7c478bd9Sstevel@tonic-gate new->next = hp; 609*7c478bd9Sstevel@tonic-gate wdp->next = new; 610*7c478bd9Sstevel@tonic-gate wdp = new; 611*7c478bd9Sstevel@tonic-gate wdp->word = savestr(*v++); 612*7c478bd9Sstevel@tonic-gate } 613*7c478bd9Sstevel@tonic-gate hp->prev = wdp; 614*7c478bd9Sstevel@tonic-gate alias(¶ml); 615*7c478bd9Sstevel@tonic-gate t = syntax(paraml.next, ¶ml, 0); 616*7c478bd9Sstevel@tonic-gate if (err) 617*7c478bd9Sstevel@tonic-gate error("%s", gettext(err)); 618*7c478bd9Sstevel@tonic-gate execute(t, -1); 619*7c478bd9Sstevel@tonic-gate freelex(¶ml), freesyn(t); 620*7c478bd9Sstevel@tonic-gate } 621*7c478bd9Sstevel@tonic-gate 622*7c478bd9Sstevel@tonic-gate isa(cp, what) 623*7c478bd9Sstevel@tonic-gate register tchar *cp; 624*7c478bd9Sstevel@tonic-gate register int what; 625*7c478bd9Sstevel@tonic-gate { 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate #ifdef TRACE 628*7c478bd9Sstevel@tonic-gate tprintf("TRACE- isa()\n"); 629*7c478bd9Sstevel@tonic-gate #endif 630*7c478bd9Sstevel@tonic-gate if (cp == 0) 631*7c478bd9Sstevel@tonic-gate return ((what & RESTOP) != 0); 632*7c478bd9Sstevel@tonic-gate if (cp[1] == 0) { 633*7c478bd9Sstevel@tonic-gate if (what & ADDOP && (*cp == '+' || *cp == '-')) 634*7c478bd9Sstevel@tonic-gate return (1); 635*7c478bd9Sstevel@tonic-gate if (what & MULOP && (*cp == '*' || *cp == '/' || *cp == '%')) 636*7c478bd9Sstevel@tonic-gate return (1); 637*7c478bd9Sstevel@tonic-gate if (what & RESTOP && (*cp == '(' || *cp == ')' || *cp == '!' || 638*7c478bd9Sstevel@tonic-gate *cp == '~' || *cp == '^' || *cp == '"')) 639*7c478bd9Sstevel@tonic-gate return (1); 640*7c478bd9Sstevel@tonic-gate } else if (cp[2] == 0) { 641*7c478bd9Sstevel@tonic-gate if (what & RESTOP) { 642*7c478bd9Sstevel@tonic-gate if (cp[0] == '|' && cp[1] == '&') 643*7c478bd9Sstevel@tonic-gate return (1); 644*7c478bd9Sstevel@tonic-gate if (cp[0] == '<' && cp[1] == '<') 645*7c478bd9Sstevel@tonic-gate return (1); 646*7c478bd9Sstevel@tonic-gate if (cp[0] == '>' && cp[1] == '>') 647*7c478bd9Sstevel@tonic-gate return (1); 648*7c478bd9Sstevel@tonic-gate } 649*7c478bd9Sstevel@tonic-gate if (what & EQOP) { 650*7c478bd9Sstevel@tonic-gate if (cp[0] == '=') { 651*7c478bd9Sstevel@tonic-gate if (cp[1] == '=') 652*7c478bd9Sstevel@tonic-gate return (EQEQ); 653*7c478bd9Sstevel@tonic-gate if (cp[1] == '~') 654*7c478bd9Sstevel@tonic-gate return (EQMATCH); 655*7c478bd9Sstevel@tonic-gate } else if (cp[0] == '!') { 656*7c478bd9Sstevel@tonic-gate if (cp[1] == '=') 657*7c478bd9Sstevel@tonic-gate return (NOTEQ); 658*7c478bd9Sstevel@tonic-gate if (cp[1] == '~') 659*7c478bd9Sstevel@tonic-gate return (NOTEQMATCH); 660*7c478bd9Sstevel@tonic-gate } 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate } 663*7c478bd9Sstevel@tonic-gate if (what & RELOP) { 664*7c478bd9Sstevel@tonic-gate if (*cp == '<') 665*7c478bd9Sstevel@tonic-gate return (LSS); 666*7c478bd9Sstevel@tonic-gate if (*cp == '>') 667*7c478bd9Sstevel@tonic-gate return (GTR); 668*7c478bd9Sstevel@tonic-gate } 669*7c478bd9Sstevel@tonic-gate return (0); 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate egetn(cp) 673*7c478bd9Sstevel@tonic-gate register tchar *cp; 674*7c478bd9Sstevel@tonic-gate { 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate #ifdef TRACE 677*7c478bd9Sstevel@tonic-gate tprintf("TRACE- egetn()\n"); 678*7c478bd9Sstevel@tonic-gate #endif 679*7c478bd9Sstevel@tonic-gate if (*cp && *cp != '-' && !digit(*cp)) 680*7c478bd9Sstevel@tonic-gate bferr("Expression syntax"); 681*7c478bd9Sstevel@tonic-gate return (getn(cp)); 682*7c478bd9Sstevel@tonic-gate } 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate /* Phew! */ 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG 687*7c478bd9Sstevel@tonic-gate etraci(str, i, vp) 688*7c478bd9Sstevel@tonic-gate tchar *str; 689*7c478bd9Sstevel@tonic-gate int i; 690*7c478bd9Sstevel@tonic-gate tchar ***vp; 691*7c478bd9Sstevel@tonic-gate { 692*7c478bd9Sstevel@tonic-gate 693*7c478bd9Sstevel@tonic-gate printf("%s=%d\t", str, i); 694*7c478bd9Sstevel@tonic-gate blkpr(*vp); 695*7c478bd9Sstevel@tonic-gate printf("\n"); 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate 698*7c478bd9Sstevel@tonic-gate etracc(str, cp, vp) 699*7c478bd9Sstevel@tonic-gate tchar *str, *cp; 700*7c478bd9Sstevel@tonic-gate tchar ***vp; 701*7c478bd9Sstevel@tonic-gate { 702*7c478bd9Sstevel@tonic-gate 703*7c478bd9Sstevel@tonic-gate printf("%s=%s\t", str, cp); 704*7c478bd9Sstevel@tonic-gate blkpr(*vp); 705*7c478bd9Sstevel@tonic-gate printf("\n"); 706*7c478bd9Sstevel@tonic-gate } 707*7c478bd9Sstevel@tonic-gate #endif 708