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.4 (Berkeley) 5/5/86";
   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:         execl(value(SHELL), cp, 0);
 551:         printf("\r\ncan't execl!\r\n");
 552:         exit(1);
 553:     }
 554: }
 555: 
 556: /*
 557:  * TIPIN portion of scripting
 558:  *   initiate the conversation with TIPOUT
 559:  */
 560: setscript()
 561: {
 562:     char c;
 563:     /*
 564: 	 * enable TIPOUT side for dialogue
 565: 	 */
 566:     kill(pid, SIGEMT);
 567:     if (boolean(value(SCRIPT)))
 568:         write(fildes[1], value(RECORD), size(value(RECORD)));
 569:     write(fildes[1], "\n", 1);
 570:     /*
 571: 	 * wait for TIPOUT to finish
 572: 	 */
 573:     read(repdes[0], &c, 1);
 574:     if (c == 'n')
 575:         printf("can't create %s\r\n", value(RECORD));
 576: }
 577: 
 578: /*
 579:  * Change current working directory of
 580:  *   local portion of tip
 581:  */
 582: chdirectory()
 583: {
 584:     char dirname[80];
 585:     register char *cp = dirname;
 586: 
 587:     if (prompt("[cd] ", dirname)) {
 588:         if (stoprompt)
 589:             return;
 590:         cp = value(HOME);
 591:     }
 592:     if (chdir(cp) < 0)
 593:         printf("%s: bad directory\r\n", cp);
 594:     printf("!\r\n");
 595: }
 596: 
 597: abort(msg)
 598:     char *msg;
 599: {
 600: 
 601:     kill(pid, SIGTERM);
 602:     setreuid(euid, euid);
 603:     setregid(egid, egid);
 604:     disconnect(msg);
 605:     if (msg != NOSTR)
 606:         printf("\r\n%s", msg);
 607:     printf("\r\n[EOT]\r\n");
 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:     execl(value(SHELL), cp, "-c", s, 0);
 642: }
 643: 
 644: args(buf, a)
 645:     char *buf, *a[];
 646: {
 647:     register char *p = buf, *start;
 648:     register char **parg = a;
 649:     register int n = 0;
 650: 
 651:     do {
 652:         while (*p && (*p == ' ' || *p == '\t'))
 653:             p++;
 654:         start = p;
 655:         if (*p)
 656:             *parg = p;
 657:         while (*p && (*p != ' ' && *p != '\t'))
 658:             p++;
 659:         if (p != start)
 660:             parg++, n++;
 661:         if (*p)
 662:             *p++ = '\0';
 663:     } while (*p);
 664: 
 665:     return(n);
 666: }
 667: 
 668: prtime(s, a)
 669:     char *s;
 670:     time_t a;
 671: {
 672:     register i;
 673:     int nums[3];
 674: 
 675:     for (i = 0; i < 3; i++) {
 676:         nums[i] = (int)(a % quant[i]);
 677:         a /= quant[i];
 678:     }
 679:     printf("%s", s);
 680:     while (--i >= 0)
 681:         if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0)
 682:             printf("%d %s%c ", nums[i], sep[i],
 683:                 nums[i] == 1 ? '\0' : 's');
 684:     printf("\r\n!\r\n");
 685: }
 686: 
 687: variable()
 688: {
 689:     char    buf[256];
 690: 
 691:     if (prompt("[set] ", buf))
 692:         return;
 693:     vlex(buf);
 694:     if (vtable[BEAUTIFY].v_access&CHANGED) {
 695:         vtable[BEAUTIFY].v_access &= ~CHANGED;
 696:         kill(pid, SIGSYS);
 697:     }
 698:     if (vtable[SCRIPT].v_access&CHANGED) {
 699:         vtable[SCRIPT].v_access &= ~CHANGED;
 700:         setscript();
 701:         /*
 702: 		 * So that "set record=blah script" doesn't
 703: 		 *  cause two transactions to occur.
 704: 		 */
 705:         if (vtable[RECORD].v_access&CHANGED)
 706:             vtable[RECORD].v_access &= ~CHANGED;
 707:     }
 708:     if (vtable[RECORD].v_access&CHANGED) {
 709:         vtable[RECORD].v_access &= ~CHANGED;
 710:         if (boolean(value(SCRIPT)))
 711:             setscript();
 712:     }
 713:     if (vtable[TAND].v_access&CHANGED) {
 714:         vtable[TAND].v_access &= ~CHANGED;
 715:         if (boolean(value(TAND)))
 716:             tandem("on");
 717:         else
 718:             tandem("off");
 719:     }
 720:     if (vtable[LECHO].v_access&CHANGED) {
 721:         vtable[LECHO].v_access &= ~CHANGED;
 722:         HD = boolean(value(LECHO));
 723:     }
 724:     if (vtable[PARITY].v_access&CHANGED) {
 725:         vtable[PARITY].v_access &= ~CHANGED;
 726:         setparity();
 727:     }
 728: }
 729: 
 730: /*
 731:  * Turn tandem mode on or off for remote tty.
 732:  */
 733: tandem(option)
 734:     char *option;
 735: {
 736:     struct sgttyb rmtty;
 737: 
 738:     ioctl(FD, TIOCGETP, &rmtty);
 739:     if (strcmp(option,"on") == 0) {
 740:         rmtty.sg_flags |= TANDEM;
 741:         arg.sg_flags |= TANDEM;
 742:     } else {
 743:         rmtty.sg_flags &= ~TANDEM;
 744:         arg.sg_flags &= ~TANDEM;
 745:     }
 746:     ioctl(FD, TIOCSETP, &rmtty);
 747:     ioctl(0,  TIOCSETP, &arg);
 748: }
 749: 
 750: /*
 751:  * Send a break.
 752:  */
 753: genbrk()
 754: {
 755: 
 756:     ioctl(FD, TIOCSBRK, NULL);
 757:     sleep(1);
 758:     ioctl(FD, TIOCCBRK, NULL);
 759: }
 760: 
 761: /*
 762:  * Suspend tip
 763:  */
 764: suspend(c)
 765:     char c;
 766: {
 767: 
 768:     unraw();
 769:     kill(c == CTRL(y) ? getpid() : 0, SIGTSTP);
 770:     raw();
 771: }
 772: 
 773: /*
 774:  *	expand a file name if it includes shell meta characters
 775:  */
 776: 
 777: char *
 778: expand(name)
 779:     char name[];
 780: {
 781:     static char xname[BUFSIZ];
 782:     char cmdbuf[BUFSIZ];
 783:     register int pid, l, rc;
 784:     register char *cp, *Shell;
 785:     int s, pivec[2], (*sigint)();
 786: 
 787:     if (!anyof(name, "~{[*?$`'\"\\"))
 788:         return(name);
 789:     /* sigint = signal(SIGINT, SIG_IGN); */
 790:     if (pipe(pivec) < 0) {
 791:         perror("pipe");
 792:         /* signal(SIGINT, sigint) */
 793:         return(name);
 794:     }
 795:     sprintf(cmdbuf, "echo %s", name);
 796:     if ((pid = vfork()) == 0) {
 797:         Shell = value(SHELL);
 798:         if (Shell == NOSTR)
 799:             Shell = "/bin/sh";
 800:         close(pivec[0]);
 801:         close(1);
 802:         dup(pivec[1]);
 803:         close(pivec[1]);
 804:         close(2);
 805:         execl(Shell, Shell, "-c", cmdbuf, 0);
 806:         _exit(1);
 807:     }
 808:     if (pid == -1) {
 809:         perror("fork");
 810:         close(pivec[0]);
 811:         close(pivec[1]);
 812:         return(NOSTR);
 813:     }
 814:     close(pivec[1]);
 815:     l = read(pivec[0], xname, BUFSIZ);
 816:     close(pivec[0]);
 817:     while (wait(&s) != pid);
 818:         ;
 819:     s &= 0377;
 820:     if (s != 0 && s != SIGPIPE) {
 821:         fprintf(stderr, "\"Echo\" failed\n");
 822:         return(NOSTR);
 823:     }
 824:     if (l < 0) {
 825:         perror("read");
 826:         return(NOSTR);
 827:     }
 828:     if (l == 0) {
 829:         fprintf(stderr, "\"%s\": No match\n", name);
 830:         return(NOSTR);
 831:     }
 832:     if (l == BUFSIZ) {
 833:         fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name);
 834:         return(NOSTR);
 835:     }
 836:     xname[l] = 0;
 837:     for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--)
 838:         ;
 839:     *++cp = '\0';
 840:     return(xname);
 841: }
 842: 
 843: /*
 844:  * Are any of the characters in the two strings the same?
 845:  */
 846: 
 847: anyof(s1, s2)
 848:     register char *s1, *s2;
 849: {
 850:     register int c;
 851: 
 852:     while (c = *s1++)
 853:         if (any(c, s2))
 854:             return(1);
 855:     return(0);
 856: }

Defined functions

abort defined in line 597; used 2 times
anyof defined in line 847; used 1 times
args defined in line 644; used 2 times
chdirectory defined in line 582; used 2 times
consh defined in line 477; used 2 times
cu_put defined in line 348; used 2 times
cu_take defined in line 63; used 2 times
execute defined in line 632; used 3 times
expand defined in line 777; used 12 times
finish defined in line 613; used 4 times
genbrk defined in line 753; used 2 times
getfl defined in line 33; used 2 times
intcopy defined in line 624; used 3 times
pipefile defined in line 157; used 2 times
pipeout defined in line 424; used 2 times
prtime defined in line 668; used 5 times
send defined in line 381; used 6 times
sendfile defined in line 215; used 2 times
setscript defined in line 560; used 3 times
shell defined in line 526; used 2 times
stopsnd defined in line 203; used 2 times
suspend defined in line 764; used 3 times
tandem defined in line 733; used 2 times
timeout defined in line 414; used 5 times
transfer defined in line 91; used 3 times
transmit defined in line 250; used 2 times
variable defined in line 687; used 2 times

Defined variables

argv defined in line 22; used 12 times
intbuf defined in line 86; used 2 times
null defined in line 20; used 1 times
quant defined in line 18; used 2 times
sccsid defined in line 8; never used
sep defined in line 21; used 1 times
Last modified: 1986-05-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1782
Valid CSS Valid XHTML 1.0 Strict