GNUnet  0.11.x
common_logging.c
Go to the documentation of this file.
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 Affero 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  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
26 #include "platform.h"
27 #include "gnunet_crypto_lib.h"
28 #include "gnunet_disk_lib.h"
29 #include "gnunet_strings_lib.h"
30 #include <regex.h>
31 
32 
37 #define BULK_DELAY_THRESHOLD (12 * 60 * 60 * 1000LL * 1000LL)
38 
44 #define BULK_REPEAT_THRESHOLD 1000
45 
50 #define BULK_TRACK_SIZE 256
51 
56 #define COMP_TRACK_SIZE 32
57 
62 #define DATE_STR_SIZE 64
63 
67 #define ROTATION_KEEP 3
68 
69 #ifndef PATH_MAX
70 
73 #define PATH_MAX 4096
74 #endif
75 
76 
81 {
85  struct CustomLogger *next;
86 
91 
95  void *logger_cls;
96 };
97 
98 
104 
111 
116 
121 
126 
131 
135 static char *component;
136 
140 static char *component_nopid;
141 
145 static char *log_file_name;
146 
151 
155 static struct CustomLogger *loggers;
156 
161 
165 static FILE *GNUNET_stderr;
166 
170 struct LogDef
171 {
176 
180  regex_t file_regex;
181 
185  regex_t function_regex;
186 
192 
197  int to_line;
198 
204  int level;
205 
210  int force;
211 };
212 
213 
214 #if ! defined(GNUNET_CULL_LOGGING)
215 
218 static struct LogDef *logdefs;
219 
223 static int logdefs_size;
224 
228 static int logdefs_len;
229 
233 static int gnunet_log_parsed;
234 
239 
244 #endif
245 
246 
254 static enum GNUNET_ErrorType
255 get_type (const char *log)
256 {
257  if (NULL == log)
259  if (0 == strcasecmp (log, _ ("DEBUG")))
261  if (0 == strcasecmp (log, _ ("INFO")))
262  return GNUNET_ERROR_TYPE_INFO;
263  if (0 == strcasecmp (log, _ ("MESSAGE")))
265  if (0 == strcasecmp (log, _ ("WARNING")))
267  if (0 == strcasecmp (log, _ ("ERROR")))
269  if (0 == strcasecmp (log, _ ("NONE")))
270  return GNUNET_ERROR_TYPE_NONE;
272 }
273 
274 
278 void
280 {
281  abort ();
282 }
283 
284 
285 #if ! defined(GNUNET_CULL_LOGGING)
286 
289 static void
291 {
292  logdefs_size = (logdefs_size + 1) * 2;
293  logdefs = GNUNET_realloc (logdefs, logdefs_size * sizeof(struct LogDef));
294 }
295 
296 
302 static void
303 log_rotate (const char *new_name)
304 {
305  static char *rotation[ROTATION_KEEP];
306  static unsigned int rotation_off;
307  char *discard;
308 
309  if ('\0' == *new_name)
310  return; /* not a real log file name */
311  discard = rotation[rotation_off % ROTATION_KEEP];
312  if (NULL != discard)
313  {
314  /* Note: can't log errors during logging (recursion!), so this
315  operation MUST silently fail... */
316  (void) unlink (discard);
317  GNUNET_free (discard);
318  }
319  rotation[rotation_off % ROTATION_KEEP] = GNUNET_strdup (new_name);
320  rotation_off++;
321 }
322 
323 
330 static int
331 setup_log_file (const struct tm *tm)
332 {
333  static char last_fn[PATH_MAX + 1];
334  char fn[PATH_MAX + 1];
335  int altlog_fd;
336  int dup_return;
337  FILE *altlog;
338  char *leftsquare;
339 
340  if (NULL == log_file_name)
341  return GNUNET_SYSERR;
342  if (0 == strftime (fn, sizeof(fn), log_file_name, tm))
343  return GNUNET_SYSERR;
344  leftsquare = strrchr (fn, '[');
345  if ((NULL != leftsquare) && (']' == leftsquare[1]))
346  {
347  char *logfile_copy = GNUNET_strdup (fn);
348 
349  logfile_copy[leftsquare - fn] = '\0';
350  logfile_copy[leftsquare - fn + 1] = '\0';
351  snprintf (fn,
352  PATH_MAX,
353  "%s%d%s",
354  logfile_copy,
355  getpid (),
356  &logfile_copy[leftsquare - fn + 2]);
357  GNUNET_free (logfile_copy);
358  }
359  if (0 == strcmp (fn, last_fn))
360  return GNUNET_OK; /* no change */
361  log_rotate (last_fn);
362  strcpy (last_fn, 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  altlog_fd = open (fn,
372  O_APPEND | O_WRONLY | O_CREAT,
373  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
374 
375  if (-1 != altlog_fd)
376  {
377  if (NULL != GNUNET_stderr)
378  fclose (GNUNET_stderr);
379  dup_return = dup2 (altlog_fd, 2);
380  (void) close (altlog_fd);
381  if (-1 != dup_return)
382  {
383  altlog = fdopen (2, "ab");
384  if (NULL == altlog)
385  {
386  (void) close (2);
387  altlog_fd = -1;
388  }
389  }
390  else
391  {
392  altlog_fd = -1;
393  }
394  }
395  if (-1 == altlog_fd)
396  {
398  return GNUNET_SYSERR;
399  }
400  GNUNET_stderr = altlog;
401  return GNUNET_OK;
402 }
403 
404 
417 static int
419  const char *file,
420  const char *function,
421  int from_line,
422  int to_line,
423  int level,
424  int force)
425 {
426  struct LogDef n;
427  int r;
428 
429  if (logdefs_size == logdefs_len)
430  resize_logdefs ();
431  memset (&n, 0, sizeof(n));
432  if (0 == strlen (component))
433  component = (char *) ".*";
434  r = regcomp (&n.component_regex, (const char *) component, REG_NOSUB);
435  if (0 != r)
436  {
437  return r;
438  }
439  if (0 == strlen (file))
440  file = (char *) ".*";
441  r = regcomp (&n.file_regex, (const char *) file, REG_NOSUB);
442  if (0 != r)
443  {
444  regfree (&n.component_regex);
445  return r;
446  }
447  if ((NULL == function) || (0 == strlen (function)))
448  function = (char *) ".*";
449  r = regcomp (&n.function_regex, (const char *) function, REG_NOSUB);
450  if (0 != r)
451  {
452  regfree (&n.component_regex);
453  regfree (&n.file_regex);
454  return r;
455  }
456  n.from_line = from_line;
457  n.to_line = to_line;
458  n.level = level;
459  n.force = force;
460  logdefs[logdefs_len++] = n;
461  return 0;
462 }
463 
464 
478 int
479 GNUNET_get_log_call_status (int caller_level,
480  const char *comp,
481  const char *file,
482  const char *function,
483  int line)
484 {
485  struct LogDef *ld;
486  int i;
487  int force_only;
488 
489  if (NULL == comp)
490  /* Use default component */
491  comp = component_nopid;
492 
493  /* We have no definitions to override globally configured log level,
494  * so just use it right away.
495  */
496  if ((min_level >= 0) && (GNUNET_NO == gnunet_force_log_present))
497  return caller_level <= min_level;
498 
499  /* Only look for forced definitions? */
500  force_only = min_level >= 0;
501  for (i = 0; i < logdefs_len; i++)
502  {
503  ld = &logdefs[i];
504  if (((! force_only) || ld->force) &&
505  ((line >= ld->from_line) && (line <= ld->to_line) ) &&
506  (0 == regexec (&ld->component_regex, comp, 0, NULL, 0)) &&
507  (0 == regexec (&ld->file_regex, file, 0, NULL, 0)) &&
508  (0 == regexec (&ld->function_regex, function, 0, NULL, 0)))
509  {
510  /* We're finished */
511  return caller_level <= ld->level;
512  }
513  }
514  /* No matches - use global level, if defined */
515  if (min_level >= 0)
516  return caller_level <= min_level;
517  /* All programs/services previously defaulted to WARNING.
518  * Now *we* default to WARNING, and THEY default to NULL.
519  * Or rather we default to MESSAGE, since things aren't always bad.
520  */
521  return caller_level <= GNUNET_ERROR_TYPE_MESSAGE;
522 }
523 
524 
548 static int
549 parse_definitions (const char *constname, int force)
550 {
551  char *def;
552  const char *tmp;
553  char *comp = NULL;
554  char *file = NULL;
555  char *function = NULL;
556  char *p;
557  char *start;
558  char *t;
559  short state;
560  int level;
561  int from_line, to_line;
562  int counter = 0;
563  int keep_looking = 1;
564 
565  tmp = getenv (constname);
566  if (NULL == tmp)
567  return 0;
568  def = GNUNET_strdup (tmp);
569  from_line = 0;
570  to_line = INT_MAX;
571  for (p = def, state = 0, start = def; keep_looking; p++)
572  {
573  switch (p[0])
574  {
575  case ';': /* found a field separator */
576  p[0] = '\0';
577  switch (state)
578  {
579  case 0: /* within a component name */
580  comp = start;
581  break;
582 
583  case 1: /* within a file name */
584  file = start;
585  break;
586 
587  case 2: /* within a function name */
588  /* after a file name there must be a function name */
589  function = start;
590  break;
591 
592  case 3: /* within a from-to line range */
593  if (strlen (start) > 0)
594  {
595  errno = 0;
596  from_line = strtol (start, &t, 10);
597  if ((0 != errno) || (from_line < 0))
598  {
599  GNUNET_free (def);
600  return counter;
601  }
602  if ((t < p) && ('-' == t[0]))
603  {
604  errno = 0;
605  start = t + 1;
606  to_line = strtol (start, &t, 10);
607  if ((0 != errno) || (to_line < 0) || (t != p))
608  {
609  GNUNET_free (def);
610  return counter;
611  }
612  }
613  else /* one number means "match this line only" */
614  to_line = from_line;
615  }
616  else /* default to 0-max */
617  {
618  from_line = 0;
619  to_line = INT_MAX;
620  }
621  break;
622 
623  default:
624  fprintf (
625  stderr,
626  _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
627  p);
628  break;
629  }
630  start = p + 1;
631  state++;
632  break;
633 
634  case '\0': /* found EOL */
635  keep_looking = 0;
636 
637  /* fall through to '/' */
638  case '/': /* found a definition separator */
639  switch (state)
640  {
641  case 4: /* within a log level */
642  p[0] = '\0';
643  state = 0;
644  level = get_type ((const char *) start);
645  if ((GNUNET_ERROR_TYPE_INVALID == level) ||
646  (GNUNET_ERROR_TYPE_UNSPECIFIED == level) ||
647  (0 != add_definition (comp,
648  file,
649  function,
650  from_line,
651  to_line,
652  level,
653  force)))
654  {
655  GNUNET_free (def);
656  return counter;
657  }
658  counter++;
659  start = p + 1;
660  break;
661 
662  default:
663  fprintf (
664  stderr,
665  _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
666  p);
667  break;
668  }
669 
670  default:
671  break;
672  }
673  }
674  GNUNET_free (def);
675  return counter;
676 }
677 
678 
682 static void
684 {
687  parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO;
689 
691  parse_definitions ("GNUNET_LOG", 0);
693 }
694 
695 
696 #endif
697 
698 
707 int
708 GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile)
709 {
710  const char *env_logfile;
711 
712  min_level = get_type (loglevel);
713 #if ! defined(GNUNET_CULL_LOGGING)
715 #endif
717  GNUNET_asprintf (&component, "%s-%d", comp, getpid ());
720 
721  env_logfile = getenv ("GNUNET_FORCE_LOGFILE");
722  if ((NULL != env_logfile) && (strlen (env_logfile) > 0))
723  logfile = env_logfile;
724  if (NULL == logfile)
725  return GNUNET_OK;
728  if (NULL == log_file_name)
729  return GNUNET_SYSERR;
730 #if defined(GNUNET_CULL_LOGGING)
731  /* log file option not allowed for wallet logic */
732  GNUNET_assert (NULL == logfile);
733  return GNUNET_OK;
734 #else
735  {
736  time_t t;
737  const struct tm *tm;
738 
739  t = time (NULL);
740  tm = gmtime (&t);
741  return setup_log_file (tm);
742  }
743 #endif
744 }
745 
746 
756 void
758 {
759  struct CustomLogger *entry;
760 
761  entry = GNUNET_new (struct CustomLogger);
762  entry->logger = logger;
763  entry->logger_cls = logger_cls;
764  entry->next = loggers;
765  loggers = entry;
766 }
767 
768 
775 void
777 {
778  struct CustomLogger *pos;
779  struct CustomLogger *prev;
780 
781  prev = NULL;
782  pos = loggers;
783  while ((NULL != pos) &&
784  ((pos->logger != logger) || (pos->logger_cls != logger_cls)))
785  {
786  prev = pos;
787  pos = pos->next;
788  }
789  GNUNET_assert (NULL != pos);
790  if (NULL == prev)
791  loggers = pos->next;
792  else
793  prev->next = pos->next;
794  GNUNET_free (pos);
795 }
796 
797 
806 static void
808  const char *comp,
809  const char *datestr,
810  const char *msg)
811 {
812  struct CustomLogger *pos;
813 
814  /* only use the standard logger if no custom loggers are present */
815  if ((NULL != GNUNET_stderr) && (NULL == loggers))
816  {
817  if (kind == GNUNET_ERROR_TYPE_MESSAGE)
818  {
819  /* The idea here is to produce "normal" output messages
820  * for end users while still having the power of the
821  * logging engine for developer needs. So ideally this
822  * is what it should look like when CLI tools are used
823  * interactively, yet the same message shouldn't look
824  * this way if the output is going to logfiles or robots
825  * instead.
826  */fprintf (GNUNET_stderr, "* %s", msg);
827  }
829  {
830  static GNUNET_THREAD_LOCAL char id_buf[27];
831  char *end;
832 
833  /* We're logging, so skip_log must be currently 0. */
834  skip_log = 100;
836  sizeof(struct GNUNET_AsyncScopeId),
837  id_buf,
838  sizeof(id_buf) - 1);
839  GNUNET_assert (NULL != end);
840  *end = '\0';
841  skip_log = 0;
842  fprintf (GNUNET_stderr,
843  "%s %s(%s) %s %s",
844  datestr,
845  comp,
846  id_buf,
848  msg);
849  }
850  else
851  {
852  fprintf (GNUNET_stderr,
853  "%s %s %s %s",
854  datestr,
855  comp,
857  msg);
858  }
859  fflush (GNUNET_stderr);
860  }
861  pos = loggers;
862  while (NULL != pos)
863  {
864  pos->logger (pos->logger_cls, kind, comp, datestr, msg);
865  pos = pos->next;
866  }
867 }
868 
869 
875 static void
876 flush_bulk (const char *datestr)
877 {
878  char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
879  int rev;
880  char *last;
881  const char *ft;
882 
883  if ((0 == last_bulk_time.abs_value_us) || (0 == last_bulk_repeat))
884  return;
885  rev = 0;
886  last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
887  if (last == NULL)
888  last = &last_bulk[BULK_TRACK_SIZE - 1];
889  else if (last != last_bulk)
890  last--;
891  if (last[0] == '\n')
892  {
893  rev = 1;
894  last[0] = '\0';
895  }
896  ft =
899  GNUNET_YES);
900  snprintf (msg,
901  sizeof(msg),
902  _ ("Message `%.*s' repeated %u times in the last %s\n"),
904  last_bulk,
906  ft);
907  if (rev == 1)
908  last[0] = '\n';
911  last_bulk_repeat = 0;
912 }
913 
914 
921 void
922 GNUNET_log_skip (int n, int check_reset)
923 {
924  int ok;
925 
926  if (0 == n)
927  {
928  ok = (0 == skip_log);
929  skip_log = 0;
930  if (check_reset)
931  GNUNET_break (ok);
932  }
933  else
934  {
935  skip_log += n;
936  }
937 }
938 
939 
945 int
947 {
948  return skip_log;
949 }
950 
951 
960 static void
962  const char *comp,
963  const char *message,
964  va_list va)
965 {
966  char date[DATE_STR_SIZE];
967  char date2[DATE_STR_SIZE];
968  struct tm *tmptr;
969  size_t size;
970  va_list vacp;
971 
972  va_copy (vacp, va);
973  size = vsnprintf (NULL, 0, message, vacp) + 1;
974  GNUNET_assert (0 != size);
975  va_end (vacp);
976  memset (date, 0, DATE_STR_SIZE);
977  {
978  char buf[size];
979  long long offset;
980 
981  struct timeval timeofday;
982 
983  gettimeofday (&timeofday, NULL);
984  offset = GNUNET_TIME_get_offset ();
985  if (offset > 0)
986  {
987  timeofday.tv_sec += offset / 1000LL;
988  timeofday.tv_usec += (offset % 1000LL) * 1000LL;
989  if (timeofday.tv_usec > 1000000LL)
990  {
991  timeofday.tv_usec -= 1000000LL;
992  timeofday.tv_sec++;
993  }
994  }
995  else
996  {
997  timeofday.tv_sec += offset / 1000LL;
998  if (timeofday.tv_usec > -(offset % 1000LL) * 1000LL)
999  {
1000  timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1001  }
1002  else
1003  {
1004  timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL;
1005  timeofday.tv_sec--;
1006  }
1007  }
1008  tmptr = localtime (&timeofday.tv_sec);
1009  if (NULL == tmptr)
1010  {
1011  strcpy (date, "localtime error");
1012  }
1013  else
1014  {
1015  if (0 == strftime (date2, DATE_STR_SIZE, "%b %d %H:%M:%S-%%06u", tmptr))
1016  abort ();
1017  if (0 > snprintf (date, sizeof(date), date2, timeofday.tv_usec))
1018  abort ();
1019  }
1020 
1021  vsnprintf (buf, size, message, va);
1022 #if ! defined(GNUNET_CULL_LOGGING)
1023  if (NULL != tmptr)
1024  (void) setup_log_file (tmptr);
1025 #endif
1026  if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
1027  (0 != last_bulk_time.abs_value_us) &&
1028  (0 == strncmp (buf, last_bulk, sizeof(last_bulk))))
1029  {
1030  last_bulk_repeat++;
1034  flush_bulk (date);
1035  return;
1036  }
1037  flush_bulk (date);
1038  GNUNET_strlcpy (last_bulk, buf, sizeof(last_bulk));
1039  last_bulk_repeat = 0;
1040  last_bulk_kind = kind;
1042  GNUNET_strlcpy (last_bulk_comp, comp, sizeof(last_bulk_comp));
1043  output_message (kind, comp, date, buf);
1044  }
1045 }
1046 
1047 
1055 void
1056 GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...)
1057 {
1058  va_list va;
1059 
1060  va_start (va, message);
1061  mylog (kind, component, message, va);
1062  va_end (va);
1063 }
1064 
1065 
1075 void
1077  const char *comp,
1078  const char *message,
1079  ...)
1080 {
1081  va_list va;
1082  char comp_w_pid[128];
1083 
1084  if (comp == NULL)
1085  comp = component_nopid;
1086 
1087  va_start (va, message);
1088  GNUNET_snprintf (comp_w_pid, sizeof(comp_w_pid), "%s-%d", comp, getpid ());
1089  mylog (kind, comp_w_pid, message, va);
1090  va_end (va);
1091 }
1092 
1093 
1100 const char *
1102 {
1103  if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
1104  return _ ("ERROR");
1105  if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
1106  return _ ("WARNING");
1107  if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0)
1108  return _ ("MESSAGE");
1109  if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
1110  return _ ("INFO");
1111  if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
1112  return _ ("DEBUG");
1113  if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0)
1114  return _ ("NONE");
1115  return _ ("INVALID");
1116 }
1117 
1118 
1125 const char *
1126 GNUNET_h2s (const struct GNUNET_HashCode *hc)
1127 {
1129 
1130  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1131  ret.encoding[8] = '\0';
1132  return (const char *) ret.encoding;
1133 }
1134 
1135 
1146 const char *
1147 GNUNET_h2s2 (const struct GNUNET_HashCode *hc)
1148 {
1149  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1150 
1151  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1152  ret.encoding[8] = '\0';
1153  return (const char *) ret.encoding;
1154 }
1155 
1156 
1166 const char *
1168 {
1169  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1170  struct GNUNET_HashCode hc;
1171 
1172  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1173  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1174  ret.encoding[6] = '\0';
1175  return (const char *) ret.encoding;
1176 }
1177 
1178 
1188 const char *
1190 {
1191  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1192  struct GNUNET_HashCode hc;
1193 
1194  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1195  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1196  ret.encoding[6] = '\0';
1197  return (const char *) ret.encoding;
1198 }
1199 
1200 
1210 const char *
1212 {
1213  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1214  struct GNUNET_HashCode hc;
1215 
1216  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1217  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1218  ret.encoding[6] = '\0';
1219  return (const char *) ret.encoding;
1220 }
1221 
1222 
1232 const char *
1234 {
1235  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1236  struct GNUNET_HashCode hc;
1237 
1238  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1239  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1240  ret.encoding[6] = '\0';
1241  return (const char *) ret.encoding;
1242 }
1243 
1244 
1254 const char *
1256 {
1257  static char buf[64];
1258 
1259  GNUNET_STRINGS_data_to_string (shc, sizeof(*shc), buf, sizeof(buf));
1260  buf[6] = '\0';
1261  return (const char *) buf;
1262 }
1263 
1264 
1274 const char *
1275 GNUNET_uuid2s (const struct GNUNET_Uuid *uuid)
1276 {
1277  static char buf[32];
1278 
1279  GNUNET_STRINGS_data_to_string (uuid, sizeof(*uuid), buf, sizeof(buf));
1280  buf[6] = '\0';
1281  return (const char *) buf;
1282 }
1283 
1284 
1293 const char *
1295 {
1296  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1297 
1298  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1299  ret.encoding[sizeof(ret) - 1] = '\0';
1300  return (const char *) ret.encoding;
1301 }
1302 
1303 
1311 const char *
1313 {
1314  static GNUNET_THREAD_LOCAL char buf[5];
1315  char *ret;
1316 
1317  if (NULL == pid)
1318  return "NULL";
1320  GNUNET_strlcpy (buf, ret, sizeof(buf));
1321  GNUNET_free (ret);
1322  return buf;
1323 }
1324 
1325 
1336 const char *
1338 {
1339  static GNUNET_THREAD_LOCAL char buf[5];
1340  char *ret;
1341 
1342  if (NULL == pid)
1343  return "NULL";
1345  GNUNET_strlcpy (buf, ret, sizeof(buf));
1346  GNUNET_free (ret);
1347  return buf;
1348 }
1349 
1350 
1358 const char *
1360 {
1361  static GNUNET_THREAD_LOCAL char buf[256];
1362  char *ret;
1363 
1365  strcpy (buf, ret);
1366  GNUNET_free (ret);
1367  return buf;
1368 }
1369 
1370 
1381 const char *
1382 GNUNET_a2s (const struct sockaddr *addr, socklen_t addrlen)
1383 {
1384 #define LEN \
1385  GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \
1386  (1 + sizeof(struct sockaddr_un) - sizeof(sa_family_t)))
1387  static char buf[LEN];
1388 #undef LEN
1389  static char b2[6];
1390  const struct sockaddr_in *v4;
1391  const struct sockaddr_un *un;
1392  const struct sockaddr_in6 *v6;
1393  unsigned int off;
1394 
1395  if (addr == NULL)
1396  return _ ("unknown address");
1397  switch (addr->sa_family)
1398  {
1399  case AF_INET:
1400  if (addrlen != sizeof(struct sockaddr_in))
1401  return "<invalid v4 address>";
1402  v4 = (const struct sockaddr_in *) addr;
1403  inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN);
1404  if (0 == ntohs (v4->sin_port))
1405  return buf;
1406  strcat (buf, ":");
1407  GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v4->sin_port));
1408  strcat (buf, b2);
1409  return buf;
1410 
1411  case AF_INET6:
1412  if (addrlen != sizeof(struct sockaddr_in6))
1413  return "<invalid v6 address>";
1414  v6 = (const struct sockaddr_in6 *) addr;
1415  buf[0] = '[';
1416  inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN);
1417  if (0 == ntohs (v6->sin6_port))
1418  return &buf[1];
1419  strcat (buf, "]:");
1420  GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v6->sin6_port));
1421  strcat (buf, b2);
1422  return buf;
1423 
1424  case AF_UNIX:
1425  if (addrlen <= sizeof(sa_family_t))
1426  return "<unbound UNIX client>";
1427  un = (const struct sockaddr_un *) addr;
1428  off = 0;
1429  if ('\0' == un->sun_path[0])
1430  off++;
1431  memset (buf, 0, sizeof(buf));
1432  GNUNET_snprintf (buf,
1433  sizeof(buf),
1434  "%s%.*s",
1435  (1 == off) ? "@" : "",
1436  (int) (addrlen - sizeof(sa_family_t) - off),
1437  &un->sun_path[off]);
1438  return buf;
1439 
1440  default:
1441  return _ ("invalid address");
1442  }
1443 }
1444 
1445 
1453 void
1455  const char *section,
1456  const char *option)
1457 {
1458  GNUNET_log (kind,
1459  _ (
1460  "Configuration fails to specify option `%s' in section `%s'!\n"),
1461  option,
1462  section);
1463 }
1464 
1465 
1474 void
1476  const char *section,
1477  const char *option,
1478  const char *required)
1479 {
1480  GNUNET_log (
1481  kind,
1482  _ (
1483  "Configuration specifies invalid value for option `%s' in section `%s': %s\n"),
1484  option,
1485  section,
1486  required);
1487 }
1488 
1489 
1496 void
1498  struct GNUNET_AsyncScopeSave *old_scope)
1499 {
1500  *old_scope = current_async_scope;
1503 }
1504 
1505 
1511 void
1513 {
1514  current_async_scope = *old_scope;
1515 }
1516 
1517 
1523 void
1525 {
1527  aid_ret,
1528  sizeof(struct GNUNET_AsyncScopeId));
1529 }
1530 
1531 
1537 void
1539 {
1540  *scope_ret = current_async_scope;
1541 }
1542 
1543 
1547 void __attribute__ ((constructor))
1548 GNUNET_util_cl_init ()
1549 {
1550  GNUNET_stderr = stderr;
1551 }
1552 
1553 
1557 void __attribute__ ((destructor))
1558 GNUNET_util_cl_fini ()
1559 {
1560 
1561 }
1562 
1563 
1564 /* end of common_logging.c */
void GNUNET_logger_add(GNUNET_Logger logger, void *logger_cls)
Add a custom logger.
#define DATE_STR_SIZE
How many characters can a date/time string be at most?
static int logdefs_len
The number of units used in logdefs array.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
static GNUNET_THREAD_LOCAL struct GNUNET_TIME_Absolute last_bulk_time
Time of the last bulk error message (0 for none)
const char * GNUNET_i2s2(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
uint64_t rel_value_us
The actual value.
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
#define COMP_TRACK_SIZE
How many characters do we use for matching of bulk components?
struct CustomLogger * next
This is a linked list.
void GNUNET_logger_remove(GNUNET_Logger logger, void *logger_cls)
Remove a custom logger.
static int parse_definitions(const char *constname, int force)
Utility function - parses a definition.
#define GNUNET_THREAD_LOCAL
Definition: platform.h:255
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
const char * GNUNET_error_type_to_string(enum GNUNET_ErrorType kind)
Convert error type to string.
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
#define BULK_TRACK_SIZE
How many characters do we use for matching of bulk messages?
const char * GNUNET_e2s2(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static char * log_file_name
Format string describing the name of the log file.
static int logdefs_size
Allocated size of logdefs array (in units)
static FILE * GNUNET_stderr
File descriptor to use for "stderr", or NULL for none.
static int ok
Return value from &#39;main&#39; (0 == success)
const char * GNUNET_p2s2(const struct GNUNET_CRYPTO_EddsaPublicKey *p)
Convert a public key value to a string (for printing debug messages).
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
void * logger_cls
Closure for logger.
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:684
static struct LogDef * logdefs
Dynamic array of logging definitions.
#define GNUNET_NO
Definition: gnunet_common.h:86
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
GNUNET_ErrorType
Types of errors.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int force
1 if this definition comes from GNUNET_FORCE_LOG, which means that it overrides any configuration opt...
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
Identifier for an asynchronous execution context.
#define BULK_DELAY_THRESHOLD
After how many milliseconds do we always print that "message X was repeated N times"? Use 12h.
static struct GNUNET_SCHEDULER_Task * t
Main task.
int to_line
Highest line at which this definition matches.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define PATH_MAX
Assumed maximum path length (for the log file name).
int from_line
Lowest line at which this definition matches.
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char * component
Running component.
A 256-bit hashcode.
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
static char * section
Name of the section.
Definition: gnunet-config.c:33
void GNUNET_abort_()
Abort the process, generate a core dump if possible.
static void parse_all_definitions()
Utility function - parses GNUNET_LOG and GNUNET_FORCE_LOG.
static GNUNET_THREAD_LOCAL char last_bulk_comp[32+1]
Component when the last bulk was logged.
#define INT_MAX
cryptographic primitives for GNUnet
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
const char * GNUNET_h2s2(const struct GNUNET_HashCode *hc)
Convert a hash to a string (for printing debug messages).
Linked list of active loggers.
enum State state
current state of profiling
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
static char * line
Desired phone line (string to be converted to a hash).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
const char * GNUNET_p2s(const struct GNUNET_CRYPTO_EddsaPublicKey *p)
Convert a public key value to a string (for printing debug messages).
static struct CustomLogger * loggers
Linked list of our custom loggres.
const char * GNUNET_uuid2s(const struct GNUNET_Uuid *uuid)
Convert a UUID to a string (for printing debug messages).
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static char * fn
Filename of the unique file.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
char * GNUNET_CRYPTO_eddsa_public_key_to_string(const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:256
void GNUNET_log_nocheck(enum GNUNET_ErrorType kind, const char *message,...)
Main log function.
static void resize_logdefs()
Utility function - reallocates logdefs array to be twice as large.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:687
static char * option
Name of the option.
Definition: gnunet-config.c:38
static char buf[2048]
static int gnunet_force_log_present
GNUNET_YES if at least one definition with forced == 1 is available.
#define ROTATION_KEEP
How many log files to keep?
A UUID, a 128 bit random value.
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages)...
regex_t function_regex
Function name regex.
static int gnunet_log_parsed
GNUNET_YES if GNUNET_LOG environment variable is already parsed.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
regex_t component_regex
Component name regex.
void GNUNET_log_from_nocheck(enum GNUNET_ErrorType kind, const char *comp, const char *message,...)
Log function that specifies an alternative component.
void __attribute__((constructor))
Initializer.
int GNUNET_get_log_call_status(int caller_level, const char *comp, const char *file, const char *function, int line)
Decides whether a particular logging call should or should not be allowed to be made.
void GNUNET_CRYPTO_hash_to_enc(const struct GNUNET_HashCode *block, struct GNUNET_CRYPTO_HashAsciiEncoded *result)
Convert hash to ASCII encoding.
Definition: crypto_hash.c:73
#define GNUNET_SYSERR
Definition: gnunet_common.h:84
static unsigned int size
Size of the "table".
Definition: peer.c:67
static void log_rotate(const char *new_name)
Rotate logs, deleting the oldest log.
int have_scope
GNUNET_YES unless this saved scope is the unnamed root scope.
Saved async scope identifier or root scope.
#define LEN
static int add_definition(const char *component, const char *file, const char *function, int from_line, int to_line, int level, int force)
Utility function - adds a parsed definition to logdefs array.
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition: strings.c:603
Represents a single logging definition.
char * getenv()
const char * GNUNET_h2s_full(const struct GNUNET_HashCode *hc)
Convert a hash to a string (for printing debug messages).
void GNUNET_async_scope_restore(struct GNUNET_AsyncScopeSave *old_scope)
Clear the current thread&#39;s async scope.
long long GNUNET_TIME_get_offset(void)
Get the timestamp offset for this instance.
Definition: time.c:65
0-terminated ASCII encoding of a struct GNUNET_HashCode.
static void mylog(enum GNUNET_ErrorType kind, const char *comp, const char *message, va_list va)
Output a log message using the default mechanism.
void GNUNET_async_scope_enter(const struct GNUNET_AsyncScopeId *aid, struct GNUNET_AsyncScopeSave *old_scope)
Set the async scope for the current thread.
static void output_message(enum GNUNET_ErrorType kind, const char *comp, const char *datestr, const char *msg)
Actually output the log message.
The identity of the host (wraps the signing key of the peer).
void GNUNET_async_scope_fresh(struct GNUNET_AsyncScopeId *aid_ret)
Generate a fresh async scope identifier.
struct GNUNET_AsyncScopeId scope_id
Saved scope.
#define BULK_REPEAT_THRESHOLD
After how many repetitions do we always print that "message X was repeated N times"? (even if we have not yet reached the delay threshold)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:375
static GNUNET_THREAD_LOCAL unsigned int last_bulk_repeat
Number of times that bulk message has been repeated since.
void GNUNET_async_scope_get(struct GNUNET_AsyncScopeSave *scope_ret)
Get the current async scope.
void GNUNET_log_skip(int n, int check_reset)
Ignore the next n calls to the log function.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
#define GNUNET_log(kind,...)
regex_t file_regex
File name regex.
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
static GNUNET_THREAD_LOCAL char last_bulk [256] __nonstring
The last "bulk" error message that we have been logging.
static int setup_log_file(const struct tm *tm)
Setup the log file.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:85
static enum GNUNET_ErrorType get_type(const char *log)
Convert a textual description of a loglevel to the respective GNUNET_GE_KIND.
int GNUNET_get_log_skip()
Get the number of log calls that are going to be skipped.
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
static GNUNET_THREAD_LOCAL int skip_log
Number of log calls to ignore.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
void(* GNUNET_Logger)(void *cls, enum GNUNET_ErrorType kind, const char *component, const char *date, const char *message)
User-defined handler for log messages.
static void flush_bulk(const char *datestr)
Flush an existing bulk report to the output.
static enum GNUNET_ErrorType min_level
Minimum log level.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:219
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
int level
Maximal log level allowed for calls that match this definition.
static __thread struct GNUNET_AsyncScopeSave current_async_scope
Asynchronous scope of the current thread, or NULL if we have not entered an async scope yet...
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:856
static char * component_nopid
Running component (without pid).
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_Logger logger
Log function.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
static int gnunet_force_log_parsed
GNUNET_YES if GNUNET_FORCE_LOG environment variable is already parsed.
static GNUNET_THREAD_LOCAL enum GNUNET_ErrorType last_bulk_kind
Type of the last bulk message.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...