Annotation of 43BSD/usr.bin/uucp/conn.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)conn.c     5.10 (Berkeley) 1/24/86";
                      3: #endif
                      4: 
                      5: #include <signal.h>
                      6: #include "uucp.h"
                      7: #include <setjmp.h>
                      8: #include <ctype.h>
                      9: #include <errno.h>
                     10: #ifdef USG
                     11: #include <termio.h>
                     12: #include <fcntl.h>
                     13: #endif
                     14: #ifndef        USG
                     15: #include <sgtty.h>
                     16: #endif
                     17: #ifdef BSD4_2
                     18: #include <sys/time.h>
                     19: #else
                     20: #include <time.h>
                     21: #endif
                     22: 
                     23: #define MAXC 1000
                     24: 
                     25: extern jmp_buf Sjbuf;
                     26: jmp_buf Cjbuf;
                     27: extern int errno, onesys;
                     28: extern char *sys_errlist[];
                     29: extern char MaxGrade, DefMaxGrade;
                     30: 
                     31: /* Parity control during login procedure */
                     32: #define        P_ZERO  0
                     33: #define        P_ONE   1
                     34: #define        P_EVEN  2
                     35: #define        P_ODD   3
                     36: 
                     37: #define ABORT -2
                     38: 
                     39: char   *AbortOn = NULL;
                     40: char   par_tab[128];   /* must be power of two */
                     41: int    linebaudrate;   /* used for the sleep test in pk1.c */
                     42: int next_fd = -1;      /* predicted fd to close interrupted opens */
                     43: 
                     44: char *PCP = "PCP";     /* PC Pursuit device type */
                     45: /*
                     46:  *     catch alarm routine for "expect".
                     47:  */
                     48: alarmtr()
                     49: {
                     50:        signal(SIGALRM, alarmtr);
                     51:        if (next_fd >= 0) {
                     52:                if (close(next_fd))
                     53:                        logent("FAIL", "ACU LINE CLOSE");
                     54:                next_fd = -1;
                     55:        }
                     56:        longjmp(Sjbuf, 1);
                     57: }
                     58: 
                     59: /* This template is for seismo to call ihnp4 
                     60:  * the 3 lines marked ---> will be overwritten for the appropriate city
                     61:  */
                     62: #define PCP_BAUD       3
                     63: #define PCP_PHONE      4
                     64: #define PCP_CALLBACK   8
                     65: #define PCP_CITY       10
                     66: #define PCP_RPHONE     12
                     67: #define NPCFIELDS      15
                     68: 
                     69: static char *PCFlds[] = {
                     70:        "PC-PURSUIT",
                     71:        "Any",
                     72:        "ACU",
                     73:        "1200",
                     74:        CNULL,  /* <--- **** Welcome to Telenet PC Pursuit ***** */
                     75:        "ABORT",
                     76:        "Good", /* Abort of Good bye! */
                     77:        ")",    /* <--- Enter your 7-digit phone number (xxx-xxxx) */
                     78:        CNULL,  /* ---> 528-1234 */
                     79:        "call?",        /* <--- Which city do you wish to call? */
                     80:        CNULL,  /* ---> CHICAGO */
                     81:        ")",    /* <--- Enter the phone number you wish to call (xxx-xxxx) */
                     82:        CNULL,  /* ---> 690-7171 */
                     83:        "R)?",  /* <--- You are #1 in the queue. Do you want to wait, or Restart (Y/N/R)? */
                     84:        "Y",
                     85:        CNULL   /* <--- .....Good Bye! */
                     86: };
                     87: 
                     88: static char PCP_brand[20];
                     89: 
                     90: /*
                     91:  *     place a telephone call to system and login, etc.
                     92:  *
                     93:  *     return codes:
                     94:  *             CF_SYSTEM: don't know system
                     95:  *             CF_TIME: wrong time to call
                     96:  *             CF_DIAL: call failed
                     97:  *             CF_NODEV: no devices available to place call
                     98:  *             CF_LOGIN: login/password dialog failed
                     99:  *
                    100:  *             >0  - file no.  -  connect ok
                    101:  */
                    102: 
                    103: int Dcf = -1;
                    104: char *Flds[MAXC/10];
                    105: char LineType[10];
                    106: extern int LocalOnly;
                    107: 
                    108: conn(system)
                    109: char *system;
                    110: {
                    111:        int nf;
                    112:        char info[MAXC], wkpre[NAMESIZE], file[NAMESIZE];
                    113:        register FILE *fsys;
                    114:        int fcode = 0;
                    115: 
                    116:        nf = 0;
                    117: 
                    118:        fsys = fopen(SYSFILE, "r");
                    119:        ASSERT(fsys != NULL, "CAN'T OPEN", SYSFILE, 0);
                    120: 
                    121:        DEBUG(4, "finds (%s) called\n", system);
                    122: keeplooking:
                    123:        while((nf = finds(fsys, system, info, Flds)) > 0) {
                    124:                strncpy(LineType, Flds[F_LINE], 10);
                    125:                if (LocalOnly) {
                    126:                        if (strcmp("TCP", LineType)
                    127:                                && strcmp("DIR", LineType)
                    128:                                && strcmp("LOCAL", LineType) ) {
                    129:                                        fcode = CF_TIME;
                    130:                                        continue;
                    131:                        }
                    132:                }
                    133:                sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname);
                    134:                if (!onesys && MaxGrade != DefMaxGrade &&
                    135:                        !iswrk(file, "chk", Spool, wkpre))  {
                    136:                                fcode = CF_TIME;
                    137:                                continue;
                    138:                }
                    139:                /* For GTE's PC Pursuit */
                    140:                if (snccmp(LineType, PCP) == SAME) {
                    141:                        FILE *dfp;
                    142:                        int status;
                    143:                        static struct Devices dev;
                    144:                        dfp = fopen(DEVFILE, "r");
                    145:                        ASSERT(dfp != NULL, "Can't open", DEVFILE, 0);
                    146:                        while ((status=rddev(dfp, &dev)) != FAIL
                    147:                                && strcmp(PCP, dev.D_type) != SAME)
                    148:                                        ;
                    149:                        fclose(dfp);
                    150:                        if (status == FAIL)
                    151:                                continue;
                    152:                        if (mlock(PCP) == FAIL) {
                    153:                                fcode = CF_NODEV;
                    154:                                logent("DEVICE", "NO");
                    155:                                continue;
                    156:                        }
                    157:                        PCFlds[PCP_BAUD] = dev.D_class;
                    158:                        PCFlds[PCP_PHONE] = dev.D_calldev;
                    159:                        PCFlds[PCP_CALLBACK] = dev.D_arg[D_CHAT];
                    160:                        PCFlds[PCP_CITY] = Flds[F_CLASS];
                    161:                        PCFlds[PCP_RPHONE] = Flds[F_PHONE];
                    162:                        strncpy(PCP_brand, dev.D_brand, sizeof(PCP_brand));
                    163:                        if ((fcode = getto(PCFlds)) < 0)
                    164:                                continue;
                    165:                        Dcf = fcode;
                    166:                        fcode = login(NPCFIELDS, PCFlds, Dcf);
                    167:                        clsacu(); /* Hang up, they'll call back */
                    168:                        if (fcode != SUCCESS) {
                    169:                                fcode = CF_DIAL;
                    170:                                continue;
                    171:                        }
                    172:                        Flds[F_CLASS] = dev.D_class;
                    173:                        Flds[F_PHONE] = dev.D_line;
                    174:                        
                    175:                } /* end PC Pursuit */
                    176:                if ((fcode = getto(Flds)) > 0) 
                    177:                        break;
                    178:        }
                    179: 
                    180:        if (nf <= 0) {
                    181:                fclose(fsys);
                    182:                return fcode ? fcode : nf;
                    183:        }
                    184: 
                    185:        Dcf = fcode;
                    186: 
                    187:        if (fcode >= 0 && snccmp(LineType, PCP) == SAME) {
                    188:                AbortOn = "Good";       /* .... Good Bye */
                    189:                fcode = expect("****~300", Dcf);
                    190:                if (fcode != SUCCESS) {
                    191:                        DEBUG(4, "\nexpect timed out\n", CNULL);
                    192:                        fcode = CF_DIAL;
                    193:                }
                    194:        }
                    195:        if (fcode >= 0) {
                    196:                DEBUG(4, "login %s\n", "called");
                    197:                fcode = login(nf, Flds, Dcf);
                    198:        }
                    199:        if (fcode < 0) {
                    200:                clsacu();
                    201:                if (fcode == ABORT) {
                    202:                        fcode = CF_DIAL;
                    203:                        goto  keeplooking;
                    204:                } else {
                    205:                        fclose(fsys);
                    206:                        return CF_LOGIN;
                    207:                }
                    208:        }
                    209:        fclose(fsys);
                    210:        fioclex(Dcf);
                    211:        return Dcf;
                    212: }
                    213: 
                    214: /*
                    215:  *     connect to remote machine
                    216:  *
                    217:  *     return codes:
                    218:  *             >0  -  file number - ok
                    219:  *             FAIL  -  failed
                    220:  */
                    221: 
                    222: getto(flds)
                    223: register char *flds[];
                    224: {
                    225:        register struct condev *cd;
                    226:        int nulldev(), diropn();
                    227:        char *line;
                    228: 
                    229:        DEBUG(4, "getto: call no. %s ", flds[F_PHONE]);
                    230:        DEBUG(4, "for sys %s\n", flds[F_NAME]);
                    231: 
                    232:        if (snccmp(flds[F_LINE], "LOCAL") == SAME)
                    233:                line = "ACU";
                    234:        else
                    235:                line = flds[F_LINE];
                    236: #ifdef DIALINOUT
                    237:        if (snccmp(line, "ACU") != SAME)
                    238:                reenable();
                    239: #endif DIALINOUT
                    240:        CU_end = nulldev;
                    241:        if (snccmp(line, PCP) == SAME) {
                    242:                for(cd = condevs; cd->CU_meth != NULL; cd++) {
                    243:                        if (snccmp(PCP_brand, cd->CU_brand) == SAME) {
                    244:                                CU_end = cd->CU_clos;
                    245:                                return diropn(flds);
                    246:                        }
                    247:                }
                    248:                logent(PCP_brand, "UNSUPPORTED ACU TYPE");
                    249:        } else {
                    250:                for (cd = condevs; cd->CU_meth != NULL; cd++) {
                    251:                        if (snccmp(cd->CU_meth, line) == SAME) {
                    252:                                DEBUG(4, "Using %s to call\n", cd->CU_meth);
                    253:                                return (*(cd->CU_gen))(flds);
                    254:                        }
                    255:                }
                    256:                DEBUG(1, "Can't find %s, assuming DIR\n", flds[F_LINE]);
                    257:        }
                    258:        return diropn(flds);    /* search failed, so use direct */
                    259: }
                    260: 
                    261: /*
                    262:  *     close call unit
                    263:  *
                    264:  *     return codes:  none
                    265:  */
                    266: 
                    267: int (*CU_end)() = nulldev;
                    268: clsacu()
                    269: {
                    270:        /* make *sure* Dcf is no longer exclusive.
                    271:         * Otherwise dual call-in/call-out modems could get stuck.
                    272:         * Unfortunately, doing this here is not ideal, but it is the
                    273:         * easiest place to put the call.
                    274:         * Hopefully everyone honors the LCK protocol, of course
                    275:         */
                    276: #ifdef TIOCNXCL
                    277:        if (!IsTcpIp && Dcf >= 0 && ioctl(Dcf, TIOCNXCL, STBNULL) < 0)
                    278:                DEBUG(5, "clsacu ioctl %s\n", sys_errlist[errno]);
                    279: #endif
                    280:        if  (setjmp(Sjbuf))
                    281:                logent(Rmtname, "CLOSE TIMEOUT");
                    282:        else {
                    283:                signal(SIGALRM, alarmtr);
                    284:                alarm(20);
                    285:                (*(CU_end))(Dcf);
                    286:                alarm(0);
                    287:        }
                    288:        if (close(Dcf) == 0) {
                    289:                DEBUG(4, "fd %d NOT CLOSED by CU_clos\n", Dcf);
                    290:                logent("clsacu", "NOT CLOSED by CU_clos");
                    291:        }
                    292:        Dcf = -1;
                    293:        CU_end = nulldev;
                    294: }
                    295: 
                    296: /*
                    297:  *     expand phone number for given prefix and number
                    298:  */
                    299: 
                    300: exphone(in, out)
                    301: register char *in, *out;
                    302: {
                    303:        FILE *fn;
                    304:        char pre[MAXPH], npart[MAXPH], tpre[MAXPH], p[MAXPH];
                    305:        char buf[BUFSIZ];
                    306:        register char *s1;
                    307: 
                    308:        if (!isascii(*in) || !isalpha(*in)) {
                    309:                strcpy(out, in);
                    310:                return;
                    311:        }
                    312: 
                    313:        s1=pre;
                    314:        while (isascii(*in) && isalpha(*in))
                    315:                *s1++ = *in++;
                    316:        *s1 = '\0';
                    317:        s1 = npart;
                    318:        while (*in != '\0')
                    319:                *s1++ = *in++;
                    320:        *s1 = '\0';
                    321: 
                    322:        tpre[0] = '\0';
                    323:        if ((fn = fopen(DIALFILE, "r")) == NULL)
                    324:                DEBUG(2, "CAN'T OPEN %s\n", DIALFILE);
                    325:        else {
                    326:                while (cfgets(buf, BUFSIZ, fn)) {
                    327:                        if (sscanf(buf, "%s%s", p, tpre) != 2)
                    328:                                continue;
                    329:                        if (strcmp(p, pre) == SAME)
                    330:                                goto found;
                    331:                        tpre[0] = '\0';
                    332:                }
                    333:                DEBUG(2, "CAN'T FIND dialcodes prefix '%s'\n", pre);
                    334:        found:;
                    335:                fclose(fn);
                    336:        }
                    337: 
                    338:        strcpy(out, tpre);
                    339:        strcat(out, npart);
                    340: }
                    341: 
                    342: /*
                    343:  *     read and decode a line from device file
                    344:  *
                    345:  *     return code - FAIL at end-of file; 0 otherwise
                    346:  */
                    347: 
                    348: rddev(fp, dev)
                    349: register struct Devices *dev;
                    350: FILE *fp;
                    351: {
                    352:        register int na;
                    353: 
                    354:        if (!cfgets(dev->D_argbfr, sizeof(dev->D_argbfr), fp))
                    355:                return FAIL;
                    356:        na = getargs(dev->D_argbfr, dev->D_arg, 20);
                    357:        ASSERT(na >= 4, "BAD DEVICE ENTRY", dev->D_argbfr, 0);
                    358:        if (na == 4) {
                    359:                dev->D_brand = "";
                    360:                na++;
                    361:        }
                    362:        dev->D_speed = atoi(fdig(dev->D_class));
                    363:        dev->D_numargs = na;
                    364:        return 0;
                    365: }
                    366: 
                    367: /*
                    368:  *     set system attribute vector
                    369:  *
                    370:  *     return codes:
                    371:  *             >0  -  number of arguments in vector - succeeded
                    372:  *             CF_SYSTEM  -  system name not found
                    373:  *             CF_TIME  -  wrong time to call
                    374:  */
                    375: 
                    376: finds(fsys, sysnam, info, flds)
                    377: char *sysnam, info[], *flds[];
                    378: FILE *fsys;
                    379: {
                    380:        int na;
                    381:        int fcode = 0;
                    382: 
                    383:        /* format of fields
                    384:         *      0 name;
                    385:         *      1 time
                    386:         *      2 acu/hardwired
                    387:         *      3 speed
                    388:         *      etc
                    389:         */
                    390:        while (cfgets(info, MAXC, fsys) != NULL) {
                    391:                na = getargs(info, flds, MAXC/10);
                    392:                if (strncmp(sysnam, flds[F_NAME], MAXBASENAME) != SAME)
                    393:                        continue;
                    394:                if (ifdate(flds[F_TIME]) != FAIL)
                    395:                        /*  found a good entry  */
                    396:                        return na;
                    397:                DEBUG(2, "Wrong time ('%s') to call\n", flds[F_TIME]);
                    398:                fcode = CF_TIME;
                    399:        }
                    400:        return fcode ? fcode : CF_SYSTEM;
                    401: }
                    402: 
                    403: /*
                    404:  *     do login conversation
                    405:  *
                    406:  *     return codes:  SUCCESS  |  FAIL
                    407:  */
                    408: 
                    409: login(nf, flds, fn)
                    410: register char *flds[];
                    411: int nf, fn;
                    412: {
                    413:        register char *want, *altern;
                    414:        int k, ok;
                    415: 
                    416:        ASSERT(nf > 4, "TOO FEW LOG FIELDS", CNULL, nf);
                    417:        if (setjmp(Cjbuf))
                    418:                return FAIL;
                    419:        AbortOn = NULL;
                    420:        for (k = F_LOGIN; k < nf; k += 2) {
                    421:                want = flds[k];
                    422:                ok = FAIL;
                    423:                while (ok != SUCCESS) {
                    424:                        altern = index(want, '-');
                    425:                        if (altern != NULL)
                    426:                                *altern++ = '\0';
                    427:                        if (strcmp(want, "ABORT") == 0) {
                    428:                                AbortOn = flds[k+1];
                    429:                                DEBUG(4, "ABORT ON: %s\n", AbortOn);
                    430:                                goto nextfield;
                    431:                        }
                    432:                        DEBUG(4, "wanted \"%s\"\n", want);
                    433:                        ok = expect(want, fn);
                    434:                        DEBUG(4, "got: %s\n", ok ? "?" : "that");
                    435:                        if (ok == FAIL) {
                    436:                                if (altern == NULL) {
                    437:                                        logent("LOGIN", _FAILED);
                    438:                                        return FAIL;
                    439:                                }
                    440:                                want = index(altern, '-');
                    441:                                if (want != NULL)
                    442:                                        *want++ = '\0';
                    443:                                sendthem(altern, fn);
                    444:                        } else
                    445:                                if (ok == ABORT) {
                    446:                                        logent("LOGIN ABORTED", _FAILED);
                    447:                                        return ABORT;
                    448:                                }
                    449:                }
                    450:                sleep(1);
                    451:                if (k+1 < nf)
                    452:                        sendthem(flds[k+1], fn);
                    453: nextfield: ;
                    454:        }
                    455:        return SUCCESS;
                    456: }
                    457: 
                    458: 
                    459: /* conditional table generation to support odd speeds */
                    460: struct sg_spds {int sp_val, sp_name;} spds[] = {
                    461: #ifdef B50
                    462:        {  50,   B50},
                    463: #endif
                    464: #ifdef B75
                    465:        {  75,   B75},
                    466: #endif
                    467: #ifdef B110
                    468:        { 110,  B110},
                    469: #endif
                    470: #ifdef B150
                    471:        { 150,  B150},
                    472: #endif
                    473: #ifdef B200
                    474:        { 200,  B200},
                    475: #endif
                    476: #ifdef B300
                    477:        { 300,  B300},
                    478: #endif
                    479: #ifdef B600
                    480:        {600,   B600},
                    481: #endif
                    482: #ifdef B1200
                    483:        {1200, B1200},
                    484: #endif
                    485: #ifdef B1800
                    486:        {1800, B1800},
                    487: #endif
                    488: #ifdef B2000
                    489:        {2000, B2000},
                    490: #endif
                    491: #ifdef B2400
                    492:        {2400, B2400},
                    493: #endif
                    494: #ifdef B3600
                    495:        {3600, B3600},
                    496: #endif
                    497: #ifdef B4800
                    498:        {4800, B4800},
                    499: #endif
                    500: #ifdef B7200
                    501:        {7200, B7200},
                    502: #endif
                    503: #ifdef B9600
                    504:        {9600, B9600},
                    505: #endif
                    506: #ifdef B19200
                    507:        {19200, B19200},
                    508: #endif
                    509: #ifdef EXTA
                    510:        {19200, EXTA},
                    511: #endif
                    512:        {0, 0}
                    513: };
                    514: 
                    515: /*
                    516:  *     set speed/echo/mode...
                    517:  *
                    518:  *     return codes:  none
                    519:  */
                    520: 
                    521: fixline(tty, spwant)
                    522: int tty, spwant;
                    523: {
                    524: #ifdef USG
                    525:        struct termio ttbuf;
                    526: #else  !USG
                    527:        struct sgttyb ttbuf;
                    528: #endif !USG
                    529:        register struct sg_spds *ps;
                    530:        int speed = -1;
                    531: 
                    532:        for (ps = spds; ps->sp_val; ps++)
                    533:                if (ps->sp_val == spwant)
                    534:                        speed = ps->sp_name;
                    535:        ASSERT(speed >= 0, "BAD SPEED", CNULL, speed);
                    536: #ifdef USG
                    537:        if (ioctl(tty, TCGETA, &ttbuf) < 0)
                    538:                return FAIL;
                    539:        /* ttbuf.sg_flags = (ANYP|RAW);
                    540:        ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; */
                    541:        ttbuf.c_iflag = (ushort)0;
                    542:        ttbuf.c_oflag = (ushort)0;
                    543:        ttbuf.c_cflag = (speed|CS8|HUPCL|CREAD);
                    544:        ttbuf.c_lflag = (ushort)0;
                    545:        ttbuf.c_cc[VMIN] = 6;
                    546:        ttbuf.c_cc[VTIME] = 1;
                    547:        if (ioctl(tty, TCSETA, &ttbuf) < 0)
                    548:                return FAIL;
                    549: #else  !USG
                    550:        if (ioctl(tty, TIOCGETP, &ttbuf) < 0)
                    551:                return FAIL;
                    552:        ttbuf.sg_flags = (ANYP|RAW);
                    553:        ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed;
                    554:        if (ioctl(tty, TIOCSETP, &ttbuf) < 0)
                    555:                return FAIL;
                    556: #endif
                    557: #ifndef        USG
                    558:        if (ioctl(tty, TIOCHPCL, STBNULL) < 0)
                    559:                return FAIL;
                    560:        if (ioctl(tty, TIOCEXCL, STBNULL) < 0)
                    561:                return FAIL;
                    562: #endif
                    563:        linebaudrate = spwant;
                    564:        return SUCCESS;
                    565: }
                    566: 
                    567: #define MR 100
                    568: 
                    569: /*
                    570:  *     look for expected string
                    571:  *
                    572:  *     return codes:
                    573:  *             0  -  found
                    574:  *             FAIL  -  lost line or too many characters read
                    575:  *             some character  -  timed out
                    576:  */
                    577: 
                    578: expect(str, fn)
                    579: register char *str;
                    580: int fn;
                    581: {
                    582:        char rdvec[MR];
                    583:        register char *rp = rdvec, *strptr;
                    584:        int kr, cnt_char;
                    585:        char nextch;
                    586:        int timo = MAXMSGTIME;
                    587: 
                    588:        if (*str == '\0' || strcmp(str, "\"\"") == SAME)
                    589:                return SUCCESS;
                    590:        /* Cleanup str, convert \0xx strings to one char  */
                    591:        for (strptr = str; *strptr; strptr++) {
                    592:                if (*strptr == '\\')
                    593:                        switch(*++strptr) {
                    594:                        case 's':
                    595:                                DEBUG(5, "BLANK\n", CNULL);
                    596:                                *strptr = ' ';
                    597:                                break;
                    598:                        default:
                    599:                                strptr--;  /* back up to backslash */
                    600:                                sscanf(strptr + 1,"%o", &cnt_char);
                    601:                                DEBUG(6, "BACKSLASHED %02xH\n", cnt_char);
                    602:                                *strptr = (char) (cnt_char);
                    603:                                strcpy(&strptr[1], &strptr[4]);
                    604:                        }
                    605:        }
                    606: 
                    607:        strptr = index(str, '~');
                    608:        if (strptr != NULL) {
                    609:                *strptr++ = '\0';
                    610:                timo = atoi(strptr);
                    611:                if (timo <= 0)
                    612:                        timo = MAXMSGTIME;
                    613:        }
                    614: 
                    615:        if (setjmp(Sjbuf))
                    616:                return FAIL;
                    617:        signal(SIGALRM, alarmtr);
                    618:        alarm(timo);
                    619:        *rp = 0;
                    620:        while (notin(str, rdvec)) {
                    621:                int c;
                    622:                if(AbortOn != NULL && !notin(AbortOn, rdvec)) {
                    623:                        DEBUG(1, "Call aborted on '%s'\n", AbortOn);
                    624:                        alarm(0);
                    625:                        return ABORT;
                    626:                }
                    627:                kr = read(fn, &nextch, 1);
                    628:                if (kr <= 0) {
                    629:                        alarm(0);
                    630:                        DEBUG(4, "lost line kr - %d\n, ", kr);
                    631:                        logent("LOGIN", "LOST LINE");
                    632:                        return FAIL;
                    633:                }
                    634:                c = nextch & 0177;
                    635:                if (c == '\0')
                    636:                        continue;
                    637:                DEBUG(4, (isprint(c) || isspace(c)) ? "%c" : "\\%03o", c);
                    638:                *rp++ = c;
                    639:                if (rp >= rdvec + MR) {
                    640:                        register char *p;
                    641:                        for (p = rdvec+MR/2; p < rp; p++)
                    642:                                *(p-MR/2) = *p;
                    643:                        rp -= MR/2;
                    644:                }
                    645:                *rp = '\0';
                    646:        }
                    647:        alarm(0);
                    648:        return SUCCESS;
                    649: }
                    650: 
                    651: 
                    652: /*
                    653:  * Determine next file descriptor that would be allocated.
                    654:  * This permits later closing of a file whose open was interrupted.
                    655:  * It is a UNIX kernel problem, but it has to be handled.
                    656:  * unc!smb (Steve Bellovin) probably first discovered it.
                    657:  */
                    658: getnextfd()
                    659: {
                    660:        close(next_fd = open("/", 0));
                    661: }
                    662: 
                    663: /*
                    664:  *     send line of login sequence
                    665:  *
                    666:  *     return codes:  none
                    667:  */
                    668: sendthem(str, fn)
                    669: register char *str;
                    670: int fn;
                    671: {
                    672:        register char *strptr;
                    673:        int i, n, cr = 1;
                    674:        register char c;
                    675:        static int p_init = 0;
                    676: 
                    677:        DEBUG(5, "send \"%s\"\n", str);
                    678: 
                    679:        if (!p_init) {
                    680:                p_init++;
                    681:                bld_partab(P_EVEN);
                    682:        }
                    683: 
                    684:        if (prefix("BREAK", str)) {
                    685:                sscanf(&str[5], "%1d", &i);
                    686:                if (i <= 0 || i > 10)
                    687:                        i = 3;
                    688:                /* send break */
                    689:                genbrk(fn, i);
                    690:                return;
                    691:        }
                    692: 
                    693:        if (prefix("PAUSE", str)) {
                    694:                sscanf(&str[5], "%1d", &i);
                    695:                if (i <= 0 || i > 10)
                    696:                        i = 3;
                    697:                /* pause for a while */
                    698:                sleep((unsigned)i);
                    699:                return;
                    700:        }
                    701: 
                    702:        if (strcmp(str, "EOT") == SAME) {
                    703:                p_chwrite(fn, '\04');
                    704:                return;
                    705:        }
                    706: 
                    707:        /* Send a '\n' */
                    708:        if (strcmp(str, "LF") == SAME) {
                    709:                p_chwrite(fn, '\n');
                    710:                return;
                    711:        }
                    712: 
                    713:        /* Send a '\r' */
                    714:        if (strcmp(str, "CR") == SAME) {
                    715:                p_chwrite(fn, '\r');
                    716:                return;
                    717:        }
                    718: 
                    719:        /* Set parity as needed */
                    720:        if (strcmp(str, "P_ZERO") == SAME) {
                    721:                bld_partab(P_ZERO);
                    722:                return;
                    723:        }
                    724:        if (strcmp(str, "P_ONE") == SAME) {
                    725:                bld_partab(P_ONE);
                    726:                return;
                    727:        }
                    728:        if (strcmp(str, "P_EVEN") == SAME) {
                    729:                bld_partab(P_EVEN);
                    730:                return;
                    731:        }
                    732:        if (strcmp(str, "P_ODD") == SAME) {
                    733:                bld_partab(P_ODD);
                    734:                return;
                    735:        }
                    736: 
                    737:        /* If "", just send '\r' */
                    738:        if (strcmp(str, "\"\"") == SAME) {
                    739:                p_chwrite(fn, '\r');
                    740:                return;
                    741:        }
                    742: 
                    743:        strptr = str;
                    744:        while ((c = *strptr++) != '\0') {
                    745:                if (c == '\\') {
                    746:                        switch(*strptr++) {
                    747:                        case '\0':
                    748:                                DEBUG(5, "TRAILING BACKSLASH IGNORED\n", CNULL);
                    749:                                --strptr;
                    750:                                continue;
                    751:                        case 's':
                    752:                                DEBUG(5, "BLANK\n", CNULL);
                    753:                                c = ' ';
                    754:                                break;
                    755:                        case 'd':
                    756:                                DEBUG(5, "DELAY\n", CNULL);
                    757:                                sleep(1);
                    758:                                continue;
                    759:                        case 'n':
                    760:                                DEBUG(5, "NEW LINE\n", CNULL);
                    761:                                c = '\n';
                    762:                                break;
                    763:                        case 'r':
                    764:                                DEBUG(5, "RETURN\n", CNULL);
                    765:                                c = '\r';
                    766:                                break;
                    767:                        case 'b':
                    768:                                if (isdigit(*strptr)) {
                    769:                                        i = (*strptr++ - '0');
                    770:                                        if (i <= 0 || i > 10)
                    771:                                                i = 3;
                    772:                                } else
                    773:                                        i = 3;
                    774:                                /* send break */
                    775:                                genbrk(fn, i);
                    776:                                if (*strptr == '\0')
                    777:                                        cr = 0;
                    778:                                continue;
                    779:                        case 'c':
                    780:                                if (*strptr == '\0') {
                    781:                                        DEBUG(5, "NO CR\n", CNULL);
                    782:                                        cr = 0;
                    783:                                } else
                    784:                                        DEBUG(5, "NO CR - IGNORED NOT EOL\n", CNULL);
                    785:                                continue;
                    786: #define isoctal(x)     ((x >= '0') && (x <= '7'))
                    787:                        default:
                    788:                                if (isoctal(strptr[-1])) {
                    789:                                        i = 0;
                    790:                                        n = 0;
                    791:                                        --strptr;
                    792:                                        while (isoctal(*strptr) && ++n <= 3)
                    793:                                                i = i * 8 + (*strptr++ - '0');
                    794:                                        DEBUG(5, "\\%o\n", i);
                    795:                                        p_chwrite(fn, (char)i);
                    796:                                        continue;
                    797:                                }
                    798:                        }
                    799:                }
                    800:                p_chwrite(fn, c);
                    801:        }
                    802: 
                    803:        if (cr)
                    804:                p_chwrite(fn, '\r');
                    805:        return;
                    806: }
                    807: 
                    808: p_chwrite(fd, c)
                    809: int fd;
                    810: char c;
                    811: {
                    812:        c = par_tab[c&0177];
                    813:        if (write(fd, &c, 1) != 1) {
                    814:                logent(sys_errlist[errno], "BAD WRITE");
                    815:                longjmp(Cjbuf, 2);
                    816:        }
                    817: }
                    818: 
                    819: /*
                    820:  * generate parity table for use by p_chwrite.
                    821:  */
                    822: bld_partab(type)
                    823: int type;
                    824: {
                    825:        register int i, j, n;
                    826: 
                    827:        for (i = 0; i < sizeof(par_tab); i++) {
                    828:                n = 0;
                    829:                for (j = i&(sizeof(par_tab)-1); j; j = (j-1)&j)
                    830:                        n++;
                    831:                par_tab[i] = i;
                    832:                if (type == P_ONE
                    833:                 || (type == P_EVEN && (n&01) != 0)
                    834:                 || (type == P_ODD && (n&01) == 0))
                    835:                        par_tab[i] |= sizeof(par_tab);
                    836:        }
                    837: }
                    838: 
                    839: /*
                    840:  *     check for occurrence of substring "sh"
                    841:  *
                    842:  *     return codes:
                    843:  *             0  -  found the string
                    844:  *             1  -  not in the string
                    845:  */
                    846: notin(sh, lg)
                    847: register char *sh, *lg;
                    848: {
                    849:        while (*lg != '\0') {
                    850:                if (wprefix(sh, lg))
                    851:                        return 0;
                    852:                else
                    853:                        lg++;
                    854:        }
                    855:        return 1;
                    856: }
                    857: 
                    858: /*
                    859:  *     Allow multiple date specifications separated by ','.
                    860:  */
                    861: ifdate(p)
                    862: register char *p;
                    863: {
                    864:        register char *np;
                    865:        register int ret, g;
                    866:        int rtime, i;
                    867: 
                    868:        /*  pick up retry time for failures  */
                    869:        /*  global variable Retrytime is set here  */
                    870:        if ((np = index(p, ';')) == NULL) {
                    871:                Retrytime = RETRYTIME;
                    872:        } else {
                    873:                i = sscanf(np+1, "%d", &rtime);
                    874:                if (i < 1 || rtime < 0)
                    875:                        rtime = 5;
                    876:                Retrytime  = rtime * 60;
                    877:        }
                    878: 
                    879:        ret = FAIL;
                    880:        MaxGrade = '\0';
                    881:        do {
                    882:                np = strpbrk(p, ",|");  /* prefer , but allow | for compat */
                    883:                if (np)
                    884:                        *np = '\0';
                    885:                g = ifadate(p);
                    886:                DEBUG(11,"ifadate returns %o\n", g);
                    887:                if (g != FAIL) {
                    888:                        ret = SUCCESS;
                    889:                        if (g > MaxGrade)
                    890:                                MaxGrade = g;
                    891:                }
                    892:                if (np)
                    893:                        *np = ',';
                    894:                p = np + 1;
                    895:        } while (np);
                    896:        if (MaxGrade == '\0')
                    897:                MaxGrade = DefMaxGrade;
                    898:        return ret;
                    899: }
                    900: 
                    901: /*
                    902:  *     this routine will check a string (string)
                    903:  *     like "MoTu0800-1730" to see if the present
                    904:  *     time is within the given limits.
                    905:  *     SIDE EFFECT - Retrytime is set
                    906:  *
                    907:  *     return codes:
                    908:  *             0  -  not within limits
                    909:  *             1  -  within limits
                    910:  */
                    911: 
                    912: ifadate(string)
                    913: char *string;
                    914: {
                    915:        static char *days[]={
                    916:                "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0
                    917:        };
                    918:        time_t clock;
                    919:        register char *s = string;
                    920:        int i, tl, th, tn, dayok=0;
                    921:        struct tm *localtime();
                    922:        struct tm *tp;
                    923:        char *p, MGrade;
                    924: 
                    925:        if ((p = index(s, '/')) == NULL)
                    926:                MGrade = DefMaxGrade;
                    927:        else
                    928:                MGrade = p[1];
                    929: 
                    930:        time(&clock);
                    931:        tp = localtime(&clock);
                    932:        while (isascii(*s) && isalpha(*s)) {
                    933:                for (i = 0; days[i]; i++) {
                    934:                        if (prefix(days[i], s))
                    935:                                if (tp->tm_wday == i)
                    936:                                        dayok = 1;
                    937:                }
                    938: 
                    939:                if (prefix("Wk", s))
                    940:                        if (tp->tm_wday >= 1 && tp->tm_wday <= 5)
                    941:                                dayok = 1;
                    942:                if (prefix("Any", s))
                    943:                        dayok = 1;
                    944:                if (prefix("Evening", s)) {
                    945:                        /* Sat or Sun */
                    946:                        if (tp->tm_wday == 6 || tp->tm_wday == 0
                    947:                                || tp->tm_hour >= 17 || tp->tm_hour < 8)
                    948:                                        dayok = 1;
                    949:                }
                    950:                if (prefix("Night", s)) {
                    951:                        if (tp->tm_wday == 6  /* Sat */
                    952:                                || tp->tm_hour >= 23 || tp->tm_hour < 8
                    953:                                        /* Sunday before 5pm */
                    954:                                || (tp->tm_wday == 0 && tp->tm_hour < 17))
                    955:                                        dayok = 1;
                    956:                }
                    957:                if (prefix("NonPeak", s)) { /* For Tymnet and PC Pursuit */
                    958:                        /* Sat or Sun */
                    959:                        if (tp->tm_wday == 6 || tp->tm_wday == 0
                    960:                                || tp->tm_hour >= 18 || tp->tm_hour < 7)
                    961:                                        dayok = 1;
                    962:                }
                    963:                s++;
                    964:        }
                    965: 
                    966:        if (dayok == 0 && s != string)
                    967:                return FAIL;
                    968:        i = sscanf(s, "%d-%d", &tl, &th);
                    969:        if (i < 2)
                    970:                return MGrade;
                    971:        tn = tp->tm_hour * 100 + tp->tm_min;
                    972:        if (th < tl) {          /* crosses midnight */
                    973:                if (tl <= tn || tn < th)
                    974:                        return MGrade;
                    975:        } else {
                    976:                if (tl <= tn && tn < th)
                    977:                        return MGrade;
                    978:        }
                    979:        return FAIL;
                    980: }
                    981: 
                    982: /*
                    983:  *     find first digit in string
                    984:  *
                    985:  *     return - pointer to first digit in string or end of string
                    986:  */
                    987: char *
                    988: fdig(cp)
                    989: register char *cp;
                    990: {
                    991:        register char *c;
                    992: 
                    993:        for (c = cp; *c; c++)
                    994:                if (*c >= '0' && *c <= '9')
                    995:                        break;
                    996:        return c;
                    997: }
                    998: 
                    999: /*
                   1000:  * Compare strings:  s1>s2: >0  s1==s2: 0  s1<s2: <0
                   1001:  * Strings are compared as if they contain all capital letters.
                   1002:  */
                   1003: snccmp(s1, s2)
                   1004: register char *s1, *s2;
                   1005: {
                   1006:        char c1, c2;
                   1007: 
                   1008:        if (islower(*s1))
                   1009:                c1 = toupper(*s1);
                   1010:        else
                   1011:                c1 = *s1;
                   1012:        if (islower(*s2))
                   1013:                c2 = toupper(*s2);
                   1014:        else
                   1015:                c2 = *s2;
                   1016: 
                   1017:        while (c1 == c2) {
                   1018:                if (*s1++ == '\0')
                   1019:                        return 0;
                   1020:                s2++;
                   1021:                if (islower(*s1))
                   1022:                        c1 = toupper(*s1);
                   1023:                else
                   1024:                        c1 = *s1;
                   1025:                if (islower(*s2))
                   1026:                        c2 = toupper(*s2);
                   1027:                else
                   1028:                        c2 = *s2;
                   1029:        }
                   1030:        return c1 - c2;
                   1031: }
                   1032: 
                   1033: /*
                   1034:  * Compare strings:  s1>s2: >0  s1==s2: 0  s1<s2: <0
                   1035:  * Strings are compared as if they contain all capital letters.
                   1036:  */
                   1037: sncncmp(s1, s2, n)
                   1038: register char *s1, *s2;
                   1039: register int n;
                   1040: {
                   1041:        char c1, c2;
                   1042: 
                   1043:        if (islower(*s1))
                   1044:                c1 = toupper(*s1);
                   1045:        else
                   1046:                c1 = *s1;
                   1047:        if (islower(*s2))
                   1048:                c2 = toupper(*s2);
                   1049:        else
                   1050:                c2 = *s2;
                   1051: 
                   1052:        while ( --n >= 0 && c1 == c2) {
                   1053:                if (*s1++ == '\0')
                   1054:                        return 0;
                   1055:                s2++;
                   1056:                if (islower(*s1))
                   1057:                        c1 = toupper(*s1);
                   1058:                else
                   1059:                        c1 = *s1;
                   1060:                if (islower(*s2))
                   1061:                        c2 = toupper(*s2);
                   1062:                else
                   1063:                        c2 = *s2;
                   1064:        }
                   1065:        return n<0 ? 0 : (c1 - c2);
                   1066: }
                   1067: /*
                   1068:  * do chat script
                   1069:  * occurs after local port is opened,
                   1070:  * before 'dialing' the other machine.
                   1071:  */
                   1072: dochat(dev, flds, fd)
                   1073: register struct Devices *dev;
                   1074: char *flds[];
                   1075: int fd;
                   1076: {
                   1077:        register int i;
                   1078:        register char *p;
                   1079:        char bfr[sizeof(dev->D_argbfr)];
                   1080: 
                   1081:        if (dev->D_numargs <= 5)
                   1082:                return(0);
                   1083:        DEBUG(4, "dochat called %d\n", dev->D_numargs);
                   1084:        for (i = 0; i < dev->D_numargs-5; i++) {
                   1085:                sprintf(bfr, dev->D_arg[D_CHAT+i], flds[F_PHONE]);
                   1086:                if (strcmp(bfr, dev->D_arg[D_CHAT+i])) {
                   1087:                        p = malloc((unsigned)strlen(bfr)+1);
                   1088:                        if (p != NULL) {
                   1089:                                strcpy(p, bfr);
                   1090:                                dev->D_arg[D_CHAT+i] = p;
                   1091:                        }
                   1092:                }
                   1093:        }
                   1094:        /* following is a kludge because login() arglist is a kludge */
                   1095:        i = login(dev->D_numargs, &dev->D_arg[D_CHAT-5], fd);
                   1096:        /*
                   1097:         * If login() last did a sendthem(), must pause so things can settle.
                   1098:         * But don't bother if chat failed.
                   1099:         */
                   1100:        if (i == 0 && (dev->D_numargs&01))
                   1101:                sleep(2);
                   1102:        return(i);
                   1103: }
                   1104: 
                   1105: /*
                   1106:  *     fix kill/echo/raw on line
                   1107:  *
                   1108:  *     return codes:  none
                   1109:  */
                   1110: fixmode(tty)
                   1111: register int tty;
                   1112: {
                   1113: #ifdef USG
                   1114:        struct termio ttbuf;
                   1115: #else  !USG
                   1116:        struct sgttyb ttbuf;
                   1117: #endif !USG
                   1118:        register struct sg_spds *ps;
                   1119:        int speed;
                   1120: 
                   1121:        if (IsTcpIp)
                   1122:                return;
                   1123: #ifdef USG
                   1124:        ioctl(tty, TCGETA, &ttbuf);
                   1125:        ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0;
                   1126:        speed = ttbuf.c_cflag &= (CBAUD);
                   1127:        ttbuf.c_cflag |= (CS8|CREAD);
                   1128:        ttbuf.c_cc[VMIN] = 6;
                   1129:        ttbuf.c_cc[VTIME] = 1;
                   1130:        ioctl(tty, TCSETA, &ttbuf);
                   1131: #else  !USG
                   1132:        ioctl(tty, TIOCGETP, &ttbuf);
                   1133:        ttbuf.sg_flags = (ANYP | RAW);
                   1134:        ioctl(tty, TIOCSETP, &ttbuf);
                   1135:        speed = ttbuf.sg_ispeed;
                   1136:        ioctl(tty, TIOCEXCL, STBNULL);
                   1137: #endif !USG
                   1138: 
                   1139:        for (ps = spds; ps->sp_val; ps++)
                   1140:                if (ps->sp_name == speed) {
                   1141:                        linebaudrate = ps->sp_val;
                   1142:                        DEBUG(9,"Incoming baudrate is %d\n", linebaudrate);
                   1143:                        return;
                   1144:                }
                   1145:        ASSERT(linebaudrate >= 0, "BAD SPEED", CNULL, speed);
                   1146: }
                   1147: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.