GNUnet  0.10.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 
110 static GNUNET_THREAD_LOCAL char last_bulk[BULK_TRACK_SIZE]
111  __attribute__ ((nonstring));
112 
117 
122 
127 
132 
136 static char *component;
137 
141 static char *component_nopid;
142 
146 static char *log_file_name;
147 
152 
156 static struct CustomLogger *loggers;
157 
162 
166 static FILE *GNUNET_stderr;
167 
171 struct LogDef
172 {
177 
181  regex_t file_regex;
182 
186  regex_t function_regex;
187 
193 
198  int to_line;
199 
205  int level;
206 
211  int force;
212 };
213 
214 
215 #if ! defined(GNUNET_CULL_LOGGING)
216 
219 static struct LogDef *logdefs;
220 
224 static int logdefs_size;
225 
229 static int logdefs_len;
230 
234 static int gnunet_log_parsed;
235 
240 
245 #endif
246 
247 #ifdef WINDOWS
248 
251 static LARGE_INTEGER performance_frequency;
252 #endif
253 
254 
262 static enum GNUNET_ErrorType
263 get_type (const char *log)
264 {
265  if (NULL == log)
267  if (0 == strcasecmp (log, _ ("DEBUG")))
269  if (0 == strcasecmp (log, _ ("INFO")))
270  return GNUNET_ERROR_TYPE_INFO;
271  if (0 == strcasecmp (log, _ ("MESSAGE")))
273  if (0 == strcasecmp (log, _ ("WARNING")))
275  if (0 == strcasecmp (log, _ ("ERROR")))
277  if (0 == strcasecmp (log, _ ("NONE")))
278  return GNUNET_ERROR_TYPE_NONE;
280 }
281 
282 
286 void
288 {
289 #if WINDOWS
290  DebugBreak ();
291 #endif
292  abort ();
293 }
294 
295 
296 #if ! defined(GNUNET_CULL_LOGGING)
297 
300 static void
302 {
303  logdefs_size = (logdefs_size + 1) * 2;
304  logdefs = GNUNET_realloc (logdefs, logdefs_size * sizeof (struct LogDef));
305 }
306 
307 
308 #if ! TALER_WALLET_ONLY
309 
314 static void
315 log_rotate (const char *new_name)
316 {
317  static char *rotation[ROTATION_KEEP];
318  static unsigned int rotation_off;
319  char *discard;
320 
321  if ('\0' == *new_name)
322  return; /* not a real log file name */
323  discard = rotation[rotation_off % ROTATION_KEEP];
324  if (NULL != discard)
325  {
326  /* Note: can't log errors during logging (recursion!), so this
327  operation MUST silently fail... */
328  (void) UNLINK (discard);
329  GNUNET_free (discard);
330  }
331  rotation[rotation_off % ROTATION_KEEP] = GNUNET_strdup (new_name);
332  rotation_off++;
333 }
334 
335 
342 static int
343 setup_log_file (const struct tm *tm)
344 {
345  static char last_fn[PATH_MAX + 1];
346  char fn[PATH_MAX + 1];
347  int altlog_fd;
348  int dup_return;
349  FILE *altlog;
350  char *leftsquare;
351 
352  if (NULL == log_file_name)
353  return GNUNET_SYSERR;
354  if (0 == strftime (fn, sizeof (fn), log_file_name, tm))
355  return GNUNET_SYSERR;
356  leftsquare = strrchr (fn, '[');
357  if ((NULL != leftsquare) && (']' == leftsquare[1]))
358  {
359  char *logfile_copy = GNUNET_strdup (fn);
360 
361  logfile_copy[leftsquare - fn] = '\0';
362  logfile_copy[leftsquare - fn + 1] = '\0';
363  snprintf (fn,
364  PATH_MAX,
365  "%s%d%s",
366  logfile_copy,
367  getpid (),
368  &logfile_copy[leftsquare - fn + 2]);
369  GNUNET_free (logfile_copy);
370  }
371  if (0 == strcmp (fn, last_fn))
372  return GNUNET_OK; /* no change */
373  log_rotate (last_fn);
374  strcpy (last_fn, fn);
376  {
377  fprintf (stderr,
378  "Failed to create directory for `%s': %s\n",
379  fn,
380  STRERROR (errno));
381  return GNUNET_SYSERR;
382  }
383 #if WINDOWS
384  altlog_fd =
385  OPEN (fn, O_APPEND | O_BINARY | O_WRONLY | O_CREAT, _S_IREAD | _S_IWRITE);
386 #else
387  altlog_fd = OPEN (fn,
388  O_APPEND | O_WRONLY | O_CREAT,
389  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
390 #endif
391  if (-1 != altlog_fd)
392  {
393  if (NULL != GNUNET_stderr)
394  fclose (GNUNET_stderr);
395  dup_return = dup2 (altlog_fd, 2);
396  (void) close (altlog_fd);
397  if (-1 != dup_return)
398  {
399  altlog = fdopen (2, "ab");
400  if (NULL == altlog)
401  {
402  (void) close (2);
403  altlog_fd = -1;
404  }
405  }
406  else
407  {
408  altlog_fd = -1;
409  }
410  }
411  if (-1 == altlog_fd)
412  {
414  return GNUNET_SYSERR;
415  }
416  GNUNET_stderr = altlog;
417  return GNUNET_OK;
418 }
419 #endif
420 
421 
434 static int
435 add_definition (const char *component,
436  const char *file,
437  const char *function,
438  int from_line,
439  int to_line,
440  int level,
441  int force)
442 {
443  struct LogDef n;
444  int r;
445 
446  if (logdefs_size == logdefs_len)
447  resize_logdefs ();
448  memset (&n, 0, sizeof (n));
449  if (0 == strlen (component))
450  component = (char *) ".*";
451  r = regcomp (&n.component_regex, (const char *) component, REG_NOSUB);
452  if (0 != r)
453  {
454  return r;
455  }
456  if (0 == strlen (file))
457  file = (char *) ".*";
458  r = regcomp (&n.file_regex, (const char *) file, REG_NOSUB);
459  if (0 != r)
460  {
461  regfree (&n.component_regex);
462  return r;
463  }
464  if ((NULL == function) || (0 == strlen (function)))
465  function = (char *) ".*";
466  r = regcomp (&n.function_regex, (const char *) function, REG_NOSUB);
467  if (0 != r)
468  {
469  regfree (&n.component_regex);
470  regfree (&n.file_regex);
471  return r;
472  }
473  n.from_line = from_line;
474  n.to_line = to_line;
475  n.level = level;
476  n.force = force;
477  logdefs[logdefs_len++] = n;
478  return 0;
479 }
480 
481 
495 int
496 GNUNET_get_log_call_status (int caller_level,
497  const char *comp,
498  const char *file,
499  const char *function,
500  int line)
501 {
502  struct LogDef *ld;
503  int i;
504  int force_only;
505 
506  if (NULL == comp)
507  /* Use default component */
508  comp = component_nopid;
509 
510  /* We have no definitions to override globally configured log level,
511  * so just use it right away.
512  */
513  if ((min_level >= 0) && (GNUNET_NO == gnunet_force_log_present))
514  return caller_level <= min_level;
515 
516  /* Only look for forced definitions? */
517  force_only = min_level >= 0;
518  for (i = 0; i < logdefs_len; i++)
519  {
520  ld = &logdefs[i];
521  if (((! force_only) || ld->force) &&
522  (line >= ld->from_line && line <= ld->to_line) &&
523  (0 == regexec (&ld->component_regex, comp, 0, NULL, 0)) &&
524  (0 == regexec (&ld->file_regex, file, 0, NULL, 0)) &&
525  (0 == regexec (&ld->function_regex, function, 0, NULL, 0)))
526  {
527  /* We're finished */
528  return caller_level <= ld->level;
529  }
530  }
531  /* No matches - use global level, if defined */
532  if (min_level >= 0)
533  return caller_level <= min_level;
534  /* All programs/services previously defaulted to WARNING.
535  * Now *we* default to WARNING, and THEY default to NULL.
536  * Or rather we default to MESSAGE, since things aren't always bad.
537  */
538  return caller_level <= GNUNET_ERROR_TYPE_MESSAGE;
539 }
540 
541 
565 static int
566 parse_definitions (const char *constname, int force)
567 {
568  char *def;
569  const char *tmp;
570  char *comp = NULL;
571  char *file = NULL;
572  char *function = NULL;
573  char *p;
574  char *start;
575  char *t;
576  short state;
577  int level;
578  int from_line, to_line;
579  int counter = 0;
580  int keep_looking = 1;
581 
582  tmp = getenv (constname);
583  if (NULL == tmp)
584  return 0;
585  def = GNUNET_strdup (tmp);
586  from_line = 0;
587  to_line = INT_MAX;
588  for (p = def, state = 0, start = def; keep_looking; p++)
589  {
590  switch (p[0])
591  {
592  case ';': /* found a field separator */
593  p[0] = '\0';
594  switch (state)
595  {
596  case 0: /* within a component name */
597  comp = start;
598  break;
599  case 1: /* within a file name */
600  file = start;
601  break;
602  case 2: /* within a function name */
603  /* after a file name there must be a function name */
604  function = start;
605  break;
606  case 3: /* within a from-to line range */
607  if (strlen (start) > 0)
608  {
609  errno = 0;
610  from_line = strtol (start, &t, 10);
611  if ((0 != errno) || (from_line < 0))
612  {
613  GNUNET_free (def);
614  return counter;
615  }
616  if ((t < p) && ('-' == t[0]))
617  {
618  errno = 0;
619  start = t + 1;
620  to_line = strtol (start, &t, 10);
621  if ((0 != errno) || (to_line < 0) || (t != p))
622  {
623  GNUNET_free (def);
624  return counter;
625  }
626  }
627  else /* one number means "match this line only" */
628  to_line = from_line;
629  }
630  else /* default to 0-max */
631  {
632  from_line = 0;
633  to_line = INT_MAX;
634  }
635  break;
636  default:
637  fprintf (
638  stderr,
639  _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
640  p);
641  break;
642  }
643  start = p + 1;
644  state++;
645  break;
646  case '\0': /* found EOL */
647  keep_looking = 0;
648  /* fall through to '/' */
649  case '/': /* found a definition separator */
650  switch (state)
651  {
652  case 4: /* within a log level */
653  p[0] = '\0';
654  state = 0;
655  level = get_type ((const char *) start);
656  if ((GNUNET_ERROR_TYPE_INVALID == level) ||
657  (GNUNET_ERROR_TYPE_UNSPECIFIED == level) ||
658  (0 != add_definition (comp,
659  file,
660  function,
661  from_line,
662  to_line,
663  level,
664  force)))
665  {
666  GNUNET_free (def);
667  return counter;
668  }
669  counter++;
670  start = p + 1;
671  break;
672  default:
673  fprintf (
674  stderr,
675  _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
676  p);
677  break;
678  }
679  default:
680  break;
681  }
682  }
683  GNUNET_free (def);
684  return counter;
685 }
686 
687 
691 static void
693 {
694  if (GNUNET_NO == gnunet_force_log_parsed)
695  gnunet_force_log_present =
696  parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO;
697  gnunet_force_log_parsed = GNUNET_YES;
698 
699  if (GNUNET_NO == gnunet_log_parsed)
700  parse_definitions ("GNUNET_LOG", 0);
701  gnunet_log_parsed = GNUNET_YES;
702 }
703 #endif
704 
705 
714 int
715 GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile)
716 {
717  const char *env_logfile;
718 
719  min_level = get_type (loglevel);
720 #if ! defined(GNUNET_CULL_LOGGING)
722 #endif
723 #ifdef WINDOWS
724  QueryPerformanceFrequency (&performance_frequency);
725 #endif
726  GNUNET_free_non_null (component);
727  GNUNET_asprintf (&component, "%s-%d", comp, getpid ());
728  GNUNET_free_non_null (component_nopid);
729  component_nopid = GNUNET_strdup (comp);
730 
731  env_logfile = getenv ("GNUNET_FORCE_LOGFILE");
732  if ((NULL != env_logfile) && (strlen (env_logfile) > 0))
733  logfile = env_logfile;
734  if (NULL == logfile)
735  return GNUNET_OK;
736  GNUNET_free_non_null (log_file_name);
737  log_file_name = GNUNET_STRINGS_filename_expand (logfile);
738  if (NULL == log_file_name)
739  return GNUNET_SYSERR;
740 #if TALER_WALLET_ONLY || defined(GNUNET_CULL_LOGGING)
741  /* log file option not allowed for wallet logic */
742  GNUNET_assert (NULL == logfile);
743  return GNUNET_OK;
744 #else
745  {
746  time_t t;
747  const struct tm *tm;
748 
749  t = time (NULL);
750  tm = gmtime (&t);
751  return setup_log_file (tm);
752  }
753 #endif
754 }
755 
756 
766 void
768 {
769  struct CustomLogger *entry;
770 
771  entry = GNUNET_new (struct CustomLogger);
772  entry->logger = logger;
773  entry->logger_cls = logger_cls;
774  entry->next = loggers;
775  loggers = entry;
776 }
777 
778 
785 void
787 {
788  struct CustomLogger *pos;
789  struct CustomLogger *prev;
790 
791  prev = NULL;
792  pos = loggers;
793  while ((NULL != pos) &&
794  ((pos->logger != logger) || (pos->logger_cls != logger_cls)))
795  {
796  prev = pos;
797  pos = pos->next;
798  }
799  GNUNET_assert (NULL != pos);
800  if (NULL == prev)
801  loggers = pos->next;
802  else
803  prev->next = pos->next;
804  GNUNET_free (pos);
805 }
806 
807 #if WINDOWS
808 CRITICAL_SECTION output_message_cs;
809 #endif
810 
811 
820 static void
822  const char *comp,
823  const char *datestr,
824  const char *msg)
825 {
826  struct CustomLogger *pos;
827 
828 #if WINDOWS
829  EnterCriticalSection (&output_message_cs);
830 #endif
831  /* only use the standard logger if no custom loggers are present */
832  if ((NULL != GNUNET_stderr) && (NULL == loggers))
833  {
834  if (kind == GNUNET_ERROR_TYPE_MESSAGE)
835  {
836  /* The idea here is to produce "normal" output messages
837  * for end users while still having the power of the
838  * logging engine for developer needs. So ideally this
839  * is what it should look like when CLI tools are used
840  * interactively, yet the same message shouldn't look
841  * this way if the output is going to logfiles or robots
842  * instead.
843  */
844  FPRINTF (GNUNET_stderr, "* %s", msg);
845  }
847  {
848  static GNUNET_THREAD_LOCAL char id_buf[27];
849  char *end;
850 
851  /* We're logging, so skip_log must be currently 0. */
852  skip_log = 100;
854  sizeof (struct GNUNET_AsyncScopeId),
855  id_buf,
856  sizeof (id_buf) - 1);
857  GNUNET_assert (NULL != end);
858  *end = '\0';
859  skip_log = 0;
860  FPRINTF (GNUNET_stderr,
861  "%s %s(%s) %s %s",
862  datestr,
863  comp,
864  id_buf,
866  msg);
867  }
868  else
869  {
870  FPRINTF (GNUNET_stderr,
871  "%s %s %s %s",
872  datestr,
873  comp,
875  msg);
876  }
877  fflush (GNUNET_stderr);
878  }
879  pos = loggers;
880  while (NULL != pos)
881  {
882  pos->logger (pos->logger_cls, kind, comp, datestr, msg);
883  pos = pos->next;
884  }
885 #if WINDOWS
886  LeaveCriticalSection (&output_message_cs);
887 #endif
888 }
889 
890 
896 static void
897 flush_bulk (const char *datestr)
898 {
899  char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
900  int rev;
901  char *last;
902  const char *ft;
903 
904  if ((0 == last_bulk_time.abs_value_us) || (0 == last_bulk_repeat))
905  return;
906  rev = 0;
907  last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
908  if (last == NULL)
909  last = &last_bulk[BULK_TRACK_SIZE - 1];
910  else if (last != last_bulk)
911  last--;
912  if (last[0] == '\n')
913  {
914  rev = 1;
915  last[0] = '\0';
916  }
917  ft =
920  GNUNET_YES);
921  snprintf (msg,
922  sizeof (msg),
923  _ ("Message `%.*s' repeated %u times in the last %s\n"),
925  last_bulk,
926  last_bulk_repeat,
927  ft);
928  if (rev == 1)
929  last[0] = '\n';
930  output_message (last_bulk_kind, last_bulk_comp, datestr, msg);
932  last_bulk_repeat = 0;
933 }
934 
935 
942 void
943 GNUNET_log_skip (int n, int check_reset)
944 {
945  int ok;
946 
947  if (0 == n)
948  {
949  ok = (0 == skip_log);
950  skip_log = 0;
951  if (check_reset)
952  GNUNET_break (ok);
953  }
954  else
955  {
956  skip_log += n;
957  }
958 }
959 
960 
966 int
968 {
969  return skip_log;
970 }
971 
972 
981 static void
983  const char *comp,
984  const char *message,
985  va_list va)
986 {
987  char date[DATE_STR_SIZE];
988  char date2[DATE_STR_SIZE];
989  struct tm *tmptr;
990  size_t size;
991  va_list vacp;
992 
993  va_copy (vacp, va);
994  size = VSNPRINTF (NULL, 0, message, vacp) + 1;
995  GNUNET_assert (0 != size);
996  va_end (vacp);
997  memset (date, 0, DATE_STR_SIZE);
998  {
999  char buf[size];
1000  long long offset;
1001 #ifdef WINDOWS
1002  LARGE_INTEGER pc;
1003  time_t timetmp;
1004 
1005  offset = GNUNET_TIME_get_offset ();
1006  time (&timetmp);
1007  timetmp += offset / 1000;
1008  tmptr = localtime (&timetmp);
1009  pc.QuadPart = 0;
1010  QueryPerformanceCounter (&pc);
1011  if (NULL == tmptr)
1012  {
1013  strcpy (date, "localtime error");
1014  }
1015  else
1016  {
1017  if (0 ==
1018  strftime (date2, DATE_STR_SIZE, "%b %d %H:%M:%S-%%020llu", tmptr))
1019  abort ();
1020  if (0 > snprintf (date,
1021  sizeof (date),
1022  date2,
1023  (long long) (pc.QuadPart /
1024  (performance_frequency.QuadPart / 1000))))
1025  abort ();
1026  }
1027 #else
1028  struct timeval timeofday;
1029 
1030  gettimeofday (&timeofday, NULL);
1031  offset = GNUNET_TIME_get_offset ();
1032  if (offset > 0)
1033  {
1034  timeofday.tv_sec += offset / 1000LL;
1035  timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1036  if (timeofday.tv_usec > 1000000LL)
1037  {
1038  timeofday.tv_usec -= 1000000LL;
1039  timeofday.tv_sec++;
1040  }
1041  }
1042  else
1043  {
1044  timeofday.tv_sec += offset / 1000LL;
1045  if (timeofday.tv_usec > -(offset % 1000LL) * 1000LL)
1046  {
1047  timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1048  }
1049  else
1050  {
1051  timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL;
1052  timeofday.tv_sec--;
1053  }
1054  }
1055  tmptr = localtime (&timeofday.tv_sec);
1056  if (NULL == tmptr)
1057  {
1058  strcpy (date, "localtime error");
1059  }
1060  else
1061  {
1062  if (0 == strftime (date2, DATE_STR_SIZE, "%b %d %H:%M:%S-%%06u", tmptr))
1063  abort ();
1064  if (0 > snprintf (date, sizeof (date), date2, timeofday.tv_usec))
1065  abort ();
1066  }
1067 #endif
1068  VSNPRINTF (buf, size, message, va);
1069 #if ! (defined(GNUNET_CULL_LOGGING) || TALER_WALLET_ONLY)
1070  if (NULL != tmptr)
1071  (void) setup_log_file (tmptr);
1072 #endif
1073  if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
1074  (0 != last_bulk_time.abs_value_us) &&
1075  (0 == strncmp (buf, last_bulk, sizeof (last_bulk))))
1076  {
1077  last_bulk_repeat++;
1080  (last_bulk_repeat > BULK_REPEAT_THRESHOLD))
1081  flush_bulk (date);
1082  return;
1083  }
1084  flush_bulk (date);
1085  GNUNET_strlcpy (last_bulk, buf, sizeof (last_bulk));
1086  last_bulk_repeat = 0;
1087  last_bulk_kind = kind;
1089  GNUNET_strlcpy (last_bulk_comp, comp, sizeof (last_bulk_comp));
1090  output_message (kind, comp, date, buf);
1091  }
1092 }
1093 
1094 
1102 void
1103 GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...)
1104 {
1105  va_list va;
1106 
1107  va_start (va, message);
1108  mylog (kind, component, message, va);
1109  va_end (va);
1110 }
1111 
1112 
1122 void
1124  const char *comp,
1125  const char *message,
1126  ...)
1127 {
1128  va_list va;
1129  char comp_w_pid[128];
1130 
1131  if (comp == NULL)
1132  comp = component_nopid;
1133 
1134  va_start (va, message);
1135  GNUNET_snprintf (comp_w_pid, sizeof (comp_w_pid), "%s-%d", comp, getpid ());
1136  mylog (kind, comp_w_pid, message, va);
1137  va_end (va);
1138 }
1139 
1140 
1147 const char *
1149 {
1150  if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
1151  return _ ("ERROR");
1152  if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
1153  return _ ("WARNING");
1154  if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0)
1155  return _ ("MESSAGE");
1156  if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
1157  return _ ("INFO");
1158  if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
1159  return _ ("DEBUG");
1160  if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0)
1161  return _ ("NONE");
1162  return _ ("INVALID");
1163 }
1164 
1165 
1172 const char *
1173 GNUNET_h2s (const struct GNUNET_HashCode *hc)
1174 {
1176 
1177  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1178  ret.encoding[8] = '\0';
1179  return (const char *) ret.encoding;
1180 }
1181 
1182 
1193 const char *
1194 GNUNET_h2s2 (const struct GNUNET_HashCode *hc)
1195 {
1196  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1197 
1198  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1199  ret.encoding[8] = '\0';
1200  return (const char *) ret.encoding;
1201 }
1202 
1203 
1213 const char *
1215 {
1216  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1217  struct GNUNET_HashCode hc;
1218 
1219  GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1220  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1221  ret.encoding[6] = '\0';
1222  return (const char *) ret.encoding;
1223 }
1224 
1225 
1235 const char *
1237 {
1238  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1239  struct GNUNET_HashCode hc;
1240 
1241  GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1242  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1243  ret.encoding[6] = '\0';
1244  return (const char *) ret.encoding;
1245 }
1246 
1247 
1257 const char *
1259 {
1260  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1261  struct GNUNET_HashCode hc;
1262 
1263  GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1264  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1265  ret.encoding[6] = '\0';
1266  return (const char *) ret.encoding;
1267 }
1268 
1269 
1279 const char *
1281 {
1282  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1283  struct GNUNET_HashCode hc;
1284 
1285  GNUNET_CRYPTO_hash (p, sizeof (*p), &hc);
1286  GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
1287  ret.encoding[6] = '\0';
1288  return (const char *) ret.encoding;
1289 }
1290 
1291 
1301 const char *
1303 {
1304  static char buf[64];
1305 
1306  GNUNET_STRINGS_data_to_string (shc, sizeof (*shc), buf, sizeof (buf));
1307  buf[6] = '\0';
1308  return (const char *) buf;
1309 }
1310 
1311 
1321 const char *
1322 GNUNET_uuid2s (const struct GNUNET_Uuid *uuid)
1323 {
1324  static char buf[32];
1325 
1326  GNUNET_STRINGS_data_to_string (uuid, sizeof (*uuid), buf, sizeof (buf));
1327  buf[6] = '\0';
1328  return (const char *) buf;
1329 }
1330 
1331 
1340 const char *
1342 {
1343  static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1344 
1345  GNUNET_CRYPTO_hash_to_enc (hc, &ret);
1346  ret.encoding[sizeof (ret) - 1] = '\0';
1347  return (const char *) ret.encoding;
1348 }
1349 
1350 
1358 const char *
1360 {
1361  static GNUNET_THREAD_LOCAL char buf[5];
1362  char *ret;
1363 
1364  if (NULL == pid)
1365  return "NULL";
1367  GNUNET_strlcpy (buf, ret, sizeof (buf));
1368  GNUNET_free (ret);
1369  return buf;
1370 }
1371 
1372 
1383 const char *
1385 {
1386  static GNUNET_THREAD_LOCAL char buf[5];
1387  char *ret;
1388 
1389  if (NULL == pid)
1390  return "NULL";
1392  GNUNET_strlcpy (buf, ret, sizeof (buf));
1393  GNUNET_free (ret);
1394  return buf;
1395 }
1396 
1397 
1405 const char *
1407 {
1408  static GNUNET_THREAD_LOCAL char buf[256];
1409  char *ret;
1410 
1412  strcpy (buf, ret);
1413  GNUNET_free (ret);
1414  return buf;
1415 }
1416 
1417 
1428 const char *
1429 GNUNET_a2s (const struct sockaddr *addr, socklen_t addrlen)
1430 {
1431 #ifndef WINDOWS
1432 #define LEN \
1433  GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \
1434  (1 + sizeof (struct sockaddr_un) - sizeof (sa_family_t)))
1435 #else
1436 #define LEN (INET6_ADDRSTRLEN + 8)
1437 #endif
1438  static char buf[LEN];
1439 #undef LEN
1440  static char b2[6];
1441  const struct sockaddr_in *v4;
1442  const struct sockaddr_un *un;
1443  const struct sockaddr_in6 *v6;
1444  unsigned int off;
1445 
1446  if (addr == NULL)
1447  return _ ("unknown address");
1448  switch (addr->sa_family)
1449  {
1450  case AF_INET:
1451  if (addrlen != sizeof (struct sockaddr_in))
1452  return "<invalid v4 address>";
1453  v4 = (const struct sockaddr_in *) addr;
1454  inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN);
1455  if (0 == ntohs (v4->sin_port))
1456  return buf;
1457  strcat (buf, ":");
1458  GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v4->sin_port));
1459  strcat (buf, b2);
1460  return buf;
1461  case AF_INET6:
1462  if (addrlen != sizeof (struct sockaddr_in6))
1463  return "<invalid v4 address>";
1464  v6 = (const struct sockaddr_in6 *) addr;
1465  buf[0] = '[';
1466  inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN);
1467  if (0 == ntohs (v6->sin6_port))
1468  return &buf[1];
1469  strcat (buf, "]:");
1470  GNUNET_snprintf (b2, sizeof (b2), "%u", ntohs (v6->sin6_port));
1471  strcat (buf, b2);
1472  return buf;
1473  case AF_UNIX:
1474  if (addrlen <= sizeof (sa_family_t))
1475  return "<unbound UNIX client>";
1476  un = (const struct sockaddr_un *) addr;
1477  off = 0;
1478  if ('\0' == un->sun_path[0])
1479  off++;
1480  memset (buf, 0, sizeof (buf));
1481  GNUNET_snprintf (buf,
1482  sizeof (buf),
1483  "%s%.*s",
1484  (1 == off) ? "@" : "",
1485  (int) (addrlen - sizeof (sa_family_t) - off),
1486  &un->sun_path[off]);
1487  return buf;
1488  default:
1489  return _ ("invalid address");
1490  }
1491 }
1492 
1493 
1501 void
1503  const char *section,
1504  const char *option)
1505 {
1506  GNUNET_log (kind,
1507  _ (
1508  "Configuration fails to specify option `%s' in section `%s'!\n"),
1509  option,
1510  section);
1511 }
1512 
1513 
1522 void
1524  const char *section,
1525  const char *option,
1526  const char *required)
1527 {
1528  GNUNET_log (
1529  kind,
1530  _ (
1531  "Configuration specifies invalid value for option `%s' in section `%s': %s\n"),
1532  option,
1533  section,
1534  required);
1535 }
1536 
1537 
1544 void
1546  struct GNUNET_AsyncScopeSave *old_scope)
1547 {
1548  *old_scope = current_async_scope;
1551 }
1552 
1553 
1559 void
1561 {
1562  current_async_scope = *old_scope;
1563 }
1564 
1565 
1571 void
1573 {
1575  aid_ret,
1576  sizeof (struct GNUNET_AsyncScopeId));
1577 }
1578 
1579 
1585 void
1587 {
1588  *scope_ret = current_async_scope;
1589 }
1590 
1591 
1595 void __attribute__ ((constructor)) GNUNET_util_cl_init ()
1596 {
1597  GNUNET_stderr = stderr;
1598 #ifdef MINGW
1599  GNInitWinEnv (NULL);
1600 #endif
1601 #if WINDOWS
1602  if (! InitializeCriticalSectionAndSpinCount (&output_message_cs, 0x00000400))
1603  GNUNET_abort_ ();
1604 #endif
1605 }
1606 
1607 
1611 void __attribute__ ((destructor)) GNUNET_util_cl_fini ()
1612 {
1613 #if WINDOWS
1614  DeleteCriticalSection (&output_message_cs);
1615 #endif
1616 #ifdef MINGW
1617  GNShutdownWinEnv ();
1618 #endif
1619 }
1620 
1621 /* 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).
#define OPEN
Definition: plibc.h:651
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:295
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
#define FPRINTF
Definition: plibc.h:683
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.
#define STRERROR(i)
Definition: plibc.h:676
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).
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:833
static struct LogDef * logdefs
Dynamic array of logging definitions.
#define GNUNET_NO
Definition: gnunet_common.h:81
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:78
static GNUNET_THREAD_LOCAL char last_bulk [256] __attribute__((nonstring))
The last "bulk" error message that we have been logging.
#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.
static int ret
Final status code.
Definition: gnunet-arm.c:89
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 UNLINK(f)
Definition: plibc.h:666
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
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:44
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:367
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:727
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 GNShutdownWinEnv()
void GNUNET_log_from_nocheck(enum GNUNET_ErrorType kind, const char *comp, const char *message,...)
Log function that specifies an alternative component.
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.
int GNInitWinEnv()
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:69
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
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:602
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.
#define VSNPRINTF(str, size, fmt, a)
Definition: plibc.h:687
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).
static struct GNUNET_FS_PublishContext * pc
Handle to FS-publishing operation.
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:373
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 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:80
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.
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:924
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...