Home | History | Annotate | Download | only in sh
      1     0   stevel /*
      2     0   stevel  * CDDL HEADER START
      3     0   stevel  *
      4     0   stevel  * The contents of this file are subject to the terms of the
      5  5976  nakanon  * Common Development and Distribution License (the "License").
      6  5976  nakanon  * You may not use this file except in compliance with the License.
      7     0   stevel  *
      8     0   stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0   stevel  * or http://www.opensolaris.org/os/licensing.
     10     0   stevel  * See the License for the specific language governing permissions
     11     0   stevel  * and limitations under the License.
     12     0   stevel  *
     13     0   stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0   stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0   stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0   stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0   stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0   stevel  *
     19     0   stevel  * CDDL HEADER END
     20     0   stevel  */
     21   527     chin 
     22   527     chin /*
     23  5976  nakanon  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24   527     chin  * Use is subject to license terms.
     25   527     chin  */
     26   527     chin 
     27     0   stevel /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     28     0   stevel /*	  All Rights Reserved  	*/
     29     0   stevel 
     30     0   stevel /*
     31     0   stevel  * UNIX shell
     32     0   stevel  */
     33     0   stevel 
     34     0   stevel #include	"defs.h"
     35     0   stevel #include	"dup.h"
     36   527     chin #include	<stdio.h>
     37     0   stevel #include	<fcntl.h>
     38     0   stevel #include	<sys/types.h>
     39     0   stevel #include	<sys/stat.h>
     40     0   stevel #include	<errno.h>
     41     0   stevel 
     42     0   stevel short topfd;
     43     0   stevel 
     44     0   stevel /* ========	input output and file copying ======== */
     45     0   stevel 
     46   527     chin void
     47   527     chin initf(int fd)
     48     0   stevel {
     49   527     chin 	struct fileblk *f = standin;
     50     0   stevel 
     51     0   stevel 	f->fdes = fd;
     52     0   stevel 	f->fsiz = ((flags & oneflg) == 0 ? BUFFERSIZE : 1);
     53     0   stevel 	f->fnxt = f->fend = f->fbuf;
     54     0   stevel 	f->nxtoff = f->endoff = 0;
     55     0   stevel 	f->feval = 0;
     56     0   stevel 	f->flin = 1;
     57     0   stevel 	f->feof = FALSE;
     58     0   stevel }
     59     0   stevel 
     60   527     chin int
     61   527     chin estabf(unsigned char *s)
     62     0   stevel {
     63   527     chin 	struct fileblk *f;
     64     0   stevel 
     65     0   stevel 	(f = standin)->fdes = -1;
     66     0   stevel 	f->fend = length(s) + (f->fnxt = s);
     67     0   stevel 	f->nxtoff = 0;
     68     0   stevel 	f->endoff = length(s);
     69     0   stevel 	f->flin = 1;
     70     0   stevel 	return (f->feof = (s == 0));
     71     0   stevel }
     72     0   stevel 
     73   527     chin void
     74   527     chin push(struct fileblk *af)
     75     0   stevel {
     76   527     chin 	struct fileblk *f;
     77     0   stevel 
     78     0   stevel 	(f = af)->fstak = standin;
     79     0   stevel 	f->feof = 0;
     80     0   stevel 	f->feval = 0;
     81     0   stevel 	standin = f;
     82     0   stevel }
     83     0   stevel 
     84   527     chin int
     85   527     chin pop(void)
     86     0   stevel {
     87   527     chin 	struct fileblk *f;
     88     0   stevel 
     89  7641  William 	if ((f = standin)->fstak) {
     90     0   stevel 		if (f->fdes >= 0)
     91     0   stevel 			close(f->fdes);
     92     0   stevel 		standin = f->fstak;
     93     0   stevel 		return (TRUE);
     94  7641  William 	} else
     95     0   stevel 		return (FALSE);
     96     0   stevel }
     97     0   stevel 
     98     0   stevel struct tempblk *tmpfptr;
     99     0   stevel 
    100   527     chin void
    101   527     chin pushtemp(int fd, struct tempblk *tb)
    102     0   stevel {
    103     0   stevel 	tb->fdes = fd;
    104     0   stevel 	tb->fstak = tmpfptr;
    105     0   stevel 	tmpfptr = tb;
    106     0   stevel }
    107     0   stevel 
    108   527     chin int
    109   527     chin poptemp(void)
    110     0   stevel {
    111  7641  William 	if (tmpfptr) {
    112     0   stevel 		close(tmpfptr->fdes);
    113     0   stevel 		tmpfptr = tmpfptr->fstak;
    114     0   stevel 		return (TRUE);
    115  7641  William 	} else
    116     0   stevel 		return (FALSE);
    117     0   stevel }
    118     0   stevel 
    119   527     chin void
    120   527     chin chkpipe(int *pv)
    121     0   stevel {
    122     0   stevel 	if (pipe(pv) < 0 || pv[INPIPE] < 0 || pv[OTPIPE] < 0)
    123     0   stevel 		error(piperr);
    124     0   stevel }
    125     0   stevel 
    126   527     chin int
    127   527     chin chkopen(unsigned char *idf, int mode)
    128     0   stevel {
    129   527     chin 	int	rc;
    130     0   stevel 
    131     0   stevel 	if ((rc = open((char *)idf, mode, 0666)) < 0)
    132     0   stevel 		failed(idf, badopen);
    133     0   stevel 	else
    134     0   stevel 		return (rc);
    135     0   stevel }
    136     0   stevel 
    137     0   stevel /*
    138     0   stevel  * Make f2 be a synonym (including the close-on-exec flag) for f1, which is
    139     0   stevel  * then closed.  If f2 is descriptor 0, modify the global ioset variable
    140     0   stevel  * accordingly.
    141     0   stevel  */
    142   527     chin void
    143   527     chin renamef(int f1, int f2)
    144     0   stevel {
    145     0   stevel #ifdef RES
    146  7641  William 	if (f1 != f2) {
    147     0   stevel 		dup(f1 | DUPFLG, f2);
    148     0   stevel 		close(f1);
    149     0   stevel 		if (f2 == 0)
    150     0   stevel 			ioset |= 1;
    151     0   stevel 	}
    152     0   stevel #else
    153     0   stevel 	int	fs;
    154     0   stevel 
    155  7641  William 	if (f1 != f2) {
    156     0   stevel 		fs = fcntl(f2, 1, 0);
    157     0   stevel 		close(f2);
    158     0   stevel 		fcntl(f1, 0, f2);
    159     0   stevel 		close(f1);
    160     0   stevel 		if (fs == 1)
    161     0   stevel 			fcntl(f2, 2, 1);
    162     0   stevel 		if (f2 == 0)
    163     0   stevel 			ioset |= 1;
    164     0   stevel 	}
    165     0   stevel #endif
    166     0   stevel }
    167     0   stevel 
    168   527     chin int
    169   527     chin create(unsigned char *s)
    170     0   stevel {
    171   527     chin 	int	rc;
    172     0   stevel 
    173     0   stevel 	if ((rc = creat((char *)s, 0666)) < 0)
    174     0   stevel 		failed(s, badcreate);
    175     0   stevel 	else
    176     0   stevel 		return (rc);
    177     0   stevel }
    178     0   stevel 
    179     0   stevel 
    180   527     chin int
    181   527     chin tmpfil(struct tempblk *tb)
    182     0   stevel {
    183     0   stevel 	int fd;
    184   527     chin 	int len;
    185   527     chin 	size_t size_left = TMPOUTSZ - tmpout_offset;
    186     0   stevel 
    187     0   stevel 	/* make sure tmp file does not already exist. */
    188     0   stevel 	do {
    189   527     chin 		len = snprintf((char *)&tmpout[tmpout_offset], size_left,
    190   527     chin 		    "%u", serial);
    191   527     chin 		fd = open((char *)tmpout, O_RDWR|O_CREAT|O_EXCL, 0600);
    192   527     chin 		serial++;
    193   527     chin 		if ((serial >= UINT_MAX) || (len >= size_left)) {
    194   527     chin 			/*
    195   527     chin 			 * We've already cycled through all the possible
    196   527     chin 			 * numbers or the tmp file name is being
    197   527     chin 			 * truncated anyway (although TMPOUTSZ should be
    198   527     chin 			 * big enough), so start over.
    199   527     chin 			 */
    200   527     chin 			serial = 0;
    201   527     chin 			break;
    202   527     chin 		}
    203     0   stevel 	} while ((fd == -1) && (errno == EEXIST));
    204     0   stevel 	if (fd != -1) {
    205     0   stevel 		pushtemp(fd, tb);
    206     0   stevel 		return (fd);
    207     0   stevel 	}
    208     0   stevel 	else
    209     0   stevel 		failed(tmpout, badcreate);
    210     0   stevel }
    211     0   stevel 
    212     0   stevel /*
    213     0   stevel  * set by trim
    214     0   stevel  */
    215     0   stevel extern BOOL		nosubst;
    216     0   stevel #define			CPYSIZ		512
    217     0   stevel 
    218   527     chin void
    219   527     chin copy(struct ionod	*ioparg)
    220     0   stevel {
    221   527     chin 	unsigned char	*cline;
    222   527     chin 	unsigned char	*clinep;
    223   527     chin 	struct ionod	*iop;
    224     0   stevel 	unsigned int	c;
    225     0   stevel 	unsigned char	*ends;
    226     0   stevel 	unsigned char	*start;
    227     0   stevel 	int		fd;
    228     0   stevel 	int		i;
    229     0   stevel 	int		stripflg;
    230     0   stevel 	unsigned char	*pc;
    231     0   stevel 
    232     0   stevel 
    233  7641  William 	if (iop = ioparg) {
    234     0   stevel 		struct tempblk tb;
    235     0   stevel 		copy(iop->iolst);
    236     0   stevel 		ends = mactrim(iop->ioname);
    237     0   stevel 		stripflg = iop->iofile & IOSTRIP;
    238     0   stevel 		if (nosubst)
    239  5976  nakanon 			iop->iofile &= ~IODOC_SUBST;
    240     0   stevel 		fd = tmpfil(&tb);
    241     0   stevel 
    242     0   stevel 		if (fndef)
    243  7641  William 			iop->ioname = (char *)make(tmpout);
    244     0   stevel 		else
    245  7641  William 			iop->ioname = (char *)cpystak(tmpout);
    246     0   stevel 
    247     0   stevel 		iop->iolst = iotemp;
    248     0   stevel 		iotemp = iop;
    249     0   stevel 
    250     0   stevel 		cline = clinep = start = locstak();
    251  7641  William 		if (stripflg) {
    252     0   stevel 			iop->iofile &= ~IOSTRIP;
    253     0   stevel 			while (*ends == '\t')
    254     0   stevel 				ends++;
    255     0   stevel 		}
    256  7641  William 		for (;;) {
    257     0   stevel 			chkpr();
    258  7641  William 			if (nosubst) {
    259     0   stevel 				c = readwc();
    260     0   stevel 				if (stripflg)
    261     0   stevel 					while (c == '\t')
    262     0   stevel 						c = readwc();
    263     0   stevel 
    264  7641  William 				while (!eolchar(c)) {
    265     0   stevel 					pc = readw(c);
    266     0   stevel 					while (*pc) {
    267     0   stevel 						if (clinep >= brkend)
    268     0   stevel 							growstak(clinep);
    269     0   stevel 						*clinep++ = *pc++;
    270     0   stevel 					}
    271     0   stevel 					c = readwc();
    272     0   stevel 				}
    273  7641  William 			} else {
    274     0   stevel 				c = nextwc();
    275     0   stevel 				if (stripflg)
    276     0   stevel 					while (c == '\t')
    277     0   stevel 						c = nextwc();
    278     0   stevel 
    279  7641  William 				while (!eolchar(c)) {
    280     0   stevel 					pc = readw(c);
    281     0   stevel 					while (*pc) {
    282     0   stevel 						if (clinep >= brkend)
    283     0   stevel 							growstak(clinep);
    284     0   stevel 						*clinep++ = *pc++;
    285     0   stevel 					}
    286  7641  William 					if (c == '\\') {
    287     0   stevel 						pc = readw(readwc());
    288     0   stevel 						/* *pc might be NULL */
    289  7641  William 						/* BEGIN CSTYLED */
    290     0   stevel 						if (*pc) {
    291     0   stevel 							while (*pc) {
    292     0   stevel 								if (clinep >= brkend)
    293     0   stevel 									growstak(clinep);
    294     0   stevel 								*clinep++ = *pc++;
    295     0   stevel 							}
    296     0   stevel 						} else {
    297     0   stevel 							if (clinep >= brkend)
    298     0   stevel 								growstak(clinep);
    299     0   stevel 							*clinep++ = *pc;
    300     0   stevel 						}
    301  7641  William 						/* END CSTYLED */
    302     0   stevel 					}
    303     0   stevel 					c = nextwc();
    304     0   stevel 				}
    305     0   stevel 			}
    306     0   stevel 
    307     0   stevel 			if (clinep >= brkend)
    308     0   stevel 				growstak(clinep);
    309     0   stevel 			*clinep = 0;
    310  7641  William 			if (eof || eq(cline, ends)) {
    311     0   stevel 				if ((i = cline - start) > 0)
    312     0   stevel 					write(fd, start, i);
    313     0   stevel 				break;
    314  7641  William 			} else {
    315     0   stevel 				if (clinep >= brkend)
    316     0   stevel 					growstak(clinep);
    317     0   stevel 				*clinep++ = NL;
    318     0   stevel 			}
    319     0   stevel 
    320     0   stevel 			if ((i = clinep - start) < CPYSIZ)
    321     0   stevel 				cline = clinep;
    322     0   stevel 			else
    323     0   stevel 			{
    324     0   stevel 				write(fd, start, i);
    325     0   stevel 				cline = clinep = start;
    326     0   stevel 			}
    327     0   stevel 		}
    328     0   stevel 
    329  7641  William 		/*
    330  7641  William 		 * Pushed in tmpfil -- bug fix for problem
    331  7641  William 		 * deleting in-line script.
    332  7641  William 		 */
    333  7641  William 		poptemp();
    334     0   stevel 	}
    335     0   stevel }
    336     0   stevel 
    337   527     chin void
    338   527     chin link_iodocs(struct ionod *i)
    339     0   stevel {
    340     0   stevel 	int r;
    341   527     chin 	int len;
    342   527     chin 	size_t size_left = TMPOUTSZ - tmpout_offset;
    343     0   stevel 
    344   527     chin 	while (i) {
    345     0   stevel 		free(i->iolink);
    346     0   stevel 
    347     0   stevel 		/* make sure tmp file does not already exist. */
    348     0   stevel 		do {
    349   527     chin 			len = snprintf((char *)&tmpout[tmpout_offset],
    350   527     chin 			    size_left, "%u", serial);
    351   527     chin 			serial++;
    352     0   stevel 			r = link(i->ioname, (char *)tmpout);
    353   527     chin 			if ((serial >= UINT_MAX) || (len >= size_left)) {
    354   527     chin 			/*
    355   527     chin 			 * We've already cycled through all the possible
    356   527     chin 			 * numbers or the tmp file name is being
    357  7641  William 			 * truncated anyway, so start over.
    358   527     chin 			 */
    359   527     chin 				serial = 0;
    360   527     chin 				break;
    361   527     chin 			}
    362     0   stevel 		} while (r == -1 && errno == EEXIST);
    363     0   stevel 
    364     0   stevel 		if (r != -1) {
    365     0   stevel 			i->iolink = (char *)make(tmpout);
    366     0   stevel 			i = i->iolst;
    367     0   stevel 		} else
    368     0   stevel 			failed(tmpout, badcreate);
    369     0   stevel 
    370     0   stevel 	}
    371     0   stevel }
    372     0   stevel 
    373   527     chin void
    374   527     chin swap_iodoc_nm(struct ionod *i)
    375     0   stevel {
    376  7641  William 	while (i) {
    377     0   stevel 		free(i->ioname);
    378     0   stevel 		i->ioname = i->iolink;
    379     0   stevel 		i->iolink = 0;
    380     0   stevel 
    381     0   stevel 		i = i->iolst;
    382     0   stevel 	}
    383     0   stevel }
    384     0   stevel 
    385   527     chin int
    386   527     chin savefd(int fd)
    387     0   stevel {
    388   527     chin 	int	f;
    389     0   stevel 
    390     0   stevel 	f = fcntl(fd, F_DUPFD, 10);
    391  7641  William 	/* this saved fd should not be found in an exec'ed cmd */
    392  7641  William 	(void) fcntl(f, F_SETFD, FD_CLOEXEC);
    393     0   stevel 	return (f);
    394     0   stevel }
    395     0   stevel 
    396   527     chin void
    397   527     chin restore(int last)
    398     0   stevel {
    399   527     chin 	int 	i;
    400   527     chin 	int	dupfd;
    401     0   stevel 
    402  7641  William 	for (i = topfd - 1; i >= last; i--) {
    403     0   stevel 		if ((dupfd = fdmap[i].dup_fd) > 0)
    404     0   stevel 			renamef(dupfd, fdmap[i].org_fd);
    405     0   stevel 		else
    406     0   stevel 			close(fdmap[i].org_fd);
    407     0   stevel 	}
    408     0   stevel 	topfd = last;
    409     0   stevel }
    410