2 * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
3 * All rights reserved. The file named COPYRIGHT specifies the terms
4 * and conditions for redistribution.
29 static int filelog_init(xlog_s *, va_list) ;
30 static void filelog_fini(xlog_s *) ;
31 static int filelog_control(xlog_s *, xlog_cmd_e, va_list) ;
32 static int filelog_write(xlog_s *, const char buf[], int, int, va_list) ;
33 static int filelog_parms(xlog_e, va_list) ;
34 static int limit_checks(const xlog_s *) ;
36 struct xlog_ops __xlog_filelog_ops =
46 static int filelog_init( xlog_s *xp, va_list ap )
49 struct filelog_s *flp ;
53 filename = va_arg(ap, char *);
54 flags = va_arg(ap, int);
56 flp = NEW( struct filelog_s ) ;
58 return( XLOG_ENOMEM ) ;
60 if ( flags & O_CREAT )
61 fd = open( filename, flags, va_arg( ap, int ) ) ;
63 fd = open( filename, flags ) ;
68 return( XLOG_EOPEN ) ;
71 FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
72 (void) Sbuftype( fd, SIO_LINEBUF ) ;
74 flp->fl_state = FL_OPEN ;
76 return( XLOG_ENOERROR ) ;
80 static void filelog_fini( xlog_s *xp )
82 struct filelog_s *flp = FILELOG( xp ) ;
84 if ( flp->fl_state != FL_CLOSED )
86 (void) Sclose( flp->fl_fd ) ;
87 flp->fl_state = FL_CLOSED ;
94 static int filelog_control( xlog_s *xp, xlog_cmd_e cmd, va_list ap )
97 struct filelog_s *flp = FILELOG( xp ) ;
98 int status = XLOG_ENOERROR ;
100 if ( flp->fl_state == FL_ERROR )
101 return( flp->fl_error ) ;
106 if ( flp->fl_state == FL_OPEN )
107 *va_arg( ap, int * ) = flp->fl_fd ;
109 status = XLOG_ENOERROR ;
113 flp->fl_soft_limit = va_arg( ap, unsigned ) ;
114 flp->fl_hard_limit = va_arg( ap, unsigned ) ;
115 flp->fl_issued_warning = FALSE ;
116 FILELOG_ENABLE_SIZE_CONTROL( flp ) ;
117 flp->fl_state = FL_OPEN ;
121 if ( ! FILELOG_SIZE_CONTROL( flp ) )
123 if ( fstat( flp->fl_fd, &st ) == -1 )
125 FILELOG_DISABLE_SIZE_CONTROL( flp ) ;
126 flp->fl_state = FL_ERROR ;
127 flp->fl_error = status = XLOG_EFSTAT ;
131 flp->fl_size = st.st_size ;
132 if ( flp->fl_size > flp->fl_soft_limit )
133 status = limit_checks( xp ) ;
150 static int limit_checks( const xlog_s *xp )
152 struct filelog_s *flp = FILELOG( xp ) ;
155 if ( ! flp->fl_issued_warning )
157 if ( xp->xl_use != NULL )
158 xlog_write( (xlog_h) xp->xl_use, buf,
159 strx_nprint( buf, sizeof( buf ),
160 "soft limit exceeded on '%s'", xp->xl_id ),
161 XLOG_NOFLAGS, LOG_ALERT ) ;
162 flp->fl_issued_warning = TRUE ;
165 if ( flp->fl_size <= flp->fl_hard_limit )
166 return( XLOG_ENOERROR ) ;
168 if ( xp->xl_use != NULL )
169 xlog_write( (xlog_h) xp->xl_use, buf,
170 strx_nprint( buf, sizeof( buf ),
171 "hard limit exceeded on '%s'; log closed", xp->xl_id ),
172 XLOG_NOFLAGS, LOG_ALERT ) ;
173 flp->fl_state = FL_ERROR ;
174 return( XLOG_ESIZE ) ;
178 static int filelog_write( xlog_s *xp, const char buf[], int len, int flags,
181 struct filelog_s *flp = FILELOG( xp ) ;
182 int action_flags = ( xp->xl_flags | flags ) ;
184 int percent_m_pos = 0 ;
187 time_t current_time ;
190 if ( flp->fl_state != FL_OPEN )
191 return( flp->fl_error ) ;
193 (void) time( ¤t_time ) ;
194 tmp = localtime( ¤t_time ) ;
195 cc = Sprint( flp->fl_fd, "%02d/%d/%d@%02d:%02d:%02d",
196 tmp->tm_year%100, tmp->tm_mon+1, tmp->tm_mday,
197 tmp->tm_hour, tmp->tm_min, tmp->tm_sec ) ;
203 if ( action_flags & XLOG_PRINT_ID )
205 cc = Sprint( flp->fl_fd, " %s", xp->xl_id ) ;
206 if ( cc == SIO_ERR ) {
207 flp->fl_size += msglen ;
213 if ( action_flags & XLOG_PRINT_PID )
215 cc = Sprint( flp->fl_fd, "[%d]", getpid() ) ;
216 if ( cc == SIO_ERR ) {
217 flp->fl_size += msglen ;
223 cc = Sprint( flp->fl_fd, ": " ) ;
224 if ( cc == SIO_ERR ) {
225 flp->fl_size += msglen ;
230 if ( ( action_flags & XLOG_NO_ERRNO ) ||
231 ( percent_m_pos = __xlog_add_errno( buf, len ) ) == -1 )
233 cc = Swrite( flp->fl_fd, buf, len ) ;
234 if ( cc == SIO_ERR ) {
235 flp->fl_size += msglen ;
242 char errno_buf[ 100 ] ;
243 unsigned size = sizeof( errno_buf ) ;
247 * The reason for the repetition of "msglen += cc ;" is that
248 * in the future we may want to check cc for SIO_ERR
250 ep = __xlog_explain_errno( errno_buf, &size ) ;
251 cc = Swrite( flp->fl_fd, buf, percent_m_pos ) ;
252 if ( cc == SIO_ERR ) {
253 flp->fl_size += msglen ;
257 cc = Swrite( flp->fl_fd, ep, size ) ;
258 if ( cc == SIO_ERR ) {
259 flp->fl_size += msglen ;
263 cc = Swrite( flp->fl_fd, buf+percent_m_pos+2,
264 len-percent_m_pos-2 ) ;
265 if ( cc == SIO_ERR ) {
266 flp->fl_size += msglen ;
272 * Writing a newline will cause a buffer flush since we asked for
273 * line-buffered output
275 if ( Sputchar( flp->fl_fd, '\n' ) != SIO_ERR )
279 * NOTE: we don't check if XLOG_NO_SIZECHECK is set in xp->xl_flags
280 * because size control is off by default and in order to
281 * be enabled XLOG_LIMITS must be used which overrides xp->xl_flags
283 if ( ! FILELOG_SIZE_CONTROL( flp ) || ( flags & XLOG_NO_SIZECHECK ) )
284 return( XLOG_ENOERROR ) ;
286 flp->fl_size += msglen ;
287 if ( flp->fl_size <= flp->fl_soft_limit ||
288 ( status = limit_checks( xp ) ) == XLOG_ENOERROR )
289 return( XLOG_ENOERROR ) ;
291 flp->fl_state = FL_SIZE ;
296 static int filelog_parms( xlog_e type, va_list ap)
298 return( XLOG_ENOERROR ) ;