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 
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) ||
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  /* RFC 3339 timestamp, with snprintf placeholder for microseconds */
1018  if (0 == strftime (date2, DATE_STR_SIZE, "%Y-%m-%dT%H:%M:%S.%%06u%z", tmptr))
1019  abort ();
1020  /* Fill in microseconds */
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)
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 
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 {
1154 
1156  ret.encoding[8] = '\0';
1157  return (const char *) ret.encoding;
1158 }
1159 
1160 
1170 const char *
1172 {
1174  struct GNUNET_HashCode hc;
1175 
1176  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1178  ret.encoding[6] = '\0';
1179  return (const char *) ret.encoding;
1180 }
1181 
1182 
1192 const char *
1194 {
1196  struct GNUNET_HashCode hc;
1197 
1198  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1200  ret.encoding[6] = '\0';
1201  return (const char *) ret.encoding;
1202 }
1203 
1204 
1214 const char *
1216 {
1218  struct GNUNET_HashCode hc;
1219 
1220  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1222  ret.encoding[6] = '\0';
1223  return (const char *) ret.encoding;
1224 }
1225 
1226 
1236 const char *
1238 {
1240  struct GNUNET_HashCode hc;
1241 
1242  GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1244  ret.encoding[6] = '\0';
1245  return (const char *) ret.encoding;
1246 }
1247 
1248 
1258 const char *
1260 {
1261  static GNUNET_THREAD_LOCAL 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 GNUNET_THREAD_LOCAL 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 {
1301 
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 GNUNET_THREAD_LOCAL char buf[LEN];
1392 #undef LEN
1393  static GNUNET_THREAD_LOCAL 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 v6 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));
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 */
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
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)
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
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_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
static char * fn
Filename of the unique file.
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:482
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:695
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:162
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:263
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:86
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:557
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.