home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-26 | 27.1 KB | 1,177 lines |
- Newsgroups: comp.sources.unix
- From: panos@cs.colorado.edu (Panos Tsirigotis)
- Subject: v26i258: xinetd-2.1.1 - inetd replacement with access control and logging, Part14/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 258
- Archive-Name: xinetd-2.1.1/part14
-
- #! /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 14 (of 31)."
- # Contents: libs/src/timer/timer.c libs/src/xlog/filelog.c
- # xinetd/connection.c xinetd/ident.c
- # Wrapped by panos@mystique on Mon Jun 21 14:51:24 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'libs/src/timer/timer.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/timer/timer.c'\"
- else
- echo shar: Extracting \"'libs/src/timer/timer.c'\" \(5561 characters\)
- sed "s/^X//" >'libs/src/timer/timer.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 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: timer.c,v 4.2 1993/05/06 06:43:14 panos Exp $" ;
- Xstatic char *version = VERSION ;
- X
- X#include "timemacros.h"
- X#include "impl.h"
- X#include "defs.h"
- X
- X#define TIMER_H_NULL ((timer_h)NULL)
- X
- X
- Xint timer_errno ;
- X
- X
- X
- X/*
- X * Create a timer of the specified type.
- X * Returns a timer handle
- X */
- Xtimer_h timer_create( type, flags, errnop )
- X enum timer_types type ;
- X int flags ;
- X int *errnop ;
- X{
- X int *errp = ( errnop != NULL ) ? errnop : &timer_errno ;
- X timer_s *tp ;
- X
- X if ( type != TIMER_REAL && type != TIMER_VIRTUAL && type != TIMER_PROF )
- X HANDLE_ERROR( flags, TIMER_H_NULL, errp, TIMER_EBADTYPE,
- X "TIMER timer_create: bad timer type\n" ) ;
- X
- X tp = TIMER_ALLOC() ;
- X if ( tp == NULL )
- X {
- X *errp = TIMER_ENOMEM ;
- X return( TIMER_H_NULL ) ;
- X }
- X
- X tp->t_state = INACTIVE ;
- X tp->t_act = IDLE ;
- X tp->t_blocked = FALSE ;
- X
- X tp->t_errnop = errp ;
- X tp->t_flags = flags & TIMER_CREATE_FLAGS ;
- X tp->t_action.ta_func = NULL ;
- X tp->t_action.ta_arg = NULL ;
- X tp->t_action.ta_flags = TIMER_NOFLAGS ;
- X if ( __ostimer_newtimer( tp, type ) == TIMER_ERR )
- X {
- X TIMER_FREE( tp ) ;
- X return( TIMER_H_NULL ) ;
- X }
- X return( (timer_h) tp ) ;
- X}
- X
- X
- Xvoid timer_destroy( handle )
- X timer_h handle ;
- X{
- X timer_s *tp = TP( handle ) ;
- X
- X __ostimer_blockall() ;
- X
- X if ( tp->t_state == TICKING )
- X {
- X __ostimer_remove( tp->t_ostimer, tp ) ;
- X tp->t_state = DESTROYED ;
- X }
- X
- X if ( tp->t_act == IDLE || tp->t_act == PENDING )
- X TIMER_FREE( tp ) ;
- X
- X __ostimer_unblockall() ;
- X}
- X
- X
- Xint timer_start( handle, itvp, time_type, ap )
- X timer_h handle ;
- X struct itimerval *itvp ;
- X enum timer_timetypes time_type ;
- X struct timer_action *ap ;
- X{
- X int result ;
- X int ok_to_start ;
- X timer_s *tp = TP( handle ) ;
- X struct os_timer *otp = tp->t_ostimer ;
- X
- X __ostimer_blockall() ;
- X
- X /*
- X * We allow invoking timer_start from within the user-specified action
- X * after the timer has expired. However, we do not allow this for
- X * timers that have a t_interval (these timers stay at the TICKING state).
- X */
- X ok_to_start = tp->t_state == INACTIVE &&
- X ( tp->t_act == IDLE || tp->t_act == INVOKED ) ;
- X
- X if ( ! ok_to_start )
- X {
- X __ostimer_unblockall() ;
- X HANDLE_ERROR( tp->t_flags, TIMER_ERR, tp->t_errnop, TIMER_EBADSTATE,
- X "TIMER timer_start: timer state does not allow this operation\n" ) ;
- X }
- X
- X if ( itvp->it_value.tv_sec < 0 || itvp->it_value.tv_usec < 0 )
- X {
- X __ostimer_unblockall() ;
- X HANDLE_ERROR( tp->t_flags, TIMER_ERR, tp->t_errnop, TIMER_EBADTIME,
- X "TIMER timer_start: neg time value)\n" ) ;
- X }
- X
- X tp->t_action = *ap ;
- X tp->t_action.ta_flags &= TIMER_START_FLAGS ;
- X
- X result = __ostimer_add( otp, tp, itvp, time_type ) ;
- X __ostimer_unblockall() ;
- X return( result ) ;
- X}
- X
- X
- Xvoid timer_stop( handle )
- X timer_h handle ;
- X{
- X timer_s *tp = TP( handle ) ;
- X
- X __ostimer_blockall() ;
- X
- X if ( tp->t_state == TICKING )
- X {
- X __ostimer_remove( tp->t_ostimer, tp ) ;
- X tp->t_state = INACTIVE ;
- X }
- X
- X if ( tp->t_act == SCHEDULED )
- X tp->t_act = INVOKED ; /* to avoid the invocation */
- X else if ( tp->t_act == PENDING )
- X tp->t_act = IDLE ;
- X
- X tp->t_blocked = FALSE ;
- X
- X __ostimer_unblockall() ;
- X}
- X
- X
- Xvoid timer_block( handle )
- X timer_h handle ;
- X{
- X timer_s *tp = TP( handle ) ;
- X
- X __ostimer_blockall() ;
- X
- X if ( tp->t_state == TICKING ||
- X tp->t_state == INACTIVE &&
- X ( tp->t_act == PENDING || tp->t_act == SCHEDULED ) )
- X tp->t_blocked = TRUE ;
- X
- X __ostimer_unblockall() ;
- X}
- X
- X
- Xvoid timer_unblock( handle )
- X timer_h handle ;
- X{
- X timer_s *tp = TP( handle ) ;
- X
- X __ostimer_blockall() ;
- X
- X if ( tp->t_blocked )
- X {
- X tp->t_blocked = FALSE ;
- X if ( tp->t_act == PENDING )
- X {
- X tp->t_act = SCHEDULED ;
- X (void) __timer_invoke( tp ) ;
- X }
- X }
- X
- X __ostimer_unblockall() ;
- X}
- X
- X
- Xunsigned timer_expirations( handle )
- X timer_h handle ;
- X{
- X return( TP( handle )->t_count ) ;
- X}
- X
- X
- X
- X/*
- X * Invoke the action of the specified timer
- X * All timer interrupts should be blocked when this function is invoked
- X * Returns TRUE if
- X */
- Xenum timer_state __timer_invoke( tp )
- X register timer_s *tp ;
- X{
- X enum timer_state state ;
- X
- X /*
- X * The reason for the infinite loop is that the timer may reexpire
- X * while its function is being invoked.
- X */
- X for ( ;; )
- X {
- X /*
- X * This is the INVOKE part
- X */
- X if ( tp->t_blocked )
- X tp->t_act = PENDING ;
- X else
- X {
- X if ( tp->t_state != DESTROYED && tp->t_act == SCHEDULED )
- X {
- X void (*func)() = tp->t_action.ta_func ;
- X void *arg = tp->t_action.ta_arg ;
- X int flags = tp->t_action.ta_flags ;
- X
- X tp->t_act = INVOKED ;
- X tp->t_expirations = tp->t_count ;
- X tp->t_count = 0 ;
- X if ( func != NULL )
- X {
- X int unblock_all_intrs = ! ( flags & TIMER_BLOCK_ALL ) ;
- X int unblock_all_but_same_intr = ! ( flags & TIMER_BLOCK_SAME ) ;
- X
- X if ( unblock_all_intrs )
- X __ostimer_unblockall() ;
- X else if ( unblock_all_but_same_intr )
- X __ostimer_unblockall_except( tp->t_ostimer ) ;
- X
- X (*func)( tp, arg ) ;
- X
- X if ( unblock_all_intrs || unblock_all_but_same_intr )
- X __ostimer_blockall() ;
- X }
- X else if ( arg != NULL )
- X {
- X int *ip = (int *) arg ;
- X
- X if ( flags & TIMER_INC_VAR )
- X *ip += tp->t_expirations ;
- X else
- X *ip = 1 ;
- X }
- X }
- X }
- X
- X state = tp->t_state ;
- X
- X /*
- X * This is the RETURN part
- X */
- X if ( tp->t_state == DESTROYED )
- X TIMER_FREE( tp ) ;
- X else
- X {
- X if ( tp->t_act == INVOKED )
- X tp->t_act = IDLE ;
- X else if ( tp->t_act == SCHEDULED )
- X continue ;
- X }
- X break ;
- X }
- X return( state ) ;
- X}
- X
- END_OF_FILE
- if test 5561 -ne `wc -c <'libs/src/timer/timer.c'`; then
- echo shar: \"'libs/src/timer/timer.c'\" unpacked with wrong size!
- fi
- # end of 'libs/src/timer/timer.c'
- fi
- if test -f 'libs/src/xlog/filelog.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/xlog/filelog.c'\"
- else
- echo shar: Extracting \"'libs/src/xlog/filelog.c'\" \(5812 characters\)
- sed "s/^X//" >'libs/src/xlog/filelog.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: filelog.c,v 2.2 1993/06/15 18:08:01 panos Exp $" ;
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <varargs.h>
- X#include <fcntl.h>
- X#include <time.h>
- X#ifndef NO_SYSLOG
- X#include <syslog.h>
- X#else
- X#define LOG_ALERT 0
- X#endif
- X
- X#include "sio.h"
- X
- X#include "xlog.h"
- X#include "impl.h"
- X#include "filelog.h"
- X
- XPRIVATE int filelog_init() ;
- XPRIVATE void filelog_fini() ;
- XPRIVATE int filelog_control() ;
- XPRIVATE int filelog_write() ;
- XPRIVATE int filelog_parms() ;
- XPRIVATE int limit_checks() ;
- X
- Xstruct xlog_ops __xlog_filelog_ops =
- X {
- X filelog_init,
- X filelog_fini,
- X filelog_write,
- X filelog_control,
- X filelog_parms
- X } ;
- X
- X
- XPRIVATE int filelog_init( xp, ap )
- X xlog_s *xp ;
- X va_list ap ;
- X{
- X int fd ;
- X struct filelog *flp ;
- X char *filename = va_arg( ap, char * ) ;
- X int flags = va_arg( ap, int ) ;
- X
- X flp = NEW( struct filelog ) ;
- X if ( flp == NULL )
- X return( XLOG_ENOMEM ) ;
- X
- X if ( flags & O_CREAT )
- X fd = open( filename, flags, va_arg( ap, int ) ) ;
- X else
- X fd = open( filename, flags ) ;
- X
- X if ( fd == -1 )
- X {
- X FREE( flp ) ;
- X return( XLOG_EOPEN ) ;
- X }
- X
- X FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
- X (void) Sbuftype( fd, SIO_LINEBUF ) ;
- X flp->fl_fd = fd ;
- X flp->fl_state = FL_OPEN ;
- X xp->xl_data = flp ;
- X return( XLOG_ENOERROR ) ;
- X}
- X
- X
- XPRIVATE void filelog_fini( xp )
- X xlog_s *xp ;
- X{
- X struct filelog *flp = FILELOG( xp ) ;
- X
- X if ( flp->fl_state != FL_CLOSED )
- X {
- X (void) close( flp->fl_fd ) ;
- X flp->fl_state = FL_CLOSED ;
- X }
- X FREE( flp ) ;
- X xp->xl_data = NULL ;
- X}
- X
- X
- X
- XPRIVATE int filelog_control( xp, cmd, ap )
- X xlog_s *xp ;
- X xlog_cmd_e cmd ;
- X va_list ap ;
- X{
- X struct stat st ;
- X struct filelog *flp = FILELOG( xp ) ;
- X int status = XLOG_ENOERROR ;
- X
- X if ( flp->fl_state == FL_ERROR )
- X return( flp->fl_error ) ;
- X
- X switch ( cmd )
- X {
- X case XLOG_GETFD:
- X if ( flp->fl_state == FL_OPEN )
- X *va_arg( ap, int * ) = flp->fl_fd ;
- X else
- X status = XLOG_ENOERROR ;
- X break ;
- X
- X case XLOG_LIMITS:
- X flp->fl_soft_limit = va_arg( ap, unsigned ) ;
- X flp->fl_hard_limit = va_arg( ap, unsigned ) ;
- X flp->fl_issued_warning = FALSE ;
- X FILELOG_ENABLE_SIZE_CONTROL( flp ) ;
- X flp->fl_state = FL_OPEN ;
- X /* FALL THROUGH */
- X
- X case XLOG_SIZECHECK:
- X if ( ! FILELOG_SIZE_CONTROL( flp ) )
- X break ;
- X if ( fstat( flp->fl_fd, &st ) == -1 )
- X {
- X FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
- X flp->fl_state = FL_ERROR ;
- X flp->fl_error = status = XLOG_EFSTAT ;
- X }
- X else
- X {
- X flp->fl_size = st.st_size ;
- X if ( flp->fl_size > flp->fl_soft_limit )
- X status = limit_checks( xp ) ;
- X }
- X break ;
- X }
- X return( status ) ;
- X}
- X
- X
- XPRIVATE int limit_checks( xp )
- X xlog_s *xp ;
- X{
- X struct filelog *flp = FILELOG( xp ) ;
- X char buf[ 100 ] ;
- X
- X if ( ! flp->fl_issued_warning )
- X {
- X if ( xp->xl_use != NULL )
- X xlog_write( (xlog_h) xp->xl_use, buf,
- X strx_nprint( buf, sizeof( buf ),
- X "soft limit exceeded on '%s'", xp->xl_id ),
- X XLOG_NOFLAGS, LOG_ALERT ) ;
- X flp->fl_issued_warning = TRUE ;
- X }
- X
- X if ( flp->fl_size <= flp->fl_hard_limit )
- X return( XLOG_ENOERROR ) ;
- X
- X if ( xp->xl_use != NULL )
- X xlog_write( (xlog_h) xp->xl_use, buf,
- X strx_nprint( buf, sizeof( buf ),
- X "hard limit exceeded on '%s'; log closed", xp->xl_id ),
- X XLOG_NOFLAGS, LOG_ALERT ) ;
- X flp->fl_state = FL_ERROR ;
- X return( XLOG_ESIZE ) ;
- X}
- X
- X
- XPRIVATE int filelog_write( xp, buf, len, flags, ap )
- X xlog_s *xp ;
- X char buf[] ;
- X int len ;
- X int flags ;
- X va_list ap ;
- X{
- X struct filelog *flp = FILELOG( xp ) ;
- X int action_flags = ( xp->xl_flags | flags ) ;
- X int msglen = 0 ;
- X char *percent_m_pos ;
- X int cc ;
- X int status ;
- X time_t current_time ;
- X struct tm *tmp ;
- X time_t time() ;
- X
- X if ( flp->fl_state != FL_OPEN )
- X return( flp->fl_error ) ;
- X
- X (void) time( ¤t_time ) ;
- X tmp = localtime( ¤t_time ) ;
- X cc = Sprint( flp->fl_fd, "%d/%d/%d@%02d:%02d:%02d",
- X tmp->tm_year, tmp->tm_mon+1, tmp->tm_mday,
- X tmp->tm_hour, tmp->tm_min, tmp->tm_sec ) ;
- X msglen += cc ;
- X
- X if ( action_flags & XLOG_PRINT_ID )
- X {
- X cc = Sprint( flp->fl_fd, " %s", xp->xl_id ) ;
- X msglen += cc ;
- X }
- X
- X if ( action_flags & XLOG_PRINT_PID )
- X {
- X cc = Sprint( flp->fl_fd, "[%d]", getpid() ) ;
- X msglen += cc ;
- X }
- X
- X cc = Sprint( flp->fl_fd, ": " ) ;
- X msglen += cc ;
- X
- X if ( ( action_flags & XLOG_NO_ERRNO ) ||
- X ( percent_m_pos = __xlog_add_errno( buf, len ) ) == NULL )
- X {
- X cc = Swrite( flp->fl_fd, buf, len ) ;
- X msglen += cc ;
- X }
- X else
- X {
- X char errno_buf[ 100 ] ;
- X unsigned size = sizeof( errno_buf ) ;
- X int cc_before_errno = percent_m_pos - buf ;
- X char *ep ;
- X
- X /*
- X * The reason for the repetition of "msglen += cc ;" is that in the
- X * future we may want to check cc for SIO_ERR
- X */
- X ep = __xlog_explain_errno( errno_buf, &size ) ;
- X cc = Swrite( flp->fl_fd, buf, cc_before_errno ) ;
- X msglen += cc ;
- X cc = Swrite( flp->fl_fd, ep, (int)size ) ;
- X msglen += cc ;
- X cc = Swrite( flp->fl_fd, percent_m_pos+2, len-cc_before_errno-2 ) ;
- X msglen += cc ;
- X }
- X /*
- X * Writing a newline will cause a buffer flush since we asked for
- X * line-buffered output
- X */
- X Sputchar( flp->fl_fd, '\n' ) ;
- X msglen++ ;
- X
- X /*
- X * NOTE: we don't check if XLOG_NO_SIZECHECK is set in xp->xl_flags
- X * because size control is off by default and in order to
- X * be enabled XLOG_LIMITS must be used which overrides xp->xl_flags
- X */
- X if ( ! FILELOG_SIZE_CONTROL( flp ) || ( flags & XLOG_NO_SIZECHECK ) )
- X return( XLOG_ENOERROR ) ;
- X
- X flp->fl_size += msglen ;
- X if ( flp->fl_size <= flp->fl_soft_limit ||
- X ( status = limit_checks( xp ) ) == XLOG_ENOERROR )
- X return( XLOG_ENOERROR ) ;
- X
- X flp->fl_state = FL_SIZE ;
- X return( status ) ;
- X}
- X
- X
- XPRIVATE int filelog_parms( ap )
- X va_list ap ;
- X{
- X return( XLOG_ENOERROR ) ;
- X}
- X
- END_OF_FILE
- if test 5812 -ne `wc -c <'libs/src/xlog/filelog.c'`; then
- echo shar: \"'libs/src/xlog/filelog.c'\" unpacked with wrong size!
- fi
- # end of 'libs/src/xlog/filelog.c'
- fi
- if test -f 'xinetd/connection.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/connection.c'\"
- else
- echo shar: Extracting \"'xinetd/connection.c'\" \(5909 characters\)
- sed "s/^X//" >'xinetd/connection.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: connection.c,v 6.5 1993/06/13 01:42:57 panos Exp $" ;
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <syslog.h>
- X
- X#include "sio.h"
- X
- X#include "connection.h"
- X#include "service.h"
- X#include "state.h"
- X
- Xchar *inet_ntoa() ;
- Xchar *malloc() ;
- X
- Xvoid msg() ;
- Xvoid out_of_memory() ;
- X
- X#define NEW_CONN() NEW( connection_s )
- X#define FREE_CONN( cop ) FREE( cop )
- X
- X
- X/*
- X * Get a new connection request and initialize 'cp' appropriately
- X */
- XPRIVATE status_e get_connection( sp, cp )
- X register struct service *sp ;
- X register connection_s *cp ;
- X{
- X int sin_len = sizeof( cp->co_remote_address ) ;
- X char *func = "get_connection" ;
- X
- X if ( SVC_ACCEPTS_CONNECTIONS( sp ) )
- X {
- X cp->co_descriptor = accept( SVC_FD( sp ),
- X SA( &cp->co_remote_address ), &sin_len ) ;
- X if ( cp->co_descriptor == -1 )
- X {
- X msg( LOG_ERR, func, "service %s, accept: %m", SVC_ID( sp ) ) ;
- X return( FAILED ) ;
- X }
- X M_SET( cp->co_flags, COF_HAVE_ADDRESS ) ;
- X M_SET( cp->co_flags, COF_NEW_DESCRIPTOR ) ;
- X }
- X else
- X {
- X if ( SVC_SOCKET_TYPE( sp ) == SOCK_DGRAM )
- X {
- X char t_ch ;
- X
- X /*
- X * This trick is done to get the remote address.
- X * select(2) guaranteed that we won't block on the recvfrom
- X */
- X if ( recvfrom( SVC_FD( sp ), &t_ch, 1, MSG_PEEK,
- X SA( &cp->co_remote_address ), &sin_len ) == -1 )
- X {
- X msg( LOG_ERR, func, "service %s, recvfrom: %m", SVC_ID( sp ) ) ;
- X return( FAILED ) ;
- X }
- X M_SET( cp->co_flags, COF_HAVE_ADDRESS ) ;
- X }
- X cp->co_descriptor = SVC_FD( sp ) ;
- X }
- X return( OK ) ;
- X}
- X
- X
- X
- X/*
- X * Get a connection for the specified service and return a pointer
- X * to a new connection_s
- X */
- Xconnection_s *conn_new( sp )
- X register struct service *sp ;
- X{
- X connection_s new_conn ;
- X register connection_s *cp ;
- X char *func = "conn_new" ;
- X
- X CLEAR( new_conn ) ;
- X
- X /*
- X * The reason we first get the connection and then allocate a
- X * 'connection_s' is because we want to always consume some input.
- X */
- X if ( get_connection( sp, &new_conn ) == FAILED )
- X return( NULL ) ;
- X
- X new_conn.co_state = CONN_OPEN ;
- X new_conn.co_sp = sp ;
- X SVC_HOLD( sp ) ;
- X if ( SVC_WAITS( sp ) )
- X svc_suspend( sp ) ;
- X
- X cp = NEW_CONN() ;
- X if ( cp == CONN_NULL )
- X {
- X out_of_memory( func ) ;
- X conn_cleanup( &new_conn ) ;
- X conn_shutdown( &new_conn ) ;
- X conn_free( &new_conn ) ;
- X return( CONN_NULL ) ;
- X }
- X *cp = new_conn ;
- X return( cp ) ;
- X}
- X
- X
- X/*
- X * Close the connection descriptor if it is a new one
- X */
- Xvoid conn_close( cp )
- X register connection_s *cp ;
- X{
- X if ( cp->co_state == CONN_OPEN &&
- X M_IS_SET( cp->co_flags, COF_NEW_DESCRIPTOR ) )
- X {
- X (void) close( cp->co_descriptor ) ;
- X cp->co_state = CONN_CLOSED ;
- X }
- X}
- X
- X
- X/*
- X * Release the specified connection.
- X * Certain actions may be performed before doing this:
- X * - invocation of the service shutdown function
- X * - drain of a single UDP packet if the socket type is SOCK_DGRAM
- X */
- Xvoid conn_free( cp )
- X register connection_s *cp ;
- X{
- X register struct service *sp = cp->co_sp ;
- X int i ;
- X void drain() ;
- X
- X if ( SVC_IS_SUSPENDED( sp ) )
- X svc_resume( sp ) ;
- X
- X if ( cp->co_state == CONN_OPEN )
- X {
- X if ( M_IS_SET( cp->co_flags, COF_SHUTDOWN ) )
- X svc_shutdown( sp, cp, (char **)NULL ) ;
- X
- X if ( M_IS_SET( cp->co_flags, COF_CLEANUP ) &&
- X SVC_SOCKET_TYPE( sp ) == SOCK_DGRAM )
- X drain( cp->co_descriptor ) ;
- X }
- X
- X if ( SVC_RELE( sp ) == 0 )
- X pset_remove( SERVICES( ps ), sp ) ;
- X
- X for ( i = 0 ; i < cp->co_alternative_count ; i++ )
- X {
- X struct service *asp = cp->co_alternatives[ i ] ;
- X
- X if ( SVC_RELE( asp ) == 0 )
- X pset_remove( SERVICES( ps ), asp ) ;
- X }
- X
- X conn_close( cp ) ;
- X
- X FREE_CONN( cp ) ;
- X}
- X
- X
- Xstatus_e conn_add_alternative( cp, sp )
- X register connection_s *cp ;
- X register struct service *sp ;
- X{
- X char *func = "conn_add_alternative" ;
- X
- X if ( sp == NULL )
- X return( FAILED ) ;
- X
- X if ( cp->co_alternative_count >= MAX_ALTERNATIVES )
- X {
- X msg( LOG_ERR, func,
- X "Cannot add alternative service %s to connection for service %s",
- X SVC_ID( sp ), SVC_ID( cp->co_sp ) ) ;
- X return( FAILED ) ;
- X }
- X
- X if ( debug.on )
- X msg( LOG_DEBUG, func,
- X "Adding alternative service %s to connection of service %s",
- X SVC_ID( sp ), SVC_ID( cp->co_sp ) ) ;
- X
- X cp->co_alternatives[ cp->co_alternative_count++ ] = sp ;
- X SVC_HOLD( sp ) ;
- X return( OK ) ;
- X}
- X
- X
- X/*
- X * Start invoking alternative services starting from the next alternative one
- X * until either we get a successful invocation or we run out of services
- X */
- Xstatus_e conn_start_alternative( cp )
- X register connection_s *cp ;
- X{
- X char *func = "conn_start_alternative" ;
- X
- X while ( cp->co_next_alternative < cp->co_alternative_count )
- X {
- X struct service *asp = cp->co_alternatives[ cp->co_next_alternative++ ] ;
- X
- X if ( svc_handle( asp, cp ) == OK )
- X {
- X if ( debug.on )
- X msg( LOG_DEBUG, func,
- X "Started alternative service %s", SVC_ID( asp ) ) ;
- X return( OK ) ;
- X }
- X }
- X return( FAILED ) ;
- X}
- X
- X
- Xvoid conn_dump( cp, fd )
- X register connection_s *cp ;
- X int fd ;
- X{
- X register unsigned u ;
- X void tabprint() ;
- X
- X tabprint( fd, 1, "state = %s\n",
- X ( cp->co_state == CONN_CLOSED ) ? "CLOSED" : "OPEN" ) ;
- X
- X tabprint( fd, 1, "service = %s\n", SVC_ID( cp->co_sp ) ) ;
- X tabprint( fd, 1, "descriptor = %d\n", cp->co_descriptor ) ;
- X tabprint( fd, 1, "flags = %#x\n", cp->co_flags ) ;
- X tabprint( fd, 1, "remote_address = %s,%d\n",
- X inet_ntoa( cp->co_remote_address.sin_addr ),
- X ntohs( cp->co_remote_address.sin_port ) ) ;
- X tabprint( fd, 1, "Alternative services = " ) ;
- X for ( u = 0 ; u < cp->co_alternative_count ; u++ )
- X Sprint( fd, " %s", SVC_ID( cp->co_alternatives[ u ] ) ) ;
- X Sputchar( fd, '\n' ) ;
- X if ( cp->co_alternative_count > 0 )
- X tabprint( fd, 1, "next alternative service = %s\n",
- X SVC_ID( cp->co_alternatives[ cp->co_next_alternative ] ) ) ;
- X}
- X
- END_OF_FILE
- if test 5909 -ne `wc -c <'xinetd/connection.c'`; then
- echo shar: \"'xinetd/connection.c'\" unpacked with wrong size!
- fi
- # end of 'xinetd/connection.c'
- fi
- if test -f 'xinetd/ident.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/ident.c'\"
- else
- echo shar: Extracting \"'xinetd/ident.c'\" \(6151 characters\)
- sed "s/^X//" >'xinetd/ident.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: ident.c,v 6.5 1993/06/06 00:25:40 panos Exp $" ;
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <signal.h>
- X#include <syslog.h>
- X#include <setjmp.h>
- X#include <errno.h>
- X#include <fcntl.h>
- X#include <string.h>
- X#include <ctype.h>
- X
- X#include "str.h"
- X
- X#include "defs.h"
- X#include "sconst.h"
- X#include "server.h"
- X
- Xvoid msg() ;
- Xstatus_e write_buf() ;
- X
- X
- X#define BUFSIZE 1024 /* RFC-1413 suggests 1000 */
- X
- X#define START_TIMER( t ) (void) alarm( t )
- X#define STOP_TIMER() (void) alarm( 0 )
- X
- Xchar *inet_ntoa() ;
- X
- X
- Xstatic jmp_buf env ;
- X
- X
- XPRIVATE void sigalrm_handler()
- X{
- X longjmp( env, 1 ) ;
- X}
- X
- X
- X/*
- X * This function always runs in a forked process.
- X */
- Xidresult_e log_remote_user( serp, timeout )
- X struct server *serp ;
- X unsigned timeout ; /* in seconds */
- X{
- X static char buf[ BUFSIZE ] ;
- X int cc ;
- X struct sockaddr_in sin_local ;
- X struct sockaddr_in sin_remote ;
- X struct sockaddr_in sin_contact ;
- X unsigned local_port ;
- X unsigned remote_port ;
- X int sd ;
- X int sin_len ;
- X char *p ;
- X char *func = "log_remote_user" ;
- X PRIVATE char *get_line() ;
- X PRIVATE char *verify_line() ;
- X
- X#ifndef NO_TIMERS
- X /*
- X * Although expiring timers are harmless, they still take time to process
- X */
- X STOP_TIMER() ;
- X#endif
- X
- X if ( timeout && (int) signal( SIGALRM, sigalrm_handler ) == -1 )
- X {
- X msg( LOG_ERR, func, "signal: %m" ) ;
- X return( IDR_ERROR ) ;
- X }
- X
- X /*
- X * Determine local and remote addresses
- X */
- X sin_len = sizeof( sin_local ) ;
- X if ( getsockname( SERVER_FD( serp ), SA( &sin_local ), &sin_len ) == -1 )
- X {
- X msg( LOG_ERR, func, "getsockname: %m" ) ;
- X return( IDR_ERROR ) ;
- X }
- X
- X if ( ! conn_address( SERVER_CONNECTION( serp ) ) )
- X {
- X /*
- X * This shouldn't happen since identification only works for
- X * connection-based services.
- X */
- X msg( LOG_ERR, func, "connection has no address" ) ;
- X return( IDR_ERROR ) ;
- X }
- X
- X sin_remote = *conn_address( SERVER_CONNECTION( serp ) ) ;
- X local_port = ntohs( sin_local.sin_port ) ;
- X remote_port = ntohs( sin_remote.sin_port ) ;
- X
- X /*
- X * Create a socket and set the close-on-exec flag on the descriptor.
- X * We set the flag in case we are called as part of a successful
- X * attempt to start a server (i.e. execve will follow).
- X */
- X sd = socket( AF_INET, SOCK_STREAM, 0 ) ;
- X if ( sd == -1 )
- X {
- X msg( LOG_ERR, func, "socket creation: %m" ) ;
- X return( IDR_ERROR ) ;
- X }
- X if ( fcntl( sd, F_SETFD, 1 ) == -1 )
- X {
- X msg( LOG_ERR, func, "fcntl F_SETFD: %m" ) ;
- X (void) close( sd ) ;
- X return( IDR_ERROR ) ;
- X }
- X
- X CLEAR( sin_contact ) ;
- X sin_contact.sin_family = sin_remote.sin_family ;
- X sin_contact.sin_addr = sin_remote.sin_addr ;
- X sin_contact.sin_port = htons( IDENTITY_SERVICE_PORT ) ;
- X
- X if ( timeout )
- X if ( setjmp( env ) == 0 )
- X START_TIMER( timeout ) ;
- X else
- X return( IDR_TIMEDOUT ) ;
- X
- X if ( connect( sd, SA( &sin_contact ), sizeof( sin_contact ) ) == -1 )
- X {
- X if ( timeout )
- X STOP_TIMER() ;
- X return( IDR_NOSERVER ) ;
- X }
- X
- X cc = strx_nprint( buf, sizeof( buf ),
- X "%d,%d\r\n", remote_port, local_port ) ;
- X if ( write_buf( sd, buf, cc ) == FAILED )
- X {
- X if ( timeout )
- X STOP_TIMER() ;
- X return( IDR_ERROR ) ;
- X }
- X
- X p = get_line( sd, buf, sizeof( buf ) ) ;
- X
- X if ( timeout )
- X STOP_TIMER() ;
- X
- X if ( p == NULL )
- X return( IDR_RESPERR ) ;
- X
- X /*
- X * Verify that the received line is OK
- X */
- X if ( ( p = verify_line( buf, local_port, remote_port ) ) == NULL )
- X {
- X msg( LOG_ERR, func, "Bad line received from identity server at %s: %s",
- X inet_ntoa( sin_remote.sin_addr ), buf ) ;
- X return( IDR_BADRESP ) ;
- X }
- X
- X svc_logprint( SERVER_CONNSERVICE( serp ), USERID_ENTRY, "%s", p ) ;
- X return( IDR_OK ) ;
- X}
- X
- X
- XPRIVATE char *verify_line( line, local_port, remote_port )
- X char *line ;
- X unsigned local_port ;
- X unsigned remote_port ;
- X{
- X register char *p ;
- X register char *start = line ;
- X
- X /*
- X * Verify port numbers
- X */
- X p = strchr( start, ',' ) ;
- X if ( p == NULL )
- X return( NULL ) ;
- X *p = NUL ;
- X if ( atoi( start ) != remote_port )
- X return( NULL ) ;
- X
- X start = p+1 ;
- X p = strchr( start, ':' ) ;
- X if ( p == NULL )
- X return( NULL ) ;
- X *p = NUL ;
- X if ( atoi( start ) != local_port )
- X return( NULL ) ;
- X
- X /*
- X * Look for the 'USERID' string
- X */
- X {
- X char *line_id = "USERID" ;
- X int line_id_len = strlen( line_id ) ;
- X
- X start = p+1 ;
- X for ( p = start ; isspace( *p ) ; p++ ) ;
- X if ( *p == NUL )
- X return( NULL ) ;
- X start = p ;
- X if ( strncmp( start, line_id, line_id_len ) != 0 )
- X return( NULL ) ;
- X start += line_id_len ; /* skip it */
- X }
- X
- X for ( p = start ; isspace( *p ) ; p++ ) ; /* skip any white-space */
- X if ( *p != ':' )
- X return( NULL ) ;
- X for ( p++ ; isspace( *p ) ; p++ ) ;
- X if ( *p == NUL )
- X return( NULL ) ;
- X return( p ) ;
- X}
- X
- X
- X
- X/*
- X * Get a line terminated by CR-LF.
- X * Replace the CR-LF with NUL.
- X */
- XPRIVATE char *get_line( sd, buf, bufsize )
- X int sd ;
- X register char *buf ;
- X unsigned bufsize ;
- X{
- X int size ;
- X register int cc ;
- X register char *p ;
- X register char *s ;
- X char *func = "get_line" ;
- X
- X for ( p = buf, size = bufsize ; size > 0 ; p += cc, size -= cc )
- X {
- X cc = read( sd, p, size ) ;
- X if ( cc == -1 )
- X if ( errno == EINTR )
- X {
- X cc = 0 ;
- X continue ;
- X }
- X else
- X {
- X msg( LOG_ERR, func, "read: %m" ) ;
- X return( CHAR_NULL ) ;
- X }
- X for ( s = p ; s < p + cc ; s++ )
- X if ( *s == '\n' && s != buf && s[-1] == '\r' )
- X {
- X s[-1] = NUL ;
- X return( buf ) ;
- X }
- X }
- X msg( LOG_ERR, func, "Too much input from identity server" ) ;
- X return( CHAR_NULL ) ;
- X}
- X
- X
- Xchar *idresult_explain( result )
- X idresult_e result ;
- X{
- X char *reason = "UNKNOWN" ;
- X
- X switch ( result )
- X {
- X case IDR_OK:
- X reason = "no error" ;
- X break ;
- X
- X case IDR_NOSERVER:
- X reason = "no server" ;
- X break ;
- X
- X case IDR_TIMEDOUT:
- X reason = "timeout" ;
- X break ;
- X
- X case IDR_ERROR:
- X reason = "system error" ;
- X break ;
- X
- X case IDR_RESPERR:
- X reason = "error while receiving response" ;
- X break ;
- X
- X case IDR_BADRESP:
- X reason = "bad response" ;
- X break ;
- X }
- X return( reason ) ;
- X}
- X
- END_OF_FILE
- if test 6151 -ne `wc -c <'xinetd/ident.c'`; then
- echo shar: \"'xinetd/ident.c'\" unpacked with wrong size!
- fi
- # end of 'xinetd/ident.c'
- fi
- echo shar: End of archive 14 \(of 31\).
- cp /dev/null ark14isdone
- 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
-