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,
709  const char *loglevel,
710  const char *logfile)
711 {
712  const char *env_logfile;
713 
714  min_level = get_type (loglevel);
715 #if ! defined(GNUNET_CULL_LOGGING)
717 #endif
719  GNUNET_asprintf (&component, "%s-%d", comp, getpid ());
722 
723  env_logfile = getenv ("GNUNET_FORCE_LOGFILE");
724  if ((NULL != env_logfile) && (strlen (env_logfile) > 0))
725  logfile = env_logfile;
726  if (NULL == logfile)
727  return GNUNET_OK;
730  if (NULL == log_file_name)
731  return GNUNET_SYSERR;
732 #if defined(GNUNET_CULL_LOGGING)
733  /* log file option not allowed for wallet logic */
734  GNUNET_assert (NULL == logfile);
735  return GNUNET_OK;
736 #else
737  {
738  time_t t;
739  const struct tm *tm;
740 
741  t = time (NULL);
742  tm = gmtime (&t);
743  return setup_log_file (tm);
744  }
745 #endif
746 }
747 
748 
758 void
760 {
761  struct CustomLogger *entry;
762 
763  entry = GNUNET_new (struct CustomLogger);
764  entry->logger = logger;
765  entry->logger_cls = logger_cls;
766  entry->next = loggers;
767  loggers = entry;
768 }
769 
770 
777 void
779 {
780  struct CustomLogger *pos;
781  struct CustomLogger *prev;
782 
783  prev = NULL;
784  pos = loggers;
785  while ((NULL != pos) &&
786  ((pos->logger != logger) || (pos->logger_cls != logger_cls)))
787  {
788  prev = pos;
789  pos = pos->next;
790  }
791  GNUNET_assert (NULL != pos);
792  if (NULL == prev)
793  loggers = pos->next;
794  else
795  prev->next = pos->next;
796  GNUNET_free (pos);
797 }
798 
799 
808 static void
810  const char *comp,
811  const char *datestr,
812  const char *msg)
813 {
814  struct CustomLogger *pos;
815 
816  /* only use the standard logger if no custom loggers are present */
817  if ((NULL != GNUNET_stderr) && (NULL == loggers))
818  {
819  if (kind == GNUNET_ERROR_TYPE_MESSAGE)
820  {
821  /* The idea here is to produce "normal" output messages
822  * for end users while still having the power of the
823  * logging engine for developer needs. So ideally this
824  * is what it should look like when CLI tools are used
825  * interactively, yet the same message shouldn't look
826  * this way if the output is going to logfiles or robots
827  * instead.
828  */fprintf (GNUNET_stderr, "* %s", msg);
829  }
831  {
832  static GNUNET_THREAD_LOCAL char id_buf[27];
833  char *end;
834 
835  /* We're logging, so skip_log must be currently 0. */
836  skip_log = 100;
838  sizeof(struct GNUNET_AsyncScopeId),
839  id_buf,
840  sizeof(id_buf) - 1);
841  GNUNET_assert (NULL != end);
842  *end = '\0';
843  skip_log = 0;
844  fprintf (GNUNET_stderr,
845  "%s %s(%s) %s %s",
846  datestr,
847  comp,
848  id_buf,
850  msg);
851  }
852  else
853  {
854  fprintf (GNUNET_stderr,
855  "%s %s %s %s",
856  datestr,
857  comp,
859  msg);
860  }
861  fflush (GNUNET_stderr);
862  }
863  pos = loggers;
864  while (NULL != pos)
865  {
866  pos->logger (pos->logger_cls, kind, comp, datestr, msg);
867  pos = pos->next;
868  }
869 }
870 
871 
877 static void
878 flush_bulk (const char *datestr)
879 {
880  char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
881  int rev;
882  char *last;
883  const char *ft;
884 
885  if ((0 == last_bulk_time.abs_value_us) || (0 == last_bulk_repeat))
886  return;
887  rev = 0;
888  last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
889  if (last == NULL)
890  last = &last_bulk[BULK_TRACK_SIZE - 1];
891  else if (last != last_bulk)
892  last--;
893  if (last[0] == '\n')
894  {
895  rev = 1;
896  last[0] = '\0';
897  }
898  ft =
901  GNUNET_YES);
902  snprintf (msg,
903  sizeof(msg),
904  _ ("Message `%.*s' repeated %u times in the last %s\n"),
906  last_bulk,
908  ft);
909  if (rev == 1)
910  last[0] = '\n';
913  last_bulk_repeat = 0;
914 }
915 
916 
923 void
924 GNUNET_log_skip (int n, int check_reset)
925 {
926  int ok;
927 
928  if (0 == n)
929  {
930  ok = (0 == skip_log);
931  skip_log = 0;
932  if (check_reset)
933  GNUNET_break (ok);
934  }
935  else
936  {
937  skip_log += n;
938  }
939 }
940 
941 
947 int
949 {
950  return skip_log;
951 }
952 
953 
962 static void
964  const char *comp,
965  const char *message,
966  va_list va)
967 {
968  char date[DATE_STR_SIZE];
969  char date2[DATE_STR_SIZE];
970  struct tm *tmptr;
971  size_t size;
972  va_list vacp;
973 
974  va_copy (vacp, va);
975  size = vsnprintf (NULL, 0, message, vacp) + 1;
976  GNUNET_assert (0 != size);
977  va_end (vacp);
978  memset (date, 0, DATE_STR_SIZE);
979  {
980  char buf[size];
981  long long offset;
982 
983  struct timeval timeofday;
984 
985  gettimeofday (&timeofday, NULL);
986  offset = GNUNET_TIME_get_offset ();
987  if (offset > 0)
988  {
989  timeofday.tv_sec += offset / 1000LL;
990  timeofday.tv_usec += (offset % 1000LL) * 1000LL;
991  if (timeofday.tv_usec > 1000000LL)
992  {
993  timeofday.tv_usec -= 1000000LL;
994  timeofday.tv_sec++;
995  }
996  }
997  else
998  {
999  timeofday.tv_sec += offset / 1000LL;
1000  if (timeofday.tv_usec > -(offset % 1000LL) * 1000LL)
1001  {
1002  timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1003  }
1004  else
1005  {
1006  timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL;
1007  timeofday.tv_sec--;
1008  }
1009  }
1010  tmptr = localtime (&timeofday.tv_sec);
1011  if (NULL == tmptr)
1012  {
1013  strcpy (date, "localtime error");
1014  }
1015  else
1016  {
1017  if (0 == strftime (date2, DATE_STR_SIZE, "%b %d %H:%M:%S-%%06u", tmptr))
1018  abort ();
1019  if (0 > snprintf (date, sizeof(date), date2, timeofday.tv_usec))
1020  abort ();
1021  }
1022 
1023  vsnprintf (buf, size, message, va);
1024 #if ! defined(GNUNET_CULL_LOGGING)
1025  if (NULL != tmptr)
1026  (void) setup_log_file (tmptr);
1027 #endif
1028  if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
1029  (0 != last_bulk_time.abs_value_us) &&
1030  (0 == strncmp (buf, last_bulk, sizeof(last_bulk))))
1031  {
1032  last_bulk_repeat++;
1036  flush_bulk (date);
1037  return;
1038  }
1039  flush_bulk (date);
1040  GNUNET_strlcpy (last_bulk, buf, sizeof(last_bulk));
1041  last_bulk_repeat = 0;
1042  last_bulk_kind = kind;
1044  GNUNET_strlcpy (last_bulk_comp, comp, sizeof(last_bulk_comp));
1045  output_message (kind, comp, date, buf);
1046  }
1047 }
1048 
1049 
1057 void
1058 GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...)
1059 {
1060  va_list va;
1061 
1062  va_start (va, message);
1063  mylog (kind, component, message, va);
1064  va_end (va);
1065 }
1066 
1067 
1077 void
1079  const char *comp,
1080  const char *message,
1081  ...)
1082 {
1083  va_list va;
1084  char comp_w_pid[128];
1085 
1086  if (comp == NULL)
1087  comp = component_nopid;
1088 
1089  va_start (va, message);
1090  GNUNET_snprintf (comp_w_pid, sizeof(comp_w_pid), "%s-%d", comp, getpid ());
1091  mylog (kind, comp_w_pid, message, va);
1092  va_end (va);
1093 }
1094 
1095 
1102 const char *
1104 {
1105  if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
1106  return _ ("ERROR");
1107  if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
1108  return _ ("WARNING");
1109  if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0)
1110  return _ ("MESSAGE");
1111  if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
1112  return _ ("INFO");
1113  if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
1114  return _ ("DEBUG");
1115  if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0)
1116  return _ ("NONE");
1117  return _ ("INVALID");
1118 }
1119 
1120 
1127 const char *
1128 GNUNET_h2s (const struct GNUNET_HashCode *hc)
1129 {
1131 
1132  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1133  ret.encoding[8] = '\0';
1134  return (const char *) ret.encoding;
1135 }
1136 
1137 
1148 const char *
1149 GNUNET_h2s2 (const struct GNUNET_HashCode *hc)
1150 {
1152 
1153  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1154  ret.encoding[8] = '\0';
1155  return (const char *) ret.encoding;
1156 }
1157 
1158 
1168 const char *
1170 {
1172  struct GNUNET_HashCode hc;
1173 
1174  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1175  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1176  ret.encoding[6] = '\0';
1177  return (const char *) ret.encoding;
1178 }
1179 
1180 
1190 const char *
1192 {
1194  struct GNUNET_HashCode hc;
1195 
1196  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1197  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1198  ret.encoding[6] = '\0';
1199  return (const char *) ret.encoding;
1200 }
1201 
1202 
1212 const char *
1214 {
1216  struct GNUNET_HashCode hc;
1217 
1218  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1219  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1220  ret.encoding[6] = '\0';
1221  return (const char *) ret.encoding;
1222 }
1223 
1224 
1234 const char *
1236 {
1238  struct GNUNET_HashCode hc;
1239 
1240  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1241  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1242  ret.encoding[6] = '\0';
1243  return (const char *) ret.encoding;
1244 }
1245 
1246 
1256 const char *
1258 {
1259  static GNUNET_THREAD_LOCAL char buf[64];
1260 
1261  GNUNET_STRINGS_data_to_string (shc, sizeof(*shc), buf, sizeof(buf));
1262  buf[6] = '\0';
1263  return (const char *) buf;
1264 }
1265 
1266 
1276 const char *
1277 GNUNET_uuid2s (const struct GNUNET_Uuid *uuid)
1278 {
1279  static GNUNET_THREAD_LOCAL char buf[32];
1280 
1281  GNUNET_STRINGS_data_to_string (uuid, sizeof(*uuid), buf, sizeof(buf));
1282  buf[6] = '\0';
1283  return (const char *) buf;
1284 }
1285 
1286 
1295 const char *
1297 {
1299 
1300  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1301  ret.encoding[sizeof(ret) - 1] = '\0';
1302  return (const char *) ret.encoding;
1303 }
1304 
1305 
1313 const char *
1315 {
1316  static GNUNET_THREAD_LOCAL char buf[5];
1317  char *ret;
1318 
1319  if (NULL == pid)
1320  return "NULL";
1322  GNUNET_strlcpy (buf, ret, sizeof(buf));
1323  GNUNET_free (ret);
1324  return buf;
1325 }
1326 
1327 
1338 const char *
1340 {
1341  static GNUNET_THREAD_LOCAL char buf[5];
1342  char *ret;
1343 
1344  if (NULL == pid)
1345  return "NULL";
1347  GNUNET_strlcpy (buf, ret, sizeof(buf));
1348  GNUNET_free (ret);
1349  return buf;
1350 }
1351 
1352 
1360 const char *
1362 {
1363  static GNUNET_THREAD_LOCAL char buf[256];
1364  char *ret;
1365 
1367  strcpy (buf, ret);
1368  GNUNET_free (ret);
1369  return buf;
1370 }
1371 
1372 
1383 const char *
1384 GNUNET_a2s (const struct sockaddr *addr, socklen_t addrlen)
1385 {
1386 #define LEN \
1387  GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \
1388  (1 + sizeof(struct sockaddr_un) - sizeof(sa_family_t)))
1389  static GNUNET_THREAD_LOCAL char buf[LEN];
1390 #undef LEN
1391  static GNUNET_THREAD_LOCAL char b2[6];
1392  const struct sockaddr_in *v4;
1393  const struct sockaddr_un *un;
1394  const struct sockaddr_in6 *v6;
1395  unsigned int off;
1396 
1397  if (addr == NULL)
1398  return _ ("unknown address");
1399  switch (addr->sa_family)
1400  {
1401  case AF_INET:
1402  if (addrlen != sizeof(struct sockaddr_in))
1403  return "<invalid v4 address>";
1404  v4 = (const struct sockaddr_in *) addr;
1405  inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN);
1406  if (0 == ntohs (v4->sin_port))
1407  return buf;
1408  strcat (buf, ":");
1409  GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v4->sin_port));
1410  strcat (buf, b2);
1411  return buf;
1412 
1413  case AF_INET6:
1414  if (addrlen != sizeof(struct sockaddr_in6))
1415  return "<invalid v6 address>";
1416  v6 = (const struct sockaddr_in6 *) addr;
1417  buf[0] = '[';
1418  inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN);
1419  if (0 == ntohs (v6->sin6_port))
1420  return &buf[1];
1421  strcat (buf, "]:");
1422  GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v6->sin6_port));
1423  strcat (buf, b2);
1424  return buf;
1425 
1426  case AF_UNIX:
1427  if (addrlen <= sizeof(sa_family_t))
1428  return "<unbound UNIX client>";
1429  un = (const struct sockaddr_un *) addr;
1430  off = 0;
1431  if ('\0' == un->sun_path[0])
1432  off++;
1433  memset (buf, 0, sizeof(buf));
1434  GNUNET_snprintf (buf,
1435  sizeof(buf),
1436  "%s%.*s",
1437  (1 == off) ? "@" : "",
1438  (int) (addrlen - sizeof(sa_family_t) - off),
1439  &un->sun_path[off]);
1440  return buf;
1441 
1442  default:
1443  return _ ("invalid address");
1444  }
1445 }
1446 
1447 
1455 void
1457  const char *section,
1458  const char *option)
1459 {
1460  GNUNET_log (kind,
1461  _ (
1462  "Configuration fails to specify option `%s' in section `%s'!\n"),
1463  option,
1464  section);
1465 }
1466 
1467 
1476 void
1478  const char *section,
1479  const char *option,
1480  const char *required)
1481 {
1482  GNUNET_log (
1483  kind,
1484  _ (
1485  "Configuration specifies invalid value for option `%s' in section `%s': %s\n"),
1486  option,
1487  section,
1488  required);
1489 }
1490 
1491 
1498 void
1500  struct GNUNET_AsyncScopeSave *old_scope)
1501 {
1502  *old_scope = current_async_scope;
1505 }
1506 
1507 
1513 void
1515 {
1516  current_async_scope = *old_scope;
1517 }
1518 
1519 
1525 void
1527 {
1529  aid_ret,
1530  sizeof(struct GNUNET_AsyncScopeId));
1531 }
1532 
1533 
1539 void
1541 {
1542  *scope_ret = current_async_scope;
1543 }
1544 
1545 
1549 void __attribute__ ((constructor))
1550 GNUNET_util_cl_init ()
1551 {
1552  GNUNET_stderr = stderr;
1553 }
1554 
1555 
1559 void __attribute__ ((destructor))
1560 GNUNET_util_cl_fini ()
1561 {
1562 
1563 }
1564 
1565 
1566 /* 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.
static GNUNET_THREAD_LOCAL struct GNUNET_AsyncScopeSave current_async_scope
Asynchronous scope of the current thread, or NULL if we have not entered an async scope yet...
#define GNUNET_THREAD_LOCAL
Definition: platform.h:259
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.
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).
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:184
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:265
void GNUNET_log_nocheck(enum GNUNET_ErrorType kind, const char *message,...)
Main log function.
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:701
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.
static void resize_logdefs(void)
Utility function - reallocates logdefs array to be twice as large.
#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
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:617
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.
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:220
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.
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:870
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...