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