spl->critical section conversion.
[dragonfly.git] / contrib / libpam / libpam / pam_log.c
1 /*
2  * pam_log.c -- PAM system logging
3  *
4  * $Id$
5  * $FreeBSD: src/contrib/libpam/libpam/pam_log.c,v 1.2.6.2 2001/06/11 15:28:12 markm Exp $
6  * $DragonFly: src/contrib/libpam/libpam/Attic/pam_log.c,v 1.2 2003/06/17 04:24:03 dillon Exp $
7  *
8  * $Log$
9  */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdarg.h>
14
15 #include "pam_private.h"
16
17 #ifdef __hpux
18 # include <stdio.h>
19 # include <syslog.h>
20 # ifdef __STDC__
21 #  ifndef __P
22 #   define __P(p)  p
23 #  endif /* __P */
24 #  include <stdarg.h>
25 #  define VA_LOCAL_DECL va_list ap;
26 #  define VA_START(f)   va_start(ap, f)
27 #  define VA_END        va_end(ap)
28 # else /* __STDC__ */
29 #  ifndef __P
30 #   define __P(p)  ()
31 #  endif /* __P */
32 #  include <varargs.h>
33 #  define VA_LOCAL_DECL va_list ap;
34 #  define VA_START(f)   va_start(ap)
35 #  define VA_END        va_end(ap)
36 # endif /* __STDC__ */
37 /**************************************************************
38  * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
39  * A bombproof version of doprnt (dopr) included.
40  * Sigh.  This sort of thing is always nasty do deal with.  Note that
41  * the version here does not include floating point...
42  *
43  * snprintf() is used instead of sprintf() as it does limit checks
44  * for string length.  This covers a nasty loophole.
45  *
46  * The other functions are there to prevent NULL pointers from
47  * causing nast effects.
48  **************************************************************/
49
50 static void dopr();
51 static char *end;
52 # ifndef _SCO_DS
53 /* VARARGS3 */
54 int
55 #  ifdef __STDC__
56 snprintf(char *str, size_t count, const char *fmt, ...)
57 #  else /* __STDC__ */
58 snprintf(str, count, fmt, va_alist)
59         char *str;
60         size_t count;
61         const char *fmt;
62         va_dcl
63 #  endif /* __STDC__ */
64 {
65         int len;
66         VA_LOCAL_DECL
67
68         VA_START(fmt);
69         len = vsnprintf(str, count, fmt, ap);
70         VA_END;
71         return len;
72 }
73 # endif /* _SCO_DS */
74
75 int
76 # ifdef __STDC__
77 vsnprintf(char *str, size_t count, const char *fmt, va_list args)
78 # else /* __STDC__ */
79 vsnprintf(str, count, fmt, args)
80         char *str;
81         int count;
82         char *fmt;
83         va_list args;
84 # endif /* __STDC__ */
85 {
86         str[0] = 0;
87         end = str + count - 1;
88         dopr( str, fmt, args );
89         if (count > 0)
90                 end[0] = 0;
91         return strlen(str);
92 }
93
94 /*
95  * dopr(): poor man's version of doprintf
96  */
97
98 static void fmtstr __P((char *value, int ljust, int len, int zpad,
99                         int maxwidth));
100 static void fmtnum __P((long value, int base, int dosign, int ljust, int len,
101                         int zpad));
102 static void dostr __P(( char * , int ));
103 static char *output;
104 static void dopr_outch __P(( int c ));
105
106 static void
107 # ifdef __STDC__
108 dopr(char  * buffer, const char * format, va_list args )
109 # else /* __STDC__ */
110 dopr( buffer, format, args )
111        char *buffer;
112        char *format;
113        va_list args;
114 # endif /* __STDC__ */
115 {
116        int ch;
117        long value;
118        int longflag  = 0;
119        int pointflag = 0;
120        int maxwidth  = 0;
121        char *strvalue;
122        int ljust;
123        int len;
124        int zpad;
125
126        output = buffer;
127        while( (ch = *format++) ){
128                switch( ch ){
129                case '%':
130                        ljust = len = zpad = maxwidth = 0;
131                        longflag = pointflag = 0;
132                nextch:
133                        ch = *format++;
134                        switch( ch ){
135                        case 0:
136                                dostr( "**end of format**" , 0);
137                                return;
138                        case '-': ljust = 1; goto nextch;
139                        case '0': /* set zero padding if len not set */
140                                if(len==0 && !pointflag) zpad = '0';
141                        case '1': case '2': case '3':
142                        case '4': case '5': case '6':
143                        case '7': case '8': case '9':
144                                if (pointflag)
145                                  maxwidth = maxwidth*10 + ch - '0';
146                                else
147                                  len = len*10 + ch - '0';
148                                goto nextch;
149                        case '*': 
150                                if (pointflag)
151                                  maxwidth = va_arg( args, int );
152                                else
153                                  len = va_arg( args, int );
154                                goto nextch;
155                        case '.': pointflag = 1; goto nextch;
156                        case 'l': longflag = 1; goto nextch;
157                        case 'u': case 'U':
158                                /*fmtnum(value,base,dosign,ljust,len,zpad) */
159                                if( longflag ){
160                                        value = va_arg( args, long );
161                                } else {
162                                        value = va_arg( args, int );
163                                }
164                                fmtnum( value, 10,0, ljust, len, zpad ); break;
165                        case 'o': case 'O':
166                                /*fmtnum(value,base,dosign,ljust,len,zpad) */
167                                if( longflag ){
168                                        value = va_arg( args, long );
169                                } else {
170                                        value = va_arg( args, int );
171                                }
172                                fmtnum( value, 8,0, ljust, len, zpad ); break;
173                        case 'd': case 'D':
174                                if( longflag ){
175                                        value = va_arg( args, long );
176                                } else {
177                                        value = va_arg( args, int );
178                                }
179                                fmtnum( value, 10,1, ljust, len, zpad ); break;
180                        case 'x':
181                                if( longflag ){
182                                        value = va_arg( args, long );
183                                } else {
184                                        value = va_arg( args, int );
185                                }
186                                fmtnum( value, 16,0, ljust, len, zpad ); break;
187                        case 'X':
188                                if( longflag ){
189                                        value = va_arg( args, long );
190                                } else {
191                                        value = va_arg( args, int );
192                                }
193                                fmtnum( value,-16,0, ljust, len, zpad ); break;
194                        case 's':
195                                strvalue = va_arg( args, char *);
196                                if (maxwidth > 0 || !pointflag) {
197                                  if (pointflag && len > maxwidth)
198                                    len = maxwidth; /* Adjust padding */
199                                  fmtstr( strvalue,ljust,len,zpad, maxwidth);
200                                }
201                                break;
202                        case 'c':
203                                ch = va_arg( args, int );
204                                dopr_outch( ch ); break;
205                        case '%': dopr_outch( ch ); continue;
206                        default:
207                                dostr(  "???????" , 0);
208                        }
209                        break;
210                default:
211                        dopr_outch( ch );
212                        break;
213                }
214        }
215        *output = 0;
216 }
217
218 static void
219 fmtstr(  value, ljust, len, zpad, maxwidth )
220        char *value;
221        int ljust, len, zpad, maxwidth;
222 {
223        int padlen, strlen;     /* amount to pad */
224
225        if( value == 0 ){
226                value = "<NULL>";
227        }
228        for( strlen = 0; value[strlen]; ++ strlen ); /* strlen */
229        if (strlen > maxwidth && maxwidth)
230          strlen = maxwidth;
231        padlen = len - strlen;
232        if( padlen < 0 ) padlen = 0;
233        if( ljust ) padlen = -padlen;
234        while( padlen > 0 ) {
235                dopr_outch( ' ' );
236                --padlen;
237        }
238        dostr( value, maxwidth );
239        while( padlen < 0 ) {
240                dopr_outch( ' ' );
241                ++padlen;
242        }
243 }
244
245 static void
246 fmtnum(  value, base, dosign, ljust, len, zpad )
247        long value;
248        int base, dosign, ljust, len, zpad;
249 {
250        int signvalue = 0;
251        unsigned long uvalue;
252        char convert[20];
253        int place = 0;
254        int padlen = 0; /* amount to pad */
255        int caps = 0;
256
257        /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
258                value, base, dosign, ljust, len, zpad )); */
259        uvalue = value;
260        if( dosign ){
261                if( value < 0 ) {
262                        signvalue = '-';
263                        uvalue = -value;
264                }
265        }
266        if( base < 0 ){
267                caps = 1;
268                base = -base;
269        }
270        do{
271                convert[place++] =
272                        (caps? "0123456789ABCDEF":"0123456789abcdef")
273                         [uvalue % (unsigned)base  ];
274                uvalue = (uvalue / (unsigned)base );
275        }while(uvalue);
276        convert[place] = 0;
277        padlen = len - place;
278        if( padlen < 0 ) padlen = 0;
279        if( ljust ) padlen = -padlen;
280        /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
281                convert,place,signvalue,padlen)); */
282        if( zpad && padlen > 0 ){
283                if( signvalue ){
284                        dopr_outch( signvalue );
285                        --padlen;
286                        signvalue = 0;
287                }
288                while( padlen > 0 ){
289                        dopr_outch( zpad );
290                        --padlen;
291                }
292        }
293        while( padlen > 0 ) {
294                dopr_outch( ' ' );
295                --padlen;
296        }
297        if( signvalue ) dopr_outch( signvalue );
298        while( place > 0 ) dopr_outch( convert[--place] );
299        while( padlen < 0 ){
300                dopr_outch( ' ' );
301                ++padlen;
302        }
303 }
304
305 static void
306 dostr( str , cut)
307      char *str;
308      int cut;
309 {
310   if (cut) {
311     while(*str && cut-- > 0) dopr_outch(*str++);
312   } else {
313     while(*str) dopr_outch(*str++);
314   }
315 }
316
317 static void
318 dopr_outch( c )
319        int c;
320 {
321        if( end == 0 || output < end )
322                *output++ = c;
323 }
324
325 int 
326 # ifdef __STDC__
327 vsyslog(int priority, const char *fmt, ...)
328 # else /* __STDC__ */
329 vsyslog(priority, fmt, va_alist)
330   int priority;
331   const char *fmt;
332   va_dcl
333 # endif /* __STDC__ */
334 {
335     VA_LOCAL_DECL
336     char logbuf[BUFSIZ];
337     
338     VA_START(fmt);
339
340     vsnprintf(logbuf, BUFSIZ, fmt, ap);
341     syslog(priority, "%s", logbuf);
342
343     VA_END;
344 }
345 #endif /* __hpux */
346
347 void pam_vsystem_log(const pam_handle_t *pamh,
348                      const struct pam_log_state *log_state,
349                      int priority, const char *format, va_list args)
350 {
351     const char *ident;
352     int option, facility;
353
354     D(("pam_vsystem_log called"));
355
356 #ifndef __FreeBSD__
357     /* make sure we have a log state to use */
358     if (NULL == log_state) {
359         if (NULL != pamh && NULL != pamh->pam_default_log.ident) {
360             ident = pamh->pam_default_log.ident;
361             option = pamh->pam_default_log.option;
362             facility = pamh->pam_default_log.facility;
363         } else {
364             ident = PAM_LOG_STATE_IDENT;
365             option = PAM_LOG_STATE_OPTION;
366             facility = PAM_LOG_STATE_FACILITY;
367         }
368         openlog(ident, option, facility);
369     } else {
370         openlog(log_state->ident, log_state->option, log_state->facility);
371     }
372 #endif
373
374     vsyslog(priority, format, args);
375 #ifndef __FreeBSD__
376     closelog();
377 #endif
378
379     D(("done."));
380 }
381
382 void pam_system_log(const pam_handle_t *pamh,
383                     const struct pam_log_state *log_state,
384                     int priority, const char *format, ... )
385 {
386     const char *ident;
387     int option, facility;
388     va_list args;
389
390     D(("pam_system_log called"));
391
392 #ifndef __FreeBSD__
393     /* make sure we have a log state to use */
394     if (NULL == log_state) {
395         if (NULL != pamh && NULL != pamh->pam_default_log.ident) {
396             ident = pamh->pam_default_log.ident;
397             option = pamh->pam_default_log.option;
398             facility = pamh->pam_default_log.facility;
399         } else {
400             ident = PAM_LOG_STATE_IDENT;
401             option = PAM_LOG_STATE_OPTION;
402             facility = PAM_LOG_STATE_FACILITY;
403         }
404         openlog(ident, option, facility);
405     } else {
406         openlog(log_state->ident, log_state->option, log_state->facility);
407     }
408 #endif
409
410     va_start(args, format);
411     vsyslog(priority, format, args);
412     va_end(args);
413 #ifndef __FreeBSD__
414     closelog();
415 #endif
416
417     D(("done."));
418 }
419
420 /*
421  * Recommended #defines to make porting legacy apps easier [Ed. at this
422  * point, the syslog() #define is breoken -- suggestions?]
423  *
424  * #ifdef PAM_LOG_STATE
425  * # define openlog(ident, option, facility) { \
426  *      struct pam_log_state tmp_state;        \
427  *      tmp_state.ident = ident;               \
428  *      tmp_state.option = option;             \
429  *      tmp_state.facility = facility;         \
430  *      (void) pam_set_item(pamh, PAM_LOG_STATE, &tmp_state); \
431  *   }
432  * # define syslog pam_system_log
433  * # define closelog()
434  * #endif
435  */