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: char copyright[] =
   9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: #endif not lint
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)tip.c	5.4 (Berkeley) 4/3/86";
  15: #endif not lint
  16: 
  17: /*
  18:  * tip - UNIX link to other systems
  19:  *  tip [-v] [-speed] system-name
  20:  * or
  21:  *  cu phone-number [-s speed] [-l line] [-a acu]
  22:  */
  23: #include "tip.h"
  24: 
  25: /*
  26:  * Baud rate mapping table
  27:  */
  28: int bauds[] = {
  29:     0, 50, 75, 110, 134, 150, 200, 300, 600,
  30:     1200, 1800, 2400, 4800, 9600, 19200, -1
  31: };
  32: 
  33: int disc = OTTYDISC;        /* tip normally runs this way */
  34: int intprompt();
  35: int timeout();
  36: int cleanup();
  37: char    *sname();
  38: char    PNbuf[256];         /* This limits the size of a number */
  39: extern char *sprintf();
  40: 
  41: main(argc, argv)
  42:     char *argv[];
  43: {
  44:     char *system = NOSTR;
  45:     register int i;
  46:     register char *p;
  47:     char sbuf[12];
  48: 
  49:     if (equal(sname(argv[0]), "cu")) {
  50:         cumode = 1;
  51:         cumain(argc, argv);
  52:         goto cucommon;
  53:     }
  54: 
  55:     if (argc > 4) {
  56:         fprintf(stderr, "usage: tip [-v] [-speed] [system-name]\n");
  57:         exit(1);
  58:     }
  59:     if (!isatty(0)) {
  60:         fprintf(stderr, "tip: must be interactive\n");
  61:         exit(1);
  62:     }
  63: 
  64:     for (; argc > 1; argv++, argc--) {
  65:         if (argv[1][0] != '-')
  66:             system = argv[1];
  67:         else switch (argv[1][1]) {
  68: 
  69:         case 'v':
  70:             vflag++;
  71:             break;
  72: 
  73:         case '0': case '1': case '2': case '3': case '4':
  74:         case '5': case '6': case '7': case '8': case '9':
  75:             BR = atoi(&argv[1][1]);
  76:             break;
  77: 
  78:         default:
  79:             fprintf(stderr, "tip: %s, unknown option\n", argv[1]);
  80:             break;
  81:         }
  82:     }
  83: 
  84:     if (system == NOSTR)
  85:         goto notnumber;
  86:     if (isalpha(*system))
  87:         goto notnumber;
  88:     /*
  89: 	 * System name is really a phone number...
  90: 	 * Copy the number then stomp on the original (in case the number
  91: 	 *	is private, we don't want 'ps' or 'w' to find it).
  92: 	 */
  93:     if (strlen(system) > sizeof PNbuf - 1) {
  94:         fprintf(stderr, "tip: phone number too long (max = %d bytes)\n",
  95:             sizeof PNbuf - 1);
  96:         exit(1);
  97:     }
  98:     strncpy( PNbuf, system, sizeof PNbuf - 1 );
  99:     for (p = system; *p; p++)
 100:         *p = '\0';
 101:     PN = PNbuf;
 102:     system = sprintf(sbuf, "tip%d", BR);
 103: 
 104: notnumber:
 105:     signal(SIGINT, cleanup);
 106:     signal(SIGQUIT, cleanup);
 107:     signal(SIGHUP, cleanup);
 108:     signal(SIGTERM, cleanup);
 109: 
 110:     if ((i = hunt(system)) == 0) {
 111:         printf("all ports busy\n");
 112:         exit(3);
 113:     }
 114:     if (i == -1) {
 115:         printf("link down\n");
 116:         delock(uucplock);
 117:         exit(3);
 118:     }
 119:     setbuf(stdout, NULL);
 120:     loginit();
 121: 
 122:     /*
 123: 	 * Kludge, their's no easy way to get the initialization
 124: 	 *   in the right order, so force it here
 125: 	 */
 126:     if ((PH = getenv("PHONES")) == NOSTR)
 127:         PH = "/etc/phones";
 128:     vinit();                /* init variables */
 129:     setparity("even");          /* set the parity table */
 130:     if ((i = speed(number(value(BAUDRATE)))) == NULL) {
 131:         printf("tip: bad baud rate %d\n", number(value(BAUDRATE)));
 132:         delock(uucplock);
 133:         exit(3);
 134:     }
 135: 
 136:     /*
 137: 	 * Now that we have the logfile and the ACU open
 138: 	 *  return to the real uid and gid.  These things will
 139: 	 *  be closed on exit.  Swap real and effective uid's
 140: 	 *  so we can get the original permissions back
 141: 	 *  for removing the uucp lock.
 142: 	 */
 143:     gid = getgid();
 144:     egid = getegid();
 145:     uid = getuid();
 146:     euid = geteuid();
 147:     setregid(egid, gid);
 148:     setreuid(euid, uid);
 149: 
 150:     /*
 151: 	 * Hardwired connections require the
 152: 	 *  line speed set before they make any transmissions
 153: 	 *  (this is particularly true of things like a DF03-AC)
 154: 	 */
 155:     if (HW)
 156:         ttysetup(i);
 157:     if (p = connect()) {
 158:         printf("\07%s\n[EOT]\n", p);
 159:         setreuid(uid, euid);
 160:         setregid(gid, egid);
 161:         delock(uucplock);
 162:         exit(1);
 163:     }
 164:     if (!HW)
 165:         ttysetup(i);
 166: cucommon:
 167:     /*
 168: 	 * From here down the code is shared with
 169: 	 * the "cu" version of tip.
 170: 	 */
 171: 
 172:     ioctl(0, TIOCGETP, (char *)&defarg);
 173:     ioctl(0, TIOCGETC, (char *)&defchars);
 174:     ioctl(0, TIOCGLTC, (char *)&deflchars);
 175:     ioctl(0, TIOCGETD, (char *)&odisc);
 176:     arg = defarg;
 177:     arg.sg_flags = ANYP | CBREAK;
 178:     tchars = defchars;
 179:     tchars.t_intrc = tchars.t_quitc = -1;
 180:     ltchars = deflchars;
 181:     ltchars.t_suspc = ltchars.t_dsuspc = ltchars.t_flushc
 182:         = ltchars.t_lnextc = -1;
 183:     raw();
 184: 
 185:     pipe(fildes); pipe(repdes);
 186:     signal(SIGALRM, timeout);
 187: 
 188:     /*
 189: 	 * Everything's set up now:
 190: 	 *	connection established (hardwired or dialup)
 191: 	 *	line conditioned (baud rate, mode, etc.)
 192: 	 *	internal data structures (variables)
 193: 	 * so, fork one process for local side and one for remote.
 194: 	 */
 195:     printf(cumode ? "Connected\r\n" : "\07connected\r\n");
 196:     if (pid = fork())
 197:         tipin();
 198:     else
 199:         tipout();
 200:     /*NOTREACHED*/
 201: }
 202: 
 203: cleanup()
 204: {
 205: 
 206:     if (uid != getuid()) {
 207:         setreuid(uid, euid);
 208:         setregid(gid, egid);
 209:     }
 210:     delock(uucplock);
 211:     if (odisc)
 212:         ioctl(0, TIOCSETD, (char *)&odisc);
 213:     exit(0);
 214: }
 215: 
 216: /*
 217:  * put the controlling keyboard into raw mode
 218:  */
 219: raw()
 220: {
 221: 
 222:     ioctl(0, TIOCSETP, &arg);
 223:     ioctl(0, TIOCSETC, &tchars);
 224:     ioctl(0, TIOCSLTC, &ltchars);
 225:     ioctl(0, TIOCSETD, (char *)&disc);
 226: }
 227: 
 228: 
 229: /*
 230:  * return keyboard to normal mode
 231:  */
 232: unraw()
 233: {
 234: 
 235:     ioctl(0, TIOCSETD, (char *)&odisc);
 236:     ioctl(0, TIOCSETP, (char *)&defarg);
 237:     ioctl(0, TIOCSETC, (char *)&defchars);
 238:     ioctl(0, TIOCSLTC, (char *)&deflchars);
 239: }
 240: 
 241: static  jmp_buf promptbuf;
 242: 
 243: /*
 244:  * Print string ``s'', then read a string
 245:  *  in from the terminal.  Handles signals & allows use of
 246:  *  normal erase and kill characters.
 247:  */
 248: prompt(s, p)
 249:     char *s;
 250:     register char *p;
 251: {
 252:     register char *b = p;
 253:     int (*oint)(), (*oquit)();
 254: 
 255:     stoprompt = 0;
 256:     oint = signal(SIGINT, intprompt);
 257:     oint = signal(SIGQUIT, SIG_IGN);
 258:     unraw();
 259:     printf("%s", s);
 260:     if (setjmp(promptbuf) == 0)
 261:         while ((*p = getchar()) != EOF && *p != '\n')
 262:             p++;
 263:     *p = '\0';
 264: 
 265:     raw();
 266:     signal(SIGINT, oint);
 267:     signal(SIGQUIT, oint);
 268:     return (stoprompt || p == b);
 269: }
 270: 
 271: /*
 272:  * Interrupt service routine during prompting
 273:  */
 274: intprompt()
 275: {
 276: 
 277:     signal(SIGINT, SIG_IGN);
 278:     stoprompt = 1;
 279:     printf("\r\n");
 280:     longjmp(promptbuf, 1);
 281: }
 282: 
 283: /*
 284:  * ****TIPIN   TIPIN****
 285:  */
 286: tipin()
 287: {
 288:     char gch, bol = 1;
 289: 
 290:     /*
 291: 	 * Kinda klugey here...
 292: 	 *   check for scripting being turned on from the .tiprc file,
 293: 	 *   but be careful about just using setscript(), as we may
 294: 	 *   send a SIGEMT before tipout has a chance to set up catching
 295: 	 *   it; so wait a second, then setscript()
 296: 	 */
 297:     if (boolean(value(SCRIPT))) {
 298:         sleep(1);
 299:         setscript();
 300:     }
 301: 
 302:     while (1) {
 303:         gch = getchar()&0177;
 304:         if ((gch == character(value(ESCAPE))) && bol) {
 305:             if (!(gch = escape()))
 306:                 continue;
 307:         } else if (!cumode && gch == character(value(RAISECHAR))) {
 308:             boolean(value(RAISE)) = !boolean(value(RAISE));
 309:             continue;
 310:         } else if (gch == '\r') {
 311:             bol = 1;
 312:             pwrite(FD, &gch, 1);
 313:             if (boolean(value(HALFDUPLEX)))
 314:                 printf("\r\n");
 315:             continue;
 316:         } else if (!cumode && gch == character(value(FORCE)))
 317:             gch = getchar()&0177;
 318:         bol = any(gch, value(EOL));
 319:         if (boolean(value(RAISE)) && islower(gch))
 320:             gch = toupper(gch);
 321:         pwrite(FD, &gch, 1);
 322:         if (boolean(value(HALFDUPLEX)))
 323:             printf("%c", gch);
 324:     }
 325: }
 326: 
 327: /*
 328:  * Escape handler --
 329:  *  called on recognition of ``escapec'' at the beginning of a line
 330:  */
 331: escape()
 332: {
 333:     register char gch;
 334:     register esctable_t *p;
 335:     char c = character(value(ESCAPE));
 336:     extern esctable_t etable[];
 337: 
 338:     gch = (getchar()&0177);
 339:     for (p = etable; p->e_char; p++)
 340:         if (p->e_char == gch) {
 341:             if ((p->e_flags&PRIV) && getuid())
 342:                 continue;
 343:             printf("%s", ctrl(c));
 344:             (*p->e_func)(gch);
 345:             return (0);
 346:         }
 347:     /* ESCAPE ESCAPE forces ESCAPE */
 348:     if (c != gch)
 349:         pwrite(FD, &c, 1);
 350:     return (gch);
 351: }
 352: 
 353: speed(n)
 354:     int n;
 355: {
 356:     register int *p;
 357: 
 358:     for (p = bauds; *p != -1;  p++)
 359:         if (*p == n)
 360:             return (p - bauds);
 361:     return (NULL);
 362: }
 363: 
 364: any(c, p)
 365:     register char c, *p;
 366: {
 367:     while (p && *p)
 368:         if (*p++ == c)
 369:             return (1);
 370:     return (0);
 371: }
 372: 
 373: size(s)
 374:     register char   *s;
 375: {
 376:     register int i = 0;
 377: 
 378:     while (s && *s++)
 379:         i++;
 380:     return (i);
 381: }
 382: 
 383: char *
 384: interp(s)
 385:     register char *s;
 386: {
 387:     static char buf[256];
 388:     register char *p = buf, c, *q;
 389: 
 390:     while (c = *s++) {
 391:         for (q = "\nn\rr\tt\ff\033E\bb"; *q; q++)
 392:             if (*q++ == c) {
 393:                 *p++ = '\\'; *p++ = *q;
 394:                 goto next;
 395:             }
 396:         if (c < 040) {
 397:             *p++ = '^'; *p++ = c + 'A'-1;
 398:         } else if (c == 0177) {
 399:             *p++ = '^'; *p++ = '?';
 400:         } else
 401:             *p++ = c;
 402:     next:
 403:         ;
 404:     }
 405:     *p = '\0';
 406:     return (buf);
 407: }
 408: 
 409: char *
 410: ctrl(c)
 411:     char c;
 412: {
 413:     static char s[3];
 414: 
 415:     if (c < 040 || c == 0177) {
 416:         s[0] = '^';
 417:         s[1] = c == 0177 ? '?' : c+'A'-1;
 418:         s[2] = '\0';
 419:     } else {
 420:         s[0] = c;
 421:         s[1] = '\0';
 422:     }
 423:     return (s);
 424: }
 425: 
 426: /*
 427:  * Help command
 428:  */
 429: help(c)
 430:     char c;
 431: {
 432:     register esctable_t *p;
 433:     extern esctable_t etable[];
 434: 
 435:     printf("%c\r\n", c);
 436:     for (p = etable; p->e_char; p++) {
 437:         if ((p->e_flags&PRIV) && getuid())
 438:             continue;
 439:         printf("%2s", ctrl(character(value(ESCAPE))));
 440:         printf("%-2s %c   %s\r\n", ctrl(p->e_char),
 441:             p->e_flags&EXP ? '*': ' ', p->e_help);
 442:     }
 443: }
 444: 
 445: /*
 446:  * Set up the "remote" tty's state
 447:  */
 448: ttysetup(speed)
 449:     int speed;
 450: {
 451:     unsigned bits = LDECCTQ;
 452: 
 453:     arg.sg_ispeed = arg.sg_ospeed = speed;
 454:     arg.sg_flags = RAW;
 455:     if (boolean(value(TAND)))
 456:         arg.sg_flags |= TANDEM;
 457:     ioctl(FD, TIOCSETP, (char *)&arg);
 458:     ioctl(FD, TIOCLBIS, (char *)&bits);
 459: }
 460: 
 461: /*
 462:  * Return "simple" name from a file name,
 463:  * strip leading directories.
 464:  */
 465: char *
 466: sname(s)
 467:     register char *s;
 468: {
 469:     register char *p = s;
 470: 
 471:     while (*s)
 472:         if (*s++ == '/')
 473:             p = s;
 474:     return (p);
 475: }
 476: 
 477: static char partab[0200];
 478: 
 479: /*
 480:  * Do a write to the remote machine with the correct parity.
 481:  * We are doing 8 bit wide output, so we just generate a character
 482:  * with the right parity and output it.
 483:  */
 484: pwrite(fd, buf, n)
 485:     int fd;
 486:     char *buf;
 487:     register int n;
 488: {
 489:     register int i;
 490:     register char *bp;
 491:     extern int errno;
 492: 
 493:     bp = buf;
 494:     for (i = 0; i < n; i++) {
 495:         *bp = partab[(*bp) & 0177];
 496:         bp++;
 497:     }
 498:     if (write(fd, buf, n) < 0) {
 499:         if (errno == EIO)
 500:             abort("Lost carrier.");
 501:         /* this is questionable */
 502:         perror("write");
 503:     }
 504: }
 505: 
 506: /*
 507:  * Build a parity table with appropriate high-order bit.
 508:  */
 509: setparity(defparity)
 510:     char *defparity;
 511: {
 512:     register int i;
 513:     char *parity;
 514:     extern char evenpartab[];
 515: 
 516:     if (value(PARITY) == NOSTR)
 517:         value(PARITY) = defparity;
 518:     parity = value(PARITY);
 519:     for (i = 0; i < 0200; i++)
 520:         partab[i] = evenpartab[i];
 521:     if (equal(parity, "even"))
 522:         return;
 523:     if (equal(parity, "odd")) {
 524:         for (i = 0; i < 0200; i++)
 525:             partab[i] ^= 0200;  /* reverse bit 7 */
 526:         return;
 527:     }
 528:     if (equal(parity, "none") || equal(parity, "zero")) {
 529:         for (i = 0; i < 0200; i++)
 530:             partab[i] &= ~0200; /* turn off bit 7 */
 531:         return;
 532:     }
 533:     if (equal(parity, "one")) {
 534:         for (i = 0; i < 0200; i++)
 535:             partab[i] |= 0200;  /* turn on bit 7 */
 536:         return;
 537:     }
 538:     fprintf(stderr, "%s: unknown parity value\n", PA);
 539:     fflush(stderr);
 540: }

Defined functions

any defined in line 364; used 6 times
cleanup defined in line 203; used 10 times
ctrl defined in line 409; used 7 times
escape defined in line 331; used 1 times
help defined in line 429; used 2 times
interp defined in line 383; used 2 times
intprompt defined in line 274; used 3 times
main defined in line 41; never used
prompt defined in line 248; used 11 times
pwrite defined in line 484; used 8 times
raw defined in line 219; used 5 times
setparity defined in line 509; used 3 times
sname defined in line 465; used 2 times
speed defined in line 353; used 7 times
tipin defined in line 286; used 1 times
ttysetup defined in line 448; used 4 times
unraw defined in line 232; used 4 times

Defined variables

PNbuf defined in line 38; used 5 times
bauds defined in line 28; used 2 times
copyright defined in line 8; never used
disc defined in line 33; used 1 times
partab defined in line 477; used 5 times
promptbuf defined in line 241; used 2 times
sccsid defined in line 14; never used
Last modified: 1986-04-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1943
Valid CSS Valid XHTML 1.0 Strict