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

  1. Newsgroups: comp.sources.unix
  2. From: panos@cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v26i267: xinetd-2.1.1 - inetd replacement with access control and logging, Part23/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 267
  9. Archive-Name: xinetd-2.1.1/part23
  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 23 (of 31)."
  18. # Contents:  libs/src/sio/sio.3 xinetd/confparse.c
  19. # Wrapped by panos@mystique on Mon Jun 21 14:51:27 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'libs/src/sio/sio.3' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'libs/src/sio/sio.3'\"
  23. else
  24. echo shar: Extracting \"'libs/src/sio/sio.3'\" \(12801 characters\)
  25. sed "s/^X//" >'libs/src/sio/sio.3' <<'END_OF_FILE'
  26. X.\"(c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  27. X.\"All rights reserved.  The file named COPYRIGHT specifies the terms 
  28. X.\"and conditions for redistribution.
  29. X.\"
  30. X.\" $Id: sio.3,v 8.1 1993/03/13 01:13:58 panos Exp $
  31. X.TH SIO 3X "29 May 1992"
  32. X.SH NAME
  33. XSread, Sgetc, Srdline, Sfetch, Swrite, Sputc, Sprint, Sprintv, Sdone, Sundo, Stie, Suntie, Sflush, Sclose, Sbuftype, Smorefds, Sgetchar, Sputchar, SIOLINELEN, SIOMAXLINELEN - fast stream I/O
  34. X.SH SYNOPSIS
  35. X.LP
  36. X.nf
  37. X.ft B
  38. X#include "sio.h"
  39. X#include <varargs.h>
  40. X.LP
  41. X.ft B
  42. Xint Sread( fd, buf, nbytes )
  43. Xint fd ;
  44. Xchar *buf ;
  45. Xint nbytes ;
  46. X.LP
  47. X.ft B
  48. Xint Sgetc( fd )
  49. Xint fd ;
  50. X.LP
  51. X.ft B
  52. Xchar *Srdline( fd )
  53. Xint fd ;
  54. X.LP
  55. X.ft B
  56. Xchar *Sfetch( fd, length )
  57. Xint fd ;
  58. Xlong *length ;
  59. X.LP
  60. X.ft B
  61. Xint Swrite( fd, buf, nbytes )
  62. Xint fd ;
  63. Xchar *buf ;
  64. Xint nbytes ;
  65. X.LP
  66. X.ft B
  67. Xint Sputc( fd, c )
  68. Xint fd ;
  69. Xchar c ;
  70. X.LP
  71. X.ft B
  72. Xint Sprint( fd, format [ , ... ] )
  73. Xint fd ;
  74. Xchar *format ;
  75. X.LP
  76. X.ft B
  77. Xint Sprintv( fd, format, ap )
  78. Xint fd ;
  79. Xchar *format ;
  80. Xva_list ap ;
  81. X.LP
  82. X.ft B
  83. Xint Sdone( fd )
  84. Xint fd ;
  85. X.LP
  86. X.ft B
  87. Xint Sundo( fd, type )
  88. Xint fd ;
  89. Xint type ;
  90. X.LP
  91. X.ft B
  92. Xint Stie( ifd, ofd )
  93. Xint ifd, ofd ;
  94. X.LP
  95. X.ft B
  96. Xint Suntie( fd )
  97. Xint fd ;
  98. X.LP
  99. X.ft B
  100. Xint Sbuftype( fd, type )
  101. Xint fd, type ;
  102. X.LP
  103. X.ft B
  104. Xint Smorefds()
  105. X.LP
  106. X.ft B
  107. Xint Sflush( fd )
  108. Xint fd ;
  109. X.LP
  110. X.ft B
  111. Xint Sclose( fd )
  112. Xint fd ;
  113. X.LP
  114. X.ft B
  115. Xint Sgetchar( fd )
  116. Xint fd ;
  117. X.LP
  118. X.ft B
  119. Xint Sputchar( fd, c )
  120. Xint fd;
  121. Xchar c ;
  122. X.LP
  123. X.ft B
  124. Xint SIOLINELEN( fd )
  125. Xint fd ;
  126. X.LP
  127. X.ft B
  128. Xint SIOMAXLINELEN( fd )
  129. Xint fd ;
  130. X.SH DESCRIPTION
  131. XThe \fISIO\fR library provides support
  132. Xfor \fIstream\fR I/O on file descriptors.
  133. XThe first argument of every function
  134. Xor macro is a file descriptor. The file descriptor may be used either for
  135. Xinput or for output but not both. Attempting to use a descriptor for
  136. Xboth input and output will cause the call to fail. When you are
  137. Xdone with using a file descriptor, you should inform \fISIO\fR
  138. Xby invoking \fBSdone()\fR (unless the program is about to 
  139. Xcall \fIexit(3)\fR).
  140. XYou can also use \fBSdone()\fR if
  141. Xyou want to perform a different type of operation on the same
  142. Xfile descriptor (e.g. first you were reading data from the file
  143. Xdescriptor and then you want to write some data).
  144. XAnother possibility is to do stream I/O at different file offsets
  145. Xby using \fBSdone()\fR before doing the \fBlseek(2)\fR to the
  146. Xnew file offset.
  147. X.LP
  148. XI/O operations on different file descriptors do not interfere
  149. X(unless the file descriptors refer to the same file, in which case
  150. Xthe results are undefined).
  151. X.LP
  152. XFor disk files I/O always starts at the current file offset.
  153. XIf that offset is not a multiple of the preferred block size for file
  154. Xsystem I/O (the \fIst_blksize\fR field in \fIstruct stat\fR),
  155. Xperformance will not be optimal.
  156. XFor optimal performance, it is recommended that no I/O operations
  157. X(like \fIread(2)\fR or \fIwrite(2)\fR)
  158. Xare applied to the file descriptor if it is to be used by \fISIO\fR.
  159. X.LP
  160. XRead I/O is either buffered or is done using memory mapping whenever
  161. Xthat is possible and appropriate.
  162. X.LP
  163. XThe library functions that do stream I/O resemble system calls
  164. X(for example \fBSread()\fR resembles \fIread(2)\fR) so that modifying
  165. Xa program that uses the system calls to use the \fISIO\fR functions
  166. Xis easy (e.g. just replace \fIread(2)\fR with \fBSread()\fR; the function
  167. Xsignatures as well as the return values are exactly the same).
  168. X.LP
  169. X.B Sread()
  170. Xreads \fInbytes\fR bytes from the stream associated with file 
  171. Xdescriptor \fIfd\fR into the buffer pointed to by \fIbuf\fR.
  172. X.LP
  173. X.B Sgetc()
  174. Xreads a character from the stream
  175. Xassociated with file descriptor \fIfd\fR.
  176. XIt returns \fBSIO_EOF\fR if the end of file has been reached.
  177. X.LP
  178. X.B Sgetchar()
  179. X(a macro) performs exactly the same function as \fBSgetc()\fR but
  180. Xit is much faster.
  181. X.LP
  182. X.B Srdline()
  183. Xreads a line from the stream
  184. Xassociated with file descriptor \fIfd\fR.
  185. XThe newline at the end of the line is replaced by a 0 byte. Lines
  186. Xlonger than the maximum line length supported by \fISIO\fR will
  187. Xhave characters deleted.
  188. X.LP
  189. X.B SIOLINELEN()
  190. X(a macro) returns the length of
  191. Xthe line returned by the last call to \fBSrdline()\fR
  192. X(the value returned by \fBSIOLINELEN()\fR is valid only after
  193. X\fBSrdline()\fR and as long as no other 
  194. X\fISIO\fR calls are performed on that file descriptor).
  195. X.LP
  196. X.B SIOMAXLINELEN()
  197. X(a macro) returns
  198. Xthe maximul line length supported by \fISIO\fR for the file
  199. Xdescriptor. As a side-effect it initializes \fIfd\fR for input.
  200. X.LP
  201. X.B Sfetch()
  202. Xreturns a pointer to data coming from the stream
  203. Xassociated with file
  204. Xdescriptor \fIfd\fR. The amount of data available is indicated
  205. Xby the \fIlength\fR argument. One possible use for this function
  206. Xis copying of files.
  207. X.LP
  208. X.B Swrite()
  209. Xwrites \fInbytes\fR bytes to the stream associated with file
  210. Xdescriptor \fIfd\fR from the buffer pointed to by \fIbuf\fR.
  211. X.LP
  212. X.B Sputc()
  213. Xwrites a single character to the stream
  214. Xassociated with file descriptor \fIfd\fR.
  215. X.LP
  216. X.B Sputchar()
  217. X(a macro) performs exactly the same function as \fBSputc()\fR
  218. Xbut it is much faster.
  219. X.LP
  220. X.B Sprint()
  221. Ximitates the behavior of printf(3) as defined in the
  222. XANSI C Standard. There are some limitations. Check the \fBSprint()\fR
  223. Xman page for more information.
  224. X.LP
  225. X.B Sprintv()
  226. Xis the same as \fBSprint()\fR except that it takes a
  227. X\fIvarargs\fR argument list.
  228. X.LP
  229. X.B Sundo()
  230. Xreturns the characters returned by the last call to
  231. X\fBSrdline()\fR, \fBSgetc()\fR or \fBSgetchar()\fR to the stream
  232. Xso that they can be reread. The \fItype\fR argument to \fBSundo()\fR
  233. Xcan be \fBSIO_UNDO_LINE\fR or \fBSIO_UNDO_CHAR\fR depending
  234. Xon whether the call whose effect needs to be undone was
  235. X\fBSrdline()\fR or \fBSgetc()\fR/\fBSgetchar()\fR respectively.
  236. XThere is no check on
  237. Xwhether the last function invoked on \fIfd\fR was one of the above
  238. Xand the results are undefined if there is no correspondence
  239. Xbetween the \fItype\fR and the last operation on \fIfd\fR.
  240. X(i.e. the result is undefined if you try \fBSIO_UNDO_CHAR\fR 
  241. Xand the last operation was not \fBSgetchar()\fR or \fBSgetc()\fR).
  242. X.LP
  243. X.B Stie()
  244. Xties the file descriptor \fIifd\fR to the file descriptor \fIofd\fR.
  245. XThis means that whenever a \fIread(2)\fR is done on \fIifd\fR, it is
  246. Xpreceded by a \fIwrite(2)\fR on \fIofd\fR.
  247. XFor filters it is useful to do \fIStie( 0, 1 )\fR to maximize concurrency.
  248. XIt is also useful to do the same thing when you issue prompts to the
  249. Xuser and you want the user reply to appear on the same line with the
  250. Xprompt.
  251. X\fIifd\fR, \fIofd\fR  will be initialized for input, output respectively
  252. X(if any of them is initialized, it must be for the appropriate
  253. Xstream type (input or output)).
  254. XIf \fIifd\fR was tied to another file descriptor, the old tie is broken.
  255. X.LP
  256. X.B Suntie()
  257. Xundoes the effect of \fBStie()\fR for the specified input file descriptor.
  258. X.LP
  259. X.B Sbuftype()
  260. Xdetermines the buffering type for the output stream associated with
  261. Xfile descriptor \fIfd\fR.
  262. XBy default output directed to terminals is line buffered, output
  263. Xdirected to file descriptor 2 (standard error) is unbuffered and
  264. Xeverything else is fully buffered.
  265. XPossible values for the \fItype\fR argument are
  266. X.RS
  267. X.TP 15
  268. X.SB SIO_FULLBUF
  269. Xfor full buffering
  270. X.TP
  271. X.SB SIO_LINEBUF
  272. Xfor line buffering
  273. X.TP
  274. X.SB SIO_NOBUF
  275. Xfor no buffering
  276. X.RE
  277. X.LP
  278. X.B Smorefds()
  279. Xshould be used to inform \fBSIO\fR that the number of available file
  280. Xdescriptors has been increased. \fBSIO\fR uses an array of internal
  281. Xstream descriptors which are indexed by the file descriptor number. Some
  282. Xoperating systems (ex. SunOS 4.1[.x]) allow the number of available
  283. Xfile descriptors to vary. If that number is increased beyond its initial
  284. Xvalue \fBSIO\fR needs to know in order to allocate more stream descriptors.
  285. X.LP
  286. X.B Sdone()
  287. Xflushes any buffered output for \fIfd\fR 
  288. Xand releases the \fISIO\fR resources used. \fBSdone()\fR 
  289. Xis useful in case the program needs to reprocess the
  290. Xdata of a file descriptor (assuming the file descriptor corresponds
  291. Xto a file).  The program can call \fBSdone()\fR,
  292. X\fIlseek(2)\fR to the beginning of the file
  293. Xand then proceed to reread the file.
  294. X.LP
  295. X.B Sflush()
  296. Xcauses any buffered stream output to be written to the
  297. Xfile descriptor. If its argument is the special value \fBSIO_FLUSH_ALL\fR
  298. Xthen all output streams will be flushed.
  299. X.LP
  300. X.B Sclose()
  301. Xcloses a file descriptor used for stream I/O, flushes
  302. Xany buffered output and releases the \fISIO\fR resources used.
  303. X.SH EXAMPLES
  304. X.LP
  305. XThe following code implements a (poor) substitute for the tee command
  306. X(it copies standard input to a file as well as to standard output).
  307. X.ne 10
  308. X.RS
  309. X.nf
  310. X.ft B
  311. X#include "sio.h"
  312. X.sp .5
  313. Xmain( argc, argv )
  314. X    int argc ;
  315. X    char *argv[] ;
  316. X{
  317. X    char *file = (argc > 1) ? argv[ 1 ] : "tee.file" ;
  318. X    int fd = creat( file, 0644 ) ;
  319. X    long length ;
  320. X    char *s ;
  321. X.sp .5
  322. X    while ( s = Sfetch( 0, &length ) )
  323. X    {
  324. X        Swrite( 1, s, length ) ;
  325. X        Swrite( fd, s, length ) ;
  326. X    }
  327. X    exit( 0 ) ;
  328. X}
  329. X.fi
  330. X.ft R
  331. X.RE
  332. X.SH RETURN VALUES
  333. X.LP
  334. X.B Sread()
  335. Xreturns the number of bytes read on success
  336. X(0 means end-of-file)
  337. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  338. X.LP
  339. X.B Sgetc()
  340. Xreturns the character read on success,
  341. XSIO_EOF when the end-of-file is reached,
  342. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  343. X.LP
  344. X.B Srdline()
  345. Xreturns a pointer to the next line on success.
  346. XOn failure or when the end-of-file is reached it returns
  347. X.SM NULL.
  348. XIf the end-of-file is reached \fIerrno\fR is set to 0, otherwise it indicates
  349. Xthe error.
  350. X.LP
  351. X.B Sfetch()
  352. Xreturns a pointer to file data on success.
  353. X(the \fIlength\fR argument indicates how many bytes
  354. Xare available).
  355. XOn failure or when the end-of-file is reached it returns
  356. X.SM NULL.
  357. XIf the end-of-file is reached \fIerrno\fR is set to 0, otherwise it indicates
  358. Xthe error.
  359. X.LP
  360. X.B Swrite()
  361. Xreturns the number of bytes written on success
  362. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  363. X.LP
  364. X.B Sputc()
  365. Xreturns the character it was given as an argument on success
  366. X.B Sprint()
  367. Xreturns the number of characters printed on success
  368. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  369. X.LP
  370. X.B Sdone()
  371. Xreturns \fB0\fR on success
  372. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  373. X.LP
  374. X.B Sundo()
  375. Xreturns \fB0\fR on success
  376. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  377. X.LP
  378. X.B Stie()
  379. Xreturns \fB0\fR on success
  380. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  381. X.LP
  382. X.B Suntie()
  383. Xreturns \fB0\fR on success
  384. Xor \fBSIO_ERR\fR on failure
  385. X(\fIerrno\fR is set to \fBEBADF\fR if there
  386. Xwas no tied file descriptor).
  387. X.LP
  388. X.B Sbuftype()
  389. Xreturns \fB0\fR on success
  390. Xor \fBSIO_ERR\fR on failure
  391. X(\fIerrno\fR is set to \fBEBADF\fR if this is not an output stream
  392. Xor to \fBEINVAL\fR if an unknown \fItype\fR is specified).
  393. X.LP
  394. X.B Smorefds()
  395. Xreturns \fB0\fR on success
  396. Xor \fBSIO_ERR\fR on failure (because of lack of memory).
  397. X.LP
  398. X.B Sflush()
  399. Xreturns \fB0\fR on success
  400. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  401. X.LP
  402. X.B Sclose()
  403. Xreturns \fB0\fR on success
  404. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  405. X.LP
  406. X.B Sgetchar()
  407. Xreturns the character read on success,
  408. XSIO_EOF when the end-of-file is reached,
  409. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  410. X.LP
  411. X.B Sputchar()
  412. Xreturns the character it was given as an argument on success
  413. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  414. X.LP
  415. X.B SIOLINELEN()
  416. Xreturns the length of the last line read by \fBSrdline()\fR.
  417. X.LP
  418. X.B SIOMAXLINELEN()
  419. Xreturns the length of the longest line supported by \fISIO\fR on success
  420. Xor \fBSIO_ERR\fR on failure (\fIerrno\fR is set to indicate the error).
  421. X.LP
  422. XAttempting a read operation on a descriptor opened for writing or vice
  423. Xversa will cause the operation to fail with \fIerrno\fR set to \fBEBADF\fR.
  424. X.LP
  425. XThe first \fISIO\fR operation on a descriptor must be a read or write
  426. Xoperation. It cannot be a control operation (like \fBSflush()\fR). Such
  427. Xan operation will fail with \fIerrno\fR set to \fBEBADF\fR.
  428. X.LP
  429. X.IP "\fBNOTE 1:\fR" 15
  430. X\fBStie()\fR is an input/output operation for the
  431. Xrespective file descriptors, not a control operation. \fBSuntie()\fR
  432. Xis a control operation.
  433. X.IP "\fBNOTE 2:\fR"
  434. X\fBSIO_ERR\fR is defined to be \fB-1\fR.
  435. X.SH "SEE ALSO"
  436. X.LP
  437. XSprint(3)
  438. X.SH BUGS
  439. X.LP
  440. XIf the operating system does not provide for invocation of a
  441. Xfinalization function upon exit, the program will have to
  442. Xexplicitly flush all output streams.
  443. XThe following operating systems provide such a facility:
  444. XSunOS 4.x, Ultrix 4.x.
  445. X.LP
  446. XSocket file descriptors can be used for input as well as output but
  447. X\fBSIO\fR does not support this.
  448. X.LP
  449. XThe current implementation will not try to use memory mapping to
  450. Xread a file if the file offset is not 0 (it will use buffered I/O instead).
  451. X.LP
  452. XPointers returned by \fBSfetch()\fR point to read-only memory.
  453. XAttempting to modify this memory will result in a segmentation
  454. Xviolation.
  455. END_OF_FILE
  456. if test 12801 -ne `wc -c <'libs/src/sio/sio.3'`; then
  457.     echo shar: \"'libs/src/sio/sio.3'\" unpacked with wrong size!
  458. fi
  459. # end of 'libs/src/sio/sio.3'
  460. fi
  461. if test -f 'xinetd/confparse.c' -a "${1}" != "-c" ; then 
  462.   echo shar: Will not clobber existing file \"'xinetd/confparse.c'\"
  463. else
  464. echo shar: Extracting \"'xinetd/confparse.c'\" \(13219 characters\)
  465. sed "s/^X//" >'xinetd/confparse.c' <<'END_OF_FILE'
  466. X/*
  467. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  468. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  469. X * and conditions for redistribution.
  470. X */
  471. X
  472. X#include <sys/types.h>
  473. X#include <syslog.h>
  474. X#include <netdb.h>
  475. X#include <string.h>
  476. X#include <netinet/in.h>
  477. X
  478. Xchar *malloc() ;
  479. Xvoid endservent() ;
  480. Xvoid endprotoent() ;
  481. Xvoid endrpcent() ;
  482. X
  483. X#include "pset.h"
  484. X#include "misc.h"
  485. X
  486. X#include "attr.h"
  487. X#include "config.h"
  488. X#include "conf.h"
  489. X#include "defs.h"
  490. X#include "parse.h"
  491. X#include "sconst.h"
  492. X#include "sconf.h"
  493. X#include "state.h"
  494. X
  495. Xvoid out_of_memory() ;
  496. Xvoid msg() ;
  497. X
  498. X/*
  499. X * Pset iterator used by functions in this file.
  500. X * It lives only when get_configuration is called (i.e. it is created and
  501. X * destroyed each time). This is because the pset it is iterating on
  502. X * changes.
  503. X */
  504. Xstatic psi_h iter ;
  505. X
  506. X
  507. XPRIVATE status_e fix_server_argv( scp )
  508. X    struct service_config *scp ;
  509. X{
  510. X    char *server_name ;
  511. X    char *func = "fix_server_argv" ;
  512. X
  513. X    /*
  514. X     * Check if the user specified any server arguments.
  515. X     * If not, then the server_argv has not been allocated yet,
  516. X     * so malloc it (size 2)
  517. X     * Put in argv[ 0 ] the last component of the server pathname
  518. X     */
  519. X    if ( ! SC_SPECIFIED( scp, A_SERVER_ARGS ) )
  520. X    {
  521. X        scp->sc_server_argv = (char **) malloc( 2 * sizeof( char * ) ) ;
  522. X        if ( scp->sc_server_argv == NULL )
  523. X        {
  524. X            out_of_memory( func ) ;
  525. X            return( FAILED ) ;
  526. X        }
  527. X        scp->sc_server_argv[ 1 ] = NULL ;
  528. X        SC_PRESENT( scp, A_SERVER_ARGS ) ;
  529. X    }
  530. X
  531. X    /*
  532. X     * Determine server name
  533. X     */
  534. X    server_name = strrchr( scp->sc_server, '/' ) ;
  535. X    if ( server_name == NULL )
  536. X        server_name = scp->sc_server ;
  537. X    else
  538. X        server_name++ ;      /* skip the '/' */
  539. X
  540. X    /*
  541. X     * Place it in argv[ 0 ]
  542. X     */
  543. X    scp->sc_server_argv[ 0 ] = make_string( 1, server_name ) ;
  544. X    if ( scp->sc_server_argv[ 0 ] == NULL )
  545. X    {
  546. X        out_of_memory( func ) ;
  547. X        return( FAILED ) ;
  548. X    }
  549. X    return( OK ) ;
  550. X}
  551. X
  552. X
  553. X
  554. X#define USE_DEFAULT( scp, def, attr_id )    \
  555. X            ( ! SC_SPECIFIED( scp, attr_id ) && SC_SPECIFIED( def, attr_id ) )
  556. X
  557. X/*
  558. X * Fill the service configuration with attributes that were not
  559. X * explicitly specified. These can be:
  560. X *        1) implied attributes (like the server name in argv[0])
  561. X *        2) attributes from 'defaults' so that we won't need to check
  562. X *            'defaults' anymore.
  563. X *        3) default values (like the service instance limit)
  564. X */
  565. XPRIVATE status_e attr_fill( scp, def )
  566. X    struct service_config *scp ;
  567. X    struct service_config *def ;
  568. X{
  569. X    char *func = "attr_fill" ;
  570. X    status_e setup_environ() ;
  571. X
  572. X    if ( ! SC_IS_INTERNAL( scp ) && fix_server_argv( scp ) == FAILED )
  573. X        return( FAILED ) ;
  574. X
  575. X    if ( ! SC_SPECIFIED( scp, A_INSTANCES ) )
  576. X    {
  577. X        scp->sc_instances = SC_SPECIFIED( def, A_INSTANCES ) ? def->sc_instances
  578. X                                                                      : DEFAULT_INSTANCE_LIMIT ;
  579. X        SC_PRESENT( scp, A_INSTANCES ) ;
  580. X    }
  581. X
  582. X    if ( USE_DEFAULT( scp, def, A_LOG_ON_SUCCESS ) )
  583. X    {
  584. X        scp->sc_log_on_success = def->sc_log_on_success ;
  585. X        SC_PRESENT( scp, A_LOG_ON_SUCCESS ) ;
  586. X    }
  587. X
  588. X    if ( USE_DEFAULT( scp, def, A_LOG_ON_FAILURE ) )
  589. X    {
  590. X        scp->sc_log_on_failure = def->sc_log_on_failure ;
  591. X        SC_PRESENT( scp, A_LOG_ON_FAILURE ) ;
  592. X    }
  593. X
  594. X    if ( USE_DEFAULT( scp, def, A_LOG_TYPE ) )
  595. X    {
  596. X        struct log *dlp = SC_LOG( def ) ;
  597. X        struct log *slp = SC_LOG( scp ) ;
  598. X
  599. X        switch ( log_get_type( dlp ) )
  600. X        {
  601. X            case L_NONE:
  602. X                log_set_type( slp, L_NONE ) ;
  603. X                break ;
  604. X            
  605. X            case L_SYSLOG:
  606. X                *slp = *dlp ;
  607. X                break ;
  608. X            
  609. X            case L_FILE:
  610. X                log_set_type( slp, L_COMMON_FILE ) ;
  611. X                break ;
  612. X
  613. X            default:
  614. X                msg( LOG_ERR, func,
  615. X                                "bad log type: %d", (int) log_get_type( dlp ) ) ;
  616. X                return( FAILED ) ;
  617. X        }
  618. X        SC_PRESENT( scp, A_LOG_TYPE ) ;
  619. X    }
  620. X    if ( setup_environ( scp, def ) == FAILED )
  621. X        return( FAILED ) ;
  622. X    return( OK ) ;
  623. X}
  624. X
  625. X
  626. XPRIVATE void remove_disabled_services( confp )
  627. X    struct configuration *confp ;
  628. X{
  629. X    pset_h disabled_services ;
  630. X    register struct service_config *scp ;
  631. X    struct service_config *defaults = confp->cnf_defaults ;
  632. X
  633. X    if ( ! SC_SPECIFIED( defaults, A_DISABLED ) )
  634. X        return ;
  635. X    
  636. X    disabled_services = defaults->sc_disabled ;
  637. X
  638. X    for ( scp = SCP( psi_start( iter ) ) ; scp ; scp = SCP( psi_next( iter ) ) )
  639. X    {
  640. X        register char *sid = SC_ID( scp ) ;
  641. X        register unsigned u ;
  642. X
  643. X        for ( u = 0 ; u < pset_count( disabled_services ) ; u++ )
  644. X            if ( EQ( sid, (char *) pset_pointer( disabled_services, u ) ) )
  645. X            {
  646. X                sc_free( scp ) ;
  647. X                psi_remove( iter ) ;
  648. X                break ;
  649. X            }
  650. X    }
  651. X}
  652. X
  653. X
  654. X/*
  655. X * Check if all required attributes have been specified
  656. X */
  657. XPRIVATE status_e attr_check( scp )
  658. X    register struct service_config *scp ;
  659. X{
  660. X    mask_t            necessary_and_specified ;
  661. X    mask_t            necessary_and_missing ;
  662. X    mask_t            must_specify = NECESSARY_ATTRS ;
  663. X    register int    attr_id ;
  664. X    char                *attr_name ;
  665. X    char                *func = "attr_check" ;
  666. X    char                *attr_name_lookup() ;
  667. X
  668. X    /*
  669. X     * Determine what attributes must be specified
  670. X     */
  671. X    if ( ! SC_IS_INTERNAL( scp ) )
  672. X        M_OR( must_specify, must_specify, NECESSARY_ATTRS_EXTERNAL ) ;
  673. X
  674. X    if ( SC_IS_UNLISTED( scp ) )
  675. X        M_OR( must_specify, must_specify, NECESSARY_ATTRS_UNLISTED ) ;
  676. X    else
  677. X        M_OR( must_specify, must_specify, NECESSARY_ATTRS_LISTED ) ;
  678. X
  679. X    if ( SC_IS_RPC( scp ) )
  680. X        if ( SC_IS_UNLISTED( scp ) )
  681. X            M_OR( must_specify, must_specify, NECESSARY_ATTRS_RPC_UNLISTED ) ;
  682. X        else
  683. X            M_OR( must_specify, must_specify, NECESSARY_ATTRS_RPC_LISTED ) ;
  684. X
  685. X    /*
  686. X     * Check if all necessary attributes have been specified
  687. X     *
  688. X     * NOTE: None of the necessary attributes can belong to "defaults"
  689. X     *            This is why we use the sc_attributes_specified mask.
  690. X     */
  691. X    M_AND( necessary_and_specified,
  692. X                        scp->sc_specified_attributes, must_specify ) ;
  693. X    M_XOR( necessary_and_missing, necessary_and_specified, must_specify ) ;
  694. X
  695. X    if ( M_ARE_ALL_CLEAR( necessary_and_missing ) )
  696. X        return( OK ) ;
  697. X    
  698. X    /*
  699. X     * Print names of missing attributes
  700. X     */
  701. X    for ( attr_id = 0 ; attr_id < SERVICE_ATTRIBUTES ; attr_id++ )
  702. X        if ( M_IS_SET( necessary_and_missing, attr_id ) && 
  703. X                        ( attr_name = attr_name_lookup( attr_id ) ) != NULL )
  704. X            msg( LOG_ERR, func,
  705. X                "Service %s missing attribute %s", scp->sc_id, attr_name ) ;
  706. X    return( FAILED ) ;
  707. X}
  708. X
  709. X
  710. X/*
  711. X * Perform validity checks on the specified entry
  712. X *
  713. X * Also does the following:
  714. X *        1. If this is an internal service, it finds the function that
  715. X *            implements it
  716. X *        2. For RPC services, it finds the program number
  717. X *        3. For non-RPC services, it finds the port number.
  718. X */
  719. XPRIVATE status_e check_entry( scp )
  720. X    register struct service_config *scp ;
  721. X{
  722. X    char *func = "check_entry" ;
  723. X
  724. X    if ( attr_check( scp ) == FAILED )
  725. X        return( FAILED ) ;
  726. X
  727. X    /*
  728. X     * Currently, we cannot intercept:
  729. X     *        1) internal services
  730. X     *        2) multi-threaded services
  731. X     * We clear the INTERCEPT flag without disabling the service.
  732. X     */
  733. X    if ( SC_IS_INTERCEPTED( scp ) )
  734. X    {
  735. X        if ( SC_IS_INTERNAL( scp ) )
  736. X        {
  737. X            msg( LOG_ERR, func,
  738. X                "Internal services cannot be intercepted: %s ", scp->sc_id ) ;
  739. X            M_CLEAR( scp->sc_flags, SF_INTERCEPT ) ;
  740. X        }
  741. X        if ( scp->sc_wait == NO )
  742. X        {
  743. X            msg( LOG_ERR, func,
  744. X                "Multi-threaded services cannot be intercepted: %s", scp->sc_id ) ;
  745. X            M_CLEAR( scp->sc_flags, SF_INTERCEPT ) ;
  746. X        }
  747. X    }
  748. X
  749. X    if ( SC_IS_INTERNAL( scp ) &&
  750. X        ( scp->sc_builtin = 
  751. X                builtin_find( scp->sc_name, scp->sc_socket_type ) ) == NULL )
  752. X            return( FAILED ) ;
  753. X
  754. X    /*
  755. X     * If this is an unlisted service we are done.
  756. X     * attr_check() guaranteed that we have all the information we need
  757. X     * to start the service.
  758. X     */
  759. X    if ( SC_IS_UNLISTED( scp ) )
  760. X        return( OK ) ;
  761. X
  762. X#ifndef NO_RPC
  763. X    if ( SC_IS_RPC( scp ) )
  764. X    {
  765. X        struct rpcent *rep = getrpcbyname( scp->sc_name ) ;
  766. X
  767. X        if ( rep == NULL )
  768. X        {
  769. X            msg( LOG_ERR, func, "unknown RPC service: %s", scp->sc_name ) ;
  770. X            return( FAILED ) ;
  771. X        }
  772. X        SC_RPCDATA( scp )->rd_program_number = rep->r_number ;
  773. X    }
  774. X    else
  775. X#endif    /* ! NO_RPC */
  776. X    {
  777. X        struct servent *sep ;
  778. X        unsigned short service_port ;
  779. X
  780. X        /*
  781. X         * Check if a protocol was specified.
  782. X         * If so, verify it is a proper protocol for the given service.
  783. X         * If no protocol was specified, find the protocol for the service
  784. X         * and its number.
  785. X         */
  786. X        if ( SC_SPECIFIED( scp, A_PROTOCOL ) )
  787. X        {
  788. X            sep = getservbyname( scp->sc_name, scp->sc_protocol.name ) ;
  789. X            if ( sep == NULL )
  790. X            {
  791. X                msg( LOG_ERR, func, 
  792. X                    "service/protocol combination not in /etc/services: %s/%s",
  793. X                        scp->sc_name, scp->sc_protocol.name ) ;
  794. X                return( FAILED ) ;
  795. X            }
  796. X        }
  797. X        else
  798. X        {
  799. X            struct protoent *pep ;
  800. X
  801. X            sep = getservbyname( scp->sc_name, CHAR_NULL ) ;
  802. X            if ( sep == NULL )
  803. X            {
  804. X                msg( LOG_ERR, func, "Unknown service: %s", scp->sc_name ) ;
  805. X                return( FAILED ) ;
  806. X            }
  807. X            scp->sc_protocol.name = make_string( 1, sep->s_proto ) ;
  808. X            if ( scp->sc_protocol.name == NULL )
  809. X            {
  810. X                out_of_memory( func ) ;
  811. X                return( FAILED ) ;
  812. X            }
  813. X            pep = getprotobyname( sep->s_proto ) ;
  814. X            if ( pep == NULL )
  815. X            {
  816. X                msg( LOG_ERR, func,
  817. X                    "Protocol '%s' for service '%s' is not in /etc/protocols",
  818. X                        sep->s_proto, scp->sc_name ) ;
  819. X                return( FAILED ) ;
  820. X            }
  821. X            scp->sc_protocol.value = pep->p_proto ;
  822. X        }
  823. X
  824. X        service_port = sep->s_port ;        /* s_port is in network-byte-order */
  825. X
  826. X        /*
  827. X         * If a port was specified, it must be the right one
  828. X         */
  829. X        if ( SC_SPECIFIED( scp, A_PORT ) && 
  830. X                                            scp->sc_port != ntohs( service_port ) )
  831. X        {
  832. X            msg( LOG_ERR, func, "Service %s expects port %d, not %d",
  833. X                                scp->sc_name, ntohs( service_port ), scp->sc_port ) ;
  834. X            return( FAILED ) ;
  835. X        }
  836. X        scp->sc_port = ntohs( service_port ) ;
  837. X    }
  838. X    return( OK ) ;
  839. X}
  840. X
  841. X
  842. Xvoid parse_conf_file() ;
  843. Xvoid parse_end() ;
  844. X
  845. X#if CONF_TIMEOUT != 0 && ! defined( NO_TIMERS )
  846. X
  847. X#include <sys/time.h>
  848. X#include "timer.h"
  849. X#include "timemacros.h"
  850. X
  851. Xstatic timer_h conf_timer ;
  852. X
  853. Xstatus_e create_conf_timer()
  854. X{
  855. X    conf_timer = timer_create( TIMER_REAL, TIMER_RETURN_ERROR, INT_NULL ) ;
  856. X    return( ( conf_timer == NULL ) ? FAILED : OK ) ;
  857. X}
  858. X
  859. X#endif    /* CONF_TIMEOUT != 0 && ! NO_TIMERS */
  860. X
  861. X
  862. X/*
  863. X * Get a configuration from the specified file.
  864. X * In case of timeout, do cleanup
  865. X */
  866. XPRIVATE status_e get_conf( fd, confp, timeout )
  867. X    int fd ;
  868. X    struct configuration *confp ;
  869. X    long timeout ;
  870. X{
  871. X#if CONF_TIMEOUT != 0 && ! defined( NO_TIMERS )
  872. X
  873. X    struct itimerval itv ;
  874. X    struct timer_action ta ;
  875. X    char *func = "get_conf" ;
  876. X    
  877. X    if ( timeout )
  878. X    {
  879. X        if ( setjmp( ta.ta_env ) )
  880. X        {
  881. X            parse_end() ;
  882. X            return( FAILED ) ;
  883. X        }
  884. X
  885. X        /*
  886. X         * Start the timer
  887. X         */
  888. X        TV_ZERO( itv.it_interval ) ;
  889. X        itv.it_value.tv_sec    = timeout ;
  890. X        itv.it_value.tv_usec    = 0 ;
  891. X        ta.ta_flags                = TIMER_LONGJMP ;
  892. X        ta.ta_func                = NULL ;
  893. X        ta.ta_arg                = VOID_NULL ;
  894. X        if ( timer_start( conf_timer, &itv, TIMER_RELATIVE, &ta ) == TIMER_ERR )
  895. X        {
  896. X            msg( LOG_ERR, func, "timer creation failed" ) ;
  897. X            return( FAILED ) ;
  898. X        }
  899. X    }
  900. X
  901. X    parse_conf_file( fd, confp ) ;
  902. X
  903. X    if ( timeout )
  904. X        timer_stop( conf_timer ) ;
  905. X    parse_end() ;
  906. X    return( OK ) ;
  907. X
  908. X#else        /* CONF_TIMEOUT == 0 || NO_TIMERS */
  909. X
  910. X#ifdef lint
  911. X    timeout = timeout ;
  912. X#endif
  913. X    parse_conf_file( fd, confp ) ;
  914. X    parse_end() ;
  915. X    return( OK ) ;
  916. X#endif    /* CONF_TIMEOUT != 0 && ! NO_TIMERS */
  917. X
  918. X}
  919. X
  920. X
  921. X
  922. X#define CHECK_AND_CLEAR( scp, mask, mask_name )                                            \
  923. X    if ( M_IS_SET( mask, LO_USERID ) )                                                        \
  924. X    {                                                                                                    \
  925. X        msg( LOG_WARNING, func,                                                                    \
  926. X        "%s service: clearing USERID option from %s", scp->sc_id, mask_name ) ;    \
  927. X        M_CLEAR( mask, LO_USERID ) ;                                                            \
  928. X    }
  929. X
  930. X
  931. X
  932. X/*
  933. X * Get a configuration by reading the configuration file.
  934. X */
  935. Xstatus_e cnf_get( confp, timeout )
  936. X    struct configuration *confp ;
  937. X    long timeout ;
  938. X{
  939. X    int config_fd ;
  940. X    struct service_config *scp ;
  941. X    builtin_s *spec_find() ;
  942. X    char *func = "get_configuration" ;
  943. X
  944. X    if ( cnf_init( confp, &config_fd, &iter ) == FAILED )
  945. X        return( FAILED ) ;
  946. X
  947. X    if ( get_conf( config_fd, confp, timeout ) == FAILED )
  948. X    {
  949. X        Sclose( config_fd ) ;
  950. X        cnf_free( confp ) ;
  951. X        psi_destroy( iter ) ;
  952. X        return( FAILED ) ;
  953. X    }
  954. X
  955. X    Sclose( config_fd ) ;
  956. X
  957. X    remove_disabled_services( confp ) ;
  958. X
  959. X    for ( scp = SCP( psi_start( iter ) ) ; scp ; scp = SCP( psi_next( iter ) ) )
  960. X    {
  961. X        if ( check_entry( scp ) == FAILED )
  962. X        {
  963. X            sc_free( scp ) ;
  964. X            psi_remove( iter ) ;
  965. X            continue ;
  966. X        }
  967. X
  968. X        /*
  969. X         * Fill the service configuration from the defaults.
  970. X         * We do this so that we don't have to look at the defaults any more.
  971. X         */
  972. X        if ( attr_fill( scp, confp->cnf_defaults ) == FAILED )
  973. X        {
  974. X            sc_free( scp ) ;
  975. X            psi_remove( iter ) ;
  976. X            continue ;
  977. X        }
  978. X
  979. X        /*
  980. X         * If the INTERCEPT flag is set, change this service to an internal 
  981. X         * service using the special INTERCEPT builtin.
  982. X         */
  983. X        if ( SC_IS_INTERCEPTED( scp ) )
  984. X        {
  985. X            builtin_s *bp ;
  986. X
  987. X            bp = spec_find( INTERCEPT_SERVICE_NAME, scp->sc_socket_type ) ;
  988. X            if ( bp == NULL )
  989. X            {
  990. X                msg( LOG_ERR, func, "removing service %s", SC_ID( scp ) ) ;
  991. X                sc_free( scp ) ;
  992. X                psi_remove( iter ) ;
  993. X                continue ;
  994. X            }
  995. X
  996. X            scp->sc_builtin = bp ;
  997. X            M_SET( scp->sc_type, ST_INTERNAL ) ;
  998. X        }
  999. X
  1000. X        /*
  1001. X         * Clear the USERID flag for the identity service because
  1002. X         * it may lead to loops (for example, remote xinetd issues request,
  1003. X         * local xinetd issues request to remote xinetd etc.)
  1004. X         * We identify the identity service by its (protocol,port) combination.
  1005. X         */
  1006. X        if ( scp->sc_port == IDENTITY_SERVICE_PORT && 
  1007. X                                                    scp->sc_protocol.value == IPPROTO_TCP )
  1008. X        {
  1009. X            CHECK_AND_CLEAR( scp, scp->sc_log_on_success, "log_on_success" ) ;
  1010. X            CHECK_AND_CLEAR( scp, scp->sc_log_on_failure, "log_on_failure" ) ;
  1011. X        }
  1012. X    }
  1013. X
  1014. X    psi_destroy( iter ) ;
  1015. X
  1016. X    if ( debug.on && debug.fd != -1 )
  1017. X        cnf_dump( confp, debug.fd ) ;
  1018. X
  1019. X    endservent() ;
  1020. X    endprotoent() ;
  1021. X#ifndef NO_RPC
  1022. X    endrpcent() ;
  1023. X#endif
  1024. X    return( OK ) ;
  1025. X}
  1026. X
  1027. X
  1028. END_OF_FILE
  1029. if test 13219 -ne `wc -c <'xinetd/confparse.c'`; then
  1030.     echo shar: \"'xinetd/confparse.c'\" unpacked with wrong size!
  1031. fi
  1032. # end of 'xinetd/confparse.c'
  1033. fi
  1034. echo shar: End of archive 23 \(of 31\).
  1035. cp /dev/null ark23isdone
  1036. MISSING=""
  1037. 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
  1038.     if test ! -f ark${I}isdone ; then
  1039.     MISSING="${MISSING} ${I}"
  1040.     fi
  1041. done
  1042. if test "${MISSING}" = "" ; then
  1043.     echo You have unpacked all 31 archives.
  1044.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1045. else
  1046.     echo You still need to unpack the following archives:
  1047.     echo "        " ${MISSING}
  1048. fi
  1049. ##  End of shell archive.
  1050. exit 0
  1051.