home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / xinetd / xlog.1.0.9 / filelog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-07  |  5.4 KB  |  263 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: filelog.c,v 1.8 1992/11/24 20:49:23 panos Exp $" ;
  8.  
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <varargs.h>
  12. #include <syslog.h>
  13. #include <fcntl.h>
  14. #include <time.h>
  15.  
  16. #include "sio.h"
  17.  
  18. #include "xlog.h"
  19. #include "impl.h"
  20. #include "filelog.h"
  21.  
  22. PRIVATE int filelog_init() ;
  23. PRIVATE void filelog_fini() ;
  24. PRIVATE int filelog_control() ;
  25. PRIVATE int filelog_write() ;
  26. PRIVATE int filelog_parms() ;
  27. PRIVATE int limit_checks() ;
  28.  
  29. struct xlog_ops __xlog_filelog_ops = 
  30.     {
  31.         filelog_init,
  32.         filelog_fini,
  33.         filelog_write,
  34.         filelog_control,
  35.         filelog_parms
  36.     } ;
  37.  
  38. char *malloc() ;
  39.  
  40.  
  41. PRIVATE int filelog_init( xp, ap )
  42.     xlog_s *xp ;
  43.     va_list ap ;
  44. {
  45.     int fd ;
  46.     char *filename = va_arg( ap, char * ) ;
  47.     int flags = va_arg( ap, int ) ;
  48.     struct filelog *flp ;
  49.  
  50.     flp = NEW( struct filelog ) ;
  51.     if ( flp == NULL )
  52.         return( XLOG_ENOMEM ) ;
  53.  
  54.     if ( flags & O_CREAT )
  55.         fd = open( filename, flags, va_arg( ap, int ) ) ;
  56.     else
  57.         fd = open( filename, flags ) ;
  58.  
  59.     if ( fd == -1 )
  60.     {
  61.         FREE( flp ) ;
  62.         return( XLOG_EOPEN ) ;
  63.     }
  64.     
  65.     flp->fd = fd ;
  66.     FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
  67.     (void) Sbuftype( fd, SIO_LINEBUF ) ;
  68.     flp->state = FL_OPEN ;
  69.     xp->data = flp ;
  70.     return( XLOG_ENOERROR ) ;
  71. }
  72.  
  73.  
  74. PRIVATE void filelog_fini( xp )
  75.     xlog_s *xp ;
  76. {
  77.     struct filelog *flp = FILELOG( xp ) ;
  78.  
  79.     if ( flp->state != FL_CLOSED )
  80.     {
  81.         (void) close( FILELOG( xp )->fd ) ;
  82.         flp->state = FL_CLOSED ;
  83.     }
  84.     FREE( flp ) ;
  85.     xp->data = NULL ;
  86. }
  87.  
  88.  
  89.  
  90. PRIVATE int filelog_control( xp, cmd, ap )
  91.     xlog_s *xp ;
  92.     xlog_cmd_e cmd ;
  93.     va_list ap ;
  94. {
  95.     struct stat st ;
  96.     struct filelog *flp = FILELOG( xp ) ;
  97.     int status = XLOG_ENOERROR ;
  98.  
  99.     if ( flp->state == FL_ERROR )
  100.         return( flp->error ) ;
  101.  
  102.     switch ( cmd )
  103.     {
  104.         case XLOG_GETFD:
  105.             *va_arg( ap, int * ) = flp->fd ;
  106.             status = XLOG_ENOERROR ;
  107.             break ;
  108.  
  109.         case XLOG_LIMITS:
  110.             flp->soft_limit = va_arg( ap, unsigned ) ;
  111.             flp->hard_limit = va_arg( ap, unsigned ) ;
  112.             flp->issued_warning = FALSE ;
  113.             FILELOG_ENABLE_SIZE_CONTROL( flp ) ;
  114.             flp->state = FL_OPEN ;
  115.             /* FALL THROUGH */
  116.  
  117.         case XLOG_SIZECHECK:
  118.             if ( ! FILELOG_SIZE_CONTROL( flp ) )
  119.                 break ;
  120.             if ( fstat( flp->fd, &st ) == -1 )
  121.             {
  122.                 FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
  123.                 flp->state = FL_ERROR ;
  124.                 flp->error = XLOG_EFSTAT ;
  125.                 return( flp->error ) ;
  126.             }
  127.             flp->size = st.st_size ;
  128.             if ( flp->size > flp->soft_limit )
  129.                 status = limit_checks( xp ) ;
  130.             else
  131.                 status = XLOG_ENOERROR ;
  132.             break ;
  133.         
  134.         default:
  135.             status = XLOG_ENOERROR ;
  136.     }
  137.     return( status ) ;
  138. }
  139.  
  140.  
  141. PRIVATE int limit_checks( xp )
  142.     xlog_s *xp ;
  143. {
  144.     struct filelog *flp = FILELOG( xp ) ;
  145.     char buf[ 100 ] ;
  146.  
  147.     if ( ! flp->issued_warning )
  148.     {
  149.         if ( xp->use != NULL )
  150.             xlog_write( (xlog_h) xp->use, buf,
  151.                 strx_nprint( buf, sizeof( buf ),
  152.                                         "%s: soft limit exceeded", xp->id ),
  153.                     XLOG_NOFLAGS, LOG_ALERT ) ;
  154.         flp->issued_warning = TRUE ;
  155.     }
  156.  
  157.     if ( flp->size <= flp->hard_limit )
  158.         return( XLOG_ENOERROR ) ;
  159.     
  160.     if ( xp->use != NULL )
  161.         xlog_write( (xlog_h) xp->use, buf,
  162.             strx_nprint( buf, sizeof( buf ),
  163.                                     "%s: hard limit exceeded; log closed", xp->id ),
  164.                 XLOG_NOFLAGS, LOG_ALERT ) ;
  165.     flp->state = FL_ERROR ;
  166.     return( XLOG_ESIZE ) ;
  167. }
  168.  
  169.  
  170. PRIVATE int filelog_write( xp, buf, len, flags, ap )
  171.     xlog_s *xp ;
  172.     char buf[] ;
  173.     int len ;
  174.     int flags ;
  175.     va_list ap ;
  176. {
  177.     struct filelog *flp = FILELOG( xp ) ;
  178.     char *percent_m_pos ;
  179.     int cc ;
  180.     int msglen = 0 ;
  181.     int status ;
  182.     int action_flags = ( xp->flags | flags ) ;
  183.  
  184.     if ( action_flags & XLOG_PRINT_TIMESTAMP )
  185.     {
  186.         time_t current_time ;
  187.         struct tm *tmp ;
  188.         time_t time() ;
  189.  
  190.         (void) time( ¤t_time ) ;
  191.         tmp = localtime( ¤t_time ) ;
  192.         cc = Sprint( flp->fd, "%d/%d/%d@%02d:%02d:%02d ",
  193.                                 tmp->tm_year, tmp->tm_mon+1, tmp->tm_mday,
  194.                                 tmp->tm_hour, tmp->tm_min, tmp->tm_sec ) ;
  195.         msglen += cc ;
  196.     }
  197.  
  198.     if ( action_flags & XLOG_PRINT_ID )
  199.     {
  200.         cc = Sprint( flp->fd, "%s ", xp->id ) ;
  201.         msglen += cc ;
  202.     }
  203.  
  204.     if ( action_flags & XLOG_PRINT_PID )
  205.     {
  206.         cc = Sprint( flp->fd, "[%d] ", getpid() ) ;
  207.         msglen += cc ;
  208.     }
  209.  
  210.     if ( ( action_flags & XLOG_NO_ERRNO ) ||
  211.                         ( percent_m_pos = __xlog_add_errno( buf, len ) ) == NULL )
  212.     {
  213.         cc = Swrite( flp->fd, buf, len ) ;
  214.         msglen += cc ;
  215.     }
  216.     else
  217.     {
  218.         char errno_buf[ 100 ] ;
  219.         unsigned size = sizeof( errno_buf ) ;
  220.         int cc_before_errno = percent_m_pos - buf ;
  221.         char *ep ;
  222.  
  223.         /*
  224.          * The reason for the repetition of "msglen += cc ;" is that in the
  225.          * future we may want to check cc for SIO_ERR
  226.          */
  227.         ep = __xlog_explain_errno( errno_buf, &size ) ;
  228.         cc = Swrite( flp->fd, buf, cc_before_errno ) ;
  229.         msglen += cc ;
  230.         cc = Swrite( flp->fd, ep, (int)size ) ;
  231.         msglen += cc ;
  232.         cc = Swrite( flp->fd, percent_m_pos+2, len-cc_before_errno-2 ) ;
  233.         msglen += cc ;
  234.     }
  235.     Sputchar( flp->fd, '\n' ) ;
  236.     msglen++ ;
  237.     (void) Sflush( flp->fd ) ;
  238.  
  239.     /*
  240.      * NOTE: we don't check if XLOG_NO_SIZECHECK is set in xp->flags
  241.      *            because size control is off by default and in order to
  242.      *            be enabled XLOG_LIMITS must be used which overrides xp->flags
  243.      */
  244.     if ( ! FILELOG_SIZE_CONTROL( flp ) || ( flags & XLOG_NO_SIZECHECK ) )
  245.         return( XLOG_ENOERROR ) ;
  246.  
  247.     flp->size += msglen ;
  248.     if ( flp->size <= flp->soft_limit || 
  249.                     ( status = limit_checks( xp ) ) == XLOG_ENOERROR )
  250.         return( XLOG_ENOERROR ) ;
  251.     
  252.     flp->state = FL_SIZE ;
  253.     return( status ) ;
  254. }
  255.  
  256.  
  257. PRIVATE int filelog_parms( ap )
  258.     va_list ap ;
  259. {
  260.     return( XLOG_ENOERROR ) ;
  261. }
  262.  
  263.