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