10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 22*527Schin 23*527Schin /* 24*527Schin * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25*527Schin * Use is subject to license terms. 26*527Schin */ 27*527Schin 280Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 290Sstevel@tonic-gate /* All Rights Reserved */ 300Sstevel@tonic-gate 31*527Schin #pragma ident "%Z%%M% %I% %E% SMI" 320Sstevel@tonic-gate /* 330Sstevel@tonic-gate * UNIX shell 340Sstevel@tonic-gate */ 350Sstevel@tonic-gate 360Sstevel@tonic-gate #include "defs.h" 370Sstevel@tonic-gate #include "dup.h" 38*527Schin #include <stdio.h> 390Sstevel@tonic-gate #include <fcntl.h> 400Sstevel@tonic-gate #include <sys/types.h> 410Sstevel@tonic-gate #include <sys/stat.h> 420Sstevel@tonic-gate #include <errno.h> 430Sstevel@tonic-gate 440Sstevel@tonic-gate short topfd; 450Sstevel@tonic-gate 460Sstevel@tonic-gate /* ======== input output and file copying ======== */ 470Sstevel@tonic-gate 48*527Schin void 49*527Schin initf(int fd) 500Sstevel@tonic-gate { 51*527Schin struct fileblk *f = standin; 520Sstevel@tonic-gate 530Sstevel@tonic-gate f->fdes = fd; 540Sstevel@tonic-gate f->fsiz = ((flags & oneflg) == 0 ? BUFFERSIZE : 1); 550Sstevel@tonic-gate f->fnxt = f->fend = f->fbuf; 560Sstevel@tonic-gate f->nxtoff = f->endoff = 0; 570Sstevel@tonic-gate f->feval = 0; 580Sstevel@tonic-gate f->flin = 1; 590Sstevel@tonic-gate f->feof = FALSE; 600Sstevel@tonic-gate } 610Sstevel@tonic-gate 62*527Schin int 63*527Schin estabf(unsigned char *s) 640Sstevel@tonic-gate { 65*527Schin struct fileblk *f; 660Sstevel@tonic-gate 670Sstevel@tonic-gate (f = standin)->fdes = -1; 680Sstevel@tonic-gate f->fend = length(s) + (f->fnxt = s); 690Sstevel@tonic-gate f->nxtoff = 0; 700Sstevel@tonic-gate f->endoff = length(s); 710Sstevel@tonic-gate f->flin = 1; 720Sstevel@tonic-gate return (f->feof = (s == 0)); 730Sstevel@tonic-gate } 740Sstevel@tonic-gate 75*527Schin void 76*527Schin push(struct fileblk *af) 770Sstevel@tonic-gate { 78*527Schin struct fileblk *f; 790Sstevel@tonic-gate 800Sstevel@tonic-gate (f = af)->fstak = standin; 810Sstevel@tonic-gate f->feof = 0; 820Sstevel@tonic-gate f->feval = 0; 830Sstevel@tonic-gate standin = f; 840Sstevel@tonic-gate } 850Sstevel@tonic-gate 86*527Schin int 87*527Schin pop(void) 880Sstevel@tonic-gate { 89*527Schin struct fileblk *f; 900Sstevel@tonic-gate 910Sstevel@tonic-gate if ((f = standin)->fstak) 920Sstevel@tonic-gate { 930Sstevel@tonic-gate if (f->fdes >= 0) 940Sstevel@tonic-gate close(f->fdes); 950Sstevel@tonic-gate standin = f->fstak; 960Sstevel@tonic-gate return (TRUE); 970Sstevel@tonic-gate }else 980Sstevel@tonic-gate return (FALSE); 990Sstevel@tonic-gate } 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate struct tempblk *tmpfptr; 1020Sstevel@tonic-gate 103*527Schin void 104*527Schin pushtemp(int fd, struct tempblk *tb) 1050Sstevel@tonic-gate { 1060Sstevel@tonic-gate tb->fdes = fd; 1070Sstevel@tonic-gate tb->fstak = tmpfptr; 1080Sstevel@tonic-gate tmpfptr = tb; 1090Sstevel@tonic-gate } 1100Sstevel@tonic-gate 111*527Schin int 112*527Schin poptemp(void) 1130Sstevel@tonic-gate { 1140Sstevel@tonic-gate if (tmpfptr){ 1150Sstevel@tonic-gate close(tmpfptr->fdes); 1160Sstevel@tonic-gate tmpfptr = tmpfptr->fstak; 1170Sstevel@tonic-gate return (TRUE); 1180Sstevel@tonic-gate }else 1190Sstevel@tonic-gate return (FALSE); 1200Sstevel@tonic-gate } 1210Sstevel@tonic-gate 122*527Schin void 123*527Schin chkpipe(int *pv) 1240Sstevel@tonic-gate { 1250Sstevel@tonic-gate if (pipe(pv) < 0 || pv[INPIPE] < 0 || pv[OTPIPE] < 0) 1260Sstevel@tonic-gate error(piperr); 1270Sstevel@tonic-gate } 1280Sstevel@tonic-gate 129*527Schin int 130*527Schin chkopen(unsigned char *idf, int mode) 1310Sstevel@tonic-gate { 132*527Schin int rc; 1330Sstevel@tonic-gate 1340Sstevel@tonic-gate if ((rc = open((char *)idf, mode, 0666)) < 0) 1350Sstevel@tonic-gate failed(idf, badopen); 1360Sstevel@tonic-gate else 1370Sstevel@tonic-gate return (rc); 1380Sstevel@tonic-gate } 1390Sstevel@tonic-gate 1400Sstevel@tonic-gate /* 1410Sstevel@tonic-gate * Make f2 be a synonym (including the close-on-exec flag) for f1, which is 1420Sstevel@tonic-gate * then closed. If f2 is descriptor 0, modify the global ioset variable 1430Sstevel@tonic-gate * accordingly. 1440Sstevel@tonic-gate */ 145*527Schin void 146*527Schin renamef(int f1, int f2) 1470Sstevel@tonic-gate { 1480Sstevel@tonic-gate #ifdef RES 1490Sstevel@tonic-gate if (f1 != f2) 1500Sstevel@tonic-gate { 1510Sstevel@tonic-gate dup(f1 | DUPFLG, f2); 1520Sstevel@tonic-gate close(f1); 1530Sstevel@tonic-gate if (f2 == 0) 1540Sstevel@tonic-gate ioset |= 1; 1550Sstevel@tonic-gate } 1560Sstevel@tonic-gate #else 1570Sstevel@tonic-gate int fs; 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate if (f1 != f2) 1600Sstevel@tonic-gate { 1610Sstevel@tonic-gate fs = fcntl(f2, 1, 0); 1620Sstevel@tonic-gate close(f2); 1630Sstevel@tonic-gate fcntl(f1, 0, f2); 1640Sstevel@tonic-gate close(f1); 1650Sstevel@tonic-gate if (fs == 1) 1660Sstevel@tonic-gate fcntl(f2, 2, 1); 1670Sstevel@tonic-gate if (f2 == 0) 1680Sstevel@tonic-gate ioset |= 1; 1690Sstevel@tonic-gate } 1700Sstevel@tonic-gate #endif 1710Sstevel@tonic-gate } 1720Sstevel@tonic-gate 173*527Schin int 174*527Schin create(unsigned char *s) 1750Sstevel@tonic-gate { 176*527Schin int rc; 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate if ((rc = creat((char *)s, 0666)) < 0) 1790Sstevel@tonic-gate failed(s, badcreate); 1800Sstevel@tonic-gate else 1810Sstevel@tonic-gate return (rc); 1820Sstevel@tonic-gate } 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate 185*527Schin int 186*527Schin tmpfil(struct tempblk *tb) 1870Sstevel@tonic-gate { 1880Sstevel@tonic-gate int fd; 189*527Schin int len; 190*527Schin size_t size_left = TMPOUTSZ - tmpout_offset; 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate /* make sure tmp file does not already exist. */ 1930Sstevel@tonic-gate do { 194*527Schin len = snprintf((char *)&tmpout[tmpout_offset], size_left, 195*527Schin "%u", serial); 196*527Schin fd = open((char *)tmpout, O_RDWR|O_CREAT|O_EXCL, 0600); 197*527Schin serial++; 198*527Schin if ((serial >= UINT_MAX) || (len >= size_left)) { 199*527Schin /* 200*527Schin * We've already cycled through all the possible 201*527Schin * numbers or the tmp file name is being 202*527Schin * truncated anyway (although TMPOUTSZ should be 203*527Schin * big enough), so start over. 204*527Schin */ 205*527Schin serial = 0; 206*527Schin break; 207*527Schin } 2080Sstevel@tonic-gate } while ((fd == -1) && (errno == EEXIST)); 2090Sstevel@tonic-gate if (fd != -1) { 2100Sstevel@tonic-gate pushtemp(fd, tb); 2110Sstevel@tonic-gate return (fd); 2120Sstevel@tonic-gate } 2130Sstevel@tonic-gate else 2140Sstevel@tonic-gate failed(tmpout, badcreate); 2150Sstevel@tonic-gate } 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate /* 2180Sstevel@tonic-gate * set by trim 2190Sstevel@tonic-gate */ 2200Sstevel@tonic-gate extern BOOL nosubst; 2210Sstevel@tonic-gate #define CPYSIZ 512 2220Sstevel@tonic-gate 223*527Schin void 224*527Schin copy(struct ionod *ioparg) 2250Sstevel@tonic-gate { 226*527Schin unsigned char *cline; 227*527Schin unsigned char *clinep; 228*527Schin struct ionod *iop; 2290Sstevel@tonic-gate unsigned int c; 2300Sstevel@tonic-gate unsigned char *ends; 2310Sstevel@tonic-gate unsigned char *start; 2320Sstevel@tonic-gate int fd; 2330Sstevel@tonic-gate int i; 2340Sstevel@tonic-gate int stripflg; 2350Sstevel@tonic-gate unsigned char *pc; 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate if (iop = ioparg) 2390Sstevel@tonic-gate { 2400Sstevel@tonic-gate struct tempblk tb; 2410Sstevel@tonic-gate copy(iop->iolst); 2420Sstevel@tonic-gate ends = mactrim(iop->ioname); 2430Sstevel@tonic-gate stripflg = iop->iofile & IOSTRIP; 2440Sstevel@tonic-gate if (nosubst) 2450Sstevel@tonic-gate iop->iofile &= ~IODOC; 2460Sstevel@tonic-gate fd = tmpfil(&tb); 2470Sstevel@tonic-gate 2480Sstevel@tonic-gate if (fndef) 2490Sstevel@tonic-gate iop->ioname = (char *) make(tmpout); 2500Sstevel@tonic-gate else 2510Sstevel@tonic-gate iop->ioname = (char *) cpystak(tmpout); 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate iop->iolst = iotemp; 2540Sstevel@tonic-gate iotemp = iop; 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate cline = clinep = start = locstak(); 2570Sstevel@tonic-gate if (stripflg) 2580Sstevel@tonic-gate { 2590Sstevel@tonic-gate iop->iofile &= ~IOSTRIP; 2600Sstevel@tonic-gate while (*ends == '\t') 2610Sstevel@tonic-gate ends++; 2620Sstevel@tonic-gate } 2630Sstevel@tonic-gate for (;;) 2640Sstevel@tonic-gate { 2650Sstevel@tonic-gate chkpr(); 2660Sstevel@tonic-gate if (nosubst) 2670Sstevel@tonic-gate { 2680Sstevel@tonic-gate c = readwc(); 2690Sstevel@tonic-gate if (stripflg) 2700Sstevel@tonic-gate while (c == '\t') 2710Sstevel@tonic-gate c = readwc(); 2720Sstevel@tonic-gate 2730Sstevel@tonic-gate while (!eolchar(c)) 2740Sstevel@tonic-gate { 2750Sstevel@tonic-gate pc = readw(c); 2760Sstevel@tonic-gate while (*pc) { 2770Sstevel@tonic-gate if (clinep >= brkend) 2780Sstevel@tonic-gate growstak(clinep); 2790Sstevel@tonic-gate *clinep++ = *pc++; 2800Sstevel@tonic-gate } 2810Sstevel@tonic-gate c = readwc(); 2820Sstevel@tonic-gate } 2830Sstevel@tonic-gate }else{ 2840Sstevel@tonic-gate c = nextwc(); 2850Sstevel@tonic-gate if (stripflg) 2860Sstevel@tonic-gate while (c == '\t') 2870Sstevel@tonic-gate c = nextwc(); 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate while (!eolchar(c)) 2900Sstevel@tonic-gate { 2910Sstevel@tonic-gate pc = readw(c); 2920Sstevel@tonic-gate while (*pc) { 2930Sstevel@tonic-gate if (clinep >= brkend) 2940Sstevel@tonic-gate growstak(clinep); 2950Sstevel@tonic-gate *clinep++ = *pc++; 2960Sstevel@tonic-gate } 2970Sstevel@tonic-gate if (c == '\\') 2980Sstevel@tonic-gate { 2990Sstevel@tonic-gate pc = readw(readwc()); 3000Sstevel@tonic-gate /* *pc might be NULL */ 3010Sstevel@tonic-gate if (*pc) { 3020Sstevel@tonic-gate while (*pc) { 3030Sstevel@tonic-gate if (clinep >= brkend) 3040Sstevel@tonic-gate growstak(clinep); 3050Sstevel@tonic-gate *clinep++ = *pc++; 3060Sstevel@tonic-gate } 3070Sstevel@tonic-gate } else { 3080Sstevel@tonic-gate if (clinep >= brkend) 3090Sstevel@tonic-gate growstak(clinep); 3100Sstevel@tonic-gate *clinep++ = *pc; 3110Sstevel@tonic-gate } 3120Sstevel@tonic-gate } 3130Sstevel@tonic-gate c = nextwc(); 3140Sstevel@tonic-gate } 3150Sstevel@tonic-gate } 3160Sstevel@tonic-gate 3170Sstevel@tonic-gate if (clinep >= brkend) 3180Sstevel@tonic-gate growstak(clinep); 3190Sstevel@tonic-gate *clinep = 0; 3200Sstevel@tonic-gate if (eof || eq(cline, ends)) 3210Sstevel@tonic-gate { 3220Sstevel@tonic-gate if ((i = cline - start) > 0) 3230Sstevel@tonic-gate write(fd, start, i); 3240Sstevel@tonic-gate break; 3250Sstevel@tonic-gate }else{ 3260Sstevel@tonic-gate if (clinep >= brkend) 3270Sstevel@tonic-gate growstak(clinep); 3280Sstevel@tonic-gate *clinep++ = NL; 3290Sstevel@tonic-gate } 3300Sstevel@tonic-gate 3310Sstevel@tonic-gate if ((i = clinep - start) < CPYSIZ) 3320Sstevel@tonic-gate cline = clinep; 3330Sstevel@tonic-gate else 3340Sstevel@tonic-gate { 3350Sstevel@tonic-gate write(fd, start, i); 3360Sstevel@tonic-gate cline = clinep = start; 3370Sstevel@tonic-gate } 3380Sstevel@tonic-gate } 3390Sstevel@tonic-gate 3400Sstevel@tonic-gate poptemp(); /* 3410Sstevel@tonic-gate * pushed in tmpfil -- bug fix for problem 3420Sstevel@tonic-gate * deleting in-line scripts 3430Sstevel@tonic-gate */ 3440Sstevel@tonic-gate } 3450Sstevel@tonic-gate } 3460Sstevel@tonic-gate 347*527Schin void 348*527Schin link_iodocs(struct ionod *i) 3490Sstevel@tonic-gate { 3500Sstevel@tonic-gate int r; 351*527Schin int len; 352*527Schin size_t size_left = TMPOUTSZ - tmpout_offset; 3530Sstevel@tonic-gate 354*527Schin while (i) { 3550Sstevel@tonic-gate free(i->iolink); 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate /* make sure tmp file does not already exist. */ 3580Sstevel@tonic-gate do { 359*527Schin len = snprintf((char *)&tmpout[tmpout_offset], 360*527Schin size_left, "%u", serial); 361*527Schin serial++; 3620Sstevel@tonic-gate r = link(i->ioname, (char *)tmpout); 363*527Schin if ((serial >= UINT_MAX) || (len >= size_left)) { 364*527Schin /* 365*527Schin * We've already cycled through all the possible 366*527Schin * numbers or the tmp file name is being 367*527Schin * truncated anyway, so start over. 368*527Schin */ 369*527Schin serial = 0; 370*527Schin break; 371*527Schin } 3720Sstevel@tonic-gate } while (r == -1 && errno == EEXIST); 3730Sstevel@tonic-gate 3740Sstevel@tonic-gate if (r != -1) { 3750Sstevel@tonic-gate i->iolink = (char *)make(tmpout); 3760Sstevel@tonic-gate i = i->iolst; 3770Sstevel@tonic-gate } else 3780Sstevel@tonic-gate failed(tmpout, badcreate); 3790Sstevel@tonic-gate 3800Sstevel@tonic-gate } 3810Sstevel@tonic-gate } 3820Sstevel@tonic-gate 383*527Schin void 384*527Schin swap_iodoc_nm(struct ionod *i) 3850Sstevel@tonic-gate { 3860Sstevel@tonic-gate while (i) 3870Sstevel@tonic-gate { 3880Sstevel@tonic-gate free(i->ioname); 3890Sstevel@tonic-gate i->ioname = i->iolink; 3900Sstevel@tonic-gate i->iolink = 0; 3910Sstevel@tonic-gate 3920Sstevel@tonic-gate i = i->iolst; 3930Sstevel@tonic-gate } 3940Sstevel@tonic-gate } 3950Sstevel@tonic-gate 396*527Schin int 397*527Schin savefd(int fd) 3980Sstevel@tonic-gate { 399*527Schin int f; 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate f = fcntl(fd, F_DUPFD, 10); 4020Sstevel@tonic-gate return (f); 4030Sstevel@tonic-gate } 4040Sstevel@tonic-gate 405*527Schin void 406*527Schin restore(int last) 4070Sstevel@tonic-gate { 408*527Schin int i; 409*527Schin int dupfd; 4100Sstevel@tonic-gate 4110Sstevel@tonic-gate for (i = topfd - 1; i >= last; i--) 4120Sstevel@tonic-gate { 4130Sstevel@tonic-gate if ((dupfd = fdmap[i].dup_fd) > 0) 4140Sstevel@tonic-gate renamef(dupfd, fdmap[i].org_fd); 4150Sstevel@tonic-gate else 4160Sstevel@tonic-gate close(fdmap[i].org_fd); 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate topfd = last; 4190Sstevel@tonic-gate } 420