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

  1. Newsgroups: comp.sources.unix
  2. From: panos@cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v26i263: xinetd-2.1.1 - inetd replacement with access control and logging, Part19/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 263
  9. Archive-Name: xinetd-2.1.1/part19
  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 19 (of 31)."
  18. # Contents:  xinetd/Makefile xinetd/addr.c
  19. # Wrapped by panos@mystique on Mon Jun 21 14:51:26 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'xinetd/Makefile' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'xinetd/Makefile'\"
  23. else
  24. echo shar: Extracting \"'xinetd/Makefile'\" \(9823 characters\)
  25. sed "s/^X//" >'xinetd/Makefile' <<'END_OF_FILE'
  26. X# (c) Copyright 1992 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#
  31. X# $Id: Makefile,v 6.12 1993/06/15 18:55:53 panos Exp $
  32. X#
  33. X# Based on Program makefile template: *Revision: 1.14 *
  34. X#
  35. X
  36. X#
  37. X# Available entries:
  38. X#        $(NAME)        --> create the program (this is the default target)
  39. X#        install        --> install the program (and man page)
  40. X#        uninstall    --> uninstall the program (and man page)
  41. X#        clean            --> cleanup
  42. X#        spotless        --> clean + uninstall
  43. X#         lint            --> lints a specific file (usage: make lint MODULE=foo.c)
  44. X#        lintall        --> lint all files
  45. X#        tags            --> creates a tags file
  46. X#        checkout     --> checkout all files
  47. X#
  48. X
  49. X#
  50. X# The following variables must be set by you
  51. X#
  52. XNAME                    = xinetd
  53. XVERSION                = 2.1.1
  54. X
  55. X#
  56. X# Possible flags that can be defined in DEFS:
  57. X#
  58. X#        -DCUSTOMCONF        if you want to change any of the constants that
  59. X#                                affect xinetd's behavior (check config.h)
  60. X#     -DNO_POSIX_TYPES  if your OS does not know about POSIX types like pid_t
  61. X#     -DNO_TERMIOS      if you don't have /usr/include/sys/termios.h
  62. X#     -DOLD_WAIT        if your OS supports union wait
  63. X#     -DNO_RPC          if your OS does not support RPC
  64. X#     -DNO_SIGLIST      if your C library does not contain sys_siglist
  65. X#        -DNO_TIMERS            if you don't want to use the timer library
  66. X#
  67. X# About signal handling:
  68. X#  Case 1: POSIX signal handling is supported
  69. X#     You don't need to define anything
  70. X#  Case 2: BSD signal handling is supported (i.e. sigvec(2))
  71. X#     Use -DNO_POSIX_SIGS
  72. X#  Case 3: None of the above
  73. X#     Use -DNO_POSIX_SIGS and -DNO_SIGVEC
  74. X#
  75. X# Available debug flags:
  76. X#     DEBUG                      code is being debugged
  77. X#     DEBUG_SERVER               forked server will do a sleep
  78. X#     DEBUG_INTERCEPTOR          forked interceptor will do a sleep
  79. X#     DEBUG_SIGNALS              code that handles SIGSEGV and SIGBUS
  80. X#     DEBUG_LOGGING              forked logging server will do a sleep
  81. X#     DEBUG_SHUTDOWN             forked shutdown server will do a sleep
  82. X#     DEBUG_TPCINT               enable debugging code in the tcp interceptor
  83. X#     DEBUG_UDPINT               enable debugging code in the udp interceptor
  84. X#        DEBUG_DAEMON                    debug xinetd when not invoked with -d option
  85. X#        DEBUG_RETRY                        debug the server retry code
  86. X#
  87. XDEFS=-DDEBUG
  88. X
  89. XDEBUG                    = -g                    # either -g or -O
  90. XLDFLAGS                = -L$(LIBDIR)$(DEBUG)
  91. XLIBS                    = -lsio -lmisc -lstr -lpset -lxlog -ltimer -lpq
  92. X
  93. XHDRS                    =    \
  94. X                            access.h \
  95. X                            addr.h \
  96. X                            attr.h \
  97. X                            builtin.h \
  98. X                            conf.h config.h connection.h \
  99. X                            defs.h \
  100. X                            flags.h \
  101. X                            int.h \
  102. X                            log.h \
  103. X                            mask.h \
  104. X                            parse.h \
  105. X                            sconst.h sconf.h server.h service.h state.h
  106. X
  107. XSRCS                    =    \
  108. X                            access.c addr.c \
  109. X                            builtins.c \
  110. X                            child.c conf.c confparse.c connection.c \
  111. X                            env.c \
  112. X                            flags.c \
  113. X                            ident.c init.c int.c intcommon.c internals.c \
  114. X                            log.c logctl.c \
  115. X                            main.c msg.c \
  116. X                            nvlists.c \
  117. X                            parse.c parsesup.c parsers.c \
  118. X                            reconfig.c retry.c \
  119. X                            sconf.c server.c service.c shutdown.c \
  120. X                                signals.c special.c \
  121. X                            tcpint.c time.c \
  122. X                            udpint.c util.c
  123. X
  124. XOBJS                    =    \
  125. X                            access.o addr.o \
  126. X                            builtins.o \
  127. X                            child.o conf.o confparse.o connection.o \
  128. X                            env.o \
  129. X                            flags.o \
  130. X                            ident.o init.o int.o intcommon.o internals.o \
  131. X                            log.o logctl.o \
  132. X                            main.o msg.o \
  133. X                            nvlists.o \
  134. X                            parse.o parsesup.o parsers.o \
  135. X                            reconfig.o retry.o \
  136. X                            sconf.o server.o service.o shutdown.o \
  137. X                                signals.o special.o \
  138. X                            tcpint.o time.o \
  139. X                            udpint.o util.o
  140. X
  141. XOPT=options.opt
  142. X
  143. XOPT_SOURCE=options.c
  144. XOPT_HEADER=options.h
  145. XOPT_OBJECT=options.o
  146. X
  147. XSOURCES                = $(SRCS) $(OPT_SOURCE)
  148. XHEADERS                = $(HDRS) $(OPT_HEADER)
  149. XOBJECTS                = $(OBJS) $(OPT_OBJECT)
  150. X
  151. XINCLUDEDIR            = -I$(HOME)/.links/includes
  152. X#MANPATHDIR            = -I$(HOME)/.links/manpages    # path up to man{1,2,etc}
  153. XMANPATHDIR            = /tmp/t
  154. XINSTALLDIR            = /usr/etc
  155. X
  156. X
  157. X#
  158. X# You may modify the following variables but you probably don't need to.
  159. X#
  160. X
  161. XPROGRAM                = $(NAME)
  162. XMANPROGSECTION        = 1
  163. XMANSUBSECTION        =                        # like V,X,l
  164. XMANPROGFILE            = $(PROGRAM).man
  165. XMANPROGPAGE            = $(PROGRAM).$(MANPROGSECTION)$(MANSUBSECTION)
  166. XMANPROGDIR            = $(MANPATHDIR)/man$(MANPROGSECTION)
  167. XMANDATASECTION        = 5
  168. XMANDATANAMES        = conf log
  169. XMANDATADIR            = $(MANPATHDIR)/man$(MANDATASECTION)
  170. X
  171. XMANFILES                = $(MANPROGFILE) $(PROGRAM).conf.man $(PROGRAM).log.man
  172. X
  173. XCC                        = cc            # used for compiler-specific options
  174. XCC_FLAGS                = $(DEBUG)    # used for generic options
  175. X
  176. XXMODE                    = -m 700                # mode for executables
  177. XFMODE                    = -m 640                # mode for anything but executables
  178. XINSTALL                = install -c
  179. X
  180. XLINT_FLAGS            = -hbux
  181. XPAGER                    = less
  182. X
  183. XCPP_DEFS                = $(VERSION_DEF) $(DEFS)
  184. X
  185. X#
  186. X# The following variables do not need to be changed
  187. X#
  188. X
  189. XVERSION_DEF            = -DVERSION=\"$(PROGRAM)\ Version\ $(VERSION)\"
  190. XCPP_FLAGS            = $(CPP_DEFS) $(INCLUDEDIR)
  191. XCFLAGS                = $(CPP_FLAGS) $(CC_FLAGS)
  192. X
  193. Xall: $(PROGRAM) itox
  194. X
  195. Xitox: itox.c
  196. X    $(CC) $(DEBUG) $(INCLUDEDIR) itox.c -o $@ $(LDFLAGS) -lmisc -lsio -lstr
  197. X
  198. X$(PROGRAM): $(OBJECTS)
  199. X    $(CC) $(DEBUG) -o $@ $(OBJECTS) $(LDFLAGS) $(LIBS) || rm -f $@
  200. X
  201. Xtags: $(HEADERS) $(SOURCES)
  202. X    ctags -w $(HEADERS) $(SOURCES)
  203. X
  204. Xcheckout:
  205. X
  206. Xlint:
  207. X    lint $(LINT_FLAGS) $(CPP_FLAGS) $(MODULE) 2>&1 | $(PAGER)
  208. X
  209. Xlintall: $(OPT_HEADER)
  210. X    lint $(LINT_FLAGS) $(CPP_FLAGS) $(SOURCES) 2>&1 | $(PAGER)
  211. X
  212. XLINT_IGNORE=RCSid|warning: possible pointer alignment problem|warning: argument op unused|warning: struct/union iovec never defined|warning: null effect|(sigprocmask|sigaction) multiply declared|argument code unused
  213. X
  214. Xlintq: $(OPT_HEADER)
  215. X    lint $(LINT_FLAGS) $(CPP_FLAGS) $(SOURCES) 2>&1 | egrep -v '$(LINT_IGNORE)' | $(PAGER)
  216. X
  217. Xclean:
  218. X    rm -f $(OBJECTS) $(PROGRAM) core
  219. X
  220. Xxclean: clean
  221. X    rm -f $(OPT_SOURCE) $(OPT_HEADER)
  222. X
  223. Xinstall: $(PROGRAM)
  224. X    $(INSTALL) $(XMODE) $(PROGRAM) $(INSTALLDIR)
  225. X
  226. Xinstall.man:
  227. X    if test "$(MANPROGDIR)" ; then \
  228. X        $(INSTALL) $(FMODE) $(MANPROGFILE) $(MANPROGDIR)/$(MANPROGPAGE) ;\
  229. X    fi
  230. X    if test "$(MANDATADIR)" ; then \
  231. X        for i in $(MANDATANAMES) ; do \
  232. X            name=$(PROGRAM).$$i ; \
  233. X            $(INSTALL) $(FMODE) $$name.man $(MANDATADIR)/$$name.$(MANDATASECTION);\
  234. X        done ;\
  235. X    fi
  236. X
  237. Xuninstall:
  238. X    a=`pwd` ; cd $(INSTALLDIR) ;\
  239. X    if test $$a != `pwd` ; then rm -f $(PROGRAM) ; fi
  240. X    a=`pwd` ; cd $(MANPROGDIR) ;\
  241. X    if test $$a != `pwd` ; then rm -f $(MANPROGPAGE) ; fi
  242. X    a=`pwd` ; cd $(MANDATADIR) ;\
  243. X    if test $$a != `pwd` ; then \
  244. X        for i in $(MANDATANAMES) ; do \
  245. X            rm -f $(PROGRAM).$$i.$(MANDATASECTION) ;\
  246. X        done ;\
  247. X    fi
  248. X
  249. X#
  250. X# Distribution section
  251. X# This section contains the 2 targets for distribution support: dist, dirs
  252. X# "dist" checks out all files to be distributed
  253. X# "dirs" prints a list of directories to be included in the distribution.
  254. X# These directories should have a Makefile with a "dist" target
  255. X#
  256. XSUPPORT_FILES            = sample.conf itox.c BUG-REPORTS
  257. XDISTRIBUTION_FILES    = $(HDRS) $(SRCS) $(MANFILES) $(SUPPORT_FILES)
  258. XDIRS                        =
  259. X
  260. Xdist1:
  261. X
  262. Xdist: dist1 $(OPT_SOURCE) $(OPT_HEADER)
  263. X    -co -q $(DISTRIBUTION_FILES)
  264. X
  265. Xdirs:
  266. X    @echo $(DIRS)
  267. X
  268. X#
  269. X# This part of the file shows how to make $(OBJECTS) 
  270. X#
  271. X
  272. X
  273. X
  274. X#
  275. X# Header file dependencies
  276. X#
  277. Xaddr.h: defs.h
  278. X    @if test -f $@ ; then touch $@ ; else echo $@ is missing ; exit 1 ; fi
  279. X
  280. Xbuiltin.h: defs.h
  281. X    @if test -f $@ ; then touch $@ ; else echo $@ is missing ; exit 1 ; fi
  282. X
  283. Xconf.h: service.h
  284. X    @if test -f $@ ; then touch $@ ; else echo $@ is missing ; exit 1 ; fi
  285. X
  286. Xint.h: server.h
  287. X    @if test -f $@ ; then touch $@ ; else echo $@ is missing ; exit 1 ; fi
  288. X
  289. Xparse.h: defs.h
  290. X    @if test -f $@ ; then touch $@ ; else echo $@ is missing ; exit 1 ; fi
  291. X
  292. Xsconf.h: defs.h log.h mask.h
  293. X    @if test -f $@ ; then touch $@ ; else echo $@ is missing ; exit 1 ; fi
  294. X
  295. Xserver.h: defs.h service.h connection.h
  296. X    @if test -f $@ ; then touch $@ ; else echo $@ is missing ; exit 1 ; fi
  297. X
  298. Xservice.h: defs.h sconf.h builtin.h
  299. X    @if test -f $@ ; then touch $@ ; else echo $@ is missing ; exit 1 ; fi
  300. X
  301. Xstate.h: mask.h sconf.h conf.h
  302. X    @if test -f $@ ; then touch $@ ; else echo $@ is missing ; exit 1 ; fi
  303. X
  304. Xconnection.h: mask.h service.h
  305. X    @if test -f $@ ; then touch $@ ; else echo $@ is missing ; exit 1 ; fi
  306. X
  307. X#
  308. X# Object file dependencies
  309. X#
  310. Xaccess.o:         access.h addr.h connection.h service.h state.h
  311. Xaddr.o:             addr.h defs.h
  312. Xbuiltins.o:     builtin.h config.h defs.h sconf.h server.h
  313. Xchild.o:         attr.h config.h sconst.h server.h state.h $(OPT_HEADER)
  314. Xconf.o:             attr.h conf.h config.h defs.h service.h state.h 
  315. Xconfparse.o:    attr.h config.h conf.h defs.h parse.h sconst.h sconf.h state.h
  316. Xconnection.o:    connection.h service.h state.h
  317. Xsconf.o:            addr.h attr.h defs.h sconf.h state.h
  318. Xenv.o:            attr.h defs.h sconf.h 
  319. Xflags.o:            defs.h flags.h state.h
  320. Xident.o:            defs.h sconst.h server.h
  321. Xinit.o:            defs.h conf.h config.h state.h $(OPT_HEADER)
  322. Xint.o:            config.h connection.h defs.h int.h server.h service.h
  323. Xintcommon.o:    config.h defs.h int.h server.h service.h state.h 
  324. Xinternals.o:    config.h flags.h server.h service.h state.h
  325. Xlog.o:            access.h defs.h connection.h sconst.h server.h service.h
  326. Xlogctl.o:        config.h defs.h log.h service.h state.h
  327. Xmain.o:            service.h state.h $(OPT_HEADER)
  328. Xmsg.o:            config.h defs.h state.h $(OPT_HEADER)
  329. Xnvlists.o:        defs.h sconf.h
  330. Xparse.o:            addr.h attr.h conf.h defs.h parse.h service.h
  331. Xparsesup.o:        defs.h parse.h
  332. Xparsers.o:        addr.h config.h defs.h parse.h sconf.h
  333. Xreconfig.o:        access.h conf.h config.h defs.h server.h service.h state.h
  334. Xretry.o:            access.h config.h connection.h flags.h server.h state.h
  335. Xserver.o:        access.h config.h connection.h server.h state.h
  336. Xservice.o:        access.h attr.h config.h connection.h defs.h \
  337. X                        server.h service.h state.h $(OPT_HEADER)
  338. Xshutdown.o:        defs.h
  339. Xsignals.o:        config.h defs.h flags.h state.h
  340. Xspecial.o:        builtin.h conf.h config.h connection.h \
  341. X                        server.h sconst.h state.h $(OPT_HEADER)
  342. Xtcpint.o:        access.h config.h defs.h int.h 
  343. Xtime.o:            defs.h
  344. Xudpint.o:        access.h defs.h int.h
  345. Xutil.o:            config.h defs.h
  346. X
  347. END_OF_FILE
  348. if test 9823 -ne `wc -c <'xinetd/Makefile'`; then
  349.     echo shar: \"'xinetd/Makefile'\" unpacked with wrong size!
  350. fi
  351. # end of 'xinetd/Makefile'
  352. fi
  353. if test -f 'xinetd/addr.c' -a "${1}" != "-c" ; then 
  354.   echo shar: Will not clobber existing file \"'xinetd/addr.c'\"
  355. else
  356. echo shar: Extracting \"'xinetd/addr.c'\" \(10437 characters\)
  357. sed "s/^X//" >'xinetd/addr.c' <<'END_OF_FILE'
  358. X/*
  359. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  360. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  361. X * and conditions for redistribution.
  362. X */
  363. X
  364. Xstatic char RCSid[] = "$Id: addr.c,v 6.4 1993/06/06 00:06:13 panos Exp $" ;
  365. X
  366. X#include <sys/types.h>
  367. X#include <sys/socket.h>
  368. X#include <netinet/in.h>
  369. X#include <syslog.h>
  370. X#include <netdb.h>
  371. X#include <memory.h>
  372. X
  373. X#include "pset.h"
  374. X
  375. X#include "defs.h"
  376. X#include "addr.h"
  377. X
  378. Xunsigned long inet_addr() ;
  379. Xchar *malloc() ;
  380. Xint free() ;
  381. X
  382. Xvoid msg() ;
  383. Xvoid parsemsg() ;
  384. Xvoid out_of_memory() ;
  385. X
  386. X#define OPEN_CURLY_BRACKET            '{'
  387. X#define CLOSED_CURLY_BRACKET        '}'
  388. X#define COMMA                            ','
  389. X#define DOT                                '.'
  390. X
  391. X/*
  392. X * address types denote how the actual    numeric address was obtained.
  393. X * Currently they are only useful for debugging.
  394. X * Note that NUMERIC_ADDR includes both simple (e.g. 128.138.91.1) and
  395. X * factorized symbolic addresses (e.g. 128.138.91.{1,2,3}).
  396. X */
  397. Xtypedef enum {    NUMERIC_ADDR, NET_ADDR, HOST_ADDR } address_e ;
  398. X
  399. Xtypedef enum { CANT_PARSE, PARSED, ERROR } result_e ;
  400. X
  401. Xstruct comp_addr
  402. X{
  403. X    address_e        addr_type ;
  404. X    unsigned long    addr ;
  405. X    unsigned long    mask ;
  406. X} ;
  407. X
  408. X#define CAP( p )                ( (struct comp_addr *) (p) )
  409. X
  410. X
  411. X#define NEW_CAP()                    NEW( struct comp_addr )
  412. X#define FREE_CAP( cap )            FREE( cap )
  413. X
  414. X
  415. X/*
  416. X * Try to match the given address 'addr' with the specified address list.
  417. X * Returns TRUE if the address matched, FALSE otherwise.
  418. X * If the address matched, '*matchp' will hold the mask of the matching
  419. X * address (a greater numerical value for the mask implies a more
  420. X * precise match).
  421. X */
  422. Xbool_int addrlist_match( addr_list, addr, matchp )
  423. X    pset_h            addr_list ;
  424. X    struct in_addr *addr ;
  425. X    unsigned long    *matchp ;
  426. X{
  427. X    register unsigned long remote_addr = ntohl( addr->s_addr ) ;
  428. X    register unsigned u ;
  429. X
  430. X    for ( u = 0 ; u < pset_count( addr_list ) ; u++ )
  431. X    {
  432. X        register struct comp_addr *cap = CAP( pset_pointer( addr_list, u ) ) ;
  433. X
  434. X        if ( ( remote_addr & cap->mask ) == cap->addr )
  435. X        {
  436. X            *matchp = cap->mask ;
  437. X            return( TRUE ) ;
  438. X        }
  439. X    }
  440. X    return( FALSE ) ;
  441. X}
  442. X
  443. X
  444. X
  445. Xvoid addrlist_dump( addr_list, fd )
  446. X    pset_h    addr_list ;
  447. X    int        fd ;
  448. X{
  449. X    register unsigned u ;
  450. X    struct in_addr inaddr ;
  451. X    char *inet_ntoa() ;
  452. X
  453. X    for ( u = 0 ; u < pset_count( addr_list ) ; u++ )
  454. X    {
  455. X        struct comp_addr *cap = CAP( pset_pointer( addr_list, u ) ) ;
  456. X        char *type ;
  457. X
  458. X        inaddr.s_addr = htonl( cap->addr ) ;
  459. X        if ( cap->addr_type == NUMERIC_ADDR )
  460. X            type = "NUMERIC" ;
  461. X        else if ( cap->addr_type == NET_ADDR )
  462. X            type = "NET" ;
  463. X        else if ( cap->addr_type == HOST_ADDR )
  464. X            type = "HOST" ;
  465. X        else
  466. X            type = "BAD" ;
  467. X        
  468. X        Sprint( fd, " %s(%s)", inet_ntoa( inaddr ), type ) ;
  469. X    }
  470. X}
  471. X
  472. X
  473. Xvoid addrlist_free( addr_list )
  474. X    pset_h addr_list ;
  475. X{
  476. X    pset_apply( addr_list, free, NULL ) ;
  477. X}
  478. X
  479. X
  480. X
  481. X/*
  482. X * Add an address to the address list
  483. X */
  484. XPRIVATE status_e add( addr_list, cap )
  485. X    pset_h                addr_list ;
  486. X    struct comp_addr    *cap ;
  487. X{
  488. X    struct comp_addr *new_cap ;
  489. X    char *func = "add" ;
  490. X
  491. X    new_cap = NEW_CAP() ;
  492. X    if ( new_cap == NULL )
  493. X    {
  494. X        out_of_memory( func ) ;
  495. X        return( FAILED ) ;
  496. X    }
  497. X
  498. X    *new_cap = *cap ;
  499. X    if ( pset_add( addr_list, new_cap ) == NULL )
  500. X    {
  501. X        out_of_memory( func ) ;
  502. X        FREE_CAP( new_cap ) ;
  503. X        return( FAILED ) ;
  504. X    }
  505. X    return( OK ) ;
  506. X}
  507. X
  508. X
  509. X/*
  510. X * Find the address and remove it from the list
  511. X * Since there is no check when we add entries that an
  512. X * address is not entered twice, in this function we remove all
  513. X * addresses that match.
  514. X *
  515. X * XXX: we need to work on the way two cap's are considered equal
  516. X */
  517. XPRIVATE status_e remove( addr_list, cap )
  518. X    pset_h addr_list ;
  519. X    register struct comp_addr *cap ;
  520. X{
  521. X    register unsigned u = 0 ;
  522. X    register struct comp_addr *old_cap ;
  523. X
  524. X    for ( u = 0 ; u < pset_count( addr_list ) ; u++ )
  525. X    {
  526. X        old_cap = CAP( pset_pointer( addr_list, u ) ) ;
  527. X
  528. X        if ( old_cap->addr == cap->addr && old_cap->mask == cap->mask )
  529. X        {
  530. X            pset_pointer( addr_list, u ) = NULL ;
  531. X            FREE_CAP( old_cap ) ;
  532. X        }
  533. X    }
  534. X    pset_compact( addr_list ) ;
  535. X    return( OK ) ;
  536. X}
  537. X
  538. X
  539. X/*
  540. X * Try to parse 'str_addr' as a symbolic net name
  541. X */
  542. XPRIVATE result_e net_addr( str_addr, op, addr_list )
  543. X    char            *str_addr ;
  544. X    statfunc        op ;
  545. X    pset_h        addr_list ;
  546. X{
  547. X    /*
  548. X     *
  549. X     *  The following table demonstrates how the mask is determined
  550. X     *  given a net number N and following the relation:
  551. X     *     net #1 <= N <= #2
  552. X     *
  553. X     *     net #1      net #2      mask
  554. X     *        0           0        FFFFFFFF    (this should be rejected)
  555. X     *        1           FF       FF000000
  556. X     *        100         FFFF     FFFF0000
  557. X     *        10000       FFFFFF   FFFFFF00
  558. X     *        1000000     FFFFFFFF FFFFFFFF
  559. X     */
  560. X    static struct { int lim, mask, shift ; } net_to_mask[] =
  561. X    {
  562. X        { 0,                 0xFF000000,    24    },
  563. X        { 0xFF,            0xFFFF0000,    16    },
  564. X        { 0xFFFF,        0xFFFFFF00,    8    },
  565. X        { 0xFFFFFF,        0xFFFFFFFF,    0    },
  566. X        { 0xFFFFFFFF,    0,                0    }
  567. X    } ;
  568. X    struct comp_addr            ca ;
  569. X    struct netent                *nep ;
  570. X    register unsigned long    net_num ;
  571. X    int                            i ;
  572. X    char                            *func = "net_addr" ;
  573. X
  574. X    nep = getnetbyname( str_addr ) ;
  575. X    if ( nep == NULL || nep->n_addrtype != AF_INET || nep->n_net == 0 )
  576. X        return( CANT_PARSE ) ;
  577. X
  578. X    for ( i = 0, net_num = (unsigned long) nep->n_net ;; i++ )
  579. X    {
  580. X        if ( net_to_mask[ i ].mask == 0 )
  581. X        {
  582. X            msg( LOG_CRIT, func,
  583. X                "INTERNAL ERROR: Cannot process net number %ld", net_num ) ;
  584. X            return( ERROR ) ;
  585. X        }
  586. X        if ( net_to_mask[i].lim < net_num && net_num <= net_to_mask[i+1].lim )
  587. X        {
  588. X            ca.addr_type = NET_ADDR ;
  589. X            ca.addr = net_num << net_to_mask[ i ].shift ;
  590. X            ca.mask = net_to_mask[ i ].mask ;
  591. X            return( ( (*op)( addr_list, &ca ) == OK ) ? PARSED : ERROR ) ;
  592. X        }
  593. X    }
  594. X}
  595. X
  596. X
  597. X
  598. X/*
  599. X * Try to parse 'str_addr' as a numeric address
  600. X */
  601. XPRIVATE result_e numeric_addr( str_addr, op, addr_list )
  602. X    char *str_addr ;
  603. X    status_e (*op)() ;
  604. X    pset_h addr_list ;
  605. X{
  606. X    register unsigned long addr ;
  607. X    register unsigned long mask ;
  608. X    struct comp_addr ca ;
  609. X
  610. X    addr = inet_addr( str_addr ) ;
  611. X    if ( addr == (unsigned long) -1 )
  612. X        return( CANT_PARSE ) ;
  613. X
  614. X    if ( addr == 0 )
  615. X        mask = 0 ;            /* i.e. matches everything */
  616. X    else
  617. X    {
  618. X        for ( mask = 0xFF ;; )
  619. X        {
  620. X            if ( addr & mask )
  621. X                break ;
  622. X            mask <<= 8 ;
  623. X            mask |= 0xFF ;
  624. X        }
  625. X        mask = ~( mask >> 8 ) ;
  626. X    }
  627. X    ca.mask = mask ;
  628. X    ca.addr = addr ;
  629. X    ca.addr_type = NUMERIC_ADDR ;
  630. X    return( ( (*op)( addr_list, &ca ) == OK ) ? PARSED : ERROR ) ;
  631. X}
  632. X
  633. X
  634. X
  635. X/*
  636. X * Try to parse 'str_addr' as a symbolic host name
  637. X * Apply 'op' to the 'addrlist' for *all* IP addresses of the host
  638. X */
  639. XPRIVATE result_e host_addr( str_addr, op, addr_list )
  640. X    char *str_addr ;
  641. X    status_e (*op)() ;
  642. X    pset_h addr_list ;
  643. X{
  644. X    struct hostent *hep ;
  645. X    struct comp_addr ca ;
  646. X    char **ap ;
  647. X
  648. X    hep = gethostbyname( str_addr ) ;
  649. X    if ( hep == NULL || hep->h_addrtype != AF_INET )
  650. X        return( CANT_PARSE ) ;
  651. X
  652. X    ca.addr_type = HOST_ADDR ;
  653. X    for ( ap = hep->h_addr_list ; *ap ; ap++ )
  654. X    {
  655. X        struct in_addr inaddr ;
  656. X
  657. X        /*
  658. X         * Copy the address to avoid alignment problems
  659. X         */
  660. X        (void) memcpy( (char *) &inaddr, *ap, hep->h_length ) ;
  661. X
  662. X        ca.addr = ntohl( inaddr.s_addr ) ;
  663. X        ca.mask = 0xFFFFFFFF ;
  664. X        if ( (*op)( addr_list, &ca ) == FAILED )
  665. X            return( ERROR ) ;
  666. X    }
  667. X    return( PARSED ) ;
  668. X}
  669. X
  670. X
  671. X/*
  672. X * Try to parse 'str_addr' as a factorized address
  673. X * (for example, 128.138.{200,201})
  674. X *
  675. X * XXX: It is unclear whether this function should exist. It is really doing
  676. X *       the job of a preprocessor.
  677. X */
  678. XPRIVATE result_e factorized_addr( str_addr, op, addr_list )
  679. X    char        *str_addr ;
  680. X    status_e (*op)() ;
  681. X    pset_h    addr_list ;
  682. X{
  683. X    char                    *p ;
  684. X    char                    *fact_start ;
  685. X    int                    pass ;
  686. X    char                    last    = DOT ;
  687. X    unsigned                num    = 0 ;
  688. X    int                    shift = 24 ;    /* because we assume a 32-bit IP address */
  689. X    register unsigned long addr = 0 ;
  690. X    struct comp_addr    ca ;
  691. X    char                    *func = "factorized_addr" ;
  692. X
  693. X    for ( p = str_addr ; *p != OPEN_CURLY_BRACKET ; last = *p++ )
  694. X    {
  695. X        if ( isdigit( *p ) )
  696. X        {
  697. X            num = num * 10 + *p - '0' ;
  698. X            continue ;
  699. X        }
  700. X        switch ( *p )
  701. X        {
  702. X            case DOT:
  703. X                if ( last == DOT )
  704. X                {
  705. X                    parsemsg( LOG_ERR, func,
  706. X                        "Bad address: %s. Consecutive dots", str_addr ) ;
  707. X                    return( ERROR ) ;
  708. X                }
  709. X                addr = addr * 256 + num ;
  710. X                num = 0 ;
  711. X                shift -= 8 ;
  712. X                break ;
  713. X            
  714. X            default:
  715. X                return( CANT_PARSE ) ;
  716. X        }
  717. X    }
  718. X
  719. X    ca.addr_type = NUMERIC_ADDR ;
  720. X    fact_start = p+1 ;
  721. X    if ( addr != 0 )
  722. X        addr <<= ( shift+8 ) ;
  723. X
  724. X    /*
  725. X     * First pass is for syntax checking
  726. X     */
  727. X    for ( pass = 0 ; pass < 2 ; pass++ )
  728. X    {
  729. X        num = 0 ;
  730. X        for ( p = fact_start, last = COMMA ;; last = *p++ )
  731. X        {
  732. X            if ( isdigit( *p ) )
  733. X            {
  734. X                num = num * 10 + *p - '0' ;
  735. X                continue ;
  736. X            }
  737. X            switch ( *p )
  738. X            {
  739. X                case COMMA:
  740. X                case CLOSED_CURLY_BRACKET:
  741. X                    if ( last == COMMA )
  742. X                    {
  743. X                        parsemsg( LOG_ERR, func,
  744. X                            "Bad address: %s. Consecutive commas", str_addr ) ;
  745. X                        return( ERROR ) ;
  746. X                    }
  747. X
  748. X                    if ( pass == 1 )
  749. X                    {
  750. X                        ca.addr = addr + ( num << shift ) ;
  751. X                        ca.mask = ~( ( 1 << shift ) - 1 ) ;
  752. X                        if ( (*op)( addr_list, &ca ) == FAILED )
  753. X                            return( ERROR ) ;
  754. X                        num = 0 ;
  755. X                    }
  756. X                    break ;
  757. X                
  758. X                default:
  759. X                    parsemsg( LOG_ERR, func, "Bad address: %s", str_addr ) ;
  760. X                    return( ERROR ) ;
  761. X            }
  762. X            if ( *p == CLOSED_CURLY_BRACKET )
  763. X            {
  764. X                if ( p[1] != NUL )
  765. X                {
  766. X                    parsemsg( LOG_ERR, func, "Bad address: %s", str_addr ) ;
  767. X                    return( ERROR ) ;
  768. X                }
  769. X
  770. X                if ( pass == 0 )
  771. X                    break ;
  772. X                else
  773. X                    return( PARSED ) ;
  774. X            }
  775. X        }
  776. X    }
  777. X    /* NOTREACHED */
  778. X}
  779. X
  780. X
  781. X/*
  782. X * Try to parse 'str_addr' using all known methods.
  783. X * Try until one of the methods succeeds.
  784. X * A successful method will apply 'op' with the parsed address to the 
  785. X * 'addr_list'. The 'op' can be either 'add' or 'remove'
  786. X * This means that the parsed address will be either added or removed
  787. X * from the addr_list.
  788. X */
  789. XPRIVATE status_e addrlist_op( addr_list, op, str_addr )
  790. X    pset_h addr_list ;
  791. X    status_e (*op)() ;
  792. X    char *str_addr ;
  793. X{
  794. X    int i ;
  795. X    static result_e (*addr_parser[])() =
  796. X        {
  797. X            numeric_addr,
  798. X            factorized_addr,
  799. X            net_addr,
  800. X            host_addr,
  801. X            NULL
  802. X        } ;
  803. X    char *func = "addrlist_op" ;
  804. X
  805. X    for ( i = 0 ; addr_parser[ i ] != NULL ; i++ )
  806. X        switch ( (*addr_parser[ i ])( str_addr, op, addr_list ) )
  807. X        {
  808. X            case PARSED:
  809. X                return( OK ) ;
  810. X            
  811. X            case ERROR:
  812. X                return( FAILED ) ;
  813. X        }
  814. X
  815. X    parsemsg( LOG_ERR, func, "failed to parse %s", str_addr ) ;
  816. X    return( OK ) ;
  817. X}
  818. X
  819. X
  820. Xstatus_e addrlist_add( addr_list, str_addr ) 
  821. X    pset_h addr_list ;
  822. X    char *str_addr ;
  823. X{
  824. X    return( addrlist_op( addr_list, add, str_addr ) ) ;
  825. X}
  826. X
  827. X
  828. Xstatus_e addrlist_remove( addr_list, str_addr ) 
  829. X    pset_h addr_list ;
  830. X    char *str_addr ;
  831. X{
  832. X    return( addrlist_op( addr_list, remove, str_addr ) ) ;
  833. X}
  834. X
  835. X
  836. Xstatus_e addrlist_copy( from, to )
  837. X    pset_h from ;
  838. X    pset_h *to ;
  839. X{
  840. X    status_e copy_pset() ;
  841. X
  842. X    return( copy_pset( from, to, sizeof( struct comp_addr ) ) ) ;
  843. X}
  844. X
  845. END_OF_FILE
  846. if test 10437 -ne `wc -c <'xinetd/addr.c'`; then
  847.     echo shar: \"'xinetd/addr.c'\" unpacked with wrong size!
  848. fi
  849. # end of 'xinetd/addr.c'
  850. fi
  851. echo shar: End of archive 19 \(of 31\).
  852. cp /dev/null ark19isdone
  853. MISSING=""
  854. 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
  855.     if test ! -f ark${I}isdone ; then
  856.     MISSING="${MISSING} ${I}"
  857.     fi
  858. done
  859. if test "${MISSING}" = "" ; then
  860.     echo You have unpacked all 31 archives.
  861.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  862. else
  863.     echo You still need to unpack the following archives:
  864.     echo "        " ${MISSING}
  865. fi
  866. ##  End of shell archive.
  867. exit 0
  868.