# 2.11BSD#431 - /usr/src/usr.bin/tip/tip.c

##### Functions

    any               X
    cleanup           X
    ctrl              X
    daemon_uid        X
    escape            X
    help              X
    interp            X
    intprompt         X
    main              X
    prompt            X
    pwrite            X
    raw               X
    setparity         X
    shell_uid         X
    size              X
    sname             X
    speed             X
    tipin             X
    ttysetup          X
    unraw             X
    user_uid          X

##### Variables

    PNbuf             X
    bauds             X
    copyright         X
    disc              X

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

#### Defined functions

any defined in line 395; used 6 times

- in line 349
- in /usr/src/usr.bin/tip/acu.c line 92, 101
- in /usr/src/usr.bin/tip/cmds.c line 123, 855
- in /usr/src/usr.bin/tip/tipout.c line 123

cleanup defined in line 201; used 10 times

- in line 36, 109-112(4)
- in /usr/src/usr.bin/tip/cu.c line 13, 71-74(4)

ctrl defined in line 440; used 7 times

- in line 374, 470-471(2)
- in /usr/src/usr.bin/tip/cmds.c line 406
- in /usr/src/usr.bin/tip/tip.h line 234
- in /usr/src/usr.bin/tip/value.c line 174, 209

daemon_uid defined in line 230; used 4 times

- in line 158, 204
- in /usr/src/usr.bin/tip/cmds.c line 607
- in /usr/src/usr.bin/tip/cu.c line 100

escape defined in line 362; used 1 times

- in line 336

help defined in line 460; used 2 times

- in /usr/src/usr.bin/tip/cmdtab.c line 14, 34

interp defined in line 414; used 2 times

- in /usr/src/usr.bin/tip/value.c line 174, 194

intprompt defined in line 305; used 3 times

- in line 34, 287
- in /usr/src/usr.bin/tip/cmds.c line 26

main defined in line 40; never used
prompt defined in line 279; used 11 times

- in /usr/src/usr.bin/tip/cmds.c line 42, 53, 69, 164, 176, 226, 357, 431, 484, 588, 692

pwrite defined in line 515; used 8 times

- in line 343, 352, 380
- in /usr/src/usr.bin/tip/acu.c line 44
- in /usr/src/usr.bin/tip/cmds.c line 101, 109, 388, 409

raw defined in line 250; used 5 times

- in line 181, 296
- in /usr/src/usr.bin/tip/cmds.c line 538, 627, 771

setparity defined in line 540; used 3 times

- in line 133
- in /usr/src/usr.bin/tip/cmds.c line 727
- in /usr/src/usr.bin/tip/cu.c line 94

shell_uid defined in line 240; used 2 times

- in /usr/src/usr.bin/tip/cmds.c line 550, 806

size defined in line 404; used 7 times

- in /usr/src/usr.bin/tip/acu.c line 44
- in /usr/src/usr.bin/tip/cmds.c line 101, 569
- in /usr/src/usr.bin/tip/value.c line 76, 179, 195, 210

sname defined in line 496; used 2 times

- in line 37, 52

speed defined in line 384; used 7 times

- in line 134, 479-484(3)
- in /usr/src/usr.bin/tip/cu.c line 46, 97, 105

tipin defined in line 317; used 1 times

- in line 195

ttysetup defined in line 479; used 4 times

- in line 155, 163
- in /usr/src/usr.bin/tip/cu.c line 97, 105

unraw defined in line 263; used 4 times

- in line 289
- in /usr/src/usr.bin/tip/cmds.c line 535, 609, 769

user_uid defined in line 221; used 3 times

- in line 147
- in /usr/src/usr.bin/tip/cmds.c line 641
- in /usr/src/usr.bin/tip/cu.c line 92

#### Defined variables

PNbuf defined in line 38; used 5 times

- in line 96-104(5)

bauds defined in line 28; used 2 times

- in line 389-391(2)

copyright defined in line 8; never used
disc defined in line 33; used 1 times

- in line 256

partab defined in line 508; used 5 times

- in line 526, 551-566(4)

promptbuf defined in line 272; used 2 times

- in line 291, 311

sccsid defined in line 14; never used
uidswapped defined in line 219; used 4 times

- in line 223-226(2), 233-236(2)

Last modified: 1987-10-23 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1982 |