123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867 |
- /*
- *
- * Conditionally compiled routines for setting up and reading the line. Things
- * were getting out of hand with all the ifdefs, and even though this defeats
- * part of the purpose of conditional complilation directives, I think it's easier
- * to follow this way. Thanks to Alan Buckwalter for the System V DKHOST code.
- *
- * postio now can be run as separate read and write processes, but requires that
- * you write a procedure called resetline() and perhaps modify readline() some.
- * I've already tested the code on System V and it seems to work. Ninth Edition
- * and BSD code may be missing.
- *
- * By request I've changed the way some of the setupline() procedures (eg. in the
- * System V implementation) handle things when no line has been given. If line is
- * NULL the new setupline() procedures try to continue, assuming whoever called
- * postio connected stdout to the printer. Things will only work if we can read
- * and write stdout!
- *
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <errno.h>
- #include "ifdef.h" /* conditional header file inclusion */
- #include "gen.h" /* general purpose definitions */
- FILE *fp_ttyi, *fp_ttyo;
- char *ptr = mesg;
- extern int window_size;
- /*****************************************************************************/
- #ifdef SYSV
- setupline()
- {
- struct termio termio;
- /*
- *
- * Line initialization for SYSV. For now if no line is given (ie. line == NULL )
- * we continue on as before using stdout as ttyi and ttyo. Doesn't work when we're
- * running in interactive mode or forcing stuff that comes back from the printer
- * to stdout. Both cases are now caught by a test that's been added to routine
- * initialize(). The change is primarily for the version of lp that's available
- * with SVR3.2.
- *
- */
- #ifdef DKHOST
- if ( line != NULL && *line != '/' ) {
- if ( strncmp(line, "DK:", 3) == 0 )
- line += 3;
- dkhost_connect();
- #ifdef DKSTREAMS
- if ( ioctl(ttyi, I_PUSH, DKSTREAMS) == -1 )
- error(FATAL, "ioctl error - %s", DKSTREAMS);
- if ( ioctl(ttyi, I_PUSH, "ldterm") == -1 )
- error(FATAL, "ioctl error - ldterm");
- #endif
- } else
- #endif
- if ( line == NULL )
- ttyi = fileno(stdout);
- else if ( (ttyi = open(line, O_RDWR)) == -1 )
- error(FATAL, "can't open %s", line);
- if ( (ttyo = dup(ttyi)) == -1 )
- error(FATAL, "can't dup file descriptor for %s", line);
- if ( stopbits == 1 )
- stopbits = 0;
- else stopbits = CSTOPB;
- if ( fcntl(ttyi, F_SETFL, O_NDELAY) == -1 )
- error(FATAL, "fcntl error - F_SETFL");
- if ( ioctl(ttyi, TCGETA, &termio) == -1 )
- error(FATAL, "ioctl error - TCGETA");
- termio.c_iflag = IXON | IGNCR;
- termio.c_oflag = 0;
- termio.c_cflag = HUPCL | CREAD | CS8 | stopbits | baudrate;
- termio.c_lflag = 0;
- termio.c_cc[VMIN] = termio.c_cc[VTIME] = 0;
- if ( ioctl(ttyi, TCSETA, &termio) == -1 )
- error(FATAL, "ioctl error - TCSETA");
- if ( ioctl(ttyi, TCFLSH, 2) == -1 )
- error(FATAL, "ioctl error - TCFLSH");
- fp_ttyi = fdopen(ttyi, "r");
- } /* End of setupline */
- /*****************************************************************************/
- resetline()
- {
- int flags; /* for turning O_NDELAY off */
- struct termio termio; /* so we can reset flow control */
- /*
- *
- * Only used if we're running the program as separate read and write processes.
- * Called from split() after the initial connection has been made and returns
- * TRUE if two processes should work. Don't know if the O_NDELAY stuff is really
- * needed, but setting c_cc[VMIN] to 1 definitely is. If we leave it be (as a 0)
- * the read in readline() won't block!
- *
- */
- if ( (flags = fcntl(ttyi, F_GETFL, 0)) == -1 )
- error(FATAL, "fcntl error - F_GETFL");
- flags &= ~O_NDELAY;
- if ( fcntl(ttyi, F_SETFL, flags) == -1 )
- error(FATAL, "fcntl error - F_SETFL");
- if ( ioctl(ttyi, TCGETA, &termio) == -1 )
- error(FATAL, "ioctl error - TCGETA");
- termio.c_iflag &= ~IXANY;
- termio.c_iflag |= IXON | IXOFF;
- termio.c_cc[VMIN] = 1;
- termio.c_cc[VTIME] = 0;
- if ( ioctl(ttyi, TCSETA, &termio) == -1 )
- error(FATAL, "ioctl error - TCSETA");
- return(TRUE);
- } /* End of resetline */
- /*****************************************************************************/
- setupstdin(mode)
- int mode; /* what to do with stdin settings */
- {
- struct termio termio;
- static int saved = FALSE;
- static struct termio oldtermio;
- /*
- *
- * Save (mode = 0), reset (mode = 1), or restore (mode = 2) the tty settings for
- * stdin. Expect something like raw mode with no echo will be set up. Explicit
- * code to ensure blocking reads probably isn't needed because blocksize is set
- * to 1 when we're in interactive mode, but I've included it anyway.
- *
- */
- if ( interactive == TRUE )
- switch ( mode ) {
- case 0:
- if ( isatty(0) != 1 )
- error(FATAL, "stdin not a terminal - can't run interactive mode");
- if ( ioctl(0, TCGETA, &oldtermio) == -1 )
- error(FATAL, "can't save terminal settings");
- saved = TRUE;
- break;
- case 1:
- termio = oldtermio;
- termio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL);
- termio.c_cc[VMIN] = 1;
- termio.c_cc[VTIME] = 0;
- ioctl(0, TCSETA, &termio);
- break;
- case 2:
- if ( saved == TRUE )
- ioctl(0, TCSETA, &oldtermio);
- break;
- } /* End switch */
- } /* End of setupstdin */
- /*****************************************************************************/
- readline()
- {
- int n; /* read() return value */
- int ch; /* for interactive mode */
- static int tries = 0; /* consecutive times read returned 0 */
- /*
- *
- * Reads characters coming back from the printer on ttyi up to a newline (or EOF)
- * or until no more characters are available. Characters are put in mesg[], the
- * string is terminated with '\0' when we're done with a line and TRUE is returned
- * to the caller. If complete line wasn't available FALSE is returned. Interactive
- * mode should loop here forever, except during start(), echoing characters to
- * stdout. If it happens to leave FALSE should be returned. The non-blocking read
- * gets us out until split() is called.
- *
- * Some users (apparently just on 3B2 DKHOST systems) have had problems with the
- * two process implementation that's forced me to kludge things up some. When a
- * printer (on those systems) is turned off while postio is transmitting files
- * the write process hangs in writeblock() (postio.c) - it's typically in the
- * middle of a write() call, while the read() call (below) continually returns 0.
- * In the original code readline() returned FALSE when read() returned 0 and we
- * get into a loop that never ends - because the write process is hung. In the
- * one process implementation having read return 0 is legitimate because the line
- * is opened for no delay, but with two processes the read() blocks and a return
- * value of 0 should never occur. From my point of view the real problem is that
- * the write() call hangs on 3B2 DKHOST systems and apparently doesn't anywhere
- * else. If the write returned anything less than or equal to 0 writeblock() would
- * shut things down. The kludge I've implemented counts the number of consecutive
- * times read() returns a 0 and if it exceeds a limit (100) the read process will
- * shut things down. In fact one return of 0 from read() when we're in the two
- * process mode is undoubtedly sufficient and no counting should be necessary!!!
- * Moving the check to getstatus() should also work and is probably where things
- * belong.
- *
- */
- if ( interactive == FALSE ) {
- while ( (n = read(ttyi, ptr, 1)) != 0 ) {
- if ( n < 0 )
- if ( errno == EINTR )
- continue;
- else error(FATAL, "error reading %s", line);
- tries = 0;
- if ( *ptr == '\n' || *ptr == '\004' || ptr >= endmesg ) {
- *(ptr+1) = '\0';
- if ( *ptr == '\004' )
- strcpy(ptr, "%%[ status: endofjob ]%%\n");
- ptr = mesg;
- return(TRUE);
- } /* End if */
- ptr++;
- } /* End while */
- if ( canread == TRUE && canwrite == FALSE ) /* read process kludge */
- if ( ++tries > 100 )
- error(FATAL, "printer appears to be offline - shutting down");
- return(FALSE);
- } /* End if */
- if ( canwrite == TRUE ) /* don't block during start() */
- return(FALSE);
- while ( (ch = getc(fp_ttyi)) != EOF )
- putc(ch, stdout);
- return(FALSE);
- } /* End of readline */
- #endif
- /*****************************************************************************/
- #ifdef V9
- #include <ipc.h>
- char tbuf[256]; /* temporary input buffer */
- char *nptr = tbuf; /* next character comes from here */
- char *eptr = tbuf; /* one past the last character in tbuf */
- setupline()
- {
- struct sgttyb sgtty;
- struct ttydevb ttydev; /* for setting up the line */
- static struct tchars tchar = { '\377', /* interrupt */
- '\377', /* quit */
- '\021', /* start output */
- '\023', /* stop output */
- '\377', /* end-of-file */
- '\377' /* input delimiter */
- };
- /*
- *
- * Line initialization for V9.
- *
- */
- if ( line == NULL ) {
- ttyi = ttyo = 1;
- return;
- } /* End if */
- alarm(120); /* watch for hanging opens */
- if ( line[0] == '/' ) {
- if ( (ttyi = open(line, O_RDWR)) == -1 )
- error(FATAL, "can't open %s", line);
- } else if ((ttyi = ipcopen(ipcpath(line, "dk", 0), "")) < 0) {
- sleep(5); /* wait for Datakit to hangup */
- if ((ttyi = ipcopen(ipcpath(line, "dk", 0), "")) < 0) {
- fprintf(stderr, "%s", errstr);
- error(FATAL, "can't ipcopen %s", line);
- }
- }
- alarm(0);
- if ( (ttyo = dup(ttyi)) == -1 )
- error(FATAL, "can't dup file descriptor for %s", line);
- if ( ioctl(ttyi, FIOPUSHLD, &tty_ld) == -1 )
- error(FATAL, "ioctl error - FIOPUSHLD");
- if ( ioctl(ttyi, TIOCGDEV, &ttydev) == -1 )
- error(FATAL, "ioctl error - TIOCGDEV");
- if ( ioctl(ttyi, TIOCGETP, &sgtty) == -1 )
- error(FATAL, "ioctl error - TIOCGETP");
- sgtty.sg_flags &= ~ECHO;
- sgtty.sg_flags &= ~CRMOD;
- sgtty.sg_flags |= CBREAK;
- ttydev.ispeed = baudrate;
- ttydev.ospeed = baudrate;
- if ( ioctl(ttyi, TIOCSDEV, &ttydev) == -1 )
- error(FATAL, "ioctl error - TIOCSDEV");
- if ( ioctl(ttyi, TIOCSETP, &sgtty) == -1 )
- error(FATAL, "ioctl error - TIOCSETP");
- if ( ioctl(ttyi, TIOCSETC, &tchar) == -1 )
- error(FATAL, "ioctl error - TIOCSETC");
- fp_ttyi = fdopen(ttyi, "r");
- } /* End of setupline */
- /*****************************************************************************/
- resetline()
- {
- struct sgttyb sgtty;
- /*
- *
- * Only used if we're running the program as separate read and write processes.
- * Called from split() after the initial connection has been made and returns
- * TRUE if two processes should work. Haven't tested or even compiled the stuff
- * for separate read and write processes on Ninth Edition systems - no guarantees
- * even though we return TRUE!
- *
- */
- if ( ioctl(ttyi, TIOCGETP, &sgtty) == -1 )
- error(FATAL, "ioctl error - TIOCGETP");
- sgtty.sg_flags |= TANDEM;
- if ( ioctl(ttyi, TIOCSETP, &sgtty) == -1 )
- error(FATAL, "ioctl error - TIOCSETP");
- return(TRUE);
- } /* End of resetline */
- /*****************************************************************************/
- setupstdin(mode)
- int mode; /* what to do with stdin settings */
- {
- struct sgttyb sgtty;
- static int saved = FALSE;
- static struct sgttyb oldsgtty;
- /*
- *
- * Save (mode = 0), reset (mode = 1), or restore (mode = 2) the tty settings for
- * stdin. Expect something like raw mode with no echo will be set up. Need to make
- * sure interrupt and quit still work - they're the only good way to exit when
- * we're running interactive mode. I haven't tested or even compiled this code
- * so there are no guarantees.
- *
- */
- if ( interactive == TRUE )
- switch ( mode ) {
- case 0:
- if ( ioctl(0, TIOCGETP, &oldsgtty) == -1 )
- error(FATAL, "can't save terminal settings");
- saved = TRUE;
- break;
- case 1:
- sgtty = oldsgtty;
- sgtty.sg_flags &= ~ECHO;
- sgtty.sg_flags |= CBREAK;
- ioctl(0, TIOCSETP, &sgtty);
- break;
- case 2:
- if ( saved == TRUE )
- ioctl(0, TIOCSETP, &oldsgtty);
- break;
- } /* End switch */
- } /* End of setupstdin */
- /*****************************************************************************/
- readline()
- {
- int n; /* read() return value */
- int ch; /* for interactive mode */
- /*
- *
- * Reads characters coming back from the printer on ttyi up to a newline (or EOF)
- * and transfers each line to the mesg[] array. Everything available on ttyi is
- * initially stored in tbuf[] and a line at a time is transferred from there to
- * mesg[]. The string in mesg[] is terminated with a '\0' and TRUE is returned to
- * the caller when we find a newline, EOF, or reach the end of the mesg[] array.
- * If nothing is available on ttyi we return FALSE if a single process is being
- * used for reads and writes, while in the two process implementation we force a
- * one character read. Interactive mode loops here forever, except during start(),
- * echoing everything that comes back on ttyi to stdout. The performance of a
- * simple getc/putc loop for interactive mode was unacceptable when run under mux
- * and has been replaced by more complicated code. When layers wasn't involved
- * the getc/putc loop worked well.
- *
- */
- if ( interactive == FALSE ) {
- while ( 1 ) {
- while ( nptr < eptr ) { /* grab characters from tbuf */
- *ptr = *nptr++;
- if ( *ptr == '\r' ) continue;
- if ( *ptr == '\n' || *ptr == '\004' || ptr >= endmesg ) {
- *(ptr+1) = '\0';
- if ( *ptr == '\004' )
- strcpy(ptr, "%%[ status: endofjob ]%%\n");
- ptr = mesg;
- return(TRUE);
- } /* End if */
- ++ptr;
- } /* End for */
- nptr = eptr = tbuf;
- if ( ioctl(ttyi, FIONREAD, &n) < 0 )
- if ( errno == EINTR )
- continue;
- else error(FATAL, "ioctl error - FIONREAD");
- if ( n <= 0 )
- if ( canwrite == TRUE )
- return(FALSE);
- n = ((n < 1) ? 1 : ((n < sizeof(tbuf)) ? n : sizeof(tbuf)));
- if ( (n = read(ttyi, tbuf, n)) < 0 )
- if ( errno == EINTR )
- continue;
- else error(FATAL, "error reading line %s", line);
- else eptr = nptr + n;
- } /* End while */
- } /* End if */
- if ( canwrite == TRUE ) /* don't block during start() */
- return(FALSE);
- while ( 1 ) { /* only interactive mode gets here */
- if ( ioctl(ttyi, FIONREAD, &n) < 0 )
- error(FATAL, "ioctl error - FIONREAD");
- n = ((n < 1) ? 1 : ((n < sizeof(tbuf)) ? n : sizeof(tbuf)));
- if ( (n = read(ttyi, tbuf, n)) < 0 )
- error(FATAL, "error reading line %s", line);
- else if ( n == 0 ) /* should not happen */
- error(FATAL, "end of file in interactive mode");
- if ( write(1, tbuf, n) != n )
- error(FATAL, "error writing to stdout");
- } /* End while */
- return(FALSE);
- } /* End of readline */
- #endif
- /*****************************************************************************/
- #ifdef BSD4_2
- setupline()
- {
- struct sgttyb sgtty;
- static struct tchars tchar = { '\377', /* interrupt */
- '\377', /* quit */
- '\021', /* start output */
- '\023', /* stop output */
- '\377', /* end-of-file */
- '\377' /* input delimiter */
- };
- long lmodes;
- int disc = NTTYDISC;
- /*
- *
- * Line initialization for BSD4_2. As in the System V code, if no line is given
- * (ie. line == NULL) we continue on as before using stdout as ttyi and ttyo.
- *
- */
- if ( line == NULL )
- ttyi = fileno(stdout);
- else if ( (ttyi = open(line, O_RDWR)) == -1 )
- error(FATAL, "can't open %s", line);
- if ( (ttyo = dup(ttyi)) == -1 )
- error(FATAL, "can't dup file descriptor for %s", line);
- if (ioctl(ttyi, TIOCSETD, &disc) == -1 )
- error(FATAL, "ioctl error - TIOCSETD");
- if ( ioctl(ttyi, TIOCGETP, &sgtty) == -1 )
- error(FATAL, "ioctl error - TIOCGETP");
- if ( ioctl(ttyi, TIOCLGET, &lmodes) == -1 )
- error(FATAL, "ioctl error - TIOCLGET");
- sgtty.sg_flags &= ~ECHO;
- sgtty.sg_flags &= ~CRMOD;
- sgtty.sg_flags |= CBREAK;
- sgtty.sg_ispeed = baudrate;
- sgtty.sg_ospeed = baudrate;
- lmodes |= LDECCTQ;
- if ( ioctl(ttyi, TIOCSETP, &sgtty) == -1 )
- error(FATAL, "ioctl error - TIOCSETP");
- if ( ioctl(ttyi, TIOCSETC, &tchar) == -1 )
- error(FATAL, "ioctl error - TIOCSETC");
- if ( ioctl(ttyi, TIOCLSET, &lmodes) == -1 )
- error(FATAL, "ioctl error - TIOCLSET");
- fp_ttyi = fdopen(ttyi, "r");
- } /* End of setupline */
- /*****************************************************************************/
- resetline()
- {
- struct sgttyb sgtty;
- /*
- *
- * Only used if we're running the program as separate read and write processes.
- * Called from split() after the initial connection has been made and returns
- * TRUE if two processes should work. Haven't tested or even compiled the stuff
- * for separate read and write processes on Berkeley systems - no guarantees
- * even though we return TRUE!
- *
- */
- if ( ioctl(ttyi, TIOCGETP, &sgtty) == -1 )
- error(FATAL, "ioctl error - TIOCGETP");
- sgtty.sg_flags |= TANDEM;
- if ( ioctl(ttyi, TIOCSETP, &sgtty) == -1 )
- error(FATAL, "ioctl error - TIOCSETP");
- return(TRUE);
- } /* End of resetline */
- /*****************************************************************************/
- setupstdin(mode)
- int mode; /* what to do with stdin settings */
- {
- struct sgttyb sgtty;
- static int saved = FALSE;
- static struct sgttyb oldsgtty;
- /*
- *
- * Save (mode = 0), reset (mode = 1), or restore (mode = 2) the tty settings for
- * stdin. Expect something like raw mode with no echo will be set up. Need to make
- * sure interrupt and quit still work - they're the only good way to exit when
- * we're running interactive mode. I haven't tested or even compiled this code
- * so there are no guarantees.
- *
- */
- if ( interactive == TRUE )
- switch ( mode ) {
- case 0:
- if ( isatty(0) != 1 )
- error(FATAL, "stdin not a terminal - can't run interactive mode");
- if ( ioctl(0, TIOCGETP, &oldsgtty) == -1 )
- error(FATAL, "can't save terminal settings");
- saved = TRUE;
- break;
- case 1:
- sgtty = oldsgtty;
- sgtty.sg_flags &= ~ECHO;
- sgtty.sg_flags |= CBREAK;
- ioctl(0, TIOCSETP, &sgtty);
- break;
- case 2:
- if ( saved == TRUE )
- ioctl(0, TIOCSETP, &oldsgtty);
- break;
- } /* End switch */
- } /* End of setupstdin */
- /*****************************************************************************/
- readline()
- {
- int n; /* read() return value */
- int ch; /* for interactive mode */
- /*
- *
- * Reads characters coming back from the printer on ttyo up to a newline (or EOF)
- * or until no more characters are available. Characters are put in mesg[], the
- * string is terminated with '\0' when we're done with a line and TRUE is returned
- * to the caller. If complete line wasn't available FALSE is returned. Interactive
- * mode should loop here forever, except during start(), echoing characters to
- * stdout. If it happens to leave FALSE should be returned. Probably should read
- * everything available on ttyi into a temporary buffer and work from there rather
- * than reading one character at a time.
- *
- */
- if ( interactive == FALSE ) {
- while ( 1 ) {
- if ( ioctl(ttyi, FIONREAD, &n) < 0 )
- if ( errno == EINTR )
- continue;
- else error(FATAL, "ioctl error - FIONREAD");
- if ( n <= 0 )
- if ( canwrite == TRUE )
- return(FALSE);
- else n = 1;
- for ( ; n > 0; n-- ) {
- /*if ( read(ttyi, ptr, 1) < 0 )*/
- if ( (*ptr = getc(fp_ttyi)) == EOF )
- if ( errno == EINTR )
- continue;
- else error(FATAL, "error reading %s", line);
- if ( *ptr == '\r' ) continue;
- if ( *ptr == '\n' || *ptr == '\004' || ptr >= endmesg ) {
- *(ptr+1) = '\0';
- if ( *ptr == '\004' )
- strcpy(ptr, "%%[ status: endofjob ]%%\n");
- ptr = mesg;
- return(TRUE);
- } /* End if */
- ++ptr;
- } /* End for */
- } /* End while */
- } /* End if */
- if ( canwrite == TRUE ) /* don't block during start() */
- return(FALSE);
- while ( (ch = getc(fp_ttyi)) != EOF )
- putc(ch, stdout);
- return(FALSE);
- } /* End of readline */
- /*****************************************************************************/
- /* @(#)strspn.c 1.2 */
- /*LINTLIBRARY*/
- /*
- * Return the number of characters in the maximum leading segment
- * of string which consists solely of characters from charset.
- */
- int
- strspn(string, charset)
- char *string;
- register char *charset;
- {
- register char *p, *q;
- for(q=string; *q != '\0'; ++q) {
- for(p=charset; *p != '\0' && *p != *q; ++p)
- ;
- if(*p == '\0')
- break;
- }
- return(q-string);
- }
- /* @(#)strpbrk.c 1.2 */
- /*LINTLIBRARY*/
- /*
- * Return ptr to first occurance of any character from `brkset'
- * in the character string `string'; NULL if none exists.
- */
- char *
- strpbrk(string, brkset)
- register char *string, *brkset;
- {
- register char *p;
- do {
- for(p=brkset; *p != '\0' && *p != *string; ++p)
- ;
- if(*p != '\0')
- return(string);
- }
- while(*string++);
- return((char*)0);
- }
- /* @(#)strtok.c 1.2 */
- /* 3.0 SID # 1.2 */
- /*LINTLIBRARY*/
- /*
- * uses strpbrk and strspn to break string into tokens on
- * sequentially subsequent calls. returns NULL when no
- * non-separator characters remain.
- * `subsequent' calls are calls with first argument NULL.
- */
- extern int strspn();
- extern char *strpbrk();
- char *
- strtok(string, sepset)
- char *string, *sepset;
- {
- register char *p, *q, *r;
- static char *savept;
- /*first or subsequent call*/
- p = (string == (char*)0)? savept: string;
- if(p == 0) /* return if no tokens remaining */
- return((char*)0);
- q = p + strspn(p, sepset); /* skip leading separators */
- if(*q == '\0') /* return if no tokens remaining */
- return((char*)0);
- if((r = strpbrk(q, sepset)) == (char*)0) /* move past token */
- savept = 0; /* indicate this is last token */
- else {
- *r = '\0';
- savept = ++r;
- }
- return(q);
- }
- #endif
- /*****************************************************************************/
- #ifdef DKHOST
- #ifndef DKSTREAMS
- short dkrmode[3] = {DKR_TIME, 0, 0};
- #endif
- dkhost_connect()
- {
- int ofd; /* for saving and restoring stderr */
- int dfd;
- int retrytime = 5;
- /*
- *
- * Tries to connect to a Datakit destination. The extra stuff I've added to save
- * and later restore stderr is primarily for our spooling setup at Murray Hill.
- * postio is usually called with stderr directed to a file that will be returned
- * to the user when the job finishes printing. Problems encountered by dkdial(),
- * like busy messages, go to stderr but don't belong in the user's mail. They'll
- * be temporarily directed to the log file. After we've connected stderr will be
- * restored.
- *
- */
- if ( *line == '\0' )
- error(FATAL, "incomplete Datakit line");
- if ( fp_log != NULL && fp_log != stderr ) { /* redirect dkdial errors */
- ofd = dup(2);
- close(2);
- dup(fileno(fp_log));
- } /* End if */
- while ( (dfd = ttyi = dkdial(line)) < 0 ) {
- if ( retrytime < 0 )
- error(FATAL, "can't connect to %s", line);
- sleep(retrytime++);
- if ( retrytime > 60 )
- retrytime = 60;
- } /* End while */
- if ( fp_log != NULL && fp_log != stderr ) { /* restore stderr */
- close(2);
- dup(ofd);
- close(ofd);
- } /* End if */
- #ifndef DKSTREAMS
- if ( ioctl(ttyi, DIOCRMODE, dkrmode) == -1 )
- error(FATAL, "ioctl error - DIOCRMODE");
- #ifdef DIOURPWD
- if ( window_size > 0 ) {
- short dkparm[3];
- dkparm[0] = dkminor(ttyi);
- dkparm[1] = 1;
- dkparm[2] = window_size;
- if ( ioctl(ttyi, DIOURPWD, dkparm) < 0 || ioctl(ttyi, DIOCFLUSH, 0) < 0 )
- error(NON_FATAL, "WSA failed");
- } /* End if */
- #endif
- line = dtnamer(dkminor(ttyi));
- if ( (ttyi = open(line, O_RDWR)) == -1 )
- error(FATAL, "can't open %s", line);
- close(dfd);
- #endif
- } /* End of dkhost_connect */
- #endif
- /*****************************************************************************/
|