ifdef.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1996 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.2 */
/*
*
* 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 <errno.h>
#include "ifdef.h" /* conditional header file inclusion */
#include "gen.h" /* general purpose definitions */
/*****************************************************************************/
#ifdef SYSV
{
char buf[100];
/*
*
* 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
line += 3;
} else
#endif
}
}
}
}
}
} else {
}
}
}
line = "stdout";
}
} /* End of setupline */
/*****************************************************************************/
{
int flags; /* for turning O_NDELAY off */
/*
*
* 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!
*
*/
return(TRUE);
} /* End of resetline */
/*****************************************************************************/
int mode; /* what to do with stdin settings */
{
/*
*
* 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 )
break;
case 1:
break;
case 2:
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 ) {
if ( n < 0 )
continue;
tries = 0;
if ( *ptr == '\004' )
return(TRUE);
} /* End if */
ptr++;
} /* End while */
if ( ++tries > 100 )
return(FALSE);
} /* End if */
return(FALSE);
return(FALSE);
} /* End of readline */
#endif
/*****************************************************************************/
#ifdef V9
#include <ipc.h>
{
'\377', /* quit */
'\021', /* start output */
'\023', /* stop output */
'\377', /* end-of-file */
'\377' /* input delimiter */
};
/*
*
* Line initialization for V9.
*
*/
return;
} /* End if */
}
} /* End of setupline */
/*****************************************************************************/
{
/*
*
* 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!
*
*/
return(TRUE);
} /* End of resetline */
/*****************************************************************************/
int mode; /* what to do with stdin settings */
{
/*
*
* 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:
break;
case 1:
break;
case 2:
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
* and has been replaced by more complicated code. When layers wasn't involved
*
*/
if ( interactive == FALSE ) {
while ( 1 ) {
if ( *ptr == '\r' ) continue;
if ( *ptr == '\004' )
return(TRUE);
} /* End if */
++ptr;
} /* End for */
continue;
if ( n <= 0 )
return(FALSE);
continue;
} /* End while */
} /* End if */
return(FALSE);
while ( 1 ) { /* only interactive mode gets here */
else if ( n == 0 ) /* should not happen */
} /* End while */
return(FALSE);
} /* End of readline */
#endif
/*****************************************************************************/
#ifdef BSD4_2
{
'\377', /* quit */
'\021', /* start output */
'\023', /* stop output */
'\377', /* end-of-file */
'\377' /* input delimiter */
};
long lmodes;
/*
*
* 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.
*
*/
} /* End of setupline */
/*****************************************************************************/
{
/*
*
* 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!
*
*/
return(TRUE);
} /* End of resetline */
/*****************************************************************************/
int mode; /* what to do with stdin settings */
{
/*
*
* 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 )
break;
case 1:
break;
case 2:
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 ) {
continue;
if ( n <= 0 )
return(FALSE);
else n = 1;
for ( ; n > 0; n-- ) {
/*if ( read(ttyi, ptr, 1) < 0 )*/
continue;
if ( *ptr == '\r' ) continue;
if ( *ptr == '\004' )
return(TRUE);
} /* End if */
++ptr;
} /* End for */
} /* End while */
} /* End if */
return(FALSE);
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
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 *
{
register char *p;
do {
;
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 *
{
register char *p, *q, *r;
static char *savept;
/*first or subsequent call*/
if(p == 0) /* return if no tokens remaining */
return((char*)0);
if(*q == '\0') /* return if no tokens remaining */
return((char*)0);
savept = 0; /* indicate this is last token */
else {
*r = '\0';
savept = ++r;
}
return(q);
}
#endif
/*****************************************************************************/
#ifdef DKHOST
{
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' )
close(2);
} /* End if */
if ( retrytime < 0 )
if ( retrytime > 60 )
retrytime = 60;
} /* End while */
close(2);
} /* End if */
} /* End of dkhost_connect */
#endif
/*****************************************************************************/