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

  1. Newsgroups: comp.sources.unix
  2. From: panos@cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v26i260: xinetd-2.1.1 - inetd replacement with access control and logging, Part16/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 260
  9. Archive-Name: xinetd-2.1.1/part16
  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 16 (of 31)."
  18. # Contents:  libs/src/xlog/xlog.3 xinetd/init.c xinetd/sconf.h
  19. #   xinetd/server.c
  20. # Wrapped by panos@mystique on Mon Jun 21 14:51:25 1993
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'libs/src/xlog/xlog.3' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'libs/src/xlog/xlog.3'\"
  24. else
  25. echo shar: Extracting \"'libs/src/xlog/xlog.3'\" \(7126 characters\)
  26. sed "s/^X//" >'libs/src/xlog/xlog.3' <<'END_OF_FILE'
  27. X.\"(c) Copyright 1992, 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.\" $Id: xlog.3,v 2.3 1993/06/15 18:09:31 panos Exp $
  32. X.TH XLOG 3X "15 June 1993"
  33. Xxlog_parms, xlog_create, xlog_destroy, xlog_write, xlog_control -- general purpose logging facility
  34. X.SH SYNOPSIS
  35. X.LP
  36. X.nf
  37. X.ft B
  38. X#include "xlog.h"
  39. X.LP
  40. X.ft B
  41. Xxlog_h xlog_create( type, id, flags, ... )
  42. Xxlog_e type ;
  43. Xchar *id ;
  44. Xint flags ;
  45. X.LP
  46. X.ft B
  47. Xint xlog_parms( type, ... )
  48. Xxlog_e type ;
  49. X.LP
  50. X.ft B
  51. Xvoid xlog_destroy( xlog )
  52. Xxlog_h xlog ;
  53. X.LP
  54. X.ft B
  55. Xvoid xlog_write( xlog, buf, len, flags, ... )
  56. Xxlog_h xlog ;
  57. Xchar buf[] ;
  58. Xint len ;
  59. Xint flags ;
  60. X.LP
  61. X.ft B
  62. Xint xlog_control( xlog, cmd, ... )
  63. Xxlog_h xlog ;
  64. Xxlog_cmd_e cmd ;
  65. X.SH DESCRIPTION
  66. XThe purpose of this library is to provide a general purpose logging facility
  67. Xby providing
  68. X.I xlogs,
  69. Xlogging objects that may be connected to various existent logging facilities.
  70. XCurrently, the only logging facilities supported are
  71. X.I "syslog(3)"
  72. Xand logging to files.
  73. XLog entries are timestamped lines which may contain arbitrary information.
  74. X.\" ********************* xlog_create ***********************
  75. X.LP
  76. X.B xlog_create()
  77. Xcreates a new xlog of the specified
  78. X.I type.
  79. XPossible type values are:
  80. X.RS
  81. X.TP 20
  82. X.SB XLOG_SYSLOG
  83. XVarargs: \fIint facility, int priority\fP.
  84. XThe xlog will be connected to 
  85. X.I "syslog(3)." 
  86. X.I facility
  87. Xdetermines the syslog facility to use for logged messages and 
  88. X.I priority
  89. Xis the default message priority.
  90. X.TP
  91. X.SB XLOG_FILELOG
  92. XVarargs: \fIchar *pathname, int flags [, int flags]\fP.
  93. XThe xlog will be connected to the file identified by
  94. X.I pathname.
  95. XThe variable part of the argument list has the same semantics as the
  96. Xargument list of the
  97. X.I "open(2)"
  98. Xsystem call.
  99. X.RE
  100. X.LP
  101. XAll xlogs have an id, specified by the 
  102. X.I id 
  103. Xargument. The
  104. X.I flags
  105. Xargument is formed by ORing one or more of the following constants:
  106. X.RS
  107. X.TP 20
  108. X.SB XLOG_NO_ERRNO
  109. Xdo not replace 
  110. X.I "%m" 
  111. Xwith an explanation of the current value of errno.
  112. X.TP
  113. X.SB XLOG_NO_SIZECHECK
  114. X.I "(XLOG_FILELOG only)"
  115. Xdo not perform size checks on the file.
  116. X.TP
  117. X.SB XLOG_PRINT_ID
  118. Xprecede each log entry with the xlog id
  119. X.TP
  120. X.SB XLOG_PRINT_PID
  121. Xprecede each log entry with the process id
  122. X(the process id will follow the xlog id)
  123. X.RE
  124. X.LP
  125. XFlags that do not apply to the xlog are ignored.
  126. XThe contant
  127. X.SM XLOG_NOFLAGS
  128. Xcan be used if you don't want to specify any flags.
  129. X.\" ********************* xlog_parms ***********************
  130. X.LP
  131. X.B xlog_parms()
  132. Xsets default parameters for the specified xlog
  133. X.I type:
  134. X.RS
  135. X.TP 20
  136. X.SB XLOG_SYSLOG
  137. X3 arguments are expected which correspond one-to-one to the arguments of 
  138. X.I "openlog(3)."
  139. XThe defaults, in case this function is not used, are:
  140. X"XLOG", LOG_PID + LOG_NOWAIT, LOG_USER
  141. X.TP
  142. X.SB XLOG_FILELOG
  143. XNo action.
  144. X.RE
  145. X.LP
  146. X.B xlog_parms()
  147. Xshould be invoked before any xlogs of the specified type
  148. Xare created.
  149. X.\" ********************* xlog_destroy ***********************
  150. X.LP
  151. X.B xlog_destroy()
  152. Xdestroys an xlog. The action taken depends on the type of the xlog:
  153. X.RS
  154. X.TP 20
  155. X.SB XLOG_SYSLOG
  156. Xif this is the last xlog using syslog, then
  157. X.I "closelog(3)"
  158. Xis invoked.
  159. X.TP
  160. X.SB XLOG_FILELOG
  161. XThe file is closed.
  162. X.RE
  163. X.\" ********************* xlog_control ***********************
  164. X.LP
  165. X.B xlog_control()
  166. Xapplies control operations to an xlog. Certain operations are common to
  167. Xall xlogs while others are type-specific. The common ones are:
  168. X.RS
  169. X.TP 15
  170. X.SB XLOG_LINK
  171. XArgument list: \fIxlog_h link_to\fP.
  172. XLink the specified xlog to the one provided as argument.
  173. X(if the argument is
  174. X.SM NULL
  175. Xany existent link is severed).
  176. XLinking xlogs has the effect that if one finds an error it uses the
  177. Xother to report it.
  178. X.TP
  179. X.SB XLOG_CALLBACK
  180. XArgument list: \fIvoid (*callback)(), void *arg\fP.
  181. XThis function will be invoked in case of error while writing a log
  182. Xentry. It will be given
  183. X3 arguments: the xlog handle, an integer that indicates the type
  184. Xof error and the
  185. X.I arg 
  186. Xspecified in this call. Possible errors include:
  187. X.RS
  188. X.TP 15
  189. X.SB XLOG_ENOMEM
  190. Xlack of memory
  191. X.TP
  192. X.SB XLOG_EOPEN
  193. X.I "open(2)"
  194. Xfailed
  195. X.TP
  196. X.SB XLOG_EFSTAT
  197. X.I "fstat(2)"
  198. Xfailed
  199. X.TP
  200. X.SB XLOG_ESIZE
  201. Xhard limit exceeded
  202. X.RE
  203. X.TP
  204. X.SB XLOG_SETFLAG
  205. XArgument list: \fIint flag, int *value\fP.
  206. XThe value of
  207. X.I flag
  208. X(one of those listed before) is set according to
  209. X.I "*value"
  210. Xwhich should be either 0 or 1.
  211. XThe old flag value is placed in 
  212. X.I "*value."
  213. X.TP
  214. X.SB XLOG_GETFLAG
  215. XArgument list: \fIint flag, int *value\fP.
  216. XThe value of 
  217. X.I flag
  218. X(one of those listed before) is placed in
  219. X.I "*value."
  220. X.RE
  221. X.LP
  222. XXlogs of type
  223. X.B XLOG_SYSLOG
  224. Xalso support the following operations:
  225. X.RS
  226. X.TP 15
  227. X.SB XLOG_FACILITY
  228. XArgument list: \fIint facility\fP.
  229. XSets the syslog facility to the specified value.
  230. X.TP
  231. X.SB XLOG_LEVEL
  232. XArgument list: \fIint level\fP.
  233. XSets the default syslog level for this xlog to the specified value.
  234. X.TP
  235. X.SB XLOG_PREEXEC
  236. XArgument list: \fIvoid\fP.
  237. XPrepares the xlog for an impending exec operation
  238. X.TP
  239. X.SB XLOG_POSTEXEC
  240. XArgument list: \fIvoid\fP.
  241. XInforms the xlog that the exec failed
  242. X.RE
  243. X.LP
  244. XXlogs of type
  245. X.B XLOG_FILELOG
  246. Xalso support the following operations:
  247. X.RS
  248. X.TP 15
  249. X.SB XLOG_LIMITS
  250. XArgument list: \fIunsigned soft_limit, unsigned hard_limit\fP.
  251. XSets soft and hard limits on the size of the file.
  252. XWhen any of the limits is exceeded a message is sent to the linked xlog.
  253. X(if there is no linked xlog, no message is sent)
  254. XWhen the soft limit is exceeded a warning message is sent to the linked xlog
  255. X(if the linked xlog is of the
  256. X.SB XLOG_SYSLOG
  257. Xtype, the message will be sent at the
  258. X.I LOG_ALERT
  259. Xlevel).
  260. XIf the exceeded limit is the hard limit, logging is terminated.
  261. XThe actual file size is checked every time this operation is applied to
  262. Xthe file.
  263. XIf logging was terminated because the hard limit was exceeded and
  264. Xthis operation increases the hard limit beyond the actual file size,
  265. Xlogging will be resumed.
  266. X.TP
  267. X.SB XLOG_SIZECHECK
  268. XArgument list: \fIvoid\fP.
  269. XChecks the actual file size.
  270. X.TP
  271. X.SB XLOG_GETFD
  272. XArgument list: \fIint *value\fP.
  273. XPlaces in
  274. X.I "*value"
  275. Xthe file descriptor of the log file.
  276. X.RE
  277. X.\" ********************* xlog_write ***********************
  278. X.LP
  279. X.B xlog_write()
  280. Xwrites a message to the specified xlog. A
  281. X.SM NEWLINE
  282. Xis always appended to the message.
  283. XThe first occurrence of "%m" in
  284. X.I buf
  285. Xis replaced by a string explaining the current value of
  286. X.I errno.
  287. XThe
  288. X.I flags
  289. Xargument is formed in the same way as in 
  290. X.B xlog_create().
  291. XOne additional constant is available:
  292. X.RS
  293. X.TP 20
  294. X.SB XLOG_SET_LEVEL
  295. X.I "(XLOG_SYSLOG only)"
  296. Xthe next argument is an integer that should be used as the syslog level
  297. Xfor this message instead of the default level of the xlog.
  298. X.RE
  299. X.SH "RETURN VALUES"
  300. X.B xlog_create()
  301. Xreturns an xlog handle or
  302. X.SM NULL
  303. Xif it fails.
  304. X.LP
  305. X.B xlog_control()
  306. Xreturns an error code (it returns
  307. X.SM XLOG_ENOERROR
  308. Xif it is successful).
  309. X.LP
  310. X.B xlog_parms()
  311. Xreturns an error code (it returns
  312. X.SM XLOG_ENOERROR
  313. Xif it is successful).
  314. X.SH "SEE ALSO"
  315. Xopenlog(3), syslog(3), closelog(3)
  316. X.SH BUGS
  317. X.LP
  318. XOnly the first occurrence of
  319. X.I "%m"
  320. Xis replaced by an errno explanation.
  321. X.LP
  322. XThere is no check for cycles when linking xlogs. In particular it is
  323. Xpossible to link a xlog to itself.
  324. END_OF_FILE
  325. if test 7126 -ne `wc -c <'libs/src/xlog/xlog.3'`; then
  326.     echo shar: \"'libs/src/xlog/xlog.3'\" unpacked with wrong size!
  327. fi
  328. # end of 'libs/src/xlog/xlog.3'
  329. fi
  330. if test -f 'xinetd/init.c' -a "${1}" != "-c" ; then 
  331.   echo shar: Will not clobber existing file \"'xinetd/init.c'\"
  332. else
  333. echo shar: Extracting \"'xinetd/init.c'\" \(7287 characters\)
  334. sed "s/^X//" >'xinetd/init.c' <<'END_OF_FILE'
  335. X/*
  336. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  337. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  338. X * and conditions for redistribution.
  339. X */
  340. X
  341. Xstatic char RCSid[] = "$Id: init.c,v 6.11 1993/06/15 23:25:57 panos Exp $" ;
  342. X
  343. X#include <sys/types.h>
  344. X#include <sys/time.h>
  345. X#include <sys/resource.h>
  346. X#include <syslog.h>
  347. X#include <fcntl.h>
  348. X
  349. X#include "sio.h"
  350. X#include "str.h"
  351. X#include "pset.h"
  352. X#include "xlog.h"
  353. X
  354. X#include "options.h"
  355. X
  356. X#include "state.h"
  357. X#include "defs.h"
  358. X#include "config.h"
  359. X#include "conf.h"
  360. X
  361. X
  362. Xstruct module
  363. X{
  364. X    char *name ;
  365. X    status_e (*initializer)() ;
  366. X} ;
  367. X
  368. X
  369. Xchar        *msg_init() ;
  370. Xstatus_e signal_init() ;
  371. Xstatus_e initenv() ;
  372. Xstatus_e create_conf_timer() ;
  373. Xstatus_e create_retry_timer() ;
  374. Xstatus_e create_cc_timer() ;
  375. X
  376. Xstatic struct module program_modules[] = 
  377. X    {
  378. X        { "signal",                            signal_init                },
  379. X        { "environment",                    initenv                    },
  380. X#ifndef NO_TIMERS
  381. X        { "conf timer",                    create_conf_timer        },
  382. X        { "retry timer",                    create_retry_timer    },
  383. X        { "consistency check timer",    create_cc_timer        },
  384. X#endif
  385. X        { CHAR_NULL }
  386. X    } ;
  387. X
  388. X
  389. Xstatic bool_int have_stderr ;
  390. X
  391. Xextern int sys_nerr;
  392. Xextern char *sys_errlist[];
  393. Xextern int errno;
  394. X
  395. Xvoid msg() ;
  396. X
  397. Xvoid exit() ;
  398. X
  399. X#define STDERR_FD                        2
  400. X
  401. X
  402. X/*
  403. X * This function is invoked when a system call fails during initialization.
  404. X * A message is printed to stderr, and the program is terminated
  405. X */
  406. XPRIVATE void syscall_failed( call )
  407. X    char *call ;
  408. X{
  409. X    char errno_buf[ 40 ] ;
  410. X    char *err ;
  411. X
  412. X    if ( have_stderr )
  413. X    {
  414. X        if ( errno < sys_nerr )
  415. X            err = sys_errlist[ errno ] ;
  416. X        else
  417. X            err = strx_sprint( errno_buf, sizeof( errno_buf ),
  418. X                                                                "errno = %d", errno ) ;
  419. X        Sprint( STDERR_FD, "%s: %s failed: %s\n", program_name, call, err ) ;
  420. X    }
  421. X    exit( 1 ) ;
  422. X}
  423. X
  424. X
  425. X
  426. X/*
  427. X * Close all descriptors except STDERR_FD. We need this to report
  428. X * errors and the process pid of the daemon.
  429. X * Open all descriptors in the range 0..MAX_PASS_FD (except STDERR_FD)
  430. X * to the root directory.
  431. X * STDERR_FD should not be 0.
  432. X */
  433. XPRIVATE void setup_file_descriptors()
  434. X{
  435. X    int    fd ;
  436. X    int    new ;
  437. X    int    root_fd ;
  438. X    int    n_descriptors = getdtablesize() ;
  439. X
  440. X    /*
  441. X     * Close all unneeded descriptors
  442. X     */
  443. X    for ( fd = 0 ; fd < n_descriptors ; fd++ )
  444. X        if ( fd != STDERR_FD )
  445. X            (void) close( fd ) ;
  446. X    
  447. X    /*
  448. X     * Check if the STDERR_FD descriptor is open.
  449. X     */
  450. X    new = dup( STDERR_FD ) ;
  451. X    if ( new != -1 )
  452. X    {
  453. X        have_stderr = TRUE ;
  454. X        (void) close( new ) ;
  455. X    }
  456. X
  457. X    if ( ( root_fd = open( "/", O_RDONLY ) ) == -1 )
  458. X        syscall_failed( "open of '/'" ) ;
  459. X
  460. X    for ( fd = 0 ; fd <= MAX_PASS_FD ; fd++ )
  461. X    {
  462. X        if ( have_stderr && fd == STDERR_FD )
  463. X            continue ;
  464. X        if ( fd != root_fd && dup2( root_fd, fd ) == -1 )
  465. X            syscall_failed( "dup2" ) ;
  466. X    }
  467. X
  468. X    if ( root_fd > MAX_PASS_FD )
  469. X        (void) close( root_fd ) ;
  470. X}
  471. X
  472. X
  473. X
  474. XPRIVATE void set_fd_limit()
  475. X{
  476. X#ifdef RLIMIT_NOFILE
  477. X
  478. X    struct rlimit rl ;
  479. X    char *func = "set_fd_limit" ;
  480. X
  481. X    /*
  482. X     * Set the soft file descriptor limit to the hard limit.
  483. X     */
  484. X    if ( getrlimit( RLIMIT_NOFILE, &rl ) == -1 )
  485. X    {
  486. X        msg( LOG_CRIT, func, "getrlimit: %m" ) ;
  487. X        exit( 1 ) ;
  488. X    }
  489. X
  490. X    ps.ros.orig_max_descriptors = rl.rlim_cur ;
  491. X   ps.ros.max_descriptors = rl.rlim_max ;
  492. X
  493. X    rl.rlim_cur = rl.rlim_max ;
  494. X    if ( setrlimit( RLIMIT_NOFILE, &rl ) == -1 )
  495. X    {
  496. X        ps.ros.max_descriptors = ps.ros.orig_max_descriptors ;
  497. X        return ;
  498. X    }
  499. X
  500. X    if ( Smorefds() == SIO_ERR )
  501. X    {
  502. X        msg( LOG_CRIT, func, "Smorefds: %m" ) ;
  503. X        exit( 1 ) ;
  504. X    }
  505. X
  506. X#else        /* ! RLIMIT_NOFILE */
  507. X
  508. X   ps.ros.max_descriptors = getdtablesize() ;
  509. X
  510. X#endif    /* RLIMIT_NOFILE */
  511. X}
  512. X
  513. X
  514. XPRIVATE void init_common( argc, argv )
  515. X    int argc ;
  516. X    char *argv[] ;
  517. X{
  518. X    struct module *mp ;
  519. X    char *func = "init_common" ;
  520. X
  521. X    /*
  522. X     * Initialize the program state
  523. X     */
  524. X    set_fd_limit() ;
  525. X
  526. X    ps.ros.Argv = argv ;
  527. X    ps.ros.Argc = argc ;
  528. X   ps.ros.config_file = f_option ? f_option_arg : DEFAULT_CONFIG_FILE ;
  529. X    ps.ros.is_superuser = ( geteuid() == 0 ) ;
  530. X    if ( limit_option )
  531. X        ps.ros.process_limit = limit_option_arg ;
  532. X    ps.ros.loop_rate = ( loop_option ) ? loop_option_arg : DEFAULT_LOOP_RATE ;
  533. X
  534. X    /*
  535. X     * Initialize the program modules
  536. X     */
  537. X    for ( mp = program_modules ; mp->name ; mp++ )
  538. X        if ( (*mp->initializer)() == FAILED )
  539. X        {
  540. X            msg( LOG_CRIT, func,
  541. X                "Initialization of %s facility failed. Exiting...", mp->name ) ;
  542. X            exit( 1 ) ;
  543. X        }
  544. X    (void) umask( 0 ) ;
  545. X}
  546. X
  547. X
  548. X/*
  549. X * Become a daemon by forking a new process. The parent process exits.
  550. X */
  551. XPRIVATE void become_daemon()
  552. X{
  553. X    int    tries ;
  554. X    int    pid ;
  555. X    char    *func = "become_daemon" ;
  556. X    void    no_control_tty() ;
  557. X
  558. X    /*
  559. X     * First fork so that the parent will think we have exited
  560. X     */
  561. X    for ( tries = 0 ;; tries++ )
  562. X    {
  563. X        if ( tries == 5 )
  564. X        {
  565. X            msg( LOG_CRIT, func, "fork: %m. Exiting..." ) ;
  566. X            exit( 0 ) ;
  567. X        }
  568. X
  569. X        pid = fork() ;
  570. X
  571. X        if ( pid == -1 )
  572. X        {
  573. X            sleep( 1 ) ;    /* wait for a second */
  574. X            continue ;        /* and then retry        */
  575. X        }
  576. X        else if ( pid == 0 )
  577. X            break ;
  578. X        else
  579. X        {
  580. X            if ( pid_option && have_stderr )
  581. X                Sprint( STDERR_FD, "%d\n", pid ) ;
  582. X#ifndef DEBUG_DAEMON
  583. X            sleep( 3 ) ;    /* give some time to the daemon to initialize */
  584. X#endif
  585. X            exit( 0 ) ;
  586. X        }
  587. X    }
  588. X
  589. X    (void) dup2( 0, STDERR_FD ) ;
  590. X    no_control_tty() ;
  591. X
  592. X#ifdef DEBUG_DAEMON
  593. X    sleep( 20 ) ;         /* XXX: timers will probably not work after this */
  594. X#endif
  595. X}
  596. X
  597. X
  598. X
  599. XPRIVATE pset_h new_table( size )
  600. X    unsigned size ;
  601. X{
  602. X    char *func = "new_table" ;
  603. X    pset_h tab = pset_create( size, 0 ) ;
  604. X
  605. X    if ( tab == NULL )
  606. X    {
  607. X        msg( LOG_CRIT, func, "Failed to create table" ) ;
  608. X        exit( 1 ) ;
  609. X    }
  610. X    return( tab ) ;
  611. X}
  612. X
  613. X
  614. X/*
  615. X * Create tables
  616. X */
  617. XPRIVATE void init_rw_state()
  618. X{
  619. X   SERVERS( ps ) = new_table( 0 ) ;
  620. X    RETRIES( ps ) = new_table( 0 ) ;
  621. X    SERVICES( ps ) = new_table( 0 ) ;
  622. X
  623. X    ps.rws.descriptors_free = ps.ros.max_descriptors - DESCRIPTORS_RESERVED ;
  624. X
  625. X    FD_ZERO( &ps.rws.socket_mask ) ;
  626. X    ps.rws.mask_max = 0 ;
  627. X
  628. X}
  629. X
  630. X
  631. X/*
  632. X * Perform all necessary initializations
  633. X */
  634. Xvoid init_daemon( argc, argv )
  635. X    int argc ;
  636. X    char *argv[] ;
  637. X{
  638. X    char *fail ;
  639. X
  640. X    setup_file_descriptors() ;
  641. X
  642. X    (void) opt_recognize( argc, argv ) ;
  643. X    debug.on = d_option ;
  644. X
  645. X    /*
  646. X     * XXX: we only use xlog_parms on XLOG_SYSLOG-type logs but in general
  647. X     *          we should do it for all types of xlog's we may use. We can get
  648. X     *          away with this now, because xlog_parms for XLOG_FILELOG is a noop.
  649. X     */
  650. X    (void) xlog_parms( XLOG_SYSLOG,
  651. X                    program_name, LOG_PID + LOG_NOWAIT, LOG_DAEMON ) ;
  652. X
  653. X    /*
  654. X     * Initialize the message facility; after this everything can use the
  655. X     * msg() interface
  656. X     */
  657. X    if ( fail = msg_init() )
  658. X    {
  659. X        if ( have_stderr )
  660. X            Sprint( STDERR_FD, "%s: msg_init failed: %s\n", program_name, fail ) ;
  661. X        exit( 1 ) ;
  662. X    }
  663. X
  664. X    init_common( argc, argv ) ;
  665. X
  666. X    if ( ! debug.on )
  667. X        become_daemon() ;
  668. X    
  669. X    init_rw_state() ;
  670. X}
  671. X
  672. X
  673. X/*
  674. X * Initialize all services
  675. X *
  676. X * This function is either successful in starting some services 
  677. X * or it terminates the program.
  678. X */
  679. Xvoid init_services()
  680. X{
  681. X    struct configuration conf ;
  682. X    char *func = "init_services" ;
  683. X    void spec_include() ;
  684. X
  685. X    if ( cnf_get( &conf, (long)0 ) == FAILED )
  686. X    {
  687. X        msg( LOG_CRIT, func, "couldn't get configuration. Exiting..." ) ;
  688. X        exit( 1 ) ;
  689. X    }
  690. X
  691. X    DEFAULTS( ps ) = CNF_DEFAULTS( &conf ) ;
  692. X    (void) cnf_start_services( &conf ) ;
  693. X    CNF_DEFAULTS( &conf ) = NULL ;        /* to avoid the free by cnf_free */
  694. X    cnf_free( &conf ) ;
  695. X
  696. X    /*
  697. X     * The number of available/active services is kept by the service functions
  698. X     */
  699. X    if ( ps.rws.available_services == 0 )
  700. X    {
  701. X        msg( LOG_CRIT, func, "no services. Exiting..." ) ;
  702. X        exit( 1 ) ;
  703. X    }
  704. X
  705. X    spec_include() ;        /* include special services */
  706. X}
  707. X
  708. END_OF_FILE
  709. if test 7287 -ne `wc -c <'xinetd/init.c'`; then
  710.     echo shar: \"'xinetd/init.c'\" unpacked with wrong size!
  711. fi
  712. # end of 'xinetd/init.c'
  713. fi
  714. if test -f 'xinetd/sconf.h' -a "${1}" != "-c" ; then 
  715.   echo shar: Will not clobber existing file \"'xinetd/sconf.h'\"
  716. else
  717. echo shar: Extracting \"'xinetd/sconf.h'\" \(7383 characters\)
  718. sed "s/^X//" >'xinetd/sconf.h' <<'END_OF_FILE'
  719. X/*
  720. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  721. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  722. X * and conditions for redistribution.
  723. X */
  724. X
  725. X#ifndef SCONF_H
  726. X#define SCONF_H
  727. X
  728. X/*
  729. X * $Id: sconf.h,v 6.5 1993/06/01 22:56:06 panos Exp $
  730. X */
  731. X
  732. X#include "pset.h"
  733. X#include "env.h"
  734. X#include "sio.h"
  735. X
  736. X#include "defs.h"
  737. X#include "log.h"
  738. X#include "mask.h"
  739. X#include "builtin.h"
  740. X
  741. X/*
  742. X * Service types
  743. X */
  744. X#define ST_RPC                      1
  745. X#define ST_INTERNAL                 2
  746. X#define ST_UNLISTED                 3
  747. X#define ST_SPECIAL                    4
  748. X
  749. X/*
  750. X * Service flags
  751. X */
  752. X#define SF_INTERCEPT                    1
  753. X#define SF_REUSE                        2
  754. X#define SF_NORETRY                    3
  755. X#define SF_IDONLY                        4
  756. X
  757. X/*
  758. X * Values for log options
  759. X */
  760. X#define LO_HOST      1
  761. X#define LO_DURATION  3
  762. X#define LO_ATTEMPT   4
  763. X#define LO_EXIT      5
  764. X#define LO_RECORD    6
  765. X#define LO_PID            7
  766. X#define LO_START     8
  767. X#define LO_USERID        9
  768. X
  769. X
  770. X
  771. Xstruct rpc_data
  772. X{
  773. X   unsigned long rd_min_version ;
  774. X   unsigned long rd_max_version ;
  775. X   unsigned long rd_program_number ;
  776. X} ;
  777. X
  778. X#define RD_MINVERS( rdp )                (rdp)->rd_min_version
  779. X#define RD_MAXVERS( rdp )                (rdp)->rd_max_version
  780. X#define RD_PROGNUM( rdp )                 (rdp)->rd_program_number
  781. X
  782. Xtypedef enum { NO_ENV = 0, STD_ENV, DEF_ENV, CUSTOM_ENV } environ_e ;
  783. X
  784. Xstruct environment
  785. X{
  786. X   environ_e    env_type ;
  787. X    env_h            env_handle ;
  788. X} ;
  789. X
  790. X
  791. X/*
  792. X * NOTE: Clearing the structure will give all its fields their default values
  793. X */
  794. Xstruct service_config
  795. X{
  796. X   mask_t         sc_specified_attributes ;    /* specified attributes          */
  797. X   mask_t         sc_attributes_present ;    /* includes those from defaults  */
  798. X   mask_t         sc_type ;                  /* RPC, UNLISTED etc.            */
  799. X    mask_t         sc_flags ;                        /* REUSE, INTERCEPT etc.            */
  800. X   char             *sc_name ;                 /* e.g. "echo"                   */
  801. X   char             *sc_id ;                   /* e.g. "echo-stream"            */
  802. X   unsigned     sc_port ;                  /* in host byte order            */
  803. X   int             sc_socket_type ;           /* e.g. SOCK_DGRAM               */
  804. X   struct name_value sc_protocol ;        /* e.g. "TCP", IPPROTO_TCP       */
  805. X   boolean_e     sc_wait ;
  806. X   int            sc_uid ;
  807. X   int            sc_user_gid ;              /* gid corresponding to uid      */
  808. X   int            sc_gid ;                   /* gid corresponding to group    */
  809. X   char            *sc_server ;
  810. X   char            **sc_server_argv ;
  811. X   int            sc_instances ;
  812. X    int            sc_nice ;                        /* argument for nice(3)                */
  813. X   pset_h        sc_env_var_defs ;          /* list of env strings           */
  814. X   pset_h        sc_pass_env_vars ;         /* env vars to pass to server    */
  815. X   pset_h        sc_access_times ;
  816. X   pset_h        sc_only_from ;
  817. X   pset_h        sc_no_access ;
  818. X   mask_t        sc_log_on_success ;
  819. X   mask_t        sc_log_on_failure ;
  820. X   struct log    sc_log ;
  821. X   struct rpc_data sc_rd ;
  822. X   pset_h        sc_disabled ;              /* used only by the default entry */
  823. X   struct environment sc_environment ;
  824. X    builtin_s    *sc_builtin ;
  825. X} ;
  826. X
  827. X#define SCP( p )                        ((struct service_config *)(p))
  828. X
  829. X/*
  830. X * Field access macros
  831. X */
  832. X#define SC_LOG( scp )                (&(scp)->sc_log)
  833. X#define SC_RPCDATA( scp )        (&(scp)->sc_rd)
  834. X#define SC_ENV( scp )            (&(scp)->sc_environment)
  835. X#define SC_BUILTIN( scp )            (scp)->sc_builtin
  836. X#define SC_PORT( scp )                (scp)->sc_port
  837. X#define SC_NICE( scp )                (scp)->sc_nice
  838. X#define SC_SOCKET_TYPE( scp )        (scp)->sc_socket_type
  839. X#define SC_ID( scp )                    (scp)->sc_id
  840. X#define SC_NAME( scp )                (scp)->sc_name
  841. X#define SC_PROTOVAL( scp )            (scp)->sc_protocol.value
  842. X#define SC_PROTONAME( scp )        (scp)->sc_protocol.name
  843. X#define SC_INSTANCES( scp )        (scp)->sc_instances
  844. X#define SC_UID( scp )                (scp)->sc_uid
  845. X#define SC_SERVER( scp )            (scp)->sc_server
  846. X#define SC_SERVER_ARGV( scp )        (scp)->sc_server_argv
  847. X#define SC_ONLY_FROM( scp )        (scp)->sc_only_from
  848. X#define SC_NO_ACCESS( scp )        (scp)->sc_no_access
  849. X#define SC_ACCESS_TIMES( scp )    (scp)->sc_access_times
  850. X#define SC_LOG_ON_SUCCESS( scp )    (scp)->sc_log_on_success
  851. X#define SC_LOG_ON_FAILURE( scp )    (scp)->sc_log_on_failure
  852. X
  853. X/*
  854. X * Field set macros
  855. X */
  856. X#define sc_set_port( scp, port )    (scp)->sc_port = (port)
  857. X
  858. X/*
  859. X * Predicate checking macros
  860. X */
  861. X#define SC_FORKS( scp )                ( ! SC_IS_INTERNAL( scp ) ||                        \
  862. X                                                    builtin_forks( (scp)->sc_builtin ) )
  863. X#define SC_WAITS( scp )                ( (scp)->sc_wait == YES )
  864. X#define SC_RETRY( scp )             ( M_IS_CLEAR( (scp)->sc_flags, SF_NORETRY ) )
  865. X#define SC_REUSE_ADDRESS( scp )    M_IS_SET( (scp)->sc_flags, SF_REUSE )
  866. X#define SC_MUST_IDENTIFY( scp )    M_IS_SET( (scp)->sc_flags, SF_IDONLY )
  867. X
  868. X#define SC_IS_RPC( scp )            ( M_IS_SET( (scp)->sc_type, ST_RPC ) )
  869. X#define SC_IS_INTERNAL( scp )        ( M_IS_SET( (scp)->sc_type, ST_INTERNAL ) )
  870. X#define SC_IS_SPECIAL( scp )        ( M_IS_SET( (scp)->sc_type, ST_SPECIAL ) )
  871. X#define SC_IS_UNLISTED( scp )        ( M_IS_SET( (scp)->sc_type, ST_UNLISTED ) )
  872. X#define SC_IS_INTERCEPTED( scp )    ( M_IS_SET( (scp)->sc_flags, SF_INTERCEPT ) )
  873. X
  874. X#define LOGS_USERID( scp, flags )                                                            \
  875. X        ( M_IS_SET( (scp)->flags, LO_USERID ) && SC_ACCEPTS_CONNECTIONS( scp ) )
  876. X
  877. X#define LOGS_ANY( scp, flags )                ( ! M_ARE_ALL_CLEAR( (scp)->flags ) )
  878. X
  879. X#define SC_LOGS_ON_SUCCESS( scp )            LOGS_ANY( scp, sc_log_on_success )
  880. X#define SC_LOGS_ON_FAILURE( scp )            LOGS_ANY( scp, sc_log_on_failure )
  881. X#define SC_LOGS_USERID_ON_FAILURE( scp )    LOGS_USERID( scp, sc_log_on_failure )
  882. X#define SC_LOGS_USERID_ON_SUCCESS( scp )    LOGS_USERID( scp, sc_log_on_success )
  883. X#define SC_LOGS_ON_EXIT( scp )                                                                \
  884. X                ( M_IS_SET( (scp)->sc_log_on_success, LO_DURATION ) ||                \
  885. X                M_IS_SET( (scp)->sc_log_on_success, LO_EXIT ) )
  886. X#define SC_RECORDS( scp )        M_IS_SET( (scp)->sc_log_on_failure, LO_RECORD ) 
  887. X#define SC_LOGS_PID( scp )        M_IS_SET( (scp)->sc_log_on_success, LO_PID )
  888. X#define SC_LOGS_EXITS( scp )    M_IS_SET( (scp)->sc_log_on_success, LO_EXIT )
  889. X#define SC_LOGS_DURATION( scp )        \
  890. X                                        M_IS_SET( (scp)->sc_log_on_success, LO_DURATION )
  891. X
  892. X
  893. X#define SC_MUST_LISTEN( scp )    ( (scp)->sc_socket_type == SOCK_STREAM )
  894. X
  895. X#define SC_ACCEPTS_CONNECTIONS( scp )           \
  896. X      ( (scp)->sc_wait == NO && (scp)->sc_socket_type == SOCK_STREAM )
  897. X
  898. X#define SC_SPECIFIED( scp, attr )   \
  899. X               M_IS_SET( (scp)->sc_specified_attributes, (attr) )
  900. X#define SC_SPECIFY( scp, attr )     \
  901. X               {                                                      \
  902. X                  M_SET( (scp)->sc_specified_attributes, (attr) ) ;  \
  903. X                  SC_PRESENT( (scp), (attr) ) ;                      \
  904. X               }
  905. X#define SC_UNSPECIFY( scp, attr )   \
  906. X               M_CLEAR( (scp)->sc_specified_attributes, (attr) )
  907. X
  908. X#define SC_IS_PRESENT( scp, attr )  \
  909. X               M_IS_SET( (scp)->sc_attributes_present, (attr) )
  910. X#define SC_PRESENT( scp, attr )     \
  911. X               M_SET( (scp)->sc_attributes_present, (attr) )
  912. X#define SC_ABSENT( scp, attr )      \
  913. X               {                                                      \
  914. X                  M_CLEAR( (scp)->sc_attributes_present, (attr) ) ;  \
  915. X                  SC_UNSPECIFY( (scp), (attr) ) ;                       \
  916. X               }
  917. X
  918. X#define sc_getgid( scp )            ( SC_SPECIFIED( scp, A_GROUP )                     \
  919. X                                                    ? (scp)->sc_gid : (scp)->sc_user_gid )
  920. X#define sc_internal( scp, serp )    builtin_invoke( (scp)->sc_builtin, serp )
  921. X#define sc_make_external( scp )    M_CLEAR( (scp)->sc_type, ST_INTERNAL )
  922. X
  923. Xstatus_e                        sc_init() ;
  924. Xstruct service_config     *sc_alloc() ;
  925. Xvoid                             sc_free() ;
  926. Xvoid                             sc_dump() ;
  927. Xstruct service_config    *sc_make_special() ;
  928. Xbool_int                        sc_different_confs() ;
  929. X
  930. X#endif    /* SCONF_H */
  931. X
  932. END_OF_FILE
  933. if test 7383 -ne `wc -c <'xinetd/sconf.h'`; then
  934.     echo shar: \"'xinetd/sconf.h'\" unpacked with wrong size!
  935. fi
  936. # end of 'xinetd/sconf.h'
  937. fi
  938. if test -f 'xinetd/server.c' -a "${1}" != "-c" ; then 
  939.   echo shar: Will not clobber existing file \"'xinetd/server.c'\"
  940. else
  941. echo shar: Extracting \"'xinetd/server.c'\" \(7431 characters\)
  942. sed "s/^X//" >'xinetd/server.c' <<'END_OF_FILE'
  943. X/*
  944. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  945. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  946. X * and conditions for redistribution.
  947. X */
  948. X
  949. Xstatic char RCSid[] = "$Id: server.c,v 6.11 1993/06/15 23:25:57 panos Exp $" ;
  950. X
  951. X#include <sys/types.h>
  952. X#include <sys/socket.h>
  953. X#include <syslog.h>
  954. X#include <fcntl.h>
  955. X#include <time.h>
  956. X
  957. X#include "sio.h"
  958. X
  959. X#include "state.h"
  960. X#include "access.h"
  961. X#include "connection.h"
  962. X#include "config.h"
  963. X#include "server.h"
  964. X
  965. X#define NEW_SERVER()                        NEW( struct server )
  966. X#define FREE_SERVER( serp )            FREE( serp )
  967. X
  968. X
  969. Xchar *inet_ntoa() ;
  970. Xtime_t time() ;
  971. Xchar *malloc() ;
  972. X
  973. Xvoid msg() ;
  974. Xvoid out_of_memory() ;
  975. X
  976. X#ifndef DEBUG_RETRY
  977. X#define do_fork()            fork()
  978. X#else
  979. X#include <errno.h>
  980. Xextern int errno ;
  981. X
  982. X/*
  983. X * 3 out of 4 times the do_fork() will fail
  984. X */
  985. X#define do_fork()            ( random() & 0x11 ) ? ( errno = EAGAIN, -1 ) : fork()
  986. X#endif     /* DEBUG_RETRY */
  987. X
  988. X
  989. X/*
  990. X * Allocate a server, initialize it from init_serp, and insert it in stab
  991. X */
  992. XPRIVATE struct server *server_alloc( init_serp, stab )
  993. X    struct server        *init_serp ;
  994. X    register pset_h    stab ;
  995. X{
  996. X    register struct server    *serp ;
  997. X    char                            *func = "server_alloc" ;
  998. X
  999. X    serp = NEW_SERVER() ;
  1000. X    if ( serp == NULL )
  1001. X    {
  1002. X        out_of_memory( func ) ;
  1003. X        return( NULL ) ;
  1004. X    }
  1005. X
  1006. X    if ( pset_add( stab, serp ) == NULL )
  1007. X    {
  1008. X        msg( LOG_CRIT, func, "couldn't insert server in server table" ) ;
  1009. X        FREE_SERVER( serp ) ;
  1010. X        return( NULL ) ;
  1011. X    }
  1012. X
  1013. X    *serp = *init_serp ;            /* initialize it */
  1014. X    SVC_HOLD( serp->svr_sp ) ;
  1015. X
  1016. X    return( serp ) ;
  1017. X}
  1018. X
  1019. X
  1020. Xvoid server_release( serp )
  1021. X    register struct server *serp ;
  1022. X{
  1023. X    struct service        *sp    = SERVER_SERVICE( serp ) ;
  1024. X    register int        count = SVC_RELE( sp ) ;
  1025. X
  1026. X    if ( count == 0 && ! SC_IS_SPECIAL( SVC_CONF( sp ) ) )
  1027. X        pset_remove( SERVICES( ps ), sp ) ;
  1028. X    
  1029. X    FREE_SERVER( serp ) ;
  1030. X}
  1031. X
  1032. X
  1033. X/*
  1034. X * If a service is internal and does not require forking a process:
  1035. X *        -     if it accepts connections, we put the accepted connection
  1036. X *         in non-blocking mode to avoid a possible block on 
  1037. X *         the write(2).
  1038. X *        -    the log flags that have to do with the server exiting are 
  1039. X *            ignored (i.e. nothing is logged).
  1040. X *        -    it can be identified in the log because the server pid is 0.
  1041. X */
  1042. XPRIVATE void server_internal( serp )
  1043. X    register struct server *serp ;
  1044. X{
  1045. X    register struct service *sp = serp->svr_sp ;
  1046. X    char *func = "server_internal" ;
  1047. X
  1048. X    serp->svr_pid = 0 ;
  1049. X    if ( SVC_ACCEPTS_CONNECTIONS( sp ) &&
  1050. X                fcntl( SERVER_FD( serp ), F_SETFL, FNDELAY ) == -1 )
  1051. X    {
  1052. X        msg( LOG_ERR, func, "%s: fcntl F_SETFL failed: %m", SVC_ID( sp ) ) ;
  1053. X        return ;
  1054. X    }
  1055. X    svc_log_success( sp, serp->svr_conn, serp->svr_pid ) ;
  1056. X    svc_internal( sp, serp ) ;
  1057. X}
  1058. X
  1059. X/*
  1060. X * Attempt to start a server for service 'sp' to handle 
  1061. X * connection 'cp'.
  1062. X * Return value:
  1063. X *        OK:        if a server is started or a retry attempt
  1064. X *                    is scheduled
  1065. X *        FAILED:    otherwise (a log entry is also made)
  1066. X */
  1067. Xstatus_e server_run( sp, cp )
  1068. X    struct service        *sp ;
  1069. X    connection_s        *cp ;
  1070. X{
  1071. X    struct server                server ;
  1072. X    register struct server    *serp ;
  1073. X    char                            *func = "server_run" ;
  1074. X    status_e                        schedule_retry() ;
  1075. X
  1076. X    CLEAR( server ) ;
  1077. X    server.svr_sp = sp ;
  1078. X    server.svr_conn = cp ;
  1079. X
  1080. X    /*
  1081. X     * Allocate a server struct only if we will fork a new process
  1082. X     */
  1083. X    if ( ! SVC_FORKS( sp ) )
  1084. X    {
  1085. X        server_internal( &server ) ;
  1086. X        conn_free( cp ) ;
  1087. X        return( OK ) ;
  1088. X    }
  1089. X
  1090. X    /*
  1091. X     * Insert new struct server in server table first, to avoid the
  1092. X     * possibility of running out of memory *after* the fork.
  1093. X     */
  1094. X    serp = server_alloc( &server, SERVERS( ps ) ) ; 
  1095. X    if ( serp == NULL )
  1096. X        return( FAILED ) ;
  1097. X
  1098. X    if ( server_start( serp ) == OK )
  1099. X    {
  1100. X        conn_close( cp ) ;
  1101. X        return( OK ) ;
  1102. X    }
  1103. X
  1104. X    /*
  1105. X     * Fork failed; remove the server from the server table
  1106. X     */
  1107. X    pset_remove( SERVERS( ps ), serp ) ;
  1108. X
  1109. X    /*
  1110. X     * Currently, fork failures are the only reason for retrying.
  1111. X     * There is no retry if we exceed the max allowed number of fork failures
  1112. X     */
  1113. X    if ( ! SERVER_FORKLIMIT( serp ) && SVC_RETRY( sp ) )
  1114. X    {
  1115. X        if ( schedule_retry( serp ) == OK )
  1116. X            return( OK ) ;
  1117. X        else
  1118. X            msg( LOG_ERR, func, "Retry failure for %s service", SVC_ID( sp ) ) ;
  1119. X    }
  1120. X    else
  1121. X        svc_log_failure( sp, cp, AC_FORK ) ;
  1122. X
  1123. X    server_release( serp ) ;
  1124. X    return( FAILED ) ;
  1125. X}
  1126. X
  1127. X
  1128. X/*
  1129. X * Try to fork a server process
  1130. X */
  1131. Xstatus_e server_start( serp )
  1132. X    register struct server *serp ;
  1133. X{
  1134. X    register struct service        *sp    = serp->svr_sp ;
  1135. X    char                                *func = "server_start" ;
  1136. X    void                                child_process() ;
  1137. X
  1138. X    serp->svr_log_remote_user = SVC_LOGS_USERID_ON_SUCCESS( sp ) ;
  1139. X    
  1140. X    serp->svr_pid = do_fork() ;
  1141. X
  1142. X    switch ( serp->svr_pid )
  1143. X    {
  1144. X        case 0:
  1145. X            ps.rws.env_is_valid = FALSE ;
  1146. X
  1147. X            child_process( serp ) ;
  1148. X
  1149. X            msg( LOG_ERR, func, "INTERNAL ERROR: child_process returned" ) ;
  1150. X            _exit( 0 ) ;
  1151. X            /* NOTREACHED */
  1152. X        
  1153. X        case -1:
  1154. X            msg( LOG_ERR, func, "%s: fork failed: %m", SVC_ID( sp ) ) ;
  1155. X            serp->svr_fork_failures++ ;
  1156. X            return( FAILED ) ;
  1157. X
  1158. X        default:
  1159. X            (void) time( &serp->svr_start_time ) ;
  1160. X            svc_inc_running_servers( sp ) ;
  1161. X
  1162. X            /*
  1163. X             * Log the start of another server (if it is not an interceptor).
  1164. X             * Determine if the server writes to the log (because in that case
  1165. X             * we will have to check the log size).
  1166. X             */
  1167. X            if ( ! SVC_IS_INTERCEPTED( sp ) )
  1168. X                svc_log_success( sp, serp->svr_conn, serp->svr_pid ) ;
  1169. X            else
  1170. X                serp->svr_writes_to_log = SVC_IS_LOGGING( sp ) ;
  1171. X            serp->svr_writes_to_log |= serp->svr_log_remote_user ;
  1172. X            return( OK ) ;
  1173. X    }
  1174. X}
  1175. X
  1176. X
  1177. Xvoid server_dump( serp, fd )
  1178. X   register struct server *serp ;
  1179. X   int fd ;
  1180. X{
  1181. X    struct service *sp = serp->svr_sp ;
  1182. X
  1183. X    Sprint( fd, "%s server\n", SVC_ID( sp ) ) ;
  1184. X   Sprint( fd, "pid = %d\n", serp->svr_pid ) ;
  1185. X   Sprint( fd, "start_time = %s", ctime( &serp->svr_start_time ) ) ;
  1186. X    Sprint( fd, "Connection info:\n" ) ;
  1187. X    conn_dump( serp->svr_conn, fd ) ;
  1188. X    if ( serp->svr_fork_failures )
  1189. X        Sprint( fd, "fork_failures = %d\n", serp->svr_fork_failures ) ;
  1190. X   Sprint( fd,
  1191. X            "log_remote_user = %s\n", serp->svr_log_remote_user ? "YES" : "NO" ) ;
  1192. X   Sprint( fd,
  1193. X            "writes_to_log = %s\n", serp->svr_writes_to_log ? "YES" : "NO" ) ;
  1194. X   Sputchar( fd, '\n' ) ;
  1195. X    Sflush( fd ) ;
  1196. X}
  1197. X
  1198. X
  1199. X/*
  1200. X * Invoked when a server dies, either because of a signal or in case of
  1201. X * a normal exit.
  1202. X */
  1203. Xvoid server_end( serp )
  1204. X    register struct server *serp ;
  1205. X{
  1206. X    register struct service *sp = serp->svr_sp ;
  1207. X    char *func = "server_end" ;
  1208. X
  1209. X    if ( PROC_EXITED( serp->svr_exit_status ) || 
  1210. X                        PROC_SIGNALED( serp->svr_exit_status ) )
  1211. X    {
  1212. X        char *death_type = PROC_EXITED( serp->svr_exit_status ) ? "exited" 
  1213. X                                                                                  : "died" ;
  1214. X        if ( debug.on )
  1215. X        {
  1216. X            struct service *conn_sp = CONN_SERVICE( serp->svr_conn ) ;
  1217. X
  1218. X            if ( conn_sp == sp )
  1219. X                msg( LOG_DEBUG, func,
  1220. X                    "%s server %d %s", SVC_ID( sp ) , serp->svr_pid, death_type ) ;
  1221. X            else
  1222. X                msg( LOG_DEBUG, func,
  1223. X                    "%s server %d running on behalf of service %s %s",
  1224. X                        SVC_ID( sp ), serp->svr_pid, SVC_ID( conn_sp ), death_type ) ;
  1225. X        }
  1226. X        
  1227. X        svc_postmortem( sp, serp ) ;
  1228. X        pset_remove( SERVERS( ps ), serp ) ;
  1229. X        server_release( serp ) ;
  1230. X    }
  1231. X    else if ( PROC_STOPPED( serp->svr_exit_status ) )
  1232. X        msg( LOG_WARNING, func, "service %s: server with pid %d stopped",
  1233. X                                                                SVC_ID( sp ), serp->svr_pid ) ;
  1234. X}
  1235. X
  1236. X
  1237. X/*
  1238. X * Find the running server with the specified pid
  1239. X */
  1240. Xstruct server *server_lookup( pid )
  1241. X   register int pid ;
  1242. X{
  1243. X   register unsigned u ;
  1244. X
  1245. X   for ( u = 0 ; u < pset_count( SERVERS( ps ) ) ; u++ )
  1246. X   {
  1247. X      register struct server *serp ;
  1248. X
  1249. X      serp = SERP( pset_pointer( SERVERS( ps ), u ) ) ;
  1250. X      if ( serp->svr_pid == pid )
  1251. X         return( serp ) ;
  1252. X   }
  1253. X   return( NULL ) ;
  1254. X}
  1255. X
  1256. END_OF_FILE
  1257. if test 7431 -ne `wc -c <'xinetd/server.c'`; then
  1258.     echo shar: \"'xinetd/server.c'\" unpacked with wrong size!
  1259. fi
  1260. # end of 'xinetd/server.c'
  1261. fi
  1262. echo shar: End of archive 16 \(of 31\).
  1263. cp /dev/null ark16isdone
  1264. MISSING=""
  1265. 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
  1266.     if test ! -f ark${I}isdone ; then
  1267.     MISSING="${MISSING} ${I}"
  1268.     fi
  1269. done
  1270. if test "${MISSING}" = "" ; then
  1271.     echo You have unpacked all 31 archives.
  1272.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1273. else
  1274.     echo You still need to unpack the following archives:
  1275.     echo "        " ${MISSING}
  1276. fi
  1277. ##  End of shell archive.
  1278. exit 0
  1279.