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

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)conn.c     5.3 (Berkeley) 8/13/83";
                      3: #endif
                      4: 
                      5: #include "uucp.h"
                      6: #include <signal.h>
                      7: #include <setjmp.h>
                      8: #include <ctype.h>
                      9: #include <sys/types.h>
                     10: #include <sys/time.h>
                     11: #include <errno.h>
                     12: #ifdef SYSIII
                     13: #include <termio.h>
                     14: #include <fcntl.h>
                     15: #endif
                     16: #ifndef        SYSIII
                     17: #include <sgtty.h>
                     18: #endif
                     19: 
                     20: #define MAXC 1000
                     21: 
                     22: extern jmp_buf Sjbuf;
                     23: extern int errno;
                     24: 
                     25: /* Parity control during login procedure */
                     26: #define        P_ZERO  0
                     27: #define        P_ONE   1
                     28: #define        P_EVEN  2
                     29: #define        P_ODD   3
                     30: char   par_tab[128];   /* must be power of two */
                     31: 
                     32: int next_fd = -1;      /* predicted fd to close interrupted opens */
                     33:                                /* rti!trt, courtesy unc!smb */
                     34: /***
                     35:  *     alarmtr()  -  catch alarm routine for "expect".
                     36:  */
                     37: alarmtr()
                     38: {
                     39:        signal(SIGALRM, alarmtr);
                     40:        if (next_fd >= 0) {
                     41:                if (close(next_fd))
                     42:                        logent("FAIL", "ACU LINE CLOSE");
                     43:                next_fd = -1;
                     44:        }
                     45:        longjmp(Sjbuf, 1);
                     46: }
                     47: 
                     48: /*******
                     49:  *     conn(system)
                     50:  *     char *system;
                     51:  *
                     52:  *     conn - place a telephone call to system and
                     53:  *     login, etc.
                     54:  *
                     55:  *     return codes:
                     56:  *             CF_SYSTEM: don't know system
                     57:  *             CF_TIME: wrong time to call
                     58:  *             CF_DIAL: call failed
                     59:  *             CF_NODEV: no devices available to place call
                     60:  *             CF_LOGIN: login/password dialog failed
                     61:  *
                     62:  *             >0  - file no.  -  connect ok
                     63:  *
                     64:  */
                     65: 
                     66: int Dcf = -1;
                     67: 
                     68: conn(system)
                     69: char *system;
                     70: {
                     71:        int ret, nf;
                     72:        register int fn, fnd;
                     73:        char info[MAXC], *flds[MAXC/10];
                     74:        register FILE *fsys;
                     75:        int fcode = 0;
                     76: 
                     77:        nf = 0;
                     78:        fnd = 0;
                     79: 
                     80: 
                     81:        fsys = fopen(SYSFILE, "r");
                     82:        ASSERT(fsys != NULL, "CAN'T OPEN", SYSFILE, 0);
                     83: 
                     84:        DEBUG(4, "finds %s\n", "called");
                     85:        while((nf = finds(fsys, system, info, flds)) > 0) {
                     86:                DEBUG(4, "getto %s\n", "called");
                     87:                if ((fn = getto(flds)) > 0) {
                     88:                        fnd = 1;
                     89:                        Dcf = fn;
                     90:                        break;
                     91:                }
                     92:                fcode = (fn == FAIL ? CF_DIAL : fn);
                     93:        }
                     94:        fclose(fsys);
                     95: 
                     96:        if (nf <= 0)
                     97:                return(fcode ? fcode : nf);
                     98: 
                     99:        DEBUG(4, "login %s\n", "called");
                    100:        ret = login(nf, flds, fn);
                    101:        if (ret < 0) {
                    102:                clsacu();
                    103:                return(CF_LOGIN);
                    104:        }
                    105:        /* rti!trt:  avoid passing file to children */
                    106:        fioclex(fn);
                    107:        return(fn);
                    108: }
                    109: 
                    110: /***
                    111:  *     getto(flds)             connect to remote machine
                    112:  *     char *flds[];
                    113:  *
                    114:  *     return codes:
                    115:  *             >0  -  file number - ok
                    116:  *             FAIL  -  failed
                    117:  */
                    118: 
                    119: getto(flds)
                    120: register char *flds[];
                    121: {
                    122:        register struct condev *cd;
                    123:        int nulldev(), diropn();
                    124: 
                    125:        DEBUG(4, "call: no. %s ", flds[F_PHONE]);
                    126:        DEBUG(4, "for sys %s\n", flds[F_NAME]);
                    127: 
                    128:        CU_end = nulldev;
                    129:        for (cd = condevs; cd->CU_meth != NULL; cd++) {
                    130:                if (snccmp(cd->CU_meth, flds[F_LINE]) == SAME) {
                    131:                        DEBUG(4, "Using %s to call\n", cd->CU_meth);
                    132:                        return((*(cd->CU_gen))(flds));
                    133:                        }
                    134:                }
                    135:        logent(flds[F_LINE], "getto: Can't find, using DIR");
                    136:        return(diropn(flds));   /* search failed, so use direct */
                    137:        }
                    138: 
                    139: /***
                    140:  *     clsacu()        close call unit
                    141:  *
                    142:  *     return codes:  none
                    143:  */
                    144: 
                    145: int (*CU_end)() = nulldev;
                    146: clsacu()
                    147: {
                    148:        (*(CU_end))(Dcf);
                    149:        if (close(Dcf) == 0) {
                    150:                DEBUG(4, "fd %d NOT CLOSED by CU_clos\n", Dcf);
                    151:                logent("clsacu", "NOT CLOSED by CU_clos");
                    152:        }
                    153:        Dcf = -1;
                    154:        CU_end = nulldev;
                    155: }
                    156: 
                    157: /***
                    158:  *     exphone - expand phone number for given prefix and number
                    159:  *
                    160:  *     return code - none
                    161:  */
                    162: 
                    163: exphone(in, out)
                    164: register char *in, *out;
                    165: {
                    166:        FILE *fn;
                    167:        char pre[MAXPH], npart[MAXPH], tpre[MAXPH], p[MAXPH];
                    168:        char buf[BUFSIZ];
                    169:        register char *s1;
                    170: 
                    171:        if (!isalpha(*in)) {
                    172:                strcpy(out, in);
                    173:                return;
                    174:        }
                    175: 
                    176:        s1=pre;
                    177:        while (isalpha(*in))
                    178:                *s1++ = *in++;
                    179:        *s1 = '\0';
                    180:        s1 = npart;
                    181:        while (*in != '\0')
                    182:                *s1++ = *in++;
                    183:        *s1 = '\0';
                    184: 
                    185:        tpre[0] = '\0';
                    186:        if ((fn = fopen(DIALFILE, "r")) == NULL)
                    187:                DEBUG(2, "CAN'T OPEN %s\n", DIALFILE);
                    188:        else {
                    189:                while (cfgets(buf, BUFSIZ, fn)) {
                    190:                        sscanf(buf, "%s%s", p, tpre);
                    191:                        if (strcmp(p, pre) == SAME)
                    192:                                goto found;
                    193:                        tpre[0] = '\0';
                    194:                }
                    195:                DEBUG(2, "CAN'T FIND dialcodes prefix '%s'\n", pre);
                    196:        found:;
                    197:                fclose(fn);
                    198:        }
                    199: 
                    200:        strcpy(out, tpre);
                    201:        strcat(out, npart);
                    202:        return;
                    203: }
                    204: 
                    205: /***
                    206:  *     rddev - read and decode a line from device file
                    207:  *
                    208:  *     return code - FAIL at end-of file; 0 otherwise
                    209:  */
                    210: 
                    211: rddev(fp, dev)
                    212: register struct Devices *dev;
                    213: FILE *fp;
                    214: {
                    215:        char *fdig();
                    216:        char buf[BUFSIZ];
                    217:        int na;
                    218: 
                    219:        if (!cfgets(buf, BUFSIZ, fp))
                    220:                return(FAIL);
                    221: 
                    222:        na = sscanf(buf, "%s%s%s%s%s", dev->D_type, dev->D_line,
                    223:          dev->D_calldev, dev->D_class, dev->D_brand);
                    224:        ASSERT(na >= 4, "BAD DEVICE ENTRY", buf, 0);
                    225:        if (na != 5) dev->D_brand[0] = '\0';
                    226:        dev->D_speed = atoi(fdig(dev->D_class));
                    227:        return(0);
                    228: }
                    229: 
                    230: /***
                    231:  *     finds(fsys, sysnam, info, flds) set system attribute vector
                    232:  *
                    233:  *     return codes:
                    234:  *             >0  -  number of arguments in vector - succeeded
                    235:  *             CF_SYSTEM  -  system name not found
                    236:  *             CF_TIME  -  wrong time to call
                    237:  */
                    238: 
                    239: finds(fsys, sysnam, info, flds)
                    240: char *sysnam, info[], *flds[];
                    241: FILE *fsys;
                    242: {
                    243:        char sysn[8];
                    244:        int na;
                    245:        int fcode = 0;
                    246: 
                    247:        /* format of fields
                    248:         *      0 name;
                    249:         *      1 time
                    250:         *      2 acu/hardwired
                    251:         *      3 speed
                    252:         *      etc
                    253:         */
                    254:        while (cfgets(info, MAXC, fsys) != NULL) {
                    255:                na = getargs(info, flds);
                    256:                sprintf(sysn, "%.7s", flds[F_NAME]);
                    257:                if (strcmp(sysnam, sysn) != SAME)
                    258:                        continue;
                    259:                if (ifdate(flds[F_TIME]))
                    260:                        /*  found a good entry  */
                    261:                        return(na);
                    262:                DEBUG(2, "Wrong time ('%s') to call\n", flds[F_TIME]);
                    263:                fcode = CF_TIME;
                    264:        }
                    265:        return(fcode ? fcode : CF_SYSTEM);
                    266: }
                    267: 
                    268: /***
                    269:  *     login(nf, flds, dcr)            do login conversation
                    270:  *     char *flds[];
                    271:  *     int nf;
                    272:  *
                    273:  *     return codes:  0  |  FAIL
                    274:  */
                    275: 
                    276: login(nf, flds, fn)
                    277: register char *flds[];
                    278: int nf, fn;
                    279: {
                    280:        register char *want, *altern;
                    281:        extern char *index();
                    282:        int k, ok;
                    283: 
                    284:        ASSERT(nf > 4, "TOO FEW LOG FIELDS", "", nf);
                    285:        for (k = F_LOGIN; k < nf; k += 2) {
                    286:                want = flds[k];
                    287:                ok = FAIL;
                    288:                while (ok != 0) {
                    289:                        altern = index(want, '-');
                    290:                        if (altern != NULL)
                    291:                                *altern++ = '\0';
                    292:                        DEBUG(4, "wanted %s ", want);
                    293:                        ok = expect(want, fn);
                    294:                        DEBUG(4, "got %s\n", ok ? "?" : "that");
                    295:                        if (ok == 0)
                    296:                                break;
                    297:                        if (altern == NULL) {
                    298:                                logent("LOGIN", "FAILED");
                    299:                                /* close *not* needed here. rti!trt */
                    300:                                return(FAIL);
                    301:                        }
                    302:                        want = index(altern, '-');
                    303:                        if (want != NULL)
                    304:                                *want++ = '\0';
                    305:                        sendthem(altern, fn);
                    306:                }
                    307:                sleep(2);
                    308:                if (k+1 < nf)
                    309:                        sendthem(flds[k+1], fn);
                    310:        }
                    311:        return(0);
                    312: }
                    313: 
                    314: 
                    315: /* rti!trt: conditional table generation to support odd speeds */
                    316: /* Suggested in n44a.139 by n44!dan (Dan Ts'o) */
                    317: struct sg_spds {int sp_val, sp_name;} spds[] = {
                    318: #ifdef B50
                    319:        {  50,   B50},
                    320: #endif
                    321: #ifdef B75
                    322:        {  75,   B75},
                    323: #endif
                    324: #ifdef B110
                    325:        { 110,  B110},
                    326: #endif
                    327: #ifdef B150
                    328:        { 150,  B150},
                    329: #endif
                    330: #ifdef B200
                    331:        { 200,  B200},
                    332: #endif
                    333: #ifdef B300
                    334:        { 300,  B300},
                    335: #endif
                    336: #ifdef B600
                    337:        {600,   B600},
                    338: #endif
                    339: #ifdef B1200
                    340:        {1200, B1200},
                    341: #endif
                    342: #ifdef B1800
                    343:        {1800, B1800},
                    344: #endif
                    345: #ifdef B2000
                    346:        {2000, B2000},
                    347: #endif
                    348: #ifdef B2400
                    349:        {2400, B2400},
                    350: #endif
                    351: #ifdef B3600
                    352:        {3600, B3600},
                    353: #endif
                    354: #ifdef B4800
                    355:        {4800, B4800},
                    356: #endif
                    357: #ifdef B7200
                    358:        {7200, B7200},
                    359: #endif
                    360: #ifdef B9600
                    361:        {9600, B9600},
                    362: #endif
                    363: #ifdef B19200
                    364:        {19200,B19200},
                    365: #endif
                    366:        {0, 0}
                    367: };
                    368: 
                    369: /***
                    370:  *     fixline(tty, spwant)    set speed/echo/mode...
                    371:  *     int tty, spwant;
                    372:  *
                    373:  *     return codes:  none
                    374:  */
                    375: 
                    376: fixline(tty, spwant)
                    377: int tty, spwant;
                    378: {
                    379: #ifdef SYSIII
                    380:        struct termio ttbuf;
                    381: #endif
                    382: #ifndef        SYSIII
                    383:        struct sgttyb ttbuf;
                    384: #endif
                    385:        register struct sg_spds *ps;
                    386:        int speed = -1;
                    387:        int ret;
                    388: 
                    389:        for (ps = spds; ps->sp_val; ps++)
                    390:                if (ps->sp_val == spwant)
                    391:                        speed = ps->sp_name;
                    392:        ASSERT(speed >= 0, "BAD SPEED", "", speed);
                    393: #ifdef SYSIII
                    394:        ioctl(tty, TCGETA, &ttbuf);
                    395:        /* ttbuf.sg_flags = (ANYP|RAW);
                    396:        ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; */
                    397:        ttbuf.c_iflag = (ushort)0;
                    398:        ttbuf.c_oflag = (ushort)0;
                    399:        ttbuf.c_cflag = (speed|CS8|HUPCL|CREAD);
                    400:        ttbuf.c_lflag = (ushort)0;
                    401:        ttbuf.c_cc[VMIN] = 6;
                    402:        ttbuf.c_cc[VTIME] = 1;
                    403:        ret = ioctl(tty, TCSETA, &ttbuf);
                    404: #endif
                    405: #ifndef        SYSIII
                    406:        ioctl(tty, TIOCGETP, &ttbuf);
                    407:        ttbuf.sg_flags = (ANYP|RAW);
                    408:        ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed;
                    409:        ret = ioctl(tty, TIOCSETP, &ttbuf);
                    410: #endif
                    411:        ASSERT(ret >= 0, "RETURN FROM STTY", "", ret);
                    412: #ifndef        SYSIII
                    413:        ioctl(tty, TIOCHPCL, STBNULL);
                    414:        ioctl(tty, TIOCEXCL, STBNULL);
                    415: #endif
                    416:        return;
                    417: }
                    418: 
                    419: 
                    420: /* Bill Shannon recommends MR 2000, but that takes too much space on PDPs */
                    421: /* Actually, the 'expect' algorithm should be rewritten. */
                    422: #define MR 1000
                    423: 
                    424: 
                    425: /***
                    426:  *     expect(str, fn) look for expected string
                    427:  *     char *str;
                    428:  *
                    429:  *     return codes:
                    430:  *             0  -  found
                    431:  *             FAIL  -  lost line or too many characters read
                    432:  *             some character  -  timed out
                    433:  */
                    434: 
                    435: expect(str, fn)
                    436: register char *str;
                    437: int fn;
                    438: {
                    439:        char rdvec[MR];
                    440:        register char *rp = rdvec;
                    441:        int kr;
                    442:        char nextch;
                    443: 
                    444:        if (strcmp(str, "\"\"") == SAME)
                    445:                return(0);
                    446:        *rp = 0;
                    447:        if (setjmp(Sjbuf)) {
                    448:                return(FAIL);
                    449:        }
                    450:        signal(SIGALRM, alarmtr);
                    451: /* change MAXCHARTIME to MAXMSGTIME, outside while loop -- brl-bmd!dpk */
                    452:        alarm(MAXMSGTIME);
                    453:        while (notin(str, rdvec)) {
                    454:                kr = read(fn, &nextch, 1);
                    455:                if (kr <= 0) {
                    456:                        alarm(0);
                    457:                        DEBUG(4, "lost line kr - %d\n, ", kr);
                    458:                        logent("LOGIN", "LOST LINE");
                    459:                        return(FAIL);
                    460:                }
                    461:                {
                    462:                int c;
                    463:                c = nextch & 0177;
                    464:                DEBUG(4, c >= 040 ? "%c" : "\\%03o", c);
                    465:                }
                    466:                if ((*rp = nextch & 0177) != '\0')
                    467:                        rp++;
                    468: /* Check rdvec before null termination -- cmcl2!salkind */
                    469:                if (rp >= rdvec + MR) {
                    470:                        alarm(0);
                    471:                        return(FAIL);
                    472:                }
                    473:                *rp = '\0';
                    474:        }
                    475:        alarm(0);
                    476:        return(0);
                    477: }
                    478: 
                    479: 
                    480: /*
                    481:  * Determine next file descriptor that would be allocated.
                    482:  * This permits later closing of a file whose open was interrupted.
                    483:  * It is a UNIX kernel problem, but it has to be handled.
                    484:  * unc!smb (Steve Bellovin) probably first discovered it.
                    485:  */
                    486: getnextfd()
                    487: {
                    488:        close(next_fd = open("/", 0));
                    489: }
                    490: 
                    491: /***
                    492:  *     sendthem(str, fn)       send line of login sequence
                    493:  *     char *str;
                    494:  *
                    495:  *     return codes:  none
                    496:  */
                    497: 
                    498: sendthem(str, fn)
                    499: register char *str;
                    500: int fn;
                    501: {
                    502:        register char *strptr;
                    503:        int i, n, cr = 1;
                    504:        static int p_init = 0;
                    505: 
                    506:        /* Note: debugging authorized only for privileged users */
                    507:        DEBUG(5, "send %s\n", str);
                    508: 
                    509:        if (!p_init) {
                    510:                p_init++;
                    511:                bld_partab(P_EVEN);
                    512:        }
                    513: 
                    514:        if (prefix("BREAK", str)) {
                    515:                sscanf(&str[5], "%1d", &i);
                    516:                if (i <= 0 || i > 10)
                    517:                        i = 3;
                    518:                /* send break */
                    519:                genbrk(fn, i);
                    520:                return;
                    521:        }
                    522: 
                    523:        if (prefix("PAUSE", str)) {
                    524:                sscanf(&str[5], "%1d", &i);
                    525:                if (i <= 0 || i > 10)
                    526:                        i = 3;
                    527:                /* pause for a while */
                    528:                sleep((unsigned)i);
                    529:                return;
                    530:        }
                    531: 
                    532:        if (strcmp(str, "EOT") == SAME) {
                    533:                p_chwrite(fn, '\04');
                    534:                return;
                    535:        }
                    536: 
                    537:        /* LF, CR, and "" courtesy unc!smb */
                    538:        /* Send a '\n' */
                    539:        if (strcmp(str, "LF") == SAME)
                    540:                str = "\\n\\c";
                    541: 
                    542:        /* Send a '\r' */
                    543:        if (strcmp(str, "CR") == SAME)
                    544:                str = "\\r\\c";
                    545: 
                    546:        /* Set parity as needed */
                    547:        if (strcmp(str, "P_ZERO") == SAME) {
                    548:                bld_partab(P_ZERO);
                    549:                return;
                    550:        }
                    551:        if (strcmp(str, "P_ONE") == SAME) {
                    552:                bld_partab(P_ONE);
                    553:                return;
                    554:        }
                    555:        if (strcmp(str, "P_EVEN") == SAME) {
                    556:                bld_partab(P_EVEN);
                    557:                return;
                    558:        }
                    559:        if (strcmp(str, "P_ODD") == SAME) {
                    560:                bld_partab(P_ODD);
                    561:                return;
                    562:        }
                    563: 
                    564:        /* If "", just send '\r' */
                    565:        if (strcmp(str, "\"\"") != SAME)
                    566:        for (strptr = str; *strptr; strptr++) {
                    567:                if (*strptr == '\\') switch(*++strptr) {
                    568:                case 's':
                    569:                        DEBUG(5, "BLANK\n", "");
                    570:                        *strptr = ' ';
                    571:                        break;
                    572:                case 'd':
                    573:                        DEBUG(5, "DELAY\n", "");
                    574:                        sleep(1);
                    575:                        continue;
                    576:                case 'r':
                    577:                        DEBUG(5, "RETURN\n", "");
                    578:                        *strptr = '\r';
                    579:                        break;
                    580:                case 'b':
                    581:                        if (isdigit(*(strptr+1))) {
                    582:                                i = (*++strptr - '0');
                    583:                                if (i <= 0 || i > 10)
                    584:                                        i = 3;
                    585:                        } else
                    586:                                i = 3;
                    587:                        /* send break */
                    588:                        genbrk(fn, i);
                    589:                        continue;
                    590:                case 'c':
                    591:                        if (*(strptr+1) == '\0') {
                    592:                        DEBUG(5, "NO CR\n", "");
                    593:                                cr = 0;
                    594:                                continue;
                    595:                        }
                    596:                        DEBUG(5, "NO CR - MIDDLE IGNORED\n", "");
                    597:                        continue;
                    598:                default:
                    599:                        if (isdigit(strptr[1])) {
                    600:                                i = 0;
                    601:                                n = 0;
                    602:                                while (isdigit(strptr[1]) && ++n <= 3)
                    603:                                        i = i*8 + (*++strptr - '0');
                    604:                                p_chwrite(fn, i);
                    605:                                continue;
                    606:                        }
                    607:                        DEBUG(5, "BACKSLASH\n", "");
                    608:                        strptr--;
                    609:                }
                    610:                p_chwrite(fn, *strptr);
                    611:        }
                    612: 
                    613:        /* '\n' changed to '\r'--a better default. rti!trt */
                    614:        if (cr)
                    615:                p_chwrite(fn, '\r');
                    616:        return;
                    617: }
                    618: 
                    619: p_chwrite(fd, c)
                    620: int fd;
                    621: int c;
                    622: {
                    623:        char t[2];
                    624: 
                    625:        t[0] = par_tab[c&0177];
                    626:        t[1] = '\0';
                    627:        ASSERT(write(fd, t, 1) == 1, "BAD WRITE", "", t[0]);
                    628: }
                    629: 
                    630: /*
                    631:  * generate parity table for use by p_chwrite.
                    632:  */
                    633: bld_partab(type)
                    634: int type;
                    635: {
                    636:        register int i, j, n;
                    637: 
                    638:        for (i = 0; i < sizeof(par_tab); i++) {
                    639:                n = 0;
                    640:                for (j = i&(sizeof(par_tab)-1); j; j = (j-1)&j)
                    641:                        n++;
                    642:                par_tab[i] = i;
                    643:                if (type == P_ONE
                    644:                 || (type == P_EVEN && (n&01) != 0)
                    645:                 || (type == P_ODD && (n&01) == 0))
                    646:                        par_tab[i] |= sizeof(par_tab);
                    647:        }
                    648: }
                    649: 
                    650: #define BSPEED B150
                    651: 
                    652: /***
                    653:  *     genbrk          send a break
                    654:  *
                    655:  *     return codes;  none
                    656:  */
                    657: 
                    658: genbrk(fn, bnulls)
                    659: register int fn, bnulls;
                    660: {
                    661:        register int ret;
                    662: #ifdef SYSIII
                    663:        ret = ioctl(fn, TCSBRK, STBNULL);
                    664:        DEBUG(5, "break ioctl ret %d\n", ret);
                    665: #endif
                    666: #ifndef        SYSIII
                    667: #ifdef TIOCSBRK
                    668:        ret = ioctl(fn, TIOCSBRK, STBNULL);
                    669:        DEBUG(5, "break ioctl ret %d\n", ret);
                    670: #ifdef TIOCCBRK
                    671:        ret = write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", bnulls);
                    672:        ASSERT(ret > 0, "BAD WRITE genbrk", "", ret);
                    673:        sleep(1);
                    674:        ret = ioctl(fn, TIOCCBRK, STBNULL);
                    675:        DEBUG(5, "break ioctl ret %d\n", ret);
                    676: #endif
                    677:        DEBUG(4, "ioctl 1 second break\n", STBNULL);
                    678: #else
                    679:        struct sgttyb ttbuf;
                    680:        register int sospeed;
                    681: 
                    682:        ret = ioctl(fn, TIOCGETP, &ttbuf);
                    683:        sospeed = ttbuf.sg_ospeed;
                    684:        ttbuf.sg_ospeed = BSPEED;
                    685:        ret = ioctl(fn, TIOCSETP, &ttbuf);
                    686:        ret = write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", bnulls);
                    687:        ASSERT(ret > 0, "BAD WRITE genbrk", "", ret);
                    688:        ttbuf.sg_ospeed = sospeed;
                    689:        ret = ioctl(fn, TIOCSETP, &ttbuf);
                    690:        ret = write(fn, "@", 1);
                    691:        ASSERT(ret > 0, "BAD WRITE genbrk", "", ret);
                    692:        DEBUG(4, "sent BREAK nulls - %d\n", bnulls);
                    693: #endif
                    694: #endif
                    695: }
                    696: 
                    697: 
                    698: /***
                    699:  *     notin(sh, lg)   check for occurrence of substring "sh"
                    700:  *     char *sh, *lg;
                    701:  *
                    702:  *     return codes:
                    703:  *             0  -  found the string
                    704:  *             1  -  not in the string
                    705:  */
                    706: 
                    707: notin(sh, lg)
                    708: register char *sh, *lg;
                    709: {
                    710:        while (*lg != '\0') {
                    711:                /* Dave Martingale: permit wild cards in 'expect' */
                    712:                if (wprefix(sh, lg))
                    713:                        return(0);
                    714:                else
                    715:                        lg++;
                    716:        }
                    717:        return(1);
                    718: }
                    719: 
                    720: 
                    721: /*******
                    722:  *     ifdate(s)
                    723:  *     char *s;
                    724:  *
                    725:  *     ittvax!swatt
                    726:  *     Allow multiple date specifications separated by '|'.
                    727:  *     Calls ifadate, formerly "ifdate".
                    728:  *
                    729:  *     return codes:
                    730:  *             see ifadate
                    731:  */
                    732: 
                    733: ifdate(s)
                    734: char *s;
                    735: {
                    736:        register char *p;
                    737:        register int ret;
                    738: 
                    739:        for (p = s; p && (*p == '|' ? *++p : *p); p = index(p, '|'))
                    740:                if (ret = ifadate(p))
                    741:                        return(ret);
                    742:        return(0);
                    743: }
                    744: 
                    745: 
                    746: /*******
                    747:  *     ifadate(s)
                    748:  *     char *s;
                    749:  *
                    750:  *     ifadate  -  this routine will check a string (s)
                    751:  *     like "MoTu0800-1730" to see if the present
                    752:  *     time is within the given limits.
                    753:  *     SIDE EFFECT - Retrytime is set
                    754:  *
                    755:  *     String alternatives:
                    756:  *             Wk - Mo thru Fr
                    757:  *             zero or one time means all day
                    758:  *             Any - any day
                    759:  *
                    760:  *     return codes:
                    761:  *             0  -  not within limits
                    762:  *             1  -  within limits
                    763:  */
                    764: 
                    765: ifadate(s)
                    766: char *s;
                    767: {
                    768:        static char *days[]={
                    769:                "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0
                    770:        };
                    771:        time_t clock;
                    772:        int rtime;
                    773:        int i, tl, th, tn, flag, dayok=0;
                    774:        struct tm *localtime();
                    775:        struct tm *tp;
                    776:        char *index();
                    777:        char *p;
                    778: 
                    779:        /*  pick up retry time for failures  */
                    780:        /*  global variable Retrytime is set here  */
                    781:        if ((p = index(s, ',')) == NULL) {
                    782:                Retrytime = RETRYTIME;
                    783:        }
                    784:        else {
                    785:                i = sscanf(p+1, "%d", &rtime);
                    786:                if (i < 1 || rtime < 5)
                    787:                        rtime = 5;
                    788:                Retrytime  = rtime * 60;
                    789:        }
                    790: 
                    791:        time(&clock);
                    792:        tp = localtime(&clock);
                    793:        while (isalpha(*s)) {
                    794:                for (i = 0; days[i]; i++) {
                    795:                        if (prefix(days[i], s))
                    796:                                if (tp->tm_wday == i)
                    797:                                        dayok = 1;
                    798:                }
                    799: 
                    800:                if (prefix("Wk", s))
                    801:                        if (tp->tm_wday >= 1 && tp->tm_wday <= 5)
                    802:                                dayok = 1;
                    803:                if (prefix("Any", s))
                    804:                        dayok = 1;
                    805:                s++;
                    806:        }
                    807: 
                    808:        if (dayok == 0)
                    809:                return(0);
                    810:        i = sscanf(s, "%d-%d", &tl, &th);
                    811:        tn = tp->tm_hour * 100 + tp->tm_min;
                    812:        if (i < 2)
                    813:                return(1);
                    814:        if (th < tl)
                    815:                flag = 0;  /* set up for crossover 2400 test */
                    816:        else
                    817:                flag = 1;
                    818:        if ((tn >= tl && tn <= th)
                    819:          || (tn >= th && tn <= tl)) /* test for crossover 2400 */
                    820:                return(flag);
                    821:        else
                    822:                return(!flag);
                    823: }
                    824: 
                    825: 
                    826: /***
                    827:  *     char *
                    828:  *     lastc(s)        return pointer to last character
                    829:  *     char *s;
                    830:  *
                    831:  */
                    832: 
                    833: char *
                    834: lastc(s)
                    835: register char *s;
                    836: {
                    837:        while (*s != '\0') s++;
                    838:        return(s);
                    839: }
                    840: 
                    841: 
                    842: /***
                    843:  *     char *
                    844:  *     fdig(cp)        find first digit in string
                    845:  *
                    846:  *     return - pointer to first digit in string or end of string
                    847:  */
                    848: 
                    849: char *
                    850: fdig(cp)
                    851: register char *cp;
                    852: {
                    853:        register char *c;
                    854: 
                    855:        for (c = cp; *c; c++)
                    856:                if (*c >= '0' && *c <= '9')
                    857:                        break;
                    858:        return(c);
                    859: }
                    860: 
                    861: 
                    862: /*
                    863:  * Compare strings:  s1>s2: >0  s1==s2: 0  s1<s2: <0
                    864:  * Strings are compared as if they contain all capital letters.
                    865:  */
                    866: 
                    867: snccmp(s1, s2)
                    868: register char *s1, *s2;
                    869: {
                    870:        char c1, c2;
                    871: 
                    872:        if (islower(*s1)) c1 = toupper(*s1);
                    873:        else c1 = *s1;
                    874:        if (islower(*s2)) c2 = toupper(*s2);
                    875:        else c2 = *s2;
                    876: 
                    877:        while (c1 == c2) {
                    878:                if (*s1++=='\0')
                    879:                        return(0);
                    880:                s2++;
                    881:                if (islower(*s1)) c1 = toupper(*s1);
                    882:                else c1 = *s1;
                    883:                if (islower(*s2)) c2 = toupper(*s2);
                    884:                else c2 = *s2;
                    885:        }
                    886:        return(c1 - c2);
                    887: }

unix.superglobalmegacorp.com

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