Import upstream 2.3.14
[packages/xinetd.git] / libs / src / xlog / slog.c
1 /*
2  * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
3  * All rights reserved.  The file named COPYRIGHT specifies the terms 
4  * and conditions for redistribution.
5  */
6
7
8 #include "config.h"
9 #ifndef NO_SYSLOG
10 #include <syslog.h>
11 #endif
12
13 #include "xlog.h"
14 #include "impl.h"
15 #include "slog.h"
16 #include "str.h"
17 #include <stdarg.h>
18
19 #define MSGBUFSIZE         2048
20
21
22 static int syslog_init(xlog_s *, va_list) ;
23 static void syslog_fini(xlog_s *) ;
24 static int syslog_control(xlog_s *, xlog_cmd_e, va_list ) ;
25 static int syslog_write(xlog_s *, const char buf[], int , int , va_list ) ;
26 static int syslog_parms(xlog_e, va_list) ;
27
28 static struct syslog_parms parms =
29 {
30       0,
31 #ifndef NO_SYSLOG
32       LOG_PID + LOG_NOWAIT,
33       LOG_USER,
34 #else
35       0,
36       0,
37 #endif
38       "XLOG",
39 } ;
40
41
42 struct xlog_ops __xlog_syslog_ops =
43    {
44       syslog_init,
45       syslog_fini,
46       syslog_write,
47       syslog_control,
48       syslog_parms
49    } ;
50
51 #ifdef NO_SYSLOG
52
53 /*
54  * Notice that the following functions will never be invoked since
55  * the xlog_* functions will not call them. However, we need to define
56  * them so that we don't have any unresolved references; and we define 
57  * them without any arguments.
58  */
59 static void syslog()
60 {
61 }
62
63 static void openlog()
64 {
65 }
66
67 static void closelog()
68 {
69 }
70
71 #endif   /* NO_SYSLOG */
72
73
74 /*
75  * Expected arguments:
76  *      facility, level
77  */
78 static int syslog_init( xlog_s *xp, va_list ap )
79 {
80    struct syslog_parms   *slp = &parms ;
81    struct syslog_s                 *sp ;
82
83    sp = NEW( struct syslog_s ) ;
84    if ( sp == NULL )
85       return( XLOG_ENOMEM ) ;
86    sp->sl_facility = va_arg( ap, int ) ;
87    sp->sl_default_level = va_arg( ap, int ) ;
88    if ( slp->slp_n_xlogs++ == 0 )
89       openlog( slp->slp_ident, slp->slp_logopts, slp->slp_facility ) ;
90    xp->xl_data = sp ;
91    return( XLOG_ENOERROR ) ;
92 }
93
94
95 static void syslog_fini( xlog_s *xp )
96 {
97    if ( --parms.slp_n_xlogs == 0 )
98       closelog() ;
99    free( SYSLOG( xp ) ) ;
100    xp->xl_data = NULL ;
101 }
102
103
104 static int syslog_control( xlog_s *xp, xlog_cmd_e cmd, va_list ap )
105 {
106    switch ( cmd )
107    {
108       case XLOG_LEVEL:
109          SYSLOG( xp )->sl_default_level = va_arg( ap, int ) ;
110          break ;
111
112       case XLOG_FACILITY:
113          SYSLOG( xp )->sl_facility = va_arg( ap, int ) ;
114          break ;
115       
116       case XLOG_PREEXEC:
117          closelog() ;
118          break ;
119
120       case XLOG_POSTEXEC:
121          if ( parms.slp_n_xlogs )
122             openlog( parms.slp_ident, parms.slp_logopts, parms.slp_facility ) ;
123          break ;
124
125       /* These fall through ? */
126       case XLOG_LINK:
127       case XLOG_CALLBACK:
128       case XLOG_GETFLAG:
129       case XLOG_SETFLAG: 
130       case XLOG_SIZECHECK:
131       case XLOG_GETFD:
132       case XLOG_LIMITS:
133          break ;
134    }
135    return( XLOG_ENOERROR ) ;
136 }
137
138
139 static int syslog_write( xlog_s *xp, const char buf[], int len, int flags, va_list ap )
140 {
141    int   level ;
142    int   syslog_arg ;
143    char   prefix[ MSGBUFSIZE ] ;
144    int   prefix_size = sizeof( prefix ) ;
145    int   prefix_len = 0 ;
146    int   cc ;
147    int   percent_m_pos ;
148    int   action_flags = ( flags | xp->xl_flags ) ;
149
150    if ( flags & XLOG_SET_LEVEL )
151       level = va_arg( ap, int ) ;
152    else
153       level = SYSLOG( xp )->sl_default_level ;
154    syslog_arg = SYSLOG( xp )->sl_facility + level ;
155
156    if ( action_flags & XLOG_PRINT_ID )
157    {
158       cc = strx_nprint( &prefix[ prefix_len ], prefix_size, "%s: ",
159                      xp->xl_id ) ;
160       prefix_len += cc ;
161       prefix_size -= cc ;
162    }
163
164    if ( ( action_flags & XLOG_NO_ERRNO ) ||
165                   ( percent_m_pos = __xlog_add_errno( buf, len ) ) == -1 )
166       syslog( syslog_arg, "%.*s%.*s", prefix_len, prefix, len, buf ) ;
167    else
168    {
169       char *ep ;
170       char errno_buf[ 100 ] ;
171       unsigned size = sizeof( errno_buf ) ;
172       
173       ep = __xlog_explain_errno( errno_buf, &size ) ;
174       syslog( syslog_arg, "%.*s%.*s%.*s%.*s",
175             prefix_len, prefix,
176                percent_m_pos, buf,
177                   (int)size, ep,
178                      len - percent_m_pos - 2, buf + percent_m_pos + 2 ) ;
179    }
180    return( XLOG_ENOERROR ) ;
181 }
182
183
184 static int syslog_parms( xlog_e type, va_list ap )
185 {
186    char *id = NULL;
187
188    id = __xlog_new_string( va_arg( ap, char * ) );
189    if ( id == NULL )
190       return( XLOG_ENOMEM ) ;
191    parms.slp_ident = id ;
192    parms.slp_logopts = va_arg( ap, int ) ;
193    parms.slp_facility = va_arg( ap, int ) ;
194    return( XLOG_ENOERROR ) ;
195 }
196