Annotation of researchv10no/cmd/post.src/postio/ifdef.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *
        !             3:  * Conditionally compiled routines for setting up and reading the line. Things
        !             4:  * were getting out of hand with all the ifdefs, and even though this defeats
        !             5:  * part of the purpose of conditional complilation directives, I think it's easier
        !             6:  * to follow this way. Thanks to Alan Buckwalter for the System V DKHOST code.
        !             7:  *
        !             8:  * postio now can be run as separate read and write processes, but requires that
        !             9:  * you write a procedure called resetline() and perhaps modify readline() some.
        !            10:  * I've already tested the code on System V and it seems to work. Ninth Edition
        !            11:  * and BSD code may be missing.
        !            12:  *
        !            13:  * By request I've changed the way some of the setupline() procedures (eg. in the
        !            14:  * System V implementation) handle things when no line has been given. If line is
        !            15:  * NULL the new setupline() procedures try to continue, assuming whoever called
        !            16:  * postio connected stdout to the printer. Things will only work if we can read
        !            17:  * and write stdout!
        !            18:  *
        !            19:  */
        !            20: 
        !            21: #include <stdio.h>
        !            22: #include <ctype.h>
        !            23: #include <fcntl.h>
        !            24: #include <signal.h>
        !            25: #include <sys/types.h>
        !            26: #include <errno.h>
        !            27: 
        !            28: #include "ifdef.h"                     /* conditional header file inclusion */
        !            29: #include "gen.h"                       /* general purpose definitions */
        !            30: 
        !            31: FILE   *fp_ttyi, *fp_ttyo;
        !            32: char   *ptr = mesg;
        !            33: 
        !            34: extern int     window_size;
        !            35: 
        !            36: /*****************************************************************************/
        !            37: 
        !            38: #ifdef SYSV
        !            39: setupline()
        !            40: 
        !            41: {
        !            42: 
        !            43:     struct termio      termio;
        !            44: 
        !            45: /*
        !            46:  *
        !            47:  * Line initialization for SYSV. For now if no line is given (ie. line == NULL )
        !            48:  * we continue on as before using stdout as ttyi and ttyo. Doesn't work when we're
        !            49:  * running in interactive mode or forcing stuff that comes back from the printer
        !            50:  * to stdout. Both cases are now caught by a test that's been added to routine
        !            51:  * initialize(). The change is primarily for the version of lp that's available
        !            52:  * with SVR3.2.
        !            53:  *
        !            54:  */
        !            55: 
        !            56: #ifdef DKHOST
        !            57:     if ( line != NULL && *line != '/' )  {
        !            58:        if ( strncmp(line, "DK:", 3) == 0 )
        !            59:            line += 3;
        !            60:        dkhost_connect();
        !            61: #ifdef DKSTREAMS
        !            62:        if ( ioctl(ttyi, I_PUSH, DKSTREAMS) == -1 )
        !            63:            error(FATAL, "ioctl error - %s", DKSTREAMS);
        !            64:        if ( ioctl(ttyi, I_PUSH, "ldterm") == -1 )
        !            65:            error(FATAL, "ioctl error - ldterm");
        !            66: #endif
        !            67:     } else
        !            68: #endif
        !            69: 
        !            70:     if ( line == NULL )
        !            71:        ttyi = fileno(stdout);
        !            72:     else if ( (ttyi = open(line, O_RDWR)) == -1 )
        !            73:        error(FATAL, "can't open %s", line);
        !            74: 
        !            75:     if ( (ttyo = dup(ttyi)) == -1 )
        !            76:        error(FATAL, "can't dup file descriptor for %s", line);
        !            77: 
        !            78:     if ( stopbits == 1 )
        !            79:        stopbits = 0;
        !            80:     else stopbits = CSTOPB;
        !            81: 
        !            82:     if ( fcntl(ttyi, F_SETFL, O_NDELAY) == -1 )
        !            83:        error(FATAL, "fcntl error - F_SETFL");
        !            84: 
        !            85:     if ( ioctl(ttyi, TCGETA, &termio) == -1 )
        !            86:        error(FATAL, "ioctl error - TCGETA");
        !            87: 
        !            88:     termio.c_iflag = IXON | IGNCR;
        !            89:     termio.c_oflag = 0;
        !            90:     termio.c_cflag = HUPCL | CREAD | CS8 | stopbits | baudrate;
        !            91:     termio.c_lflag = 0;
        !            92:     termio.c_cc[VMIN] = termio.c_cc[VTIME] = 0;
        !            93: 
        !            94:     if ( ioctl(ttyi, TCSETA, &termio) == -1 )
        !            95:        error(FATAL, "ioctl error - TCSETA");
        !            96: 
        !            97:     if ( ioctl(ttyi, TCFLSH, 2) == -1 )
        !            98:        error(FATAL, "ioctl error - TCFLSH");
        !            99: 
        !           100:     fp_ttyi = fdopen(ttyi, "r");
        !           101: 
        !           102: }   /* End of setupline */
        !           103: 
        !           104: /*****************************************************************************/
        !           105: 
        !           106: resetline()
        !           107: 
        !           108: {
        !           109: 
        !           110:     int                        flags;          /* for turning O_NDELAY off */
        !           111:     struct termio      termio;         /* so we can reset flow control */
        !           112: 
        !           113: /*
        !           114:  *
        !           115:  * Only used if we're running the program as separate read and write processes.
        !           116:  * Called from split() after the initial connection has been made and returns
        !           117:  * TRUE if two processes should work. Don't know if the O_NDELAY stuff is really
        !           118:  * needed, but setting c_cc[VMIN] to 1 definitely is. If we leave it be (as a 0)
        !           119:  * the read in readline() won't block!
        !           120:  *
        !           121:  */
        !           122: 
        !           123:     if ( (flags = fcntl(ttyi, F_GETFL, 0)) == -1 )
        !           124:        error(FATAL, "fcntl error - F_GETFL");
        !           125: 
        !           126:     flags &= ~O_NDELAY;
        !           127: 
        !           128:     if ( fcntl(ttyi, F_SETFL, flags) == -1 )
        !           129:        error(FATAL, "fcntl error - F_SETFL");
        !           130: 
        !           131:     if ( ioctl(ttyi, TCGETA, &termio) == -1 )
        !           132:        error(FATAL, "ioctl error - TCGETA");
        !           133: 
        !           134:     termio.c_iflag &= ~IXANY;
        !           135:     termio.c_iflag |= IXON | IXOFF;
        !           136:     termio.c_cc[VMIN] = 1;
        !           137:     termio.c_cc[VTIME] = 0;
        !           138: 
        !           139:     if ( ioctl(ttyi, TCSETA, &termio) == -1 )
        !           140:        error(FATAL, "ioctl error - TCSETA");
        !           141: 
        !           142:     return(TRUE);
        !           143: 
        !           144: }   /* End of resetline */
        !           145: 
        !           146: /*****************************************************************************/
        !           147: 
        !           148: setupstdin(mode)
        !           149: 
        !           150:     int                mode;                   /* what to do with stdin settings */
        !           151: 
        !           152: {
        !           153: 
        !           154:     struct termio              termio;
        !           155: 
        !           156:     static int                 saved = FALSE;
        !           157:     static struct termio       oldtermio;
        !           158: 
        !           159: /*
        !           160:  *
        !           161:  * Save (mode = 0), reset (mode = 1), or restore (mode = 2) the tty settings for
        !           162:  * stdin. Expect something like raw mode with no echo will be set up. Explicit
        !           163:  * code to ensure blocking reads probably isn't needed because blocksize is set
        !           164:  * to 1 when we're in interactive mode, but I've included it anyway.
        !           165:  *
        !           166:  */
        !           167: 
        !           168:     if ( interactive == TRUE )
        !           169:        switch ( mode )  {
        !           170:            case 0:
        !           171:                if ( isatty(0) != 1 )
        !           172:                    error(FATAL, "stdin not a terminal - can't run interactive mode");
        !           173:                if ( ioctl(0, TCGETA, &oldtermio) == -1 )
        !           174:                    error(FATAL, "can't save terminal settings");
        !           175:                saved = TRUE;
        !           176:                break;
        !           177: 
        !           178:            case 1:
        !           179:                termio = oldtermio;
        !           180:                termio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL);
        !           181:                termio.c_cc[VMIN] = 1;
        !           182:                termio.c_cc[VTIME] = 0;
        !           183:                ioctl(0, TCSETA, &termio);
        !           184:                break;
        !           185: 
        !           186:            case 2:
        !           187:                if ( saved == TRUE )
        !           188:                    ioctl(0, TCSETA, &oldtermio);
        !           189:                break;
        !           190:        }   /* End switch */
        !           191: 
        !           192: }   /* End of setupstdin */
        !           193: 
        !           194: /*****************************************************************************/
        !           195: 
        !           196: readline()
        !           197: 
        !           198: {
        !           199: 
        !           200:     int                n;                      /* read() return value */
        !           201:     int                ch;                     /* for interactive mode */
        !           202: 
        !           203:     static int tries = 0;              /* consecutive times read returned 0 */
        !           204: 
        !           205: /*
        !           206:  *
        !           207:  * Reads characters coming back from the printer on ttyi up to a newline (or EOF)
        !           208:  * or until no more characters are available. Characters are put in mesg[], the
        !           209:  * string is terminated with '\0' when we're done with a line and TRUE is returned
        !           210:  * to the caller. If complete line wasn't available FALSE is returned. Interactive
        !           211:  * mode should loop here forever, except during start(), echoing characters to
        !           212:  * stdout. If it happens to leave FALSE should be returned. The non-blocking read
        !           213:  * gets us out until split() is called.
        !           214:  *
        !           215:  * Some users (apparently just on 3B2 DKHOST systems) have had problems with the
        !           216:  * two process implementation that's forced me to kludge things up some. When a
        !           217:  * printer (on those systems) is turned off while postio is transmitting files
        !           218:  * the write process hangs in writeblock() (postio.c) - it's typically in the
        !           219:  * middle of a write() call, while the read() call (below) continually returns 0.
        !           220:  * In the original code readline() returned FALSE when read() returned 0 and we
        !           221:  * get into a loop that never ends - because the write process is hung. In the
        !           222:  * one process implementation having read return 0 is legitimate because the line
        !           223:  * is opened for no delay, but with two processes the read() blocks and a return
        !           224:  * value of 0 should never occur. From my point of view the real problem is that
        !           225:  * the write() call hangs on 3B2 DKHOST systems and apparently doesn't anywhere
        !           226:  * else. If the write returned anything less than or equal to 0 writeblock() would
        !           227:  * shut things down. The kludge I've implemented counts the number of consecutive
        !           228:  * times read() returns a 0 and if it exceeds a limit (100) the read process will
        !           229:  * shut things down. In fact one return of 0 from read() when we're in the two
        !           230:  * process mode is undoubtedly sufficient and no counting should be necessary!!!
        !           231:  * Moving the check to getstatus() should also work and is probably where things
        !           232:  * belong.
        !           233:  *
        !           234:  */
        !           235: 
        !           236:     if ( interactive == FALSE )  {
        !           237:        while ( (n = read(ttyi, ptr, 1)) != 0 )  {
        !           238:            if ( n < 0 )
        !           239:                if ( errno == EINTR )
        !           240:                    continue;
        !           241:                else error(FATAL, "error reading %s", line);
        !           242:            tries = 0;
        !           243:            if ( *ptr == '\n' || *ptr == '\004' || ptr >= endmesg )  {
        !           244:                *(ptr+1) = '\0';
        !           245:                if ( *ptr == '\004' )
        !           246:                    strcpy(ptr, "%%[ status: endofjob ]%%\n");
        !           247:                ptr = mesg;
        !           248:                return(TRUE);
        !           249:            }   /* End if */
        !           250:            ptr++;
        !           251:        }   /* End while */
        !           252:        if ( canread == TRUE && canwrite == FALSE )     /* read process kludge */
        !           253:            if ( ++tries > 100 )
        !           254:                error(FATAL, "printer appears to be offline - shutting down");
        !           255:        return(FALSE);
        !           256:     }  /* End if */
        !           257: 
        !           258:     if ( canwrite == TRUE )            /* don't block during start() */
        !           259:        return(FALSE);
        !           260: 
        !           261:     while ( (ch = getc(fp_ttyi)) != EOF )
        !           262:        putc(ch, stdout);
        !           263:     return(FALSE);
        !           264: 
        !           265: }   /* End of readline */
        !           266: #endif
        !           267: 
        !           268: /*****************************************************************************/
        !           269: 
        !           270: #ifdef V9
        !           271: #include <ipc.h>
        !           272: 
        !           273: char   tbuf[256];                      /* temporary input buffer */
        !           274: char   *nptr = tbuf;                   /* next character comes from here */
        !           275: char   *eptr = tbuf;                   /* one past the last character in tbuf */
        !           276: 
        !           277: setupline()
        !           278: 
        !           279: {
        !           280: 
        !           281:     struct sgttyb      sgtty;
        !           282:     struct ttydevb     ttydev;         /* for setting up the line */
        !           283:     static struct tchars       tchar = { '\377',       /* interrupt */
        !           284:                                          '\377',       /* quit */
        !           285:                                          '\021',       /* start output */
        !           286:                                          '\023',       /* stop output */
        !           287:                                          '\377',       /* end-of-file */
        !           288:                                          '\377'        /* input delimiter */
        !           289:                                        };
        !           290: 
        !           291: /*
        !           292:  *
        !           293:  * Line initialization for V9.
        !           294:  *
        !           295:  */
        !           296: 
        !           297:     if ( line == NULL )  {
        !           298:        ttyi = ttyo = 1;
        !           299:        return;
        !           300:     }  /* End if */
        !           301:     alarm(120);                        /* watch for hanging opens */
        !           302:     if ( line[0] == '/' ) {
        !           303:        if ( (ttyi = open(line, O_RDWR)) == -1 )
        !           304:        error(FATAL, "can't open %s", line);
        !           305:     } else if ((ttyi = ipcopen(ipcpath(line, "dk", 0), "")) < 0) {
        !           306:                sleep(5);       /* wait for Datakit to hangup */
        !           307:                if ((ttyi = ipcopen(ipcpath(line, "dk", 0), "")) < 0) {
        !           308:                        fprintf(stderr, "%s", errstr);
        !           309:                        error(FATAL, "can't ipcopen %s", line);
        !           310:                }
        !           311:     }
        !           312:     alarm(0);
        !           313: 
        !           314:     if ( (ttyo = dup(ttyi)) == -1 )
        !           315:        error(FATAL, "can't dup file descriptor for %s", line);
        !           316: 
        !           317:     if ( ioctl(ttyi, FIOPUSHLD, &tty_ld) == -1 )
        !           318:        error(FATAL, "ioctl error - FIOPUSHLD");
        !           319: 
        !           320:     if ( ioctl(ttyi, TIOCGDEV, &ttydev) == -1 )
        !           321:        error(FATAL, "ioctl error - TIOCGDEV");
        !           322: 
        !           323:     if ( ioctl(ttyi, TIOCGETP, &sgtty) == -1 )
        !           324:        error(FATAL, "ioctl error - TIOCGETP");
        !           325: 
        !           326:     sgtty.sg_flags &= ~ECHO;
        !           327:     sgtty.sg_flags &= ~CRMOD;
        !           328:     sgtty.sg_flags |= CBREAK;
        !           329:     ttydev.ispeed = baudrate;
        !           330:     ttydev.ospeed = baudrate;
        !           331: 
        !           332:     if ( ioctl(ttyi, TIOCSDEV, &ttydev) == -1 )
        !           333:        error(FATAL, "ioctl error - TIOCSDEV");
        !           334: 
        !           335:     if ( ioctl(ttyi, TIOCSETP, &sgtty) == -1 )
        !           336:        error(FATAL, "ioctl error - TIOCSETP");
        !           337: 
        !           338:     if ( ioctl(ttyi, TIOCSETC, &tchar) == -1 )
        !           339:        error(FATAL, "ioctl error - TIOCSETC");
        !           340: 
        !           341:     fp_ttyi = fdopen(ttyi, "r");
        !           342: 
        !           343: }   /* End of setupline */
        !           344: 
        !           345: /*****************************************************************************/
        !           346: 
        !           347: resetline()
        !           348: 
        !           349: {
        !           350: 
        !           351:     struct sgttyb      sgtty;
        !           352: 
        !           353: /*
        !           354:  *
        !           355:  * Only used if we're running the program as separate read and write processes.
        !           356:  * Called from split() after the initial connection has been made and returns
        !           357:  * TRUE if two processes should work. Haven't tested or even compiled the stuff
        !           358:  * for separate read and write processes on Ninth Edition systems - no guarantees
        !           359:  * even though we return TRUE!
        !           360:  *
        !           361:  */
        !           362: 
        !           363:     if ( ioctl(ttyi, TIOCGETP, &sgtty) == -1 )
        !           364:        error(FATAL, "ioctl error - TIOCGETP");
        !           365: 
        !           366:     sgtty.sg_flags |= TANDEM;
        !           367: 
        !           368:     if ( ioctl(ttyi, TIOCSETP, &sgtty) == -1 )
        !           369:        error(FATAL, "ioctl error - TIOCSETP");
        !           370: 
        !           371:     return(TRUE);
        !           372: 
        !           373: }   /* End of resetline */
        !           374: 
        !           375: /*****************************************************************************/
        !           376: 
        !           377: setupstdin(mode)
        !           378: 
        !           379:     int                mode;                   /* what to do with stdin settings */
        !           380: 
        !           381: {
        !           382: 
        !           383:     struct sgttyb              sgtty;
        !           384: 
        !           385:     static int                 saved = FALSE;
        !           386:     static struct sgttyb       oldsgtty;
        !           387: 
        !           388: /*
        !           389:  *
        !           390:  * Save (mode = 0), reset (mode = 1), or restore (mode = 2) the tty settings for
        !           391:  * stdin. Expect something like raw mode with no echo will be set up. Need to make
        !           392:  * sure interrupt and quit still work - they're the only good way to exit when
        !           393:  * we're running interactive mode. I haven't tested or even compiled this code
        !           394:  * so there are no guarantees.
        !           395:  *
        !           396:  */
        !           397: 
        !           398:     if ( interactive == TRUE )
        !           399:        switch ( mode )  {
        !           400:            case 0:
        !           401:                if ( ioctl(0, TIOCGETP, &oldsgtty) == -1 )
        !           402:                    error(FATAL, "can't save terminal settings");
        !           403:                saved = TRUE;
        !           404:                break;
        !           405: 
        !           406:            case 1:
        !           407:                sgtty = oldsgtty;
        !           408:                sgtty.sg_flags &= ~ECHO;
        !           409:                sgtty.sg_flags |= CBREAK;
        !           410:                ioctl(0, TIOCSETP, &sgtty);
        !           411:                break;
        !           412: 
        !           413:            case 2:
        !           414:                if ( saved == TRUE )
        !           415:                    ioctl(0, TIOCSETP, &oldsgtty);
        !           416:                break;
        !           417:        }   /* End switch */
        !           418: 
        !           419: }   /* End of setupstdin */
        !           420: 
        !           421: /*****************************************************************************/
        !           422: 
        !           423: readline()
        !           424: 
        !           425: {
        !           426: 
        !           427:     int                n;                      /* read() return value */
        !           428:     int                ch;                     /* for interactive mode */
        !           429: 
        !           430: /*
        !           431:  *
        !           432:  * Reads characters coming back from the printer on ttyi up to a newline (or EOF)
        !           433:  * and transfers each line to the mesg[] array. Everything available on ttyi is
        !           434:  * initially stored in tbuf[] and a line at a time is transferred from there to
        !           435:  * mesg[]. The string in mesg[] is terminated with a '\0' and TRUE is returned to
        !           436:  * the caller when we find a newline, EOF, or reach the end of the mesg[] array.
        !           437:  * If nothing is available on ttyi we return FALSE if a single process is being
        !           438:  * used for reads and writes, while in the two process implementation we force a
        !           439:  * one character read. Interactive mode loops here forever, except during start(),
        !           440:  * echoing everything that comes back on ttyi to stdout. The performance of a
        !           441:  * simple getc/putc loop for interactive mode was unacceptable when run under mux
        !           442:  * and has been replaced by more complicated code. When layers wasn't involved
        !           443:  * the getc/putc loop worked well.
        !           444:  *
        !           445:  */
        !           446: 
        !           447:     if ( interactive == FALSE )  {
        !           448:        while ( 1 )  {
        !           449:            while ( nptr < eptr )  {    /* grab characters from tbuf */
        !           450:                *ptr = *nptr++;
        !           451:                if ( *ptr == '\r' ) continue;
        !           452:                if ( *ptr == '\n' || *ptr == '\004' || ptr >= endmesg )  {
        !           453:                    *(ptr+1) = '\0';
        !           454:                    if ( *ptr == '\004' )
        !           455:                        strcpy(ptr, "%%[ status: endofjob ]%%\n");
        !           456:                    ptr = mesg;
        !           457:                    return(TRUE);
        !           458:                }   /* End if */
        !           459:                ++ptr;
        !           460:            }   /* End for */
        !           461: 
        !           462:            nptr = eptr = tbuf;
        !           463:            if ( ioctl(ttyi, FIONREAD, &n) < 0 )
        !           464:                if ( errno == EINTR )
        !           465:                    continue;
        !           466:                else error(FATAL, "ioctl error - FIONREAD");
        !           467:            if ( n <= 0 )
        !           468:                if ( canwrite == TRUE )
        !           469:                    return(FALSE);
        !           470:            n = ((n < 1) ? 1 : ((n < sizeof(tbuf)) ? n : sizeof(tbuf)));
        !           471:            if ( (n = read(ttyi, tbuf, n)) < 0 )
        !           472:                if ( errno == EINTR )
        !           473:                    continue;
        !           474:                else error(FATAL, "error reading line %s", line);
        !           475:            else eptr = nptr + n;
        !           476:        }   /* End while */
        !           477:     }  /* End if */
        !           478: 
        !           479:     if ( canwrite == TRUE )            /* don't block during start() */
        !           480:        return(FALSE);
        !           481: 
        !           482:     while ( 1 )  {                     /* only interactive mode gets here */
        !           483:        if ( ioctl(ttyi, FIONREAD, &n) < 0 )
        !           484:            error(FATAL, "ioctl error - FIONREAD");
        !           485:        n = ((n < 1) ? 1 : ((n < sizeof(tbuf)) ? n : sizeof(tbuf)));
        !           486:        if ( (n = read(ttyi, tbuf, n)) < 0 )
        !           487:            error(FATAL, "error reading line %s", line);
        !           488:        else if ( n == 0 )              /* should not happen */
        !           489:            error(FATAL, "end of file in interactive mode");
        !           490:        if ( write(1, tbuf, n) != n )
        !           491:            error(FATAL, "error writing to stdout");
        !           492:     }  /* End while */
        !           493: 
        !           494:     return(FALSE);
        !           495: 
        !           496: }   /* End of readline */
        !           497: #endif
        !           498: 
        !           499: /*****************************************************************************/
        !           500: 
        !           501: #ifdef BSD4_2
        !           502: setupline()
        !           503: 
        !           504: {
        !           505: 
        !           506:     struct sgttyb      sgtty;
        !           507:     static struct tchars       tchar = { '\377',       /* interrupt */
        !           508:                                          '\377',       /* quit */
        !           509:                                          '\021',       /* start output */
        !           510:                                          '\023',       /* stop output */
        !           511:                                          '\377',       /* end-of-file */
        !           512:                                          '\377'        /* input delimiter */
        !           513:                                        };
        !           514:     long       lmodes;
        !           515:     int                disc = NTTYDISC;
        !           516: 
        !           517: /*
        !           518:  *
        !           519:  * Line initialization for BSD4_2. As in the System V code, if no line is given
        !           520:  * (ie. line == NULL) we continue on as before using stdout as ttyi and ttyo.
        !           521:  *
        !           522:  */
        !           523: 
        !           524:     if ( line == NULL )
        !           525:        ttyi = fileno(stdout);
        !           526:     else if ( (ttyi = open(line, O_RDWR)) == -1 )
        !           527:        error(FATAL, "can't open %s", line);
        !           528: 
        !           529:     if ( (ttyo = dup(ttyi)) == -1 )
        !           530:        error(FATAL, "can't dup file descriptor for %s", line);
        !           531: 
        !           532:     if (ioctl(ttyi, TIOCSETD, &disc) == -1 )
        !           533:        error(FATAL, "ioctl error - TIOCSETD");
        !           534: 
        !           535:     if ( ioctl(ttyi, TIOCGETP, &sgtty) == -1 )
        !           536:        error(FATAL, "ioctl error - TIOCGETP");
        !           537: 
        !           538:     if ( ioctl(ttyi, TIOCLGET, &lmodes) == -1 )
        !           539:        error(FATAL, "ioctl error - TIOCLGET");
        !           540: 
        !           541:     sgtty.sg_flags &= ~ECHO;
        !           542:     sgtty.sg_flags &= ~CRMOD;
        !           543:     sgtty.sg_flags |= CBREAK;
        !           544:     sgtty.sg_ispeed = baudrate;
        !           545:     sgtty.sg_ospeed = baudrate;
        !           546:     lmodes |= LDECCTQ;
        !           547: 
        !           548:     if ( ioctl(ttyi, TIOCSETP, &sgtty) == -1 )
        !           549:        error(FATAL, "ioctl error - TIOCSETP");
        !           550: 
        !           551:     if ( ioctl(ttyi, TIOCSETC, &tchar) == -1 )
        !           552:        error(FATAL, "ioctl error - TIOCSETC");
        !           553: 
        !           554:     if ( ioctl(ttyi, TIOCLSET, &lmodes) == -1 )
        !           555:        error(FATAL, "ioctl error - TIOCLSET");
        !           556: 
        !           557:     fp_ttyi = fdopen(ttyi, "r");
        !           558: 
        !           559: }   /* End of setupline */
        !           560: 
        !           561: /*****************************************************************************/
        !           562: 
        !           563: resetline()
        !           564: 
        !           565: {
        !           566: 
        !           567:     struct sgttyb      sgtty;
        !           568: 
        !           569: /*
        !           570:  *
        !           571:  * Only used if we're running the program as separate read and write processes.
        !           572:  * Called from split() after the initial connection has been made and returns
        !           573:  * TRUE if two processes should work. Haven't tested or even compiled the stuff
        !           574:  * for separate read and write processes on Berkeley systems - no guarantees
        !           575:  * even though we return TRUE!
        !           576:  *
        !           577:  */
        !           578: 
        !           579:     if ( ioctl(ttyi, TIOCGETP, &sgtty) == -1 )
        !           580:        error(FATAL, "ioctl error - TIOCGETP");
        !           581: 
        !           582:     sgtty.sg_flags |= TANDEM;
        !           583: 
        !           584:     if ( ioctl(ttyi, TIOCSETP, &sgtty) == -1 )
        !           585:        error(FATAL, "ioctl error - TIOCSETP");
        !           586: 
        !           587:     return(TRUE);
        !           588: 
        !           589: }   /* End of resetline */
        !           590: 
        !           591: /*****************************************************************************/
        !           592: 
        !           593: setupstdin(mode)
        !           594: 
        !           595:     int                mode;                   /* what to do with stdin settings */
        !           596: 
        !           597: {
        !           598: 
        !           599:     struct sgttyb              sgtty;
        !           600: 
        !           601:     static int                 saved = FALSE;
        !           602:     static struct sgttyb       oldsgtty;
        !           603: 
        !           604: /*
        !           605:  *
        !           606:  * Save (mode = 0), reset (mode = 1), or restore (mode = 2) the tty settings for
        !           607:  * stdin. Expect something like raw mode with no echo will be set up. Need to make
        !           608:  * sure interrupt and quit still work - they're the only good way to exit when
        !           609:  * we're running interactive mode. I haven't tested or even compiled this code
        !           610:  * so there are no guarantees.
        !           611:  *
        !           612:  */
        !           613: 
        !           614:     if ( interactive == TRUE )
        !           615:        switch ( mode )  {
        !           616:            case 0:
        !           617:                if ( isatty(0) != 1 )
        !           618:                    error(FATAL, "stdin not a terminal - can't run interactive mode");
        !           619:                if ( ioctl(0, TIOCGETP, &oldsgtty) == -1 )
        !           620:                    error(FATAL, "can't save terminal settings");
        !           621:                saved = TRUE;
        !           622:                break;
        !           623: 
        !           624:            case 1:
        !           625:                sgtty = oldsgtty;
        !           626:                sgtty.sg_flags &= ~ECHO;
        !           627:                sgtty.sg_flags |= CBREAK;
        !           628:                ioctl(0, TIOCSETP, &sgtty);
        !           629:                break;
        !           630: 
        !           631:            case 2:
        !           632:                if ( saved == TRUE )
        !           633:                    ioctl(0, TIOCSETP, &oldsgtty);
        !           634:                break;
        !           635:        }   /* End switch */
        !           636: 
        !           637: }   /* End of setupstdin */
        !           638: 
        !           639: /*****************************************************************************/
        !           640: 
        !           641: readline()
        !           642: 
        !           643: {
        !           644: 
        !           645:     int                n;                      /* read() return value */
        !           646:     int                ch;                     /* for interactive mode */
        !           647: 
        !           648: /*
        !           649:  *
        !           650:  * Reads characters coming back from the printer on ttyo up to a newline (or EOF)
        !           651:  * or until no more characters are available. Characters are put in mesg[], the
        !           652:  * string is terminated with '\0' when we're done with a line and TRUE is returned
        !           653:  * to the caller. If complete line wasn't available FALSE is returned. Interactive
        !           654:  * mode should loop here forever, except during start(), echoing characters to
        !           655:  * stdout. If it happens to leave FALSE should be returned. Probably should read
        !           656:  * everything available on ttyi into a temporary buffer and work from there rather
        !           657:  * than reading one character at a time.
        !           658:  *
        !           659:  */
        !           660: 
        !           661:     if ( interactive == FALSE )  {
        !           662:        while ( 1 )  {
        !           663:            if ( ioctl(ttyi, FIONREAD, &n) < 0 )
        !           664:                if ( errno == EINTR )
        !           665:                    continue;
        !           666:                else error(FATAL, "ioctl error - FIONREAD");
        !           667:            if ( n <= 0 )
        !           668:                if ( canwrite == TRUE )
        !           669:                    return(FALSE);
        !           670:                else n = 1;
        !           671:            for ( ; n > 0; n-- )  {
        !           672:                /*if ( read(ttyi, ptr, 1) < 0 )*/
        !           673:                if ( (*ptr = getc(fp_ttyi)) == EOF )
        !           674:                    if ( errno == EINTR )
        !           675:                        continue;
        !           676:                    else error(FATAL, "error reading %s", line);
        !           677:                if ( *ptr == '\r' ) continue;
        !           678:                if ( *ptr == '\n' || *ptr == '\004' || ptr >= endmesg )  {
        !           679:                    *(ptr+1) = '\0';
        !           680:                    if ( *ptr == '\004' )
        !           681:                        strcpy(ptr, "%%[ status: endofjob ]%%\n");
        !           682:                    ptr = mesg;
        !           683:                    return(TRUE);
        !           684:                }   /* End if */
        !           685:                ++ptr;
        !           686:            }   /* End for */
        !           687:        }   /* End while */
        !           688:     }  /* End if */
        !           689: 
        !           690:     if ( canwrite == TRUE )            /* don't block during start() */
        !           691:        return(FALSE);
        !           692: 
        !           693:     while ( (ch = getc(fp_ttyi)) != EOF )
        !           694:        putc(ch, stdout);
        !           695:     return(FALSE);
        !           696: 
        !           697: }   /* End of readline */
        !           698: 
        !           699: /*****************************************************************************/
        !           700: 
        !           701: /*     @(#)strspn.c    1.2     */
        !           702: /*LINTLIBRARY*/
        !           703: /*
        !           704:  * Return the number of characters in the maximum leading segment
        !           705:  * of string which consists solely of characters from charset.
        !           706:  */
        !           707: int
        !           708: strspn(string, charset)
        !           709: char   *string;
        !           710: register char  *charset;
        !           711: {
        !           712:        register char *p, *q;
        !           713: 
        !           714:        for(q=string; *q != '\0'; ++q) {
        !           715:                for(p=charset; *p != '\0' && *p != *q; ++p)
        !           716:                        ;
        !           717:                if(*p == '\0')
        !           718:                        break;
        !           719:        }
        !           720:        return(q-string);
        !           721: }
        !           722: 
        !           723: /*     @(#)strpbrk.c   1.2     */
        !           724: /*LINTLIBRARY*/
        !           725: /*
        !           726:  * Return ptr to first occurance of any character from `brkset'
        !           727:  * in the character string `string'; NULL if none exists.
        !           728:  */
        !           729: 
        !           730: char *
        !           731: strpbrk(string, brkset)
        !           732: register char *string, *brkset;
        !           733: {
        !           734:        register char *p;
        !           735: 
        !           736:        do {
        !           737:                for(p=brkset; *p != '\0' && *p != *string; ++p)
        !           738:                        ;
        !           739:                if(*p != '\0')
        !           740:                        return(string);
        !           741:        }
        !           742:        while(*string++);
        !           743:        return((char*)0);
        !           744: }
        !           745: 
        !           746: /*     @(#)strtok.c    1.2     */
        !           747: /*     3.0 SID #       1.2     */
        !           748: /*LINTLIBRARY*/
        !           749: /*
        !           750:  * uses strpbrk and strspn to break string into tokens on
        !           751:  * sequentially subsequent calls.  returns NULL when no
        !           752:  * non-separator characters remain.
        !           753:  * `subsequent' calls are calls with first argument NULL.
        !           754:  */
        !           755: 
        !           756: 
        !           757: extern int strspn();
        !           758: extern char *strpbrk();
        !           759: 
        !           760: char *
        !           761: strtok(string, sepset)
        !           762: char   *string, *sepset;
        !           763: {
        !           764:        register char   *p, *q, *r;
        !           765:        static char     *savept;
        !           766: 
        !           767:        /*first or subsequent call*/
        !           768:        p = (string == (char*)0)? savept: string;
        !           769: 
        !           770:        if(p == 0)              /* return if no tokens remaining */
        !           771:                return((char*)0);
        !           772: 
        !           773:        q = p + strspn(p, sepset);      /* skip leading separators */
        !           774: 
        !           775:        if(*q == '\0')          /* return if no tokens remaining */
        !           776:                return((char*)0);
        !           777: 
        !           778:        if((r = strpbrk(q, sepset)) == (char*)0)        /* move past token */
        !           779:                savept = 0;     /* indicate this is last token */
        !           780:        else {
        !           781:                *r = '\0';
        !           782:                savept = ++r;
        !           783:        }
        !           784:        return(q);
        !           785: }
        !           786: #endif
        !           787: 
        !           788: /*****************************************************************************/
        !           789: 
        !           790: #ifdef DKHOST
        !           791: 
        !           792: #ifndef DKSTREAMS
        !           793: short  dkrmode[3] = {DKR_TIME, 0, 0};
        !           794: #endif
        !           795: 
        !           796: dkhost_connect()
        !           797: 
        !           798: {
        !           799: 
        !           800:     int                ofd;                    /* for saving and restoring stderr */
        !           801:     int                dfd;
        !           802:     int                retrytime = 5;
        !           803: 
        !           804: /*
        !           805:  *
        !           806:  * Tries to connect to a Datakit destination. The extra stuff I've added to save
        !           807:  * and later restore stderr is primarily for our spooling setup at Murray Hill.
        !           808:  * postio is usually called with stderr directed to a file that will be returned
        !           809:  * to the user when the job finishes printing. Problems encountered by dkdial(),
        !           810:  * like busy messages, go to stderr but don't belong in the user's mail. They'll
        !           811:  * be temporarily directed to the log file. After we've connected stderr will be
        !           812:  * restored.
        !           813:  *
        !           814:  */
        !           815: 
        !           816:     if ( *line == '\0' )
        !           817:        error(FATAL, "incomplete Datakit line");
        !           818: 
        !           819:     if ( fp_log != NULL && fp_log != stderr )  {       /* redirect dkdial errors */
        !           820:        ofd = dup(2);
        !           821:        close(2);
        !           822:        dup(fileno(fp_log));
        !           823:     }  /* End if */
        !           824: 
        !           825:     while ( (dfd = ttyi = dkdial(line)) < 0 )  {
        !           826:        if ( retrytime < 0 )
        !           827:            error(FATAL, "can't connect to %s", line);
        !           828:        sleep(retrytime++);
        !           829:        if ( retrytime > 60 )
        !           830:            retrytime = 60;
        !           831:     }  /* End while */
        !           832: 
        !           833:     if ( fp_log != NULL && fp_log != stderr )  {       /* restore stderr */
        !           834:        close(2);
        !           835:        dup(ofd);
        !           836:        close(ofd);
        !           837:     }  /* End if */
        !           838: 
        !           839: #ifndef DKSTREAMS
        !           840:     if ( ioctl(ttyi, DIOCRMODE, dkrmode) == -1 )
        !           841:        error(FATAL, "ioctl error - DIOCRMODE");
        !           842: 
        !           843: #ifdef DIOURPWD
        !           844:     if ( window_size > 0 ) {
        !           845:        short   dkparm[3];
        !           846: 
        !           847:        dkparm[0] = dkminor(ttyi);
        !           848:        dkparm[1] = 1;
        !           849:        dkparm[2] = window_size;
        !           850:        if ( ioctl(ttyi, DIOURPWD, dkparm) < 0 || ioctl(ttyi, DIOCFLUSH, 0) < 0 )
        !           851:            error(NON_FATAL, "WSA failed");
        !           852:     }  /* End if */
        !           853: #endif
        !           854: 
        !           855:     line = dtnamer(dkminor(ttyi));
        !           856: 
        !           857:     if ( (ttyi = open(line, O_RDWR)) == -1 )
        !           858:        error(FATAL, "can't open %s", line);
        !           859: 
        !           860:     close(dfd);
        !           861: #endif
        !           862: 
        !           863: }   /* End of dkhost_connect */
        !           864: #endif
        !           865: 
        !           866: /*****************************************************************************/
        !           867: 

unix.superglobalmegacorp.com

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