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

  1. Newsgroups: comp.sources.unix
  2. From: panos@cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v26i259: xinetd-2.1.1 - inetd replacement with access control and logging, Part15/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 259
  9. Archive-Name: xinetd-2.1.1/part15
  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 15 (of 31)."
  18. # Contents:  libs/src/sio/sio.h libs/src/str/strs.c xinetd/child.c
  19. #   xinetd/udpint.c
  20. # Wrapped by panos@mystique on Mon Jun 21 14:51:24 1993
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'libs/src/sio/sio.h' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'libs/src/sio/sio.h'\"
  24. else
  25. echo shar: Extracting \"'libs/src/sio/sio.h'\" \(6642 characters\)
  26. sed "s/^X//" >'libs/src/sio/sio.h' <<'END_OF_FILE'
  27. X/*
  28. X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  29. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  30. X * and conditions for redistribution.
  31. X */
  32. X
  33. X/*
  34. X * $Id: sio.h,v 8.1 1993/03/13 01:13:58 panos Exp $
  35. X */
  36. X
  37. X#ifndef __SIO_H
  38. X#define __SIO_H
  39. X
  40. X#include <errno.h>
  41. X#include <varargs.h>
  42. X
  43. X/*
  44. X * Naming conventions:
  45. X *        1) SIO functions and macros have names starting with a capital S
  46. X *        2) SIO constants meant to be used by user programs have 
  47. X *            names starting with SIO_
  48. X *        3) Internal functions, struct identifiers, enum identifiers 
  49. X *            etc. have names starting with __sio
  50. X *        4) Internal constants and macros have names starting with __SIO
  51. X */
  52. X
  53. X
  54. X/*
  55. X * external constants
  56. X *
  57. X * SIO_FLUSH_ALL: flush all output streams
  58. X * SIO_EOF:    eof on stream
  59. X * SIO_ERR: operation failed
  60. X */
  61. X#define SIO_FLUSH_ALL                (-1)
  62. X#define SIO_EOF                        (-2)
  63. X#define SIO_ERR                        (-1)
  64. X
  65. X/*
  66. X * Undo types
  67. X */
  68. X#define SIO_UNDO_LINE        0
  69. X#define SIO_UNDO_CHAR        1
  70. X
  71. X/*
  72. X * Buffering types
  73. X */
  74. X#define SIO_FULLBUF            0
  75. X#define SIO_LINEBUF            1
  76. X#define SIO_NOBUF                2
  77. X
  78. X/*
  79. X * Descriptor for an input stream
  80. X */
  81. Xstruct __sio_input_descriptor
  82. X{
  83. X    /*
  84. X     * buf:        points to the buffer area.
  85. X     *                When doing memory mapping, it is equal to the unit 
  86. X     *                from which we are reading. When doing buffered I/O
  87. X     *                it points to the primary buffer.
  88. X     */
  89. X    char *buf ;
  90. X    unsigned buffer_size ;
  91. X
  92. X    char *start ;                 /* start of valid buffer contents       */
  93. X    char *end ;                   /* end of valid buffer contents + 1     */
  94. X    char *nextb ;                 /* pointer to next byte to read/write     */
  95. X                                            /* Always:  start <= nextb < end            */
  96. X
  97. X    unsigned line_length ;
  98. X    int max_line_length ;
  99. X    int tied_fd ;
  100. X
  101. X    int memory_mapped ;                /* flag to denote if we use                */
  102. X                                            /* memory mapping                                */
  103. X} ;
  104. X
  105. Xtypedef struct __sio_input_descriptor __sio_id_t ;
  106. X
  107. X
  108. X/*
  109. X * Descriptor for an output stream
  110. X */
  111. Xstruct __sio_output_descriptor
  112. X{
  113. X    /*
  114. X     * buf:        points to the buffer area.
  115. X     * buf_end: is equal to buf + buffer_size
  116. X     */
  117. X    char *buf ;
  118. X    char *buf_end ;
  119. X
  120. X    unsigned buffer_size ;
  121. X
  122. X    char *start ;                 /* start of valid buffer contents       */
  123. X                                            /* (used by the R and W functions)         */
  124. X    char *nextb ;                 /* pointer to next byte to read/write  */
  125. X                                            /* Always:  start <= nextb < buf_end    */
  126. X    int buftype ;                        /* type of buffering                         */
  127. X} ;
  128. X
  129. Xtypedef struct __sio_output_descriptor __sio_od_t ;
  130. X
  131. X
  132. X
  133. X/*
  134. X * Stream types
  135. X */
  136. Xenum __sio_stream { __SIO_INPUT_STREAM, __SIO_OUTPUT_STREAM } ;
  137. X
  138. X
  139. X/*
  140. X * General descriptor
  141. X */
  142. Xstruct __sio_descriptor
  143. X{
  144. X    union
  145. X    {
  146. X        __sio_id_t input_descriptor ;
  147. X        __sio_od_t output_descriptor ;
  148. X    } descriptor ;
  149. X    enum __sio_stream stream_type ;
  150. X    int initialized ;
  151. X} ;
  152. X
  153. Xtypedef struct __sio_descriptor __sio_descriptor_t ;
  154. X
  155. X
  156. X/*
  157. X * The array of descriptors (as many as available file descriptors)
  158. X */
  159. Xextern __sio_descriptor_t *__sio_descriptors ;
  160. X
  161. Xextern int errno ;
  162. X
  163. X
  164. X/*
  165. X * Internally used macros
  166. X */
  167. X#define __SIO_FD_INITIALIZED( fd )        (__sio_descriptors[ fd ].initialized)
  168. X#define __SIO_ID( fd )    (__sio_descriptors[ fd ].descriptor.input_descriptor)
  169. X#define __SIO_OD( fd )    (__sio_descriptors[ fd ].descriptor.output_descriptor)
  170. X#define __SIO_MUST_FLUSH( od, ch )                                                    \
  171. X                    ( (od).buftype != SIO_FULLBUF &&                                    \
  172. X                        ( (od).buftype == SIO_NOBUF || ch == '\n' ) )
  173. X
  174. X
  175. X/*
  176. X * SIO Macros:
  177. X *
  178. X *        SIOLINELEN( fd )
  179. X *        SIOMAXLINELEN( fd )
  180. X *        Sputchar( fd, c )
  181. X *        Sgetchar( fd )
  182. X *
  183. X * NOTE: The maximum line size depends on whether the descriptor
  184. X *            was originally memory mapped. If it was, then the maximum
  185. X *            line size will be the map_unit_size (a function of the system
  186. X *            page size and PAGES_MAPPED). Otherwise, it will be either the
  187. X *            optimal block size as reported by stat(2) or SIO_BUFFER_SIZE.
  188. X */
  189. X
  190. X#define SIOLINELEN( fd )      __SIO_ID( fd ).line_length
  191. X#define SIOMAXLINELEN( fd )                                                                    \
  192. X    (                                                                                                    \
  193. X        __SIO_FD_INITIALIZED( fd )                                                                \
  194. X            ? (                                                                                         \
  195. X                 (__sio_descriptors[ fd ].stream_type == __SIO_INPUT_STREAM)        \
  196. X                    ? __SIO_ID( fd ).max_line_length                                            \
  197. X                    : ( errno = EBADF, SIO_ERR )                                                \
  198. X              )                                                                                        \
  199. X            : (        /* not initialized; initialize it for input */                    \
  200. X                 (__sio_init( &__sio_descriptors[ fd ], fd, __SIO_INPUT_STREAM )    \
  201. X                                                                                    == SIO_ERR)        \
  202. X                    ? SIO_ERR                                                                        \
  203. X                    : __SIO_ID( fd ).max_line_length                                            \
  204. X              )                                                                                        \
  205. X    )
  206. X
  207. X
  208. X
  209. X/*
  210. X * Adds a character to a buffer, returns the character or SIO_ERR
  211. X */
  212. X#define  __SIO_ADDCHAR( od, fd, c )                                  \
  213. X     ( od.buftype == SIO_FULLBUF )                                   \
  214. X         ? (int) ( *(od.nextb)++ = (unsigned char) (c) )             \
  215. X         : ( od.buftype == SIO_LINEBUF )                             \
  216. X               ? ( ( *(od.nextb) = (unsigned char) (c) ) != '\n' )   \
  217. X                     ? (int) *(od.nextb)++                           \
  218. X                     : Sputc( fd, *(od.nextb) )                      \
  219. X               : Sputc( fd, c )
  220. X
  221. X
  222. X/*
  223. X * The Sgetchar/Sputchar macros depend on the fact that the fields 
  224. X *                 nextb, buf_end, end
  225. X * are 0 if a stream descriptor is not being used or has not yet been
  226. X * initialized.
  227. X * This is true initially because of the static allocation of the
  228. X * descriptor array, and Sdone must make sure that it is true
  229. X * after I/O on a descriptor is over.
  230. X */
  231. X#define Sputchar( fd, c )                                                        \
  232. X        (                                                                                \
  233. X            ( __SIO_OD( fd ).nextb < __SIO_OD( fd ).buf_end )            \
  234. X                ? ( __SIO_ADDCHAR( __SIO_OD( fd ), fd, c ) )                \
  235. X                : Sputc( fd, c )                                                    \
  236. X        )
  237. X
  238. X#define Sgetchar( fd )                                                    \
  239. X        (                                                                        \
  240. X            ( __SIO_ID( fd ).nextb < __SIO_ID( fd ).end )        \
  241. X                ? (int) *__SIO_ID( fd ).nextb++                         \
  242. X                : Sgetc( fd )                                                \
  243. X        )
  244. X
  245. X
  246. X#ifdef __ARGS
  247. X#undef __ARGS
  248. X#endif
  249. X
  250. X#ifdef PROTOTYPES
  251. X#    define __ARGS( s )                    s
  252. X#else
  253. X#    define __ARGS( s )                    ()
  254. X#endif
  255. X
  256. X/*
  257. X * The Read functions
  258. X */
  259. Xint Sread __ARGS( ( int fd, char *buf, int nbytes ) ) ;
  260. Xint Sgetc __ARGS( ( int fd ) ) ;
  261. Xchar *Srdline __ARGS( ( int fd ) ) ;
  262. Xchar *Sfetch __ARGS( ( int fd, long *length ) ) ;
  263. X
  264. X/*
  265. X * The Write functions
  266. X */
  267. Xint Swrite __ARGS( ( int fd, char *buf, int nbytes ) ) ;
  268. Xint Sputc __ARGS( ( int fd, char c ) ) ;
  269. Xint Sprint __ARGS( ( int fd, char *format, ... ) ) ;
  270. Xint Sprintv __ARGS( ( int fd, char *format, va_list ) ) ;
  271. X
  272. X/*
  273. X * other functions
  274. X */
  275. Xint Sdone __ARGS( ( int fd ) ) ;
  276. Xint Sundo __ARGS( ( int fd, int type ) ) ;
  277. Xint Sflush __ARGS( ( int fd ) ) ;
  278. Xint Sclose __ARGS( ( int fd ) ) ;
  279. Xint Sbuftype __ARGS( ( int fd, int type ) ) ;
  280. X
  281. X#endif /* __SIO_H */
  282. X
  283. END_OF_FILE
  284. if test 6642 -ne `wc -c <'libs/src/sio/sio.h'`; then
  285.     echo shar: \"'libs/src/sio/sio.h'\" unpacked with wrong size!
  286. fi
  287. # end of 'libs/src/sio/sio.h'
  288. fi
  289. if test -f 'libs/src/str/strs.c' -a "${1}" != "-c" ; then 
  290.   echo shar: Will not clobber existing file \"'libs/src/str/strs.c'\"
  291. else
  292. echo shar: Extracting \"'libs/src/str/strs.c'\" \(6391 characters\)
  293. sed "s/^X//" >'libs/src/str/strs.c' <<'END_OF_FILE'
  294. X/*
  295. X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  296. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  297. X * and conditions for redistribution.
  298. X */
  299. X
  300. Xstatic char RCSid[] = "$Id: strs.c,v 3.1 1993/06/13 02:50:39 panos Exp $" ;
  301. X
  302. X#include <ctype.h>
  303. X#include <memory.h>
  304. X#include <varargs.h>
  305. X
  306. Xchar *malloc() ;
  307. X
  308. X#include "ss_impl.h"
  309. X
  310. X/*
  311. X * NOTE: The brute force method (with the __strs_bfops) must be always 
  312. X *         available so that we can switch to it if another method fails.
  313. X */
  314. Xextern struct ss_ops __strs_bfops ;
  315. Xextern struct ss_ops __strs_rkops ;
  316. Xextern struct ss_ops __strs_kmpops ;
  317. Xextern struct ss_ops __strs_sbmops ;
  318. Xextern struct ss_ops __strs_bmhops ;
  319. Xextern struct ss_ops __strs_soops ;
  320. X
  321. X/*
  322. X * NOTE: This table is arranged according to increasing method number.
  323. X *            This allows quick indexing into it using the user-provided
  324. X *            method as a hint:
  325. X *                if ( selection_table[ user_method ].method == user_method )
  326. X *                    FOUND
  327. X *                else
  328. X *                    DO SEQUENTIAL SEARCH
  329. X *            This allows both quick access and a change of method numbers
  330. X *            in the future without requiring recompilation of programs in
  331. X *            order to work with new versions of the library.
  332. X */
  333. Xstatic struct ss_select selection_table[] =
  334. X    {
  335. X        { STRS_BF,                    &__strs_bfops        },
  336. X        { STRS_RK,                    &__strs_rkops        },
  337. X        { STRS_KMP,                    &__strs_kmpops        },
  338. X        { STRS_SBM,                    &__strs_sbmops        },
  339. X        { STRS_BMH,                    &__strs_bmhops        },
  340. X        { STRS_SO,                    &__strs_soops        },
  341. X        { 0,                            0                        }
  342. X    } ;
  343. X
  344. Xstatic char identity_map[ ALPHABET_SIZE ] ;
  345. Xstatic char upper_to_lower_map[ ALPHABET_SIZE ] ;
  346. X
  347. Xstatic int tables_initialized ;
  348. X
  349. X/*
  350. X * This header is returned when an empty pattern is given to strs_setup.
  351. X * The rest of the functions check ss_patlen and do nothing if that is zero.
  352. X * ss_patlen in this header will be initialized to zero.
  353. X */
  354. Xstatic header_s empty_pattern_header ;
  355. X
  356. X
  357. XPRIVATE void initialize_tables()
  358. X{
  359. X    int i ;
  360. X
  361. X    for ( i = 0 ; i < sizeof( upper_to_lower_map ) ; i++ )
  362. X    {
  363. X        if ( isascii( i ) && isupper( i ) )
  364. X            upper_to_lower_map[ i ] = i + 'a' - 'A' ;
  365. X        else
  366. X            upper_to_lower_map[ i ] = i ;
  367. X        identity_map[ i ] = i ;
  368. X    }
  369. X}
  370. X
  371. X
  372. X/*
  373. X * Initializes header
  374. X *
  375. X * Note that 'pattern' does not need to be a NUL-terminated string.
  376. X */
  377. XPRIVATE int init( hp, flags, pattern, patlen )
  378. X    register header_s        *hp ;
  379. X    int                        flags ;
  380. X    char                        *pattern ;
  381. X    int                        patlen ;
  382. X{
  383. X    int requested_method = SS_GETMETHOD( flags ) ;
  384. X    register struct ss_select *selp ;
  385. X
  386. X    if ( ! tables_initialized )
  387. X    {
  388. X        initialize_tables() ;
  389. X        tables_initialized = TRUE ;
  390. X    }
  391. X
  392. X    /*
  393. X     * Initialize header fields
  394. X     */
  395. X    SS_FLAGS( hp ) = SS_GETFLAGS( flags ) ;
  396. X    SS_PATLEN( hp ) = patlen ;
  397. X    if ( SS_SWITCH( hp ) && patlen < 4 )
  398. X        SS_OPS( hp ) = &__strs_bfops ;        /* brute force */
  399. X    else
  400. X    {
  401. X        /*
  402. X         * Determine ops
  403. X         */
  404. X        if ( selection_table[ requested_method ].sel_method == requested_method )
  405. X            selp = &selection_table[ requested_method ] ;
  406. X        else
  407. X            for ( selp = &selection_table[ 0 ] ; selp->sel_ops ; selp++ )
  408. X                if ( requested_method == selp->sel_method )
  409. X                    break ;
  410. X        if ( selp->sel_ops )
  411. X            SS_OPS( hp ) = selp->sel_ops ;
  412. X        else if ( SS_SWITCH( hp ) )
  413. X            SS_OPS( hp ) = &__strs_bfops ;        /* brute force */
  414. X        else
  415. X            return( SS_ERR ) ;
  416. X    }
  417. X
  418. X    if ( SS_MALLOC( hp ) )
  419. X    {
  420. X        SS_PATTERN( hp ) = malloc( (unsigned)SS_PATLEN( hp ) ) ;
  421. X        if ( SS_PATTERN( hp ) == CHAR_NULL )
  422. X        {
  423. X            (void) free( (char *)hp ) ;
  424. X            return( SS_ERR ) ;
  425. X        }
  426. X        (void) memcpy( SS_PATTERN( hp ), pattern, (int)SS_PATLEN( hp ) ) ;
  427. X    }
  428. X    else
  429. X        SS_PATTERN( hp ) = pattern ;
  430. X
  431. X    /*
  432. X     * If the user asked for case-insensitive search, we create our own
  433. X     * copy of the pattern in lower case. If the pattern is malloc'ed
  434. X     * we overwrite, otherwise we malloc some memory and clear the
  435. X     * STRS_NOMALLOC flag.
  436. X     */
  437. X    if ( SS_IGNCASE( hp ) )
  438. X    {
  439. X        char *new_pattern ;
  440. X        register int i ;
  441. X
  442. X        SS_SETMAP( hp, upper_to_lower_map ) ;
  443. X
  444. X        if ( SS_MALLOC( hp ) )
  445. X            new_pattern = SS_PATTERN( hp ) ;
  446. X        else
  447. X        {
  448. X            new_pattern = malloc( (unsigned)SS_PATLEN( hp ) + 1 ) ;
  449. X            if ( new_pattern == CHAR_NULL )
  450. X                return( SS_ERR ) ;
  451. X            SS_SETMALLOC( hp ) ;            /* clears the STRS_NOMALLOC flag */
  452. X        }
  453. X        for ( i = 0 ; i < SS_PATLEN( hp ) ; i++ )
  454. X            new_pattern[ i ] = SS_MAP( hp, SS_PATTERN( hp )[ i ] ) ;
  455. X        SS_PATTERN( hp ) = new_pattern ;
  456. X    }
  457. X    else
  458. X        SS_SETMAP( hp, identity_map ) ;
  459. X
  460. X    for ( ;; )
  461. X    {
  462. X        if ( SS_SETUP( hp ) == SS_OK )
  463. X            return( SS_OK ) ;
  464. X        else
  465. X        {
  466. X            if ( ! SS_SWITCH( hp ) || SS_OPS( hp ) == &__strs_bfops )
  467. X            {
  468. X                if ( SS_MALLOC( hp ) )
  469. X                    (void) free( (char *)hp ) ;
  470. X                return( SS_ERR ) ;
  471. X            }
  472. X            SS_OPS( hp ) = &__strs_bfops ;
  473. X        }
  474. X    }
  475. X}
  476. X
  477. X
  478. X/*
  479. X * Finalize header
  480. X */
  481. XPRIVATE void fini( hp )
  482. X    header_s *hp ;
  483. X{
  484. X    SS_DONE( hp ) ;
  485. X    if ( SS_MALLOC( hp ) )
  486. X        (void) free( SS_PATTERN( hp ) ) ;
  487. X}
  488. X
  489. X
  490. X/*
  491. X * Create a search handle
  492. X */
  493. Xstrs_h strs_setup( flags, pattern, va_alist )
  494. X    int    flags ;
  495. X    char    *pattern ;
  496. X    va_dcl
  497. X{
  498. X    header_s        *hp ;
  499. X    int            patlen ;
  500. X    va_list        ap ;
  501. X
  502. X    hp = HP( malloc( sizeof( *hp ) ) ) ;
  503. X    if ( hp == NULL )
  504. X        return( NULL_HANDLE ) ;
  505. X    
  506. X    if ( flags & STRS_PATLEN )
  507. X    {
  508. X        va_start( ap ) ;
  509. X        patlen = va_arg( ap, int ) ;
  510. X        va_end( ap ) ;
  511. X    }
  512. X    else
  513. X        patlen = strlen( pattern ) ;
  514. X
  515. X    if ( patlen == 0 )
  516. X        return( (strs_h) &empty_pattern_header ) ;
  517. X
  518. X    if ( init( hp, flags, pattern, patlen ) == SS_OK )
  519. X        return( (strs_h)hp ) ;
  520. X    else
  521. X    {
  522. X        free( (char *)hp ) ;
  523. X        return( NULL_HANDLE ) ;
  524. X    }
  525. X}
  526. X
  527. X
  528. X/*
  529. X * Destroy a search handle
  530. X */
  531. Xvoid strs_done( handle )
  532. X    strs_h handle ;
  533. X{
  534. X    header_s *hp = HP( handle ) ;
  535. X
  536. X    if ( SS_PATLEN( hp ) != 0 )
  537. X    {
  538. X        fini( hp ) ;
  539. X        (void) free( (char *) handle ) ;
  540. X    }
  541. X}
  542. X
  543. X
  544. Xchar *strs_match( handle, str, len )
  545. X    strs_h    handle ;
  546. X    char        *str ;
  547. X    int        len ;
  548. X{
  549. X    register header_s *hp = HP( handle ) ;
  550. X
  551. X    if ( SS_PATLEN( hp ) == 0 )
  552. X        return( str ) ;
  553. X    if ( SS_PATLEN( hp ) > len )
  554. X        return( CHAR_NULL ) ;
  555. X    return( SS_MATCH( hp, str, len ) ) ;
  556. X}
  557. X
  558. X
  559. X
  560. Xchar *strs_search( flags, str, len, pattern, va_alist )
  561. X    int    flags ;
  562. X    char    *str ;
  563. X    int    len ;
  564. X    char    *pattern ;            /* NUL-terminated */
  565. X    va_dcl
  566. X{
  567. X    header_s        t_header ;
  568. X    char            *p ;
  569. X    int            patlen ;
  570. X    va_list        ap ;
  571. X
  572. X    if ( flags & STRS_PATLEN )
  573. X    {
  574. X        va_start( ap ) ;
  575. X        patlen = va_arg( ap, int ) ;
  576. X        va_end( ap ) ;
  577. X    }
  578. X    else
  579. X        patlen = strlen( pattern ) ;
  580. X
  581. X    if ( patlen == 0 )
  582. X        return( str ) ;
  583. X
  584. X    if ( patlen > len )
  585. X        return( CHAR_NULL ) ;
  586. X
  587. X    if ( init( &t_header, flags | STRS_NOMALLOC, pattern, patlen ) == SS_OK )
  588. X    {
  589. X        p = SS_MATCH( &t_header, str, len ) ;
  590. X        fini( &t_header ) ;
  591. X        return( p ) ;
  592. X    }
  593. X    else
  594. X        return( CHAR_NULL ) ;
  595. X}
  596. X
  597. X
  598. END_OF_FILE
  599. if test 6391 -ne `wc -c <'libs/src/str/strs.c'`; then
  600.     echo shar: \"'libs/src/str/strs.c'\" unpacked with wrong size!
  601. fi
  602. # end of 'libs/src/str/strs.c'
  603. fi
  604. if test -f 'xinetd/child.c' -a "${1}" != "-c" ; then 
  605.   echo shar: Will not clobber existing file \"'xinetd/child.c'\"
  606. else
  607. echo shar: Extracting \"'xinetd/child.c'\" \(6363 characters\)
  608. sed "s/^X//" >'xinetd/child.c' <<'END_OF_FILE'
  609. X/*
  610. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  611. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  612. X * and conditions for redistribution.
  613. X */
  614. X
  615. Xstatic char RCSid[] = "$Id: child.c,v 6.6 1993/06/13 01:42:13 panos Exp $" ;
  616. X
  617. X#include <sys/types.h>
  618. X#include <sys/socket.h>
  619. X#include <sys/time.h>
  620. X#include <sys/resource.h>
  621. X#include <sys/wait.h>
  622. X#include <netinet/in.h>
  623. X#include <syslog.h>
  624. X#include <errno.h>
  625. X
  626. X#include "str.h"
  627. X#include "pset.h"
  628. X
  629. X#include "options.h"
  630. X
  631. X#include "attr.h"
  632. X#include "server.h"
  633. X#include "state.h"
  634. X#include "sconst.h"
  635. X#include "config.h"
  636. X
  637. Xchar *inet_ntoa() ;
  638. X
  639. Xvoid msg() ;
  640. Xvoid msg_suspend() ;
  641. Xvoid msg_resume() ;
  642. X
  643. X
  644. X
  645. XPRIVATE void exec_server( serp )
  646. X    struct server *serp ;
  647. X{
  648. X    struct service_config *scp = SVC_CONF( SERVER_SERVICE( serp ) ) ;
  649. X    int fd ;
  650. X    int descriptor = SERVER_FD( serp ) ;
  651. X    char *server = SC_SERVER( scp ) ;
  652. X    char *func = "exec_server" ;
  653. X    void no_control_tty() ;
  654. X
  655. X    if ( debug.on )
  656. X        msg( LOG_DEBUG, func, "duping %d", descriptor ) ;
  657. X
  658. X    for ( fd = 0 ; fd <= MAX_PASS_FD ; fd++ )
  659. X        if ( dup2( descriptor, fd ) == -1 )
  660. X        {
  661. X            msg( LOG_ERR, func,
  662. X                    "dup2( %d, %d ) failed: %m", descriptor, fd ) ;
  663. X            _exit( 1 ) ;
  664. X        }
  665. X
  666. X    (void) close( descriptor ) ;
  667. X
  668. X    if ( debug.on )
  669. X    {
  670. X        msg( LOG_DEBUG, func, "exec( %s ). no control terminal", server ) ;
  671. X        no_control_tty() ;
  672. X    }
  673. X
  674. X#ifdef RLIMIT_NOFILE
  675. X    {
  676. X        struct rlimit rl ;
  677. X
  678. X        rl.rlim_cur = ps.ros.orig_max_descriptors ;
  679. X        rl.rlim_max = ps.ros.max_descriptors ;
  680. X        (void) setrlimit( RLIMIT_NOFILE, &rl ) ;
  681. X    }
  682. X#endif
  683. X
  684. X    msg_suspend() ;
  685. X
  686. X    (void) execve( server, SC_SERVER_ARGV( scp ),
  687. X                                            env_getvars( SC_ENV( scp )->env_handle ) ) ;
  688. X
  689. X    /*
  690. X     * The exec failed. Log the error and exit.
  691. X     */
  692. X    msg_resume() ;
  693. X    msg( LOG_ERR, func, "execv( %s ) failed: %m", server ) ;
  694. X    _exit( 0 ) ;
  695. X}
  696. X
  697. X
  698. X/*
  699. X * Rename this process by changing the ps.ros.Argv vector
  700. X * Try to put the name of the service in ps.ros.Argv[0], Argv[1]
  701. X * until either the service name is exhausted or we run out
  702. X * of ps.ros.Argv's. 
  703. X * The rest of ps.ros.Argv is cleared to spaces
  704. X */
  705. XPRIVATE void rename_process( name )
  706. X    char *name ;
  707. X{
  708. X    register char *from = name ;
  709. X    register char *to = ps.ros.Argv[ 0 ] ;
  710. X    register int index = 1 ;
  711. X
  712. X    while ( *from != NUL )
  713. X    {
  714. X        if ( *to != NUL )
  715. X            *to++ = *from++ ;
  716. X        else
  717. X            if ( index < ps.ros.Argc )
  718. X                to = ps.ros.Argv[ index++ ] ;
  719. X            else
  720. X                break ;
  721. X    }
  722. X    str_fill( to, ' ' ) ;
  723. X    while ( index < ps.ros.Argc )
  724. X        str_fill( ps.ros.Argv[ index++ ], ' ' ) ;
  725. X}
  726. X
  727. X
  728. XPRIVATE void set_credentials( scp )
  729. X    register struct service_config *scp ;
  730. X{
  731. X    char *func = "set_credentials" ;
  732. X
  733. X    if ( SC_SPECIFIED( scp, A_GROUP ) || SC_SPECIFIED( scp, A_USER ) )
  734. X        if ( ps.ros.is_superuser )
  735. X        {
  736. X            int gid = sc_getgid( scp ) ;
  737. X
  738. X            if ( setgid( gid ) == -1 )
  739. X            {
  740. X                msg( LOG_ERR, func, "setgid failed: %m" ) ;
  741. X                _exit( 1 ) ;
  742. X            }
  743. X        }
  744. X        else
  745. X            msg( LOG_WARNING, func, "can't change gid; not superuser" ) ;
  746. X
  747. X    if ( SC_SPECIFIED( scp, A_USER ) )
  748. X        if ( ps.ros.is_superuser )
  749. X        {
  750. X            if ( setuid( SC_UID( scp ) ) == -1 )
  751. X            {
  752. X                msg( LOG_ERR, func, "setuid failed: %m" ) ;
  753. X                _exit( 1 ) ;
  754. X            }
  755. X        }
  756. X        else
  757. X            msg( LOG_WARNING, func, "can't change uid; not superuser" ) ;
  758. X}
  759. X
  760. X
  761. X
  762. X/*
  763. X * This function is invoked in a forked process to run a server. 
  764. X * If the service is internal the appropriate function is invoked
  765. X * otherwise the server program is exec'ed.
  766. X * This function also logs the remote user id if appropriate
  767. X */
  768. Xvoid child_process( serp )
  769. X    register struct server *serp ;
  770. X{
  771. X    struct service                            *sp = SERVER_SERVICE( serp ) ;
  772. X    register struct service_config    *scp = SVC_CONF( sp ) ;
  773. X    idresult_e                                log_remote_user() ;
  774. X    char                                        *idresult_explain() ;
  775. X    void                                        signal_default_state() ;
  776. X
  777. X#ifdef DEBUG_SERVER
  778. X    if ( debug.on )
  779. X    {
  780. X        msg( LOG_DEBUG, "child_process", "Process %d is sleeping", getpid() ) ;
  781. X        sleep( 10 ) ;
  782. X    }
  783. X#endif
  784. X
  785. X    if ( SERVER_LOGUSER( serp ) )
  786. X    {
  787. X        unsigned timeout ;
  788. X        idresult_e result ;
  789. X        
  790. X        /*
  791. X         * We use LOGUSER_SUCCESS_TIMEOUT unless the service requires
  792. X         * identification, in which case we use an infinite timeout
  793. X         */
  794. X        timeout = SC_MUST_IDENTIFY( scp ) ? 0 : LOGUSER_SUCCESS_TIMEOUT ;
  795. X        result = log_remote_user( serp, timeout ) ;
  796. X
  797. X        if ( result != IDR_OK && SC_MUST_IDENTIFY( scp ) )
  798. X        {
  799. X            svc_logprint( sp, NOID_ENTRY, "%s %s",
  800. X                        conn_addrstr( SERVER_CONNECTION( serp ) ),
  801. X                            idresult_explain( result ) ) ;
  802. X            _exit( 0 ) ;
  803. X        }
  804. X    }
  805. X
  806. X    if ( ! SC_IS_INTERCEPTED( scp ) )
  807. X    {
  808. X        set_credentials( scp ) ;
  809. X        signal_default_state() ;
  810. X        if ( SC_SPECIFIED( scp, A_NICE ) )
  811. X            (void) nice( SC_NICE( scp ) ) ;
  812. X    }
  813. X
  814. X    if ( ! SC_IS_INTERNAL( scp ) )
  815. X        exec_server( serp ) ;
  816. X    else
  817. X    {
  818. X        char name[ 180 ] ;
  819. X
  820. X        /*
  821. X         * We don't bother to disassociate from the controlling terminal
  822. X         *    (we have a controlling terminal only if debug.on is TRUE)
  823. X         *
  824. X         * Also, for interceptor processes, we give them the name:
  825. X         *                <program_name> <service-id> interceptor
  826. X         */
  827. X        if ( SC_IS_INTERCEPTED( scp ) )
  828. X            strx_print( INT_NULL, name, sizeof( name ),
  829. X                                    "%s %s interceptor", program_name, SC_ID( scp ) ) ;
  830. X        else
  831. X        {
  832. X            int namelen = sizeof( name ) - 1 ;        /* leave space for the NUL */
  833. X            struct sockaddr_in *sinp = conn_address( SERVER_CONNECTION( serp ) ) ;
  834. X            int len = strx_nprint( name, namelen,
  835. X                                        "(%s service) %s", program_name, SC_ID( scp ) ) ;
  836. X            
  837. X            if ( SC_ACCEPTS_CONNECTIONS( scp ) && sinp != SOCKADDRIN_NULL )
  838. X                strx_print( INT_NULL, &name[ len ], namelen - len,
  839. X                                                    " %s", inet_ntoa( sinp->sin_addr ) ) ;
  840. X        }
  841. X        rename_process( name ) ;
  842. X        svc_internal( sp, serp ) ;
  843. X    }
  844. X    _exit( 0 ) ;
  845. X    /* NOTREACHED */
  846. X}
  847. X
  848. X
  849. X/*
  850. X * This function is invoked when a SIGCLD is received
  851. X */
  852. Xvoid child_exit()
  853. X{
  854. X    char *func = "child_exit" ;
  855. X
  856. X    for ( ;; )                /* Find all children that exited */
  857. X    {
  858. X        int status ;
  859. X        register int pid ;
  860. X        struct server *serp ;
  861. X        
  862. X#if defined( sun ) && defined( lint )
  863. X        pid = wait3( (union wait *)&status, WNOHANG, RUSAGE_NULL ) ;
  864. X#else
  865. X        pid = wait3( &status, WNOHANG, RUSAGE_NULL ) ;
  866. X#endif
  867. X
  868. X        if ( debug.on )
  869. X            msg( LOG_DEBUG, func, "wait3 returned = %d", pid ) ;
  870. X        
  871. X        if ( pid == -1 )
  872. X            if ( errno == EINTR )
  873. X                continue ;
  874. X            else
  875. X                break ;
  876. X
  877. X        if ( pid == 0 )
  878. X            break ;
  879. X        
  880. X        if ( ( serp = server_lookup( pid ) ) != NULL )
  881. X        {
  882. X            serp->svr_exit_status = status ;
  883. X            server_end( serp ) ;
  884. X        }
  885. X        else
  886. X            msg( LOG_NOTICE, func, "unknown child process %d %s", pid,
  887. X                PROC_STOPPED( status ) ? "stopped" : "died" ) ;
  888. X    }
  889. X}
  890. X
  891. END_OF_FILE
  892. if test 6363 -ne `wc -c <'xinetd/child.c'`; then
  893.     echo shar: \"'xinetd/child.c'\" unpacked with wrong size!
  894. fi
  895. # end of 'xinetd/child.c'
  896. fi
  897. if test -f 'xinetd/udpint.c' -a "${1}" != "-c" ; then 
  898.   echo shar: Will not clobber existing file \"'xinetd/udpint.c'\"
  899. else
  900. echo shar: Extracting \"'xinetd/udpint.c'\" \(6887 characters\)
  901. sed "s/^X//" >'xinetd/udpint.c' <<'END_OF_FILE'
  902. X/*
  903. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  904. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  905. X * and conditions for redistribution.
  906. X */
  907. X
  908. Xstatic char RCSid[] = "$Id: udpint.c,v 6.4 1993/06/06 00:15:17 panos Exp $" ;
  909. X
  910. X#include <sys/types.h>
  911. X#include <sys/socket.h>
  912. X#include <netinet/in.h>
  913. X#include <netdb.h>
  914. X#include <sys/time.h>
  915. X#include <syslog.h>
  916. X#include <errno.h>
  917. X
  918. X#include "access.h"
  919. X#include "defs.h"
  920. X#include "int.h"
  921. X
  922. X/*
  923. X * Datagrams greater than this will be truncated
  924. X */
  925. X#define MAX_DATAGRAM_SIZE            ( 32 * 1024 )
  926. X
  927. Xchar *inet_ntoa() ;
  928. X
  929. Xvoid msg() ;
  930. X
  931. Xstruct packet
  932. X{
  933. X    struct sockaddr_in    from ;
  934. X    char                        *data ;
  935. X    int                        size ;
  936. X} ;
  937. X
  938. Xtypedef struct packet packet_s ;
  939. X
  940. X
  941. Xstruct idgram_private
  942. X{
  943. X    unsigned received_packets ;
  944. X} ;
  945. X
  946. X#define IDP( p )                    ((struct idgram_private *)(p))
  947. X
  948. X
  949. Xstatic struct idgram_private idgram ;
  950. X
  951. XPRIVATE void di_mux() ;
  952. XPRIVATE void di_exit() ;
  953. X
  954. Xstatic struct intercept_ops idgram_ops =
  955. X    {
  956. X        di_mux,
  957. X        di_exit
  958. X    } ;
  959. X
  960. X
  961. Xstatic struct intercept dgram_intercept_state ;
  962. X
  963. X
  964. Xstruct intercept *di_init( serp )
  965. X    struct server *serp ;
  966. X{
  967. X    register struct intercept *ip = &dgram_intercept_state ;
  968. X    
  969. X    ip->int_socket_type = SOCK_DGRAM ;
  970. X    ip->int_priv = (void *) &idgram ;
  971. X    ip->int_ops = &idgram_ops ;
  972. X    int_init( ip, serp ) ;
  973. X    return( ip ) ;
  974. X}
  975. X
  976. X
  977. XPRIVATE void di_exit()
  978. X{
  979. X    register struct intercept *ip = &dgram_intercept_state ;
  980. X    void drain() ;
  981. X
  982. X    if ( IDP( ip->int_priv )->received_packets == 0 )
  983. X        drain( INT_REMOTE( ip ) ) ;
  984. X    int_exit( ip ) ;
  985. X}
  986. X
  987. X
  988. X/*
  989. X * Returns only if there is an I/O error while communicating with the server
  990. X */
  991. XPRIVATE void di_mux()
  992. X{
  993. X    register struct intercept    *ip = &dgram_intercept_state ;
  994. X    fd_set                            socket_mask ;
  995. X    int                                mask_max ;
  996. X    PRIVATE void                    udp_remote_to_local() ;
  997. X    PRIVATE status_e                udp_local_to_remote() ;
  998. X
  999. X    FD_ZERO( &socket_mask ) ;
  1000. X    FD_SET( INT_REMOTE( ip ), &socket_mask ) ;
  1001. X    mask_max = INT_REMOTE( ip ) ;
  1002. X
  1003. X    for ( ;; )
  1004. X    {
  1005. X        register unsigned u ;
  1006. X        channel_s *chp ;
  1007. X        fd_set read_mask ;
  1008. X        int n_ready ;
  1009. X
  1010. X        read_mask = socket_mask ;
  1011. X        n_ready = int_select( mask_max+1, &read_mask ) ;
  1012. X
  1013. X        if ( n_ready == -1 )
  1014. X            return ;
  1015. X        
  1016. X        if ( FD_ISSET( INT_REMOTE( ip ), &read_mask ) )
  1017. X        {
  1018. X            udp_remote_to_local( ip, &chp ) ;
  1019. X            if ( chp != NULL )
  1020. X            {
  1021. X                FD_SET( chp->ch_local_socket, &socket_mask ) ;
  1022. X                if ( chp->ch_local_socket > mask_max )
  1023. X                    mask_max = chp->ch_local_socket ;
  1024. X            }
  1025. X            if ( --n_ready == 0 )
  1026. X                continue ;
  1027. X        }
  1028. X
  1029. X        for ( u = 0 ; u < pset_count( INT_CONNECTIONS( ip ) ) ; u++ )
  1030. X        {
  1031. X            chp = CHP( pset_pointer( INT_CONNECTIONS( ip ), u ) ) ;
  1032. X
  1033. X            if ( FD_ISSET( chp->ch_local_socket, &read_mask ) )
  1034. X            {
  1035. X                if ( udp_local_to_remote( chp ) == FAILED )
  1036. X                    return ;
  1037. X                if ( --n_ready == 0 )
  1038. X                    break ;
  1039. X            }
  1040. X        }
  1041. X    }
  1042. X}
  1043. X
  1044. X
  1045. X/*
  1046. X * Read data from the remote socket and send it to the appropriate local 
  1047. X * socket.
  1048. X * If this is a new connection, insert it in the connection table and
  1049. X * place its handle in *chpp.
  1050. X */
  1051. XPRIVATE void udp_remote_to_local( ip, chpp )
  1052. X    struct intercept    *ip ;
  1053. X    channel_s            **chpp ;
  1054. X{
  1055. X    char                    buf[ MAX_DATAGRAM_SIZE ] ;
  1056. X    packet_s                packet ;
  1057. X    channel_s            *chp ;
  1058. X    bool_int                addr_checked ;
  1059. X    PRIVATE void        send_data() ;
  1060. X    PRIVATE status_e    get_incoming_packet() ;
  1061. X
  1062. X    *chpp = CHANNEL_NULL ;
  1063. X
  1064. X    packet.data = buf ;
  1065. X    packet.size = sizeof( buf ) ;
  1066. X    if ( get_incoming_packet( ip, &packet ) == FAILED )
  1067. X        return ;
  1068. X
  1069. X    chp = int_lookupconn( ip, &packet.from, &addr_checked ) ;
  1070. X    if ( chp == CHANNEL_NULL )
  1071. X    {
  1072. X        struct server        *serp = INT_SERVER( ip ) ;
  1073. X        struct service     *sp = SERVER_SERVICE( serp ) ;
  1074. X        connection_s        *cop = SERVER_CONNECTION( serp ) ;
  1075. X
  1076. X        if ( ( chp = int_newconn( ip, &packet.from, INT_REMOTE( ip ) ) ) == NULL )
  1077. X            return ;
  1078. X
  1079. X        conn_setaddr( cop, &packet.from ) ;        /* for logging */
  1080. X
  1081. X        if ( INTERCEPT( ip ) )
  1082. X        {
  1083. X            mask_t check_mask ;
  1084. X            access_e result ;
  1085. X
  1086. X            M_OR( check_mask, MASK( CF_ADDRESS ), MASK( CF_TIME ) ) ;
  1087. X            result = access_control( sp, cop, &check_mask ) ;
  1088. X
  1089. X            if ( result != AC_OK )
  1090. X            {
  1091. X                svc_log_failure( sp, cop, result ) ;
  1092. X                chp->ch_state = BAD_CHANNEL ;
  1093. X                return ;
  1094. X            }
  1095. X        }
  1096. X        
  1097. X        /*
  1098. X         * Since we don't distinguish ports, there is no point to log
  1099. X         * another successful attempt from the same address
  1100. X         */
  1101. X        if ( ! addr_checked )
  1102. X            svc_log_success( sp, cop, SERVER_PID( serp ) ) ;
  1103. X            
  1104. X        *chpp = chp ;
  1105. X    }
  1106. X    else if ( chp->ch_state == BAD_CHANNEL )
  1107. X        return ;
  1108. X    
  1109. X#ifdef DEBUG_UDPINT
  1110. X    if ( debug.on )
  1111. X        msg( LOG_DEBUG, "udp_remote_to_local",
  1112. X                    "sending %d bytes to server on port %d",
  1113. X                            packet.size, ntohs( INT_LOCALADDR( ip )->sin_port ) ) ;
  1114. X#endif
  1115. X
  1116. X    send_data( chp->ch_local_socket,
  1117. X            packet.data, packet.size, SOCKADDRIN_NULL ) ;
  1118. X}
  1119. X
  1120. X
  1121. X/*
  1122. X * Send the data in buf to destination addr using the socket sd.
  1123. X * If addr is NULL, use the default socket destination
  1124. X */
  1125. XPRIVATE void send_data( sd, buf, len, addr )
  1126. X    int                        sd ;
  1127. X    char                        *buf ;
  1128. X    int                        len ;
  1129. X    struct sockaddr_in    *addr ;
  1130. X{
  1131. X    char    *p ;
  1132. X    int    left ;
  1133. X    int    cc ;
  1134. X    char    *func = "send_data" ;
  1135. X
  1136. X    for ( p = buf, left = len ; left > 0 ; left -= cc, p+= cc )
  1137. X    {
  1138. X        if ( addr == SOCKADDRIN_NULL )
  1139. X            cc = send( sd, p, left, 0 ) ;
  1140. X        else
  1141. X            cc = sendto( sd, p, left, 0, SA( addr ), sizeof( *addr ) ) ;
  1142. X
  1143. X        if ( cc == -1 )
  1144. X            if ( errno == EINTR )
  1145. X            {
  1146. X                cc = 0 ;
  1147. X                continue ;
  1148. X            }
  1149. X            else
  1150. X            {
  1151. X                msg( LOG_ERR, func, "%s: %m", addr ? "sendto" : "send" ) ;
  1152. X                return ;
  1153. X            }
  1154. X    }
  1155. X}
  1156. X
  1157. X
  1158. XPRIVATE status_e get_incoming_packet( ip, pp )
  1159. X    struct intercept *ip ;
  1160. X    packet_s *pp ;
  1161. X{
  1162. X    int from_len ;
  1163. X    char *func = "get_incoming_packet" ;
  1164. X
  1165. X    for ( ;; )
  1166. X    {
  1167. X        int cc ;
  1168. X
  1169. X        from_len = sizeof( pp->from ) ;
  1170. X        cc = recvfrom( INT_REMOTE( ip ), pp->data, pp->size,
  1171. X                                                0, SA( &pp->from ), &from_len ) ;
  1172. X        if ( cc == -1 )
  1173. X        {
  1174. X            if ( errno != EINTR )
  1175. X            {
  1176. X                msg( LOG_ERR, func, "recvfrom error: %m" ) ;
  1177. X                return( FAILED ) ;
  1178. X            }
  1179. X        }
  1180. X        else if ( cc == 0 )
  1181. X            return( FAILED ) ;
  1182. X        else
  1183. X        {
  1184. X            pp->size = cc ;
  1185. X            IDP( ip->int_priv )->received_packets++ ;
  1186. X            break ;
  1187. X        }
  1188. X    }
  1189. X
  1190. X    if ( from_len == 0 )
  1191. X    {
  1192. X        msg( LOG_ERR, func, "incoming packet had 0 length address" ) ;
  1193. X        return( FAILED ) ;
  1194. X    }
  1195. X    
  1196. X#ifdef DEBUG_UDPINT
  1197. X    if ( debug.on )
  1198. X        msg( LOG_DEBUG, func, "Received %d bytes from address: %s,%d",
  1199. X            pp->size,
  1200. X                inet_ntoa( pp->from.sin_addr ), ntohs( pp->from.sin_port ) ) ;
  1201. X#endif
  1202. X
  1203. X    return( OK ) ;
  1204. X}
  1205. X
  1206. X
  1207. X
  1208. XPRIVATE status_e udp_local_to_remote( chp )
  1209. X    channel_s *chp ;
  1210. X{
  1211. X    char    buf[ MAX_DATAGRAM_SIZE ] ;
  1212. X    int    cc ;
  1213. X    char    *func = "udp_local_to_remote" ;
  1214. X
  1215. X    for ( ;; )
  1216. X    {
  1217. X        cc = recv( chp->ch_local_socket, buf, sizeof( buf ), 0 ) ;
  1218. X    
  1219. X        if ( cc == -1 )
  1220. X        {
  1221. X            if ( errno != EINTR ) 
  1222. X            {
  1223. X                msg( LOG_ERR, func, "recv from daemon: %m" ) ;
  1224. X                return( FAILED ) ;
  1225. X            }
  1226. X        }
  1227. X        else if ( cc == 0 )
  1228. X            return( FAILED ) ;
  1229. X        else
  1230. X            break ;
  1231. X    }
  1232. X    
  1233. X#ifdef DEBUG_UDPINT
  1234. X    if ( debug.on )
  1235. X        msg( LOG_DEBUG, func, "sending %d bytes to address %s,%d",
  1236. X            cc, inet_ntoa( chp->ch_from.sin_addr ), ntohs( chp->ch_from.sin_port ) ) ;
  1237. X#endif
  1238. X
  1239. X    send_data( chp->ch_remote_socket, buf, cc, &chp->ch_from ) ;
  1240. X    return( OK ) ;
  1241. X}
  1242. X
  1243. END_OF_FILE
  1244. if test 6887 -ne `wc -c <'xinetd/udpint.c'`; then
  1245.     echo shar: \"'xinetd/udpint.c'\" unpacked with wrong size!
  1246. fi
  1247. # end of 'xinetd/udpint.c'
  1248. fi
  1249. echo shar: End of archive 15 \(of 31\).
  1250. cp /dev/null ark15isdone
  1251. MISSING=""
  1252. 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
  1253.     if test ! -f ark${I}isdone ; then
  1254.     MISSING="${MISSING} ${I}"
  1255.     fi
  1256. done
  1257. if test "${MISSING}" = "" ; then
  1258.     echo You have unpacked all 31 archives.
  1259.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1260. else
  1261.     echo You still need to unpack the following archives:
  1262.     echo "        " ${MISSING}
  1263. fi
  1264. ##  End of shell archive.
  1265. exit 0
  1266.