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

  1. Newsgroups: comp.sources.unix
  2. From: panos@cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v26i258: xinetd-2.1.1 - inetd replacement with access control and logging, Part14/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 258
  9. Archive-Name: xinetd-2.1.1/part14
  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 14 (of 31)."
  18. # Contents:  libs/src/timer/timer.c libs/src/xlog/filelog.c
  19. #   xinetd/connection.c xinetd/ident.c
  20. # Wrapped by panos@mystique on Mon Jun 21 14:51:24 1993
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'libs/src/timer/timer.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'libs/src/timer/timer.c'\"
  24. else
  25. echo shar: Extracting \"'libs/src/timer/timer.c'\" \(5561 characters\)
  26. sed "s/^X//" >'libs/src/timer/timer.c' <<'END_OF_FILE'
  27. X/*
  28. X * (c) Copyright 1993 by Panagiotis Tsirigotis
  29. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  30. X * and conditions for redistribution.
  31. X */
  32. X
  33. Xstatic char RCSid[] = "$Id: timer.c,v 4.2 1993/05/06 06:43:14 panos Exp $" ;
  34. Xstatic char *version = VERSION ;
  35. X
  36. X#include "timemacros.h"
  37. X#include "impl.h"
  38. X#include "defs.h"
  39. X
  40. X#define TIMER_H_NULL                    ((timer_h)NULL)
  41. X
  42. X
  43. Xint timer_errno ;
  44. X
  45. X
  46. X
  47. X/*
  48. X * Create a timer of the specified type.
  49. X * Returns a timer handle
  50. X */
  51. Xtimer_h timer_create( type, flags, errnop )
  52. X    enum timer_types    type ;
  53. X    int                    flags ;
  54. X    int                    *errnop ;
  55. X{
  56. X    int        *errp = ( errnop != NULL ) ? errnop : &timer_errno ;
  57. X    timer_s    *tp ;
  58. X
  59. X    if ( type != TIMER_REAL && type != TIMER_VIRTUAL && type != TIMER_PROF )
  60. X            HANDLE_ERROR( flags, TIMER_H_NULL, errp, TIMER_EBADTYPE,
  61. X                            "TIMER timer_create: bad timer type\n" ) ;
  62. X            
  63. X    tp = TIMER_ALLOC() ;
  64. X    if ( tp == NULL )
  65. X    {
  66. X        *errp = TIMER_ENOMEM ;
  67. X        return( TIMER_H_NULL ) ;
  68. X    }
  69. X    
  70. X    tp->t_state = INACTIVE ;
  71. X    tp->t_act = IDLE ;
  72. X    tp->t_blocked = FALSE ;
  73. X
  74. X    tp->t_errnop = errp ;
  75. X    tp->t_flags = flags & TIMER_CREATE_FLAGS ;
  76. X    tp->t_action.ta_func = NULL ;
  77. X    tp->t_action.ta_arg = NULL ;
  78. X    tp->t_action.ta_flags = TIMER_NOFLAGS ;
  79. X    if ( __ostimer_newtimer( tp, type ) == TIMER_ERR )
  80. X    {
  81. X        TIMER_FREE( tp ) ;
  82. X        return( TIMER_H_NULL ) ;
  83. X    }
  84. X    return( (timer_h) tp ) ;
  85. X}
  86. X
  87. X
  88. Xvoid timer_destroy( handle )
  89. X    timer_h    handle ;
  90. X{
  91. X    timer_s    *tp = TP( handle ) ;
  92. X
  93. X    __ostimer_blockall() ;
  94. X
  95. X    if ( tp->t_state == TICKING )
  96. X    {
  97. X        __ostimer_remove( tp->t_ostimer, tp ) ;
  98. X        tp->t_state = DESTROYED ;
  99. X    }
  100. X    
  101. X    if ( tp->t_act == IDLE || tp->t_act == PENDING )
  102. X        TIMER_FREE( tp ) ;
  103. X
  104. X    __ostimer_unblockall() ;
  105. X}
  106. X
  107. X
  108. Xint timer_start( handle, itvp, time_type, ap )
  109. X    timer_h                    handle ;
  110. X    struct itimerval        *itvp ;
  111. X    enum timer_timetypes time_type ;
  112. X    struct timer_action    *ap ;
  113. X{
  114. X    int                    result ;
  115. X    int                    ok_to_start ;
  116. X    timer_s                *tp    = TP( handle ) ;
  117. X    struct os_timer    *otp    = tp->t_ostimer ;
  118. X
  119. X    __ostimer_blockall() ;
  120. X
  121. X    /*
  122. X     * We allow invoking timer_start from within the user-specified action
  123. X     * after the timer has expired. However, we do not allow this for
  124. X     * timers that have a t_interval (these timers stay at the TICKING state).
  125. X     */
  126. X    ok_to_start = tp->t_state == INACTIVE &&
  127. X                            ( tp->t_act == IDLE || tp->t_act == INVOKED ) ;
  128. X
  129. X    if ( ! ok_to_start )
  130. X    {
  131. X        __ostimer_unblockall() ;
  132. X        HANDLE_ERROR( tp->t_flags, TIMER_ERR, tp->t_errnop, TIMER_EBADSTATE,
  133. X            "TIMER timer_start: timer state does not allow this operation\n" ) ;
  134. X    }
  135. X
  136. X    if ( itvp->it_value.tv_sec < 0 || itvp->it_value.tv_usec < 0 )
  137. X    {
  138. X        __ostimer_unblockall() ;
  139. X        HANDLE_ERROR( tp->t_flags, TIMER_ERR, tp->t_errnop, TIMER_EBADTIME,
  140. X            "TIMER timer_start: neg time value)\n" ) ;
  141. X    }
  142. X
  143. X    tp->t_action = *ap ;
  144. X    tp->t_action.ta_flags &= TIMER_START_FLAGS ;
  145. X
  146. X    result = __ostimer_add( otp, tp, itvp, time_type ) ;
  147. X    __ostimer_unblockall() ;
  148. X    return( result ) ;
  149. X}
  150. X
  151. X
  152. Xvoid timer_stop( handle )
  153. X    timer_h handle ;
  154. X{
  155. X    timer_s *tp = TP( handle ) ;
  156. X
  157. X    __ostimer_blockall() ;
  158. X
  159. X    if ( tp->t_state == TICKING )
  160. X    {
  161. X        __ostimer_remove( tp->t_ostimer, tp ) ;
  162. X        tp->t_state = INACTIVE ;
  163. X    }
  164. X
  165. X    if ( tp->t_act == SCHEDULED )
  166. X        tp->t_act = INVOKED ;        /* to avoid the invocation */
  167. X    else if ( tp->t_act == PENDING )
  168. X        tp->t_act = IDLE ;
  169. X
  170. X    tp->t_blocked = FALSE ;
  171. X    
  172. X    __ostimer_unblockall() ;
  173. X}
  174. X
  175. X
  176. Xvoid timer_block( handle )
  177. X    timer_h handle ;
  178. X{
  179. X    timer_s *tp = TP( handle ) ;
  180. X
  181. X    __ostimer_blockall() ;
  182. X
  183. X    if ( tp->t_state == TICKING || 
  184. X            tp->t_state == INACTIVE && 
  185. X                ( tp->t_act == PENDING || tp->t_act == SCHEDULED ) )
  186. X        tp->t_blocked = TRUE ;
  187. X
  188. X    __ostimer_unblockall() ;
  189. X}
  190. X
  191. X
  192. Xvoid timer_unblock( handle )
  193. X    timer_h handle ;
  194. X{
  195. X    timer_s *tp = TP( handle ) ;
  196. X
  197. X    __ostimer_blockall() ;
  198. X
  199. X    if ( tp->t_blocked )
  200. X    {
  201. X        tp->t_blocked = FALSE ;
  202. X        if ( tp->t_act == PENDING )
  203. X        {
  204. X            tp->t_act = SCHEDULED ;
  205. X            (void) __timer_invoke( tp ) ;
  206. X        }
  207. X    }
  208. X    
  209. X    __ostimer_unblockall() ;
  210. X}
  211. X
  212. X
  213. Xunsigned timer_expirations( handle )
  214. X    timer_h handle ;
  215. X{
  216. X    return( TP( handle )->t_count ) ;
  217. X}
  218. X
  219. X
  220. X
  221. X/*
  222. X * Invoke the action of the specified timer
  223. X * All timer interrupts should be blocked when this function is invoked
  224. X * Returns TRUE if 
  225. X */
  226. Xenum timer_state __timer_invoke( tp )
  227. X    register timer_s *tp ;
  228. X{
  229. X    enum timer_state state ;
  230. X
  231. X    /*
  232. X     * The reason for the infinite loop is that the timer may reexpire
  233. X     * while its function is being invoked.
  234. X     */
  235. X    for ( ;; )
  236. X    {
  237. X        /*
  238. X         * This is the INVOKE part
  239. X         */
  240. X        if ( tp->t_blocked )
  241. X            tp->t_act = PENDING ;
  242. X        else
  243. X        {
  244. X            if ( tp->t_state != DESTROYED && tp->t_act == SCHEDULED )
  245. X            {
  246. X                void    (*func)()    = tp->t_action.ta_func ;
  247. X                void    *arg            = tp->t_action.ta_arg ;
  248. X                int    flags         = tp->t_action.ta_flags ;
  249. X
  250. X                tp->t_act = INVOKED ;
  251. X                tp->t_expirations = tp->t_count ;
  252. X                tp->t_count = 0 ;
  253. X                if ( func != NULL )
  254. X                {
  255. X                    int unblock_all_intrs = ! ( flags & TIMER_BLOCK_ALL ) ;
  256. X                    int unblock_all_but_same_intr = ! ( flags & TIMER_BLOCK_SAME ) ;
  257. X                    
  258. X                    if ( unblock_all_intrs )
  259. X                        __ostimer_unblockall() ;
  260. X                    else if ( unblock_all_but_same_intr )
  261. X                        __ostimer_unblockall_except( tp->t_ostimer ) ;
  262. X
  263. X                    (*func)( tp, arg ) ;
  264. X
  265. X                    if ( unblock_all_intrs || unblock_all_but_same_intr )
  266. X                        __ostimer_blockall() ;
  267. X                }
  268. X                else if ( arg != NULL )
  269. X                {
  270. X                    int *ip = (int *) arg ;
  271. X
  272. X                    if ( flags & TIMER_INC_VAR )
  273. X                        *ip += tp->t_expirations ;
  274. X                    else
  275. X                        *ip = 1 ;
  276. X                }
  277. X            }
  278. X        }
  279. X
  280. X        state = tp->t_state ;
  281. X
  282. X        /*
  283. X         * This is the RETURN part
  284. X         */
  285. X        if ( tp->t_state == DESTROYED )
  286. X            TIMER_FREE( tp ) ;
  287. X        else
  288. X        {
  289. X            if ( tp->t_act == INVOKED )
  290. X                tp->t_act = IDLE ;
  291. X            else if ( tp->t_act == SCHEDULED )
  292. X                continue ;
  293. X        }
  294. X        break ;
  295. X    }
  296. X    return( state ) ;
  297. X}
  298. X
  299. END_OF_FILE
  300. if test 5561 -ne `wc -c <'libs/src/timer/timer.c'`; then
  301.     echo shar: \"'libs/src/timer/timer.c'\" unpacked with wrong size!
  302. fi
  303. # end of 'libs/src/timer/timer.c'
  304. fi
  305. if test -f 'libs/src/xlog/filelog.c' -a "${1}" != "-c" ; then 
  306.   echo shar: Will not clobber existing file \"'libs/src/xlog/filelog.c'\"
  307. else
  308. echo shar: Extracting \"'libs/src/xlog/filelog.c'\" \(5812 characters\)
  309. sed "s/^X//" >'libs/src/xlog/filelog.c' <<'END_OF_FILE'
  310. X/*
  311. X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  312. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  313. X * and conditions for redistribution.
  314. X */
  315. X
  316. Xstatic char RCSid[] = "$Id: filelog.c,v 2.2 1993/06/15 18:08:01 panos Exp $" ;
  317. X
  318. X#include <sys/types.h>
  319. X#include <sys/stat.h>
  320. X#include <varargs.h>
  321. X#include <fcntl.h>
  322. X#include <time.h>
  323. X#ifndef NO_SYSLOG
  324. X#include <syslog.h>
  325. X#else
  326. X#define LOG_ALERT                0
  327. X#endif
  328. X
  329. X#include "sio.h"
  330. X
  331. X#include "xlog.h"
  332. X#include "impl.h"
  333. X#include "filelog.h"
  334. X
  335. XPRIVATE int filelog_init() ;
  336. XPRIVATE void filelog_fini() ;
  337. XPRIVATE int filelog_control() ;
  338. XPRIVATE int filelog_write() ;
  339. XPRIVATE int filelog_parms() ;
  340. XPRIVATE int limit_checks() ;
  341. X
  342. Xstruct xlog_ops __xlog_filelog_ops = 
  343. X    {
  344. X        filelog_init,
  345. X        filelog_fini,
  346. X        filelog_write,
  347. X        filelog_control,
  348. X        filelog_parms
  349. X    } ;
  350. X
  351. X
  352. XPRIVATE int filelog_init( xp, ap )
  353. X    xlog_s    *xp ;
  354. X    va_list    ap ;
  355. X{
  356. X    int                fd ;
  357. X    struct filelog *flp ;
  358. X    char                *filename    = va_arg( ap, char * ) ;
  359. X    int                flags            = va_arg( ap, int ) ;
  360. X
  361. X    flp = NEW( struct filelog ) ;
  362. X    if ( flp == NULL )
  363. X        return( XLOG_ENOMEM ) ;
  364. X
  365. X    if ( flags & O_CREAT )
  366. X        fd = open( filename, flags, va_arg( ap, int ) ) ;
  367. X    else
  368. X        fd = open( filename, flags ) ;
  369. X
  370. X    if ( fd == -1 )
  371. X    {
  372. X        FREE( flp ) ;
  373. X        return( XLOG_EOPEN ) ;
  374. X    }
  375. X    
  376. X    FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
  377. X    (void) Sbuftype( fd, SIO_LINEBUF ) ;
  378. X    flp->fl_fd = fd ;
  379. X    flp->fl_state = FL_OPEN ;
  380. X    xp->xl_data = flp ;
  381. X    return( XLOG_ENOERROR ) ;
  382. X}
  383. X
  384. X
  385. XPRIVATE void filelog_fini( xp )
  386. X    xlog_s *xp ;
  387. X{
  388. X    struct filelog *flp = FILELOG( xp ) ;
  389. X
  390. X    if ( flp->fl_state != FL_CLOSED )
  391. X    {
  392. X        (void) close( flp->fl_fd ) ;
  393. X        flp->fl_state = FL_CLOSED ;
  394. X    }
  395. X    FREE( flp ) ;
  396. X    xp->xl_data = NULL ;
  397. X}
  398. X
  399. X
  400. X
  401. XPRIVATE int filelog_control( xp, cmd, ap )
  402. X    xlog_s        *xp ;
  403. X    xlog_cmd_e    cmd ;
  404. X    va_list        ap ;
  405. X{
  406. X    struct stat        st ;
  407. X    struct filelog *flp        = FILELOG( xp ) ;
  408. X    int                status    = XLOG_ENOERROR ;
  409. X
  410. X    if ( flp->fl_state == FL_ERROR )
  411. X        return( flp->fl_error ) ;
  412. X
  413. X    switch ( cmd )
  414. X    {
  415. X        case XLOG_GETFD:
  416. X            if ( flp->fl_state == FL_OPEN )
  417. X                *va_arg( ap, int * ) = flp->fl_fd ;
  418. X            else
  419. X                status = XLOG_ENOERROR ;
  420. X            break ;
  421. X
  422. X        case XLOG_LIMITS:
  423. X            flp->fl_soft_limit = va_arg( ap, unsigned ) ;
  424. X            flp->fl_hard_limit = va_arg( ap, unsigned ) ;
  425. X            flp->fl_issued_warning = FALSE ;
  426. X            FILELOG_ENABLE_SIZE_CONTROL( flp ) ;
  427. X            flp->fl_state = FL_OPEN ;
  428. X            /* FALL THROUGH */
  429. X
  430. X        case XLOG_SIZECHECK:
  431. X            if ( ! FILELOG_SIZE_CONTROL( flp ) )
  432. X                break ;
  433. X            if ( fstat( flp->fl_fd, &st ) == -1 )
  434. X            {
  435. X                FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
  436. X                flp->fl_state = FL_ERROR ;
  437. X                flp->fl_error = status = XLOG_EFSTAT ;
  438. X            }
  439. X            else
  440. X            {
  441. X                flp->fl_size = st.st_size ;
  442. X                if ( flp->fl_size > flp->fl_soft_limit )
  443. X                    status = limit_checks( xp ) ;
  444. X            }
  445. X            break ;
  446. X    }
  447. X    return( status ) ;
  448. X}
  449. X
  450. X
  451. XPRIVATE int limit_checks( xp )
  452. X    xlog_s *xp ;
  453. X{
  454. X    struct filelog *flp = FILELOG( xp ) ;
  455. X    char buf[ 100 ] ;
  456. X
  457. X    if ( ! flp->fl_issued_warning )
  458. X    {
  459. X        if ( xp->xl_use != NULL )
  460. X            xlog_write( (xlog_h) xp->xl_use, buf,
  461. X                strx_nprint( buf, sizeof( buf ),
  462. X                                    "soft limit exceeded on '%s'", xp->xl_id ),
  463. X                    XLOG_NOFLAGS, LOG_ALERT ) ;
  464. X        flp->fl_issued_warning = TRUE ;
  465. X    }
  466. X
  467. X    if ( flp->fl_size <= flp->fl_hard_limit )
  468. X        return( XLOG_ENOERROR ) ;
  469. X    
  470. X    if ( xp->xl_use != NULL )
  471. X        xlog_write( (xlog_h) xp->xl_use, buf,
  472. X            strx_nprint( buf, sizeof( buf ),
  473. X                        "hard limit exceeded on '%s'; log closed", xp->xl_id ),
  474. X                XLOG_NOFLAGS, LOG_ALERT ) ;
  475. X    flp->fl_state = FL_ERROR ;
  476. X    return( XLOG_ESIZE ) ;
  477. X}
  478. X
  479. X
  480. XPRIVATE int filelog_write( xp, buf, len, flags, ap )
  481. X    xlog_s    *xp ;
  482. X    char        buf[] ;
  483. X    int        len ;
  484. X    int        flags ;
  485. X    va_list    ap ;
  486. X{
  487. X    struct filelog    *flp                = FILELOG( xp ) ;
  488. X    int                 action_flags    = ( xp->xl_flags | flags ) ;
  489. X    int                msglen            = 0 ;
  490. X    char                *percent_m_pos ;
  491. X    int                cc ;
  492. X    int                status ;
  493. X    time_t             current_time ;
  494. X    struct tm        *tmp ;
  495. X    time_t            time() ;
  496. X
  497. X    if ( flp->fl_state != FL_OPEN )
  498. X        return( flp->fl_error ) ;
  499. X
  500. X    (void) time( ¤t_time ) ;
  501. X    tmp = localtime( ¤t_time ) ;
  502. X    cc = Sprint( flp->fl_fd, "%d/%d/%d@%02d:%02d:%02d",
  503. X                            tmp->tm_year, tmp->tm_mon+1, tmp->tm_mday,
  504. X                            tmp->tm_hour, tmp->tm_min, tmp->tm_sec ) ;
  505. X    msglen += cc ;
  506. X
  507. X    if ( action_flags & XLOG_PRINT_ID )
  508. X    {
  509. X        cc = Sprint( flp->fl_fd, " %s", xp->xl_id ) ;
  510. X        msglen += cc ;
  511. X    }
  512. X
  513. X    if ( action_flags & XLOG_PRINT_PID )
  514. X    {
  515. X        cc = Sprint( flp->fl_fd, "[%d]", getpid() ) ;
  516. X        msglen += cc ;
  517. X    }
  518. X
  519. X    cc = Sprint( flp->fl_fd, ": " ) ;
  520. X    msglen += cc ;
  521. X
  522. X    if ( ( action_flags & XLOG_NO_ERRNO ) ||
  523. X                        ( percent_m_pos = __xlog_add_errno( buf, len ) ) == NULL )
  524. X    {
  525. X        cc = Swrite( flp->fl_fd, buf, len ) ;
  526. X        msglen += cc ;
  527. X    }
  528. X    else
  529. X    {
  530. X        char errno_buf[ 100 ] ;
  531. X        unsigned size = sizeof( errno_buf ) ;
  532. X        int cc_before_errno = percent_m_pos - buf ;
  533. X        char *ep ;
  534. X
  535. X        /*
  536. X         * The reason for the repetition of "msglen += cc ;" is that in the
  537. X         * future we may want to check cc for SIO_ERR
  538. X         */
  539. X        ep = __xlog_explain_errno( errno_buf, &size ) ;
  540. X        cc = Swrite( flp->fl_fd, buf, cc_before_errno ) ;
  541. X        msglen += cc ;
  542. X        cc = Swrite( flp->fl_fd, ep, (int)size ) ;
  543. X        msglen += cc ;
  544. X        cc = Swrite( flp->fl_fd, percent_m_pos+2, len-cc_before_errno-2 ) ;
  545. X        msglen += cc ;
  546. X    }
  547. X    /*
  548. X     * Writing a newline will cause a buffer flush since we asked for
  549. X     * line-buffered output
  550. X     */
  551. X    Sputchar( flp->fl_fd, '\n' ) ;
  552. X    msglen++ ;
  553. X
  554. X    /*
  555. X     * NOTE: we don't check if XLOG_NO_SIZECHECK is set in xp->xl_flags
  556. X     *            because size control is off by default and in order to
  557. X     *            be enabled XLOG_LIMITS must be used which overrides xp->xl_flags
  558. X     */
  559. X    if ( ! FILELOG_SIZE_CONTROL( flp ) || ( flags & XLOG_NO_SIZECHECK ) )
  560. X        return( XLOG_ENOERROR ) ;
  561. X
  562. X    flp->fl_size += msglen ;
  563. X    if ( flp->fl_size <= flp->fl_soft_limit || 
  564. X                    ( status = limit_checks( xp ) ) == XLOG_ENOERROR )
  565. X        return( XLOG_ENOERROR ) ;
  566. X    
  567. X    flp->fl_state = FL_SIZE ;
  568. X    return( status ) ;
  569. X}
  570. X
  571. X
  572. XPRIVATE int filelog_parms( ap )
  573. X    va_list ap ;
  574. X{
  575. X    return( XLOG_ENOERROR ) ;
  576. X}
  577. X
  578. END_OF_FILE
  579. if test 5812 -ne `wc -c <'libs/src/xlog/filelog.c'`; then
  580.     echo shar: \"'libs/src/xlog/filelog.c'\" unpacked with wrong size!
  581. fi
  582. # end of 'libs/src/xlog/filelog.c'
  583. fi
  584. if test -f 'xinetd/connection.c' -a "${1}" != "-c" ; then 
  585.   echo shar: Will not clobber existing file \"'xinetd/connection.c'\"
  586. else
  587. echo shar: Extracting \"'xinetd/connection.c'\" \(5909 characters\)
  588. sed "s/^X//" >'xinetd/connection.c' <<'END_OF_FILE'
  589. X/*
  590. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  591. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  592. X * and conditions for redistribution.
  593. X */
  594. X
  595. Xstatic char RCSid[] = "$Id: connection.c,v 6.5 1993/06/13 01:42:57 panos Exp $" ;
  596. X
  597. X#include <sys/types.h>
  598. X#include <sys/socket.h>
  599. X#include <netinet/in.h>
  600. X#include <syslog.h>
  601. X
  602. X#include "sio.h"
  603. X
  604. X#include "connection.h"
  605. X#include "service.h"
  606. X#include "state.h"
  607. X
  608. Xchar *inet_ntoa() ;
  609. Xchar *malloc() ;
  610. X
  611. Xvoid msg() ;
  612. Xvoid out_of_memory() ;
  613. X
  614. X#define NEW_CONN()                    NEW( connection_s )
  615. X#define FREE_CONN( cop )            FREE( cop )
  616. X
  617. X
  618. X/*
  619. X * Get a new connection request and initialize 'cp' appropriately
  620. X */
  621. XPRIVATE status_e get_connection( sp, cp )
  622. X    register struct service *sp ;
  623. X    register connection_s *cp ;
  624. X{
  625. X    int sin_len = sizeof( cp->co_remote_address ) ;
  626. X    char *func = "get_connection" ;
  627. X
  628. X    if ( SVC_ACCEPTS_CONNECTIONS( sp ) )
  629. X    {
  630. X        cp->co_descriptor = accept( SVC_FD( sp ),
  631. X                                                SA( &cp->co_remote_address ), &sin_len ) ;
  632. X        if ( cp->co_descriptor == -1 )
  633. X        {
  634. X            msg( LOG_ERR, func, "service %s, accept: %m", SVC_ID( sp ) ) ;
  635. X            return( FAILED ) ;
  636. X        }
  637. X        M_SET( cp->co_flags, COF_HAVE_ADDRESS ) ;
  638. X        M_SET( cp->co_flags, COF_NEW_DESCRIPTOR ) ;
  639. X    }
  640. X    else
  641. X    {
  642. X        if ( SVC_SOCKET_TYPE( sp ) == SOCK_DGRAM )
  643. X        {
  644. X            char t_ch ;
  645. X
  646. X            /*
  647. X             * This trick is done to get the remote address.
  648. X             * select(2) guaranteed that we won't block on the recvfrom
  649. X             */
  650. X            if ( recvfrom( SVC_FD( sp ), &t_ch, 1, MSG_PEEK,
  651. X                                        SA( &cp->co_remote_address ), &sin_len ) == -1 )
  652. X            {
  653. X                msg( LOG_ERR, func, "service %s, recvfrom: %m", SVC_ID( sp ) ) ;
  654. X                return( FAILED ) ;
  655. X            }
  656. X            M_SET( cp->co_flags, COF_HAVE_ADDRESS ) ;
  657. X        }
  658. X        cp->co_descriptor = SVC_FD( sp ) ;
  659. X    }
  660. X    return( OK ) ;
  661. X}
  662. X
  663. X
  664. X
  665. X/*
  666. X * Get a connection for the specified service and return a pointer
  667. X * to a new connection_s
  668. X */
  669. Xconnection_s *conn_new( sp )
  670. X    register struct service *sp ;
  671. X{
  672. X    connection_s                new_conn ;
  673. X    register connection_s    *cp ;
  674. X    char                            *func = "conn_new" ;
  675. X
  676. X    CLEAR( new_conn ) ;
  677. X
  678. X    /*
  679. X     * The reason we first get the connection and then allocate a
  680. X     * 'connection_s' is because we want to always consume some input.
  681. X     */
  682. X    if ( get_connection( sp, &new_conn ) == FAILED )
  683. X        return( NULL ) ;
  684. X
  685. X    new_conn.co_state = CONN_OPEN ;
  686. X    new_conn.co_sp = sp ;
  687. X    SVC_HOLD( sp ) ;
  688. X    if ( SVC_WAITS( sp ) )
  689. X        svc_suspend( sp ) ;
  690. X
  691. X    cp = NEW_CONN() ;
  692. X    if ( cp == CONN_NULL )
  693. X    {
  694. X        out_of_memory( func ) ;
  695. X        conn_cleanup( &new_conn ) ;
  696. X        conn_shutdown( &new_conn ) ;
  697. X        conn_free( &new_conn ) ;
  698. X        return( CONN_NULL ) ;
  699. X    }
  700. X    *cp = new_conn ;
  701. X    return( cp ) ;
  702. X}
  703. X
  704. X
  705. X/*
  706. X * Close the connection descriptor if it is a new one
  707. X */
  708. Xvoid conn_close( cp )
  709. X    register connection_s *cp ;
  710. X{
  711. X    if ( cp->co_state == CONN_OPEN && 
  712. X                                        M_IS_SET( cp->co_flags, COF_NEW_DESCRIPTOR ) )
  713. X    {
  714. X        (void) close( cp->co_descriptor ) ;
  715. X        cp->co_state = CONN_CLOSED ;
  716. X    }
  717. X}
  718. X
  719. X
  720. X/*
  721. X * Release the specified connection.
  722. X * Certain actions may be performed before doing this:
  723. X *        - invocation of the service shutdown function
  724. X *        - drain of a single UDP packet if the socket type is SOCK_DGRAM
  725. X */
  726. Xvoid conn_free( cp )
  727. X    register connection_s *cp ;
  728. X{
  729. X    register struct service *sp = cp->co_sp ;
  730. X    int i ;
  731. X    void drain() ;
  732. X
  733. X    if ( SVC_IS_SUSPENDED( sp ) )
  734. X        svc_resume( sp ) ;
  735. X
  736. X    if ( cp->co_state == CONN_OPEN )
  737. X    {
  738. X        if ( M_IS_SET( cp->co_flags, COF_SHUTDOWN ) )
  739. X            svc_shutdown( sp, cp, (char **)NULL ) ;
  740. X        
  741. X        if ( M_IS_SET( cp->co_flags, COF_CLEANUP ) && 
  742. X                                    SVC_SOCKET_TYPE( sp ) == SOCK_DGRAM )
  743. X            drain( cp->co_descriptor ) ;
  744. X    }
  745. X
  746. X    if ( SVC_RELE( sp ) == 0 )
  747. X        pset_remove( SERVICES( ps ), sp ) ;
  748. X
  749. X    for ( i = 0 ; i < cp->co_alternative_count ; i++ )
  750. X    {
  751. X        struct service *asp = cp->co_alternatives[ i ] ;
  752. X
  753. X        if ( SVC_RELE( asp ) == 0 )
  754. X            pset_remove( SERVICES( ps ), asp ) ;
  755. X    }
  756. X
  757. X    conn_close( cp ) ;
  758. X
  759. X    FREE_CONN( cp ) ;
  760. X}
  761. X
  762. X
  763. Xstatus_e conn_add_alternative( cp, sp )
  764. X    register connection_s *cp ;
  765. X    register struct service *sp ;
  766. X{
  767. X    char *func = "conn_add_alternative" ;
  768. X
  769. X    if ( sp == NULL )
  770. X        return( FAILED ) ;
  771. X
  772. X    if ( cp->co_alternative_count >= MAX_ALTERNATIVES )
  773. X    {
  774. X        msg( LOG_ERR, func,
  775. X            "Cannot add alternative service %s to connection for service %s",
  776. X                SVC_ID( sp ), SVC_ID( cp->co_sp ) ) ;
  777. X        return( FAILED ) ;
  778. X    }
  779. X
  780. X    if ( debug.on )
  781. X        msg( LOG_DEBUG, func,
  782. X            "Adding alternative service %s to connection of service %s",
  783. X                SVC_ID( sp ), SVC_ID( cp->co_sp ) ) ;
  784. X
  785. X    cp->co_alternatives[ cp->co_alternative_count++ ] = sp ;
  786. X    SVC_HOLD( sp ) ;
  787. X    return( OK ) ;
  788. X}
  789. X
  790. X
  791. X/*
  792. X * Start invoking alternative services starting from the next alternative one
  793. X * until either we get a successful invocation or we run out of services
  794. X */
  795. Xstatus_e conn_start_alternative( cp )
  796. X    register connection_s *cp ;
  797. X{
  798. X    char *func = "conn_start_alternative" ;
  799. X
  800. X    while ( cp->co_next_alternative < cp->co_alternative_count )
  801. X    {
  802. X        struct service *asp = cp->co_alternatives[ cp->co_next_alternative++ ] ;
  803. X        
  804. X        if ( svc_handle( asp, cp ) == OK )
  805. X        {
  806. X            if ( debug.on )
  807. X                msg( LOG_DEBUG, func,
  808. X                    "Started alternative service %s", SVC_ID( asp ) ) ;
  809. X            return( OK ) ;
  810. X        }
  811. X    }
  812. X    return( FAILED ) ;
  813. X}
  814. X
  815. X
  816. Xvoid conn_dump( cp, fd )
  817. X    register connection_s *cp ;
  818. X    int fd ;
  819. X{
  820. X    register unsigned u ;
  821. X    void tabprint() ;
  822. X
  823. X    tabprint( fd, 1, "state = %s\n",
  824. X            ( cp->co_state == CONN_CLOSED ) ? "CLOSED" : "OPEN" ) ;
  825. X
  826. X    tabprint( fd, 1, "service = %s\n", SVC_ID( cp->co_sp ) ) ;
  827. X    tabprint( fd, 1, "descriptor = %d\n", cp->co_descriptor ) ;
  828. X    tabprint( fd, 1, "flags = %#x\n", cp->co_flags ) ;
  829. X    tabprint( fd, 1, "remote_address = %s,%d\n",
  830. X                                        inet_ntoa( cp->co_remote_address.sin_addr ),
  831. X                                        ntohs( cp->co_remote_address.sin_port ) ) ;
  832. X    tabprint( fd, 1, "Alternative services = " ) ;
  833. X    for ( u = 0 ; u < cp->co_alternative_count ; u++ )
  834. X        Sprint( fd, " %s", SVC_ID( cp->co_alternatives[ u ] ) ) ;
  835. X    Sputchar( fd, '\n' ) ;
  836. X    if ( cp->co_alternative_count > 0 )
  837. X        tabprint( fd, 1, "next alternative service = %s\n",
  838. X                SVC_ID( cp->co_alternatives[ cp->co_next_alternative ] ) ) ;
  839. X}
  840. X
  841. END_OF_FILE
  842. if test 5909 -ne `wc -c <'xinetd/connection.c'`; then
  843.     echo shar: \"'xinetd/connection.c'\" unpacked with wrong size!
  844. fi
  845. # end of 'xinetd/connection.c'
  846. fi
  847. if test -f 'xinetd/ident.c' -a "${1}" != "-c" ; then 
  848.   echo shar: Will not clobber existing file \"'xinetd/ident.c'\"
  849. else
  850. echo shar: Extracting \"'xinetd/ident.c'\" \(6151 characters\)
  851. sed "s/^X//" >'xinetd/ident.c' <<'END_OF_FILE'
  852. X/*
  853. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  854. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  855. X * and conditions for redistribution.
  856. X */
  857. X
  858. Xstatic char RCSid[] = "$Id: ident.c,v 6.5 1993/06/06 00:25:40 panos Exp $" ;
  859. X
  860. X#include <sys/types.h>
  861. X#include <sys/socket.h>
  862. X#include <netinet/in.h>
  863. X#include <netdb.h>
  864. X#include <signal.h>
  865. X#include <syslog.h>
  866. X#include <setjmp.h>
  867. X#include <errno.h>
  868. X#include <fcntl.h>
  869. X#include <string.h>
  870. X#include <ctype.h>
  871. X
  872. X#include "str.h"
  873. X
  874. X#include "defs.h"
  875. X#include "sconst.h"
  876. X#include "server.h"
  877. X
  878. Xvoid msg() ;
  879. Xstatus_e write_buf() ;
  880. X
  881. X
  882. X#define BUFSIZE                    1024        /* RFC-1413 suggests 1000 */
  883. X
  884. X#define START_TIMER( t )        (void) alarm( t )
  885. X#define STOP_TIMER()                (void) alarm( 0 )
  886. X
  887. Xchar *inet_ntoa() ;
  888. X
  889. X
  890. Xstatic jmp_buf env ;
  891. X
  892. X
  893. XPRIVATE void sigalrm_handler()
  894. X{
  895. X    longjmp( env, 1 ) ;
  896. X}
  897. X
  898. X
  899. X/*
  900. X * This function always runs in a forked process.
  901. X */
  902. Xidresult_e log_remote_user( serp, timeout )
  903. X    struct server *serp ;
  904. X    unsigned timeout ;                /* in seconds */
  905. X{
  906. X    static char                buf[ BUFSIZE ] ;
  907. X    int                        cc ;
  908. X    struct sockaddr_in    sin_local ;
  909. X    struct sockaddr_in    sin_remote ;
  910. X    struct sockaddr_in    sin_contact ;
  911. X    unsigned                    local_port ;
  912. X    unsigned                    remote_port ;
  913. X    int                        sd ;
  914. X    int                        sin_len ;
  915. X    char                        *p ;
  916. X    char                        *func = "log_remote_user" ;
  917. X    PRIVATE char            *get_line() ;
  918. X    PRIVATE char            *verify_line() ;
  919. X
  920. X#ifndef NO_TIMERS
  921. X    /*
  922. X     * Although expiring timers are harmless, they still take time to process
  923. X     */
  924. X    STOP_TIMER() ;
  925. X#endif
  926. X
  927. X    if ( timeout && (int) signal( SIGALRM, sigalrm_handler ) == -1 )
  928. X    {
  929. X        msg( LOG_ERR, func, "signal: %m" ) ;
  930. X        return( IDR_ERROR ) ;
  931. X    }
  932. X
  933. X    /*
  934. X     * Determine local and remote addresses
  935. X     */
  936. X    sin_len = sizeof( sin_local ) ;
  937. X    if ( getsockname( SERVER_FD( serp ), SA( &sin_local ), &sin_len ) == -1 )
  938. X    {
  939. X        msg( LOG_ERR, func, "getsockname: %m" ) ;
  940. X        return( IDR_ERROR ) ;
  941. X    }
  942. X
  943. X    if ( ! conn_address( SERVER_CONNECTION( serp ) ) )
  944. X    {
  945. X        /*
  946. X         * This shouldn't happen since identification only works for
  947. X         * connection-based services.
  948. X         */
  949. X        msg( LOG_ERR, func, "connection has no address" ) ;
  950. X        return( IDR_ERROR ) ;
  951. X    }
  952. X
  953. X    sin_remote = *conn_address( SERVER_CONNECTION( serp ) ) ;
  954. X    local_port = ntohs( sin_local.sin_port ) ;
  955. X    remote_port = ntohs( sin_remote.sin_port ) ;
  956. X
  957. X    /*
  958. X     * Create a socket and set the close-on-exec flag on the descriptor.
  959. X     * We set the flag in case we are called as part of a successful
  960. X     * attempt to start a server (i.e. execve will follow).
  961. X     */
  962. X    sd = socket( AF_INET, SOCK_STREAM, 0 ) ;
  963. X    if ( sd == -1 )
  964. X    {
  965. X        msg( LOG_ERR, func, "socket creation: %m" ) ;
  966. X        return( IDR_ERROR ) ;
  967. X    }
  968. X    if ( fcntl( sd, F_SETFD, 1 ) == -1 )
  969. X    {
  970. X        msg( LOG_ERR, func, "fcntl F_SETFD: %m" ) ;
  971. X        (void) close( sd ) ;
  972. X        return( IDR_ERROR ) ;
  973. X    }
  974. X
  975. X    CLEAR( sin_contact ) ;
  976. X    sin_contact.sin_family = sin_remote.sin_family ;
  977. X    sin_contact.sin_addr = sin_remote.sin_addr ;
  978. X    sin_contact.sin_port = htons( IDENTITY_SERVICE_PORT ) ;
  979. X
  980. X    if ( timeout )
  981. X        if ( setjmp( env ) == 0 )
  982. X            START_TIMER( timeout ) ;
  983. X        else
  984. X            return( IDR_TIMEDOUT ) ;
  985. X
  986. X    if ( connect( sd, SA( &sin_contact ), sizeof( sin_contact ) ) == -1 )
  987. X    {
  988. X        if ( timeout )
  989. X            STOP_TIMER() ;
  990. X        return( IDR_NOSERVER ) ;
  991. X    }
  992. X
  993. X    cc = strx_nprint( buf, sizeof( buf ),
  994. X                                        "%d,%d\r\n", remote_port, local_port ) ;
  995. X    if ( write_buf( sd, buf, cc ) == FAILED )
  996. X    {
  997. X        if ( timeout )
  998. X            STOP_TIMER() ;
  999. X        return( IDR_ERROR ) ;
  1000. X    }
  1001. X
  1002. X    p = get_line( sd, buf, sizeof( buf ) ) ;
  1003. X
  1004. X    if ( timeout )
  1005. X        STOP_TIMER() ;
  1006. X
  1007. X    if ( p == NULL )
  1008. X        return( IDR_RESPERR ) ;
  1009. X    
  1010. X    /*
  1011. X     * Verify that the received line is OK
  1012. X     */
  1013. X    if ( ( p = verify_line( buf, local_port, remote_port ) ) == NULL )
  1014. X    {
  1015. X        msg( LOG_ERR, func, "Bad line received from identity server at %s: %s",
  1016. X                                        inet_ntoa( sin_remote.sin_addr ), buf ) ;
  1017. X        return( IDR_BADRESP ) ;
  1018. X    }
  1019. X
  1020. X    svc_logprint( SERVER_CONNSERVICE( serp ), USERID_ENTRY, "%s", p ) ;
  1021. X    return( IDR_OK ) ;
  1022. X}
  1023. X
  1024. X
  1025. XPRIVATE char *verify_line( line, local_port, remote_port )
  1026. X    char            *line ;
  1027. X    unsigned     local_port ;
  1028. X    unsigned     remote_port ;
  1029. X{
  1030. X    register char    *p ;
  1031. X    register char    *start = line ;
  1032. X
  1033. X    /*
  1034. X     * Verify port numbers
  1035. X     */
  1036. X    p = strchr( start, ',' ) ;
  1037. X    if ( p == NULL )
  1038. X        return( NULL ) ;
  1039. X    *p = NUL ;
  1040. X    if ( atoi( start ) != remote_port )
  1041. X        return( NULL ) ;
  1042. X    
  1043. X    start = p+1 ;
  1044. X    p = strchr( start, ':' ) ;
  1045. X    if ( p == NULL )
  1046. X        return( NULL ) ;
  1047. X    *p = NUL ;
  1048. X    if ( atoi( start ) != local_port )
  1049. X        return( NULL ) ;
  1050. X    
  1051. X    /*
  1052. X     * Look for the 'USERID' string
  1053. X     */
  1054. X    {
  1055. X        char *line_id = "USERID" ;
  1056. X        int line_id_len = strlen( line_id ) ;
  1057. X
  1058. X        start = p+1 ;
  1059. X        for ( p = start ; isspace( *p ) ; p++ ) ;
  1060. X        if ( *p == NUL )
  1061. X            return( NULL ) ;
  1062. X        start = p ;
  1063. X        if ( strncmp( start, line_id, line_id_len ) != 0 )
  1064. X            return( NULL ) ;
  1065. X        start += line_id_len ;        /* skip it */
  1066. X    }
  1067. X
  1068. X    for ( p = start ; isspace( *p ) ; p++ ) ;        /* skip any white-space */
  1069. X    if ( *p != ':' )
  1070. X        return( NULL ) ;
  1071. X    for ( p++ ; isspace( *p ) ; p++ ) ;
  1072. X    if ( *p == NUL )
  1073. X        return( NULL ) ;
  1074. X    return( p ) ;
  1075. X}
  1076. X
  1077. X    
  1078. X
  1079. X/*
  1080. X * Get a line terminated by CR-LF.
  1081. X * Replace the CR-LF with NUL.
  1082. X */
  1083. XPRIVATE char *get_line( sd, buf, bufsize )
  1084. X    int                sd ;
  1085. X    register char    *buf ;
  1086. X    unsigned         bufsize ;
  1087. X{
  1088. X    int                size ;
  1089. X    register int    cc ;
  1090. X    register char    *p ;
  1091. X    register char    *s ;
  1092. X    char                *func = "get_line" ;
  1093. X
  1094. X    for ( p = buf, size = bufsize ; size > 0 ; p += cc, size -= cc )
  1095. X    {
  1096. X        cc = read( sd, p, size ) ;
  1097. X        if ( cc == -1 )
  1098. X            if ( errno == EINTR )
  1099. X            {
  1100. X                cc = 0 ;
  1101. X                continue ;
  1102. X            }
  1103. X            else
  1104. X            {
  1105. X                msg( LOG_ERR, func, "read: %m" ) ;
  1106. X                return( CHAR_NULL ) ;
  1107. X            }
  1108. X        for ( s = p ; s < p + cc ; s++ )
  1109. X            if ( *s == '\n' && s != buf && s[-1] == '\r' )
  1110. X            {
  1111. X                s[-1] = NUL ;
  1112. X                return( buf ) ;
  1113. X            }
  1114. X    }
  1115. X    msg( LOG_ERR, func, "Too much input from identity server" ) ;
  1116. X    return( CHAR_NULL ) ;
  1117. X}
  1118. X
  1119. X
  1120. Xchar *idresult_explain( result )
  1121. X    idresult_e result ;
  1122. X{
  1123. X    char *reason = "UNKNOWN" ;
  1124. X
  1125. X    switch ( result )
  1126. X    {
  1127. X        case IDR_OK:
  1128. X            reason = "no error" ;
  1129. X            break ;
  1130. X
  1131. X        case IDR_NOSERVER:
  1132. X            reason = "no server" ;
  1133. X            break ;
  1134. X
  1135. X        case IDR_TIMEDOUT:
  1136. X            reason = "timeout" ;
  1137. X            break ;
  1138. X        
  1139. X        case IDR_ERROR:
  1140. X            reason = "system error" ;
  1141. X            break ;
  1142. X        
  1143. X        case IDR_RESPERR:
  1144. X            reason = "error while receiving response" ;
  1145. X            break ;
  1146. X        
  1147. X        case IDR_BADRESP:
  1148. X            reason = "bad response" ;
  1149. X            break ;
  1150. X    }
  1151. X    return( reason ) ;
  1152. X}
  1153. X
  1154. END_OF_FILE
  1155. if test 6151 -ne `wc -c <'xinetd/ident.c'`; then
  1156.     echo shar: \"'xinetd/ident.c'\" unpacked with wrong size!
  1157. fi
  1158. # end of 'xinetd/ident.c'
  1159. fi
  1160. echo shar: End of archive 14 \(of 31\).
  1161. cp /dev/null ark14isdone
  1162. MISSING=""
  1163. 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
  1164.     if test ! -f ark${I}isdone ; then
  1165.     MISSING="${MISSING} ${I}"
  1166.     fi
  1167. done
  1168. if test "${MISSING}" = "" ; then
  1169.     echo You have unpacked all 31 archives.
  1170.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1171. else
  1172.     echo You still need to unpack the following archives:
  1173.     echo "        " ${MISSING}
  1174. fi
  1175. ##  End of shell archive.
  1176. exit 0
  1177.