first batch of license fixes (boring)
[oweals/gnunet.git] / src / util / common_logging.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2006-2013 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14 */
15
16 /**
17  * @file util/common_logging.c
18  * @brief error handling API
19  * @author Christian Grothoff
20  */
21 #include "platform.h"
22 #include "gnunet_crypto_lib.h"
23 #include "gnunet_disk_lib.h"
24 #include "gnunet_strings_lib.h"
25 #include <regex.h>
26
27
28 /**
29  * After how many milliseconds do we always print
30  * that "message X was repeated N times"?  Use 12h.
31  */
32 #define BULK_DELAY_THRESHOLD (12 * 60 * 60 * 1000LL * 1000LL)
33
34 /**
35  * After how many repetitions do we always print
36  * that "message X was repeated N times"? (even if
37  * we have not yet reached the delay threshold)
38  */
39 #define BULK_REPEAT_THRESHOLD 1000
40
41 /**
42  * How many characters do we use for matching of
43  * bulk messages?
44  */
45 #define BULK_TRACK_SIZE 256
46
47 /**
48  * How many characters do we use for matching of
49  * bulk components?
50  */
51 #define COMP_TRACK_SIZE 32
52
53 /**
54  * How many characters can a date/time string
55  * be at most?
56  */
57 #define DATE_STR_SIZE 64
58
59 /**
60  * How many log files to keep?
61  */
62 #define ROTATION_KEEP 3
63
64 #ifndef PATH_MAX
65 /**
66  * Assumed maximum path length (for the log file name).
67  */
68 #define PATH_MAX 4096
69 #endif
70
71
72 /**
73  * Linked list of active loggers.
74  */
75 struct CustomLogger
76 {
77   /**
78    * This is a linked list.
79    */
80   struct CustomLogger *next;
81
82   /**
83    * Log function.
84    */
85   GNUNET_Logger logger;
86
87   /**
88    * Closure for logger.
89    */
90   void *logger_cls;
91 };
92
93 /**
94  * The last "bulk" error message that we have been logging.
95  * Note that this message maybe truncated to the first BULK_TRACK_SIZE
96  * characters, in which case it is NOT 0-terminated!
97  */
98 static char last_bulk[BULK_TRACK_SIZE];
99
100 /**
101  * Type of the last bulk message.
102  */
103 static enum GNUNET_ErrorType last_bulk_kind;
104
105 /**
106  * Time of the last bulk error message (0 for none)
107  */
108 static struct GNUNET_TIME_Absolute last_bulk_time;
109
110 /**
111  * Number of times that bulk message has been repeated since.
112  */
113 static unsigned int last_bulk_repeat;
114
115 /**
116  * Component when the last bulk was logged.  Will be 0-terminated.
117  */
118 static char last_bulk_comp[COMP_TRACK_SIZE + 1];
119
120 /**
121  * Running component.
122  */
123 static char *component;
124
125 /**
126  * Running component (without pid).
127  */
128 static char *component_nopid;
129
130 /**
131  * Format string describing the name of the log file.
132  */
133 static char *log_file_name;
134
135 /**
136  * Minimum log level.
137  */
138 static enum GNUNET_ErrorType min_level;
139
140 /**
141  * Linked list of our custom loggres.
142  */
143 static struct CustomLogger *loggers;
144
145 /**
146  * Number of log calls to ignore.
147  */
148 static int skip_log = 0;
149
150 /**
151  * File descriptor to use for "stderr", or NULL for none.
152  */
153 static FILE *GNUNET_stderr;
154
155 /**
156  * Represents a single logging definition
157  */
158 struct LogDef
159 {
160   /**
161    * Component name regex
162    */
163   regex_t component_regex;
164
165   /**
166    * File name regex
167    */
168   regex_t file_regex;
169
170   /**
171    * Function name regex
172    */
173   regex_t function_regex;
174
175   /**
176    * Lowest line at which this definition matches.
177    * Defaults to 0. Must be <= to_line.
178    */
179   int from_line;
180
181   /**
182    * Highest line at which this definition matches.
183    * Defaults to INT_MAX. Must be >= from_line.
184    */
185   int to_line;
186
187   /**
188    * Maximal log level allowed for calls that match this definition.
189    * Calls with higher log level will be disabled.
190    * Must be >= 0
191    */
192   int level;
193
194   /**
195    * 1 if this definition comes from GNUNET_FORCE_LOG, which means that it
196    * overrides any configuration options. 0 otherwise.
197    */
198   int force;
199 };
200
201
202 #if !defined(GNUNET_CULL_LOGGING)
203 /**
204  * Dynamic array of logging definitions
205  */
206 static struct LogDef *logdefs;
207
208 /**
209  * Allocated size of logdefs array (in units)
210  */
211 static int logdefs_size;
212
213 /**
214  * The number of units used in logdefs array.
215  */
216 static int logdefs_len;
217
218 /**
219  * #GNUNET_YES if GNUNET_LOG environment variable is already parsed.
220  */
221 static int gnunet_log_parsed;
222
223 /**
224  * #GNUNET_YES if GNUNET_FORCE_LOG environment variable is already parsed.
225  */
226 static int gnunet_force_log_parsed;
227
228 /**
229  * #GNUNET_YES if at least one definition with forced == 1 is available.
230  */
231 static int gnunet_force_log_present;
232 #endif
233
234 #ifdef WINDOWS
235 /**
236  * Contains the number of performance counts per second.
237  */
238 static LARGE_INTEGER performance_frequency;
239 #endif
240
241
242 /**
243  * Convert a textual description of a loglevel
244  * to the respective GNUNET_GE_KIND.
245  *
246  * @param log loglevel to parse
247  * @return GNUNET_GE_INVALID if log does not parse
248  */
249 static enum GNUNET_ErrorType
250 get_type (const char *log)
251 {
252   if (NULL == log)
253     return GNUNET_ERROR_TYPE_UNSPECIFIED;
254   if (0 == strcasecmp (log, _("DEBUG")))
255     return GNUNET_ERROR_TYPE_DEBUG;
256   if (0 == strcasecmp (log, _("INFO")))
257     return GNUNET_ERROR_TYPE_INFO;
258   if (0 == strcasecmp (log, _("MESSAGE")))
259     return GNUNET_ERROR_TYPE_MESSAGE;
260   if (0 == strcasecmp (log, _("WARNING")))
261     return GNUNET_ERROR_TYPE_WARNING;
262   if (0 == strcasecmp (log, _("ERROR")))
263     return GNUNET_ERROR_TYPE_ERROR;
264   if (0 == strcasecmp (log, _("NONE")))
265     return GNUNET_ERROR_TYPE_NONE;
266   return GNUNET_ERROR_TYPE_INVALID;
267 }
268
269
270 /**
271  * Abort the process, generate a core dump if possible.
272  */
273 void
274 GNUNET_abort_ ()
275 {
276 #if WINDOWS
277   DebugBreak ();
278 #endif
279   abort ();
280 }
281
282
283 #if !defined(GNUNET_CULL_LOGGING)
284 /**
285  * Utility function - reallocates logdefs array to be twice as large.
286  */
287 static void
288 resize_logdefs ()
289 {
290   logdefs_size = (logdefs_size + 1) * 2;
291   logdefs = GNUNET_realloc (logdefs, logdefs_size * sizeof (struct LogDef));
292 }
293
294
295 #if ! TALER_WALLET_ONLY
296 /**
297  * Rotate logs, deleting the oldest log.
298  *
299  * @param new_name new name to add to the rotation
300  */
301 static void
302 log_rotate (const char *new_name)
303 {
304   static char *rotation[ROTATION_KEEP];
305   static unsigned int rotation_off;
306   char *discard;
307
308   if ('\0' == *new_name)
309     return; /* not a real log file name */
310   discard = rotation[rotation_off % ROTATION_KEEP];
311   if (NULL != discard)
312   {
313     /* Note: can't log errors during logging (recursion!), so this
314        operation MUST silently fail... */
315     (void) UNLINK (discard);
316     GNUNET_free (discard);
317   }
318   rotation[rotation_off % ROTATION_KEEP] = GNUNET_strdup (new_name);
319   rotation_off++;
320 }
321
322
323 /**
324  * Setup the log file.
325  *
326  * @param tm timestamp for which we should setup logging
327  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
328  */
329 static int
330 setup_log_file (const struct tm *tm)
331 {
332   static char last_fn[PATH_MAX + 1];
333   char fn[PATH_MAX + 1];
334   int altlog_fd;
335   int dup_return;
336   FILE *altlog;
337   char *leftsquare;
338
339   if (NULL == log_file_name)
340     return GNUNET_SYSERR;
341   if (0 == strftime (fn, sizeof (fn), log_file_name, tm))
342     return GNUNET_SYSERR;
343   leftsquare = strrchr (fn, '[');
344   if ( (NULL != leftsquare) && (']' == leftsquare[1]) )
345   {
346     char *logfile_copy = GNUNET_strdup (fn);
347
348     logfile_copy[leftsquare - fn] = '\0';
349     logfile_copy[leftsquare - fn + 1] = '\0';
350     snprintf (fn,
351               PATH_MAX,
352               "%s%d%s",
353               logfile_copy,
354               getpid (),
355               &logfile_copy[leftsquare - fn + 2]);
356     GNUNET_free (logfile_copy);
357   }
358   if (0 == strcmp (fn, last_fn))
359     return GNUNET_OK; /* no change */
360   log_rotate (last_fn);
361   strcpy (last_fn, fn);
362   if (GNUNET_SYSERR ==
363       GNUNET_DISK_directory_create_for_file (fn))
364   {
365     fprintf (stderr,
366              "Failed to create directory for `%s': %s\n",
367              fn,
368              STRERROR (errno));
369     return GNUNET_SYSERR;
370   }
371 #if WINDOWS
372   altlog_fd = OPEN (fn, O_APPEND |
373                         O_BINARY |
374                         O_WRONLY | O_CREAT,
375                         _S_IREAD | _S_IWRITE);
376 #else
377   altlog_fd = OPEN (fn, O_APPEND |
378                         O_WRONLY | O_CREAT,
379                         S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
380 #endif
381   if (-1 != altlog_fd)
382   {
383     if (NULL != GNUNET_stderr)
384       fclose (GNUNET_stderr);
385     dup_return = dup2 (altlog_fd, 2);
386     (void) close (altlog_fd);
387     if (-1 != dup_return)
388     {
389       altlog = fdopen (2, "ab");
390       if (NULL == altlog)
391       {
392         (void) close (2);
393         altlog_fd = -1;
394       }
395     }
396     else
397     {
398       altlog_fd = -1;
399     }
400   }
401   if (-1 == altlog_fd)
402   {
403     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn);
404     return GNUNET_SYSERR;
405   }
406   GNUNET_stderr = altlog;
407   return GNUNET_OK;
408 }
409 #endif
410
411
412 /**
413  * Utility function - adds a parsed definition to logdefs array.
414  *
415  * @param component see struct LogDef, can't be NULL
416  * @param file see struct LogDef, can't be NULL
417  * @param function see struct LogDef, can't be NULL
418  * @param from_line see struct LogDef
419  * @param to_line see struct LogDef
420  * @param level see struct LogDef, must be >= 0
421  * @param force see struct LogDef
422  * @return 0 on success, regex-specific error otherwise
423  */
424 static int
425 add_definition (const char *component,
426                 const char *file,
427                 const char *function,
428                 int from_line,
429                 int to_line,
430                 int level,
431                 int force)
432 {
433   struct LogDef n;
434   int r;
435
436   if (logdefs_size == logdefs_len)
437     resize_logdefs ();
438   memset (&n, 0, sizeof (n));
439   if (0 == strlen (component))
440     component = (char *) ".*";
441   r = regcomp (&n.component_regex, (const char *) component, REG_NOSUB);
442   if (0 != r)
443   {
444     return r;
445   }
446   if (0 == strlen (file))
447     file = (char *) ".*";
448   r = regcomp (&n.file_regex, (const char *) file, REG_NOSUB);
449   if (0 != r)
450   {
451     regfree (&n.component_regex);
452     return r;
453   }
454   if ((NULL == function) || (0 == strlen (function)))
455     function = (char *) ".*";
456   r = regcomp (&n.function_regex, (const char *) function, REG_NOSUB);
457   if (0 != r)
458   {
459     regfree (&n.component_regex);
460     regfree (&n.file_regex);
461     return r;
462   }
463   n.from_line = from_line;
464   n.to_line = to_line;
465   n.level = level;
466   n.force = force;
467   logdefs[logdefs_len++] = n;
468   return 0;
469 }
470
471
472 /**
473  * Decides whether a particular logging call should or should not be allowed
474  * to be made. Used internally by GNUNET_log*()
475  *
476  * @param caller_level loglevel the caller wants to use
477  * @param comp component name the caller uses (NULL means that global
478  *   component name is used)
479  * @param file file name containing the logging call, usually __FILE__
480  * @param function function which tries to make a logging call,
481  *   usually __FUNCTION__
482  * @param line line at which the call is made, usually __LINE__
483  * @return 0 to disallow the call, 1 to allow it
484  */
485 int
486 GNUNET_get_log_call_status (int caller_level,
487                             const char *comp,
488                             const char *file,
489                             const char *function,
490                             int line)
491 {
492   struct LogDef *ld;
493   int i;
494   int force_only;
495
496   if (NULL == comp)
497     /* Use default component */
498     comp = component_nopid;
499
500   /* We have no definitions to override globally configured log level,
501    * so just use it right away.
502    */
503   if ( (min_level >= 0) && (GNUNET_NO == gnunet_force_log_present) )
504     return caller_level <= min_level;
505
506   /* Only look for forced definitions? */
507   force_only = min_level >= 0;
508   for (i = 0; i < logdefs_len; i++)
509   {
510     ld = &logdefs[i];
511     if (( (!force_only) || ld->force) &&
512         (line >= ld->from_line && line <= ld->to_line) &&
513         (0 == regexec (&ld->component_regex, comp, 0, NULL, 0)) &&
514         (0 == regexec (&ld->file_regex, file, 0, NULL, 0)) &&
515         (0 == regexec (&ld->function_regex, function, 0, NULL, 0)))
516     {
517       /* We're finished */
518       return caller_level <= ld->level;
519     }
520   }
521   /* No matches - use global level, if defined */
522   if (min_level >= 0)
523     return caller_level <= min_level;
524   /* All programs/services previously defaulted to WARNING.
525    * Now *we* default to WARNING, and THEY default to NULL.
526    * Or rather we default to MESSAGE, since things aren't always bad.
527    */
528   return caller_level <= GNUNET_ERROR_TYPE_MESSAGE;
529 }
530
531
532 /**
533  * Utility function - parses a definition
534  *
535  * Definition format:
536  * component;file;function;from_line-to_line;level[/component...]
537  * All entries are mandatory, but may be empty.
538  * Empty entries for component, file and function are treated as
539  * "matches anything".
540  * Empty line entry is treated as "from 0 to INT_MAX"
541  * Line entry with only one line is treated as "this line only"
542  * Entry for level MUST NOT be empty.
543  * Entries for component, file and function that consist of a
544  * single character "*" are treated (at the moment) the same way
545  * empty entries are treated (wildcard matching is not implemented (yet?)).
546  * file entry is matched to the end of __FILE__. That is, it might be
547  * a base name, or a base name with leading directory names (some compilers
548  * define __FILE__ to absolute file path).
549  *
550  * @param constname name of the environment variable from which to get the
551  *   string to be parsed
552  * @param force 1 if definitions found in constname are to be forced
553  * @return number of added definitions
554  */
555 static int
556 parse_definitions (const char *constname, int force)
557 {
558   char *def;
559   const char *tmp;
560   char *comp = NULL;
561   char *file = NULL;
562   char *function = NULL;
563   char *p;
564   char *start;
565   char *t;
566   short state;
567   int level;
568   int from_line, to_line;
569   int counter = 0;
570   int keep_looking = 1;
571
572   tmp = getenv (constname);
573   if (NULL == tmp)
574     return 0;
575   def = GNUNET_strdup (tmp);
576   from_line = 0;
577   to_line = INT_MAX;
578   for (p = def, state = 0, start = def; keep_looking; p++)
579   {
580     switch (p[0])
581     {
582     case ';':                  /* found a field separator */
583       p[0] = '\0';
584       switch (state)
585       {
586       case 0:                  /* within a component name */
587         comp = start;
588         break;
589       case 1:                  /* within a file name */
590         file = start;
591         break;
592       case 2:                  /* within a function name */
593         /* after a file name there must be a function name */
594         function = start;
595         break;
596       case 3:                  /* within a from-to line range */
597         if (strlen (start) > 0)
598         {
599           errno = 0;
600           from_line = strtol (start, &t, 10);
601           if ( (0 != errno) || (from_line < 0) )
602           {
603             GNUNET_free (def);
604             return counter;
605           }
606           if ( (t < p) && ('-' == t[0]) )
607           {
608             errno = 0;
609             start = t + 1;
610             to_line = strtol (start, &t, 10);
611             if ( (0 != errno) || (to_line < 0) || (t != p) )
612             {
613               GNUNET_free (def);
614               return counter;
615             }
616           }
617           else                  /* one number means "match this line only" */
618             to_line = from_line;
619         }
620         else                    /* default to 0-max */
621         {
622           from_line = 0;
623           to_line = INT_MAX;
624         }
625         break;
626       }
627       start = p + 1;
628       state++;
629       break;
630     case '\0':                 /* found EOL */
631       keep_looking = 0;
632       /* fall through to '/' */
633     case '/':                  /* found a definition separator */
634       switch (state)
635       {
636       case 4:                  /* within a log level */
637         p[0] = '\0';
638         state = 0;
639         level = get_type ((const char *) start);
640         if ( (GNUNET_ERROR_TYPE_INVALID == level) ||
641              (GNUNET_ERROR_TYPE_UNSPECIFIED == level) ||
642              (0 != add_definition (comp, file, function, from_line, to_line,
643                                    level, force)) )
644         {
645           GNUNET_free (def);
646           return counter;
647         }
648         counter++;
649         start = p + 1;
650         break;
651       default:
652         break;
653       }
654     default:
655       break;
656     }
657   }
658   GNUNET_free (def);
659   return counter;
660 }
661
662
663 /**
664  * Utility function - parses GNUNET_LOG and GNUNET_FORCE_LOG.
665  */
666 static void
667 parse_all_definitions ()
668 {
669   if (GNUNET_NO == gnunet_log_parsed)
670     parse_definitions ("GNUNET_LOG", 0);
671   gnunet_log_parsed = GNUNET_YES;
672   if (GNUNET_NO == gnunet_force_log_parsed)
673     gnunet_force_log_present =
674         parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO;
675   gnunet_force_log_parsed = GNUNET_YES;
676 }
677 #endif
678
679
680 /**
681  * Setup logging.
682  *
683  * @param comp default component to use
684  * @param loglevel what types of messages should be logged
685  * @param logfile which file to write log messages to (can be NULL)
686  * @return #GNUNET_OK on success
687  */
688 int
689 GNUNET_log_setup (const char *comp,
690                   const char *loglevel,
691                   const char *logfile)
692 {
693   const char *env_logfile;
694
695   min_level = get_type (loglevel);
696 #if !defined(GNUNET_CULL_LOGGING)
697   parse_all_definitions ();
698 #endif
699 #ifdef WINDOWS
700   QueryPerformanceFrequency (&performance_frequency);
701 #endif
702   GNUNET_free_non_null (component);
703   GNUNET_asprintf (&component, "%s-%d", comp, getpid ());
704   GNUNET_free_non_null (component_nopid);
705   component_nopid = GNUNET_strdup (comp);
706
707   env_logfile = getenv ("GNUNET_FORCE_LOGFILE");
708   if ((NULL != env_logfile) && (strlen (env_logfile) > 0))
709     logfile = env_logfile;
710   if (NULL == logfile)
711     return GNUNET_OK;
712   GNUNET_free_non_null (log_file_name);
713   log_file_name = GNUNET_STRINGS_filename_expand (logfile);
714   if (NULL == log_file_name)
715     return GNUNET_SYSERR;
716 #if TALER_WALLET_ONLY || defined(GNUNET_CULL_LOGGING)
717   /* log file option not allowed for wallet logic */
718   GNUNET_assert (NULL == logfile);
719   return GNUNET_OK;
720 #else
721   {
722     time_t t;
723     const struct tm *tm;
724
725     t = time (NULL);
726     tm = gmtime (&t);
727     return setup_log_file (tm);
728   }
729 #endif
730 }
731
732
733 /**
734  * Add a custom logger. Note that installing any custom logger
735  * will disable the standard logger.  When multiple custom loggers
736  * are installed, all will be called.  The standard logger will
737  * only be used if no custom loggers are present.
738  *
739  * @param logger log function
740  * @param logger_cls closure for @a logger
741  */
742 void
743 GNUNET_logger_add (GNUNET_Logger logger,
744                    void *logger_cls)
745 {
746   struct CustomLogger *entry;
747
748   entry = GNUNET_new (struct CustomLogger);
749   entry->logger = logger;
750   entry->logger_cls = logger_cls;
751   entry->next = loggers;
752   loggers = entry;
753 }
754
755
756 /**
757  * Remove a custom logger.
758  *
759  * @param logger log function
760  * @param logger_cls closure for @a logger
761  */
762 void
763 GNUNET_logger_remove (GNUNET_Logger logger,
764                       void *logger_cls)
765 {
766   struct CustomLogger *pos;
767   struct CustomLogger *prev;
768
769   prev = NULL;
770   pos = loggers;
771   while ((NULL != pos) &&
772          ((pos->logger != logger) || (pos->logger_cls != logger_cls)))
773   {
774     prev = pos;
775     pos = pos->next;
776   }
777   GNUNET_assert (NULL != pos);
778   if (NULL == prev)
779     loggers = pos->next;
780   else
781     prev->next = pos->next;
782   GNUNET_free (pos);
783 }
784
785 #if WINDOWS
786 CRITICAL_SECTION output_message_cs;
787 #endif
788
789
790 /**
791  * Actually output the log message.
792  *
793  * @param kind how severe was the issue
794  * @param comp component responsible
795  * @param datestr current date/time
796  * @param msg the actual message
797  */
798 static void
799 output_message (enum GNUNET_ErrorType kind,
800                 const char *comp,
801                 const char *datestr,
802                 const char *msg)
803 {
804   struct CustomLogger *pos;
805
806 #if WINDOWS
807   EnterCriticalSection (&output_message_cs);
808 #endif
809   /* only use the standard logger if no custom loggers are present */
810   if ( (NULL != GNUNET_stderr) &&
811        (NULL == loggers) )
812   {
813     if (kind == GNUNET_ERROR_TYPE_MESSAGE) {
814         /* The idea here is to produce "normal" output messages
815          * for end users while still having the power of the
816          * logging engine for developer needs. So ideally this
817          * is what it should look like when CLI tools are used
818          * interactively, yet the same message shouldn't look
819          * this way if the output is going to logfiles or robots
820          * instead. Is this the right place to do this? --lynX
821          */
822         FPRINTF (GNUNET_stderr,
823              "* %s",
824              msg);
825     } else {
826         FPRINTF (GNUNET_stderr,
827              "%s %s %s %s",
828              datestr,
829              comp,
830              GNUNET_error_type_to_string (kind),
831              msg);
832     }
833     fflush (GNUNET_stderr);
834   }
835   pos = loggers;
836   while (pos != NULL)
837   {
838     pos->logger (pos->logger_cls, kind, comp, datestr, msg);
839     pos = pos->next;
840   }
841 #if WINDOWS
842   LeaveCriticalSection (&output_message_cs);
843 #endif
844 }
845
846
847 /**
848  * Flush an existing bulk report to the output.
849  *
850  * @param datestr our current timestamp
851  */
852 static void
853 flush_bulk (const char *datestr)
854 {
855   char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
856   int rev;
857   char *last;
858   const char *ft;
859
860   if ( (0 == last_bulk_time.abs_value_us) ||
861        (0 == last_bulk_repeat) )
862     return;
863   rev = 0;
864   last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
865   if (last == NULL)
866     last = &last_bulk[BULK_TRACK_SIZE - 1];
867   else if (last != last_bulk)
868     last--;
869   if (last[0] == '\n')
870   {
871     rev = 1;
872     last[0] = '\0';
873   }
874   ft = GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration
875                                                (last_bulk_time), GNUNET_YES);
876   snprintf (msg, sizeof (msg),
877             _("Message `%.*s' repeated %u times in the last %s\n"),
878             BULK_TRACK_SIZE, last_bulk, last_bulk_repeat, ft);
879   if (rev == 1)
880     last[0] = '\n';
881   output_message (last_bulk_kind, last_bulk_comp, datestr, msg);
882   last_bulk_time = GNUNET_TIME_absolute_get ();
883   last_bulk_repeat = 0;
884 }
885
886
887 /**
888  * Ignore the next n calls to the log function.
889  *
890  * @param n number of log calls to ignore (could be negative)
891  * @param check_reset #GNUNET_YES to assert that the log skip counter is currently zero
892  */
893 void
894 GNUNET_log_skip (int n,
895                  int check_reset)
896 {
897   int ok;
898
899   if (0 == n)
900   {
901     ok = (0 == skip_log);
902     skip_log = 0;
903     if (check_reset)
904       GNUNET_break (ok);
905   }
906   else
907   {
908     skip_log += n;
909   }
910 }
911
912
913 /**
914  * Get the number of log calls that are going to be skipped
915  *
916  * @return number of log calls to be ignored
917  */
918 int
919 GNUNET_get_log_skip ()
920 {
921   return skip_log;
922 }
923
924
925 /**
926  * Output a log message using the default mechanism.
927  *
928  * @param kind how severe was the issue
929  * @param comp component responsible
930  * @param message the actual message
931  * @param va arguments to the format string "message"
932  */
933 static void
934 mylog (enum GNUNET_ErrorType kind,
935        const char *comp,
936        const char *message,
937        va_list va)
938 {
939   char date[DATE_STR_SIZE];
940   char date2[DATE_STR_SIZE];
941   struct tm *tmptr;
942   size_t size;
943   va_list vacp;
944
945   va_copy (vacp, va);
946   size = VSNPRINTF (NULL,
947                     0,
948                     message,
949                     vacp) + 1;
950   GNUNET_assert (0 != size);
951   va_end (vacp);
952   memset (date,
953           0,
954           DATE_STR_SIZE);
955   {
956     char buf[size];
957     long long offset;
958 #ifdef WINDOWS
959     LARGE_INTEGER pc;
960     time_t timetmp;
961
962     offset = GNUNET_TIME_get_offset ();
963     time (&timetmp);
964     timetmp += offset / 1000;
965     tmptr = localtime (&timetmp);
966     pc.QuadPart = 0;
967     QueryPerformanceCounter (&pc);
968     if (NULL == tmptr)
969     {
970       strcpy (date, "localtime error");
971     }
972     else
973     {
974       if (0 ==
975           strftime (date2,
976                     DATE_STR_SIZE,
977                     "%b %d %H:%M:%S-%%020llu",
978                     tmptr))
979         abort ();
980       if (0 >
981           snprintf (date,
982                     sizeof (date),
983                     date2,
984                     (long long) (pc.QuadPart /
985                                  (performance_frequency.QuadPart / 1000))))
986         abort ();
987     }
988 #else
989     struct timeval timeofday;
990
991     gettimeofday (&timeofday,
992                   NULL);
993     offset = GNUNET_TIME_get_offset ();
994     if (offset > 0)
995     {
996       timeofday.tv_sec += offset / 1000LL;
997       timeofday.tv_usec += (offset % 1000LL) * 1000LL;
998       if (timeofday.tv_usec > 1000000LL)
999       {
1000         timeofday.tv_usec -= 1000000LL;
1001         timeofday.tv_sec++;
1002       }
1003     }
1004     else
1005     {
1006       timeofday.tv_sec += offset / 1000LL;
1007       if (timeofday.tv_usec > - (offset % 1000LL) * 1000LL)
1008       {
1009         timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1010       }
1011       else
1012       {
1013         timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL;
1014         timeofday.tv_sec--;
1015       }
1016     }
1017     tmptr = localtime (&timeofday.tv_sec);
1018     if (NULL == tmptr)
1019     {
1020       strcpy (date,
1021               "localtime error");
1022     }
1023     else
1024     {
1025       if (0 ==
1026           strftime (date2,
1027                     DATE_STR_SIZE,
1028                     "%b %d %H:%M:%S-%%06u",
1029                     tmptr))
1030         abort ();
1031       if (0 >
1032           snprintf (date,
1033                     sizeof (date),
1034                     date2,
1035                     timeofday.tv_usec))
1036         abort ();
1037     }
1038 #endif
1039     VSNPRINTF (buf,
1040                size,
1041                message,
1042                va);
1043 #if ! (defined(GNUNET_CULL_LOGGING) || TALER_WALLET_ONLY)
1044     if (NULL != tmptr)
1045       (void) setup_log_file (tmptr);
1046 #endif
1047     if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
1048         (0 != last_bulk_time.abs_value_us) &&
1049         (0 == strncmp (buf,
1050                        last_bulk,
1051                        sizeof (last_bulk))))
1052     {
1053       last_bulk_repeat++;
1054       if ( (GNUNET_TIME_absolute_get_duration (last_bulk_time).rel_value_us >
1055             BULK_DELAY_THRESHOLD) ||
1056            (last_bulk_repeat > BULK_REPEAT_THRESHOLD) )
1057         flush_bulk (date);
1058       return;
1059     }
1060     flush_bulk (date);
1061     strncpy (last_bulk,
1062              buf,
1063              sizeof (last_bulk));
1064     last_bulk_repeat = 0;
1065     last_bulk_kind = kind;
1066     last_bulk_time = GNUNET_TIME_absolute_get ();
1067     strncpy (last_bulk_comp,
1068              comp,
1069              COMP_TRACK_SIZE);
1070     output_message (kind,
1071                     comp,
1072                     date,
1073                     buf);
1074   }
1075 }
1076
1077
1078 /**
1079  * Main log function.
1080  *
1081  * @param kind how serious is the error?
1082  * @param message what is the message (format string)
1083  * @param ... arguments for format string
1084  */
1085 void
1086 GNUNET_log_nocheck (enum GNUNET_ErrorType kind,
1087                     const char *message, ...)
1088 {
1089   va_list va;
1090
1091   va_start (va, message);
1092   mylog (kind, component, message, va);
1093   va_end (va);
1094 }
1095
1096
1097 /**
1098  * Log function that specifies an alternative component.
1099  * This function should be used by plugins.
1100  *
1101  * @param kind how serious is the error?
1102  * @param comp component responsible for generating the message
1103  * @param message what is the message (format string)
1104  * @param ... arguments for format string
1105  */
1106 void
1107 GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind, const char *comp,
1108                          const char *message, ...)
1109 {
1110   va_list va;
1111   char comp_w_pid[128];
1112
1113   if (comp == NULL)
1114     comp = component_nopid;
1115
1116   va_start (va, message);
1117   GNUNET_snprintf (comp_w_pid, sizeof (comp_w_pid), "%s-%d", comp, getpid ());
1118   mylog (kind, comp_w_pid, message, va);
1119   va_end (va);
1120 }
1121
1122
1123 /**
1124  * Convert error type to string.
1125  *
1126  * @param kind type to convert
1127  * @return string corresponding to the type
1128  */
1129 const char *
1130 GNUNET_error_type_to_string (enum GNUNET_ErrorType kind)
1131 {
1132   if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
1133     return _("ERROR");
1134   if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
1135     return _("WARNING");
1136   if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0)
1137     return _("MESSAGE");
1138   if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
1139     return _("INFO");
1140   if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
1141     return _("DEBUG");
1142   if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0)
1143     return _("NONE");
1144   return _("INVALID");
1145 }
1146
1147
1148 /**
1149  * Convert a hash to a string (for printing debug messages).
1150  * This is one of the very few calls in the entire API that is
1151  * NOT reentrant!
1152  *
1153  * @param hc the hash code
1154  * @return string form; will be overwritten by next call to GNUNET_h2s.
1155  */
1156 const char *
1157 GNUNET_h2s (const struct GNUNET_HashCode * hc)
1158 {
1159   static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1160
1161   GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1162   ret.encoding[8] = '\0';
1163   return (const char *) ret.encoding;
1164 }
1165
1166
1167 /**
1168  * Convert a hash to a string (for printing debug messages).
1169  * This is one of the very few calls in the entire API that is
1170  * NOT reentrant! Identical to #GNUNET_h2s(), except that another
1171  * buffer is used so both #GNUNET_h2s() and #GNUNET_h2s2() can be
1172  * used within the same log statement.
1173  *
1174  * @param hc the hash code
1175  * @return string form; will be overwritten by next call to GNUNET_h2s.
1176  */
1177 const char *
1178 GNUNET_h2s2 (const struct GNUNET_HashCode * hc)
1179 {
1180   static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1181
1182   GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1183   ret.encoding[8] = '\0';
1184   return (const char *) ret.encoding;
1185 }
1186
1187
1188 /**
1189  * @ingroup logging
1190  * Convert a public key value to a string (for printing debug messages).
1191  * This is one of the very few calls in the entire API that is
1192  * NOT reentrant!
1193  *
1194  * @param hc the hash code
1195  * @return string
1196  */
1197 const char *
1198 GNUNET_p2s (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
1199 {
1200   static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1201   struct GNUNET_HashCode hc;
1202
1203   GNUNET_CRYPTO_hash (p,
1204                       sizeof (*p),
1205                       &hc);
1206   GNUNET_CRYPTO_hash_to_enc (&hc,
1207                              &ret);
1208   ret.encoding[6] = '\0';
1209   return (const char *) ret.encoding;
1210 }
1211
1212
1213 /**
1214  * @ingroup logging
1215  * Convert a public key value to a string (for printing debug messages).
1216  * This is one of the very few calls in the entire API that is
1217  * NOT reentrant!
1218  *
1219  * @param hc the hash code
1220  * @return string
1221  */
1222 const char *
1223 GNUNET_p2s2 (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
1224 {
1225   static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1226   struct GNUNET_HashCode hc;
1227
1228   GNUNET_CRYPTO_hash (p,
1229                       sizeof (*p),
1230                       &hc);
1231   GNUNET_CRYPTO_hash_to_enc (&hc,
1232                              &ret);
1233   ret.encoding[6] = '\0';
1234   return (const char *) ret.encoding;
1235 }
1236
1237
1238 /**
1239  * @ingroup logging
1240  * Convert a public key value to a string (for printing debug messages).
1241  * This is one of the very few calls in the entire API that is
1242  * NOT reentrant!
1243  *
1244  * @param hc the hash code
1245  * @return string
1246  */
1247 const char *
1248 GNUNET_e2s (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
1249 {
1250   static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1251   struct GNUNET_HashCode hc;
1252
1253   GNUNET_CRYPTO_hash (p,
1254                       sizeof (*p),
1255                       &hc);
1256   GNUNET_CRYPTO_hash_to_enc (&hc,
1257                              &ret);
1258   ret.encoding[6] = '\0';
1259   return (const char *) ret.encoding;
1260 }
1261
1262
1263 /**
1264  * @ingroup logging
1265  * Convert a public key value to a string (for printing debug messages).
1266  * This is one of the very few calls in the entire API that is
1267  * NOT reentrant!
1268  *
1269  * @param hc the hash code
1270  * @return string
1271  */
1272 const char *
1273 GNUNET_e2s2 (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
1274 {
1275   static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1276   struct GNUNET_HashCode hc;
1277
1278   GNUNET_CRYPTO_hash (p,
1279                       sizeof (*p),
1280                       &hc);
1281   GNUNET_CRYPTO_hash_to_enc (&hc,
1282                              &ret);
1283   ret.encoding[6] = '\0';
1284   return (const char *) ret.encoding;
1285 }
1286
1287
1288 /**
1289  * @ingroup logging
1290  * Convert a short hash value to a string (for printing debug messages).
1291  * This is one of the very few calls in the entire API that is
1292  * NOT reentrant!
1293  *
1294  * @param shc the hash code
1295  * @return string
1296  */
1297 const char *
1298 GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc)
1299 {
1300   static char buf[64];
1301
1302   GNUNET_STRINGS_data_to_string (shc,
1303                                  sizeof (*shc),
1304                                  buf,
1305                                  sizeof (buf));
1306   buf[6] = '\0';
1307   return (const char *) buf;
1308 }
1309
1310
1311 /**
1312  * Convert a hash to a string (for printing debug messages).
1313  * This is one of the very few calls in the entire API that is
1314  * NOT reentrant!
1315  *
1316  * @param hc the hash code
1317  * @return string form; will be overwritten by next call to GNUNET_h2s_full.
1318  */
1319 const char *
1320 GNUNET_h2s_full (const struct GNUNET_HashCode * hc)
1321 {
1322   static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1323
1324   GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1325   ret.encoding[sizeof (ret) - 1] = '\0';
1326   return (const char *) ret.encoding;
1327 }
1328
1329
1330 /**
1331  * Convert a peer identity to a string (for printing debug messages).
1332  * This is one of the very few calls in the entire API that is
1333  * NOT reentrant!
1334  *
1335  * @param pid the peer identity
1336  * @return string form of the pid; will be overwritten by next
1337  *         call to #GNUNET_i2s.
1338  */
1339 const char *
1340 GNUNET_i2s (const struct GNUNET_PeerIdentity *pid)
1341 {
1342   static char buf[5];
1343   char *ret;
1344
1345   if (NULL == pid)
1346     return "NULL";
1347   ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
1348   strncpy (buf,
1349            ret,
1350            sizeof (buf) - 1);
1351   GNUNET_free (ret);
1352   buf[4] = '\0';
1353   return buf;
1354 }
1355
1356
1357 /**
1358  * Convert a peer identity to a string (for printing debug messages).
1359  * This is one of the very few calls in the entire API that is
1360  * NOT reentrant!  Identical to #GNUNET_i2s(), except that another
1361  * buffer is used so both #GNUNET_i2s() and #GNUNET_i2s2() can be
1362  * used within the same log statement.
1363  *
1364  * @param pid the peer identity
1365  * @return string form of the pid; will be overwritten by next
1366  *         call to #GNUNET_i2s.
1367  */
1368 const char *
1369 GNUNET_i2s2 (const struct GNUNET_PeerIdentity *pid)
1370 {
1371   static char buf[5];
1372   char *ret;
1373
1374   if (NULL == pid)
1375     return "NULL";
1376   ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
1377   strncpy (buf,
1378            ret,
1379            sizeof (buf) - 1);
1380   GNUNET_free (ret);
1381   buf[4] = '\0';
1382   return buf;
1383 }
1384
1385
1386 /**
1387  * Convert a peer identity to a string (for printing debug messages).
1388  * This is one of the very few calls in the entire API that is
1389  * NOT reentrant!
1390  *
1391  * @param pid the peer identity
1392  * @return string form of the pid; will be overwritten by next
1393  *         call to #GNUNET_i2s_full.
1394  */
1395 const char *
1396 GNUNET_i2s_full (const struct GNUNET_PeerIdentity *pid)
1397 {
1398   static char buf[256];
1399   char *ret;
1400
1401   ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
1402   strcpy (buf, ret);
1403   GNUNET_free (ret);
1404   return buf;
1405 }
1406
1407
1408 /**
1409  * Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string
1410  * (for printing debug messages).  This is one of the very few calls
1411  * in the entire API that is NOT reentrant!
1412  *
1413  * @param addr the address
1414  * @param addrlen the length of the address in @a addr
1415  * @return nicely formatted string for the address
1416  *  will be overwritten by next call to #GNUNET_a2s.
1417  */
1418 const char *
1419 GNUNET_a2s (const struct sockaddr *addr,
1420             socklen_t addrlen)
1421 {
1422 #ifndef WINDOWS
1423 #define LEN GNUNET_MAX ((INET6_ADDRSTRLEN + 8),         \
1424                         (1 + sizeof (struct sockaddr_un) - sizeof (sa_family_t)))
1425 #else
1426 #define LEN (INET6_ADDRSTRLEN + 8)
1427 #endif
1428   static char buf[LEN];
1429 #undef LEN
1430   static char b2[6];
1431   const struct sockaddr_in *v4;
1432   const struct sockaddr_un *un;
1433   const struct sockaddr_in6 *v6;
1434   unsigned int off;
1435
1436   if (addr == NULL)
1437     return _("unknown address");
1438   switch (addr->sa_family)
1439   {
1440   case AF_INET:
1441     if (addrlen != sizeof (struct sockaddr_in))
1442       return "<invalid v4 address>";
1443     v4 = (const struct sockaddr_in *) addr;
1444     inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN);
1445     if (0 == ntohs (v4->sin_port))
1446       return buf;
1447     strcat (buf, ":");
1448     GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v4->sin_port));
1449     strcat (buf, b2);
1450     return buf;
1451   case AF_INET6:
1452     if (addrlen != sizeof (struct sockaddr_in6))
1453       return "<invalid v4 address>";
1454     v6 = (const struct sockaddr_in6 *) addr;
1455     buf[0] = '[';
1456     inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN);
1457     if (0 == ntohs (v6->sin6_port))
1458       return &buf[1];
1459     strcat (buf, "]:");
1460     GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v6->sin6_port));
1461     strcat (buf, b2);
1462     return buf;
1463   case AF_UNIX:
1464     if (addrlen <= sizeof (sa_family_t))
1465       return "<unbound UNIX client>";
1466     un = (const struct sockaddr_un *) addr;
1467     off = 0;
1468     if ('\0' == un->sun_path[0])
1469       off++;
1470     memset (buf, 0, sizeof (buf));
1471     GNUNET_snprintf (buf,
1472                      sizeof (buf),
1473                      "%s%.*s",
1474                      (1 == off) ? "@" : "",
1475                      (int) (addrlen - sizeof (sa_family_t) - off),
1476                      &un->sun_path[off]);
1477     return buf;
1478   default:
1479     return _("invalid address");
1480   }
1481 }
1482
1483
1484 /**
1485  * Log error message about missing configuration option.
1486  *
1487  * @param kind log level
1488  * @param section section with missing option
1489  * @param option name of missing option
1490  */
1491 void
1492 GNUNET_log_config_missing (enum GNUNET_ErrorType kind,
1493                            const char *section,
1494                            const char *option)
1495 {
1496   GNUNET_log (kind,
1497               _("Configuration fails to specify option `%s' in section `%s'!\n"),
1498               option,
1499               section);
1500 }
1501
1502
1503 /**
1504  * Log error message about invalid configuration option value.
1505  *
1506  * @param kind log level
1507  * @param section section with invalid option
1508  * @param option name of invalid option
1509  * @param required what is required that is invalid about the option
1510  */
1511 void
1512 GNUNET_log_config_invalid (enum GNUNET_ErrorType kind,
1513                            const char *section,
1514                            const char *option,
1515                            const char *required)
1516 {
1517   GNUNET_log (kind,
1518               _("Configuration specifies invalid value for option `%s' in section `%s': %s\n"),
1519               option, section, required);
1520 }
1521
1522
1523 /**
1524  * Initializer
1525  */
1526 void __attribute__ ((constructor))
1527 GNUNET_util_cl_init ()
1528 {
1529   GNUNET_stderr = stderr;
1530 #ifdef MINGW
1531   GNInitWinEnv (NULL);
1532 #endif
1533 #if WINDOWS
1534   if (!InitializeCriticalSectionAndSpinCount (&output_message_cs, 0x00000400))
1535     GNUNET_abort_ ();
1536 #endif
1537 }
1538
1539
1540 /**
1541  * Destructor
1542  */
1543 void __attribute__ ((destructor))
1544 GNUNET_util_cl_fini ()
1545 {
1546 #if WINDOWS
1547   DeleteCriticalSection (&output_message_cs);
1548 #endif
1549 #ifdef MINGW
1550   GNShutdownWinEnv ();
1551 #endif
1552 }
1553
1554 /* end of common_logging.c */