home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-26 | 28.6 KB | 1,051 lines |
- Newsgroups: comp.sources.unix
- From: panos@cs.colorado.edu (Panos Tsirigotis)
- Subject: v26i267: xinetd-2.1.1 - inetd replacement with access control and logging, Part23/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 267
- Archive-Name: xinetd-2.1.1/part23
-
- #! /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 23 (of 31)."
- # Contents: libs/src/sio/sio.3 xinetd/confparse.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.3' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/sio/sio.3'\"
- else
- echo shar: Extracting \"'libs/src/sio/sio.3'\" \(12801 characters\)
- sed "s/^X//" >'libs/src/sio/sio.3' <<'END_OF_FILE'
- 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.\" $Id: sio.3,v 8.1 1993/03/13 01:13:58 panos Exp $
- X.TH SIO 3X "29 May 1992"
- X.SH NAME
- XSread, Sgetc, Srdline, Sfetch, Swrite, Sputc, Sprint, Sprintv, Sdone, Sundo, Stie, Suntie, Sflush, Sclose, Sbuftype, Smorefds, Sgetchar, Sputchar, SIOLINELEN, SIOMAXLINELEN - fast stream I/O
- X.SH SYNOPSIS
- X.LP
- X.nf
- X.ft B
- X#include "sio.h"
- X#include <varargs.h>
- X.LP
- X.ft B
- Xint Sread( fd, buf, nbytes )
- Xint fd ;
- Xchar *buf ;
- Xint nbytes ;
- X.LP
- X.ft B
- Xint Sgetc( fd )
- Xint fd ;
- X.LP
- X.ft B
- Xchar *Srdline( fd )
- Xint fd ;
- X.LP
- X.ft B
- Xchar *Sfetch( fd, length )
- Xint fd ;
- Xlong *length ;
- X.LP
- X.ft B
- Xint Swrite( fd, buf, nbytes )
- Xint fd ;
- Xchar *buf ;
- Xint nbytes ;
- X.LP
- X.ft B
- Xint Sputc( fd, c )
- Xint fd ;
- Xchar c ;
- X.LP
- X.ft B
- Xint Sprint( fd, format [ , ... ] )
- Xint fd ;
- Xchar *format ;
- X.LP
- X.ft B
- Xint Sprintv( fd, format, ap )
- Xint fd ;
- Xchar *format ;
- Xva_list ap ;
- X.LP
- X.ft B
- Xint Sdone( fd )
- Xint fd ;
- X.LP
- X.ft B
- Xint Sundo( fd, type )
- Xint fd ;
- Xint type ;
- X.LP
- X.ft B
- Xint Stie( ifd, ofd )
- Xint ifd, ofd ;
- X.LP
- X.ft B
- Xint Suntie( fd )
- Xint fd ;
- X.LP
- X.ft B
- Xint Sbuftype( fd, type )
- Xint fd, type ;
- X.LP
- X.ft B
- Xint Smorefds()
- X.LP
- X.ft B
- Xint Sflush( fd )
- Xint fd ;
- X.LP
- X.ft B
- Xint Sclose( fd )
- Xint fd ;
- X.LP
- X.ft B
- Xint Sgetchar( fd )
- Xint fd ;
- X.LP
- X.ft B
- Xint Sputchar( fd, c )
- Xint fd;
- Xchar c ;
- X.LP
- X.ft B
- Xint SIOLINELEN( fd )
- Xint fd ;
- X.LP
- X.ft B
- Xint SIOMAXLINELEN( fd )
- Xint fd ;
- X.SH DESCRIPTION
- XThe \fISIO\fR library provides support
- Xfor \fIstream\fR I/O on file descriptors.
- XThe first argument of every function
- Xor macro is a file descriptor. The file descriptor may be used either for
- Xinput or for output but not both. Attempting to use a descriptor for
- Xboth input and output will cause the call to fail. When you are
- Xdone with using a file descriptor, you should inform \fISIO\fR
- Xby invoking \fBSdone()\fR (unless the program is about to
- Xcall \fIexit(3)\fR).
- XYou can also use \fBSdone()\fR if
- Xyou want to perform a different type of operation on the same
- Xfile descriptor (e.g. first you were reading data from the file
- Xdescriptor and then you want to write some data).
- XAnother possibility is to do stream I/O at different file offsets
- Xby using \fBSdone()\fR before doing the \fBlseek(2)\fR to the
- Xnew file offset.
- X.LP
- XI/O operations on different file descriptors do not interfere
- X(unless the file descriptors refer to the same file, in which case
- Xthe results are undefined).
- X.LP
- XFor disk files I/O always starts at the current file offset.
- XIf that offset is not a multiple of the preferred block size for file
- Xsystem I/O (the \fIst_blksize\fR field in \fIstruct stat\fR),
- Xperformance will not be optimal.
- XFor optimal performance, it is recommended that no I/O operations
- X(like \fIread(2)\fR or \fIwrite(2)\fR)
- Xare applied to the file descriptor if it is to be used by \fISIO\fR.
- X.LP
- XRead I/O is either buffered or is done using memory mapping whenever
- Xthat is possible and appropriate.
- X.LP
- XThe library functions that do stream I/O resemble system calls
- X(for example \fBSread()\fR resembles \fIread(2)\fR) so that modifying
- Xa program that uses the system calls to use the \fISIO\fR functions
- Xis easy (e.g. just replace \fIread(2)\fR with \fBSread()\fR; the function
- Xsignatures as well as the return values are exactly the same).
- X.LP
- X.B Sread()
- Xreads \fInbytes\fR bytes from the stream associated with file
- Xdescriptor \fIfd\fR into the buffer pointed to by \fIbuf\fR.
- X.LP
- X.B Sgetc()
- Xreads a character from the stream
- Xassociated with file descriptor \fIfd\fR.
- XIt returns \fBSIO_EOF\fR if the end of file has been reached.
- X.LP
- X.B Sgetchar()
- X(a macro) performs exactly the same function as \fBSgetc()\fR but
- Xit is much faster.
- X.LP
- X.B Srdline()
- Xreads a line from the stream
- Xassociated with file descriptor \fIfd\fR.
- XThe newline at the end of the line is replaced by a 0 byte. Lines
- Xlonger than the maximum line length supported by \fISIO\fR will
- Xhave characters deleted.
- X.LP
- X.B SIOLINELEN()
- X(a macro) returns the length of
- Xthe line returned by the last call to \fBSrdline()\fR
- X(the value returned by \fBSIOLINELEN()\fR is valid only after
- X\fBSrdline()\fR and as long as no other
- X\fISIO\fR calls are performed on that file descriptor).
- X.LP
- X.B SIOMAXLINELEN()
- X(a macro) returns
- Xthe maximul line length supported by \fISIO\fR for the file
- Xdescriptor. As a side-effect it initializes \fIfd\fR for input.
- X.LP
- X.B Sfetch()
- Xreturns a pointer to data coming from the stream
- Xassociated with file
- Xdescriptor \fIfd\fR. The amount of data available is indicated
- Xby the \fIlength\fR argument. One possible use for this function
- Xis copying of files.
- X.LP
- X.B Swrite()
- Xwrites \fInbytes\fR bytes to the stream associated with file
- Xdescriptor \fIfd\fR from the buffer pointed to by \fIbuf\fR.
- X.LP
- X.B Sputc()
- Xwrites a single character to the stream
- Xassociated with file descriptor \fIfd\fR.
- X.LP
- X.B Sputchar()
- X(a macro) performs exactly the same function as \fBSputc()\fR
- Xbut it is much faster.
- X.LP
- X.B Sprint()
- Ximitates the behavior of printf(3) as defined in the
- XANSI C Standard. There are some limitations. Check the \fBSprint()\fR
- Xman page for more information.
- X.LP
- X.B Sprintv()
- Xis the same as \fBSprint()\fR except that it takes a
- X\fIvarargs\fR argument list.
- X.LP
- X.B Sundo()
- Xreturns the characters returned by the last call to
- X\fBSrdline()\fR, \fBSgetc()\fR or \fBSgetchar()\fR to the stream
- Xso that they can be reread. The \fItype\fR argument to \fBSundo()\fR
- Xcan be \fBSIO_UNDO_LINE\fR or \fBSIO_UNDO_CHAR\fR depending
- Xon whether the call whose effect needs to be undone was
- X\fBSrdline()\fR or \fBSgetc()\fR/\fBSgetchar()\fR respectively.
- XThere is no check on
- Xwhether the last function invoked on \fIfd\fR was one of the above
- Xand the results are undefined if there is no correspondence
- Xbetween the \fItype\fR and the last operation on \fIfd\fR.
- X(i.e. the result is undefined if you try \fBSIO_UNDO_CHAR\fR
- Xand the last operation was not \fBSgetchar()\fR or \fBSgetc()\fR).
- X.LP
- X.B Stie()
- Xties the file descriptor \fIifd\fR to the file descriptor \fIofd\fR.
- XThis means that whenever a \fIread(2)\fR is done on \fIifd\fR, it is
- Xpreceded by a \fIwrite(2)\fR on \fIofd\fR.
- XFor filters it is useful to do \fIStie( 0, 1 )\fR to maximize concurrency.
- XIt is also useful to do the same thing when you issue prompts to the
- Xuser and you want the user reply to appear on the same line with the
- Xprompt.
- X\fIifd\fR, \fIofd\fR will be initialized for input, output respectively
- X(if any of them is initialized, it must be for the appropriate
- Xstream type (input or output)).
- XIf \fIifd\fR was tied to another file descriptor, the old tie is broken.
- X.LP
- X.B Suntie()
- Xundoes the effect of \fBStie()\fR for the specified input file descriptor.
- X.LP
- X.B Sbuftype()
- Xdetermines the buffering type for the output stream associated with
- Xfile descriptor \fIfd\fR.
- XBy default output directed to terminals is line buffered, output
- Xdirected to file descriptor 2 (standard error) is unbuffered and
- Xeverything else is fully buffered.
- XPossible values for the \fItype\fR argument are
- X.RS
- X.TP 15
- X.SB SIO_FULLBUF
- Xfor full buffering
- X.TP
- X.SB SIO_LINEBUF
- Xfor line buffering
- X.TP
- X.SB SIO_NOBUF
- Xfor no buffering
- X.RE
- X.LP
- X.B Smorefds()
- Xshould be used to inform \fBSIO\fR that the number of available file
- Xdescriptors has been increased. \fBSIO\fR uses an array of internal
- Xstream descriptors which are indexed by the file descriptor number. Some
- Xoperating systems (ex. SunOS 4.1[.x]) allow the number of available
- Xfile descriptors to vary. If that number is increased beyond its initial
- Xvalue \fBSIO\fR needs to know in order to allocate more stream descriptors.
- X.LP
- X.B Sdone()
- Xflushes any buffered output for \fIfd\fR
- Xand releases the \fISIO\fR resources used. \fBSdone()\fR
- Xis useful in case the program needs to reprocess the
- Xdata of a file descriptor (assuming the file descriptor corresponds
- Xto a file). The program can call \fBSdone()\fR,
- X\fIlseek(2)\fR to the beginning of the file
- Xand then proceed to reread the file.
- X.LP
- X.B Sflush()
- Xcauses any buffered stream output to be written to the
- Xfile descriptor. If its argument is the special value \fBSIO_FLUSH_ALL\fR
- Xthen all output streams will be flushed.
- X.LP
- X.B Sclose()
- Xcloses a file descriptor used for stream I/O, flushes
- Xany buffered output and releases the \fISIO\fR resources used.
- X.SH EXAMPLES
- X.LP
- XThe following code implements a (poor) substitute for the tee command
- X(it copies standard input to a file as well as to standard output).
- X.ne 10
- X.RS
- X.nf
- X.ft B
- X#include "sio.h"
- X.sp .5
- Xmain( argc, argv )
- X int argc ;
- X char *argv[] ;
- X{
- X char *file = (argc > 1) ? argv[ 1 ] : "tee.file" ;
- X int fd = creat( file, 0644 ) ;
- X long length ;
- X char *s ;
- X.sp .5
- X while ( s = Sfetch( 0, &length ) )
- X {
- X Swrite( 1, s, length ) ;
- X Swrite( fd, s, length ) ;
- X }
- X exit( 0 ) ;
- X}
- X.fi
- X.ft R
- X.RE
- X.SH RETURN VALUES
- X.LP
- X.B Sread()
- Xreturns the number of bytes read on success
- X(0 means end-of-file)
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- X.B Sgetc()
- Xreturns the character read on success,
- XSIO_EOF when the end-of-file is reached,
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- X.B Srdline()
- Xreturns a pointer to the next line on success.
- XOn failure or when the end-of-file is reached it returns
- X.SM NULL.
- XIf the end-of-file is reached \fIerrno\fR is set to 0, otherwise it indicates
- Xthe error.
- X.LP
- X.B Sfetch()
- Xreturns a pointer to file data on success.
- X(the \fIlength\fR argument indicates how many bytes
- Xare available).
- XOn failure or when the end-of-file is reached it returns
- X.SM NULL.
- XIf the end-of-file is reached \fIerrno\fR is set to 0, otherwise it indicates
- Xthe error.
- X.LP
- X.B Swrite()
- Xreturns the number of bytes written on success
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- X.B Sputc()
- Xreturns the character it was given as an argument on success
- X.B Sprint()
- Xreturns the number of characters printed on success
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- X.B Sdone()
- Xreturns \fB0\fR on success
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- X.B Sundo()
- Xreturns \fB0\fR on success
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- X.B Stie()
- Xreturns \fB0\fR on success
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- X.B Suntie()
- Xreturns \fB0\fR on success
- Xor \fBSIO_ERR\fR on failure
- X(\fIerrno\fR is set to \fBEBADF\fR if there
- Xwas no tied file descriptor).
- X.LP
- X.B Sbuftype()
- Xreturns \fB0\fR on success
- Xor \fBSIO_ERR\fR on failure
- X(\fIerrno\fR is set to \fBEBADF\fR if this is not an output stream
- Xor to \fBEINVAL\fR if an unknown \fItype\fR is specified).
- X.LP
- X.B Smorefds()
- Xreturns \fB0\fR on success
- Xor \fBSIO_ERR\fR on failure (because of lack of memory).
- X.LP
- X.B Sflush()
- Xreturns \fB0\fR on success
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- X.B Sclose()
- Xreturns \fB0\fR on success
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- X.B Sgetchar()
- Xreturns the character read on success,
- XSIO_EOF when the end-of-file is reached,
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- X.B Sputchar()
- Xreturns the character it was given as an argument on success
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- X.B SIOLINELEN()
- Xreturns the length of the last line read by \fBSrdline()\fR.
- X.LP
- X.B SIOMAXLINELEN()
- Xreturns the length of the longest line supported by \fISIO\fR on success
- Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
- X.LP
- XAttempting a read operation on a descriptor opened for writing or vice
- Xversa will cause the operation to fail with \fIerrno\fR set to \fBEBADF\fR.
- X.LP
- XThe first \fISIO\fR operation on a descriptor must be a read or write
- Xoperation. It cannot be a control operation (like \fBSflush()\fR). Such
- Xan operation will fail with \fIerrno\fR set to \fBEBADF\fR.
- X.LP
- X.IP "\fBNOTE 1:\fR" 15
- X\fBStie()\fR is an input/output operation for the
- Xrespective file descriptors, not a control operation. \fBSuntie()\fR
- Xis a control operation.
- X.IP "\fBNOTE 2:\fR"
- X\fBSIO_ERR\fR is defined to be \fB-1\fR.
- X.SH "SEE ALSO"
- X.LP
- XSprint(3)
- X.SH BUGS
- X.LP
- XIf the operating system does not provide for invocation of a
- Xfinalization function upon exit, the program will have to
- Xexplicitly flush all output streams.
- XThe following operating systems provide such a facility:
- XSunOS 4.x, Ultrix 4.x.
- X.LP
- XSocket file descriptors can be used for input as well as output but
- X\fBSIO\fR does not support this.
- X.LP
- XThe current implementation will not try to use memory mapping to
- Xread a file if the file offset is not 0 (it will use buffered I/O instead).
- X.LP
- XPointers returned by \fBSfetch()\fR point to read-only memory.
- XAttempting to modify this memory will result in a segmentation
- Xviolation.
- END_OF_FILE
- if test 12801 -ne `wc -c <'libs/src/sio/sio.3'`; then
- echo shar: \"'libs/src/sio/sio.3'\" unpacked with wrong size!
- fi
- # end of 'libs/src/sio/sio.3'
- fi
- if test -f 'xinetd/confparse.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/confparse.c'\"
- else
- echo shar: Extracting \"'xinetd/confparse.c'\" \(13219 characters\)
- sed "s/^X//" >'xinetd/confparse.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1992 by Panagiotis Tsirigotis
- X * All rights reserved. The file named COPYRIGHT specifies the terms
- X * and conditions for redistribution.
- X */
- X
- X#include <sys/types.h>
- X#include <syslog.h>
- X#include <netdb.h>
- X#include <string.h>
- X#include <netinet/in.h>
- X
- Xchar *malloc() ;
- Xvoid endservent() ;
- Xvoid endprotoent() ;
- Xvoid endrpcent() ;
- X
- X#include "pset.h"
- X#include "misc.h"
- X
- X#include "attr.h"
- X#include "config.h"
- X#include "conf.h"
- X#include "defs.h"
- X#include "parse.h"
- X#include "sconst.h"
- X#include "sconf.h"
- X#include "state.h"
- X
- Xvoid out_of_memory() ;
- Xvoid msg() ;
- X
- X/*
- X * Pset iterator used by functions in this file.
- X * It lives only when get_configuration is called (i.e. it is created and
- X * destroyed each time). This is because the pset it is iterating on
- X * changes.
- X */
- Xstatic psi_h iter ;
- X
- X
- XPRIVATE status_e fix_server_argv( scp )
- X struct service_config *scp ;
- X{
- X char *server_name ;
- X char *func = "fix_server_argv" ;
- X
- X /*
- X * Check if the user specified any server arguments.
- X * If not, then the server_argv has not been allocated yet,
- X * so malloc it (size 2)
- X * Put in argv[ 0 ] the last component of the server pathname
- X */
- X if ( ! SC_SPECIFIED( scp, A_SERVER_ARGS ) )
- X {
- X scp->sc_server_argv = (char **) malloc( 2 * sizeof( char * ) ) ;
- X if ( scp->sc_server_argv == NULL )
- X {
- X out_of_memory( func ) ;
- X return( FAILED ) ;
- X }
- X scp->sc_server_argv[ 1 ] = NULL ;
- X SC_PRESENT( scp, A_SERVER_ARGS ) ;
- X }
- X
- X /*
- X * Determine server name
- X */
- X server_name = strrchr( scp->sc_server, '/' ) ;
- X if ( server_name == NULL )
- X server_name = scp->sc_server ;
- X else
- X server_name++ ; /* skip the '/' */
- X
- X /*
- X * Place it in argv[ 0 ]
- X */
- X scp->sc_server_argv[ 0 ] = make_string( 1, server_name ) ;
- X if ( scp->sc_server_argv[ 0 ] == NULL )
- X {
- X out_of_memory( func ) ;
- X return( FAILED ) ;
- X }
- X return( OK ) ;
- X}
- X
- X
- X
- X#define USE_DEFAULT( scp, def, attr_id ) \
- X ( ! SC_SPECIFIED( scp, attr_id ) && SC_SPECIFIED( def, attr_id ) )
- X
- X/*
- X * Fill the service configuration with attributes that were not
- X * explicitly specified. These can be:
- X * 1) implied attributes (like the server name in argv[0])
- X * 2) attributes from 'defaults' so that we won't need to check
- X * 'defaults' anymore.
- X * 3) default values (like the service instance limit)
- X */
- XPRIVATE status_e attr_fill( scp, def )
- X struct service_config *scp ;
- X struct service_config *def ;
- X{
- X char *func = "attr_fill" ;
- X status_e setup_environ() ;
- X
- X if ( ! SC_IS_INTERNAL( scp ) && fix_server_argv( scp ) == FAILED )
- X return( FAILED ) ;
- X
- X if ( ! SC_SPECIFIED( scp, A_INSTANCES ) )
- X {
- X scp->sc_instances = SC_SPECIFIED( def, A_INSTANCES ) ? def->sc_instances
- X : DEFAULT_INSTANCE_LIMIT ;
- X SC_PRESENT( scp, A_INSTANCES ) ;
- X }
- X
- X if ( USE_DEFAULT( scp, def, A_LOG_ON_SUCCESS ) )
- X {
- X scp->sc_log_on_success = def->sc_log_on_success ;
- X SC_PRESENT( scp, A_LOG_ON_SUCCESS ) ;
- X }
- X
- X if ( USE_DEFAULT( scp, def, A_LOG_ON_FAILURE ) )
- X {
- X scp->sc_log_on_failure = def->sc_log_on_failure ;
- X SC_PRESENT( scp, A_LOG_ON_FAILURE ) ;
- X }
- X
- X if ( USE_DEFAULT( scp, def, A_LOG_TYPE ) )
- X {
- X struct log *dlp = SC_LOG( def ) ;
- X struct log *slp = SC_LOG( scp ) ;
- X
- X switch ( log_get_type( dlp ) )
- X {
- X case L_NONE:
- X log_set_type( slp, L_NONE ) ;
- X break ;
- X
- X case L_SYSLOG:
- X *slp = *dlp ;
- X break ;
- X
- X case L_FILE:
- X log_set_type( slp, L_COMMON_FILE ) ;
- X break ;
- X
- X default:
- X msg( LOG_ERR, func,
- X "bad log type: %d", (int) log_get_type( dlp ) ) ;
- X return( FAILED ) ;
- X }
- X SC_PRESENT( scp, A_LOG_TYPE ) ;
- X }
- X if ( setup_environ( scp, def ) == FAILED )
- X return( FAILED ) ;
- X return( OK ) ;
- X}
- X
- X
- XPRIVATE void remove_disabled_services( confp )
- X struct configuration *confp ;
- X{
- X pset_h disabled_services ;
- X register struct service_config *scp ;
- X struct service_config *defaults = confp->cnf_defaults ;
- X
- X if ( ! SC_SPECIFIED( defaults, A_DISABLED ) )
- X return ;
- X
- X disabled_services = defaults->sc_disabled ;
- X
- X for ( scp = SCP( psi_start( iter ) ) ; scp ; scp = SCP( psi_next( iter ) ) )
- X {
- X register char *sid = SC_ID( scp ) ;
- X register unsigned u ;
- X
- X for ( u = 0 ; u < pset_count( disabled_services ) ; u++ )
- X if ( EQ( sid, (char *) pset_pointer( disabled_services, u ) ) )
- X {
- X sc_free( scp ) ;
- X psi_remove( iter ) ;
- X break ;
- X }
- X }
- X}
- X
- X
- X/*
- X * Check if all required attributes have been specified
- X */
- XPRIVATE status_e attr_check( scp )
- X register struct service_config *scp ;
- X{
- X mask_t necessary_and_specified ;
- X mask_t necessary_and_missing ;
- X mask_t must_specify = NECESSARY_ATTRS ;
- X register int attr_id ;
- X char *attr_name ;
- X char *func = "attr_check" ;
- X char *attr_name_lookup() ;
- X
- X /*
- X * Determine what attributes must be specified
- X */
- X if ( ! SC_IS_INTERNAL( scp ) )
- X M_OR( must_specify, must_specify, NECESSARY_ATTRS_EXTERNAL ) ;
- X
- X if ( SC_IS_UNLISTED( scp ) )
- X M_OR( must_specify, must_specify, NECESSARY_ATTRS_UNLISTED ) ;
- X else
- X M_OR( must_specify, must_specify, NECESSARY_ATTRS_LISTED ) ;
- X
- X if ( SC_IS_RPC( scp ) )
- X if ( SC_IS_UNLISTED( scp ) )
- X M_OR( must_specify, must_specify, NECESSARY_ATTRS_RPC_UNLISTED ) ;
- X else
- X M_OR( must_specify, must_specify, NECESSARY_ATTRS_RPC_LISTED ) ;
- X
- X /*
- X * Check if all necessary attributes have been specified
- X *
- X * NOTE: None of the necessary attributes can belong to "defaults"
- X * This is why we use the sc_attributes_specified mask.
- X */
- X M_AND( necessary_and_specified,
- X scp->sc_specified_attributes, must_specify ) ;
- X M_XOR( necessary_and_missing, necessary_and_specified, must_specify ) ;
- X
- X if ( M_ARE_ALL_CLEAR( necessary_and_missing ) )
- X return( OK ) ;
- X
- X /*
- X * Print names of missing attributes
- X */
- X for ( attr_id = 0 ; attr_id < SERVICE_ATTRIBUTES ; attr_id++ )
- X if ( M_IS_SET( necessary_and_missing, attr_id ) &&
- X ( attr_name = attr_name_lookup( attr_id ) ) != NULL )
- X msg( LOG_ERR, func,
- X "Service %s missing attribute %s", scp->sc_id, attr_name ) ;
- X return( FAILED ) ;
- X}
- X
- X
- X/*
- X * Perform validity checks on the specified entry
- X *
- X * Also does the following:
- X * 1. If this is an internal service, it finds the function that
- X * implements it
- X * 2. For RPC services, it finds the program number
- X * 3. For non-RPC services, it finds the port number.
- X */
- XPRIVATE status_e check_entry( scp )
- X register struct service_config *scp ;
- X{
- X char *func = "check_entry" ;
- X
- X if ( attr_check( scp ) == FAILED )
- X return( FAILED ) ;
- X
- X /*
- X * Currently, we cannot intercept:
- X * 1) internal services
- X * 2) multi-threaded services
- X * We clear the INTERCEPT flag without disabling the service.
- X */
- X if ( SC_IS_INTERCEPTED( scp ) )
- X {
- X if ( SC_IS_INTERNAL( scp ) )
- X {
- X msg( LOG_ERR, func,
- X "Internal services cannot be intercepted: %s ", scp->sc_id ) ;
- X M_CLEAR( scp->sc_flags, SF_INTERCEPT ) ;
- X }
- X if ( scp->sc_wait == NO )
- X {
- X msg( LOG_ERR, func,
- X "Multi-threaded services cannot be intercepted: %s", scp->sc_id ) ;
- X M_CLEAR( scp->sc_flags, SF_INTERCEPT ) ;
- X }
- X }
- X
- X if ( SC_IS_INTERNAL( scp ) &&
- X ( scp->sc_builtin =
- X builtin_find( scp->sc_name, scp->sc_socket_type ) ) == NULL )
- X return( FAILED ) ;
- X
- X /*
- X * If this is an unlisted service we are done.
- X * attr_check() guaranteed that we have all the information we need
- X * to start the service.
- X */
- X if ( SC_IS_UNLISTED( scp ) )
- X return( OK ) ;
- X
- X#ifndef NO_RPC
- X if ( SC_IS_RPC( scp ) )
- X {
- X struct rpcent *rep = getrpcbyname( scp->sc_name ) ;
- X
- X if ( rep == NULL )
- X {
- X msg( LOG_ERR, func, "unknown RPC service: %s", scp->sc_name ) ;
- X return( FAILED ) ;
- X }
- X SC_RPCDATA( scp )->rd_program_number = rep->r_number ;
- X }
- X else
- X#endif /* ! NO_RPC */
- X {
- X struct servent *sep ;
- X unsigned short service_port ;
- X
- X /*
- X * Check if a protocol was specified.
- X * If so, verify it is a proper protocol for the given service.
- X * If no protocol was specified, find the protocol for the service
- X * and its number.
- X */
- X if ( SC_SPECIFIED( scp, A_PROTOCOL ) )
- X {
- X sep = getservbyname( scp->sc_name, scp->sc_protocol.name ) ;
- X if ( sep == NULL )
- X {
- X msg( LOG_ERR, func,
- X "service/protocol combination not in /etc/services: %s/%s",
- X scp->sc_name, scp->sc_protocol.name ) ;
- X return( FAILED ) ;
- X }
- X }
- X else
- X {
- X struct protoent *pep ;
- X
- X sep = getservbyname( scp->sc_name, CHAR_NULL ) ;
- X if ( sep == NULL )
- X {
- X msg( LOG_ERR, func, "Unknown service: %s", scp->sc_name ) ;
- X return( FAILED ) ;
- X }
- X scp->sc_protocol.name = make_string( 1, sep->s_proto ) ;
- X if ( scp->sc_protocol.name == NULL )
- X {
- X out_of_memory( func ) ;
- X return( FAILED ) ;
- X }
- X pep = getprotobyname( sep->s_proto ) ;
- X if ( pep == NULL )
- X {
- X msg( LOG_ERR, func,
- X "Protocol '%s' for service '%s' is not in /etc/protocols",
- X sep->s_proto, scp->sc_name ) ;
- X return( FAILED ) ;
- X }
- X scp->sc_protocol.value = pep->p_proto ;
- X }
- X
- X service_port = sep->s_port ; /* s_port is in network-byte-order */
- X
- X /*
- X * If a port was specified, it must be the right one
- X */
- X if ( SC_SPECIFIED( scp, A_PORT ) &&
- X scp->sc_port != ntohs( service_port ) )
- X {
- X msg( LOG_ERR, func, "Service %s expects port %d, not %d",
- X scp->sc_name, ntohs( service_port ), scp->sc_port ) ;
- X return( FAILED ) ;
- X }
- X scp->sc_port = ntohs( service_port ) ;
- X }
- X return( OK ) ;
- X}
- X
- X
- Xvoid parse_conf_file() ;
- Xvoid parse_end() ;
- X
- X#if CONF_TIMEOUT != 0 && ! defined( NO_TIMERS )
- X
- X#include <sys/time.h>
- X#include "timer.h"
- X#include "timemacros.h"
- X
- Xstatic timer_h conf_timer ;
- X
- Xstatus_e create_conf_timer()
- X{
- X conf_timer = timer_create( TIMER_REAL, TIMER_RETURN_ERROR, INT_NULL ) ;
- X return( ( conf_timer == NULL ) ? FAILED : OK ) ;
- X}
- X
- X#endif /* CONF_TIMEOUT != 0 && ! NO_TIMERS */
- X
- X
- X/*
- X * Get a configuration from the specified file.
- X * In case of timeout, do cleanup
- X */
- XPRIVATE status_e get_conf( fd, confp, timeout )
- X int fd ;
- X struct configuration *confp ;
- X long timeout ;
- X{
- X#if CONF_TIMEOUT != 0 && ! defined( NO_TIMERS )
- X
- X struct itimerval itv ;
- X struct timer_action ta ;
- X char *func = "get_conf" ;
- X
- X if ( timeout )
- X {
- X if ( setjmp( ta.ta_env ) )
- X {
- X parse_end() ;
- X return( FAILED ) ;
- X }
- X
- X /*
- X * Start the timer
- X */
- X TV_ZERO( itv.it_interval ) ;
- X itv.it_value.tv_sec = timeout ;
- X itv.it_value.tv_usec = 0 ;
- X ta.ta_flags = TIMER_LONGJMP ;
- X ta.ta_func = NULL ;
- X ta.ta_arg = VOID_NULL ;
- X if ( timer_start( conf_timer, &itv, TIMER_RELATIVE, &ta ) == TIMER_ERR )
- X {
- X msg( LOG_ERR, func, "timer creation failed" ) ;
- X return( FAILED ) ;
- X }
- X }
- X
- X parse_conf_file( fd, confp ) ;
- X
- X if ( timeout )
- X timer_stop( conf_timer ) ;
- X parse_end() ;
- X return( OK ) ;
- X
- X#else /* CONF_TIMEOUT == 0 || NO_TIMERS */
- X
- X#ifdef lint
- X timeout = timeout ;
- X#endif
- X parse_conf_file( fd, confp ) ;
- X parse_end() ;
- X return( OK ) ;
- X#endif /* CONF_TIMEOUT != 0 && ! NO_TIMERS */
- X
- X}
- X
- X
- X
- X#define CHECK_AND_CLEAR( scp, mask, mask_name ) \
- X if ( M_IS_SET( mask, LO_USERID ) ) \
- X { \
- X msg( LOG_WARNING, func, \
- X "%s service: clearing USERID option from %s", scp->sc_id, mask_name ) ; \
- X M_CLEAR( mask, LO_USERID ) ; \
- X }
- X
- X
- X
- X/*
- X * Get a configuration by reading the configuration file.
- X */
- Xstatus_e cnf_get( confp, timeout )
- X struct configuration *confp ;
- X long timeout ;
- X{
- X int config_fd ;
- X struct service_config *scp ;
- X builtin_s *spec_find() ;
- X char *func = "get_configuration" ;
- X
- X if ( cnf_init( confp, &config_fd, &iter ) == FAILED )
- X return( FAILED ) ;
- X
- X if ( get_conf( config_fd, confp, timeout ) == FAILED )
- X {
- X Sclose( config_fd ) ;
- X cnf_free( confp ) ;
- X psi_destroy( iter ) ;
- X return( FAILED ) ;
- X }
- X
- X Sclose( config_fd ) ;
- X
- X remove_disabled_services( confp ) ;
- X
- X for ( scp = SCP( psi_start( iter ) ) ; scp ; scp = SCP( psi_next( iter ) ) )
- X {
- X if ( check_entry( scp ) == FAILED )
- X {
- X sc_free( scp ) ;
- X psi_remove( iter ) ;
- X continue ;
- X }
- X
- X /*
- X * Fill the service configuration from the defaults.
- X * We do this so that we don't have to look at the defaults any more.
- X */
- X if ( attr_fill( scp, confp->cnf_defaults ) == FAILED )
- X {
- X sc_free( scp ) ;
- X psi_remove( iter ) ;
- X continue ;
- X }
- X
- X /*
- X * If the INTERCEPT flag is set, change this service to an internal
- X * service using the special INTERCEPT builtin.
- X */
- X if ( SC_IS_INTERCEPTED( scp ) )
- X {
- X builtin_s *bp ;
- X
- X bp = spec_find( INTERCEPT_SERVICE_NAME, scp->sc_socket_type ) ;
- X if ( bp == NULL )
- X {
- X msg( LOG_ERR, func, "removing service %s", SC_ID( scp ) ) ;
- X sc_free( scp ) ;
- X psi_remove( iter ) ;
- X continue ;
- X }
- X
- X scp->sc_builtin = bp ;
- X M_SET( scp->sc_type, ST_INTERNAL ) ;
- X }
- X
- X /*
- X * Clear the USERID flag for the identity service because
- X * it may lead to loops (for example, remote xinetd issues request,
- X * local xinetd issues request to remote xinetd etc.)
- X * We identify the identity service by its (protocol,port) combination.
- X */
- X if ( scp->sc_port == IDENTITY_SERVICE_PORT &&
- X scp->sc_protocol.value == IPPROTO_TCP )
- X {
- X CHECK_AND_CLEAR( scp, scp->sc_log_on_success, "log_on_success" ) ;
- X CHECK_AND_CLEAR( scp, scp->sc_log_on_failure, "log_on_failure" ) ;
- X }
- X }
- X
- X psi_destroy( iter ) ;
- X
- X if ( debug.on && debug.fd != -1 )
- X cnf_dump( confp, debug.fd ) ;
- X
- X endservent() ;
- X endprotoent() ;
- X#ifndef NO_RPC
- X endrpcent() ;
- X#endif
- X return( OK ) ;
- X}
- X
- X
- END_OF_FILE
- if test 13219 -ne `wc -c <'xinetd/confparse.c'`; then
- echo shar: \"'xinetd/confparse.c'\" unpacked with wrong size!
- fi
- # end of 'xinetd/confparse.c'
- fi
- echo shar: End of archive 23 \(of 31\).
- cp /dev/null ark23isdone
- 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
-