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

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

unix.superglobalmegacorp.com

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