GNUnet 0.22.2
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
80{
85
90
95};
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
705{
708 parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO;
710
712 parse_definitions ("GNUNET_LOG", 0);
714}
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) || (pos->logger_cls != logger_cls)))
798 {
799 prev = pos;
800 pos = pos->next;
801 }
802 GNUNET_assert (NULL != pos);
803 if (NULL == prev)
804 loggers = pos->next;
805 else
806 prev->next = pos->next;
807 GNUNET_free (pos);
808}
809
810
819static void
821 const char *comp,
822 const char *datestr,
823 const char *msg)
824{
825 static int have_journald = -1;
826 struct CustomLogger *pos;
827 const char *optional_newline = "\n";
828
829 if ((strlen (msg) > 0) &&
830 ('\n' == msg[strlen (msg) - 1]))
831 optional_newline = "";
832
833 if (-1 == have_journald)
834 {
835 /* systemd after version 231 sets this environment
836 variable if we are logging to journald. In this
837 case, skip outputting our component name, PID
838 and timestamp as journald already adds those. (#8032) */
839 if (NULL != getenv ("JOURNAL_STREAM"))
840 have_journald = 1;
841 else
842 have_journald = 0;
843 }
844
845 /* only use the standard logger if no custom loggers are present */
846 if ((NULL != GNUNET_stderr) && (NULL == loggers))
847 {
848 if (kind == GNUNET_ERROR_TYPE_MESSAGE)
849 {
850 /* The idea here is to produce "normal" output messages
851 * for end users while still having the power of the
852 * logging engine for developer needs. So ideally this
853 * is what it should look like when CLI tools are used
854 * interactively, yet the same message shouldn't look
855 * this way if the output is going to logfiles or robots
856 * instead.
857 */
858 fprintf (GNUNET_stderr, "* %s%s", msg, optional_newline);
859 }
861 {
862 static GNUNET_THREAD_LOCAL char id_buf[27];
863 char *end;
864
865 /* We're logging, so skip_log must be currently 0. */
866 skip_log = 100;
868 sizeof(struct GNUNET_AsyncScopeId),
869 id_buf,
870 sizeof(id_buf) - 1);
871 GNUNET_assert (NULL != end);
872 *end = '\0';
873 skip_log = 0;
874 if (have_journald)
875 fprintf (GNUNET_stderr,
876 "(%s) %s %s%s",
877 id_buf,
879 msg,
880 optional_newline);
881 else
882 fprintf (GNUNET_stderr,
883 "%s %s(%s) %s %s%s",
884 datestr,
885 comp,
886 id_buf,
888 msg,
889 optional_newline);
890 }
891 else
892 {
893 if (have_journald)
894 fprintf (GNUNET_stderr,
895 "%s %s%s",
897 msg,
898 optional_newline);
899 else
900 fprintf (GNUNET_stderr,
901 "%s %s %s %s%s",
902 datestr,
903 comp,
905 msg,
906 optional_newline);
907 }
908 fflush (GNUNET_stderr);
909 }
910 pos = loggers;
911 while (NULL != pos)
912 {
913 pos->logger (pos->logger_cls, kind, comp, datestr, msg);
914 pos = pos->next;
915 }
916}
917
918
924static void
925flush_bulk (const char *datestr)
926{
927 char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
928 int rev;
929 char *last;
930 const char *ft;
931
932 if ((0 == last_bulk_time.abs_value_us) || (0 == last_bulk_repeat))
933 return;
934 rev = 0;
935 last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
936 if (last == NULL)
937 last = &last_bulk[BULK_TRACK_SIZE - 1];
938 else if (last != last_bulk)
939 last--;
940 if (last[0] == '\n')
941 {
942 rev = 1;
943 last[0] = '\0';
944 }
945 ft =
948 GNUNET_YES);
949 snprintf (msg,
950 sizeof(msg),
951 _ ("Message `%.*s' repeated %u times in the last %s\n"),
953 last_bulk,
955 ft);
956 if (rev == 1)
957 last[0] = '\n';
961}
962
963
964void
965GNUNET_log_skip (int n, int check_reset)
966{
967 int ok;
968
969 if (0 == n)
970 {
971 ok = (0 == skip_log);
972 skip_log = 0;
973 if (check_reset)
974 GNUNET_break (ok);
975 }
976 else
977 {
978 skip_log += n;
979 }
980}
981
982
988int
990{
991 return skip_log;
992}
993
994
1003static void
1005 const char *comp,
1006 const char *message,
1007 va_list va)
1008{
1009 char date[DATE_STR_SIZE];
1010 char date2[DATE_STR_SIZE];
1011 struct tm *tmptr;
1012 size_t size;
1013 va_list vacp;
1014
1015 va_copy (vacp, va);
1016 size = vsnprintf (NULL, 0, message, vacp) + 1;
1017 GNUNET_assert (0 != size);
1018 va_end (vacp);
1019 memset (date, 0, DATE_STR_SIZE);
1020 {
1021 char buf[size];
1022 long long offset;
1023
1024 struct timeval timeofday;
1025
1026 gettimeofday (&timeofday, NULL);
1027 offset = GNUNET_TIME_get_offset ();
1028 if (offset > 0)
1029 {
1030 timeofday.tv_sec += offset / 1000LL;
1031 timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1032 if (timeofday.tv_usec > 1000000LL)
1033 {
1034 timeofday.tv_usec -= 1000000LL;
1035 timeofday.tv_sec++;
1036 }
1037 }
1038 else
1039 {
1040 timeofday.tv_sec += offset / 1000LL;
1041 if (timeofday.tv_usec > -(offset % 1000LL) * 1000LL)
1042 {
1043 timeofday.tv_usec += (offset % 1000LL) * 1000LL;
1044 }
1045 else
1046 {
1047 timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL;
1048 timeofday.tv_sec--;
1049 }
1050 }
1051 tmptr = localtime (&timeofday.tv_sec);
1052 if (NULL == tmptr)
1053 {
1054 strcpy (date, "localtime error");
1055 }
1056 else
1057 {
1058 /* RFC 3339 timestamp, with snprintf placeholder for microseconds */
1059 if (0 == strftime (date2, DATE_STR_SIZE, "%Y-%m-%dT%H:%M:%S.%%06u%z",
1060 tmptr))
1061 abort ();
1062 /* Fill in microseconds */
1063 if (0 > snprintf (date, sizeof(date), date2, timeofday.tv_usec))
1064 abort ();
1065 }
1066
1067 vsnprintf (buf, size, message, va);
1068#if ! defined(GNUNET_CULL_LOGGING)
1069 if (NULL != tmptr)
1070 (void) setup_log_file (tmptr);
1071#endif
1072 if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
1074 (0 == strncmp (buf, last_bulk, sizeof(last_bulk))))
1075 {
1080 flush_bulk (date);
1081 return;
1082 }
1083 flush_bulk (date);
1084 GNUNET_strlcpy (last_bulk, buf, sizeof(last_bulk));
1085 last_bulk_repeat = 0;
1086 last_bulk_kind = kind;
1089 output_message (kind, comp, date, buf);
1090 }
1091}
1092
1093
1101void
1102GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...)
1103{
1104 va_list va;
1105
1106 va_start (va, message);
1107 mylog (kind, component, message, va);
1108 va_end (va);
1109}
1110
1111
1121void
1123 const char *comp,
1124 const char *message,
1125 ...)
1126{
1127 va_list va;
1128 char comp_w_pid[128];
1129
1130 if (comp == NULL)
1131 comp = component_nopid;
1132
1133 va_start (va, message);
1134 GNUNET_snprintf (comp_w_pid, sizeof(comp_w_pid), "%s-%d", comp, getpid ());
1135 mylog (kind, comp_w_pid, message, va);
1136 va_end (va);
1137}
1138
1139
1140const char *
1142{
1143 if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
1144 return _ ("ERROR");
1145 if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
1146 return _ ("WARNING");
1147 if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0)
1148 return _ ("MESSAGE");
1149 if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
1150 return _ ("INFO");
1151 if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
1152 return _ ("DEBUG");
1153 if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0)
1154 return _ ("NONE");
1155 return _ ("INVALID");
1156}
1157
1158
1165const char *
1166GNUNET_h2s (const struct GNUNET_HashCode *hc)
1167{
1169
1171 ret.encoding[8] = '\0';
1172 return (const char *) ret.encoding;
1173}
1174
1175
1186const char *
1188{
1190
1192 ret.encoding[8] = '\0';
1193 return (const char *) ret.encoding;
1194}
1195
1196
1197const char *
1199{
1201 struct GNUNET_HashCode hc;
1202
1203 GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1205 ret.encoding[6] = '\0';
1206 return (const char *) ret.encoding;
1207}
1208
1209
1210const char *
1212{
1214 struct GNUNET_HashCode hc;
1215
1216 GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1218 ret.encoding[6] = '\0';
1219 return (const char *) ret.encoding;
1220}
1221
1222
1223const char *
1225{
1227 struct GNUNET_HashCode hc;
1228
1229 GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
1231 ret.encoding[6] = '\0';
1232 return (const char *) ret.encoding;
1233}
1234
1235
1236const 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
1258const 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
1278const char *
1279GNUNET_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
1297const char *
1299{
1301
1303 ret.encoding[sizeof(ret) - 1] = '\0';
1304 return (const char *) ret.encoding;
1305}
1306
1307
1315const 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
1340const 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
1362const 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
1385const char *
1386GNUNET_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));
1436 GNUNET_snprintf (buf,
1437 sizeof(buf),
1438 "%s%.*s",
1439 (1 == off) ? "@" : "",
1440 (int) (addrlen - sizeof(sa_family_t) - off),
1441 &un->sun_path[off]);
1442 return buf;
1443
1444 default:
1445 return _ ("invalid address");
1446 }
1447}
1448
1449
1450void
1452 const char *section,
1453 const char *option)
1454{
1455 GNUNET_log (kind,
1456 _ (
1457 "Configuration fails to specify option `%s' in section `%s'!\n")
1458 ,
1459 option,
1460 section);
1461}
1462
1463
1464void
1466 const char *section,
1467 const char *option,
1468 const char *required)
1469{
1470 GNUNET_log (
1471 kind,
1472 _ (
1473 "Configuration specifies invalid value for option `%s' in section `%s': %s\n"),
1474 option,
1475 section,
1476 required);
1477}
1478
1479
1486void
1488 struct GNUNET_AsyncScopeSave *old_scope)
1489{
1490 *old_scope = current_async_scope;
1493}
1494
1495
1501void
1503{
1504 current_async_scope = *old_scope;
1505}
1506
1507
1513void
1515{
1517 aid_ret,
1518 sizeof(struct GNUNET_AsyncScopeId));
1519}
1520
1521
1527void
1529{
1530 *scope_ret = current_async_scope;
1531}
1532
1533
1534size_t
1535GNUNET_hex2b (const char *src, void *dst, size_t dstlen, int invert)
1536{
1537 const char *line = src;
1538 const char *data = line;
1539 uint8_t *buf = dst;
1540 int off;
1541 int read_byte;
1542 int data_len = 0;
1543
1544 while ((data_len < dstlen) &&
1545 (sscanf (data, " %02x%n", &read_byte, &off) == 1))
1546 {
1547 if (invert)
1548 buf[dstlen - 1 - data_len++] = read_byte;
1549 else
1550 buf[data_len++] = read_byte;
1551 data += off;
1552 }
1553 return data_len;
1554}
1555
1556
1557void
1558GNUNET_print_bytes (const void *buf, size_t buf_len, int fold, int in_be)
1559{
1560 int i;
1561
1562 for (i = 0; i < buf_len; i++)
1563 {
1564 if (0 != i)
1565 {
1566 if ((0 != fold) && (i % fold == 0))
1567 printf ("\n");
1568 }
1569 if (in_be)
1570 printf ("%02x", ((unsigned char*) buf)[buf_len - 1 - i]);
1571 else
1572 printf ("%02x", ((unsigned char*) buf)[i]);
1573 }
1574 printf ("\n");
1575}
1576
1577
1578void
1580
1584void __attribute__ ((constructor))
1586{
1587 GNUNET_stderr = stderr;
1588}
1589
1590
1591void
1593
1597void __attribute__ ((destructor))
1599{
1600
1601}
1602
1603
1604/* 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.
void GNUNET_util_cl_fini(void)
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.
void __attribute__((constructor))
Initializer.
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.
Definition: gnunet-hello.c:52
enum State state
current state of profiling
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
static struct GNUNET_SCHEDULER_Task * t
Main task.
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:606
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:732
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:787
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition: strings.c:504
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:579
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:178
#define GNUNET_THREAD_LOCAL
Definition: platform.h:247
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.