home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-26 | 28.2 KB | 1,320 lines |
- Newsgroups: comp.sources.unix
- From: panos@cs.colorado.edu (Panos Tsirigotis)
- Subject: v26i255: xinetd-2.1.1 - inetd replacement with access control and logging, Part11/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 255
- Archive-Name: xinetd-2.1.1/part11
-
- #! /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 11 (of 31)."
- # Contents: libs/src/misc/env.c libs/src/sio/README xinetd/log.c
- # xinetd/main.c xinetd/sample.conf
- # Wrapped by panos@mystique on Mon Jun 21 14:51:23 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'libs/src/misc/env.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/misc/env.c'\"
- else
- echo shar: Extracting \"'libs/src/misc/env.c'\" \(4772 characters\)
- sed "s/^X//" >'libs/src/misc/env.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
- Xstatic char RCSid[] = "$Id: env.c,v 1.4 1992/11/03 00:07:50 panos Exp $" ;
- X
- X#include <memory.h>
- X#include <string.h>
- X
- X#include "misc.h"
- X#include "env.h"
- X
- Xtypedef struct __env env_s ;
- X
- X#define PRIVATE static
- X#define INITIAL_VARS 20
- X#define INCREASE 10
- X
- X#ifndef NULL
- X#define NULL 0
- X#endif
- X
- Xchar *malloc() ;
- Xchar *realloc() ;
- X
- Xint env_errno ;
- X
- X
- X
- XPRIVATE env_s *alloc_env( max_vars )
- X unsigned max_vars ;
- X{
- X env_s *ep ;
- X unsigned size ;
- X char **pointers ;
- X
- X ep = (env_s *) malloc( sizeof( env_s ) ) ;
- X if ( ep == ENV_NULL )
- X {
- X env_errno = ENV_ENOMEM ;
- X return( ENV_NULL ) ;
- X }
- X
- X size = ( max_vars + 1 ) * sizeof( char * ) ;
- X pointers = (char **) malloc( size ) ;
- X if ( pointers == NULL )
- X {
- X free( (char *)ep ) ;
- X env_errno = ENV_ENOMEM ;
- X return( ENV_NULL ) ;
- X }
- X (void) memset( (char *)pointers, 0, (int) size ) ;
- X
- X ep->vars = pointers ;
- X ep->max_vars = max_vars ;
- X ep->n_vars = 0 ;
- X return( ep ) ;
- X}
- X
- X
- Xenv_h env_create( init_env )
- X env_h init_env ;
- X{
- X unsigned u ;
- X env_s *ep ;
- X unsigned max_vars ;
- X
- X if ( init_env == ENV_NULL )
- X max_vars = INITIAL_VARS ;
- X else
- X max_vars = init_env->n_vars + 5 ;
- X
- X ep = alloc_env( max_vars ) ;
- X if ( ep == NULL )
- X {
- X env_errno = ENV_ENOMEM ;
- X return( ENV_NULL ) ;
- X }
- X
- X if ( init_env == ENV_NULL )
- X return( ep ) ;
- X
- X for ( u = 0, ep->n_vars = 0 ; u < init_env->n_vars ; u++, ep->n_vars++ )
- X {
- X ep->vars[ ep->n_vars ] = make_string( 1, init_env->vars[ u ] ) ;
- X if ( ep->vars[ ep->n_vars ] == NULL )
- X {
- X env_destroy( ep ) ;
- X env_errno = ENV_ENOMEM ;
- X return( ENV_NULL ) ;
- X }
- X }
- X return( ep ) ;
- X}
- X
- X
- Xvoid env_destroy( env )
- X env_h env ;
- X{
- X unsigned u ;
- X
- X for ( u = 0 ; u < env->n_vars ; u++ )
- X free( env->vars[ u ] ) ;
- X free( (char *)env->vars ) ;
- X free( (char *)env ) ;
- X}
- X
- X
- Xenv_h env_make( env_strings )
- X char **env_strings ;
- X{
- X env_s *ep ;
- X char **pp ;
- X
- X for ( pp = env_strings ; *pp ; pp++ ) ;
- X
- X ep = alloc_env( (unsigned) (pp-env_strings) ) ;
- X if ( ep == NULL )
- X {
- X env_errno = ENV_ENOMEM ;
- X return( ENV_NULL ) ;
- X }
- X
- X for ( pp = env_strings ; *pp ; pp++ )
- X {
- X char *p = make_string( 1, *pp ) ;
- X
- X if ( p == NULL )
- X {
- X env_destroy( ep ) ;
- X env_errno = ENV_ENOMEM ;
- X return( ENV_NULL ) ;
- X }
- X ep->vars[ ep->n_vars++ ] = p ;
- X }
- X return( ep ) ;
- X}
- X
- X
- Xchar *env_lookup( env, var )
- X env_h env ;
- X char *var ;
- X{
- X char **lookup() ;
- X char **pp = lookup( env, var, strlen( var ) ) ;
- X
- X return( ( pp == NULL ) ? NULL : *pp ) ;
- X}
- X
- X
- XPRIVATE char **lookup( env, var, len )
- X env_h env ;
- X char *var ;
- X register int len ;
- X{
- X register char **pp ;
- X
- X for ( pp = env->vars ; *pp ; pp++ )
- X if ( strncmp( *pp, var, len ) == 0 && (*pp)[ len ] == '=' )
- X return( pp ) ;
- X return( NULL ) ;
- X}
- X
- X
- XPRIVATE int grow( ep )
- X env_s *ep ;
- X{
- X char **new_vars ;
- X unsigned new_max_vars ;
- X unsigned new_size ;
- X
- X new_max_vars = ep->max_vars + INCREASE ;
- X new_size = ( new_max_vars+1 ) * sizeof( char * ) ;
- X new_vars = (char **) realloc( (char *)ep->vars, new_size ) ;
- X if ( new_vars == NULL )
- X return( ENV_ERR ) ;
- X
- X ep->vars = new_vars ;
- X ep->max_vars = new_max_vars ;
- X return( ENV_OK ) ;
- X}
- X
- X
- X/*
- X * Add the variable string to the given environment.
- X */
- XPRIVATE int addstring( ep, var_string, len )
- X env_s *ep ;
- X char *var_string ;
- X int len ;
- X{
- X char **pp ;
- X char *p ;
- X
- X p = make_string( 1, var_string ) ;
- X if ( p == NULL )
- X return( ENV_ERR ) ;
- X
- X pp = lookup( ep, var_string, len ) ;
- X if ( pp == NULL )
- X {
- X if ( ep->n_vars >= ep->max_vars && grow( ep ) == ENV_ERR )
- X {
- X free( p ) ;
- X env_errno = ENV_ENOMEM ;
- X return( ENV_ERR ) ;
- X }
- X ep->vars[ ep->n_vars++ ] = p ;
- X }
- X else
- X {
- X free( *pp ) ;
- X *pp = p ;
- X }
- X return( ENV_OK ) ;
- X}
- X
- X
- Xint env_addvar( env, from_env, var_name )
- X env_h env ;
- X env_h from_env ;
- X char *var_name ;
- X{
- X char *var_string = env_lookup( from_env, var_name ) ;
- X
- X if ( var_string == NULL )
- X {
- X env_errno = ENV_EBADVAR ;
- X return( ENV_ERR ) ;
- X }
- X
- X return( addstring( env, var_string, strlen( var_name ) ) ) ;
- X}
- X
- X
- Xint env_addstr( env, var_string )
- X env_h env ;
- X char *var_string ;
- X{
- X char *p = strchr( var_string, '=' ) ;
- X
- X if ( p == NULL )
- X {
- X env_errno = ENV_EBADSTRING ;
- X return( ENV_ERR ) ;
- X }
- X
- X return( addstring( env, var_string, p-var_string ) ) ;
- X}
- X
- X
- Xint env_remvar( env, var )
- X env_h env ;
- X char *var ;
- X{
- X char **pp = lookup( env, var, strlen( var ) ) ;
- X
- X if ( pp == NULL )
- X {
- X env_errno = ENV_EBADVAR ;
- X return( ENV_ERR ) ;
- X }
- X
- X free( *pp ) ;
- X *pp = env->vars[ --env->n_vars ] ;
- X return( ENV_OK ) ;
- X}
- X
- X
- X#ifdef notdef
- XPRIVATE int comparator( p1, p2 )
- X char **p1, **p2 ;
- X{
- X return( strcmp( *p1, *p2 ) ) ;
- X}
- X
- X
- Xvoid env_sort( env )
- X env_h env ;
- X{
- X qsort( (char *)env->vars, env->n_vars, sizeof( char * ), comparator ) ;
- X}
- X#endif
- END_OF_FILE
- if test 4772 -ne `wc -c <'libs/src/misc/env.c'`; then
- echo shar: \"'libs/src/misc/env.c'\" unpacked with wrong size!
- fi
- # end of 'libs/src/misc/env.c'
- fi
- if test -f 'libs/src/sio/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/sio/README'\"
- else
- echo shar: Extracting \"'libs/src/sio/README'\" \(4739 characters\)
- sed "s/^X//" >'libs/src/sio/README' <<'END_OF_FILE'
- X======================================================================
- XNOTE: I use vi with a tabstop value of 3. Using the same tabstop
- X value will make the text/code look properly indented.
- X======================================================================
- X
- X
- X1. What is SIO ?
- X
- XSIO is a library that provides _stream_ I/O which is what most Unix
- Xprograms do. As such it is a competitor to stdio.
- X
- X
- X2. Why would you care to use it ?
- X
- Xa. SIO is a little faster than stdio
- Xb. SIO provides an easier-to-use interface (IMHO)
- Xc. SIO is capable of using memory mapping for reading files if the operating
- X system supports it.
- Xd. If you have a program that uses read(2)/write(2) it is trivial
- X to convert it to use SIO (just replace read with Sread and
- X write with Swrite)
- Xe. You get source
- X
- X
- X
- X3. Setting up the Stream I/O (SIO) library
- X
- XThere are 3 steps to the process:
- X 1) modifying the SIO configuration file (but you can skip this
- X step if you are using one of the operating systems listed below).
- X 2) testing SIO
- X 3) installing the library and manpages
- X
- X
- X3.1. How to compile the Stream I/O (SIO) library
- X
- XAll the system-dependent stuff of SIO is placed in the sioconf.h file.
- XIf your system is not listed below, you will need to read that file
- Xto see what flags you need to set to properly compile SIO.
- X
- XFor the following systems, here is what you need to do:
- X
- X SunOS 4.x:
- X make "DEFS=-DHAS_MMAP -DHAS_ONEXIT -DHAS_MEMOPS -DHAS_ISATTY"
- X
- X SunOS 5.x (aka Solaris 2.y):
- X make "DEFS=-DHAS_MMAP -DHAS_ATEXIT -DHAS_MEMOPS -DHAS_ISATTY"
- X (I don't have access to a system running Solaris 2.y so I have not
- X tested this)
- X
- X Ultrix 4.x:
- X make "DEFS=-DHAS_MEMOPS -DHAS_ATEXIT -DHAS_ISATTY"
- X
- XIf your system is one of the above, then you can skip to the next subsection.
- XHowever, I should mention that the library compiles by default with
- Xdebugging enabled (i.e. uses the -g flag of cc). You can override this
- Xby appending to the invocation of 'make' the argument "DEBUG=-O"
- X
- XIf your system is not among the above, then you will need to modify the
- Xsioconf.h file. You do this by uncommenting the inclusion of
- Xcustomconf.h. Then, you can override all constants/macros defined in
- Xsioconf.h by defining them first in customconf.h. Please read
- Xsioconf.h for more information on what constants/macros can be
- Xdefined.
- X
- XThe Makefile has a header that explains what the Makefile can do.
- XThe only flag that you may want to define is -DDEBUG which enables
- Xassertions in the SIO code (if an assertion fails, the program is
- Xterminated with an error message that lists the SIO file and line
- Xnumber where the error occured).
- X
- X
- X3.2. Testing SIO
- X
- XAfter you have successfully compiled SIO, you can use the programs in
- Xthe "suite" directory to test the SIO functions. Testing should be
- Xdone before installing the library.
- XThe script testlib does everything; just type:
- X
- X testlib all
- X
- XThe script sprint_test (invoked by testlib) tests Sprint by using a variety
- Xof formats and comparing its output with that of an ANSI-compatible printf.
- XAt least on Ultrix 4.1 and 4.2 this test fails because printf is not
- XANSI-compatible.
- XIn such a case, you can test the rest of the SIO functions by typing:
- X
- X testlib all Sprint
- X
- X(anything after the 'all' argument is interpreted as a function that
- Xshould not be tested).
- X
- XThe README file in the "suite" directory describes how to do a
- Xfew more tests that cannot be done automatically.
- X
- X
- X3.3. Installing the library and manpages
- X
- XThe 'make' command will create libsio.a in the current directory.
- XThe Makefile includes an "install" target. Doing a 'make install' will
- Xcause the following:
- X
- Xa) libsio.a will be installed in LIBDIR
- Xb) the necessary SIO header files will be installed in INCLUDEDIR
- Xc) the SIO man pages will be installed in MANDIR
- X
- XLIBDIR, INCLUDEDIR, and MANDIR are Makefile variables that you can edit in
- Xthe Makefile or override when you invoke 'make'.
- XHere is a sample command to install SIO:
- X
- X make install LIBDIR=/usr/local/lib INCLUDEDIR=/usr/local/include MANDIR=/usr/local/man/man3
- X
- X
- X4. Epilogue
- X
- XFeel free to modify SIO to suit your needs. Please let me know of
- Xany bugs you find.
- X
- XIf you want to distribute your modifications, please read the COPYRIGHT
- Xfile. It basically says that you are free to redistribute as long as
- Xyou retain the original copyright notice and you make sure that your
- Xmodifications are identifiable. In order to achieve this I have
- Xreserved the first 3 components of the version number (for example,
- X1.4.2) and you can identify your mods by appending another component to
- Xthat version number (for example, 1.4.2.A2). Also, if you distribute a
- Xmodified version of the library, you take full responsibility for any
- Xbugs in the code (not just your code; the whole thing).
- X
- END_OF_FILE
- if test 4739 -ne `wc -c <'libs/src/sio/README'`; then
- echo shar: \"'libs/src/sio/README'\" unpacked with wrong size!
- fi
- # end of 'libs/src/sio/README'
- fi
- if test -f 'xinetd/log.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/log.c'\"
- else
- echo shar: Extracting \"'xinetd/log.c'\" \(4978 characters\)
- sed "s/^X//" >'xinetd/log.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
- Xstatic char RCSid[] = "$Id: log.c,v 6.10 1993/06/15 23:25:57 panos Exp $" ;
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/wait.h>
- X#include <syslog.h>
- X#include <time.h>
- X
- X#include "sio.h"
- X#include "str.h"
- X
- X#include "connection.h"
- X#include "defs.h"
- X#include "access.h"
- X#include "sconst.h"
- X#include "service.h"
- X#include "server.h"
- X
- X
- Xvoid msg() ;
- X
- X#define LOGBUF_SIZE 1024
- X
- X
- Xtime_t time() ;
- X
- X
- XPRIVATE int log_common() ;
- X
- X/*
- X * This function writes log records of the form:
- X *
- X * START: service [pid] [from_address]
- X */
- Xvoid svc_log_success( sp, cp, pid )
- X register struct service *sp ;
- X connection_s *cp ;
- X pid_t pid ;
- X{
- X char buf[ LOGBUF_SIZE ] ;
- X int bufsize ;
- X register struct service_config *scp = SVC_CONF( sp ) ;
- X register int len ;
- X register int cc ;
- X
- X if ( ! SVC_LOGS_ON_SUCCESS( sp ) )
- X return ;
- X
- X bufsize = sizeof( buf ) ;
- X len = 0 ;
- X
- X cc = strx_nprint( buf, bufsize, "%s: %s", START_ENTRY, SC_ID( scp ) ) ;
- X len += cc ;
- X bufsize -= cc ;
- X
- X if ( SC_LOGS_PID( scp ) )
- X {
- X cc = strx_nprint( &buf[ len ], bufsize, " pid=%d", pid ) ;
- X len += cc ;
- X bufsize -= cc ;
- X }
- X
- X cc = log_common( &SC_LOG_ON_FAILURE( scp ), &buf[len], bufsize, cp ) ;
- X len += cc ;
- X bufsize -= cc ;
- X
- X xlog_write( sp->svc_log, buf, len, XLOG_NOFLAGS ) ;
- X}
- X
- X
- X/*
- X * This function writes log records of the form:
- X *
- X * FAIL: service failure-type [from_address]
- X *
- X */
- Xvoid svc_log_failure( sp, cp, access_failure )
- X register struct service *sp ;
- X connection_s *cp ;
- X access_e access_failure ;
- X{
- X char buf[ LOGBUF_SIZE ] ;
- X int bufsize ;
- X register struct service_config *scp = SVC_CONF( sp ) ;
- X register int len = 0 ;
- X register int cc ;
- X
- X if ( ! SVC_LOGS_ON_FAILURE( sp ) )
- X return ;
- X
- X bufsize = sizeof( buf ) ;
- X cc = strx_nprint( buf, bufsize, "%s: %s", FAIL_ENTRY, SC_ID( scp ) ) ;
- X len += cc ;
- X bufsize -= cc ;
- X
- X cc = strx_nprint( &buf[ len ], bufsize,
- X " %s", access_explain( access_failure ) ) ;
- X len += cc ;
- X bufsize -= cc ;
- X
- X cc = log_common( &SC_LOG_ON_FAILURE( scp ), &buf[ len ], bufsize, cp ) ;
- X len += cc ;
- X bufsize -= cc ;
- X
- X xlog_write( sp->svc_log, buf, len, XLOG_NOFLAGS ) ;
- X}
- X
- X
- X
- XPRIVATE int log_common( logmask, buf, bufsize, cp )
- X mask_t *logmask ;
- X char *buf ;
- X int bufsize ;
- X connection_s *cp ;
- X{
- X register int len = 0 ;
- X int cc ;
- X
- X if ( M_IS_SET( *logmask, LO_HOST ) )
- X {
- X cc = strx_nprint( &buf[ len ], bufsize, " from=%s", conn_addrstr( cp ) ) ;
- X len += cc ;
- X bufsize -= cc ;
- X }
- X return( len ) ;
- X}
- X
- X
- X
- Xvoid svc_log_exit( sp, serp )
- X register struct service *sp ;
- X struct server *serp ;
- X{
- X char buf[ LOGBUF_SIZE ] ;
- X int bufsize ;
- X register int cc ;
- X register int len ;
- X int exit_status = SERVER_EXITSTATUS( serp ) ;
- X register struct service_config *scp = SVC_CONF( sp ) ;
- X char *func = "log_exit" ;
- X
- X if ( ! SVC_LOGS_ON_EXIT( sp ) )
- X return ;
- X
- X bufsize = sizeof( buf ) ;
- X len = 0 ;
- X
- X cc = strx_nprint( buf, bufsize, "%s: %s", EXIT_ENTRY, SC_ID( scp ) ) ;
- X bufsize -= cc ;
- X len += cc ;
- X
- X /*
- X * If the EXIT flag was used, log the exit status or the signal that
- X * killed the process. We assume that these are the only reasons
- X * for process termination.
- X */
- X if ( SC_LOGS_EXITS( scp ) )
- X {
- X int num ;
- X char *s ;
- X
- X if ( PROC_EXITED( exit_status ) )
- X {
- X s = "status" ;
- X num = PROC_EXITSTATUS( exit_status ) ;
- X }
- X else if ( PROC_SIGNALED( exit_status ) )
- X {
- X s = "signal" ;
- X num = PROC_TERMSIG( exit_status ) ;
- X }
- X else
- X {
- X msg( LOG_ERR, func, "Bad exit status" ) ;
- X s = NULL ;
- X }
- X
- X if ( s )
- X {
- X cc = strx_nprint( &buf[ len ], bufsize, " %s=%d", s, num ) ;
- X len += cc ;
- X bufsize -= cc ;
- X }
- X }
- X
- X if ( SC_LOGS_PID( scp ) )
- X {
- X cc = strx_nprint( &buf[ len ], bufsize, " pid=%d", SERVER_PID( serp ) ) ;
- X len += cc ;
- X bufsize -= cc ;
- X }
- X
- X if ( SC_LOGS_DURATION( scp ) )
- X {
- X time_t current_time ;
- X
- X (void) time( ¤t_time ) ;
- X cc = strx_nprint( &buf[ len ], bufsize, " duration=%d(sec)",
- X current_time - SERVER_STARTTIME( serp ) ) ;
- X len += cc ;
- X bufsize -= cc ;
- X }
- X xlog_write( sp->svc_log, buf, len, XLOG_NOFLAGS ) ;
- X}
- X
- X
- X
- X/*
- X * Used by other parts of xinetd that want to log something without
- X * going through the proper channels (i.e. log_{success,failure} and log_exit)
- X */
- X/* VARARGS3 */
- Xvoid svc_logprint( sp, line_id, fmt, va_alist )
- X register struct service *sp ;
- X char *line_id ;
- X char *fmt ;
- X va_dcl
- X{
- X char buf[ LOGBUF_SIZE ] ;
- X int bufsize = sizeof( buf ) ;
- X int len ;
- X int cc ;
- X va_list ap ;
- X
- X if ( ! SVC_IS_LOGGING( sp ) )
- X return ;
- X
- X len = strx_nprint( buf, bufsize, "%s: %s ", line_id, SVC_ID( sp ) ) ;
- X va_start( ap ) ;
- X cc = strx_nprintv( &buf[ len ], bufsize, fmt, ap ) ;
- X va_end( ap ) ;
- X xlog_write( sp->svc_log, buf, len+cc, XLOG_NO_SIZECHECK ) ;
- X}
- X
- END_OF_FILE
- if test 4978 -ne `wc -c <'xinetd/log.c'`; then
- echo shar: \"'xinetd/log.c'\" unpacked with wrong size!
- fi
- # end of 'xinetd/log.c'
- fi
- if test -f 'xinetd/main.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/main.c'\"
- else
- echo shar: Extracting \"'xinetd/main.c'\" \(4832 characters\)
- sed "s/^X//" >'xinetd/main.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
- Xstatic char RCSid[] = "$Id: main.c,v 6.4 1993/06/06 00:10:02 panos Exp $" ;
- Xchar program_version[] = VERSION ;
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/time.h>
- X#include <errno.h>
- X#include <syslog.h>
- X
- X#include "sio.h"
- X
- X#include "options.h"
- X
- X#include "service.h"
- X#include "state.h"
- X
- X
- X/*
- X * The following are the only global variables of this program
- X */
- Xstruct program_state ps ;
- Xstruct debug debug ;
- X
- Xextern int errno ;
- X
- Xvoid exit() ;
- Xvoid msg() ;
- X
- X/*
- X * This is where the story starts...
- X */
- Xint main( argc, argv )
- X int argc ;
- X char *argv[] ;
- X{
- X char *func = "main" ;
- X PRIVATE void main_loop() ;
- X void init_services() ;
- X void init_daemon() ;
- X void enable_periodic_check() ;
- X
- X init_daemon( argc, argv ) ;
- X init_services() ;
- X
- X msg( LOG_NOTICE, func, "Started working: %d available service%s",
- X ps.rws.available_services,
- X ( ps.rws.available_services > 1 ) ? "s" : "" ) ;
- X
- X if ( cc_option )
- X#ifndef NO_TIMERS
- X enable_periodic_check( cc_option_arg ) ;
- X#else
- X msg( LOG_WARNING, func, "-cc option not supported" ) ;
- X#endif
- X
- X /*
- X * The reason for doing the setjmp here instead of in main_loop is
- X * that setjmp is not guaranteed to restore register values which
- X * can cause a problem for register variables
- X */
- X if ( setjmp( ps.rws.env ) == 0 )
- X ps.rws.env_is_valid = TRUE ;
- X
- X main_loop() ;
- X
- X /* NOTREACHED */
- X}
- X
- X
- X/*
- X * What main_loop does:
- X *
- X * check if any flags are set
- X * select on all active services
- X * for each socket where a request is pending
- X * try to start a server
- X */
- XPRIVATE void main_loop()
- X{
- X char *func = "main_loop" ;
- X PRIVATE void find_bad_fd() ;
- X void check_flags() ;
- X void signal_wait() ;
- X
- X for ( ;; )
- X {
- X fd_set read_mask ;
- X register int n_active ;
- X register unsigned u ;
- X
- X check_flags() ;
- X
- X if ( debug.on )
- X msg( LOG_DEBUG, func,
- X "active_services = %d", ps.rws.active_services ) ;
- X
- X if ( ps.rws.active_services == 0 )
- X {
- X signal_wait() ;
- X continue ;
- X }
- X
- X read_mask = ps.rws.socket_mask ;
- X n_active = select( ps.rws.mask_max+1, &read_mask,
- X FD_SET_NULL, FD_SET_NULL, TIMEVAL_NULL ) ;
- X if ( n_active == -1 )
- X {
- X if ( errno == EINTR )
- X continue ;
- X else if ( errno == EBADF )
- X find_bad_fd() ;
- X else
- X msg( LOG_NOTICE, func, "select error: %m" ) ;
- X continue ;
- X }
- X else if ( n_active == 0 )
- X continue ;
- X
- X if ( debug.on )
- X msg( LOG_DEBUG, func, "select returned %d", n_active ) ;
- X
- X for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
- X {
- X register struct service *sp ;
- X
- X sp = SP( pset_pointer( SERVICES( ps ), u ) ) ;
- X
- X if ( ! SVC_IS_ACTIVE( sp ) )
- X continue ;
- X
- X if ( FD_ISSET( SVC_FD( sp ), &read_mask ) )
- X {
- X svc_request( sp ) ;
- X if ( --n_active == 0 )
- X break ;
- X }
- X }
- X if ( n_active > 0 )
- X msg( LOG_ERR, func, "%d descriptors still set", n_active ) ;
- X }
- X}
- X
- X
- X
- X/*
- X * This function identifies if any of the fd's in the socket mask
- X * is bad. We use it in case select(2) returns EBADF
- X * When we identify such a bad fd, we remove it from the mask
- X * and deactivate the service.
- X */
- XPRIVATE void find_bad_fd()
- X{
- X register int fd ;
- X struct stat st ;
- X unsigned bad_fd_count = 0 ;
- X char *func = "find_bad_fd" ;
- X
- X for ( fd = 0 ; fd < ps.ros.max_descriptors ; fd++ )
- X if ( FD_ISSET( fd, &ps.rws.socket_mask ) && fstat( fd, &st ) == -1 )
- X {
- X int found = FALSE ;
- X register unsigned u ;
- X
- X for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
- X {
- X register struct service *sp ;
- X
- X sp = SP( pset_pointer( SERVICES( ps ), u ) ) ;
- X
- X if ( ! SVC_IS_AVAILABLE( sp ) )
- X continue ;
- X
- X if ( SVC_FD( sp ) == fd )
- X {
- X msg( LOG_ERR, func,
- X "file descriptor of service %s has been closed",
- X SVC_ID( sp ) ) ;
- X svc_deactivate( sp ) ;
- X found = TRUE ;
- X break ;
- X }
- X }
- X if ( ! found )
- X {
- X FD_CLR( fd, &ps.rws.socket_mask ) ;
- X msg( LOG_ERR, func,
- X "No active service for file descriptor %d\n", fd ) ;
- X bad_fd_count++ ;
- X }
- X }
- X if ( bad_fd_count == 0 )
- X msg( LOG_NOTICE, func,
- X "select reported EBADF but no bad file descriptors were found" ) ;
- X}
- X
- X
- X/*
- X * Deactivates all active processes.
- X * The real reason for doing this instead of just exiting is
- X * to deregister the RPC services
- X */
- Xvoid quit_program()
- X{
- X register unsigned u ;
- X char *func = "quit_program" ;
- X
- X for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
- X svc_deactivate( SP( pset_pointer( SERVICES( ps ), u ) ) ) ;
- X msg( LOG_WARNING, func, "Exiting..." ) ;
- X exit( 0 ) ;
- X}
- X
- X
- Xvoid terminate_program()
- X{
- X register unsigned u ;
- X void terminate_servers() ;
- X
- X for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
- X terminate_servers( SP( pset_pointer( SERVICES( ps ), u ) ) ) ;
- X quit_program() ;
- X}
- X
- END_OF_FILE
- if test 4832 -ne `wc -c <'xinetd/main.c'`; then
- echo shar: \"'xinetd/main.c'\" unpacked with wrong size!
- fi
- # end of 'xinetd/main.c'
- fi
- if test -f 'xinetd/sample.conf' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/sample.conf'\"
- else
- echo shar: Extracting \"'xinetd/sample.conf'\" \(4809 characters\)
- sed "s/^X//" >'xinetd/sample.conf' <<'END_OF_FILE'
- X#
- X# Sample configuration file for xinetd
- X#
- X
- Xdefaults
- X{
- X instances = 25
- X log_type = FILE /var/log/servicelog
- X log_on_success = HOST PID
- X log_on_failure = HOST RECORD
- X only_from = 128.138.193.0 128.138.204.0 128.138.209.0 128.138.243.0
- X only_from = localhost
- X disabled = tftp
- X}
- X
- X
- X#
- X# Group 1: BSD services
- X#
- X# Shell, login, exec, comsat, talk, ntalk
- X#
- X
- Xservice login
- X{
- X flags = REUSE
- X socket_type = stream
- X protocol = tcp
- X wait = no
- X user = root
- X server = /usr/etc/in.rlogind
- X log_type = SYSLOG local4 info
- X}
- X
- X
- Xservice shell
- X{
- X socket_type = stream
- X wait = no
- X user = root
- X instances = UNLIMITED
- X flags = IDONLY
- X log_on_success += USERID
- X server = /usr/etc/in.rshd
- X}
- X
- X
- Xservice exec
- X{
- X socket_type = stream
- X wait = no
- X user = root
- X server = /usr/etc/in.rexecd
- X}
- X
- Xservice comsat
- X{
- X socket_type = dgram
- X wait = yes
- X user = nobody
- X group = tty
- X server = /usr/etc/in.comsat
- X}
- X
- Xservice talk
- X{
- X socket_type = dgram
- X wait = yes
- X user = root
- X server = /usr/etc/in.talkd
- X}
- X
- Xservice ntalk
- X{
- X socket_type = dgram
- X wait = yes
- X user = root
- X server = /usr/etc/in.ntalkd
- X}
- X
- X#
- X# Group 2: standard Internet services
- X#
- X# Telnet, ftp
- X#
- Xservice telnet
- X{
- X flags = REUSE
- X socket_type = stream
- X wait = no
- X user = root
- X server = /usr/etc/in.telnetd
- X log_on_failure += USERID
- X}
- X
- Xservice ftp
- X{
- X socket_type = stream
- X wait = no
- X user = root
- X server = /usr/etc/in.ftpd
- X server_args = -l
- X instances = 4
- X log_on_success += DURATION USERID
- X log_on_failure += USERID
- X access_times = 2:00-8:59 12:00-23:59
- X nice = 10
- X}
- X
- X#
- X# Group 3: other services
- X#
- X
- X#
- X# Tnamed serves the obsolete IEN-116 name server protocol.
- X#
- Xservice name
- X{
- X socket_type = dgram
- X wait = yes
- X user = root
- X server = /usr/etc/in.tnamed
- X}
- X
- X#service uucp
- X#{
- X# socket_type = stream
- X# wait = no
- X# user = root
- X# server = /usr/etc/in.uucpd
- X#}
- X
- Xservice tftp
- X{
- X socket_type = dgram
- X wait = yes
- X user = root
- X server = /usr/etc/in.tftpd
- X server_args = -s /tftpboot
- X}
- X
- X
- X#
- X# Group 4: information services
- X#
- Xservice finger
- X{
- X socket_type = stream
- X wait = no
- X user = nobody
- X server = /usr/etc/in.fingerd
- X}
- X
- Xservice systat
- X{
- X socket_type = stream
- X wait = no
- X user = nobody
- X server = /usr/bin/ps
- X server_args = -auwwx
- X only_from = 128.138.209.0
- X log_on_success = HOST
- X}
- X
- Xservice netstat
- X{
- X socket_type = stream
- X wait = no
- X user = nobody
- X server = /usr/ucb/netstat
- X server_args = -f inet
- X only_from = 128.138.209.0
- X log_on_success = HOST
- X}
- X
- X
- X#
- X# Group 5: internal services
- X#
- X# echo, time, daytime, chargen, servers, services
- X#
- Xservice echo
- X{
- X type = INTERNAL
- X id = echo-stream
- X socket_type = stream
- X protocol = tcp
- X user = root
- X wait = no
- X}
- X
- Xservice echo
- X{
- X type = INTERNAL
- X id = echo-dgram
- X socket_type = dgram
- X protocol = udp
- X user = root
- X wait = yes
- X}
- X
- Xservice chargen
- X{
- X type = INTERNAL
- X id = chargen-stream
- X socket_type = stream
- X protocol = tcp
- X user = root
- X wait = no
- X}
- X
- Xservice chargen
- X{
- X type = INTERNAL
- X id = chargen-dgram
- X socket_type = dgram
- X protocol = udp
- X user = root
- X wait = yes
- X}
- X
- Xservice daytime
- X{
- X type = INTERNAL
- X id = daytime-stream
- X socket_type = stream
- X protocol = tcp
- X user = root
- X wait = no
- X}
- X
- Xservice daytime
- X{
- X type = INTERNAL
- X id = daytime-dgram
- X socket_type = dgram
- X protocol = udp
- X user = root
- X wait = yes
- X}
- X
- Xservice time
- X{
- X type = INTERNAL
- X id = time-stream
- X socket_type = stream
- X protocol = tcp
- X user = root
- X wait = no
- X}
- X
- X
- Xservice time
- X{
- X type = INTERNAL
- X id = time-dgram
- X socket_type = dgram
- X protocol = udp
- X user = root
- X wait = yes
- X}
- X
- X
- Xservice servers
- X{
- X type = INTERNAL UNLISTED
- X port = 9099
- X protocol = tcp
- X socket_type = stream
- X wait = no
- X instances = 2
- X}
- X
- X
- Xservice services
- X{
- X type = INTERNAL UNLISTED
- X port = 9098
- X protocol = tcp
- X socket_type = stream
- X wait = no
- X instances = 2
- X}
- X
- X
- X#
- X# Group 6: RPC services
- X#
- Xservice rstatd
- X{
- X type = RPC
- X flags = INTERCEPT
- X rpc_version = 2-4
- X socket_type = dgram
- X protocol = udp
- X server = /usr/etc/rpc.rstatd
- X wait = yes
- X user = root
- X}
- X
- Xservice rquotad
- X{
- X type = RPC
- X rpc_version = 1
- X socket_type = dgram
- X protocol = udp
- X wait = yes
- X user = root
- X server = /usr/etc/rpc.rstatd
- X}
- X
- Xservice rusersd
- X{
- X type = RPC
- X rpc_version = 1-2
- X socket_type = dgram
- X protocol = udp
- X wait = yes
- X user = root
- X server = /usr/etc/rpc.rusersd
- X}
- X
- Xservice sprayd
- X{
- X type = RPC
- X rpc_version = 1
- X socket_type = dgram
- X protocol = udp
- X wait = yes
- X user = root
- X server = /usr/etc/rpc.sprayd
- X}
- X
- Xservice walld
- X{
- X type = RPC
- X rpc_version = 1
- X socket_type = dgram
- X protocol = udp
- X wait = yes
- X user = nobody
- X group = tty
- X server = /usr/etc/rpc.rwalld
- X}
- X
- END_OF_FILE
- if test 4809 -ne `wc -c <'xinetd/sample.conf'`; then
- echo shar: \"'xinetd/sample.conf'\" unpacked with wrong size!
- fi
- # end of 'xinetd/sample.conf'
- fi
- echo shar: End of archive 11 \(of 31\).
- cp /dev/null ark11isdone
- 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
-