home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.unix
- From: panos@cs.colorado.edu (Panos Tsirigotis)
- Subject: v26i269: xinetd-2.1.1 - inetd replacement with access control and logging, Part25/31
- Sender: unix-sources-moderator@gw.home.vix.com
- Approved: vixie@gw.home.vix.com
-
- Submitted-By: panos@cs.colorado.edu (Panos Tsirigotis)
- Posting-Number: Volume 26, Issue 269
- Archive-Name: xinetd-2.1.1/part25
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 25 (of 31)."
- # Contents: libs/src/sio/sio.c
- # Wrapped by panos@mystique on Mon Jun 21 14:51:27 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'libs/src/sio/sio.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/sio/sio.c'\"
- else
- echo shar: Extracting \"'libs/src/sio/sio.c'\" \(15212 characters\)
- sed "s/^X//" >'libs/src/sio/sio.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
- X * All rights reserved. The file named COPYRIGHT specifies the terms
- X * and conditions for redistribution.
- X */
- X
- Xstatic char RCSid[] = "$Id: sio.c,v 8.1 1993/03/13 01:15:55 panos Exp $" ;
- Xstatic char sio_version[] = VERSION ;
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#include "sio.h"
- X#include "impl.h"
- X
- X#ifdef EVENTS
- X#include "events.h"
- X#endif
- X
- X/*
- X * SIO WRITE FUNCTIONS: Swrite, Sputc
- X */
- X
- X/*
- X * Stream write call: arguments same as those of write(2)
- X */
- Xint Swrite( fd, addr, nbytes )
- X int fd ;
- X register char *addr ;
- X register int nbytes ;
- X{
- X register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
- X register __sio_od_t *odp = ODP( dp ) ;
- X register int b_transferred ;
- X register int b_avail ;
- X int total_b_transferred ;
- X int b_written ;
- X int b_in_buffer ;
- X
- X#ifdef EVENTS
- X EVENT( fd, EV_SWRITE ) ;
- X#endif
- X
- X IO_SETUP( fd, dp, __SIO_OUTPUT_STREAM, SIO_ERR ) ;
- X ASSERT( odp->start <= odp->nextb && odp->nextb <= odp->buf_end ) ;
- X
- X b_avail = odp->buf_end - odp->nextb ;
- X b_transferred = MIN( nbytes, b_avail ) ;
- X sio_memcopy( addr, odp->nextb, b_transferred ) ;
- X odp->nextb += b_transferred ;
- X
- X /*
- X * check if we are done
- X */
- X if ( b_transferred == nbytes )
- X return( b_transferred ) ;
- X
- X /*
- X * at this point we know that the buffer is full
- X */
- X b_in_buffer = odp->buf_end - odp->start ;
- X b_written = __sio_writef( odp, fd ) ;
- X if ( b_written != b_in_buffer )
- X return( (b_written >= nbytes) ? nbytes : b_written ) ;
- X
- X total_b_transferred = b_transferred ;
- X addr += b_transferred ;
- X nbytes -= b_transferred ;
- X
- X for ( ;; )
- X {
- X b_transferred = MIN( nbytes, odp->buffer_size ) ;
- X sio_memcopy( addr, odp->nextb, b_transferred ) ;
- X odp->nextb += b_transferred ;
- X nbytes -= b_transferred ;
- X if ( nbytes == 0 )
- X {
- X total_b_transferred += b_transferred ;
- X break ;
- X }
- X /*
- X * the buffer is full
- X */
- X b_written = __sio_writef( odp, fd ) ;
- X if ( b_written != odp->buffer_size )
- X {
- X if ( b_written != SIO_ERR )
- X {
- X total_b_transferred += b_written ;
- X odp->nextb += b_written ;
- X }
- X break ;
- X }
- X /*
- X * everything is ok
- X */
- X total_b_transferred += b_transferred ;
- X addr += b_transferred ;
- X }
- X return( total_b_transferred ) ;
- X}
- X
- X
- X/*
- X * Add a character to a file
- X */
- Xint Sputc( fd, c )
- X int fd ;
- X char c ;
- X{
- X register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
- X register __sio_od_t *odp = ODP( dp ) ;
- X
- X#ifdef EVENTS
- X EVENT( fd, EV_SPUTC ) ;
- X#endif
- X
- X IO_SETUP( fd, dp, __SIO_OUTPUT_STREAM, SIO_ERR ) ;
- X ASSERT( odp->start <= odp->nextb && odp->nextb <= odp->buf_end ) ;
- X
- X /*
- X * The following is a weak check since we should really be
- X * checking that nextb == buf_end (it would be an error for
- X * nextb to exceed buf_end; btw, the assertion above, when
- X * enabled makes sure this does not occur).
- X *
- X * NOTE: __sio_writef NEVER uses data beyond the end of buffer.
- X */
- X if ( odp->nextb >= odp->buf_end )
- X {
- X int b_in_buffer = odp->buf_end - odp->start ;
- X
- X /*
- X * There is nothing we can do if __sio_writef does not manage
- X * to write the whole buffer
- X */
- X if ( __sio_writef( odp, fd ) != b_in_buffer )
- X return( SIO_ERR ) ;
- X }
- X *odp->nextb++ = c ;
- X if ( __SIO_MUST_FLUSH( *odp, c ) && __sio_writef( odp, fd ) == SIO_ERR )
- X return( SIO_ERR ) ;
- X return ( c ) ;
- X}
- X
- X
- X
- X/*
- X * SIO READ FUNCTIONS
- X */
- X
- X/*
- X * Stream read call: arguments same as those of read(2)
- X */
- Xint Sread( fd, addr, nbytes )
- X int fd ;
- X char *addr ;
- X int nbytes ;
- X{
- X register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
- X register __sio_id_t *idp = IDP( dp ) ;
- X register int b_transferred ;
- X int b_read ;
- X int total_b_transferred ;
- X int b_left ;
- X
- X#ifdef EVENTS
- X EVENT( fd, EV_SREAD ) ;
- X#endif
- X
- X IO_SETUP( fd, dp, __SIO_INPUT_STREAM, SIO_ERR ) ;
- X ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
- X
- X b_left = idp->end - idp->nextb ;
- X b_transferred = MIN( b_left, nbytes ) ;
- X sio_memcopy( idp->nextb, addr, b_transferred ) ;
- X idp->nextb += b_transferred ;
- X if ( b_transferred == nbytes )
- X return( b_transferred ) ;
- X
- X nbytes -= b_transferred ;
- X total_b_transferred = b_transferred ;
- X addr += b_transferred ;
- X
- X do
- X {
- X b_read = __sio_readf( idp, fd ) ;
- X switch ( b_read )
- X {
- X case SIO_ERR:
- X if ( total_b_transferred == 0 )
- X return( SIO_ERR ) ;
- X /* FALL THROUGH */
- X
- X case 0:
- X return( total_b_transferred ) ;
- X }
- X
- X b_transferred = MIN( b_read, nbytes ) ;
- X sio_memcopy( idp->nextb, addr, b_transferred ) ;
- X addr += b_transferred ;
- X idp->nextb += b_transferred ;
- X total_b_transferred += b_transferred ;
- X nbytes -= b_transferred ;
- X }
- X while ( nbytes && b_read == idp->buffer_size ) ;
- X return( total_b_transferred ) ;
- X}
- X
- X
- X
- X/*
- X * Read a line from a file
- X * Returns a pointer to the beginning of the line or NULL
- X */
- Xchar *Srdline( fd )
- X int fd ;
- X{
- X register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
- X register __sio_id_t *idp = IDP( dp ) ;
- X register char *cp ;
- X register char *line_start ;
- X register int b_left ;
- X register int extension ;
- X
- X#ifdef EVENTS
- X EVENT( fd, EV_SRDLINE ) ;
- X#endif
- X
- X IO_SETUP( fd, dp, __SIO_INPUT_STREAM, NULL ) ;
- X ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
- X
- X#ifdef HAS_MMAP
- X if ( idp->memory_mapped && __sio_switch( idp, fd ) == FAILURE )
- X return( NULL ) ;
- X#endif
- X
- X b_left = idp->end - idp->nextb ;
- X /*
- X * Look for a '\n'. If the search fails, extend the buffer
- X * and search again (the extension is performed by copying the
- X * bytes that were searched to the auxiliary buffer and reading
- X * new input in the main buffer).
- X * If the new input still does not contain a '\n' and there is
- X * more space in the main buffer (this can happen with network
- X * connections), read more input until either the buffer is full
- X * or a '\n' is found.
- X * Finally, set cp to point to the '\n', and line_start to
- X * the beginning of the line
- X */
- X if ( b_left && ( cp = sio_memscan( idp->nextb, b_left, '\n' ) ) != NULL )
- X {
- X line_start = idp->nextb ;
- X idp->nextb = cp + 1 ;
- X }
- X else
- X {
- X extension = __sio_extend_buffer( idp, fd, b_left ) ;
- X if ( extension > 0 )
- X {
- X ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
- X
- X line_start = idp->start ;
- X cp = sio_memscan( idp->nextb, extension, '\n' ) ;
- X if ( cp != NULL )
- X idp->nextb = cp + 1 ;
- X else
- X for ( ;; )
- X {
- X idp->nextb = idp->end ;
- X extension = __sio_more( idp, fd ) ;
- X if ( extension > 0 )
- X {
- X cp = sio_memscan( idp->nextb, extension, '\n' ) ;
- X if ( cp == NULL )
- X continue ;
- X idp->nextb = cp + 1 ;
- X break ;
- X }
- X else
- X {
- X /*
- X * If there is spare room in the buffer avoid trashing
- X * the last character
- X */
- X if ( idp->end < &idp->buf[ idp->buffer_size ] )
- X cp = idp->end ;
- X else
- X cp = &idp->buf[ idp->buffer_size - 1 ] ;
- X break ;
- X }
- X }
- X }
- X else /* buffer could not be extended */
- X if ( b_left == 0 )
- X {
- X /*
- X * Set errno to 0 if EOF has been reached
- X */
- X if ( extension == 0 )
- X errno = 0 ;
- X return( NULL ) ;
- X }
- X else
- X {
- X line_start = idp->start ;
- X cp = idp->end ;
- X /*
- X * By setting idp->nextb to be equal to idp->end,
- X * subsequent calls to Srdline will return NULL because
- X * __sio_extend_buffer will be invoked and it will return 0.
- X */
- X idp->nextb = idp->end ;
- X }
- X }
- X *cp = NUL ;
- X idp->line_length = cp - line_start ;
- X return( line_start ) ;
- X}
- X
- X
- X/*
- X * Get a character from a file
- X */
- Xint Sgetc( fd )
- X int fd ;
- X{
- X register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
- X register __sio_id_t *idp = IDP( dp ) ;
- X
- X#ifdef EVENTS
- X EVENT( fd, EV_SGETC ) ;
- X#endif
- X
- X IO_SETUP( fd, dp, __SIO_INPUT_STREAM, SIO_ERR ) ;
- X ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
- X if ( idp->nextb >= idp->end )
- X {
- X register int b_read = __sio_readf( idp, fd ) ;
- X
- X if ( b_read == 0 )
- X return( SIO_EOF ) ;
- X else if ( b_read == SIO_ERR )
- X return( SIO_ERR ) ;
- X }
- X return( (int) *idp->nextb++ ) ;
- X}
- X
- X
- Xchar *Sfetch( fd, lenp )
- X int fd ;
- X long *lenp ;
- X{
- X register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
- X register __sio_id_t *idp = IDP( dp ) ;
- X register int b_read ;
- X register char *p ;
- X
- X#ifdef EVENTS
- X EVENT( fd, EV_SFETCH ) ;
- X#endif
- X
- X IO_SETUP( fd, dp, __SIO_INPUT_STREAM, NULL ) ;
- X ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
- X if ( idp->nextb >= idp->end )
- X {
- X b_read = __sio_readf( idp, fd ) ;
- X if ( b_read == SIO_ERR )
- X return( NULL ) ;
- X if ( b_read == 0 )
- X {
- X errno = 0 ;
- X return( NULL ) ;
- X }
- X }
- X *lenp = idp->end - idp->nextb ;
- X p = idp->nextb ;
- X idp->nextb = idp->end ;
- X return( p ) ;
- X}
- X
- X
- X
- X/*
- X * SIO CONTROL FUNCTIONS
- X */
- X
- X/*
- X * Undo the last Srdline or Sgetc
- X */
- Xint Sundo( fd, type )
- X int fd ;
- X int type ;
- X{
- X register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
- X register __sio_id_t *idp = IDP( dp ) ;
- X int retval = 0 ;
- X
- X#ifdef EVENTS
- X EVENT( fd, EV_SUNDO ) ;
- X#endif
- X
- X CONTROL_SETUP( dp, __SIO_INPUT_STREAM, SIO_ERR ) ;
- X
- X /*
- X * Undo works only for fd's used for input
- X */
- X if ( dp->stream_type != __SIO_INPUT_STREAM )
- X return( SIO_ERR ) ;
- X
- X /*
- X * Check if the operation makes sense; if so, do it, otherwise ignore it
- X */
- X switch ( type )
- X {
- X case SIO_UNDO_LINE:
- X if ( idp->nextb - idp->line_length > idp->start )
- X {
- X *--idp->nextb = '\n' ;
- X idp->nextb -= idp->line_length ;
- X }
- X ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
- X break ;
- X
- X case SIO_UNDO_CHAR:
- X if ( idp->nextb > idp->start )
- X idp->nextb-- ;
- X ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;
- X break ;
- X
- X default:
- X retval = SIO_ERR ;
- X break ;
- X }
- X return( retval ) ;
- X}
- X
- X
- X/*
- X * Flush the buffer associated with the given file descriptor
- X * The special value, SIO_FLUSH_ALL flushes all buffers
- X *
- X * Return value:
- X * 0 : if fd is SIO_FLUSH_ALL or if the flush is successful
- X * SIO_ERR: if fd is not SIO_FLUSH_ALL and
- X * the flush is unsuccessful
- X * or the descriptor is not initialized or it is not
- X * an output descriptor
- X */
- Xint Sflush( fd )
- X int fd ;
- X{
- X register __sio_descriptor_t *dp ;
- X int b_in_buffer ;
- X
- X#ifdef EVENTS
- X EVENT( fd, EV_SFLUSH ) ;
- X#endif
- X
- X if ( fd == SIO_FLUSH_ALL )
- X {
- X for ( fd = 0, dp = __sio_descriptors ;
- X fd < N_SIO_DESCRIPTORS ;
- X dp++, fd++ )
- X if ( DESCRIPTOR_INITIALIZED( dp ) &&
- X dp->stream_type == __SIO_OUTPUT_STREAM )
- X (void) __sio_writef( ODP( dp ), fd ) ;
- X return( 0 ) ;
- X }
- X else
- X {
- X dp = &__sio_descriptors[ fd ] ;
- X
- X CONTROL_SETUP( dp, __SIO_OUTPUT_STREAM, SIO_ERR ) ;
- X b_in_buffer = ODP( dp )->nextb - ODP( dp )->start ;
- X if ( __sio_writef( ODP( dp ), fd ) != b_in_buffer )
- X return( SIO_ERR ) ;
- X else
- X return( 0 ) ;
- X }
- X}
- X
- X
- X/*
- X * Close the file descriptor. This call is provided because
- X * a file descriptor may be closed and then reopened. There is
- X * no easy way for SIO to identify such a situation, so Sclose
- X * must be used.
- X *
- X * Sclose invokes Sdone which finalizes the buffer.
- X * There is no SIO_CLOSE_ALL value for fd because such a thing
- X * would imply that the program will exit very soon, therefore
- X * the closing of all file descriptors will be done in the kernel
- X * (and the finalization will be done by the finalization function
- X * NOTE: not true if the OS does not support a finalization function)
- X *
- X * There is no need to invoke SETUP; Sdone will do it.
- X */
- Xint Sclose( fd )
- X int fd ;
- X{
- X#ifdef EVENTS
- X EVENT( fd, EV_SCLOSE ) ;
- X#endif
- X
- X if ( __SIO_FD_INITIALIZED( fd ) )
- X if ( Sdone( fd ) == SIO_ERR )
- X return( SIO_ERR ) ;
- X return( close( fd ) ) ;
- X}
- X
- X
- X
- X/*
- X * Tie the file descriptor in_fd to the file descriptor out_fd
- X * This means that whenever a read(2) is done on in_fd, it is
- X * preceded by a write(2) on out_fd.
- X * Why this is nice to have:
- X * 1) When used in filters it maximizes concurrency
- X * 2) When the program prompts the user for something it forces
- X * the prompt string to be displayed even if it does not
- X * end with a '\n' (which would cause a flush).
- X * In this implementation, out_fd cannot be a regular file.
- X * This is done to avoid non-block-size write's.
- X * The file descriptors are initialized if that has not been done
- X * already. If any of them is initialized, it must be for the appropriate
- X * stream type (input or output).
- X *
- X * NOTE: the code handles correctly the case when in_fd == out_fd
- X */
- Xint Stie( in_fd, out_fd )
- X int in_fd, out_fd ;
- X{
- X struct stat st ;
- X register __sio_descriptor_t *dp ;
- X int was_initialized ;
- X boolean_e failed = NO ;
- X
- X#ifdef EVENTS
- X EVENT( in_fd, EV_STIE ) ;
- X#endif
- X
- X /*
- X * Check if the out_fd is open
- X */
- X if ( fstat( out_fd, &st ) == -1 )
- X return( SIO_ERR ) ;
- X
- X /*
- X * If the out_fd refers to a regular file, the request is silently ignored
- X */
- X if ( ( st.st_mode & S_IFMT ) == S_IFREG )
- X return( 0 ) ;
- X
- X dp = &__sio_descriptors[ in_fd ] ;
- X was_initialized = dp->initialized ; /* remember if it was initialized */
- X IO_SETUP( in_fd, dp, __SIO_INPUT_STREAM, SIO_ERR ) ;
- X
- X /*
- X * Perform manual initialization of out_fd to avoid leaving in_fd
- X * initialized if the initialization of out_fd fails.
- X * If out_fd is initialized, check if it is used for output.
- X * If it is not initialized, initialize it for output.
- X */
- X dp = &__sio_descriptors[ out_fd ] ;
- X if ( DESCRIPTOR_INITIALIZED( dp ) )
- X {
- X if ( dp->stream_type != __SIO_OUTPUT_STREAM )
- X {
- X failed = YES ;
- X errno = EBADF ;
- X }
- X }
- X else
- X if ( __sio_init( dp, out_fd, __SIO_OUTPUT_STREAM ) == SIO_ERR )
- X failed = YES ;
- X
- X if ( failed == NO )
- X {
- X __SIO_ID( in_fd ).tied_fd = out_fd ;
- X return( 0 ) ;
- X }
- X else
- X {
- X /*
- X * We failed. If we did any initialization, undo it
- X */
- X if ( ! was_initialized )
- X {
- X int save_errno = errno ;
- X
- X (void) Sdone( in_fd ) ;
- X errno = save_errno ;
- X }
- X return( SIO_ERR ) ;
- X }
- X}
- X
- X
- X/*
- X * Untie a file descriptor
- X */
- Xint Suntie( fd )
- X int fd ;
- X{
- X register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
- X
- X#ifdef EVENTS
- X EVENT( fd, EV_SUNTIE ) ;
- X#endif
- X
- X CONTROL_SETUP( dp, __SIO_INPUT_STREAM, SIO_ERR ) ;
- X
- X if ( IDP( dp )->tied_fd != SIO_NO_TIED_FD )
- X {
- X IDP( dp )->tied_fd = SIO_NO_TIED_FD ;
- X return( 0 ) ;
- X }
- X else
- X {
- X errno = EBADF ;
- X return( SIO_ERR ) ;
- X }
- X}
- X
- X
- X/*
- X * Changes the type of buffering on the specified descriptor.
- X * As a side-effect, it initializes the descriptor as an output stream.
- X */
- Xint Sbuftype( fd, type )
- X int fd, type ;
- X{
- X register __sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;
- X
- X#ifdef EVENTS
- X EVENT( fd, EV_SBUFTYPE ) ;
- X#endif
- X
- X /*
- X * Check for a valid type
- X */
- X if ( type != SIO_LINEBUF && type != SIO_FULLBUF && type != SIO_NOBUF )
- X {
- X errno = EINVAL ;
- X return( SIO_ERR ) ;
- X }
- X
- X IO_SETUP( fd, dp, __SIO_OUTPUT_STREAM, SIO_ERR ) ;
- X ODP( dp )->buftype = type ;
- X return( 0 ) ;
- X}
- X
- X
- X#ifndef sio_memscan
- X
- XPRIVATE char *sio_memscan( from, how_many, ch )
- X char *from ;
- X int how_many ;
- X register char ch ;
- X{
- X register char *p ;
- X register char *last = from + how_many ;
- X
- X for ( p = from ; p < last ; p++ )
- X if ( *p == ch )
- X return( p ) ;
- X return( 0 ) ;
- X}
- X
- X#endif /* sio_memscan */
- X
- X
- X#ifdef NEED_MEMCOPY
- X
- Xvoid __sio_memcopy( from, to, nbytes )
- X register char *from, *to ;
- X register int nbytes ;
- X{
- X while ( nbytes-- )
- X *to++ = *from++ ;
- X}
- X
- X#endif /* NEED_MEMCOPY */
- X
- X
- END_OF_FILE
- if test 15212 -ne `wc -c <'libs/src/sio/sio.c'`; then
- echo shar: \"'libs/src/sio/sio.c'\" unpacked with wrong size!
- fi
- # end of 'libs/src/sio/sio.c'
- fi
- echo shar: End of archive 25 \(of 31\).
- cp /dev/null ark25isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 31 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-