home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / xinetd21 / part17 < prev    next >
Encoding:
Text File  |  1993-06-26  |  25.9 KB  |  970 lines

  1. Newsgroups: comp.sources.unix
  2. From: panos@cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v26i261: xinetd-2.1.1 - inetd replacement with access control and logging, Part17/31
  4. Sender: unix-sources-moderator@gw.home.vix.com
  5. Approved: vixie@gw.home.vix.com
  6.  
  7. Submitted-By: panos@cs.colorado.edu (Panos Tsirigotis)
  8. Posting-Number: Volume 26, Issue 261
  9. Archive-Name: xinetd-2.1.1/part17
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 17 (of 31)."
  18. # Contents:  libs/src/timer/sysdep.c xinetd/tcpint.c xinetd/xinetd.man
  19. # Wrapped by panos@mystique on Mon Jun 21 14:51:25 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'libs/src/timer/sysdep.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'libs/src/timer/sysdep.c'\"
  23. else
  24. echo shar: Extracting \"'libs/src/timer/sysdep.c'\" \(7453 characters\)
  25. sed "s/^X//" >'libs/src/timer/sysdep.c' <<'END_OF_FILE'
  26. X/*
  27. X * (c) Copyright 1993 by Panagiotis Tsirigotis
  28. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  29. X * and conditions for redistribution.
  30. X */
  31. X
  32. X#include <signal.h>
  33. X#include <sys/time.h>
  34. X#include <sys/resource.h>
  35. X
  36. X#include "defs.h"
  37. X#include "impl.h"
  38. X#include "ostimer.h"
  39. X#include "timemacros.h"
  40. X
  41. X
  42. XPRIVATE void sigalrm_handler() ;
  43. XPRIVATE void sigvtalrm_handler() ;
  44. XPRIVATE void sigprof_handler() ;
  45. X
  46. XPRIVATE void get_real_time() ;
  47. XPRIVATE void get_virtual_time() ;
  48. XPRIVATE void get_prof_time() ;
  49. X
  50. X#define SIGNOSIG                            0
  51. X
  52. Xstatic struct os_timer os_timers[] =
  53. X   {
  54. X#ifdef ITIMER_REAL
  55. X        { AVAILABLE,     ITIMER_REAL,
  56. X#else
  57. X        { UNAVAILABLE,    0,
  58. X#endif
  59. X            TIMER_REAL,            SIGALRM,    sigalrm_handler,     get_real_time     },
  60. X
  61. X#ifdef ITIMER_VIRTUAL
  62. X        { AVAILABLE,    ITIMER_VIRTUAL,
  63. X#else
  64. X        { UNAVAILABLE,    0,
  65. X#endif
  66. X        TIMER_VIRTUAL,        SIGVTALRM,  sigvtalrm_handler,   get_virtual_time  },
  67. X
  68. X#ifdef ITIMER_PROF
  69. X        { AVAILABLE,    ITIMER_PROF,
  70. X#else
  71. X        { UNAVAILABLE,    0,
  72. X#endif
  73. X        TIMER_PROF,         SIGPROF,    sigprof_handler,     get_prof_time     },
  74. X
  75. X        { UNAVAILABLE,    0,
  76. X        TIMER_REAL,            SIGNOSIG,    NULL,                NULL,             }
  77. X   } ;
  78. X
  79. X
  80. X/*
  81. X * The timer_block_mask blocks all timer signals when a timer signal
  82. X * happens (using the sa_mask field of struct sigaction). This is necessary
  83. X * when the user function associated with the timer does not return.
  84. X * Consider the following scenario:
  85. X *    The user creates 2 timers, one TIMER_REAL (signal: SIGALRM), one
  86. X *    TIMER_VIRTUAL (signal: SIGVTALRM).
  87. X *    SIGALRM occurs first but before it is handled, SIGVTALRM happens.
  88. X *    At this point both SIGARLM and SIGVTALRM are blocked.
  89. X *    SIGVTALRM gets unblocked and the function for the TIMER_VIRTUAL is
  90. X *    invoked and never returns. The function for the TIMER_REAL is never
  91. X *    invoked (and any TIMER_REAL timers never expire).
  92. X */
  93. X#ifndef NO_POSIX_SIGS
  94. Xstatic sigset_t timer_block_mask ;
  95. X#else
  96. Xstatic int timer_block_mask ;
  97. X#endif
  98. X
  99. Xstatic int timer_block_mask_set ;         /* flag */
  100. X
  101. X
  102. X/*
  103. X * Initialize the timer_block_mask.
  104. X * As a side-effect it also initializes the block_mask of each ostimer.
  105. X */
  106. XPRIVATE void set_timer_block_mask()
  107. X{
  108. X   ostimer_s *otp ;
  109. X
  110. X#ifndef NO_POSIX_SIGS
  111. X   (void) sigemptyset( &timer_block_mask ) ;
  112. X#else
  113. X    /* timer_block_mask is a global variable so it is initialized to 0 */
  114. X#endif
  115. X
  116. X   for ( otp = &os_timers[ 0 ] ; otp->ost_handler ; otp++ )
  117. X   {
  118. X#ifndef NO_POSIX_SIGS
  119. X      (void) sigemptyset( &otp->ost_block_mask ) ;
  120. X      (void) sigaddset( &otp->ost_block_mask, otp->ost_signal ) ;
  121. X      (void) sigaddset( &timer_block_mask, otp->ost_signal ) ;
  122. X#else
  123. X      otp->ost_block_mask = sigmask( otp->ost_signal ) ;
  124. X      timer_block_mask |= otp->ost_block_mask ;
  125. X#endif
  126. X   }
  127. X
  128. X   timer_block_mask_set = TRUE ;
  129. X}
  130. X
  131. X
  132. XPRIVATE ostimer_s *ostimer_find( type )
  133. X    enum timer_types    type ;
  134. X{
  135. X    register ostimer_s *otp ;
  136. X
  137. X    for ( otp = os_timers ; otp->ost_handler ; otp++ )
  138. X        if ( otp->ost_timertype == type )
  139. X            return( otp->ost_availability == AVAILABLE ? otp : OSTIMER_NULL ) ;
  140. X    return( OSTIMER_NULL ) ;
  141. X}
  142. X
  143. X
  144. XPRIVATE int time_compare( p1, p2 )
  145. X   pq_obj p1, p2 ;
  146. X{
  147. X   return( TV_LT( TP( p1 )->t_expiration, TP( p2 )->t_expiration ) ) ;
  148. X}
  149. X
  150. X
  151. X/*
  152. X * Initialize an OS timer. The initialization steps are:
  153. X *
  154. X *    create priority queue
  155. X *    install signal handler
  156. X *
  157. X * We also initialize the timer_block_mask if it has not been initialized yet.
  158. X */
  159. Xostimer_s *__ostimer_init( tp, type )
  160. X    timer_s                *tp ;
  161. X    enum timer_types    type ;
  162. X{
  163. X#ifndef NO_POSIX_SIGS
  164. X   struct sigaction  sa ;
  165. X#else
  166. X   struct sigvec     sv ;
  167. X#endif
  168. X   ostimer_s           *otp ;
  169. X   struct timer_q    *tqp ;
  170. X
  171. X    /*
  172. X     * Find the corresponding ostimer
  173. X     */
  174. X    if ( ( otp = ostimer_find( type ) ) == OSTIMER_NULL )
  175. X        HANDLE_ERROR( tp->t_flags, OSTIMER_NULL,
  176. X            tp->t_errnop, TIMER_ENOTAVAILABLE,
  177. X                "TIMER __ostimer_init: requested timer type not available\n" ) ;
  178. X
  179. X    /*
  180. X     * We use the value of ost_timerq to determine if the os_timer
  181. X     * has been initialized.
  182. X     */
  183. X   tqp = &otp->ost_timerq ;
  184. X    if ( tqp->tq_handle )
  185. X        return( otp ) ;
  186. X    
  187. X   tqp->tq_handle = pq_create( time_compare,
  188. X                tp->t_flags & TIMER_RETURN_ERROR ? PQ_RETURN_ERROR : PQ_NOFLAGS,
  189. X                                        &tqp->tq_errno ) ;
  190. X   if ( tqp->tq_handle == NULL )
  191. X   {
  192. X      *tp->t_errnop = TIMER_ENOMEM ;
  193. X      return( OSTIMER_NULL ) ;
  194. X   }
  195. X
  196. X   if ( ! timer_block_mask_set )
  197. X      set_timer_block_mask() ;
  198. X
  199. X#ifndef NO_POSIX_SIGS
  200. X   sa.sa_handler = otp->ost_handler ;
  201. X   sa.sa_mask = timer_block_mask ;
  202. X   sa.sa_flags = 0 ;
  203. X   if ( sigaction( otp->ost_signal, &sa, SIGACTION_NULL ) == -1 )
  204. X#else
  205. X   sv.sv_handler = otp->ost_handler ;
  206. X   sv.sv_mask = timer_block_mask ;
  207. X   sv.sv_flags = 0 ;
  208. X   if ( sigvec( otp->ost_signal, &sv, SIGVEC_NULL ) == -1 )
  209. X#endif
  210. X      HANDLE_ERROR( tp->t_flags, OSTIMER_NULL, tp->t_errnop, TIMER_ESIGPROBLEM,
  211. X         "TIMER __ostimer_init: signal handler installation failed\n" ) ;
  212. X   return( otp ) ;
  213. X}
  214. X
  215. X
  216. X/*
  217. X * timer_* functions that need access to private data of ostimer
  218. X */
  219. Xvoid timer_block_type( type )
  220. X   enum timer_types    type ;
  221. X{
  222. X   ostimer_s            *otp = ostimer_find( type ) ;
  223. X
  224. X    if ( otp == OSTIMER_NULL )
  225. X        return ;
  226. X
  227. X#ifndef NO_POSIX_SIGS
  228. X   (void) sigprocmask( SIG_BLOCK, &otp->ost_block_mask, SIGSET_NULL ) ;
  229. X#else
  230. X   (void) sigblock( otp->ost_block_mask ) ;
  231. X#endif
  232. X}
  233. X
  234. X
  235. Xvoid timer_unblock_type( type )
  236. X   enum timer_types    type ;
  237. X{
  238. X   ostimer_s            *otp = ostimer_find( type ) ;
  239. X
  240. X    if ( otp == OSTIMER_NULL )
  241. X        return ;
  242. X
  243. X#ifndef NO_POSIX_SIGS
  244. X   (void) sigprocmask( SIG_UNBLOCK, &otp->ost_block_mask, SIGSET_NULL ) ;
  245. X#else
  246. X    {
  247. X        int old_mask = sigblock( ~0 ) ;
  248. X
  249. X        (void) sigsetmask( old_mask & ~otp->ost_block_mask ) ;
  250. X    }
  251. X#endif
  252. X}
  253. X
  254. X
  255. Xvoid __ostimer_blockall()
  256. X{
  257. X#ifndef NO_POSIX_SIGS
  258. X   (void) sigprocmask( SIG_BLOCK, &timer_block_mask, SIGSET_NULL ) ;
  259. X#else
  260. X   (void) sigblock( timer_block_mask ) ;
  261. X#endif
  262. X}
  263. X
  264. X
  265. Xvoid __ostimer_unblockall()
  266. X{
  267. X#ifndef NO_POSIX_SIGS
  268. X   (void) sigprocmask( SIG_UNBLOCK, &timer_block_mask, SIGSET_NULL ) ;
  269. X#else
  270. X   int old_mask = sigblock( ~0 ) ;
  271. X
  272. X   (void) sigsetmask( old_mask & ~timer_block_mask ) ;
  273. X#endif
  274. X}
  275. X
  276. X
  277. Xvoid __ostimer_unblockall_except( otp )
  278. X   ostimer_s *otp ;
  279. X{
  280. X#ifndef NO_POSIX_SIGS
  281. X   sigset_t new_mask = timer_block_mask ;
  282. X
  283. X   (void) sigdelset( &new_mask, otp->ost_signal ) ;
  284. X   (void) sigprocmask( SIG_UNBLOCK, &new_mask, SIGSET_NULL ) ;
  285. X#else
  286. X   int old_mask = sigblock( ~0 ) ;
  287. X
  288. X   (void) sigsetmask( ( old_mask & ~timer_block_mask )
  289. X                                          | otp->ost_block_mask ) ;
  290. X#endif
  291. X}
  292. X
  293. X
  294. XPRIVATE void sigalrm_handler()
  295. X{
  296. X#ifdef DEBUG_MSGS
  297. X   printf( "\tSIGALRM happened\n" ) ;
  298. X#endif
  299. X   __ostimer_interrupt( &os_timers[ (int)TIMER_REAL ] ) ;
  300. X}
  301. X
  302. X
  303. XPRIVATE void sigvtalrm_handler()
  304. X{
  305. X#ifdef DEBUG_MSGS
  306. X   printf( "\tSIGVTALRM happened\n" ) ;
  307. X#endif
  308. X   __ostimer_interrupt( &os_timers[ (int)TIMER_VIRTUAL ] ) ;
  309. X}
  310. X
  311. X
  312. XPRIVATE void sigprof_handler()
  313. X{
  314. X#ifdef DEBUG_MSGS
  315. X   printf( "\tSIGPROF happened\n" ) ;
  316. X#endif
  317. X   __ostimer_interrupt( &os_timers[ (int)TIMER_PROF ] ) ;
  318. X}
  319. X
  320. X
  321. XPRIVATE void get_real_time( tvp )
  322. X   struct timeval *tvp ;
  323. X{
  324. X#ifdef ITIMER_REAL
  325. X   (void) gettimeofday( tvp, TIMEZONE_NULL ) ;
  326. X#endif
  327. X}
  328. X
  329. X
  330. XPRIVATE void get_virtual_time( tvp )
  331. X   struct timeval *tvp ;
  332. X{
  333. X#ifdef ITIMER_VIRTUAL
  334. X   struct rusage ru ;
  335. X
  336. X   (void) getrusage( RUSAGE_SELF, &ru ) ;
  337. X   *tvp = ru.ru_utime ;
  338. X#endif
  339. X}
  340. X
  341. X
  342. XPRIVATE void get_prof_time( tvp )
  343. X   struct timeval *tvp ;
  344. X{
  345. X#ifdef ITIMER_PROF
  346. X   struct rusage ru ;
  347. X
  348. X   (void) getrusage( RUSAGE_SELF, &ru ) ;
  349. X   TV_ADD( *tvp, ru.ru_utime, ru.ru_stime ) ;
  350. X#endif
  351. X}
  352. X
  353. X
  354. END_OF_FILE
  355. if test 7453 -ne `wc -c <'libs/src/timer/sysdep.c'`; then
  356.     echo shar: \"'libs/src/timer/sysdep.c'\" unpacked with wrong size!
  357. fi
  358. # end of 'libs/src/timer/sysdep.c'
  359. fi
  360. if test -f 'xinetd/tcpint.c' -a "${1}" != "-c" ; then 
  361.   echo shar: Will not clobber existing file \"'xinetd/tcpint.c'\"
  362. else
  363. echo shar: Extracting \"'xinetd/tcpint.c'\" \(7988 characters\)
  364. sed "s/^X//" >'xinetd/tcpint.c' <<'END_OF_FILE'
  365. X/*
  366. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  367. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  368. X * and conditions for redistribution.
  369. X */
  370. X
  371. Xstatic char RCSid[] = "$Id: tcpint.c,v 6.6 1993/06/15 23:25:57 panos Exp $" ;
  372. X
  373. X#include <sys/types.h>
  374. X#include <sys/socket.h>
  375. X#include <sys/time.h>
  376. X#include <syslog.h>
  377. X#include <signal.h>
  378. X#include <errno.h>
  379. X
  380. X#include "config.h"
  381. X#include "int.h"
  382. X#include "access.h"
  383. X#include "defs.h"
  384. X
  385. Xchar *inet_ntoa() ;
  386. Xvoid msg() ;
  387. X
  388. Xtypedef enum { S_OK, S_SERVER_ERR, S_CLIENT_ERR } stream_status_e ;
  389. X
  390. Xstruct istream_private
  391. X{
  392. X    unsigned accepted_connections ;
  393. X} ;
  394. X
  395. X#define SIP( p )                        ((struct istream_private *)(p))
  396. X
  397. Xstatic struct istream_private istream ;
  398. X
  399. XPRIVATE void si_mux() ;
  400. XPRIVATE void si_exit() ;
  401. X
  402. Xstatic struct intercept_ops istream_ops =
  403. X    {
  404. X        si_mux,
  405. X        si_exit
  406. X    } ;
  407. X
  408. Xstatic struct intercept stream_intercept_state ;
  409. X
  410. X
  411. Xstruct intercept *si_init( serp )
  412. X    struct server *serp ;
  413. X{
  414. X    register struct intercept *ip = &stream_intercept_state ;
  415. X
  416. X    ip->int_socket_type = SOCK_STREAM ;
  417. X    ip->int_priv = (void *) &istream ;
  418. X    ip->int_ops = &istream_ops ;
  419. X    int_init( ip, serp ) ;
  420. X    if ( (int) signal( SIGPIPE, SIG_IGN ) == -1 )
  421. X        int_fail( ip, "signal" ) ;
  422. X    return( ip ) ;
  423. X}
  424. X
  425. X
  426. XPRIVATE void si_exit()
  427. X{
  428. X    register struct intercept *ip = &stream_intercept_state ;
  429. X    
  430. X    if ( SIP( ip->int_priv )->accepted_connections == 0 )
  431. X        (void) accept( INT_REMOTE( ip ), SA( NULL ), INT_NULL ) ;
  432. X    int_exit( ip ) ;
  433. X}
  434. X
  435. X
  436. XPRIVATE void si_mux()
  437. X{
  438. X    register struct intercept    *ip = &stream_intercept_state ;
  439. X    fd_set                            socket_mask ;
  440. X    int                                mask_max ;
  441. X    psi_h                                iter ;
  442. X    char                                *func = "si_mux" ;
  443. X    PRIVATE status_e                handle_io() ;
  444. X    PRIVATE stream_status_e        tcp_local_to_remote() ;
  445. X    PRIVATE stream_status_e        tcp_remote_to_local() ;
  446. X    PRIVATE void                    connection_request() ;
  447. X
  448. X    FD_ZERO( &socket_mask ) ;
  449. X    FD_SET( INT_REMOTE( ip ), &socket_mask ) ;
  450. X    mask_max = INT_REMOTE( ip ) ;
  451. X
  452. X    iter = psi_create( INT_CONNECTIONS( ip ) ) ;
  453. X    if ( iter == NULL )
  454. X    {
  455. X        msg( LOG_ERR, func, ES_NOMEM ) ;
  456. X        return ;
  457. X    }
  458. X
  459. X    for ( ;; )
  460. X    {
  461. X        channel_s *chp ;
  462. X        fd_set read_mask ;
  463. X        int n_ready ;
  464. X
  465. X        read_mask = socket_mask ;
  466. X        n_ready = int_select( mask_max+1, &read_mask ) ;
  467. X
  468. X        if ( n_ready == -1 )
  469. X            return ;
  470. X        
  471. X      if ( FD_ISSET( INT_REMOTE( ip ), &read_mask ) )
  472. X      {
  473. X         connection_request( ip, &chp ) ;
  474. X            if ( chp != NULL )
  475. X            {
  476. X                FD_SET( chp->ch_local_socket, &socket_mask ) ;
  477. X                if ( chp->ch_local_socket > mask_max )
  478. X                    mask_max = chp->ch_local_socket ;
  479. X                FD_SET( chp->ch_remote_socket, &socket_mask ) ;
  480. X                if ( chp->ch_remote_socket > mask_max )
  481. X                    mask_max = chp->ch_remote_socket ;
  482. X            }
  483. X         if ( --n_ready == 0 )
  484. X            continue ;
  485. X      }
  486. X
  487. X        for ( chp = CHP( psi_start(iter) ) ; chp ; chp = CHP( psi_next(iter) ) )
  488. X        {
  489. X            if ( FD_ISSET( chp->ch_local_socket, &read_mask ) )
  490. X            {
  491. X#ifdef DEBUG_TCPINT
  492. X                if ( debug.on )
  493. X                    msg( LOG_DEBUG, func, "Input available on local socket %d", 
  494. X                                                                            chp->ch_local_socket ) ;
  495. X#endif
  496. X                if ( handle_io( iter, chp,
  497. X                                &socket_mask, tcp_local_to_remote ) == FAILED )
  498. X                    return ;
  499. X                if ( --n_ready == 0 )
  500. X                    break ;
  501. X            }
  502. X
  503. X            if ( FD_ISSET( chp->ch_remote_socket, &read_mask ) )
  504. X            {
  505. X#ifdef DEBUG_TCPINT
  506. X                msg( LOG_DEBUG, func, "Input available on remote socket %d", 
  507. X                                                                        chp->ch_remote_socket ) ;
  508. X#endif
  509. X                if ( handle_io( iter, chp,
  510. X                                &socket_mask, tcp_remote_to_local ) == FAILED )
  511. X                    return ;
  512. X                if ( --n_ready == 0 )
  513. X                    break ;
  514. X            }
  515. X        }
  516. X    }
  517. X}
  518. X
  519. X
  520. XPRIVATE status_e handle_io( iter, chp, maskp, iofunc )
  521. X    psi_h                    iter ;
  522. X    channel_s            *chp ;
  523. X    fd_set                *maskp ;
  524. X    stream_status_e    (*iofunc)() ;
  525. X{
  526. X    char *func = "handle_io" ;
  527. X
  528. X    switch ( (*iofunc)( chp ) )
  529. X    {
  530. X        case S_SERVER_ERR:
  531. X            return( FAILED ) ;
  532. X        
  533. X        case S_CLIENT_ERR:
  534. X
  535. X            if ( debug.on )
  536. X                msg( LOG_DEBUG, func,
  537. X                    "Closing channel to %s,%d using sockets %d(l),%d(r)",
  538. X                        inet_ntoa( chp->ch_from.sin_addr ),
  539. X                            ntohs( chp->ch_from.sin_port ),
  540. X                                chp->ch_local_socket, chp->ch_remote_socket ) ;
  541. X
  542. X            FD_CLR( chp->ch_local_socket, maskp ) ;
  543. X            FD_CLR( chp->ch_remote_socket, maskp ) ;
  544. X            (void) close( chp->ch_remote_socket ) ;
  545. X            (void) close( chp->ch_local_socket ) ;
  546. X            psi_remove( iter ) ;
  547. X            FREE_CHANNEL( chp ) ;
  548. X            break ;
  549. X    }
  550. X    return( OK ) ;
  551. X}
  552. X
  553. X
  554. XPRIVATE void connection_request( ip, chpp )
  555. X    struct intercept    *ip ;
  556. X    channel_s            **chpp ;
  557. X{
  558. X    struct sockaddr_in    sin ;
  559. X    int                        sin_len = sizeof( sin ) ;
  560. X    channel_s                *chp ;
  561. X    int                        sd ;
  562. X    bool_int                    addr_checked ;
  563. X    char                        *func = "connection_request" ;
  564. X
  565. X    *chpp = NULL ;
  566. X
  567. X    if ( ( sd = accept( INT_REMOTE( ip ), SA( &sin ), &sin_len ) ) == -1 )
  568. X        return ;
  569. X    
  570. X    SIP( ip->int_priv )->accepted_connections++ ;
  571. X
  572. X    if ( debug.on )
  573. X        msg( LOG_DEBUG, func, "connection request from %s,%d",
  574. X            inet_ntoa( sin.sin_addr ), ntohs( sin.sin_port ) ) ;
  575. X
  576. X    chp = int_lookupconn( ip, &sin, &addr_checked ) ;
  577. X    if ( chp == NULL )
  578. X    {
  579. X        struct server    *serp    = INT_SERVER( ip ) ;
  580. X        struct service *sp    = SERVER_SERVICE( serp ) ;
  581. X        connection_s    *cop    = SERVER_CONNECTION( serp ) ;
  582. X
  583. X        conn_setaddr( cop, &sin ) ;
  584. X
  585. X        if ( INTERCEPT( ip ) )
  586. X        {
  587. X            mask_t check_mask ;
  588. X            access_e result ;
  589. X            
  590. X            M_OR( check_mask, MASK( CF_ADDRESS ), MASK( CF_TIME ) ) ;
  591. X            result = access_control( sp, cop, &check_mask ) ;
  592. X
  593. X            if ( result != AC_OK )
  594. X            {
  595. X                svc_log_failure( sp, cop, result ) ;
  596. X                (void) close( sd ) ;
  597. X                return ;
  598. X            }
  599. X        }
  600. X
  601. X        if ( ( chp = int_newconn( ip, &sin, sd ) ) == NULL )
  602. X        {
  603. X            (void) close( sd ) ;
  604. X            return ;
  605. X        }
  606. X        
  607. X        if ( ! addr_checked )
  608. X            svc_log_success( sp, cop, SERVER_PID( serp ) ) ;
  609. X
  610. X#if defined( TCP_NODELAY )
  611. X        {
  612. X            int on = 1 ;
  613. X
  614. X            (void) setsockopt( chp->ch_local_socket, IPPROTO_TCP,
  615. X                                        TCP_NODELAY, (char *) &on, sizeof( on ) ) ;
  616. X            (void) setsockopt( chp->ch_remote_socket, IPPROTO_TCP,
  617. X                                        TCP_NODELAY, (char *) &on, sizeof( on ) ) ;
  618. X        }
  619. X#endif    /* TCP_NODELAY */
  620. X        
  621. X        *chpp = chp ;
  622. X    }
  623. X    else
  624. X        msg( LOG_ERR, func,
  625. X            "Received another connection request from %s,%d",
  626. X                inet_ntoa( sin.sin_addr ), ntohs( sin.sin_port ) ) ;
  627. X}
  628. X
  629. X
  630. XPRIVATE stream_status_e tcp_local_to_remote( chp )
  631. X    channel_s *chp ;
  632. X{
  633. X    char buf[ DATAGRAM_SIZE ] ;
  634. X    int rcc, wcc ;
  635. X    char *p ;
  636. X    int left ;
  637. X    char *func = "tcp_local_to_remote" ;
  638. X
  639. X    for ( ;; )
  640. X    {
  641. X        rcc = recv( chp->ch_local_socket, buf, sizeof( buf ), 0 ) ;
  642. X        if ( rcc == 0 )
  643. X            return( S_SERVER_ERR ) ;
  644. X        else if ( rcc == -1 )
  645. X        {
  646. X            if ( errno != EINTR )
  647. X            {
  648. X                msg( LOG_ERR, func, "recv: %m" ) ;
  649. X                return( S_SERVER_ERR ) ;
  650. X            }
  651. X        }
  652. X        else
  653. X            break ;
  654. X    }
  655. X
  656. X    for ( p = buf, left = rcc ; left ; p += wcc, left -= wcc )
  657. X    {
  658. X        wcc = send( chp->ch_remote_socket, p, left, 0 ) ;
  659. X        if ( wcc == 0 )
  660. X            return( S_CLIENT_ERR ) ;
  661. X        else if ( wcc == -1 )
  662. X        {
  663. X            if ( errno == EINTR )
  664. X                wcc = 0 ;
  665. X            else
  666. X            {
  667. X                msg( LOG_ERR, func, "send: %m" ) ;
  668. X                return( S_CLIENT_ERR ) ;
  669. X            }
  670. X        }
  671. X    }
  672. X
  673. X#ifdef DEBUG_TCPINT
  674. X    if ( debug.on )
  675. X        msg( LOG_DEBUG, func,
  676. X            "Transferred %d bytes from local socket %d to remote socket %d",
  677. X                rcc, chp->ch_local_socket, chp->ch_remote_socket ) ;
  678. X#endif
  679. X
  680. X    return( S_OK ) ;
  681. X}
  682. X
  683. X
  684. XPRIVATE stream_status_e tcp_remote_to_local( chp )
  685. X    channel_s *chp ;
  686. X{
  687. X    char buf[ DATAGRAM_SIZE ] ;
  688. X    int rcc, wcc ;
  689. X    int left ;
  690. X    char *p ;
  691. X    char *func = "tcp_remote_to_local" ;
  692. X
  693. X    for ( ;; )
  694. X    {
  695. X        rcc = recv( chp->ch_remote_socket, buf, sizeof( buf ), 0 ) ;
  696. X        if ( rcc == 0 )
  697. X            return( S_CLIENT_ERR ) ;
  698. X        else if ( rcc == -1 )
  699. X        {
  700. X            if ( errno != EINTR )
  701. X            {
  702. X                msg( LOG_ERR, func, "recv: %m" ) ;
  703. X                return( S_CLIENT_ERR ) ;
  704. X            }
  705. X        }
  706. X        else
  707. X            break ;
  708. X    }
  709. X
  710. X    for ( p = buf, left = rcc ; left ; p += wcc, left -= wcc )
  711. X    {
  712. X        wcc = send( chp->ch_local_socket, p, left, 0 ) ;
  713. X        if ( wcc == 0 )
  714. X            return( S_SERVER_ERR ) ;
  715. X        else if ( wcc == -1 )
  716. X            if ( errno == EINTR )
  717. X                rcc = 0 ;
  718. X            else
  719. X            {
  720. X                msg( LOG_ERR, func, "send: %m" ) ;
  721. X                return( S_SERVER_ERR ) ;
  722. X            }
  723. X    }
  724. X
  725. X#ifdef DEBUG_TCPINT
  726. X    if ( debug.on )
  727. X        msg( LOG_DEBUG, func,
  728. X            "Transferred %d bytes from remote socket %d to local socket %d",
  729. X                rcc, chp->ch_remote_socket, chp->ch_local_socket ) ;
  730. X#endif
  731. X
  732. X    return( S_OK ) ;
  733. X}
  734. X
  735. END_OF_FILE
  736. if test 7988 -ne `wc -c <'xinetd/tcpint.c'`; then
  737.     echo shar: \"'xinetd/tcpint.c'\" unpacked with wrong size!
  738. fi
  739. # end of 'xinetd/tcpint.c'
  740. fi
  741. if test -f 'xinetd/xinetd.man' -a "${1}" != "-c" ; then 
  742.   echo shar: Will not clobber existing file \"'xinetd/xinetd.man'\"
  743. else
  744. echo shar: Extracting \"'xinetd/xinetd.man'\" \(7518 characters\)
  745. sed "s/^X//" >'xinetd/xinetd.man' <<'END_OF_FILE'
  746. X.\"(c) Copyright 1992 by Panagiotis Tsirigotis
  747. X.\"All rights reserved.  The file named COPYRIGHT specifies the terms 
  748. X.\"and conditions for redistribution.
  749. X.\"
  750. X.\" $Id: xinetd.man,v 6.4 1993/06/06 00:13:03 panos Exp $
  751. X.TH XINETD 1L "28 April 1993"
  752. X.\" *************************** NAME *********************************
  753. X.SH NAME
  754. Xxinetd \- the extended Internet services daemon
  755. X.\" *************************** SYNOPSIS *********************************
  756. X.SH SYNOPSIS
  757. X.B xinetd
  758. X[\fIoptions\fP]
  759. X.\" *************************** DESCRIPTION *********************************
  760. X.SH DESCRIPTION
  761. X\fBxinetd\fP performs the same function as \fBinetd\fP: it starts
  762. Xprograms that provide Internet services.  Instead of having such
  763. Xservers started at system initialization time, and be dormant until a
  764. Xconnection request arrives, \fBxinetd\fP is the only daemon process
  765. Xstarted and it listens on all service ports for the services listed in
  766. Xits configuration file. When a request comes in, \fBxinetd\fP starts
  767. Xthe appropriate server.  Because of the way it operates, \fBxinetd\fP
  768. X(as well as \fBinetd\fP) is also referred to as a super-server.
  769. X.LP
  770. XThe services listed in \fBxinetd\fP's configuration file can be
  771. Xseparated into two groups.  Services in the first group are called
  772. X.I "multi-threaded"
  773. Xand they require the forking of a new server process for each new
  774. Xconnection request.  The new server then handles that connection.  For
  775. Xsuch services, \fBxinetd\fP keeps listening for new requests so that it
  776. Xcan spawn new servers.  On the other hand, the second group includes
  777. Xservices for which the service daemon is responsible for handling all
  778. Xnew connection requests.  Such services are called
  779. X.I "single-threaded"
  780. Xand \fBxinetd\fP will stop handling new requests for them until the
  781. Xserver dies.  Services in this group are usually datagram-based.
  782. X.LP
  783. XSo far, the only reason for the existence of a super-server was to
  784. Xconserve system resources by avoiding to fork a lot of processes which
  785. Xmight be dormant for most of their lifetime.  While fulfilling this
  786. Xfunction, \fBxinetd\fP takes advantage of the idea of a super-server to
  787. Xprovide features such as access control and logging.  Furthermore,
  788. X\fBxinetd\fP is not limited to services listed in
  789. X.I /etc/services.
  790. XTherefore, anybody can use \fBxinetd\fP to start special-purpose
  791. Xservers.
  792. X.\" *************************** OPTIONS *********************************
  793. X.SH OPTIONS
  794. X.TP
  795. X.BR \-d
  796. XEnables debug mode. This produces a lot of debugging output, and it
  797. Xmakes it possible to use a debugger on \fBxinetd\fP.
  798. X.TP
  799. X.BI \-syslog " syslog_facility"
  800. XThis option enables syslog logging of \fBxinetd\fP-produced messages
  801. Xusing the specified syslog facility.
  802. XThe following facility names are supported:
  803. X.I daemon,
  804. X.I auth,
  805. X.I user,
  806. X.I "local[0-7]"
  807. X(check \fIsyslog.conf(5)\fP for their meanings).
  808. XThis option is ineffective in debug mode since all relevant messages are sent
  809. Xto the terminal.
  810. X.TP
  811. X.BI \-filelog " logfile"
  812. X\fBxinetd\fP-produced messages will be placed in the specified file.
  813. XMessages are always appended to the file.
  814. XIf the file does not exist, it will be created.
  815. XThis option is ineffective in debug mode since all relevant messages are sent
  816. Xto the terminal.
  817. X.TP
  818. X.BI \-f " config_file"
  819. XDetermines the file that \fBxinetd\fP uses for configuration. The
  820. Xdefault is \fI/etc/xinetd.conf\fP.
  821. X.TP
  822. X.BR \-pid
  823. X.br
  824. XThe process ID is written to standard error.
  825. XThis option is ineffective in debug mode.
  826. X.TP
  827. X.BI \-loop " rate"
  828. XThis option sets the loop rate beyond which a service is considered in
  829. Xerror and is deactivated. The loop rate is specified in terms of
  830. Xthe number of servers per second that can be forked for a process.
  831. XThe speed of your machine determines the correct value for this option.
  832. XThe default rate is 10.
  833. X.TP
  834. X.BR \-reuse
  835. XIf this option is used, \fBxinetd\fP will set the socket option
  836. X\fISO_REUSEADDR\fP before binding the service socket to an Internet
  837. Xaddress. This allows binding of the address even if there are programs
  838. Xthat use it, which happens when a previous instance of \fBxinetd\fP
  839. Xhas started some servers that are still running.
  840. XThis option has no effect on
  841. X.SM RPC
  842. Xservices.
  843. X.TP
  844. X.BI \-limit " proc_limit"
  845. XThis option places a limit on the number of concurrently running processes
  846. Xthat can be started by
  847. X.B xinetd.
  848. XIts purpose is to prevent process table overflows.
  849. X.TP
  850. X.BI \-logprocs " limit"
  851. XThis option places a limit on the number of concurrently running servers
  852. Xfor remote userid acquisition.
  853. X.TP
  854. X.BI \-shutdownprocs " limit"
  855. XThis option places a limit on the number of concurrently running servers
  856. Xfor service shutdown (forked when the
  857. X.SB RECORD
  858. Xoption is used).
  859. X.TP
  860. X.BI \-cc " interval"
  861. XThis option instructs
  862. X.B xinetd
  863. Xto perform periodic consistency checks on its internal state every
  864. X.I interval
  865. Xseconds.
  866. X.LP
  867. XThe \fIsyslog\fP and \fIfilelog\fP options are mutually exclusive.
  868. XIf none is specified, the default is syslog using the
  869. X.I daemon
  870. Xfacility.
  871. XYou should not confuse \fBxinetd\fP messages with messages related to
  872. Xservice logging. The latter are logged only if this is specified
  873. Xvia the configuration file.
  874. X.\" *********************** CONTROLLING XINETD ****************************
  875. X.SH "CONTROLLING XINETD"
  876. X.LP
  877. X\fBxinetd\fP performs certain actions when it receives certain signals.
  878. XThe actions associated with the specific signals can be redefined
  879. Xby editing \fIconfig.h\fP and recompiling.
  880. X.TP 15
  881. X.SB SIGUSR1
  882. Xcauses a soft reconfiguration, which means that \fBxinetd\fP rereads
  883. Xthe configuration file and adjusts accordingly.
  884. X.TP
  885. X.SB SIGUSR2
  886. Xcauses a hard reconfiguration, which is the same as a soft reconfiguration
  887. Xexcept that servers for services that are no longer available are
  888. Xterminated. Access control is performed again on running servers
  889. Xby checking the remote location, access times and server instances.
  890. XIf the number of server instances is lowered, some arbitrarily picked
  891. Xservers will be killed
  892. Xto satisfy the limit; this will happen \fIafter\fP any servers are
  893. Xterminated because of failing the remote location or access time checks.
  894. XAlso, if the
  895. X.SB INTERCEPT
  896. Xflag was clear and is set, any running servers for that service will
  897. Xbe terminated;
  898. X\fIthe purpose of this is to ensure that after a hard reconfiguration
  899. Xthere will be no running servers that can accept packets from addresses
  900. Xthat do not meet the access control criteria\fP.
  901. X.TP
  902. X.SB SIGQUIT
  903. Xcauses program termination.
  904. X.TP
  905. X.SB SIGTERM
  906. Xterminates all running servers before terminating \fBxinetd\fP.
  907. X.TP
  908. X.SB SIGHUP
  909. Xcauses an internal state dump (the default dump file is
  910. X\fI/tmp/xinetd.dump\fP;
  911. Xto change the filename, edit \fIconfig.h\fP and recompile).
  912. X.TP
  913. X.SB SIGIOT
  914. Xcauses an internal consistency check to verify that the data structures
  915. Xused by the program have not been corrupted.
  916. XWhen the check is completed
  917. X.B xinetd
  918. Xwill generate a message that says if the check was successful or not.
  919. X.LP
  920. XOn reconfiguration the log files are closed and reopened. This allows
  921. Xremoval of old log files.
  922. X.\" *********************** FILES ****************************
  923. X.SH FILES
  924. X.LP
  925. X.PD .1v
  926. X.TP 20
  927. X.SB /etc/xinetd.conf
  928. Xdefault configuration file
  929. X.TP
  930. X.SB /tmp/xinetd.dump
  931. Xdefault dump file
  932. X.PD
  933. X.\" *********************** SEE ALSO ****************************
  934. X.SH "SEE ALSO"
  935. X.I "inetd(8),"
  936. X.LP
  937. X.I "xinetd.conf(5),"
  938. X.LP
  939. X.I "xinetd.log(5)"
  940. X.\" *********************** AUTHOR ****************************
  941. X.SH AUTHOR
  942. XPanos Tsirigotis, CS Dept, University of Colorado, Boulder
  943. X.\" *********************** PRONUNCIATION ****************************
  944. X.SH PRONUNCIATION
  945. Xzy-net-d
  946. X
  947. END_OF_FILE
  948. if test 7518 -ne `wc -c <'xinetd/xinetd.man'`; then
  949.     echo shar: \"'xinetd/xinetd.man'\" unpacked with wrong size!
  950. fi
  951. # end of 'xinetd/xinetd.man'
  952. fi
  953. echo shar: End of archive 17 \(of 31\).
  954. cp /dev/null ark17isdone
  955. MISSING=""
  956. 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
  957.     if test ! -f ark${I}isdone ; then
  958.     MISSING="${MISSING} ${I}"
  959.     fi
  960. done
  961. if test "${MISSING}" = "" ; then
  962.     echo You have unpacked all 31 archives.
  963.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  964. else
  965.     echo You still need to unpack the following archives:
  966.     echo "        " ${MISSING}
  967. fi
  968. ##  End of shell archive.
  969. exit 0
  970.