1 /* 2 * Copyright (c) 1983 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 static char sccsid[] = "@(#)cmds.c 5.15 (Berkeley) 3/4/91"; 36 #endif /* not lint */ 37 38 #include "tip.h" 39 #include "pathnames.h" 40 41 /* 42 * tip 43 * 44 * miscellaneous commands 45 */ 46 47 int quant[] = { 60, 60, 24 }; 48 49 char null = '\0'; 50 char *sep[] = { "second", "minute", "hour" }; 51 static char *argv[10]; /* argument vector for take and put */ 52 53 void timeout(); /* timeout function called on alarm */ 54 void stopsnd(); /* SIGINT handler during file transfers */ 55 void intcopy(); /* interrupt routine for file transfers */ 56 57 /* 58 * FTP - remote ==> local 59 * get a file from the remote host 60 */ 61 getfl(c) 62 char c; 63 { 64 char buf[256], *cp, *expand(); 65 66 putchar(c); 67 /* 68 * get the UNIX receiving file's name 69 */ 70 if (prompt("Local file name? ", copyname)) 71 return; 72 cp = expand(copyname); 73 if ((sfd = creat(cp, 0666)) < 0) { 74 printf("\r\n%s: cannot creat\r\n", copyname); 75 return; 76 } 77 78 /* 79 * collect parameters 80 */ 81 if (prompt("List command for remote system? ", buf)) { 82 unlink(copyname); 83 return; 84 } 85 transfer(buf, sfd, value(EOFREAD)); 86 } 87 88 /* 89 * Cu-like take command 90 */ 91 cu_take(cc) 92 char cc; 93 { 94 int fd, argc; 95 char line[BUFSIZ], *expand(), *cp; 96 97 if (prompt("[take] ", copyname)) 98 return; 99 if ((argc = args(copyname, argv)) < 1 || argc > 2) { 100 printf("usage: <take> from [to]\r\n"); 101 return; 102 } 103 if (argc == 1) 104 argv[1] = argv[0]; 105 cp = expand(argv[1]); 106 if ((fd = creat(cp, 0666)) < 0) { 107 printf("\r\n%s: cannot create\r\n", argv[1]); 108 return; 109 } 110 sprintf(line, "cat %s;echo \01", argv[0]); 111 transfer(line, fd, "\01"); 112 } 113 114 static jmp_buf intbuf; 115 /* 116 * Bulk transfer routine -- 117 * used by getfl(), cu_take(), and pipefile() 118 */ 119 transfer(buf, fd, eofchars) 120 char *buf, *eofchars; 121 { 122 register int ct; 123 char c, buffer[BUFSIZ]; 124 register char *p = buffer; 125 register int cnt, eof; 126 time_t start; 127 sig_t f; 128 129 pwrite(FD, buf, size(buf)); 130 quit = 0; 131 kill(pid, SIGIOT); 132 read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ 133 134 /* 135 * finish command 136 */ 137 pwrite(FD, "\r", 1); 138 do 139 read(FD, &c, 1); 140 while ((c&0177) != '\n'); 141 ioctl(0, TIOCSETC, &defchars); 142 143 (void) setjmp(intbuf); 144 f = signal(SIGINT, intcopy); 145 start = time(0); 146 for (ct = 0; !quit;) { 147 eof = read(FD, &c, 1) <= 0; 148 c &= 0177; 149 if (quit) 150 continue; 151 if (eof || any(c, eofchars)) 152 break; 153 if (c == 0) 154 continue; /* ignore nulls */ 155 if (c == '\r') 156 continue; 157 *p++ = c; 158 159 if (c == '\n' && boolean(value(VERBOSE))) 160 printf("\r%d", ++ct); 161 if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) { 162 if (write(fd, buffer, cnt) != cnt) { 163 printf("\r\nwrite error\r\n"); 164 quit = 1; 165 } 166 p = buffer; 167 } 168 } 169 if (cnt = (p-buffer)) 170 if (write(fd, buffer, cnt) != cnt) 171 printf("\r\nwrite error\r\n"); 172 173 if (boolean(value(VERBOSE))) 174 prtime(" lines transferred in ", time(0)-start); 175 ioctl(0, TIOCSETC, &tchars); 176 write(fildes[1], (char *)&ccc, 1); 177 signal(SIGINT, f); 178 close(fd); 179 } 180 181 /* 182 * FTP - remote ==> local process 183 * send remote input to local process via pipe 184 */ 185 pipefile() 186 { 187 int cpid, pdes[2]; 188 char buf[256]; 189 int status, p; 190 extern int errno; 191 192 if (prompt("Local command? ", buf)) 193 return; 194 195 if (pipe(pdes)) { 196 printf("can't establish pipe\r\n"); 197 return; 198 } 199 200 if ((cpid = fork()) < 0) { 201 printf("can't fork!\r\n"); 202 return; 203 } else if (cpid) { 204 if (prompt("List command for remote system? ", buf)) { 205 close(pdes[0]), close(pdes[1]); 206 kill (cpid, SIGKILL); 207 } else { 208 close(pdes[0]); 209 signal(SIGPIPE, intcopy); 210 transfer(buf, pdes[1], value(EOFREAD)); 211 signal(SIGPIPE, SIG_DFL); 212 while ((p = wait(&status)) > 0 && p != cpid) 213 ; 214 } 215 } else { 216 register int f; 217 218 dup2(pdes[0], 0); 219 close(pdes[0]); 220 for (f = 3; f < 20; f++) 221 close(f); 222 execute(buf); 223 printf("can't execl!\r\n"); 224 exit(0); 225 } 226 } 227 228 /* 229 * Interrupt service routine for FTP 230 */ 231 void 232 stopsnd() 233 { 234 235 stop = 1; 236 signal(SIGINT, SIG_IGN); 237 } 238 239 /* 240 * FTP - local ==> remote 241 * send local file to remote host 242 * terminate transmission with pseudo EOF sequence 243 */ 244 sendfile(cc) 245 char cc; 246 { 247 FILE *fd; 248 char *fnamex; 249 char *expand(); 250 251 putchar(cc); 252 /* 253 * get file name 254 */ 255 if (prompt("Local file name? ", fname)) 256 return; 257 258 /* 259 * look up file 260 */ 261 fnamex = expand(fname); 262 if ((fd = fopen(fnamex, "r")) == NULL) { 263 printf("%s: cannot open\r\n", fname); 264 return; 265 } 266 transmit(fd, value(EOFWRITE), NULL); 267 if (!boolean(value(ECHOCHECK))) { 268 struct sgttyb buf; 269 270 ioctl(FD, TIOCGETP, &buf); /* this does a */ 271 ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 272 } 273 } 274 275 /* 276 * Bulk transfer routine to remote host -- 277 * used by sendfile() and cu_put() 278 */ 279 transmit(fd, eofchars, command) 280 FILE *fd; 281 char *eofchars, *command; 282 { 283 char *pc, lastc; 284 int c, ccount, lcount; 285 time_t start_t, stop_t; 286 sig_t f; 287 288 kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 289 stop = 0; 290 f = signal(SIGINT, stopsnd); 291 ioctl(0, TIOCSETC, &defchars); 292 read(repdes[0], (char *)&ccc, 1); 293 if (command != NULL) { 294 for (pc = command; *pc; pc++) 295 send(*pc); 296 if (boolean(value(ECHOCHECK))) 297 read(FD, (char *)&c, 1); /* trailing \n */ 298 else { 299 struct sgttyb buf; 300 301 ioctl(FD, TIOCGETP, &buf); /* this does a */ 302 ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 303 sleep(5); /* wait for remote stty to take effect */ 304 } 305 } 306 lcount = 0; 307 lastc = '\0'; 308 start_t = time(0); 309 while (1) { 310 ccount = 0; 311 do { 312 c = getc(fd); 313 if (stop) 314 goto out; 315 if (c == EOF) 316 goto out; 317 if (c == 0177 && !boolean(value(RAWFTP))) 318 continue; 319 lastc = c; 320 if (c < 040) { 321 if (c == '\n') { 322 if (!boolean(value(RAWFTP))) 323 c = '\r'; 324 } 325 else if (c == '\t') { 326 if (!boolean(value(RAWFTP))) { 327 if (boolean(value(TABEXPAND))) { 328 send(' '); 329 while ((++ccount % 8) != 0) 330 send(' '); 331 continue; 332 } 333 } 334 } else 335 if (!boolean(value(RAWFTP))) 336 continue; 337 } 338 send(c); 339 } while (c != '\r' && !boolean(value(RAWFTP))); 340 if (boolean(value(VERBOSE))) 341 printf("\r%d", ++lcount); 342 if (boolean(value(ECHOCHECK))) { 343 timedout = 0; 344 alarm((int)value(ETIMEOUT)); 345 do { /* wait for prompt */ 346 read(FD, (char *)&c, 1); 347 if (timedout || stop) { 348 if (timedout) 349 printf("\r\ntimed out at eol\r\n"); 350 alarm(0); 351 goto out; 352 } 353 } while ((c&0177) != character(value(PROMPT))); 354 alarm(0); 355 } 356 } 357 out: 358 if (lastc != '\n' && !boolean(value(RAWFTP))) 359 send('\r'); 360 for (pc = eofchars; *pc; pc++) 361 send(*pc); 362 stop_t = time(0); 363 fclose(fd); 364 signal(SIGINT, f); 365 if (boolean(value(VERBOSE))) 366 if (boolean(value(RAWFTP))) 367 prtime(" chars transferred in ", stop_t-start_t); 368 else 369 prtime(" lines transferred in ", stop_t-start_t); 370 write(fildes[1], (char *)&ccc, 1); 371 ioctl(0, TIOCSETC, &tchars); 372 } 373 374 /* 375 * Cu-like put command 376 */ 377 cu_put(cc) 378 char cc; 379 { 380 FILE *fd; 381 char line[BUFSIZ]; 382 int argc; 383 char *expand(); 384 char *copynamex; 385 386 if (prompt("[put] ", copyname)) 387 return; 388 if ((argc = args(copyname, argv)) < 1 || argc > 2) { 389 printf("usage: <put> from [to]\r\n"); 390 return; 391 } 392 if (argc == 1) 393 argv[1] = argv[0]; 394 copynamex = expand(argv[0]); 395 if ((fd = fopen(copynamex, "r")) == NULL) { 396 printf("%s: cannot open\r\n", copynamex); 397 return; 398 } 399 if (boolean(value(ECHOCHECK))) 400 sprintf(line, "cat>%s\r", argv[1]); 401 else 402 sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); 403 transmit(fd, "\04", line); 404 } 405 406 /* 407 * FTP - send single character 408 * wait for echo & handle timeout 409 */ 410 send(c) 411 char c; 412 { 413 char cc; 414 int retry = 0; 415 416 cc = c; 417 pwrite(FD, &cc, 1); 418 #ifdef notdef 419 if (number(value(CDELAY)) > 0 && c != '\r') 420 nap(number(value(CDELAY))); 421 #endif 422 if (!boolean(value(ECHOCHECK))) { 423 #ifdef notdef 424 if (number(value(LDELAY)) > 0 && c == '\r') 425 nap(number(value(LDELAY))); 426 #endif 427 return; 428 } 429 tryagain: 430 timedout = 0; 431 alarm((int)value(ETIMEOUT)); 432 read(FD, &cc, 1); 433 alarm(0); 434 if (timedout) { 435 printf("\r\ntimeout error (%s)\r\n", ctrl(c)); 436 if (retry++ > 3) 437 return; 438 pwrite(FD, &null, 1); /* poke it */ 439 goto tryagain; 440 } 441 } 442 443 void 444 timeout() 445 { 446 signal(SIGALRM, timeout); 447 timedout = 1; 448 } 449 450 /* 451 * Stolen from consh() -- puts a remote file on the output of a local command. 452 * Identical to consh() except for where stdout goes. 453 */ 454 pipeout(c) 455 { 456 char buf[256]; 457 int cpid, status, p; 458 time_t start; 459 460 putchar(c); 461 if (prompt("Local command? ", buf)) 462 return; 463 kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 464 signal(SIGINT, SIG_IGN); 465 signal(SIGQUIT, SIG_IGN); 466 ioctl(0, TIOCSETC, &defchars); 467 read(repdes[0], (char *)&ccc, 1); 468 /* 469 * Set up file descriptors in the child and 470 * let it go... 471 */ 472 if ((cpid = fork()) < 0) 473 printf("can't fork!\r\n"); 474 else if (cpid) { 475 start = time(0); 476 while ((p = wait(&status)) > 0 && p != cpid) 477 ; 478 } else { 479 register int i; 480 481 dup2(FD, 1); 482 for (i = 3; i < 20; i++) 483 close(i); 484 signal(SIGINT, SIG_DFL); 485 signal(SIGQUIT, SIG_DFL); 486 execute(buf); 487 printf("can't find `%s'\r\n", buf); 488 exit(0); 489 } 490 if (boolean(value(VERBOSE))) 491 prtime("away for ", time(0)-start); 492 write(fildes[1], (char *)&ccc, 1); 493 ioctl(0, TIOCSETC, &tchars); 494 signal(SIGINT, SIG_DFL); 495 signal(SIGQUIT, SIG_DFL); 496 } 497 498 #ifdef CONNECT 499 /* 500 * Fork a program with: 501 * 0 <-> remote tty in 502 * 1 <-> remote tty out 503 * 2 <-> local tty out 504 */ 505 consh(c) 506 { 507 char buf[256]; 508 int cpid, status, p; 509 time_t start; 510 511 putchar(c); 512 if (prompt("Local command? ", buf)) 513 return; 514 kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 515 signal(SIGINT, SIG_IGN); 516 signal(SIGQUIT, SIG_IGN); 517 ioctl(0, TIOCSETC, &defchars); 518 read(repdes[0], (char *)&ccc, 1); 519 /* 520 * Set up file descriptors in the child and 521 * let it go... 522 */ 523 if ((cpid = fork()) < 0) 524 printf("can't fork!\r\n"); 525 else if (cpid) { 526 start = time(0); 527 while ((p = wait(&status)) > 0 && p != cpid) 528 ; 529 } else { 530 register int i; 531 532 dup2(1, 2); 533 dup2(FD, 0); 534 dup2(0, 1); 535 for (i = 3; i < 20; i++) 536 close(i); 537 signal(SIGINT, SIG_DFL); 538 signal(SIGQUIT, SIG_DFL); 539 execute(buf); 540 printf("can't find `%s'\r\n", buf); 541 exit(0); 542 } 543 if (boolean(value(VERBOSE))) 544 prtime("away for ", time(0)-start); 545 write(fildes[1], (char *)&ccc, 1); 546 ioctl(0, TIOCSETC, &tchars); 547 signal(SIGINT, SIG_DFL); 548 signal(SIGQUIT, SIG_DFL); 549 } 550 #endif 551 552 /* 553 * Escape to local shell 554 */ 555 shell() 556 { 557 int shpid, status; 558 extern char **environ; 559 char *cp; 560 561 printf("[sh]\r\n"); 562 signal(SIGINT, SIG_IGN); 563 signal(SIGQUIT, SIG_IGN); 564 unraw(); 565 if (shpid = fork()) { 566 while (shpid != wait(&status)); 567 raw(); 568 printf("\r\n!\r\n"); 569 signal(SIGINT, SIG_DFL); 570 signal(SIGQUIT, SIG_DFL); 571 return; 572 } else { 573 signal(SIGQUIT, SIG_DFL); 574 signal(SIGINT, SIG_DFL); 575 if ((cp = rindex(value(SHELL), '/')) == NULL) 576 cp = value(SHELL); 577 else 578 cp++; 579 shell_uid(); 580 execl(value(SHELL), cp, 0); 581 printf("\r\ncan't execl!\r\n"); 582 exit(1); 583 } 584 } 585 586 /* 587 * TIPIN portion of scripting 588 * initiate the conversation with TIPOUT 589 */ 590 setscript() 591 { 592 char c; 593 /* 594 * enable TIPOUT side for dialogue 595 */ 596 kill(pid, SIGEMT); 597 if (boolean(value(SCRIPT))) 598 write(fildes[1], value(RECORD), size(value(RECORD))); 599 write(fildes[1], "\n", 1); 600 /* 601 * wait for TIPOUT to finish 602 */ 603 read(repdes[0], &c, 1); 604 if (c == 'n') 605 printf("can't create %s\r\n", value(RECORD)); 606 } 607 608 /* 609 * Change current working directory of 610 * local portion of tip 611 */ 612 chdirectory() 613 { 614 char dirname[80]; 615 register char *cp = dirname; 616 617 if (prompt("[cd] ", dirname)) { 618 if (stoprompt) 619 return; 620 cp = value(HOME); 621 } 622 if (chdir(cp) < 0) 623 printf("%s: bad directory\r\n", cp); 624 printf("!\r\n"); 625 } 626 627 tipabort(msg) 628 char *msg; 629 { 630 631 kill(pid, SIGTERM); 632 disconnect(msg); 633 if (msg != NOSTR) 634 printf("\r\n%s", msg); 635 printf("\r\n[EOT]\r\n"); 636 daemon_uid(); 637 (void)uu_unlock(uucplock); 638 unraw(); 639 exit(0); 640 } 641 642 finish() 643 { 644 char *dismsg; 645 646 if ((dismsg = value(DISCONNECT)) != NOSTR) { 647 write(FD, dismsg, strlen(dismsg)); 648 sleep(5); 649 } 650 tipabort(NOSTR); 651 } 652 653 void 654 intcopy() 655 { 656 raw(); 657 quit = 1; 658 longjmp(intbuf, 1); 659 } 660 661 execute(s) 662 char *s; 663 { 664 register char *cp; 665 666 if ((cp = rindex(value(SHELL), '/')) == NULL) 667 cp = value(SHELL); 668 else 669 cp++; 670 shell_uid(); 671 execl(value(SHELL), cp, "-c", s, 0); 672 } 673 674 args(buf, a) 675 char *buf, *a[]; 676 { 677 register char *p = buf, *start; 678 register char **parg = a; 679 register int n = 0; 680 681 do { 682 while (*p && (*p == ' ' || *p == '\t')) 683 p++; 684 start = p; 685 if (*p) 686 *parg = p; 687 while (*p && (*p != ' ' && *p != '\t')) 688 p++; 689 if (p != start) 690 parg++, n++; 691 if (*p) 692 *p++ = '\0'; 693 } while (*p); 694 695 return(n); 696 } 697 698 prtime(s, a) 699 char *s; 700 time_t a; 701 { 702 register i; 703 int nums[3]; 704 705 for (i = 0; i < 3; i++) { 706 nums[i] = (int)(a % quant[i]); 707 a /= quant[i]; 708 } 709 printf("%s", s); 710 while (--i >= 0) 711 if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0) 712 printf("%d %s%c ", nums[i], sep[i], 713 nums[i] == 1 ? '\0' : 's'); 714 printf("\r\n!\r\n"); 715 } 716 717 variable() 718 { 719 char buf[256]; 720 721 if (prompt("[set] ", buf)) 722 return; 723 vlex(buf); 724 if (vtable[BEAUTIFY].v_access&CHANGED) { 725 vtable[BEAUTIFY].v_access &= ~CHANGED; 726 kill(pid, SIGSYS); 727 } 728 if (vtable[SCRIPT].v_access&CHANGED) { 729 vtable[SCRIPT].v_access &= ~CHANGED; 730 setscript(); 731 /* 732 * So that "set record=blah script" doesn't 733 * cause two transactions to occur. 734 */ 735 if (vtable[RECORD].v_access&CHANGED) 736 vtable[RECORD].v_access &= ~CHANGED; 737 } 738 if (vtable[RECORD].v_access&CHANGED) { 739 vtable[RECORD].v_access &= ~CHANGED; 740 if (boolean(value(SCRIPT))) 741 setscript(); 742 } 743 if (vtable[TAND].v_access&CHANGED) { 744 vtable[TAND].v_access &= ~CHANGED; 745 if (boolean(value(TAND))) 746 tandem("on"); 747 else 748 tandem("off"); 749 } 750 if (vtable[LECHO].v_access&CHANGED) { 751 vtable[LECHO].v_access &= ~CHANGED; 752 HD = boolean(value(LECHO)); 753 } 754 if (vtable[PARITY].v_access&CHANGED) { 755 vtable[PARITY].v_access &= ~CHANGED; 756 setparity(); 757 } 758 } 759 760 /* 761 * Turn tandem mode on or off for remote tty. 762 */ 763 tandem(option) 764 char *option; 765 { 766 struct sgttyb rmtty; 767 768 ioctl(FD, TIOCGETP, &rmtty); 769 if (strcmp(option,"on") == 0) { 770 rmtty.sg_flags |= TANDEM; 771 arg.sg_flags |= TANDEM; 772 } else { 773 rmtty.sg_flags &= ~TANDEM; 774 arg.sg_flags &= ~TANDEM; 775 } 776 ioctl(FD, TIOCSETP, &rmtty); 777 ioctl(0, TIOCSETP, &arg); 778 } 779 780 /* 781 * Send a break. 782 */ 783 genbrk() 784 { 785 786 ioctl(FD, TIOCSBRK, NULL); 787 sleep(1); 788 ioctl(FD, TIOCCBRK, NULL); 789 } 790 791 /* 792 * Suspend tip 793 */ 794 suspend(c) 795 char c; 796 { 797 798 unraw(); 799 kill(c == CTRL('y') ? getpid() : 0, SIGTSTP); 800 raw(); 801 } 802 803 /* 804 * expand a file name if it includes shell meta characters 805 */ 806 807 char * 808 expand(name) 809 char name[]; 810 { 811 static char xname[BUFSIZ]; 812 char cmdbuf[BUFSIZ]; 813 register int pid, l, rc; 814 register char *cp, *Shell; 815 int s, pivec[2], (*sigint)(); 816 817 if (!anyof(name, "~{[*?$`'\"\\")) 818 return(name); 819 /* sigint = signal(SIGINT, SIG_IGN); */ 820 if (pipe(pivec) < 0) { 821 perror("pipe"); 822 /* signal(SIGINT, sigint) */ 823 return(name); 824 } 825 sprintf(cmdbuf, "echo %s", name); 826 if ((pid = vfork()) == 0) { 827 Shell = value(SHELL); 828 if (Shell == NOSTR) 829 Shell = _PATH_BSHELL; 830 close(pivec[0]); 831 close(1); 832 dup(pivec[1]); 833 close(pivec[1]); 834 close(2); 835 shell_uid(); 836 execl(Shell, Shell, "-c", cmdbuf, 0); 837 _exit(1); 838 } 839 if (pid == -1) { 840 perror("fork"); 841 close(pivec[0]); 842 close(pivec[1]); 843 return(NOSTR); 844 } 845 close(pivec[1]); 846 l = read(pivec[0], xname, BUFSIZ); 847 close(pivec[0]); 848 while (wait(&s) != pid); 849 ; 850 s &= 0377; 851 if (s != 0 && s != SIGPIPE) { 852 fprintf(stderr, "\"Echo\" failed\n"); 853 return(NOSTR); 854 } 855 if (l < 0) { 856 perror("read"); 857 return(NOSTR); 858 } 859 if (l == 0) { 860 fprintf(stderr, "\"%s\": No match\n", name); 861 return(NOSTR); 862 } 863 if (l == BUFSIZ) { 864 fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); 865 return(NOSTR); 866 } 867 xname[l] = 0; 868 for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) 869 ; 870 *++cp = '\0'; 871 return(xname); 872 } 873 874 /* 875 * Are any of the characters in the two strings the same? 876 */ 877 878 anyof(s1, s2) 879 register char *s1, *s2; 880 { 881 register int c; 882 883 while (c = *s1++) 884 if (any(c, s2)) 885 return(1); 886 return(0); 887 } 888