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