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

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

unix.superglobalmegacorp.com

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