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 
297 #if ! TALER_WALLET_ONLY
298 
303 static void
304 log_rotate (const char *new_name)
305 {
306  static char *rotation[ROTATION_KEEP];
307  static unsigned int rotation_off;
308  char *discard;
309 
310  if ('\0' == *new_name)
311  return; /* not a real log file name */
312  discard = rotation[rotation_off % ROTATION_KEEP];
313  if (NULL != discard)
314  {
315  /* Note: can't log errors during logging (recursion!), so this
316  operation MUST silently fail... */
317  (void) unlink (discard);
318  GNUNET_free (discard);
319  }
320  rotation[rotation_off % ROTATION_KEEP] = GNUNET_strdup (new_name);
321  rotation_off++;
322 }
323 
324 
331 static int
332 setup_log_file (const struct tm *tm)
333 {
334  static char last_fn[PATH_MAX + 1];
335  char fn[PATH_MAX + 1];
336  int altlog_fd;
337  int dup_return;
338  FILE *altlog;
339  char *leftsquare;
340 
341  if (NULL == log_file_name)
342  return GNUNET_SYSERR;
343  if (0 == strftime (fn, sizeof(fn), log_file_name, tm))
344  return GNUNET_SYSERR;
345  leftsquare = strrchr (fn, '[');
346  if ((NULL != leftsquare) && (']' == leftsquare[1]))
347  {
348  char *logfile_copy = GNUNET_strdup (fn);
349 
350  logfile_copy[leftsquare - fn] = '\0';
351  logfile_copy[leftsquare - fn + 1] = '\0';
352  snprintf (fn,
353  PATH_MAX,
354  "%s%d%s",
355  logfile_copy,
356  getpid (),
357  &logfile_copy[leftsquare - fn + 2]);
358  GNUNET_free (logfile_copy);
359  }
360  if (0 == strcmp (fn, last_fn))
361  return GNUNET_OK; /* no change */
362  log_rotate (last_fn);
363  strcpy (last_fn, fn);
365  {
366  fprintf (stderr,
367  "Failed to create directory for `%s': %s\n",
368  fn,
369  strerror (errno));
370  return GNUNET_SYSERR;
371  }
372  altlog_fd = open (fn,
373  O_APPEND | O_WRONLY | O_CREAT,
374  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
375 
376  if (-1 != altlog_fd)
377  {
378  if (NULL != GNUNET_stderr)
379  fclose (GNUNET_stderr);
380  dup_return = dup2 (altlog_fd, 2);
381  (void) close (altlog_fd);
382  if (-1 != dup_return)
383  {
384  altlog = fdopen (2, "ab");
385  if (NULL == altlog)
386  {
387  (void) close (2);
388  altlog_fd = -1;
389  }
390  }
391  else
392  {
393  altlog_fd = -1;
394  }
395  }
396  if (-1 == altlog_fd)
397  {
399  return GNUNET_SYSERR;
400  }
401  GNUNET_stderr = altlog;
402  return GNUNET_OK;
403 }
404 
405 
406 #endif
407 
408 
421 static int
423  const char *file,
424  const char *function,
425  int from_line,
426  int to_line,
427  int level,
428  int force)
429 {
430  struct LogDef n;
431  int r;
432 
433  if (logdefs_size == logdefs_len)
434  resize_logdefs ();
435  memset (&n, 0, sizeof(n));
436  if (0 == strlen (component))
437  component = (char *) ".*";
438  r = regcomp (&n.component_regex, (const char *) component, REG_NOSUB);
439  if (0 != r)
440  {
441  return r;
442  }
443  if (0 == strlen (file))
444  file = (char *) ".*";
445  r = regcomp (&n.file_regex, (const char *) file, REG_NOSUB);
446  if (0 != r)
447  {
448  regfree (&n.component_regex);
449  return r;
450  }
451  if ((NULL == function) || (0 == strlen (function)))
452  function = (char *) ".*";
453  r = regcomp (&n.function_regex, (const char *) function, REG_NOSUB);
454  if (0 != r)
455  {
456  regfree (&n.component_regex);
457  regfree (&n.file_regex);
458  return r;
459  }
460  n.from_line = from_line;
461  n.to_line = to_line;
462  n.level = level;
463  n.force = force;
464  logdefs[logdefs_len++] = n;
465  return 0;
466 }
467 
468 
482 int
483 GNUNET_get_log_call_status (int caller_level,
484  const char *comp,
485  const char *file,
486  const char *function,
487  int line)
488 {
489  struct LogDef *ld;
490  int i;
491  int force_only;
492 
493  if (NULL == comp)
494  /* Use default component */
495  comp = component_nopid;
496 
497  /* We have no definitions to override globally configured log level,
498  * so just use it right away.
499  */
500  if ((min_level >= 0) && (GNUNET_NO == gnunet_force_log_present))
501  return caller_level <= min_level;
502 
503  /* Only look for forced definitions? */
504  force_only = min_level >= 0;
505  for (i = 0; i < logdefs_len; i++)
506  {
507  ld = &logdefs[i];
508  if (((! force_only) || ld->force) &&
509  ((line >= ld->from_line) && (line <= ld->to_line) ) &&
510  (0 == regexec (&ld->component_regex, comp, 0, NULL, 0)) &&
511  (0 == regexec (&ld->file_regex, file, 0, NULL, 0)) &&
512  (0 == regexec (&ld->function_regex, function, 0, NULL, 0)))
513  {
514  /* We're finished */
515  return caller_level <= ld->level;
516  }
517  }
518  /* No matches - use global level, if defined */
519  if (min_level >= 0)
520  return caller_level <= min_level;
521  /* All programs/services previously defaulted to WARNING.
522  * Now *we* default to WARNING, and THEY default to NULL.
523  * Or rather we default to MESSAGE, since things aren't always bad.
524  */
525  return caller_level <= GNUNET_ERROR_TYPE_MESSAGE;
526 }
527 
528 
552 static int
553 parse_definitions (const char *constname, int force)
554 {
555  char *def;
556  const char *tmp;
557  char *comp = NULL;
558  char *file = NULL;
559  char *function = NULL;
560  char *p;
561  char *start;
562  char *t;
563  short state;
564  int level;
565  int from_line, to_line;
566  int counter = 0;
567  int keep_looking = 1;
568 
569  tmp = getenv (constname);
570  if (NULL == tmp)
571  return 0;
572  def = GNUNET_strdup (tmp);
573  from_line = 0;
574  to_line = INT_MAX;
575  for (p = def, state = 0, start = def; keep_looking; p++)
576  {
577  switch (p[0])
578  {
579  case ';': /* found a field separator */
580  p[0] = '\0';
581  switch (state)
582  {
583  case 0: /* within a component name */
584  comp = start;
585  break;
586 
587  case 1: /* within a file name */
588  file = start;
589  break;
590 
591  case 2: /* within a function name */
592  /* after a file name there must be a function name */
593  function = start;
594  break;
595 
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  default:
628  fprintf (
629  stderr,
630  _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
631  p);
632  break;
633  }
634  start = p + 1;
635  state++;
636  break;
637 
638  case '\0': /* found EOL */
639  keep_looking = 0;
640 
641  /* fall through to '/' */
642  case '/': /* found a definition separator */
643  switch (state)
644  {
645  case 4: /* within a log level */
646  p[0] = '\0';
647  state = 0;
648  level = get_type ((const char *) start);
649  if ((GNUNET_ERROR_TYPE_INVALID == level) ||
650  (GNUNET_ERROR_TYPE_UNSPECIFIED == level) ||
651  (0 != add_definition (comp,
652  file,
653  function,
654  from_line,
655  to_line,
656  level,
657  force)))
658  {
659  GNUNET_free (def);
660  return counter;
661  }
662  counter++;
663  start = p + 1;
664  break;
665 
666  default:
667  fprintf (
668  stderr,
669  _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
670  p);
671  break;
672  }
673 
674  default:
675  break;
676  }
677  }
678  GNUNET_free (def);
679  return counter;
680 }
681 
682 
686 static void
688 {
691  parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO;
693 
695  parse_definitions ("GNUNET_LOG", 0);
697 }
698 
699 
700 #endif
701 
702 
711 int
712 GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile)
713 {
714  const char *env_logfile;
715 
716  min_level = get_type (loglevel);
717 #if ! defined(GNUNET_CULL_LOGGING)
719 #endif
721  GNUNET_asprintf (&component, "%s-%d", comp, getpid ());
724 
725  env_logfile = getenv ("GNUNET_FORCE_LOGFILE");
726  if ((NULL != env_logfile) && (strlen (env_logfile) > 0))
727  logfile = env_logfile;
728  if (NULL == logfile)
729  return GNUNET_OK;
732  if (NULL == log_file_name)
733  return GNUNET_SYSERR;
734 #if TALER_WALLET_ONLY || defined(GNUNET_CULL_LOGGING)
735  /* log file option not allowed for wallet logic */
736  GNUNET_assert (NULL == logfile);
737  return GNUNET_OK;
738 #else
739  {
740  time_t t;
741  const struct tm *tm;
742 
743  t = time (NULL);
744  tm = gmtime (&t);
745  return setup_log_file (tm);
746  }
747 #endif
748 }
749 
750 
760 void
762 {
763  struct CustomLogger *entry;
764 
765  entry = GNUNET_new (struct CustomLogger);
766  entry->logger = logger;
767  entry->logger_cls = logger_cls;
768  entry->next = loggers;
769  loggers = entry;
770 }
771 
772 
779 void
781 {
782  struct CustomLogger *pos;
783  struct CustomLogger *prev;
784 
785  prev = NULL;
786  pos = loggers;
787  while ((NULL != pos) &&
788  ((pos->logger != logger) || (pos->logger_cls != logger_cls)))
789  {
790  prev = pos;
791  pos = pos->next;
792  }
793  GNUNET_assert (NULL != pos);
794  if (NULL == prev)
795  loggers = pos->next;
796  else
797  prev->next = pos->next;
798  GNUNET_free (pos);
799 }
800 
801 
810 static void
812  const char *comp,
813  const char *datestr,
814  const char *msg)
815 {
816  struct CustomLogger *pos;
817 
818  /* only use the standard logger if no custom loggers are present */
819  if ((NULL != GNUNET_stderr) && (NULL == loggers))
820  {
821  if (kind == GNUNET_ERROR_TYPE_MESSAGE)
822  {
823  /* The idea here is to produce "normal" output messages
824  * for end users while still having the power of the
825  * logging engine for developer needs. So ideally this
826  * is what it should look like when CLI tools are used
827  * interactively, yet the same message shouldn't look
828  * this way if the output is going to logfiles or robots
829  * instead.
830  */fprintf (GNUNET_stderr, "* %s", msg);
831  }
833  {
834  static GNUNET_THREAD_LOCAL char id_buf[27];
835  char *end;
836 
837  /* We're logging, so skip_log must be currently 0. */
838  skip_log = 100;
840  sizeof(struct GNUNET_AsyncScopeId),
841  id_buf,
842  sizeof(id_buf) - 1);
843  GNUNET_assert (NULL != end);
844  *end = '\0';
845  skip_log = 0;
846  fprintf (GNUNET_stderr,
847  "%s %s(%s) %s %s",
848  datestr,
849  comp,
850  id_buf,
852  msg);
853  }
854  else
855  {
856  fprintf (GNUNET_stderr,
857  "%s %s %s %s",
858  datestr,
859  comp,
861  msg);
862  }
863  fflush (GNUNET_stderr);
864  }
865  pos = loggers;
866  while (NULL != pos)
867  {
868  pos->logger (pos->logger_cls, kind, comp, datestr, msg);
869  pos = pos->next;
870  }
871 }
872 
873 
879 static void
880 flush_bulk (const char *datestr)
881 {
882  char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
883  int rev;
884  char *last;
885  const char *ft;
886 
887  if ((0 == last_bulk_time.abs_value_us) || (0 == last_bulk_repeat))
888  return;
889  rev = 0;
890  last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
891  if (last == NULL)
892  last = &last_bulk[BULK_TRACK_SIZE - 1];
893  else if (last != last_bulk)
894  last--;
895  if (last[0] == '\n')
896  {
897  rev = 1;
898  last[0] = '\0';
899  }
900  ft =
903  GNUNET_YES);
904  snprintf (msg,
905  sizeof(msg),
906  _ ("Message `%.*s' repeated %u times in the last %s\n"),
908  last_bulk,
910  ft);
911  if (rev == 1)
912  last[0] = '\n';
915  last_bulk_repeat = 0;
916 }
917 
918 
925 void
926 GNUNET_log_skip (int n, int check_reset)
927 {
928  int ok;
929 
930  if (0 == n)
931  {
932  ok = (0 == skip_log);
933  skip_log = 0;
934  if (check_reset)
935  GNUNET_break (ok);
936  }
937  else
938  {
939  skip_log += n;
940  }
941 }
942 
943 
949 int
951 {
952  return skip_log;
953 }
954 
955 
964 static void
966  const char *comp,
967  const char *message,
968  va_list va)
969 {
970  char date[DATE_STR_SIZE];
971  char date2[DATE_STR_SIZE];
972  struct tm *tmptr;
973  size_t size;
974  va_list vacp;
975 
976  va_copy (vacp, va);
977  size = vsnprintf (NULL, 0, message, vacp) + 1;
978  GNUNET_assert (0 != size);
979  va_end (vacp);
980  memset (date, 0, DATE_STR_SIZE);
981  {
982  char buf[size];
983  long long offset;
984 
985  struct timeval timeofday;
986 
987  gettimeofday (&timeofday, NULL);
988  offset = GNUNET_TIME_get_offset ();
989  if (offset > 0)
990  {
991  timeofday.tv_sec += offset / 1000LL;
992  timeofday.tv_usec += (offset % 1000LL) * 1000LL;
993  if (timeofday.tv_usec > 1000000LL)
994  {
995  timeofday.tv_usec -= 1000000LL;
996  timeofday.tv_sec++;
997  }
998  }
999  else
1000  {
1001  timeofday.tv_sec += offset / 1000LL;
1002  if (timeofday.tv_usec > -(offset % 1000LL) * 1000LL)
1003  {
1004  timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1005  }
1006  else
1007  {
1008  timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL;
1009  timeofday.tv_sec--;
1010  }
1011  }
1012  tmptr = localtime (&timeofday.tv_sec);
1013  if (NULL == tmptr)
1014  {
1015  strcpy (date, "localtime error");
1016  }
1017  else
1018  {
1019  if (0 == strftime (date2, DATE_STR_SIZE, "%b %d %H:%M:%S-%%06u", tmptr))
1020  abort ();
1021  if (0 > snprintf (date, sizeof(date), date2, timeofday.tv_usec))
1022  abort ();
1023  }
1024 
1025  vsnprintf (buf, size, message, va);
1026 #if ! (defined(GNUNET_CULL_LOGGING) || TALER_WALLET_ONLY)
1027  if (NULL != tmptr)
1028  (void) setup_log_file (tmptr);
1029 #endif
1030  if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
1031  (0 != last_bulk_time.abs_value_us) &&
1032  (0 == strncmp (buf, last_bulk, sizeof(last_bulk))))
1033  {
1034  last_bulk_repeat++;
1038  flush_bulk (date);
1039  return;
1040  }
1041  flush_bulk (date);
1042  GNUNET_strlcpy (last_bulk, buf, sizeof(last_bulk));
1043  last_bulk_repeat = 0;
1044  last_bulk_kind = kind;
1046  GNUNET_strlcpy (last_bulk_comp, comp, sizeof(last_bulk_comp));
1047  output_message (kind, comp, date, buf);
1048  }
1049 }
1050 
1051 
1059 void
1060 GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...)
1061 {
1062  va_list va;
1063 
1064  va_start (va, message);
1065  mylog (kind, component, message, va);
1066  va_end (va);
1067 }
1068 
1069 
1079 void
1081  const char *comp,
1082  const char *message,
1083  ...)
1084 {
1085  va_list va;
1086  char comp_w_pid[128];
1087 
1088  if (comp == NULL)
1089  comp = component_nopid;
1090 
1091  va_start (va, message);
1092  GNUNET_snprintf (comp_w_pid, sizeof(comp_w_pid), "%s-%d", comp, getpid ());
1093  mylog (kind, comp_w_pid, message, va);
1094  va_end (va);
1095 }
1096 
1097 
1104 const char *
1106 {
1107  if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
1108  return _ ("ERROR");
1109  if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
1110  return _ ("WARNING");
1111  if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0)
1112  return _ ("MESSAGE");
1113  if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
1114  return _ ("INFO");
1115  if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
1116  return _ ("DEBUG");
1117  if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0)
1118  return _ ("NONE");
1119  return _ ("INVALID");
1120 }
1121 
1122 
1129 const char *
1130 GNUNET_h2s (const struct GNUNET_HashCode *hc)
1131 {
1133 
1134  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1135  ret.encoding[8] = '\0';
1136  return (const char *) ret.encoding;
1137 }
1138 
1139 
1150 const char *
1151 GNUNET_h2s2 (const struct GNUNET_HashCode *hc)
1152 {
1153  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1154 
1155  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1156  ret.encoding[8] = '\0';
1157  return (const char *) ret.encoding;
1158 }
1159 
1160 
1170 const char *
1172 {
1173  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1174  struct GNUNET_HashCode hc;
1175 
1176  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1177  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1178  ret.encoding[6] = '\0';
1179  return (const char *) ret.encoding;
1180 }
1181 
1182 
1192 const char *
1194 {
1195  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1196  struct GNUNET_HashCode hc;
1197 
1198  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1199  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1200  ret.encoding[6] = '\0';
1201  return (const char *) ret.encoding;
1202 }
1203 
1204 
1214 const char *
1216 {
1217  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1218  struct GNUNET_HashCode hc;
1219 
1220  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1221  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1222  ret.encoding[6] = '\0';
1223  return (const char *) ret.encoding;
1224 }
1225 
1226 
1236 const char *
1238 {
1239  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1240  struct GNUNET_HashCode hc;
1241 
1242  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1243  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1244  ret.encoding[6] = '\0';
1245  return (const char *) ret.encoding;
1246 }
1247 
1248 
1258 const char *
1260 {
1261  static char buf[64];
1262 
1263  GNUNET_STRINGS_data_to_string (shc, sizeof(*shc), buf, sizeof(buf));
1264  buf[6] = '\0';
1265  return (const char *) buf;
1266 }
1267 
1268 
1278 const char *
1279 GNUNET_uuid2s (const struct GNUNET_Uuid *uuid)
1280 {
1281  static char buf[32];
1282 
1283  GNUNET_STRINGS_data_to_string (uuid, sizeof(*uuid), buf, sizeof(buf));
1284  buf[6] = '\0';
1285  return (const char *) buf;
1286 }
1287 
1288 
1297 const char *
1299 {
1300  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1301 
1302  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1303  ret.encoding[sizeof(ret) - 1] = '\0';
1304  return (const char *) ret.encoding;
1305 }
1306 
1307 
1315 const char *
1317 {
1318  static GNUNET_THREAD_LOCAL char buf[5];
1319  char *ret;
1320 
1321  if (NULL == pid)
1322  return "NULL";
1324  GNUNET_strlcpy (buf, ret, sizeof(buf));
1325  GNUNET_free (ret);
1326  return buf;
1327 }
1328 
1329 
1340 const char *
1342 {
1343  static GNUNET_THREAD_LOCAL char buf[5];
1344  char *ret;
1345 
1346  if (NULL == pid)
1347  return "NULL";
1349  GNUNET_strlcpy (buf, ret, sizeof(buf));
1350  GNUNET_free (ret);
1351  return buf;
1352 }
1353 
1354 
1362 const char *
1364 {
1365  static GNUNET_THREAD_LOCAL char buf[256];
1366  char *ret;
1367 
1369  strcpy (buf, ret);
1370  GNUNET_free (ret);
1371  return buf;
1372 }
1373 
1374 
1385 const char *
1386 GNUNET_a2s (const struct sockaddr *addr, socklen_t addrlen)
1387 {
1388 #define LEN \
1389  GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \
1390  (1 + sizeof(struct sockaddr_un) - sizeof(sa_family_t)))
1391  static char buf[LEN];
1392 #undef LEN
1393  static char b2[6];
1394  const struct sockaddr_in *v4;
1395  const struct sockaddr_un *un;
1396  const struct sockaddr_in6 *v6;
1397  unsigned int off;
1398 
1399  if (addr == NULL)
1400  return _ ("unknown address");
1401  switch (addr->sa_family)
1402  {
1403  case AF_INET:
1404  if (addrlen != sizeof(struct sockaddr_in))
1405  return "<invalid v4 address>";
1406  v4 = (const struct sockaddr_in *) addr;
1407  inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN);
1408  if (0 == ntohs (v4->sin_port))
1409  return buf;
1410  strcat (buf, ":");
1411  GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v4->sin_port));
1412  strcat (buf, b2);
1413  return buf;
1414 
1415  case AF_INET6:
1416  if (addrlen != sizeof(struct sockaddr_in6))
1417  return "<invalid v4 address>";
1418  v6 = (const struct sockaddr_in6 *) addr;
1419  buf[0] = '[';
1420  inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN);
1421  if (0 == ntohs (v6->sin6_port))
1422  return &buf[1];
1423  strcat (buf, "]:");
1424  GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v6->sin6_port));
1425  strcat (buf, b2);
1426  return buf;
1427 
1428  case AF_UNIX:
1429  if (addrlen <= sizeof(sa_family_t))
1430  return "<unbound UNIX client>";
1431  un = (const struct sockaddr_un *) addr;
1432  off = 0;
1433  if ('\0' == un->sun_path[0])
1434  off++;
1435  memset (buf, 0, sizeof(buf));
1436  GNUNET_snprintf (buf,
1437  sizeof(buf),
1438  "%s%.*s",
1439  (1 == off) ? "@" : "",
1440  (int) (addrlen - sizeof(sa_family_t) - off),
1441  &un->sun_path[off]);
1442  return buf;
1443 
1444  default:
1445  return _ ("invalid address");
1446  }
1447 }
1448 
1449 
1457 void
1459  const char *section,
1460  const char *option)
1461 {
1462  GNUNET_log (kind,
1463  _ (
1464  "Configuration fails to specify option `%s' in section `%s'!\n"),
1465  option,
1466  section);
1467 }
1468 
1469 
1478 void
1480  const char *section,
1481  const char *option,
1482  const char *required)
1483 {
1484  GNUNET_log (
1485  kind,
1486  _ (
1487  "Configuration specifies invalid value for option `%s' in section `%s': %s\n"),
1488  option,
1489  section,
1490  required);
1491 }
1492 
1493 
1500 void
1502  struct GNUNET_AsyncScopeSave *old_scope)
1503 {
1504  *old_scope = current_async_scope;
1507 }
1508 
1509 
1515 void
1517 {
1518  current_async_scope = *old_scope;
1519 }
1520 
1521 
1527 void
1529 {
1531  aid_ret,
1532  sizeof(struct GNUNET_AsyncScopeId));
1533 }
1534 
1535 
1541 void
1543 {
1544  *scope_ret = current_async_scope;
1545 }
1546 
1547 
1551 void __attribute__ ((constructor))
1552 GNUNET_util_cl_init ()
1553 {
1554  GNUNET_stderr = stderr;
1555 }
1556 
1557 
1561 void __attribute__ ((destructor))
1562 GNUNET_util_cl_fini ()
1563 {
1564 
1565 }
1566 
1567 
1568 /* 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:78
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:75
#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:181
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:365
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:76
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:77
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...