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