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

unix.superglobalmegacorp.com

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