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