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 #include "config.h"
8 #include <stdlib.h>
9 #include <stdarg.h>
10
11 #include "xlog.h"
12 #include "impl.h"
13
14 extern struct xlog_ops __xlog_filelog_ops ;
15 #ifndef NO_SYSLOG
16 extern struct xlog_ops __xlog_syslog_ops ;
17 #endif
18
19 struct lookup_table
20 {
21 struct xlog_ops *ops ;
22 xlog_e type ;
23 } ;
24
25 static struct lookup_table ops_lookup_table[] =
26 {
27 { &__xlog_filelog_ops, XLOG_FILELOG },
28 #ifndef NO_SYSLOG
29 { &__xlog_syslog_ops, XLOG_SYSLOG },
30 #endif
31 { NULL, 0 }
32 } ;
33
34
35 #define CALLBACK( xp, status ) \
36 if ( (xp)->xl_callback ) \
37 (*(xp)->xl_callback)( (xlog_h)(xp), status, (xp)->xl_callback_arg )
38
39
40 static void xlog_link( xlog_s *client, xlog_s *server ) ;
41 static void xlog_unlink( xlog_s *xp ) ;
42
43
xlog_ops_lookup(xlog_e type)44 static struct xlog_ops *xlog_ops_lookup( xlog_e type )
45 {
46 struct lookup_table *ltp ;
47
48 for ( ltp = &ops_lookup_table[ 0 ] ; ltp->ops ; ltp++ )
49 if ( ltp->type == type )
50 break ;
51 return( ltp->ops ) ;
52 }
53
54
55 /* VARARGS3 */
xlog_create(xlog_e type,const char * id,int flags,...)56 xlog_h xlog_create( xlog_e type, const char *id, int flags, ... )
57 {
58 xlog_s *xp ;
59 va_list ap ;
60 struct xlog_ops *xops ;
61 int status ;
62
63 if ( ( xp = NEW( xlog_s ) ) == NULL )
64 return( NULL ) ;
65
66 if ( id == NULL || ( xp->xl_id = __xlog_new_string( id ) ) == NULL )
67 {
68 free( xp ) ;
69 return( NULL ) ;
70 }
71
72 xops = xlog_ops_lookup( type ) ;
73
74 if ( xops != NULL )
75 {
76 va_start( ap, flags ) ;
77 xp->xl_ops = xops ;
78 status = XL_INIT( xp, ap ) ;
79 va_end( ap ) ;
80
81 if ( status == XLOG_ENOERROR )
82 {
83 xp->xl_flags = flags ;
84 xp->xl_type = type ;
85 xp->xl_clients = XLOG_NULL ;
86 xp->xl_use = XLOG_NULL ;
87 return( (xlog_h) xp ) ;
88 }
89 }
90
91 free( xp->xl_id ) ;
92 free( xp ) ;
93 return( NULL ) ;
94 }
95
96
97
xlog_link(xlog_s * client,xlog_s * server)98 static void xlog_link( xlog_s *client, xlog_s *server )
99 {
100 client->xl_use = server ;
101 if ( server == NULL )
102 return ;
103
104 if ( server->xl_clients == XLOG_NULL )
105 {
106 INIT_LINKS( client, xl_other_users ) ;
107 server->xl_clients = client ;
108 }
109 else
110 LINK( server, client, xl_other_users ) ;
111 }
112
113
xlog_unlink(xlog_s * xp)114 static void xlog_unlink( xlog_s *xp )
115 {
116 xlog_s *server = xp->xl_use ;
117
118 /*
119 * Step 1: remove from server chain
120 */
121 if ( server != XLOG_NULL )
122 {
123 if ( server->xl_clients == xp )
124 if ( NEXT( xp, xl_other_users ) == xp )
125 server->xl_clients = XLOG_NULL ;
126 else
127 server->xl_clients = NEXT( xp, xl_other_users ) ;
128 else
129 UNLINK( xp, xl_other_users ) ;
130 }
131
132 /*
133 * Step 2: If we have users, clear their link to us.
134 */
135 if ( xp->xl_clients != NULL )
136 {
137 xlog_s *xp2 = xp->xl_clients ;
138
139 do
140 {
141 xp2->xl_use = XLOG_NULL ;
142 xp2 = NEXT( xp2, xl_other_users ) ;
143 }
144 while ( xp2 != xp->xl_clients ) ;
145 }
146 }
147
148
xlog_flags(xlog_s * xp,xlog_cmd_e cmd,...)149 static void xlog_flags( xlog_s *xp, xlog_cmd_e cmd, ... )
150 {
151 va_list ap;
152 int flag;
153 int old_value;
154 int *valp;
155
156 va_start(ap, cmd);
157 flag = va_arg( ap, int );
158 old_value = ((xp->xl_flags & flag) != 0);
159 valp = va_arg( ap, int * );
160 va_end(ap);
161 if ( cmd == XLOG_SETFLAG ) {
162 if ( *valp )
163 xp->xl_flags |= flag ;
164 else
165 xp->xl_flags &= ~flag ;
166 }
167 *valp = old_value ;
168 }
169
170
xlog_destroy(xlog_h pxlog)171 void xlog_destroy( xlog_h pxlog )
172 {
173 xlog_s *xp = XP( pxlog ) ;
174
175 xlog_unlink( xp ) ;
176 XL_FINI( xp ) ;
177 free( xp->xl_id ) ;
178 free( xp ) ;
179 }
180
181
182 /* VARARGS4 */
xlog_write(xlog_h pxlog,const char buf[],int len,int flags,...)183 void xlog_write( xlog_h pxlog, const char buf[], int len, int flags, ... )
184 {
185 xlog_s *xp = XP( pxlog ) ;
186 va_list ap ;
187 int status ;
188
189 va_start( ap, flags ) ;
190 status = XL_WRITE( xp, buf, len, flags, ap ) ;
191 va_end( ap ) ;
192
193 if ( status != XLOG_ENOERROR )
194 {
195 CALLBACK( xp, status ) ;
196 }
197 }
198
199
200 /* VARARGS2 */
xlog_control(xlog_h pxlog,xlog_cmd_e cmd,...)201 int xlog_control( xlog_h pxlog, xlog_cmd_e cmd, ... )
202 {
203 va_list ap ;
204 xlog_s *xp = XP( pxlog ) ;
205 int status = XLOG_ENOERROR ;
206
207 va_start( ap, cmd ) ;
208
209 switch ( cmd )
210 {
211 case XLOG_LINK:
212 xlog_unlink( xp ) ;
213 xlog_link( xp, va_arg( ap, xlog_s * ) ) ;
214 xp->xl_callback_arg = va_arg( ap, void * ) ;
215 break ;
216
217 case XLOG_CALLBACK:
218 xp->xl_callback = va_arg( ap, voidfunc ) ;
219 xp->xl_callback_arg = va_arg( ap, void * );
220 break ;
221
222 case XLOG_GETFLAG:
223 case XLOG_SETFLAG:
224 xlog_flags( xp, cmd, ap ) ;
225 break ;
226
227 default:
228 status = XL_CONTROL( xp, cmd, ap ) ;
229 }
230
231 va_end( ap ) ;
232
233 return( status ) ;
234 }
235
236
xlog_parms(xlog_e type,...)237 int xlog_parms( xlog_e type, ... )
238 {
239 va_list ap ;
240 int status ;
241
242 va_start( ap, type ) ;
243 switch ( type )
244 {
245 #ifndef NO_SYSLOG
246 case XLOG_SYSLOG:
247 status = (*__xlog_syslog_ops.parms)( type, ap ) ;
248 break ;
249 #endif
250 case XLOG_FILELOG:
251 status = (*__xlog_filelog_ops.parms)( type, ap ) ;
252 break ;
253
254 default:
255 status = XLOG_ENOERROR ;
256 }
257 va_end( ap ) ;
258 return( status ) ;
259 }
260
261