]> arthur.barton.de Git - netatalk.git/blob - libatalk/util/logger.c
Warning fixes.
[netatalk.git] / libatalk / util / logger.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 /* ==========================================================================
6
7        logger.c is part of the utils section in the libatalk library, 
8         which is part of the netatalk project.  
9
10        logger.c was written by Simon Bazley (sibaz@sibaz.com)
11
12        I believe libatalk is released under the L/GPL licence.  
13
14        Just incase, it is, thats the licence I'm applying to this file.
15
16        Netatalk 2001 (c)
17
18    ==========================================================================
19
20        Logger.c is intended as an alternative to syslog for logging
21
22        ---------------------------------------------------------------
23
24    The initial plan is to create a structure for general information needed
25     to log to a file.  
26
27    Initally I'll hard code the neccesary stuff to start a log, this should
28     probably be moved elsewhere when some code is written to read the log
29     file locations from the config files.  
30
31    As a more longterm idea, I'll code this so that the data struct can be
32     duplicated to allow multiple concurrent log files, although this is 
33     probably a recipe for wasted resources. 
34
35    ========================================================================== */
36
37 #include <stdio.h>
38 #include <limits.h>
39 #include <stdarg.h>
40 #include <string.h>
41 #include <stdlib.h>
42 #include <syslog.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <unistd.h>
46 #include <time.h>
47
48 #include <atalk/boolean.h>
49 #include <atalk/logger.h>
50
51 #define COUNT_ARRAY(array) (sizeof((array))/sizeof((array)[0]))
52 #undef  KEEP_LOGFILES_OPEN
53 #define DO_SYSLOG
54 #define DO_FILELOG
55
56 #undef  DEBUG_OUTPUT_TO_SCREEN
57 #undef  CHECK_STAT_ON_NEW_FILES 
58 #undef  CHECK_ACCESS_ON_NEW_FILES 
59
60 /* ==========================================================================
61     External function declarations
62    ========================================================================== */
63
64 /* setup the internal variables used by the logger (called automatically) */
65 void log_init();
66
67 /* Setup the log filename and the loglevel, and the type of log it is. */
68 bool log_setup(char *filename, enum loglevels loglevel, enum logtypes logtype, int display_options);
69
70 /* Setup the Level and type of log that will be logged to syslog. */
71 void syslog_setup(enum loglevels loglevel, enum logtypes logtype, int display_options, int facility);
72
73 /* finish up and close the logs */
74 void log_close();
75
76 /* This function sets up the processname */
77 void set_processname(char *processname);
78
79 /* Log a Message */
80 void make_log(enum loglevels loglevel, enum logtypes logtype, char *message, ...);
81 #ifndef DISABLE_LOGGER
82 make_log_func set_log_location(char *srcfilename, int srclinenumber);
83
84 /* ========================================================================== 
85     Structure definitions
86    ========================================================================== */
87
88 /* A structure containing object level stuff */
89 struct tag_log_file_data {
90   char log_filename[PATH_MAX];  /* Name of file */
91   FILE *log_file;      /* FILE pointer to file */
92   enum loglevels   log_level;     /* Log Level to put in this file */
93   int  display_options;
94 };
95
96 typedef struct tag_log_file_data log_file_data_pair[2];
97
98 /* A structure containg class level stuff */
99 struct tag_global_log_data {
100   int   struct_size;
101
102   char *temp_src_filename;
103   int   temp_src_linenumber;
104   char  processname[16];
105   
106   char *log_file_directory;  /* Path of directory containing log files */
107   log_file_data_pair **logs;
108 };
109
110 struct what_to_print_array {
111   bool print_datetime;
112   bool print_processname;
113   bool print_pid;
114   bool print_srcfile;
115   bool print_srcline;
116   bool print_errlevel;
117   bool print_errtype;
118 };
119
120 /* ==========================================================================
121     Internal function declarations
122    ========================================================================== */
123
124 void generate_message_details(char *message_details_buffer,
125                               int message_details_buffer_length,
126                               struct tag_log_file_data *log_struct,
127                               enum loglevels loglevel, enum logtypes logtype);
128
129 int get_syslog_equivalent(enum loglevels loglevel);
130
131 static char *get_command_name(char *commandpath);
132
133 /* ==========================================================================
134     Instanciated data
135    ========================================================================== */
136
137 /* A populated instance */
138
139 static log_file_data_pair default_log_file_data_pair = {
140 {
141   /* log_filename */ "\0\0\0\0\0\0\0\0",
142   /* log_file     */ NULL,
143   /* log_level    */ log_debug,
144   /* display_options */ logoption_pid
145 },
146 {
147   /* log_filename */ LOGFILEPATH,
148   /* log_file     */ NULL,
149   /* log_level    */ log_debug,
150   /* display_options */ logoption_pid
151 }};
152
153 static log_file_data_pair *log_file_data_array[logtype_end_of_list_marker] = 
154 {&default_log_file_data_pair};
155
156 /* The class (populated) */
157 static struct tag_global_log_data global_log_data = {
158   /* struct_size  */ sizeof(struct tag_global_log_data),
159   /* temp_src_filename */ NULL,
160   /* temp_src_linenumber */ 0,
161   /* processname */ "",
162   /* log_file_directory */ "",
163   /* logs */  NULL
164 };
165
166 /* macro to get access to the array */
167 #define log_file_arr (global_log_data.logs)
168
169 /* Array to store text to list given a log type */
170 static const char * arr_logtype_strings[] =  LOGTYPE_STRING_IDENTIFIERS;
171 static const int num_logtype_strings = COUNT_ARRAY(arr_logtype_strings);
172
173 /* Array for charachters representing log severity in the log file */
174 static const char arr_loglevel_chars[] = {'S', 'E', 'W', 'N', 'I', 'D'};
175 static const int num_loglevel_chars = COUNT_ARRAY(arr_loglevel_chars);
176
177 #else /* #ifndef DISABLE_LOGGER */
178   char *disabled_logger_processname=NULL;
179 #endif /* DISABLE_LOGGER */
180 /* ==========================================================================
181     Global function definitions
182    ========================================================================== */
183
184 #ifndef DISABLE_LOGGER
185
186 /* remember I'm keeping a copy of the actual char * Filename, so you mustn't
187    delete it, until you've finished with the log.  Also you're responsible
188    for deleting it when you have finished with it. */
189 void log_init()
190 {
191   if (global_log_data.logs==NULL)
192   {
193     /* first check default_log_file_data_pair */
194
195     /* next clear out the log_file_data_array */
196     memset(log_file_data_array, 0, sizeof(log_file_data_array));
197     /* now set default_log_file_data_pairs */
198     log_file_data_array[0] = &default_log_file_data_pair;
199
200     /* now setup the global_log_data struct */
201     global_log_data.logs = log_file_data_array;
202   }
203 }
204 #endif /* #ifndef DISABLE_LOGGER */
205
206 bool log_setup(char *filename, enum loglevels loglevel, enum logtypes logtype, int display_options)
207 {
208 #ifndef DISABLE_LOGGER
209
210   struct stat statbuf;
211   int firstattempt;
212   int retval;
213   gid_t gid;
214   uid_t uid;
215   int access;
216   char lastchar[2];
217
218   log_file_data_pair *logs;
219
220   log_init();
221
222   logs = log_file_arr[logtype];
223
224   if (logs==NULL)
225   {
226     logs = (log_file_data_pair *)malloc(sizeof(log_file_data_pair));
227     if (logs==NULL)
228     {
229       LOG(log_severe, logtype_logger, "can't calloc in log_setup");
230     }
231     else
232     {
233       /* memcpy(logs, log_file_arr[logtype_default], sizeof(log_file_data_pair)); */
234       log_file_arr[logtype] = logs;
235       (*logs)[1].log_file = NULL;
236     }
237   }
238
239   if ( ((*logs)[1].log_file == stdout) && ((*logs)[1].log_file != NULL) )
240   {
241     fclose((*logs)[1].log_file);
242     (*logs)[1].log_file = NULL;
243   }
244
245   if (strlen(global_log_data.log_file_directory)>0)
246   {
247     lastchar[0] = global_log_data.log_file_directory[strlen(global_log_data.log_file_directory)-1];
248
249     if (lastchar[0] == '/' || lastchar[0] == '\\' || lastchar[0] == ':')
250       lastchar[0] = 0;
251     else
252       /* this should probably be a platform specific path separator */
253       lastchar[0] = '/';
254
255     lastchar[1] = 0;
256   }
257   else
258     lastchar[0] = 0;
259   
260 #ifdef DEBUG_OUTPUT_TO_SCREEN
261   printf("filename is %s stored at location %p\n", (*logs)[1].log_filename, 
262                                                    (*logs)[1].log_filename);
263 #endif /* DEBUG_OUTPUT_TO_SCREEN */
264   if (filename == NULL)
265   {
266     strncpy((*logs)[1].log_filename, (*(log_file_arr[0]))[1].log_filename, PATH_MAX);
267   }
268   else
269   {
270     sprintf((*logs)[1].log_filename, "%s%s%s", global_log_data.log_file_directory,
271                                          lastchar, filename);
272   }
273   (*logs)[1].log_level    = loglevel;
274   (*logs)[1].display_options = display_options;
275
276 #ifdef DEBUG_OUTPUT_TO_SCREEN
277   printf("filename is %s stored at location %p\n", (*logs)[1].log_filename, 
278                                                    (*logs)[1].log_filename);
279 #endif /* DEBUG_OUTPUT_TO_SCREEN */
280
281 #ifdef CHECK_STAT_ON_NEW_FILES
282   uid = geteuid(); 
283   gid = getegid();
284   
285 #ifdef DEBUG_OUTPUT_TO_SCREEN
286   printf("about to stat file %s\n", (*logs)[1].log_filename);
287 #endif
288   firstattempt = stat((*logs)[1].log_filename, &statbuf);
289
290   if (firstattempt == -1)
291   {
292 #ifdef DEBUG_OUTPUT_TO_SCREEN
293     printf("about to call Log with %d, %d, %s, %s\n", log_note, logtype_logger, 
294            "can't stat Logfile",    (*logs)[1].log_filename);
295 #endif
296
297     /* syslog(LOG_INFO, "stat failed"); */
298     LOG(log_warning, logtype_logger, "stat fails on file %s",
299                      (*logs)[1].log_filename);
300
301     if (strlen(global_log_data.log_file_directory)>0)
302     {
303       retval = stat(global_log_data.log_file_directory, &statbuf);
304       if (retval == -1)
305       {
306 #ifdef DEBUG_OUTPUT_TO_SCREEN
307         printf("can't stat dir either so I'm giving up\n");
308 #endif
309         LOG(log_severe, logtype_logger, "can't stat directory %s either",
310                          global_log_data.log_file_directory);
311         return false;
312       } 
313     }
314   }
315
316 #ifdef CHECK_ACCESS_ON_NEW_FILES
317   access = ((statbuf.st_uid == uid)?(statbuf.st_mode & S_IWUSR):0) + 
318            ((statbuf.st_gid == gid)?(statbuf.st_mode & S_IWGRP):0) +
319            (statbuf.st_mode & S_IWOTH);
320
321   if (access==0)
322   {
323 #ifdef DEBUG_OUTPUT_TO_SCREEN
324     printf("failing with %d, %d, %s, %s\n", log_note, logtype_logger,
325            "can't access Logfile %s",    (*logs)[1].log_filename);
326 #endif
327
328     LOG(log_note, logtype_logger, "can't access file %s", 
329                      (*logs)[1].log_filename);
330     return false;
331   }
332 #endif /* CHECK_ACCESS_ON_NEW_FILES */
333 #endif /* CHECK_STAT_ON_NEW_FILES */
334 #ifdef KEEP_LOGFILES_OPEN
335   if ((*logs)[1].log_file!=NULL)
336     fclose((*logs)[1].log_file);
337
338   (*logs)[1].log_file     = fopen((*logs)[1].log_filename, "at");
339   if ((*logs)[1].log_file == NULL)
340   {
341     LOG(log_severe, logtype_logger, "can't open Logfile %s", (*logs)[1].log_filename);
342     return false;
343   }
344 #endif
345
346   LOG(log_info, logtype_logger, "Log setup complete");
347
348 #endif /* DISABLE_LOGGER */
349   return true;
350 }
351
352
353 void syslog_setup(enum loglevels loglevel, enum logtypes logtype, int display_options, int facility)
354 {
355 #ifndef DISABLE_LOGGER
356   log_file_data_pair *logs;
357
358   log_init();
359
360   logs = log_file_arr[logtype];
361
362   if (logs==NULL)
363   {
364     logs = (log_file_data_pair *)malloc(sizeof(log_file_data_pair));    
365     if (logs==NULL)
366     {
367       LOG(log_severe, logtype_logger, "can't calloc in log_setup");
368     }
369     else
370     {
371       memcpy(logs, log_file_arr[logtype_default], sizeof(log_file_data_pair));
372       log_file_arr[logtype] = logs;
373     }
374   }
375
376   (*logs)[0].log_file        = NULL;
377   (*logs)[0].log_filename[0] = 0;
378   (*logs)[0].log_level       = loglevel;
379   (*logs)[0].display_options = display_options;
380
381   openlog(global_log_data.processname, (*logs)[0].display_options, facility);
382
383   LOG(log_info, logtype_logger, "SysLog setup complete");
384 #else /* DISABLE_LOGGER */
385 /* behave like a normal openlog call */
386   openlog(disabled_logger_processname, display_options, facility);
387 #endif /* DISABLE_LOGGER */
388 }
389
390 void log_close()
391 {
392 #ifndef DISABLE_LOGGER
393   log_file_data_pair *logs;
394   int n;
395
396   LOG(log_info, logtype_logger, "Closing logs");
397
398   for(n=(sizeof(log_file_arr)-1);n>0;n--)
399   {
400     logs = log_file_arr[n];
401 #ifdef KEEP_LOGFILES_OPEN
402     if ((*logs)[1].log_file!=NULL)
403       fclose((*logs)[1].log_file);
404 #endif /* KEEP_LOGFILES_OPEN */
405     if (logs!=NULL)
406     {
407 #ifdef DEBUG_OUTPUT_TO_SCREEN
408       printf("Freeing log_data %d, stored at %p\n", n, logs);
409       printf("\t(filename) %s\t(type) %s\n", (*logs)[1].log_filename, 
410              ((n<num_logtype_strings)?arr_logtype_strings[n]:""));
411 #endif /* DEBUG_OUTPUT_TO_SCREEN */
412       free(logs);
413     }
414     log_file_arr[n] = NULL;
415   }
416 #ifdef DEBUG_OUTPUT_TO_SCREEN
417       printf("Freeing log_data %d, stored at %p\n", n, log_file_arr[n]);
418       printf("\t(filename) %s\t(type) %s\n", (*(log_file_arr[n]))[1].log_filename, 
419              ((n<num_logtype_strings)?arr_logtype_strings[n]:""));
420 #endif /* DEBUG_OUTPUT_TO_SCREEN */
421 #endif /* DISABLE_LOGGER */
422
423   closelog();
424 }
425
426 /* This function sets up the processname */
427 void set_processname(char *processname)
428 {
429 #ifndef DISABLE_LOGGER
430   /* strncpy(global_log_data.processname, GetCommandName(processname), 15); */
431   strncpy(global_log_data.processname, processname, 15);
432   global_log_data.processname[15] = 0;
433 #else /* DISABLE_LOGGER */
434   disabled_logger_processname = processname;
435 #endif /* DISABLE_LOGGER */
436 }
437
438 #ifndef DISABLE_LOGGER
439 /* This is called by the macro so set the location of the caller of Log */
440 make_log_func set_log_location(char *srcfilename, int srclinenumber)
441 {
442 #ifdef DEBUG_OUTPUT_TO_SCREEN
443   printf("Setting Log Location\n");
444 #endif
445   global_log_data.temp_src_filename = srcfilename;
446   global_log_data.temp_src_linenumber = srclinenumber;
447
448   return make_log_entry;
449 }
450 #endif /* DISABLE_LOGGER */
451
452 /* --------------------------------------------------------------------------
453     MakeLog has 1 main flaws:
454       The message in its entirity, must fit into the tempbuffer.  
455       So it must be shorter than MAXLOGSIZE
456    -------------------------------------------------------------------------- */
457 void make_log_entry(enum loglevels loglevel, enum logtypes logtype, char *message, ...)
458 {
459   va_list args;
460   char log_buffer[MAXLOGSIZE];
461 #ifndef DISABLE_LOGGER
462   char log_details_buffer[MAXLOGSIZE];
463
464   log_file_data_pair *logs;
465
466   log_init();
467
468   logs = log_file_arr[logtype];
469
470   if (logs==NULL)
471   {
472     logs = log_file_arr[logtype_default];
473   }
474 #ifdef DEBUG_OUTPUT_TO_SCREEN
475   printf("Making Log\n");
476 #endif
477   
478 #endif /* DISABLE_LOGGER */
479
480   /* Initialise the Messages */
481   va_start(args, message);
482
483   vsnprintf(log_buffer, sizeof(log_buffer), message, args);
484
485   /* Finished with args for now */
486   va_end(args);
487
488 #ifdef DISABLE_LOGGER
489   syslog(get_syslog_equivalent(loglevel), "%s", log_buffer);
490 #else /* DISABLE_LOGGER */
491
492 #ifdef DO_SYSLOG
493   /* check if sysloglevel is high enough */
494   if ((*logs)[0].log_level>=loglevel)
495   {
496     int sysloglevel = get_syslog_equivalent(loglevel);
497
498     generate_message_details(log_details_buffer, sizeof(log_details_buffer),
499                               &(*logs)[0], loglevel, logtype);
500
501 #ifdef DEBUG_OUTPUT_TO_SCREEN
502     printf("About to log %s %s\n", log_details_buffer, log_buffer);
503     printf("about to do syslog\n");
504     printf("done onw syslog\n");
505 #endif
506     syslog(sysloglevel, "%s: %s", log_details_buffer, log_buffer);
507     /* syslog(sysloglevel, "%s:%s: %s", log_levelString, log_typeString, LogBuffer); */
508   }
509 #endif
510
511 #ifdef DO_FILELOG
512 #ifdef DEBUG_OUTPUT_TO_SCREEN
513   printf("about to do the filelog\n");
514 #endif
515   /* check if log_level is high enough */
516   if ((*logs)[1].log_level>=loglevel) {    
517  
518 #ifdef DEBUG_OUTPUT_TO_SCREEN
519     printf("Open the Log, FILE* is %p\n", (*logs)[1].log_file);
520 #endif
521     /* if log isn't open, open it */
522     if ((*logs)[1].log_file==NULL) {
523 #ifdef DEBUG_OUTPUT_TO_SCREEN
524       printf("Opening the Log, filename is %s\n", (*logs)[1].log_filename);
525 #endif
526       (*logs)[1].log_file     = fopen((*logs)[1].log_filename, "at");
527       if ((*logs)[1].log_file == NULL)
528       {
529         (*logs)[1].log_file = stdout;
530         LOG(log_severe, logtype_logger, "can't open Logfile %s", (*logs)[1].log_filename);
531         return;
532       }
533     }
534     generate_message_details(log_details_buffer, sizeof(log_details_buffer),
535                              &(*logs)[1], loglevel, logtype);
536
537 #ifdef DEBUG_OUTPUT_TO_SCREEN
538     printf("Files open, lets log\n");
539     printf("FILE* is %p\n", (*logs)[1].log_file);
540     printf("%s: %s\n", log_details_buffer, log_buffer);
541 #endif
542
543     fprintf((*logs)[1].log_file, "%s: %s\n", log_details_buffer, log_buffer);
544
545 #ifndef KEEP_LOGFILES_OPEN
546     if ((*logs)[1].log_file != stdout)
547     {
548 #ifdef DEBUG_OUTPUT_TO_SCREEN
549       printf("Closing %s\n", (*logs)[1].log_filename);
550 #endif
551       fclose((*logs)[1].log_file);
552       (*logs)[1].log_file = NULL;
553 #ifdef DEBUG_OUTPUT_TO_SCREEN
554       printf("Closed\n");
555 #endif
556     }
557 #endif 
558   }
559 #endif
560
561   global_log_data.temp_src_filename = NULL;
562   global_log_data.temp_src_linenumber = 0;
563 #endif /* DISABLE_LOGGER */
564 }
565
566 #ifndef DISABLE_LOGGER
567 void load_proccessname_from_proc()
568 {
569   pid_t pid = getpid();
570   char buffer[PATH_MAX];
571   char procname[16];
572   FILE * statfile;
573   char *ptr;
574
575   sprintf(buffer, "/proc/%d/stat", pid);
576   statfile = fopen(buffer, "rt");
577   fgets(buffer, PATH_MAX-1, statfile);
578   fclose(statfile);
579
580   ptr = (char *)strrchr(buffer, ')');
581   *ptr = '\0';
582   memset(procname, 0, sizeof procname);
583   sscanf(buffer, "%d (%15c", &pid, procname);   /* comm[16] in kernel */
584
585   set_processname(procname);
586 }
587
588 /* ==========================================================================
589     Internal function definitions
590    ========================================================================== */
591
592 static char *get_command_name(char *commandpath)
593 {
594   char *ptr;
595 #ifdef DEBUG_OUTPUT_TO_SCREEN
596   printf("getting command name %s\n",commandpath);
597 #endif
598   ptr = (char *)strrchr(commandpath, '/');
599   if (ptr==NULL)
600     ptr = commandpath;
601   else
602     ptr++;
603
604 #ifdef DEBUG_OUTPUT_TO_SCREEN
605   printf("Concluded %s\n", ptr);
606 #endif
607   return ptr;
608 }
609
610 void  workout_what_to_print(struct what_to_print_array *what_to_print, struct tag_log_file_data *log_struct)
611 {
612   /* is this a syslog entry? */
613   if (log_struct->log_filename[0]==0)
614   {
615     what_to_print->print_datetime = false;
616     what_to_print->print_processname = false;
617     what_to_print->print_pid = false;
618   }
619   else
620   {
621     what_to_print->print_datetime = true;
622     what_to_print->print_processname = true;
623  
624     /* pid is dealt with at the syslog level if we're syslogging */
625     what_to_print->print_pid = (((log_struct->display_options & logoption_pid) == 0)?false:true);
626   }
627
628   what_to_print->print_srcfile = (((log_struct->display_options & logoption_nfile) == 0)?true:false);
629   what_to_print->print_srcline = (((log_struct->display_options & logoption_nline) == 0)?true:false);
630   
631   what_to_print->print_errlevel = true;
632   what_to_print->print_errtype = true;
633 }
634
635 void generate_message_details(char *message_details_buffer, 
636                               int message_details_buffer_length,
637                               struct tag_log_file_data *log_struct,
638                               enum loglevels loglevel, enum logtypes logtype)
639 {
640   char datebuffer[32];
641   char processinfo[64];
642
643   char *ptr = message_details_buffer;
644   int   templen;
645   int   len = message_details_buffer_length;
646
647   char log_buffer[MAXLOGSIZE];
648   const char *logtype_string;
649
650   char loglevel_string[12]; /* max int size is 2 billion, or 10 digits */
651
652   struct what_to_print_array what_to_print;
653
654   workout_what_to_print(&what_to_print, log_struct);
655
656 #ifdef DEBUG_OUTPUT_TO_SCREEN
657   printf("Making MessageDetails\n");
658 #endif
659
660   *ptr = 0;
661   /*
662   datebuffer[0] = 0;
663   ptr = datebuffer;
664   */
665
666   if (what_to_print.print_datetime)
667   {
668     time_t thetime;
669     time(&thetime);
670
671   /* some people might prefer localtime() to gmtime() */
672     strftime(ptr, len, "%b %d %H:%M:%S", gmtime(&thetime));
673 #ifdef DEBUG_OUTPUT_TO_SCREEN
674     printf("date is %s\n", ptr);
675 #endif
676
677     templen = strlen(ptr);
678     len -= templen;
679     if (what_to_print.print_processname || what_to_print.print_pid)
680       strncat(ptr, " ", len);
681     else
682       strncat(ptr, ":", len);
683
684     templen++;
685     len --;
686     ptr += templen;
687   }
688
689   /*
690   processinfo[0] = 0;
691   ptr = processinfo;
692   */
693
694   if (what_to_print.print_processname)
695   {
696     strncpy(ptr, global_log_data.processname, len);
697
698     templen = strlen(ptr);
699     len -= templen;
700     ptr += templen;
701   }
702
703   if (what_to_print.print_pid)
704   {
705     pid_t pid = getpid();
706
707     sprintf(ptr, "[%d]", pid);
708
709     templen = strlen(ptr);
710     len -= templen;
711     ptr += templen;
712   }
713
714   if (what_to_print.print_srcfile || what_to_print.print_srcline)
715   {
716     char sprintf_buffer[8];
717     char *buff_ptr;
718
719     sprintf_buffer[0] = '[';
720     if (what_to_print.print_srcfile)
721     {
722       strcpy(&sprintf_buffer[1], "%s");
723       buff_ptr = &sprintf_buffer[3];
724     }
725     if (what_to_print.print_srcfile && what_to_print.print_srcline)
726     {
727       strcpy(&sprintf_buffer[3], ":");
728       buff_ptr = &sprintf_buffer[4];
729     }
730     if (what_to_print.print_srcline)
731     {
732       strcpy(buff_ptr, "%d");
733       buff_ptr = &buff_ptr[2];
734     }
735     strcpy(buff_ptr, "]");
736
737     /* ok sprintf string is ready, now is the 1st parameter src or linenumber */
738     if (what_to_print.print_srcfile)
739     {
740       sprintf(ptr, sprintf_buffer, 
741              global_log_data.temp_src_filename, global_log_data.temp_src_linenumber);
742     }
743     else
744     {
745       sprintf(ptr, sprintf_buffer, global_log_data.temp_src_linenumber);
746     }
747
748 #ifdef DEBUG_OUTPUT_TO_SCREEN
749     printf("Process info is %s\n", ptr);
750 #endif
751
752     templen = strlen(ptr);
753     len -= templen;
754     ptr += templen;
755
756   }
757
758   if (what_to_print.print_processname || what_to_print.print_pid ||
759       what_to_print.print_srcfile || what_to_print.print_srcline)
760   {
761     strncat(ptr, ": ", len);
762     len -= 2;
763     ptr += 2;
764   }
765
766 /*
767   loglevel_string[0] = 0;
768   ptr = loglevel_string;
769 */
770
771   if (what_to_print.print_errlevel)
772   {
773     if ((loglevel/10) >= (num_loglevel_chars-1))
774     {
775       sprintf(ptr, "%c%d", arr_loglevel_chars[num_loglevel_chars-1],
776                                        loglevel/10);
777     }
778     else
779     {
780       sprintf(ptr, "%c", arr_loglevel_chars[loglevel/10]);
781     }
782
783     templen = strlen(ptr);
784     len -= templen;
785     ptr += templen;    
786   }
787
788   if (what_to_print.print_errtype)
789   {
790     const char *logtype_string;
791
792     /* get string represnetation of the Log Type */
793     if (logtype<num_logtype_strings)
794       logtype_string = arr_logtype_strings[logtype];
795     else
796       logtype_string = "";
797
798     if (what_to_print.print_errlevel)
799     {
800       strncat(ptr, ":", len);
801       ptr++;
802     }
803
804     sprintf(ptr, "%s", logtype_string);
805   }
806
807   message_details_buffer[message_details_buffer_length-1] = 0;
808
809 #ifdef DEBUG_OUTPUT_TO_SCREEN
810     printf("Message Details are %s\n", message_details_buffer);
811 #endif
812 }
813 #endif /* DISABLE_LOGGER */
814
815 int get_syslog_equivalent(enum loglevels loglevel)
816 {
817   switch (loglevel/10)
818   {
819     /* The question is we know how bad it is for us,
820                     but how should that translate in the syslogs?  */
821     case 0: /* severe */
822       return LOG_ERR;
823     case 1: /* error */
824       return LOG_ERR;
825     case 2: /* warning */
826       return LOG_WARNING;
827     case 3: /* note */
828       return LOG_NOTICE;
829     case 4: /* information */
830       return LOG_INFO;
831     default: /* debug */
832       return LOG_DEBUG;
833   }
834 }
835
836
837
838
839
840
841
842
843