home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / xinetd / xinetd.2.0.6 / internals.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-22  |  8.1 KB  |  309 lines

  1. /*
  2.  * (c) Copyright 1992 by Panagiotis Tsirigotis
  3.  * All rights reserved.  The file named COPYRIGHT specifies the terms 
  4.  * and conditions for redistribution.
  5.  */
  6.  
  7. static char RCSid[] = "$Id: internals.c,v 5.1 1992/11/01 00:01:21 panos Exp $" ;
  8.  
  9. #include <sys/types.h>
  10. #include <signal.h>
  11. #include <time.h>
  12. #include <fcntl.h>
  13. #include <syslog.h>
  14.  
  15. #include "sio.h"
  16.  
  17. #include "config.h"
  18. #include "service.h"
  19. #include "server.h"
  20. #include "state.h"
  21. #include "conf.h"
  22.  
  23. extern char program_version[] ;
  24.  
  25. void msg() ;
  26.  
  27. time_t time() ;
  28.  
  29. void dump_internal_state()
  30. {
  31.     int dump_fd ;
  32.     char *dump_file = DUMP_FILE ;
  33.     time_t current_time ;
  34.     register int fd ;
  35.     register unsigned u ;
  36.     char *func = "dump_internal_state" ;
  37.  
  38.     dump_fd = open( dump_file, O_WRONLY + O_CREAT + O_APPEND, DUMP_FILE_MODE ) ;
  39.     if ( dump_fd == -1 )
  40.     {
  41.         msg( LOG_ERR, func, "failed to open %s: %m", dump_file ) ;
  42.         return ;
  43.     }
  44.     Sbuftype( dump_fd, SIO_LINEBUF ) ;
  45.  
  46.     /*
  47.      * Print the program name, version, and timestamp.
  48.      * Note that the program_version variable contains the program name.
  49.      */
  50.     (void) time( ¤t_time ) ;
  51.     Sprint( dump_fd, "INTERNAL STATE DUMP: %s\n", program_version ) ;
  52.     Sprint( dump_fd, "Current time: %s\n", ctime( ¤t_time ) ) ;
  53.  
  54.     /*
  55.      * Dump the current configuration (services + defaults)
  56.      */
  57.     Sprint( dump_fd, "Services + defaults:\n" ) ;
  58.     dump_current_configuration( dump_fd ) ;
  59.  
  60.     /*
  61.      * Dump the server table
  62.      */
  63.     Sprint( dump_fd, "Server table dump:\n" ) ;
  64.     for ( u = 0 ; u < pset_count( ps.rws.servers ) ; u++ )
  65.         server_dump( SERP( pset_pointer( ps.rws.servers, u ) ), dump_fd ) ;
  66.     Sputchar( dump_fd, '\n' ) ;
  67.  
  68.     /*
  69.      * Dump the retry_table
  70.      */
  71.     Sprint( dump_fd, "Retry table dump:\n" ) ;
  72.     for ( u = 0 ; u < pset_count( ps.rws.retries ) ; u++ )
  73.         server_dump( SERP( pset_pointer( ps.rws.retries, u ) ), dump_fd ) ;
  74.     Sputchar( dump_fd, '\n' ) ;
  75.  
  76.     /*
  77.      * Dump the socket mask
  78.      */
  79.     Sprint( dump_fd, "Socket mask:" ) ;
  80.     for ( fd = 0 ; fd < ps.ros.max_descriptors ; fd++ )
  81.         if ( FD_ISSET( fd, &ps.rws.socket_mask ) )
  82.             Sprint( dump_fd, " %d", fd ) ;
  83.     Sputchar( dump_fd, '\n' ) ;
  84.     Sprint( dump_fd, "mask_max = %d\n", ps.rws.mask_max ) ;
  85.     Sputchar( dump_fd, '\n' ) ;
  86.  
  87.     Sprint( dump_fd, "active_services = %d\n", ps.rws.active_services ) ;
  88.     Sprint( dump_fd, "available_services = %d\n", ps.rws.available_services ) ;
  89.     Sprint( dump_fd, "descriptors_free = %d\n", ps.rws.descriptors_free ) ;
  90.     Sprint( dump_fd, "running_servers = %d\n", pset_count( ps.rws.servers ) ) ;
  91.     Sprint( dump_fd, "Logging service = %s\n",
  92.                 LOG_SERVICE( ps ) != NULL ? "enabled" : "not enabled" ) ;
  93.     Sprint( dump_fd, "Shutdown service = %s\n",
  94.                 SHUTDOWN_SERVICE( ps ) != NULL ? "enabled" : "not enabled" ) ;
  95.     Sputchar( dump_fd, '\n' ) ;
  96.  
  97.     Sprint( dump_fd, "max_descriptors = %d\n", ps.ros.max_descriptors ) ;
  98.     Sprint( dump_fd, "process_limit = %d\n", ps.ros.process_limit ) ;
  99.     Sprint( dump_fd, "config_file = %s\n", ps.ros.config_file ) ;
  100.     if ( debug.on )
  101.         Sprint( dump_fd, "debug_fd = %d\n", debug.fd ) ;
  102.     Sputchar( dump_fd, '\n' ) ;
  103.  
  104.     Sprint( dump_fd, "END OF DUMP\n\n" ) ;
  105.     Sclose( dump_fd ) ;
  106.  
  107.     msg( LOG_INFO, func, "generated state dump in file %s", dump_file ) ;
  108. }
  109.  
  110.  
  111.  
  112.  
  113. void consistency_check()
  114. {
  115.     register int fd ;
  116.     fd_set socket_mask_copy ;
  117.     register unsigned u ;
  118.     unsigned total_running_servers = 0 ;
  119.     unsigned total_retry_servers = 0 ;
  120.     unsigned error_count = 0 ;
  121.     int errors ;
  122.     bool_int service_count_check_failed = FALSE ;
  123.     char *func = "consistency_check" ;
  124.     unsigned thread_check() ;
  125.     unsigned get_server_count() ;
  126.  
  127.     socket_mask_copy = ps.rws.socket_mask ;
  128.  
  129.     for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
  130.     {
  131.         register struct service *sp = SP( pset_pointer( SERVICES( ps ), u ) ) ;
  132.         register struct service_data *sdp = SDATA( sp ) ;
  133.         struct service_config *scp = CONF( sp ) ;
  134.         unsigned running_servers = get_server_count( ps.rws.servers, sp ) ;
  135.         unsigned retry_servers = get_server_count( ps.rws.retries, sp ) ;
  136.  
  137.         switch ( sp->state )
  138.         {
  139.             case SVC_NOT_STARTED:
  140.                 msg( LOG_ERR, func, "service %s not started", scp->id ) ;
  141.                 error_count++ ;
  142.                 break ;
  143.             
  144.             case SVC_ACTIVE:
  145.             case SVC_DISABLED:
  146.                 FD_CLR( sdp->service_fd, &socket_mask_copy ) ;
  147.                 error_count += thread_check( sp, running_servers, retry_servers ) ;
  148.  
  149.                 errors = service_count_check( sp, running_servers, retry_servers ) ;
  150.                 if ( ! errors && ! service_count_check_failed )
  151.                 {
  152.                     total_retry_servers += retry_servers ;
  153.                     total_running_servers += running_servers ;
  154.                 }
  155.                 if ( errors )
  156.                 {
  157.                     service_count_check_failed = TRUE ;
  158.                     error_count += errors ;
  159.                 }
  160.  
  161.                 if ( sp->state == SVC_DISABLED && sdp->running_servers == 0 )
  162.                 {
  163.                     msg( LOG_ERR, func,
  164.                         "disabled service %s has 0 running servers\n", scp->id ) ;
  165.                     error_count++ ;
  166.                     continue ;
  167.                 }
  168.                 break ;
  169.             
  170.             default:
  171.                 msg( LOG_ERR, func,
  172.                     "bad state for service %s: %d", scp->id, (int)sp->state ) ;
  173.                 error_count++ ;
  174.         }
  175.     }
  176.  
  177.     if ( ! service_count_check_failed )
  178.     {
  179.         if ( total_running_servers != pset_count( ps.rws.servers ) )
  180.         {
  181.             msg( LOG_ERR, func,
  182.                 "total running servers (%d) != number of running servers (%d)",
  183.                     total_running_servers, pset_count( ps.rws.servers ) ) ;
  184.             error_count++ ;
  185.         }
  186.         if ( total_retry_servers != pset_count( ps.rws.retries ) )
  187.         {
  188.             msg( LOG_ERR, func,
  189.                 "total retry servers (%d) != number of retry servers (%d)",
  190.                     total_retry_servers, pset_count( ps.rws.retries ) ) ;
  191.             error_count++ ;
  192.         }
  193.     }
  194.  
  195.     /*
  196.      * Check if there are any descriptors set in socket_mask_copy
  197.      */
  198.     for ( fd = 0 ; fd < ps.ros.max_descriptors ; fd++ )
  199.         if ( FD_ISSET( fd, &socket_mask_copy ) )
  200.         {
  201.             msg( LOG_ERR, func,
  202.                 "descriptor %d set in socket mask but there is no service for it",
  203.                     fd ) ;
  204.             error_count++ ;
  205.         }
  206.  
  207.     if ( error_count == 0 )
  208.         msg( LOG_INFO, func, "Consistency check passed" ) ;
  209.     else
  210.         msg( LOG_INFO, func,
  211.                 "Consistency check detected %d errors", error_count ) ;
  212. }
  213.  
  214.  
  215. PRIVATE int service_count_check( sp, running_servers, retry_servers )
  216.     register 
  217.     struct service *sp ;
  218.     unsigned running_servers ;
  219.     unsigned retry_servers ;
  220. {
  221.     register struct service_data *sdp = SDATA( sp ) ;
  222.     register char *sid = CONF( sp )->id ;
  223.     int error_count = 0 ;
  224.     char *func = "service_count_check" ;
  225.  
  226.     if ( sdp->running_servers != running_servers )
  227.     {
  228.         msg( LOG_ERR, func,
  229.             "service %s: actual running servers = %d, known running servers = %d",
  230.                 sid, running_servers, sdp->running_servers ) ;
  231.         error_count++ ;
  232.     }
  233.     if ( sdp->retry_servers != retry_servers )
  234.     {
  235.         msg( LOG_ERR, func,
  236.             "service %s: actual retry servers = %d, known retry servers = %d",
  237.                 sid, retry_servers, sdp->retry_servers ) ;
  238.         error_count++ ;
  239.     }
  240.     return( error_count ) ;
  241. }
  242.  
  243.  
  244.  
  245. /*
  246.  * If the service is single-threaded:
  247.  *            if the descriptor is set in the socket mask, there must
  248.  *            be a server running (or to be retried)
  249.  *    If the service is multi-threaded:
  250.  *            the descriptor must be always set
  251.  */
  252. PRIVATE unsigned thread_check( sp, running_servers, retry_servers )
  253.     struct service *sp ;
  254.     unsigned running_servers ;
  255.     unsigned retry_servers ;
  256. {
  257.     struct service_config *scp = CONF( sp ) ;
  258.     struct service_data *sdp = SDATA( sp ) ;
  259.     unsigned error_count = 0 ;
  260.     char *func = "thread_check" ;
  261.  
  262.     if ( scp->wait == YES )
  263.     {
  264.         bool_int has_servers = ( running_servers + retry_servers > 0 ) ;
  265.  
  266.         if ( has_servers && FD_ISSET( sdp->service_fd, &ps.rws.socket_mask ) )
  267.         {
  268.             msg( LOG_ERR, func,
  269. "Active single-threaded service %s: server running, descriptor set",
  270.                             scp->id ) ;
  271.             error_count++ ;
  272.         }
  273.         if ( !has_servers && !FD_ISSET( sdp->service_fd, &ps.rws.socket_mask ) )
  274.         {
  275.             msg( LOG_ERR, func,
  276. "Active single-threaded service %s: no server running, descriptor not set",
  277.                 scp->id ) ;
  278.             error_count++ ;
  279.         }
  280.     }
  281.     else
  282.         if ( ! FD_ISSET( sdp->service_fd, &ps.rws.socket_mask ) )
  283.         {
  284.             msg( LOG_ERR, func,
  285. "Active multi-threaded service %s: descriptor not set", scp->id ) ;
  286.             error_count++ ;
  287.         }
  288.     return( error_count ) ;
  289. }
  290.  
  291.  
  292.  
  293. /*
  294.  * Count the number of servers for the specified service.
  295.  */
  296. PRIVATE unsigned get_server_count( servers, sp )
  297.     pset_h servers ;
  298.     register struct service *sp ;
  299. {
  300.     register unsigned u ;
  301.     register unsigned count = 0 ;
  302.  
  303.     for ( u = 0 ; u < pset_count( servers ) ; u++ )
  304.         if ( SERP( pset_pointer( servers, u ) )->sp == sp )
  305.             count++ ;
  306.     return( count ) ;
  307. }
  308.  
  309.