home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.unix
- From: panos@cs.colorado.edu (Panos Tsirigotis)
- Subject: v26i261: xinetd-2.1.1 - inetd replacement with access control and logging, Part17/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 261
- Archive-Name: xinetd-2.1.1/part17
-
- #! /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 17 (of 31)."
- # Contents: libs/src/timer/sysdep.c xinetd/tcpint.c xinetd/xinetd.man
- # Wrapped by panos@mystique on Mon Jun 21 14:51:25 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'libs/src/timer/sysdep.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/timer/sysdep.c'\"
- else
- echo shar: Extracting \"'libs/src/timer/sysdep.c'\" \(7453 characters\)
- sed "s/^X//" >'libs/src/timer/sysdep.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
- X#include <signal.h>
- X#include <sys/time.h>
- X#include <sys/resource.h>
- X
- X#include "defs.h"
- X#include "impl.h"
- X#include "ostimer.h"
- X#include "timemacros.h"
- X
- X
- XPRIVATE void sigalrm_handler() ;
- XPRIVATE void sigvtalrm_handler() ;
- XPRIVATE void sigprof_handler() ;
- X
- XPRIVATE void get_real_time() ;
- XPRIVATE void get_virtual_time() ;
- XPRIVATE void get_prof_time() ;
- X
- X#define SIGNOSIG 0
- X
- Xstatic struct os_timer os_timers[] =
- X {
- X#ifdef ITIMER_REAL
- X { AVAILABLE, ITIMER_REAL,
- X#else
- X { UNAVAILABLE, 0,
- X#endif
- X TIMER_REAL, SIGALRM, sigalrm_handler, get_real_time },
- X
- X#ifdef ITIMER_VIRTUAL
- X { AVAILABLE, ITIMER_VIRTUAL,
- X#else
- X { UNAVAILABLE, 0,
- X#endif
- X TIMER_VIRTUAL, SIGVTALRM, sigvtalrm_handler, get_virtual_time },
- X
- X#ifdef ITIMER_PROF
- X { AVAILABLE, ITIMER_PROF,
- X#else
- X { UNAVAILABLE, 0,
- X#endif
- X TIMER_PROF, SIGPROF, sigprof_handler, get_prof_time },
- X
- X { UNAVAILABLE, 0,
- X TIMER_REAL, SIGNOSIG, NULL, NULL, }
- X } ;
- X
- X
- X/*
- X * The timer_block_mask blocks all timer signals when a timer signal
- X * happens (using the sa_mask field of struct sigaction). This is necessary
- X * when the user function associated with the timer does not return.
- X * Consider the following scenario:
- X * The user creates 2 timers, one TIMER_REAL (signal: SIGALRM), one
- X * TIMER_VIRTUAL (signal: SIGVTALRM).
- X * SIGALRM occurs first but before it is handled, SIGVTALRM happens.
- X * At this point both SIGARLM and SIGVTALRM are blocked.
- X * SIGVTALRM gets unblocked and the function for the TIMER_VIRTUAL is
- X * invoked and never returns. The function for the TIMER_REAL is never
- X * invoked (and any TIMER_REAL timers never expire).
- X */
- X#ifndef NO_POSIX_SIGS
- Xstatic sigset_t timer_block_mask ;
- X#else
- Xstatic int timer_block_mask ;
- X#endif
- X
- Xstatic int timer_block_mask_set ; /* flag */
- X
- X
- X/*
- X * Initialize the timer_block_mask.
- X * As a side-effect it also initializes the block_mask of each ostimer.
- X */
- XPRIVATE void set_timer_block_mask()
- X{
- X ostimer_s *otp ;
- X
- X#ifndef NO_POSIX_SIGS
- X (void) sigemptyset( &timer_block_mask ) ;
- X#else
- X /* timer_block_mask is a global variable so it is initialized to 0 */
- X#endif
- X
- X for ( otp = &os_timers[ 0 ] ; otp->ost_handler ; otp++ )
- X {
- X#ifndef NO_POSIX_SIGS
- X (void) sigemptyset( &otp->ost_block_mask ) ;
- X (void) sigaddset( &otp->ost_block_mask, otp->ost_signal ) ;
- X (void) sigaddset( &timer_block_mask, otp->ost_signal ) ;
- X#else
- X otp->ost_block_mask = sigmask( otp->ost_signal ) ;
- X timer_block_mask |= otp->ost_block_mask ;
- X#endif
- X }
- X
- X timer_block_mask_set = TRUE ;
- X}
- X
- X
- XPRIVATE ostimer_s *ostimer_find( type )
- X enum timer_types type ;
- X{
- X register ostimer_s *otp ;
- X
- X for ( otp = os_timers ; otp->ost_handler ; otp++ )
- X if ( otp->ost_timertype == type )
- X return( otp->ost_availability == AVAILABLE ? otp : OSTIMER_NULL ) ;
- X return( OSTIMER_NULL ) ;
- X}
- X
- X
- XPRIVATE int time_compare( p1, p2 )
- X pq_obj p1, p2 ;
- X{
- X return( TV_LT( TP( p1 )->t_expiration, TP( p2 )->t_expiration ) ) ;
- X}
- X
- X
- X/*
- X * Initialize an OS timer. The initialization steps are:
- X *
- X * create priority queue
- X * install signal handler
- X *
- X * We also initialize the timer_block_mask if it has not been initialized yet.
- X */
- Xostimer_s *__ostimer_init( tp, type )
- X timer_s *tp ;
- X enum timer_types type ;
- X{
- X#ifndef NO_POSIX_SIGS
- X struct sigaction sa ;
- X#else
- X struct sigvec sv ;
- X#endif
- X ostimer_s *otp ;
- X struct timer_q *tqp ;
- X
- X /*
- X * Find the corresponding ostimer
- X */
- X if ( ( otp = ostimer_find( type ) ) == OSTIMER_NULL )
- X HANDLE_ERROR( tp->t_flags, OSTIMER_NULL,
- X tp->t_errnop, TIMER_ENOTAVAILABLE,
- X "TIMER __ostimer_init: requested timer type not available\n" ) ;
- X
- X /*
- X * We use the value of ost_timerq to determine if the os_timer
- X * has been initialized.
- X */
- X tqp = &otp->ost_timerq ;
- X if ( tqp->tq_handle )
- X return( otp ) ;
- X
- X tqp->tq_handle = pq_create( time_compare,
- X tp->t_flags & TIMER_RETURN_ERROR ? PQ_RETURN_ERROR : PQ_NOFLAGS,
- X &tqp->tq_errno ) ;
- X if ( tqp->tq_handle == NULL )
- X {
- X *tp->t_errnop = TIMER_ENOMEM ;
- X return( OSTIMER_NULL ) ;
- X }
- X
- X if ( ! timer_block_mask_set )
- X set_timer_block_mask() ;
- X
- X#ifndef NO_POSIX_SIGS
- X sa.sa_handler = otp->ost_handler ;
- X sa.sa_mask = timer_block_mask ;
- X sa.sa_flags = 0 ;
- X if ( sigaction( otp->ost_signal, &sa, SIGACTION_NULL ) == -1 )
- X#else
- X sv.sv_handler = otp->ost_handler ;
- X sv.sv_mask = timer_block_mask ;
- X sv.sv_flags = 0 ;
- X if ( sigvec( otp->ost_signal, &sv, SIGVEC_NULL ) == -1 )
- X#endif
- X HANDLE_ERROR( tp->t_flags, OSTIMER_NULL, tp->t_errnop, TIMER_ESIGPROBLEM,
- X "TIMER __ostimer_init: signal handler installation failed\n" ) ;
- X return( otp ) ;
- X}
- X
- X
- X/*
- X * timer_* functions that need access to private data of ostimer
- X */
- Xvoid timer_block_type( type )
- X enum timer_types type ;
- X{
- X ostimer_s *otp = ostimer_find( type ) ;
- X
- X if ( otp == OSTIMER_NULL )
- X return ;
- X
- X#ifndef NO_POSIX_SIGS
- X (void) sigprocmask( SIG_BLOCK, &otp->ost_block_mask, SIGSET_NULL ) ;
- X#else
- X (void) sigblock( otp->ost_block_mask ) ;
- X#endif
- X}
- X
- X
- Xvoid timer_unblock_type( type )
- X enum timer_types type ;
- X{
- X ostimer_s *otp = ostimer_find( type ) ;
- X
- X if ( otp == OSTIMER_NULL )
- X return ;
- X
- X#ifndef NO_POSIX_SIGS
- X (void) sigprocmask( SIG_UNBLOCK, &otp->ost_block_mask, SIGSET_NULL ) ;
- X#else
- X {
- X int old_mask = sigblock( ~0 ) ;
- X
- X (void) sigsetmask( old_mask & ~otp->ost_block_mask ) ;
- X }
- X#endif
- X}
- X
- X
- Xvoid __ostimer_blockall()
- X{
- X#ifndef NO_POSIX_SIGS
- X (void) sigprocmask( SIG_BLOCK, &timer_block_mask, SIGSET_NULL ) ;
- X#else
- X (void) sigblock( timer_block_mask ) ;
- X#endif
- X}
- X
- X
- Xvoid __ostimer_unblockall()
- X{
- X#ifndef NO_POSIX_SIGS
- X (void) sigprocmask( SIG_UNBLOCK, &timer_block_mask, SIGSET_NULL ) ;
- X#else
- X int old_mask = sigblock( ~0 ) ;
- X
- X (void) sigsetmask( old_mask & ~timer_block_mask ) ;
- X#endif
- X}
- X
- X
- Xvoid __ostimer_unblockall_except( otp )
- X ostimer_s *otp ;
- X{
- X#ifndef NO_POSIX_SIGS
- X sigset_t new_mask = timer_block_mask ;
- X
- X (void) sigdelset( &new_mask, otp->ost_signal ) ;
- X (void) sigprocmask( SIG_UNBLOCK, &new_mask, SIGSET_NULL ) ;
- X#else
- X int old_mask = sigblock( ~0 ) ;
- X
- X (void) sigsetmask( ( old_mask & ~timer_block_mask )
- X | otp->ost_block_mask ) ;
- X#endif
- X}
- X
- X
- XPRIVATE void sigalrm_handler()
- X{
- X#ifdef DEBUG_MSGS
- X printf( "\tSIGALRM happened\n" ) ;
- X#endif
- X __ostimer_interrupt( &os_timers[ (int)TIMER_REAL ] ) ;
- X}
- X
- X
- XPRIVATE void sigvtalrm_handler()
- X{
- X#ifdef DEBUG_MSGS
- X printf( "\tSIGVTALRM happened\n" ) ;
- X#endif
- X __ostimer_interrupt( &os_timers[ (int)TIMER_VIRTUAL ] ) ;
- X}
- X
- X
- XPRIVATE void sigprof_handler()
- X{
- X#ifdef DEBUG_MSGS
- X printf( "\tSIGPROF happened\n" ) ;
- X#endif
- X __ostimer_interrupt( &os_timers[ (int)TIMER_PROF ] ) ;
- X}
- X
- X
- XPRIVATE void get_real_time( tvp )
- X struct timeval *tvp ;
- X{
- X#ifdef ITIMER_REAL
- X (void) gettimeofday( tvp, TIMEZONE_NULL ) ;
- X#endif
- X}
- X
- X
- XPRIVATE void get_virtual_time( tvp )
- X struct timeval *tvp ;
- X{
- X#ifdef ITIMER_VIRTUAL
- X struct rusage ru ;
- X
- X (void) getrusage( RUSAGE_SELF, &ru ) ;
- X *tvp = ru.ru_utime ;
- X#endif
- X}
- X
- X
- XPRIVATE void get_prof_time( tvp )
- X struct timeval *tvp ;
- X{
- X#ifdef ITIMER_PROF
- X struct rusage ru ;
- X
- X (void) getrusage( RUSAGE_SELF, &ru ) ;
- X TV_ADD( *tvp, ru.ru_utime, ru.ru_stime ) ;
- X#endif
- X}
- X
- X
- END_OF_FILE
- if test 7453 -ne `wc -c <'libs/src/timer/sysdep.c'`; then
- echo shar: \"'libs/src/timer/sysdep.c'\" unpacked with wrong size!
- fi
- # end of 'libs/src/timer/sysdep.c'
- fi
- if test -f 'xinetd/tcpint.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/tcpint.c'\"
- else
- echo shar: Extracting \"'xinetd/tcpint.c'\" \(7988 characters\)
- sed "s/^X//" >'xinetd/tcpint.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: tcpint.c,v 6.6 1993/06/15 23:25:57 panos Exp $" ;
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/time.h>
- X#include <syslog.h>
- X#include <signal.h>
- X#include <errno.h>
- X
- X#include "config.h"
- X#include "int.h"
- X#include "access.h"
- X#include "defs.h"
- X
- Xchar *inet_ntoa() ;
- Xvoid msg() ;
- X
- Xtypedef enum { S_OK, S_SERVER_ERR, S_CLIENT_ERR } stream_status_e ;
- X
- Xstruct istream_private
- X{
- X unsigned accepted_connections ;
- X} ;
- X
- X#define SIP( p ) ((struct istream_private *)(p))
- X
- Xstatic struct istream_private istream ;
- X
- XPRIVATE void si_mux() ;
- XPRIVATE void si_exit() ;
- X
- Xstatic struct intercept_ops istream_ops =
- X {
- X si_mux,
- X si_exit
- X } ;
- X
- Xstatic struct intercept stream_intercept_state ;
- X
- X
- Xstruct intercept *si_init( serp )
- X struct server *serp ;
- X{
- X register struct intercept *ip = &stream_intercept_state ;
- X
- X ip->int_socket_type = SOCK_STREAM ;
- X ip->int_priv = (void *) &istream ;
- X ip->int_ops = &istream_ops ;
- X int_init( ip, serp ) ;
- X if ( (int) signal( SIGPIPE, SIG_IGN ) == -1 )
- X int_fail( ip, "signal" ) ;
- X return( ip ) ;
- X}
- X
- X
- XPRIVATE void si_exit()
- X{
- X register struct intercept *ip = &stream_intercept_state ;
- X
- X if ( SIP( ip->int_priv )->accepted_connections == 0 )
- X (void) accept( INT_REMOTE( ip ), SA( NULL ), INT_NULL ) ;
- X int_exit( ip ) ;
- X}
- X
- X
- XPRIVATE void si_mux()
- X{
- X register struct intercept *ip = &stream_intercept_state ;
- X fd_set socket_mask ;
- X int mask_max ;
- X psi_h iter ;
- X char *func = "si_mux" ;
- X PRIVATE status_e handle_io() ;
- X PRIVATE stream_status_e tcp_local_to_remote() ;
- X PRIVATE stream_status_e tcp_remote_to_local() ;
- X PRIVATE void connection_request() ;
- X
- X FD_ZERO( &socket_mask ) ;
- X FD_SET( INT_REMOTE( ip ), &socket_mask ) ;
- X mask_max = INT_REMOTE( ip ) ;
- X
- X iter = psi_create( INT_CONNECTIONS( ip ) ) ;
- X if ( iter == NULL )
- X {
- X msg( LOG_ERR, func, ES_NOMEM ) ;
- X return ;
- X }
- X
- X for ( ;; )
- X {
- X channel_s *chp ;
- X fd_set read_mask ;
- X int n_ready ;
- X
- X read_mask = socket_mask ;
- X n_ready = int_select( mask_max+1, &read_mask ) ;
- X
- X if ( n_ready == -1 )
- X return ;
- X
- X if ( FD_ISSET( INT_REMOTE( ip ), &read_mask ) )
- X {
- X connection_request( ip, &chp ) ;
- X if ( chp != NULL )
- X {
- X FD_SET( chp->ch_local_socket, &socket_mask ) ;
- X if ( chp->ch_local_socket > mask_max )
- X mask_max = chp->ch_local_socket ;
- X FD_SET( chp->ch_remote_socket, &socket_mask ) ;
- X if ( chp->ch_remote_socket > mask_max )
- X mask_max = chp->ch_remote_socket ;
- X }
- X if ( --n_ready == 0 )
- X continue ;
- X }
- X
- X for ( chp = CHP( psi_start(iter) ) ; chp ; chp = CHP( psi_next(iter) ) )
- X {
- X if ( FD_ISSET( chp->ch_local_socket, &read_mask ) )
- X {
- X#ifdef DEBUG_TCPINT
- X if ( debug.on )
- X msg( LOG_DEBUG, func, "Input available on local socket %d",
- X chp->ch_local_socket ) ;
- X#endif
- X if ( handle_io( iter, chp,
- X &socket_mask, tcp_local_to_remote ) == FAILED )
- X return ;
- X if ( --n_ready == 0 )
- X break ;
- X }
- X
- X if ( FD_ISSET( chp->ch_remote_socket, &read_mask ) )
- X {
- X#ifdef DEBUG_TCPINT
- X msg( LOG_DEBUG, func, "Input available on remote socket %d",
- X chp->ch_remote_socket ) ;
- X#endif
- X if ( handle_io( iter, chp,
- X &socket_mask, tcp_remote_to_local ) == FAILED )
- X return ;
- X if ( --n_ready == 0 )
- X break ;
- X }
- X }
- X }
- X}
- X
- X
- XPRIVATE status_e handle_io( iter, chp, maskp, iofunc )
- X psi_h iter ;
- X channel_s *chp ;
- X fd_set *maskp ;
- X stream_status_e (*iofunc)() ;
- X{
- X char *func = "handle_io" ;
- X
- X switch ( (*iofunc)( chp ) )
- X {
- X case S_SERVER_ERR:
- X return( FAILED ) ;
- X
- X case S_CLIENT_ERR:
- X
- X if ( debug.on )
- X msg( LOG_DEBUG, func,
- X "Closing channel to %s,%d using sockets %d(l),%d(r)",
- X inet_ntoa( chp->ch_from.sin_addr ),
- X ntohs( chp->ch_from.sin_port ),
- X chp->ch_local_socket, chp->ch_remote_socket ) ;
- X
- X FD_CLR( chp->ch_local_socket, maskp ) ;
- X FD_CLR( chp->ch_remote_socket, maskp ) ;
- X (void) close( chp->ch_remote_socket ) ;
- X (void) close( chp->ch_local_socket ) ;
- X psi_remove( iter ) ;
- X FREE_CHANNEL( chp ) ;
- X break ;
- X }
- X return( OK ) ;
- X}
- X
- X
- XPRIVATE void connection_request( ip, chpp )
- X struct intercept *ip ;
- X channel_s **chpp ;
- X{
- X struct sockaddr_in sin ;
- X int sin_len = sizeof( sin ) ;
- X channel_s *chp ;
- X int sd ;
- X bool_int addr_checked ;
- X char *func = "connection_request" ;
- X
- X *chpp = NULL ;
- X
- X if ( ( sd = accept( INT_REMOTE( ip ), SA( &sin ), &sin_len ) ) == -1 )
- X return ;
- X
- X SIP( ip->int_priv )->accepted_connections++ ;
- X
- X if ( debug.on )
- X msg( LOG_DEBUG, func, "connection request from %s,%d",
- X inet_ntoa( sin.sin_addr ), ntohs( sin.sin_port ) ) ;
- X
- X chp = int_lookupconn( ip, &sin, &addr_checked ) ;
- X if ( chp == NULL )
- X {
- X struct server *serp = INT_SERVER( ip ) ;
- X struct service *sp = SERVER_SERVICE( serp ) ;
- X connection_s *cop = SERVER_CONNECTION( serp ) ;
- X
- X conn_setaddr( cop, &sin ) ;
- X
- X if ( INTERCEPT( ip ) )
- X {
- X mask_t check_mask ;
- X access_e result ;
- X
- X M_OR( check_mask, MASK( CF_ADDRESS ), MASK( CF_TIME ) ) ;
- X result = access_control( sp, cop, &check_mask ) ;
- X
- X if ( result != AC_OK )
- X {
- X svc_log_failure( sp, cop, result ) ;
- X (void) close( sd ) ;
- X return ;
- X }
- X }
- X
- X if ( ( chp = int_newconn( ip, &sin, sd ) ) == NULL )
- X {
- X (void) close( sd ) ;
- X return ;
- X }
- X
- X if ( ! addr_checked )
- X svc_log_success( sp, cop, SERVER_PID( serp ) ) ;
- X
- X#if defined( TCP_NODELAY )
- X {
- X int on = 1 ;
- X
- X (void) setsockopt( chp->ch_local_socket, IPPROTO_TCP,
- X TCP_NODELAY, (char *) &on, sizeof( on ) ) ;
- X (void) setsockopt( chp->ch_remote_socket, IPPROTO_TCP,
- X TCP_NODELAY, (char *) &on, sizeof( on ) ) ;
- X }
- X#endif /* TCP_NODELAY */
- X
- X *chpp = chp ;
- X }
- X else
- X msg( LOG_ERR, func,
- X "Received another connection request from %s,%d",
- X inet_ntoa( sin.sin_addr ), ntohs( sin.sin_port ) ) ;
- X}
- X
- X
- XPRIVATE stream_status_e tcp_local_to_remote( chp )
- X channel_s *chp ;
- X{
- X char buf[ DATAGRAM_SIZE ] ;
- X int rcc, wcc ;
- X char *p ;
- X int left ;
- X char *func = "tcp_local_to_remote" ;
- X
- X for ( ;; )
- X {
- X rcc = recv( chp->ch_local_socket, buf, sizeof( buf ), 0 ) ;
- X if ( rcc == 0 )
- X return( S_SERVER_ERR ) ;
- X else if ( rcc == -1 )
- X {
- X if ( errno != EINTR )
- X {
- X msg( LOG_ERR, func, "recv: %m" ) ;
- X return( S_SERVER_ERR ) ;
- X }
- X }
- X else
- X break ;
- X }
- X
- X for ( p = buf, left = rcc ; left ; p += wcc, left -= wcc )
- X {
- X wcc = send( chp->ch_remote_socket, p, left, 0 ) ;
- X if ( wcc == 0 )
- X return( S_CLIENT_ERR ) ;
- X else if ( wcc == -1 )
- X {
- X if ( errno == EINTR )
- X wcc = 0 ;
- X else
- X {
- X msg( LOG_ERR, func, "send: %m" ) ;
- X return( S_CLIENT_ERR ) ;
- X }
- X }
- X }
- X
- X#ifdef DEBUG_TCPINT
- X if ( debug.on )
- X msg( LOG_DEBUG, func,
- X "Transferred %d bytes from local socket %d to remote socket %d",
- X rcc, chp->ch_local_socket, chp->ch_remote_socket ) ;
- X#endif
- X
- X return( S_OK ) ;
- X}
- X
- X
- XPRIVATE stream_status_e tcp_remote_to_local( chp )
- X channel_s *chp ;
- X{
- X char buf[ DATAGRAM_SIZE ] ;
- X int rcc, wcc ;
- X int left ;
- X char *p ;
- X char *func = "tcp_remote_to_local" ;
- X
- X for ( ;; )
- X {
- X rcc = recv( chp->ch_remote_socket, buf, sizeof( buf ), 0 ) ;
- X if ( rcc == 0 )
- X return( S_CLIENT_ERR ) ;
- X else if ( rcc == -1 )
- X {
- X if ( errno != EINTR )
- X {
- X msg( LOG_ERR, func, "recv: %m" ) ;
- X return( S_CLIENT_ERR ) ;
- X }
- X }
- X else
- X break ;
- X }
- X
- X for ( p = buf, left = rcc ; left ; p += wcc, left -= wcc )
- X {
- X wcc = send( chp->ch_local_socket, p, left, 0 ) ;
- X if ( wcc == 0 )
- X return( S_SERVER_ERR ) ;
- X else if ( wcc == -1 )
- X if ( errno == EINTR )
- X rcc = 0 ;
- X else
- X {
- X msg( LOG_ERR, func, "send: %m" ) ;
- X return( S_SERVER_ERR ) ;
- X }
- X }
- X
- X#ifdef DEBUG_TCPINT
- X if ( debug.on )
- X msg( LOG_DEBUG, func,
- X "Transferred %d bytes from remote socket %d to local socket %d",
- X rcc, chp->ch_remote_socket, chp->ch_local_socket ) ;
- X#endif
- X
- X return( S_OK ) ;
- X}
- X
- END_OF_FILE
- if test 7988 -ne `wc -c <'xinetd/tcpint.c'`; then
- echo shar: \"'xinetd/tcpint.c'\" unpacked with wrong size!
- fi
- # end of 'xinetd/tcpint.c'
- fi
- if test -f 'xinetd/xinetd.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/xinetd.man'\"
- else
- echo shar: Extracting \"'xinetd/xinetd.man'\" \(7518 characters\)
- sed "s/^X//" >'xinetd/xinetd.man' <<'END_OF_FILE'
- 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.\" $Id: xinetd.man,v 6.4 1993/06/06 00:13:03 panos Exp $
- X.TH XINETD 1L "28 April 1993"
- X.\" *************************** NAME *********************************
- X.SH NAME
- Xxinetd \- the extended Internet services daemon
- X.\" *************************** SYNOPSIS *********************************
- X.SH SYNOPSIS
- X.B xinetd
- X[\fIoptions\fP]
- X.\" *************************** DESCRIPTION *********************************
- X.SH DESCRIPTION
- X\fBxinetd\fP performs the same function as \fBinetd\fP: it starts
- Xprograms that provide Internet services. Instead of having such
- Xservers started at system initialization time, and be dormant until a
- Xconnection request arrives, \fBxinetd\fP is the only daemon process
- Xstarted and it listens on all service ports for the services listed in
- Xits configuration file. When a request comes in, \fBxinetd\fP starts
- Xthe appropriate server. Because of the way it operates, \fBxinetd\fP
- X(as well as \fBinetd\fP) is also referred to as a super-server.
- X.LP
- XThe services listed in \fBxinetd\fP's configuration file can be
- Xseparated into two groups. Services in the first group are called
- X.I "multi-threaded"
- Xand they require the forking of a new server process for each new
- Xconnection request. The new server then handles that connection. For
- Xsuch services, \fBxinetd\fP keeps listening for new requests so that it
- Xcan spawn new servers. On the other hand, the second group includes
- Xservices for which the service daemon is responsible for handling all
- Xnew connection requests. Such services are called
- X.I "single-threaded"
- Xand \fBxinetd\fP will stop handling new requests for them until the
- Xserver dies. Services in this group are usually datagram-based.
- X.LP
- XSo far, the only reason for the existence of a super-server was to
- Xconserve system resources by avoiding to fork a lot of processes which
- Xmight be dormant for most of their lifetime. While fulfilling this
- Xfunction, \fBxinetd\fP takes advantage of the idea of a super-server to
- Xprovide features such as access control and logging. Furthermore,
- X\fBxinetd\fP is not limited to services listed in
- X.I /etc/services.
- XTherefore, anybody can use \fBxinetd\fP to start special-purpose
- Xservers.
- X.\" *************************** OPTIONS *********************************
- X.SH OPTIONS
- X.TP
- X.BR \-d
- XEnables debug mode. This produces a lot of debugging output, and it
- Xmakes it possible to use a debugger on \fBxinetd\fP.
- X.TP
- X.BI \-syslog " syslog_facility"
- XThis option enables syslog logging of \fBxinetd\fP-produced messages
- Xusing the specified syslog facility.
- XThe following facility names are supported:
- X.I daemon,
- X.I auth,
- X.I user,
- X.I "local[0-7]"
- X(check \fIsyslog.conf(5)\fP for their meanings).
- XThis option is ineffective in debug mode since all relevant messages are sent
- Xto the terminal.
- X.TP
- X.BI \-filelog " logfile"
- X\fBxinetd\fP-produced messages will be placed in the specified file.
- XMessages are always appended to the file.
- XIf the file does not exist, it will be created.
- XThis option is ineffective in debug mode since all relevant messages are sent
- Xto the terminal.
- X.TP
- X.BI \-f " config_file"
- XDetermines the file that \fBxinetd\fP uses for configuration. The
- Xdefault is \fI/etc/xinetd.conf\fP.
- X.TP
- X.BR \-pid
- X.br
- XThe process ID is written to standard error.
- XThis option is ineffective in debug mode.
- X.TP
- X.BI \-loop " rate"
- XThis option sets the loop rate beyond which a service is considered in
- Xerror and is deactivated. The loop rate is specified in terms of
- Xthe number of servers per second that can be forked for a process.
- XThe speed of your machine determines the correct value for this option.
- XThe default rate is 10.
- X.TP
- X.BR \-reuse
- XIf this option is used, \fBxinetd\fP will set the socket option
- X\fISO_REUSEADDR\fP before binding the service socket to an Internet
- Xaddress. This allows binding of the address even if there are programs
- Xthat use it, which happens when a previous instance of \fBxinetd\fP
- Xhas started some servers that are still running.
- XThis option has no effect on
- X.SM RPC
- Xservices.
- X.TP
- X.BI \-limit " proc_limit"
- XThis option places a limit on the number of concurrently running processes
- Xthat can be started by
- X.B xinetd.
- XIts purpose is to prevent process table overflows.
- X.TP
- X.BI \-logprocs " limit"
- XThis option places a limit on the number of concurrently running servers
- Xfor remote userid acquisition.
- X.TP
- X.BI \-shutdownprocs " limit"
- XThis option places a limit on the number of concurrently running servers
- Xfor service shutdown (forked when the
- X.SB RECORD
- Xoption is used).
- X.TP
- X.BI \-cc " interval"
- XThis option instructs
- X.B xinetd
- Xto perform periodic consistency checks on its internal state every
- X.I interval
- Xseconds.
- X.LP
- XThe \fIsyslog\fP and \fIfilelog\fP options are mutually exclusive.
- XIf none is specified, the default is syslog using the
- X.I daemon
- Xfacility.
- XYou should not confuse \fBxinetd\fP messages with messages related to
- Xservice logging. The latter are logged only if this is specified
- Xvia the configuration file.
- X.\" *********************** CONTROLLING XINETD ****************************
- X.SH "CONTROLLING XINETD"
- X.LP
- X\fBxinetd\fP performs certain actions when it receives certain signals.
- XThe actions associated with the specific signals can be redefined
- Xby editing \fIconfig.h\fP and recompiling.
- X.TP 15
- X.SB SIGUSR1
- Xcauses a soft reconfiguration, which means that \fBxinetd\fP rereads
- Xthe configuration file and adjusts accordingly.
- X.TP
- X.SB SIGUSR2
- Xcauses a hard reconfiguration, which is the same as a soft reconfiguration
- Xexcept that servers for services that are no longer available are
- Xterminated. Access control is performed again on running servers
- Xby checking the remote location, access times and server instances.
- XIf the number of server instances is lowered, some arbitrarily picked
- Xservers will be killed
- Xto satisfy the limit; this will happen \fIafter\fP any servers are
- Xterminated because of failing the remote location or access time checks.
- XAlso, if the
- X.SB INTERCEPT
- Xflag was clear and is set, any running servers for that service will
- Xbe terminated;
- X\fIthe purpose of this is to ensure that after a hard reconfiguration
- Xthere will be no running servers that can accept packets from addresses
- Xthat do not meet the access control criteria\fP.
- X.TP
- X.SB SIGQUIT
- Xcauses program termination.
- X.TP
- X.SB SIGTERM
- Xterminates all running servers before terminating \fBxinetd\fP.
- X.TP
- X.SB SIGHUP
- Xcauses an internal state dump (the default dump file is
- X\fI/tmp/xinetd.dump\fP;
- Xto change the filename, edit \fIconfig.h\fP and recompile).
- X.TP
- X.SB SIGIOT
- Xcauses an internal consistency check to verify that the data structures
- Xused by the program have not been corrupted.
- XWhen the check is completed
- X.B xinetd
- Xwill generate a message that says if the check was successful or not.
- X.LP
- XOn reconfiguration the log files are closed and reopened. This allows
- Xremoval of old log files.
- X.\" *********************** FILES ****************************
- X.SH FILES
- X.LP
- X.PD .1v
- X.TP 20
- X.SB /etc/xinetd.conf
- Xdefault configuration file
- X.TP
- X.SB /tmp/xinetd.dump
- Xdefault dump file
- X.PD
- X.\" *********************** SEE ALSO ****************************
- X.SH "SEE ALSO"
- X.I "inetd(8),"
- X.LP
- X.I "xinetd.conf(5),"
- X.LP
- X.I "xinetd.log(5)"
- X.\" *********************** AUTHOR ****************************
- X.SH AUTHOR
- XPanos Tsirigotis, CS Dept, University of Colorado, Boulder
- X.\" *********************** PRONUNCIATION ****************************
- X.SH PRONUNCIATION
- Xzy-net-d
- X
- END_OF_FILE
- if test 7518 -ne `wc -c <'xinetd/xinetd.man'`; then
- echo shar: \"'xinetd/xinetd.man'\" unpacked with wrong size!
- fi
- # end of 'xinetd/xinetd.man'
- fi
- echo shar: End of archive 17 \(of 31\).
- cp /dev/null ark17isdone
- 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
-