GNUnet 0.27.0
 
Loading...
Searching...
No Matches
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
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include <regex.h>
30
31
36#define BULK_DELAY_THRESHOLD (12 * 60 * 60 * 1000LL * 1000LL)
37
43#define BULK_REPEAT_THRESHOLD 1000
44
49#define BULK_TRACK_SIZE 256
50
55#define COMP_TRACK_SIZE 32
56
61#define DATE_STR_SIZE 64
62
66#define ROTATION_KEEP 3
67
68#ifndef PATH_MAX
72#define PATH_MAX 4096
73#endif
74
75
96
97
103
110
115
120
125
130
134static char *component;
135
139static char *component_nopid;
140
144static char *log_file_name;
145
150
154static struct CustomLogger *loggers;
155
160
164static FILE *GNUNET_stderr;
165
169struct LogDef
170{
175
179 regex_t file_regex;
180
185
191
197
203 int level;
204
209 int force;
210};
211
212
213#if ! defined(GNUNET_CULL_LOGGING)
217static struct LogDef *logdefs;
218
222static int logdefs_size;
223
227static int logdefs_len;
228
233
238
243#endif
244
245
253static enum GNUNET_ErrorType
254get_type (const char *log)
255{
256 if (NULL == log)
258 if (0 == strcasecmp (log, "DEBUG"))
260 if (0 == strcasecmp (log, "INFO"))
262 if (0 == strcasecmp (log, "MESSAGE"))
264 if (0 == strcasecmp (log, "WARNING"))
266 if (0 == strcasecmp (log, "ERROR"))
268 if (0 == strcasecmp (log, "NONE"))
271}
272
273
277void
279{
280 abort ();
281}
282
283
284#if ! defined(GNUNET_CULL_LOGGING)
288static void
290{
291 logdefs_size = (logdefs_size + 1) * 2;
292 logdefs = GNUNET_realloc (logdefs, logdefs_size * sizeof(struct LogDef));
293}
294
295
301static void
302log_rotate (const char *new_name)
303{
304 static char *rotation[ROTATION_KEEP];
305 static unsigned int rotation_off;
306 char *discard;
307
308 if ('\0' == *new_name)
309 return; /* not a real log file name */
310 discard = rotation[rotation_off % ROTATION_KEEP];
311 if (NULL != discard)
312 {
313 /* Note: can't log errors during logging (recursion!), so this
314 operation MUST silently fail... */
315 (void) unlink (discard);
316 GNUNET_free (discard);
317 }
318 rotation[rotation_off % ROTATION_KEEP] = GNUNET_strdup (new_name);
319 rotation_off++;
320}
321
322
323const char *
324GNUNET_b2s (const void *buf,
325 size_t buf_size)
326{
327 static GNUNET_THREAD_LOCAL char ret[9];
328 struct GNUNET_HashCode hc;
329 char *tmp;
330
332 buf_size,
333 &hc);
335 sizeof (hc));
336 memcpy (ret,
337 tmp,
338 8);
339 GNUNET_free (tmp);
340 ret[8] = '\0';
341 return ret;
342}
343
344
352setup_log_file (const struct tm *tm)
353{
354 static char last_fn[PATH_MAX + 1];
355 char fn[PATH_MAX + 1];
356 int altlog_fd;
357 int dup_return;
358 FILE *altlog;
359 char *leftsquare;
360
361 if (NULL == log_file_name)
362 return GNUNET_SYSERR;
363 if (0 == strftime (fn, sizeof(fn), log_file_name, tm))
364 return GNUNET_SYSERR;
365 leftsquare = strrchr (fn, '[');
366 if ((NULL != leftsquare) && (']' == leftsquare[1]))
367 {
368 char *logfile_copy = GNUNET_strdup (fn);
369
370 logfile_copy[leftsquare - fn] = '\0';
371 logfile_copy[leftsquare - fn + 1] = '\0';
372 snprintf (fn,
373 PATH_MAX,
374 "%s%d%s",
375 logfile_copy,
376 getpid (),
377 &logfile_copy[leftsquare - fn + 2]);
378 GNUNET_free (logfile_copy);
379 }
380 if (0 == strcmp (fn, last_fn))
381 return GNUNET_OK; /* no change */
382 log_rotate (last_fn);
383 strcpy (last_fn, fn);
385 {
386 fprintf (stderr,
387 "Failed to create directory for `%s': %s\n",
388 fn,
389 strerror (errno));
390 return GNUNET_SYSERR;
391 }
392 altlog_fd = open (fn,
393 O_APPEND | O_WRONLY | O_CREAT,
394 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
395
396 if (-1 != altlog_fd)
397 {
398 if (NULL != GNUNET_stderr)
399 fclose (GNUNET_stderr);
400 dup_return = dup2 (altlog_fd, 2);
401 (void) close (altlog_fd);
402 if (-1 != dup_return)
403 {
404 altlog = fdopen (2, "ab");
405 if (NULL == altlog)
406 {
407 (void) close (2);
408 altlog_fd = -1;
409 }
410 }
411 else
412 {
413 altlog_fd = -1;
414 }
415 }
416 if (-1 == altlog_fd)
417 {
419 return GNUNET_SYSERR;
420 }
421 GNUNET_stderr = altlog;
422 return GNUNET_OK;
423}
424
425
438static int
439add_definition (const char *lcomponent,
440 const char *file,
441 const char *function,
442 int from_line,
443 int to_line,
444 int level,
445 int force)
446{
447 struct LogDef n;
448 int r;
449
452 memset (&n, 0, sizeof(n));
453 if (0 == strlen (lcomponent))
454 lcomponent = (char *) ".*";
455 r = regcomp (&n.component_regex, (const char *) lcomponent, REG_NOSUB);
456 if (0 != r)
457 {
458 return r;
459 }
460 if (0 == strlen (file))
461 file = (char *) ".*";
462 r = regcomp (&n.file_regex, (const char *) file, REG_NOSUB);
463 if (0 != r)
464 {
465 regfree (&n.component_regex);
466 return r;
467 }
468 if ((NULL == function) || (0 == strlen (function)))
469 function = (char *) ".*";
470 r = regcomp (&n.function_regex, (const char *) function, REG_NOSUB);
471 if (0 != r)
472 {
473 regfree (&n.component_regex);
474 regfree (&n.file_regex);
475 return r;
476 }
478 n.to_line = to_line;
479 n.level = level;
480 n.force = force;
481 logdefs[logdefs_len++] = n;
482 return 0;
483}
484
485
499int
501 const char *comp,
502 const char *file,
503 const char *function,
504 int line)
505{
506 struct LogDef *ld;
507 int i;
508 int force_only;
509
510 if (NULL == comp)
511 /* Use default component */
512 comp = component_nopid;
513
514 /* We have no definitions to override globally configured log level,
515 * so just use it right away.
516 */
518 return caller_level <= min_level;
519
520 /* Only look for forced definitions? */
521 force_only = min_level >= 0;
522 for (i = 0; i < logdefs_len; i++)
523 {
524 ld = &logdefs[i];
525 if (((! force_only) || ld->force) &&
526 ((line >= ld->from_line) && (line <= ld->to_line) ) &&
527 (0 == regexec (&ld->component_regex, comp, 0, NULL, 0)) &&
528 (0 == regexec (&ld->file_regex, file, 0, NULL, 0)) &&
529 (0 == regexec (&ld->function_regex, function, 0, NULL, 0)))
530 {
531 /* We're finished */
532 return caller_level <= ld->level;
533 }
534 }
535 /* No matches - use global level, if defined */
536 if (min_level >= 0)
537 return caller_level <= min_level;
538 /* All programs/services previously defaulted to WARNING.
539 * Now *we* default to WARNING, and THEY default to NULL.
540 * Or rather we default to MESSAGE, since things aren't always bad.
541 */
542 return caller_level <= GNUNET_ERROR_TYPE_MESSAGE;
543}
544
545
569static int
570parse_definitions (const char *constname, int force)
571{
572 char *def;
573 const char *tmp;
574 char *comp = NULL;
575 char *file = NULL;
576 char *function = NULL;
577 char *p;
578 char *start;
579 char *t;
580 short state;
581 int level;
582 int from_line, to_line;
583 int counter = 0;
584 int keep_looking = 1;
585
586 tmp = getenv (constname);
587 if (NULL == tmp)
588 return 0;
589 def = GNUNET_strdup (tmp);
590 from_line = 0;
592 for (p = def, state = 0, start = def; keep_looking; p++)
593 {
594 switch (p[0])
595 {
596 case ';': /* found a field separator */
597 p[0] = '\0';
598 switch (state)
599 {
600 case 0: /* within a component name */
601 comp = start;
602 break;
603
604 case 1: /* within a file name */
605 file = start;
606 break;
607
608 case 2: /* within a function name */
609 /* after a file name there must be a function name */
610 function = start;
611 break;
612
613 case 3: /* within a from-to line range */
614 if (strlen (start) > 0)
615 {
616 errno = 0;
617 from_line = strtol (start, &t, 10);
618 if ((0 != errno) || (from_line < 0))
619 {
620 GNUNET_free (def);
621 return counter;
622 }
623 if ((t < p) && ('-' == t[0]))
624 {
625 errno = 0;
626 start = t + 1;
627 to_line = strtol (start, &t, 10);
628 if ((0 != errno) || (to_line < 0) || (t != p))
629 {
630 GNUNET_free (def);
631 return counter;
632 }
633 }
634 else /* one number means "match this line only" */
636 }
637 else /* default to 0-max */
638 {
639 from_line = 0;
641 }
642 break;
643
644 default:
645 fprintf (
646 stderr,
647 _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
648 p);
649 break;
650 }
651 start = p + 1;
652 state++;
653 break;
654
655 case '\0': /* found EOL */
656 keep_looking = 0;
657
658 /* fall through to '/' */
659 case '/': /* found a definition separator */
660 switch (state)
661 {
662 case 4: /* within a log level */
663 p[0] = '\0';
664 state = 0;
665 level = get_type ((const char *) start);
668 (0 != add_definition (comp,
669 file,
670 function,
671 from_line,
672 to_line,
673 level,
674 force)))
675 {
676 GNUNET_free (def);
677 return counter;
678 }
679 counter++;
680 start = p + 1;
681 break;
682
683 default:
684 fprintf (
685 stderr,
686 _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
687 p);
688 break;
689 }
690
691 default:
692 break;
693 }
694 }
695 GNUNET_free (def);
696 return counter;
697}
698
699
703static void
715
716
717#endif
718
719
729GNUNET_log_setup (const char *comp,
730 const char *loglevel,
731 const char *logfile)
732{
733 const char *env_logfile;
734
735 min_level = get_type (loglevel);
736#if ! defined(GNUNET_CULL_LOGGING)
738#endif
741 "%s-%d",
742 comp,
743 getpid ());
746
747 env_logfile = getenv ("GNUNET_FORCE_LOGFILE");
748 if ((NULL != env_logfile) && (strlen (env_logfile) > 0))
749 logfile = env_logfile;
750 if (NULL == logfile)
751 return GNUNET_OK;
754 if (NULL == log_file_name)
755 return GNUNET_SYSERR;
756#if defined(GNUNET_CULL_LOGGING)
757 /* log file option not allowed for wallet logic */
758 GNUNET_assert (NULL == logfile);
759 return GNUNET_OK;
760#else
761 {
762 time_t t;
763 const struct tm *tm;
764
765 t = time (NULL);
766 tm = gmtime (&t);
767 return setup_log_file (tm);
768 }
769#endif
770}
771
772
773void
775 void *logger_cls)
776{
777 struct CustomLogger *entry;
778
779 entry = GNUNET_new (struct CustomLogger);
780 entry->logger = logger;
781 entry->logger_cls = logger_cls;
782 entry->next = loggers;
783 loggers = entry;
784}
785
786
787void
789 void *logger_cls)
790{
791 struct CustomLogger *pos;
792 struct CustomLogger *prev;
793
794 prev = NULL;
795 pos = loggers;
796 while ( (NULL != pos) &&
797 ( (pos->logger != logger) ||
798 (pos->logger_cls != logger_cls) ) )
799 {
800 prev = pos;
801 pos = pos->next;
802 }
803 GNUNET_assert (NULL != pos);
804 if (NULL == prev)
805 loggers = pos->next;
806 else
807 prev->next = pos->next;
808 GNUNET_free (pos);
809}
810
811
820static void
822 const char *comp,
823 const char *datestr,
824 const char *msg)
825{
826 static int have_journald = -1;
827 struct CustomLogger *pos;
828 const char *optional_newline = "\n";
829
830 if ((strlen (msg) > 0) &&
831 ('\n' == msg[strlen (msg) - 1]))
832 optional_newline = "";
833
834 if (-1 == have_journald)
835 {
836 /* systemd after version 231 sets this environment
837 variable if we are logging to journald. In this
838 case, skip outputting our component name, PID
839 and timestamp as journald already adds those. (#8032) */
840 if (NULL != getenv ("JOURNAL_STREAM"))
841 have_journald = 1;
842 else
843 have_journald = 0;
844 }
845
846 /* only use the standard logger if no custom loggers are present */
847 if ((NULL != GNUNET_stderr) && (NULL == loggers))
848 {
849 if (kind == GNUNET_ERROR_TYPE_MESSAGE)
850 {
851 /* The idea here is to produce "normal" output messages
852 * for end users while still having the power of the
853 * logging engine for developer needs. So ideally this
854 * is what it should look like when CLI tools are used
855 * interactively, yet the same message shouldn't look
856 * this way if the output is going to logfiles or robots
857 * instead.
858 */
859 fprintf (GNUNET_stderr, "* %s%s", msg, optional_newline);
860 }
862 {
863 static GNUNET_THREAD_LOCAL char id_buf[27];
864 char *end;
865
866 /* We're logging, so skip_log must be currently 0. */
867 skip_log = 100;
869 sizeof(struct GNUNET_AsyncScopeId),
870 id_buf,
871 sizeof(id_buf) - 1);
872 GNUNET_assert (NULL != end);
873 *end = '\0';
874 skip_log = 0;
875 if (have_journald)
876 fprintf (GNUNET_stderr,
877 "(%s) %s %s%s",
878 id_buf,
880 msg,
881 optional_newline);
882 else
883 fprintf (GNUNET_stderr,
884 "%s %s(%s) %s %s%s",
885 datestr,
886 comp,
887 id_buf,
889 msg,
890 optional_newline);
891 }
892 else
893 {
894 if (have_journald)
895 fprintf (GNUNET_stderr,
896 "%s %s%s",
898 msg,
899 optional_newline);
900 else
901 fprintf (GNUNET_stderr,
902 "%s %s %s %s%s",
903 datestr,
904 comp,
906 msg,
907 optional_newline);
908 }
909 fflush (GNUNET_stderr);
910 }
911 pos = loggers;
912 while (NULL != pos)
913 {
914 pos->logger (pos->logger_cls,
915 kind,
916 comp,
917 datestr,
918 msg);
919 pos = pos->next;
920 }
921}
922
923
929static void
930flush_bulk (const char *datestr)
931{
932 char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
933 int rev;
934 char *last;
935 const char *ft;
936
937 if ((0 == last_bulk_time.abs_value_us) || (0 == last_bulk_repeat))
938 return;
939 rev = 0;
940 last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
941 if (last == NULL)
942 last = &last_bulk[BULK_TRACK_SIZE - 1];
943 else if (last != last_bulk)
944 last--;
945 if (last[0] == '\n')
946 {
947 rev = 1;
948 last[0] = '\0';
949 }
950 ft =
953 GNUNET_YES);
954 snprintf (msg,
955 sizeof(msg),
956 _ ("Message `%.*s' repeated %u times in the last %s\n"),
958 last_bulk,
960 ft);
961 if (rev == 1)
962 last[0] = '\n';
965 datestr,
966 msg);
969}
970
971
972void
973GNUNET_log_skip (int n, int check_reset)
974{
975 int ok;
976
977 if (0 == n)
978 {
979 ok = (0 == skip_log);
980 skip_log = 0;
981 if (check_reset)
982 GNUNET_break (ok);
983 }
984 else
985 {
986 skip_log += n;
987 }
988}
989
990
996int
998{
999 return skip_log;
1000}
1001
1002
1011static void
1013 const char *comp,
1014 const char *message,
1015 va_list va)
1016{
1017 char date[DATE_STR_SIZE];
1018 char date2[DATE_STR_SIZE];
1019 struct tm *tmptr;
1020 size_t size;
1021 va_list vacp;
1022 int eno = errno;
1023
1024 va_copy (vacp, va);
1025 size = vsnprintf (NULL,
1026 0,
1027 message,
1028 vacp) + 1;
1029 GNUNET_assert (0 != size);
1030 va_end (vacp);
1031 memset (date, 0, DATE_STR_SIZE);
1032 {
1033 char buf[size];
1034 long long offset;
1035
1036 struct timeval timeofday;
1037
1038 gettimeofday (&timeofday,
1039 NULL);
1040 offset = GNUNET_TIME_get_offset ();
1041 if (offset > 0)
1042 {
1043 timeofday.tv_sec += offset / 1000LL / 1000LL;
1044 timeofday.tv_usec += (offset % 1000000LL) * 1000000LL;
1045 if (timeofday.tv_usec > 1000000LL)
1046 {
1047 timeofday.tv_usec -= 1000000LL;
1048 timeofday.tv_sec++;
1049 }
1050 }
1051 else
1052 {
1053 timeofday.tv_sec += offset / 1000LL / 1000LL;
1054 if (timeofday.tv_usec > -(offset % 1000000LL) * 1000000LL)
1055 {
1056 timeofday.tv_usec += (offset % 1000000LL) * 1000000LL;
1057 }
1058 else
1059 {
1060 timeofday.tv_usec += 1000000LL + (offset % 1000000LL) * 1000000LL;
1061 timeofday.tv_sec--;
1062 }
1063 }
1064 tmptr = localtime (&timeofday.tv_sec);
1065 if (NULL == tmptr)
1066 {
1067 strcpy (date, "localtime error");
1068 }
1069 else
1070 {
1071 /* RFC 3339 timestamp, with snprintf placeholder for microseconds */
1072 if (0 == strftime (date2,
1074 "%Y-%m-%dT%H:%M:%S.%%06u%z",
1075 tmptr))
1076 abort ();
1077 /* Fill in microseconds */
1078 if (0 > snprintf (date,
1079 sizeof(date),
1080 date2,
1081 timeofday.tv_usec))
1082 abort ();
1083 }
1084
1085 vsnprintf (buf, size, message, va);
1086#if ! defined(GNUNET_CULL_LOGGING)
1087 if (NULL != tmptr)
1088 (void) setup_log_file (tmptr);
1089#endif
1090 if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
1092 (0 == strncmp (buf, last_bulk, sizeof(last_bulk))))
1093 {
1098 flush_bulk (date);
1099 return;
1100 }
1101 flush_bulk (date);
1102 GNUNET_strlcpy (last_bulk,
1103 buf,
1104 sizeof(last_bulk));
1105 last_bulk_repeat = 0;
1106 last_bulk_kind = kind;
1109 comp,
1110 sizeof(last_bulk_comp));
1111 output_message (kind,
1112 comp,
1113 date,
1114 buf);
1115 }
1116 errno = eno;
1117}
1118
1119
1127void
1129 const char *message,
1130 ...)
1131{
1132 va_list va;
1133
1134 va_start (va,
1135 message);
1136 mylog (kind,
1137 component,
1138 message, va);
1139 va_end (va);
1140}
1141
1142
1152void
1154 const char *comp,
1155 const char *message,
1156 ...)
1157{
1158 va_list va;
1159 char comp_w_pid[128];
1160 int eno = errno;
1161
1162 if (NULL == comp)
1163 comp = component_nopid;
1164
1165 va_start (va, message);
1166 GNUNET_snprintf (comp_w_pid,
1167 sizeof(comp_w_pid),
1168 "%s-%d",
1169 comp,
1170 getpid ());
1171 mylog (kind,
1172 comp_w_pid,
1173 message,
1174 va);
1175 va_end (va);
1176 errno = eno;
1177}
1178
1179
1180const char *
1182{
1183 if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
1184 return _ ("ERROR");
1185 if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
1186 return _ ("WARNING");
1187 if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0)
1188 return _ ("MESSAGE");
1189 if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
1190 return _ ("INFO");
1191 if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
1192 return _ ("DEBUG");
1193 if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0)
1194 return _ ("NONE");
1195 return _ ("INVALID");
1196}
1197
1198
1205const char *
1206GNUNET_h2s (const struct GNUNET_HashCode *hc)
1207{
1209
1211 &ret);
1212 ret.encoding[8] = '\0';
1213 return (const char *) ret.encoding;
1214}
1215
1216
1227const char *
1229{
1231
1233 &ret);
1234 ret.encoding[8] = '\0';
1235 return (const char *) ret.encoding;
1236}
1237
1238
1239const char *
1241{
1243 struct GNUNET_HashCode hc;
1244
1246 sizeof(*p),
1247 &hc);
1249 &ret);
1250 ret.encoding[6] = '\0';
1251 return (const char *) ret.encoding;
1252}
1253
1254
1255const char *
1257{
1259 struct GNUNET_HashCode hc;
1260
1262 sizeof(*p),
1263 &hc);
1265 &ret);
1266 ret.encoding[6] = '\0';
1267 return (const char *) ret.encoding;
1268}
1269
1270
1271const char *
1273{
1275 struct GNUNET_HashCode hc;
1276
1278 sizeof(*p),
1279 &hc);
1281 &ret);
1282 ret.encoding[6] = '\0';
1283 return (const char *) ret.encoding;
1284}
1285
1286
1287const char *
1289{
1291 struct GNUNET_HashCode hc;
1292
1294 sizeof(*p),
1295 &hc);
1297 &ret);
1298 ret.encoding[6] = '\0';
1299 return (const char *) ret.encoding;
1300}
1301
1302
1312const char *
1314{
1315 static GNUNET_THREAD_LOCAL char buf[64];
1316
1318 sizeof(*shc),
1319 buf,
1320 sizeof(buf));
1321 buf[6] = '\0';
1322 return (const char *) buf;
1323}
1324
1325
1335const char *
1336GNUNET_uuid2s (const struct GNUNET_Uuid *uuid)
1337{
1338 static GNUNET_THREAD_LOCAL char buf[32];
1339
1340 GNUNET_STRINGS_data_to_string (uuid, sizeof(*uuid), buf, sizeof(buf));
1341 buf[6] = '\0';
1342 return (const char *) buf;
1343}
1344
1345
1354const char *
1356{
1358
1360 ret.encoding[sizeof(ret) - 1] = '\0';
1361 return (const char *) ret.encoding;
1362}
1363
1364
1372const char *
1374{
1375 static GNUNET_THREAD_LOCAL char buf[5];
1376 char *ret;
1377
1378 if (NULL == pid)
1379 return "NULL";
1381 GNUNET_strlcpy (buf, ret, sizeof(buf));
1382 GNUNET_free (ret);
1383 return buf;
1384}
1385
1386
1397const char *
1399{
1400 static GNUNET_THREAD_LOCAL char buf[5];
1401 char *ret;
1402
1403 if (NULL == pid)
1404 return "NULL";
1406 GNUNET_strlcpy (buf, ret, sizeof(buf));
1407 GNUNET_free (ret);
1408 return buf;
1409}
1410
1411
1419const char *
1421{
1422 static GNUNET_THREAD_LOCAL char buf[256];
1423 char *ret;
1424
1426 strcpy (buf, ret);
1427 GNUNET_free (ret);
1428 return buf;
1429}
1430
1431
1442const char *
1443GNUNET_a2s (const struct sockaddr *addr,
1444 socklen_t addrlen)
1445{
1446#define LEN \
1447 GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \
1448 (1 + sizeof(struct sockaddr_un) - sizeof(sa_family_t)))
1449 static GNUNET_THREAD_LOCAL char buf[LEN];
1450#undef LEN
1451 static GNUNET_THREAD_LOCAL char b2[6];
1452 const struct sockaddr_in *v4;
1453 const struct sockaddr_un *un;
1454 const struct sockaddr_in6 *v6;
1455 unsigned int off;
1456
1457 if (addr == NULL)
1458 return _ ("unknown address");
1459 switch (addr->sa_family)
1460 {
1461 case AF_INET:
1462 if (addrlen != sizeof(struct sockaddr_in))
1463 return "<invalid v4 address>";
1464 v4 = (const struct sockaddr_in *) addr;
1465 inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN);
1466 if (0 == ntohs (v4->sin_port))
1467 return buf;
1468 strcat (buf, ":");
1469 GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v4->sin_port));
1470 strcat (buf, b2);
1471 return buf;
1472
1473 case AF_INET6:
1474 if (addrlen != sizeof(struct sockaddr_in6))
1475 return "<invalid v6 address>";
1476 v6 = (const struct sockaddr_in6 *) addr;
1477 buf[0] = '[';
1478 inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN);
1479 if (0 == ntohs (v6->sin6_port))
1480 return &buf[1];
1481 strcat (buf, "]:");
1482 GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v6->sin6_port));
1483 strcat (buf, b2);
1484 return buf;
1485
1486 case AF_UNIX:
1487 if (addrlen <= sizeof(sa_family_t))
1488 return "<unbound UNIX client>";
1489 un = (const struct sockaddr_un *) addr;
1490 off = 0;
1491 if ('\0' == un->sun_path[0])
1492 off++;
1493 memset (buf, 0, sizeof(buf));
1494 GNUNET_snprintf (buf,
1495 sizeof(buf),
1496 "%s%.*s",
1497 (1 == off) ? "@" : "",
1498 (int) (addrlen - sizeof(sa_family_t) - off),
1499 &un->sun_path[off]);
1500 return buf;
1501
1502 default:
1503 return _ ("invalid address");
1504 }
1505}
1506
1507
1508void
1510 const char *section,
1511 const char *option)
1512{
1513 GNUNET_log (kind,
1514 _ (
1515 "Configuration fails to specify option `%s' in section `%s'!\n")
1516 ,
1517 option,
1518 section);
1519}
1520
1521
1522void
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
1544void
1546 struct GNUNET_AsyncScopeSave *old_scope)
1547{
1548 *old_scope = current_async_scope;
1551}
1552
1553
1559void
1561{
1562 current_async_scope = *old_scope;
1563}
1564
1565
1571void
1578
1579
1585void
1587{
1588 *scope_ret = current_async_scope;
1589}
1590
1591
1592size_t
1593GNUNET_hex2b (const char *src,
1594 void *dst,
1595 size_t dstlen,
1596 int invert)
1597{
1598 const char *line = src;
1599 const char *data = line;
1600 uint8_t *buf = dst;
1601 int off;
1602 int read_byte;
1603 int data_len = 0;
1604
1605 while ((data_len < dstlen) &&
1606 (sscanf (data, " %02x%n", &read_byte, &off) == 1))
1607 {
1608 if (invert)
1609 buf[dstlen - 1 - data_len++] = read_byte;
1610 else
1611 buf[data_len++] = read_byte;
1612 data += off;
1613 }
1614 return data_len;
1615}
1616
1617
1618void
1619GNUNET_print_bytes (const void *buf,
1620 size_t buf_len,
1621 int fold,
1622 int in_be)
1623{
1624 int i;
1625
1626 for (i = 0; i < buf_len; i++)
1627 {
1628 if (0 != i)
1629 {
1630 if ((0 != fold) && (i % fold == 0))
1631 printf ("\n");
1632 }
1633 if (in_be)
1634 printf ("%02x", ((unsigned char*) buf)[buf_len - 1 - i]);
1635 else
1636 printf ("%02x", ((unsigned char*) buf)[i]);
1637 }
1638 printf ("\n");
1639}
1640
1641
1642void
1644
1648void __attribute__ ((constructor))
1650{
1651 GNUNET_stderr = stderr;
1652}
1653
1654
1655/* 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 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.
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).
void GNUNET_util_cl_init(void)
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.
static GNUNET_THREAD_LOCAL char last_bulk[256] __nonstring
The last "bulk" error message that we have been logging.
#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.
#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.
static enum GNUNET_GenericReturnValue setup_log_file(const struct tm *tm)
Setup the log file.
#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 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.
static int add_definition(const char *lcomponent, 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 * getenv()
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static int end
Set if we are to shutdown all services (including ARM).
Definition gnunet-arm.c:33
static char * line
Desired phone line (string to be converted to a hash).
static char * data
The data to insert into the dht.
static struct GNUNET_PEERSTORE_StoreHelloContext * shc
HELLO store context handle.
static struct GNUNET_SCHEDULER_Task * t
Main task.
static int state
The current state of the parser.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_Process * p
Helper process we started.
Definition gnunet-uri.c:38
struct GNUNET_PQ_ResultSpec __attribute__
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:664
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
#define GNUNET_log(kind,...)
const char * GNUNET_b2s(const void *buf, size_t buf_size)
Convert a buffer to an 8-character string representative of the contents.
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.
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:255
void GNUNET_async_scope_enter(const struct GNUNET_AsyncScopeId *aid, struct GNUNET_AsyncScopeSave *old_scope)
Set the async scope for the current thread.
int have_scope
GNUNET_YES unless this saved scope is the unnamed root scope.
void GNUNET_async_scope_get(struct GNUNET_AsyncScopeSave *scope_ret)
Get the current async scope.
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.
GNUNET_GenericReturnValue
Named constants for return values.
struct GNUNET_AsyncScopeId scope_id
Saved scope.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
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).
void GNUNET_print_bytes(const void *buf, size_t buf_len, int fold, int in_be)
Print a byte string in hexadecimal ascii notation.
const char * GNUNET_i2s(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_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).
size_t GNUNET_hex2b(const char *src, void *dst, size_t dstlen, int invert)
Parse an ascii-encoded hexadecimal string into the buffer.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity 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.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash to a string (for printing debug messages).
enum GNUNET_GenericReturnValue GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
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).
void GNUNET_log_skip(int n, int check_reset)
Ignore the next n calls to the log function.
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_h2s2(const struct GNUNET_HashCode *hc)
Convert a hash 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_i2s2(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug 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_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:757
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition strings.c:812
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition strings.c:525
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition strings.c:137
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:438
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:604
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
long long GNUNET_TIME_get_offset(void)
Get the timestamp offset for this instance.
Definition time.c:56
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
#define GNUNET_THREAD_LOCAL
Definition platform.h:248
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.
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.