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
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 
150 static enum GNUNET_ErrorType min_level;
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)
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)
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 
324 const char *
325 GNUNET_b2s (const void *buf,
326  size_t buf_size)
327 {
328  static GNUNET_THREAD_LOCAL char ret[9];
329  struct GNUNET_HashCode hc;
330  char *tmp;
331 
333  buf_size,
334  &hc);
336  sizeof (hc));
337  memcpy (ret,
338  tmp,
339  8);
340  GNUNET_free (tmp);
341  ret[8] = '\0';
342  return ret;
343 }
344 
345 
352 static int
353 setup_log_file (const struct tm *tm)
354 {
355  static char last_fn[PATH_MAX + 1];
356  char fn[PATH_MAX + 1];
357  int altlog_fd;
358  int dup_return;
359  FILE *altlog;
360  char *leftsquare;
361 
362  if (NULL == log_file_name)
363  return GNUNET_SYSERR;
364  if (0 == strftime (fn, sizeof(fn), log_file_name, tm))
365  return GNUNET_SYSERR;
366  leftsquare = strrchr (fn, '[');
367  if ((NULL != leftsquare) && (']' == leftsquare[1]))
368  {
369  char *logfile_copy = GNUNET_strdup (fn);
370 
371  logfile_copy[leftsquare - fn] = '\0';
372  logfile_copy[leftsquare - fn + 1] = '\0';
373  snprintf (fn,
374  PATH_MAX,
375  "%s%d%s",
376  logfile_copy,
377  getpid (),
378  &logfile_copy[leftsquare - fn + 2]);
379  GNUNET_free (logfile_copy);
380  }
381  if (0 == strcmp (fn, last_fn))
382  return GNUNET_OK; /* no change */
383  log_rotate (last_fn);
384  strcpy (last_fn, fn);
386  {
387  fprintf (stderr,
388  "Failed to create directory for `%s': %s\n",
389  fn,
390  strerror (errno));
391  return GNUNET_SYSERR;
392  }
393  altlog_fd = open (fn,
394  O_APPEND | O_WRONLY | O_CREAT,
395  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
396 
397  if (-1 != altlog_fd)
398  {
399  if (NULL != GNUNET_stderr)
400  fclose (GNUNET_stderr);
401  dup_return = dup2 (altlog_fd, 2);
402  (void) close (altlog_fd);
403  if (-1 != dup_return)
404  {
405  altlog = fdopen (2, "ab");
406  if (NULL == altlog)
407  {
408  (void) close (2);
409  altlog_fd = -1;
410  }
411  }
412  else
413  {
414  altlog_fd = -1;
415  }
416  }
417  if (-1 == altlog_fd)
418  {
420  return GNUNET_SYSERR;
421  }
422  GNUNET_stderr = altlog;
423  return GNUNET_OK;
424 }
425 
426 
439 static int
441  const char *file,
442  const char *function,
443  int from_line,
444  int to_line,
445  int level,
446  int force)
447 {
448  struct LogDef n;
449  int r;
450 
451  if (logdefs_size == logdefs_len)
452  resize_logdefs ();
453  memset (&n, 0, sizeof(n));
454  if (0 == strlen (component))
455  component = (char *) ".*";
456  r = regcomp (&n.component_regex, (const char *) component, REG_NOSUB);
457  if (0 != r)
458  {
459  return r;
460  }
461  if (0 == strlen (file))
462  file = (char *) ".*";
463  r = regcomp (&n.file_regex, (const char *) file, REG_NOSUB);
464  if (0 != r)
465  {
466  regfree (&n.component_regex);
467  return r;
468  }
469  if ((NULL == function) || (0 == strlen (function)))
470  function = (char *) ".*";
471  r = regcomp (&n.function_regex, (const char *) function, REG_NOSUB);
472  if (0 != r)
473  {
474  regfree (&n.component_regex);
475  regfree (&n.file_regex);
476  return r;
477  }
478  n.from_line = from_line;
479  n.to_line = to_line;
480  n.level = level;
481  n.force = force;
482  logdefs[logdefs_len++] = n;
483  return 0;
484 }
485 
486 
500 int
501 GNUNET_get_log_call_status (int caller_level,
502  const char *comp,
503  const char *file,
504  const char *function,
505  int line)
506 {
507  struct LogDef *ld;
508  int i;
509  int force_only;
510 
511  if (NULL == comp)
512  /* Use default component */
513  comp = component_nopid;
514 
515  /* We have no definitions to override globally configured log level,
516  * so just use it right away.
517  */
518  if ((min_level >= 0) && (GNUNET_NO == gnunet_force_log_present))
519  return caller_level <= min_level;
520 
521  /* Only look for forced definitions? */
522  force_only = min_level >= 0;
523  for (i = 0; i < logdefs_len; i++)
524  {
525  ld = &logdefs[i];
526  if (((! force_only) || ld->force) &&
527  ((line >= ld->from_line) && (line <= ld->to_line) ) &&
528  (0 == regexec (&ld->component_regex, comp, 0, NULL, 0)) &&
529  (0 == regexec (&ld->file_regex, file, 0, NULL, 0)) &&
530  (0 == regexec (&ld->function_regex, function, 0, NULL, 0)))
531  {
532  /* We're finished */
533  return caller_level <= ld->level;
534  }
535  }
536  /* No matches - use global level, if defined */
537  if (min_level >= 0)
538  return caller_level <= min_level;
539  /* All programs/services previously defaulted to WARNING.
540  * Now *we* default to WARNING, and THEY default to NULL.
541  * Or rather we default to MESSAGE, since things aren't always bad.
542  */
543  return caller_level <= GNUNET_ERROR_TYPE_MESSAGE;
544 }
545 
546 
570 static int
571 parse_definitions (const char *constname, int force)
572 {
573  char *def;
574  const char *tmp;
575  char *comp = NULL;
576  char *file = NULL;
577  char *function = NULL;
578  char *p;
579  char *start;
580  char *t;
581  short state;
582  int level;
583  int from_line, to_line;
584  int counter = 0;
585  int keep_looking = 1;
586 
587  tmp = getenv (constname);
588  if (NULL == tmp)
589  return 0;
590  def = GNUNET_strdup (tmp);
591  from_line = 0;
592  to_line = INT_MAX;
593  for (p = def, state = 0, start = def; keep_looking; p++)
594  {
595  switch (p[0])
596  {
597  case ';': /* found a field separator */
598  p[0] = '\0';
599  switch (state)
600  {
601  case 0: /* within a component name */
602  comp = start;
603  break;
604 
605  case 1: /* within a file name */
606  file = start;
607  break;
608 
609  case 2: /* within a function name */
610  /* after a file name there must be a function name */
611  function = start;
612  break;
613 
614  case 3: /* within a from-to line range */
615  if (strlen (start) > 0)
616  {
617  errno = 0;
618  from_line = strtol (start, &t, 10);
619  if ((0 != errno) || (from_line < 0))
620  {
621  GNUNET_free (def);
622  return counter;
623  }
624  if ((t < p) && ('-' == t[0]))
625  {
626  errno = 0;
627  start = t + 1;
628  to_line = strtol (start, &t, 10);
629  if ((0 != errno) || (to_line < 0) || (t != p))
630  {
631  GNUNET_free (def);
632  return counter;
633  }
634  }
635  else /* one number means "match this line only" */
636  to_line = from_line;
637  }
638  else /* default to 0-max */
639  {
640  from_line = 0;
641  to_line = INT_MAX;
642  }
643  break;
644 
645  default:
646  fprintf (
647  stderr,
648  _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
649  p);
650  break;
651  }
652  start = p + 1;
653  state++;
654  break;
655 
656  case '\0': /* found EOL */
657  keep_looking = 0;
658 
659  /* fall through to '/' */
660  case '/': /* found a definition separator */
661  switch (state)
662  {
663  case 4: /* within a log level */
664  p[0] = '\0';
665  state = 0;
666  level = get_type ((const char *) start);
667  if ((GNUNET_ERROR_TYPE_INVALID == level) ||
669  (0 != add_definition (comp,
670  file,
671  function,
672  from_line,
673  to_line,
674  level,
675  force)))
676  {
677  GNUNET_free (def);
678  return counter;
679  }
680  counter++;
681  start = p + 1;
682  break;
683 
684  default:
685  fprintf (
686  stderr,
687  _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
688  p);
689  break;
690  }
691 
692  default:
693  break;
694  }
695  }
696  GNUNET_free (def);
697  return counter;
698 }
699 
700 
704 static void
706 {
709  parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO;
711 
713  parse_definitions ("GNUNET_LOG", 0);
715 }
716 
717 
718 #endif
719 
720 
729 int
730 GNUNET_log_setup (const char *comp,
731  const char *loglevel,
732  const char *logfile)
733 {
734  const char *env_logfile;
735 
736  min_level = get_type (loglevel);
737 #if ! defined(GNUNET_CULL_LOGGING)
739 #endif
741  GNUNET_asprintf (&component, "%s-%d", comp, getpid ());
744 
745  env_logfile = getenv ("GNUNET_FORCE_LOGFILE");
746  if ((NULL != env_logfile) && (strlen (env_logfile) > 0))
747  logfile = env_logfile;
748  if (NULL == logfile)
749  return GNUNET_OK;
752  if (NULL == log_file_name)
753  return GNUNET_SYSERR;
754 #if defined(GNUNET_CULL_LOGGING)
755  /* log file option not allowed for wallet logic */
756  GNUNET_assert (NULL == logfile);
757  return GNUNET_OK;
758 #else
759  {
760  time_t t;
761  const struct tm *tm;
762 
763  t = time (NULL);
764  tm = gmtime (&t);
765  return setup_log_file (tm);
766  }
767 #endif
768 }
769 
770 
780 void
782 {
783  struct CustomLogger *entry;
784 
785  entry = GNUNET_new (struct CustomLogger);
786  entry->logger = logger;
787  entry->logger_cls = logger_cls;
788  entry->next = loggers;
789  loggers = entry;
790 }
791 
792 
799 void
801 {
802  struct CustomLogger *pos;
803  struct CustomLogger *prev;
804 
805  prev = NULL;
806  pos = loggers;
807  while ((NULL != pos) &&
808  ((pos->logger != logger) || (pos->logger_cls != logger_cls)))
809  {
810  prev = pos;
811  pos = pos->next;
812  }
813  GNUNET_assert (NULL != pos);
814  if (NULL == prev)
815  loggers = pos->next;
816  else
817  prev->next = pos->next;
818  GNUNET_free (pos);
819 }
820 
821 
830 static void
832  const char *comp,
833  const char *datestr,
834  const char *msg)
835 {
836  struct CustomLogger *pos;
837 
838  /* only use the standard logger if no custom loggers are present */
839  if ((NULL != GNUNET_stderr) && (NULL == loggers))
840  {
841  if (kind == GNUNET_ERROR_TYPE_MESSAGE)
842  {
843  /* The idea here is to produce "normal" output messages
844  * for end users while still having the power of the
845  * logging engine for developer needs. So ideally this
846  * is what it should look like when CLI tools are used
847  * interactively, yet the same message shouldn't look
848  * this way if the output is going to logfiles or robots
849  * instead.
850  */fprintf (GNUNET_stderr, "* %s", msg);
851  }
853  {
854  static GNUNET_THREAD_LOCAL char id_buf[27];
855  char *end;
856 
857  /* We're logging, so skip_log must be currently 0. */
858  skip_log = 100;
860  sizeof(struct GNUNET_AsyncScopeId),
861  id_buf,
862  sizeof(id_buf) - 1);
863  GNUNET_assert (NULL != end);
864  *end = '\0';
865  skip_log = 0;
866  fprintf (GNUNET_stderr,
867  "%s %s(%s) %s %s",
868  datestr,
869  comp,
870  id_buf,
872  msg);
873  }
874  else
875  {
876  fprintf (GNUNET_stderr,
877  "%s %s %s %s",
878  datestr,
879  comp,
881  msg);
882  }
883  fflush (GNUNET_stderr);
884  }
885  pos = loggers;
886  while (NULL != pos)
887  {
888  pos->logger (pos->logger_cls, kind, comp, datestr, msg);
889  pos = pos->next;
890  }
891 }
892 
893 
899 static void
900 flush_bulk (const char *datestr)
901 {
902  char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
903  int rev;
904  char *last;
905  const char *ft;
906 
907  if ((0 == last_bulk_time.abs_value_us) || (0 == last_bulk_repeat))
908  return;
909  rev = 0;
910  last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
911  if (last == NULL)
912  last = &last_bulk[BULK_TRACK_SIZE - 1];
913  else if (last != last_bulk)
914  last--;
915  if (last[0] == '\n')
916  {
917  rev = 1;
918  last[0] = '\0';
919  }
920  ft =
923  GNUNET_YES);
924  snprintf (msg,
925  sizeof(msg),
926  _ ("Message `%.*s' repeated %u times in the last %s\n"),
928  last_bulk,
930  ft);
931  if (rev == 1)
932  last[0] = '\n';
935  last_bulk_repeat = 0;
936 }
937 
938 
945 void
946 GNUNET_log_skip (int n, int check_reset)
947 {
948  int ok;
949 
950  if (0 == n)
951  {
952  ok = (0 == skip_log);
953  skip_log = 0;
954  if (check_reset)
955  GNUNET_break (ok);
956  }
957  else
958  {
959  skip_log += n;
960  }
961 }
962 
963 
969 int
971 {
972  return skip_log;
973 }
974 
975 
984 static void
986  const char *comp,
987  const char *message,
988  va_list va)
989 {
990  char date[DATE_STR_SIZE];
991  char date2[DATE_STR_SIZE];
992  struct tm *tmptr;
993  size_t size;
994  va_list vacp;
995 
996  va_copy (vacp, va);
997  size = vsnprintf (NULL, 0, message, vacp) + 1;
998  GNUNET_assert (0 != size);
999  va_end (vacp);
1000  memset (date, 0, DATE_STR_SIZE);
1001  {
1002  char buf[size];
1003  long long offset;
1004 
1005  struct timeval timeofday;
1006 
1007  gettimeofday (&timeofday, NULL);
1008  offset = GNUNET_TIME_get_offset ();
1009  if (offset > 0)
1010  {
1011  timeofday.tv_sec += offset / 1000LL;
1012  timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1013  if (timeofday.tv_usec > 1000000LL)
1014  {
1015  timeofday.tv_usec -= 1000000LL;
1016  timeofday.tv_sec++;
1017  }
1018  }
1019  else
1020  {
1021  timeofday.tv_sec += offset / 1000LL;
1022  if (timeofday.tv_usec > -(offset % 1000LL) * 1000LL)
1023  {
1024  timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1025  }
1026  else
1027  {
1028  timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL;
1029  timeofday.tv_sec--;
1030  }
1031  }
1032  tmptr = localtime (&timeofday.tv_sec);
1033  if (NULL == tmptr)
1034  {
1035  strcpy (date, "localtime error");
1036  }
1037  else
1038  {
1039  /* RFC 3339 timestamp, with snprintf placeholder for microseconds */
1040  if (0 == strftime (date2, DATE_STR_SIZE, "%Y-%m-%dT%H:%M:%S.%%06u%z",
1041  tmptr))
1042  abort ();
1043  /* Fill in microseconds */
1044  if (0 > snprintf (date, sizeof(date), date2, timeofday.tv_usec))
1045  abort ();
1046  }
1047 
1048  vsnprintf (buf, size, message, va);
1049 #if ! defined(GNUNET_CULL_LOGGING)
1050  if (NULL != tmptr)
1051  (void) setup_log_file (tmptr);
1052 #endif
1053  if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
1054  (0 != last_bulk_time.abs_value_us) &&
1055  (0 == strncmp (buf, last_bulk, sizeof(last_bulk))))
1056  {
1057  last_bulk_repeat++;
1061  flush_bulk (date);
1062  return;
1063  }
1064  flush_bulk (date);
1065  GNUNET_strlcpy (last_bulk, buf, sizeof(last_bulk));
1066  last_bulk_repeat = 0;
1067  last_bulk_kind = kind;
1069  GNUNET_strlcpy (last_bulk_comp, comp, sizeof(last_bulk_comp));
1070  output_message (kind, comp, date, buf);
1071  }
1072 }
1073 
1074 
1082 void
1083 GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...)
1084 {
1085  va_list va;
1086 
1087  va_start (va, message);
1088  mylog (kind, component, message, va);
1089  va_end (va);
1090 }
1091 
1092 
1102 void
1104  const char *comp,
1105  const char *message,
1106  ...)
1107 {
1108  va_list va;
1109  char comp_w_pid[128];
1110 
1111  if (comp == NULL)
1112  comp = component_nopid;
1113 
1114  va_start (va, message);
1115  GNUNET_snprintf (comp_w_pid, sizeof(comp_w_pid), "%s-%d", comp, getpid ());
1116  mylog (kind, comp_w_pid, message, va);
1117  va_end (va);
1118 }
1119 
1120 
1127 const char *
1129 {
1130  if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
1131  return _ ("ERROR");
1132  if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
1133  return _ ("WARNING");
1134  if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0)
1135  return _ ("MESSAGE");
1136  if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
1137  return _ ("INFO");
1138  if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
1139  return _ ("DEBUG");
1140  if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0)
1141  return _ ("NONE");
1142  return _ ("INVALID");
1143 }
1144 
1145 
1152 const char *
1153 GNUNET_h2s (const struct GNUNET_HashCode *hc)
1154 {
1156 
1158  ret.encoding[8] = '\0';
1159  return (const char *) ret.encoding;
1160 }
1161 
1162 
1173 const char *
1174 GNUNET_h2s2 (const struct GNUNET_HashCode *hc)
1175 {
1177 
1179  ret.encoding[8] = '\0';
1180  return (const char *) ret.encoding;
1181 }
1182 
1183 
1193 const char *
1195 {
1197  struct GNUNET_HashCode hc;
1198 
1199  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1201  ret.encoding[6] = '\0';
1202  return (const char *) ret.encoding;
1203 }
1204 
1205 
1215 const char *
1217 {
1219  struct GNUNET_HashCode hc;
1220 
1221  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1223  ret.encoding[6] = '\0';
1224  return (const char *) ret.encoding;
1225 }
1226 
1227 
1237 const char *
1239 {
1241  struct GNUNET_HashCode hc;
1242 
1243  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1245  ret.encoding[6] = '\0';
1246  return (const char *) ret.encoding;
1247 }
1248 
1249 
1259 const char *
1261 {
1263  struct GNUNET_HashCode hc;
1264 
1265  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1267  ret.encoding[6] = '\0';
1268  return (const char *) ret.encoding;
1269 }
1270 
1271 
1281 const char *
1283 {
1284  static GNUNET_THREAD_LOCAL char buf[64];
1285 
1286  GNUNET_STRINGS_data_to_string (shc, sizeof(*shc), buf, sizeof(buf));
1287  buf[6] = '\0';
1288  return (const char *) buf;
1289 }
1290 
1291 
1301 const char *
1302 GNUNET_uuid2s (const struct GNUNET_Uuid *uuid)
1303 {
1304  static GNUNET_THREAD_LOCAL char buf[32];
1305 
1306  GNUNET_STRINGS_data_to_string (uuid, sizeof(*uuid), buf, sizeof(buf));
1307  buf[6] = '\0';
1308  return (const char *) buf;
1309 }
1310 
1311 
1320 const char *
1322 {
1324 
1326  ret.encoding[sizeof(ret) - 1] = '\0';
1327  return (const char *) ret.encoding;
1328 }
1329 
1330 
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 
1363 const char *
1365 {
1366  static GNUNET_THREAD_LOCAL char buf[5];
1367  char *ret;
1368 
1369  if (NULL == pid)
1370  return "NULL";
1372  GNUNET_strlcpy (buf, ret, sizeof(buf));
1373  GNUNET_free (ret);
1374  return buf;
1375 }
1376 
1377 
1385 const char *
1387 {
1388  static GNUNET_THREAD_LOCAL char buf[256];
1389  char *ret;
1390 
1392  strcpy (buf, ret);
1393  GNUNET_free (ret);
1394  return buf;
1395 }
1396 
1397 
1408 const char *
1409 GNUNET_a2s (const struct sockaddr *addr, socklen_t addrlen)
1410 {
1411 #define LEN \
1412  GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \
1413  (1 + sizeof(struct sockaddr_un) - sizeof(sa_family_t)))
1414  static GNUNET_THREAD_LOCAL char buf[LEN];
1415 #undef LEN
1416  static GNUNET_THREAD_LOCAL char b2[6];
1417  const struct sockaddr_in *v4;
1418  const struct sockaddr_un *un;
1419  const struct sockaddr_in6 *v6;
1420  unsigned int off;
1421 
1422  if (addr == NULL)
1423  return _ ("unknown address");
1424  switch (addr->sa_family)
1425  {
1426  case AF_INET:
1427  if (addrlen != sizeof(struct sockaddr_in))
1428  return "<invalid v4 address>";
1429  v4 = (const struct sockaddr_in *) addr;
1430  inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN);
1431  if (0 == ntohs (v4->sin_port))
1432  return buf;
1433  strcat (buf, ":");
1434  GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v4->sin_port));
1435  strcat (buf, b2);
1436  return buf;
1437 
1438  case AF_INET6:
1439  if (addrlen != sizeof(struct sockaddr_in6))
1440  return "<invalid v6 address>";
1441  v6 = (const struct sockaddr_in6 *) addr;
1442  buf[0] = '[';
1443  inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN);
1444  if (0 == ntohs (v6->sin6_port))
1445  return &buf[1];
1446  strcat (buf, "]:");
1447  GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v6->sin6_port));
1448  strcat (buf, b2);
1449  return buf;
1450 
1451  case AF_UNIX:
1452  if (addrlen <= sizeof(sa_family_t))
1453  return "<unbound UNIX client>";
1454  un = (const struct sockaddr_un *) addr;
1455  off = 0;
1456  if ('\0' == un->sun_path[0])
1457  off++;
1458  memset (buf, 0, sizeof(buf));
1460  sizeof(buf),
1461  "%s%.*s",
1462  (1 == off) ? "@" : "",
1463  (int) (addrlen - sizeof(sa_family_t) - off),
1464  &un->sun_path[off]);
1465  return buf;
1466 
1467  default:
1468  return _ ("invalid address");
1469  }
1470 }
1471 
1472 
1480 void
1482  const char *section,
1483  const char *option)
1484 {
1485  GNUNET_log (kind,
1486  _ (
1487  "Configuration fails to specify option `%s' in section `%s'!\n"),
1488  option,
1489  section);
1490 }
1491 
1492 
1501 void
1503  const char *section,
1504  const char *option,
1505  const char *required)
1506 {
1507  GNUNET_log (
1508  kind,
1509  _ (
1510  "Configuration specifies invalid value for option `%s' in section `%s': %s\n"),
1511  option,
1512  section,
1513  required);
1514 }
1515 
1516 
1523 void
1525  struct GNUNET_AsyncScopeSave *old_scope)
1526 {
1527  *old_scope = current_async_scope;
1530 }
1531 
1532 
1538 void
1540 {
1541  current_async_scope = *old_scope;
1542 }
1543 
1544 
1550 void
1552 {
1554  aid_ret,
1555  sizeof(struct GNUNET_AsyncScopeId));
1556 }
1557 
1558 
1564 void
1566 {
1567  *scope_ret = current_async_scope;
1568 }
1569 
1570 
1574 void __attribute__ ((constructor))
1575 GNUNET_util_cl_init ()
1576 {
1577  GNUNET_stderr = stderr;
1578 }
1579 
1580 
1584 void __attribute__ ((destructor))
1585 GNUNET_util_cl_fini ()
1586 {
1587 
1588 }
1589 
1590 
1591 /* end of common_logging.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define INT_MAX
static int gnunet_force_log_present
GNUNET_YES if at least one definition with forced == 1 is available.
#define LEN
const char * GNUNET_b2s(const void *buf, size_t buf_size)
Convert a buffer to an 8-character string representative of the contents.
static void log_rotate(const char *new_name)
Rotate logs, deleting the oldest log.
static GNUNET_THREAD_LOCAL struct GNUNET_TIME_Absolute last_bulk_time
Time of the last bulk error message (0 for none)
static GNUNET_THREAD_LOCAL char last_bulk_comp[32+1]
Component when the last bulk was logged.
static void parse_all_definitions()
Utility function - parses GNUNET_LOG and GNUNET_FORCE_LOG.
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.
static int logdefs_len
The number of units used in logdefs array.
#define BULK_DELAY_THRESHOLD
After how many milliseconds do we always print that "message X was repeated N times"?...
static int logdefs_size
Allocated size of logdefs array (in units)
void GNUNET_log_nocheck(enum GNUNET_ErrorType kind, const char *message,...)
Main log function.
static struct LogDef * logdefs
Dynamic array of logging definitions.
static int parse_definitions(const char *constname, int force)
Utility function - parses a definition.
static void mylog(enum GNUNET_ErrorType kind, const char *comp, const char *message, va_list va)
Output a log message using the default mechanism.
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.
#define BULK_REPEAT_THRESHOLD
After how many repetitions do we always print that "message X was repeated N times"?...
static void output_message(enum GNUNET_ErrorType kind, const char *comp, const char *datestr, const char *msg)
Actually output the log message.
static char * log_file_name
Format string describing the name of the log file.
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.
static GNUNET_THREAD_LOCAL unsigned int last_bulk_repeat
Number of times that bulk message has been repeated since.
static char * component_nopid
Running component (without pid).
static FILE * GNUNET_stderr
File descriptor to use for "stderr", or NULL for none.
static int gnunet_log_parsed
GNUNET_YES if GNUNET_LOG environment variable is already parsed.
void GNUNET_log_from_nocheck(enum GNUNET_ErrorType kind, const char *comp, const char *message,...)
Log function that specifies an alternative component.
static enum GNUNET_ErrorType get_type(const char *log)
Convert a textual description of a loglevel to the respective enumeration type.
void GNUNET_async_scope_enter(const struct GNUNET_AsyncScopeId *aid, struct GNUNET_AsyncScopeSave *old_scope)
Set the async scope for the current thread.
static GNUNET_THREAD_LOCAL char last_bulk[256] __nonstring
The last "bulk" error message that we have been logging.
void GNUNET_async_scope_get(struct GNUNET_AsyncScopeSave *scope_ret)
Get the current async scope.
#define COMP_TRACK_SIZE
How many characters do we use for matching of bulk components?
static GNUNET_THREAD_LOCAL int skip_log
Number of log calls to ignore.
void GNUNET_async_scope_fresh(struct GNUNET_AsyncScopeId *aid_ret)
Generate a fresh async scope identifier.
void GNUNET_async_scope_restore(struct GNUNET_AsyncScopeSave *old_scope)
Clear the current thread's async scope.
#define DATE_STR_SIZE
How many characters can a date/time string be at most?
static char * component
Running component.
#define BULK_TRACK_SIZE
How many characters do we use for matching of bulk messages?
static struct CustomLogger * loggers
Linked list of our custom loggres.
#define PATH_MAX
Assumed maximum path length (for the log file name).
static enum GNUNET_ErrorType min_level
Minimum log level.
#define ROTATION_KEEP
How many log files to keep?
static int setup_log_file(const struct tm *tm)
Setup the log file.
static void flush_bulk(const char *datestr)
Flush an existing bulk report to the output.
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.
static void resize_logdefs(void)
Utility function - reallocates logdefs array to be twice as large.
void __attribute__((constructor))
Initializer.
char * getenv()
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static char * line
Desired phone line (string to be converted to a hash).
static int ok
Return value from 'main' (0 == success)
enum State state
current state of profiling
static char buf[2048]
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:37
static struct GNUNET_SCHEDULER_Task * t
Main task.
#define GNUNET_log(kind,...)
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
cryptographic primitives for GNUnet
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:251
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:582
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
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:55
const char * GNUNET_h2s2(const struct GNUNET_HashCode *hc)
Convert a hash to a string (for printing debug messages).
GNUNET_ErrorType
Types of errors.
const char * GNUNET_e2s2(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
const char * GNUNET_p2s2(const struct GNUNET_CRYPTO_EddsaPublicKey *p)
Convert a public key value to a string (for printing debug messages).
const char * GNUNET_uuid2s(const struct GNUNET_Uuid *uuid)
Convert a UUID to a string (for printing debug messages).
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_error_type_to_string(enum GNUNET_ErrorType kind)
Convert error type to string.
int GNUNET_get_log_skip()
Get the number of log calls that are going to be skipped.
const char * GNUNET_e2s(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.
const char * GNUNET_i2s2(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_h2s_full(const struct GNUNET_HashCode *hc)
Convert a hash to a string (for printing debug messages).
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_skip(int n, int check_reset)
Ignore the next n calls to the log function.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash to a string (for printing debug messages).
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.
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_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
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).
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
void GNUNET_abort_()
Abort the process, generate a core dump if possible.
void GNUNET_logger_add(GNUNET_Logger logger, void *logger_cls)
Add a custom logger.
void(* GNUNET_Logger)(void *cls, enum GNUNET_ErrorType kind, const char *component, const char *date, const char *message)
User-defined handler for log messages.
const char * GNUNET_p2s(const struct GNUNET_CRYPTO_EddsaPublicKey *p)
Convert a public key value to a string (for printing debug messages).
void GNUNET_logger_remove(GNUNET_Logger logger, void *logger_cls)
Remove a custom logger.
@ GNUNET_ERROR_TYPE_UNSPECIFIED
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_NONE
@ GNUNET_ERROR_TYPE_INVALID
@ GNUNET_ERROR_TYPE_MESSAGE
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
#define GNUNET_free(ptr)
Wrapper around free.
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition: strings.c:495
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:709
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:764
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:139
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:435
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
long long GNUNET_TIME_get_offset(void)
Get the timestamp offset for this instance.
Definition: time.c:55
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:570
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
#define GNUNET_THREAD_LOCAL
Definition: platform.h:246
Linked list of active loggers.
void * logger_cls
Closure for logger.
struct CustomLogger * next
This is a linked list.
GNUNET_Logger logger
Log function.
Identifier for an asynchronous execution context.
Saved async scope identifier or root scope.
int have_scope
GNUNET_YES unless this saved scope is the unnamed root scope.
struct GNUNET_AsyncScopeId scope_id
Saved scope.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
0-terminated ASCII encoding of a struct GNUNET_HashCode.
A 512-bit hashcode.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
A 256-bit hashcode.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
uint64_t rel_value_us
The actual value.
A UUID, a 128 bit "random" value.
Represents a single logging definition.
int to_line
Highest line at which this definition matches.
int from_line
Lowest line at which this definition matches.
int force
1 if this definition comes from GNUNET_FORCE_LOG, which means that it overrides any configuration opt...
regex_t file_regex
File name regex.
regex_t function_regex
Function name regex.
int level
Maximal log level allowed for calls that match this definition.
regex_t component_regex
Component name regex.