Annotation of 43BSDTahoe/usr.bin/uucp/conn.c, revision 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.