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