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