common_logging.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2006-2013 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file util/common_logging.c
  18. * @brief error handling API
  19. * @author Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include "gnunet_crypto_lib.h"
  23. #include "gnunet_disk_lib.h"
  24. #include "gnunet_strings_lib.h"
  25. #include <regex.h>
  26. /**
  27. * After how many milliseconds do we always print
  28. * that "message X was repeated N times"? Use 12h.
  29. */
  30. #define BULK_DELAY_THRESHOLD (12 * 60 * 60 * 1000LL * 1000LL)
  31. /**
  32. * After how many repetitions do we always print
  33. * that "message X was repeated N times"? (even if
  34. * we have not yet reached the delay threshold)
  35. */
  36. #define BULK_REPEAT_THRESHOLD 1000
  37. /**
  38. * How many characters do we use for matching of
  39. * bulk messages?
  40. */
  41. #define BULK_TRACK_SIZE 256
  42. /**
  43. * How many characters do we use for matching of
  44. * bulk components?
  45. */
  46. #define COMP_TRACK_SIZE 32
  47. /**
  48. * How many characters can a date/time string
  49. * be at most?
  50. */
  51. #define DATE_STR_SIZE 64
  52. /**
  53. * How many log files to keep?
  54. */
  55. #define ROTATION_KEEP 3
  56. #ifndef PATH_MAX
  57. /**
  58. * Assumed maximum path length (for the log file name).
  59. */
  60. #define PATH_MAX 4096
  61. #endif
  62. /**
  63. * Linked list of active loggers.
  64. */
  65. struct CustomLogger
  66. {
  67. /**
  68. * This is a linked list.
  69. */
  70. struct CustomLogger *next;
  71. /**
  72. * Log function.
  73. */
  74. GNUNET_Logger logger;
  75. /**
  76. * Closure for logger.
  77. */
  78. void *logger_cls;
  79. };
  80. /**
  81. * Asynchronous scope of the current thread, or NULL if we have not
  82. * entered an async scope yet.
  83. */
  84. static GNUNET_THREAD_LOCAL struct GNUNET_AsyncScopeSave current_async_scope;
  85. /**
  86. * The last "bulk" error message that we have been logging.
  87. * Note that this message maybe truncated to the first BULK_TRACK_SIZE
  88. * characters, in which case it is NOT 0-terminated!
  89. */
  90. static GNUNET_THREAD_LOCAL char last_bulk[BULK_TRACK_SIZE] __nonstring;
  91. /**
  92. * Type of the last bulk message.
  93. */
  94. static GNUNET_THREAD_LOCAL enum GNUNET_ErrorType last_bulk_kind;
  95. /**
  96. * Time of the last bulk error message (0 for none)
  97. */
  98. static GNUNET_THREAD_LOCAL struct GNUNET_TIME_Absolute last_bulk_time;
  99. /**
  100. * Number of times that bulk message has been repeated since.
  101. */
  102. static GNUNET_THREAD_LOCAL unsigned int last_bulk_repeat;
  103. /**
  104. * Component when the last bulk was logged. Will be 0-terminated.
  105. */
  106. static GNUNET_THREAD_LOCAL char last_bulk_comp[COMP_TRACK_SIZE + 1];
  107. /**
  108. * Running component.
  109. */
  110. static char *component;
  111. /**
  112. * Running component (without pid).
  113. */
  114. static char *component_nopid;
  115. /**
  116. * Format string describing the name of the log file.
  117. */
  118. static char *log_file_name;
  119. /**
  120. * Minimum log level.
  121. */
  122. static enum GNUNET_ErrorType min_level;
  123. /**
  124. * Linked list of our custom loggres.
  125. */
  126. static struct CustomLogger *loggers;
  127. /**
  128. * Number of log calls to ignore.
  129. */
  130. static GNUNET_THREAD_LOCAL int skip_log = 0;
  131. /**
  132. * File descriptor to use for "stderr", or NULL for none.
  133. */
  134. static FILE *GNUNET_stderr;
  135. /**
  136. * Represents a single logging definition
  137. */
  138. struct LogDef
  139. {
  140. /**
  141. * Component name regex
  142. */
  143. regex_t component_regex;
  144. /**
  145. * File name regex
  146. */
  147. regex_t file_regex;
  148. /**
  149. * Function name regex
  150. */
  151. regex_t function_regex;
  152. /**
  153. * Lowest line at which this definition matches.
  154. * Defaults to 0. Must be <= to_line.
  155. */
  156. int from_line;
  157. /**
  158. * Highest line at which this definition matches.
  159. * Defaults to INT_MAX. Must be >= from_line.
  160. */
  161. int to_line;
  162. /**
  163. * Maximal log level allowed for calls that match this definition.
  164. * Calls with higher log level will be disabled.
  165. * Must be >= 0
  166. */
  167. int level;
  168. /**
  169. * 1 if this definition comes from GNUNET_FORCE_LOG, which means that it
  170. * overrides any configuration options. 0 otherwise.
  171. */
  172. int force;
  173. };
  174. #if ! defined(GNUNET_CULL_LOGGING)
  175. /**
  176. * Dynamic array of logging definitions
  177. */
  178. static struct LogDef *logdefs;
  179. /**
  180. * Allocated size of logdefs array (in units)
  181. */
  182. static int logdefs_size;
  183. /**
  184. * The number of units used in logdefs array.
  185. */
  186. static int logdefs_len;
  187. /**
  188. * #GNUNET_YES if GNUNET_LOG environment variable is already parsed.
  189. */
  190. static int gnunet_log_parsed;
  191. /**
  192. * #GNUNET_YES if GNUNET_FORCE_LOG environment variable is already parsed.
  193. */
  194. static int gnunet_force_log_parsed;
  195. /**
  196. * #GNUNET_YES if at least one definition with forced == 1 is available.
  197. */
  198. static int gnunet_force_log_present;
  199. #endif
  200. /**
  201. * Convert a textual description of a loglevel
  202. * to the respective GNUNET_GE_KIND.
  203. *
  204. * @param log loglevel to parse
  205. * @return GNUNET_GE_INVALID if log does not parse
  206. */
  207. static enum GNUNET_ErrorType
  208. get_type (const char *log)
  209. {
  210. if (NULL == log)
  211. return GNUNET_ERROR_TYPE_UNSPECIFIED;
  212. if (0 == strcasecmp (log, _ ("DEBUG")))
  213. return GNUNET_ERROR_TYPE_DEBUG;
  214. if (0 == strcasecmp (log, _ ("INFO")))
  215. return GNUNET_ERROR_TYPE_INFO;
  216. if (0 == strcasecmp (log, _ ("MESSAGE")))
  217. return GNUNET_ERROR_TYPE_MESSAGE;
  218. if (0 == strcasecmp (log, _ ("WARNING")))
  219. return GNUNET_ERROR_TYPE_WARNING;
  220. if (0 == strcasecmp (log, _ ("ERROR")))
  221. return GNUNET_ERROR_TYPE_ERROR;
  222. if (0 == strcasecmp (log, _ ("NONE")))
  223. return GNUNET_ERROR_TYPE_NONE;
  224. return GNUNET_ERROR_TYPE_INVALID;
  225. }
  226. /**
  227. * Abort the process, generate a core dump if possible.
  228. */
  229. void
  230. GNUNET_abort_ ()
  231. {
  232. abort ();
  233. }
  234. #if ! defined(GNUNET_CULL_LOGGING)
  235. /**
  236. * Utility function - reallocates logdefs array to be twice as large.
  237. */
  238. static void
  239. resize_logdefs (void)
  240. {
  241. logdefs_size = (logdefs_size + 1) * 2;
  242. logdefs = GNUNET_realloc (logdefs, logdefs_size * sizeof(struct LogDef));
  243. }
  244. /**
  245. * Rotate logs, deleting the oldest log.
  246. *
  247. * @param new_name new name to add to the rotation
  248. */
  249. static void
  250. log_rotate (const char *new_name)
  251. {
  252. static char *rotation[ROTATION_KEEP];
  253. static unsigned int rotation_off;
  254. char *discard;
  255. if ('\0' == *new_name)
  256. return; /* not a real log file name */
  257. discard = rotation[rotation_off % ROTATION_KEEP];
  258. if (NULL != discard)
  259. {
  260. /* Note: can't log errors during logging (recursion!), so this
  261. operation MUST silently fail... */
  262. (void) unlink (discard);
  263. GNUNET_free (discard);
  264. }
  265. rotation[rotation_off % ROTATION_KEEP] = GNUNET_strdup (new_name);
  266. rotation_off++;
  267. }
  268. /**
  269. * Setup the log file.
  270. *
  271. * @param tm timestamp for which we should setup logging
  272. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  273. */
  274. static int
  275. setup_log_file (const struct tm *tm)
  276. {
  277. static char last_fn[PATH_MAX + 1];
  278. char fn[PATH_MAX + 1];
  279. int altlog_fd;
  280. int dup_return;
  281. FILE *altlog;
  282. char *leftsquare;
  283. if (NULL == log_file_name)
  284. return GNUNET_SYSERR;
  285. if (0 == strftime (fn, sizeof(fn), log_file_name, tm))
  286. return GNUNET_SYSERR;
  287. leftsquare = strrchr (fn, '[');
  288. if ((NULL != leftsquare) && (']' == leftsquare[1]))
  289. {
  290. char *logfile_copy = GNUNET_strdup (fn);
  291. logfile_copy[leftsquare - fn] = '\0';
  292. logfile_copy[leftsquare - fn + 1] = '\0';
  293. snprintf (fn,
  294. PATH_MAX,
  295. "%s%d%s",
  296. logfile_copy,
  297. getpid (),
  298. &logfile_copy[leftsquare - fn + 2]);
  299. GNUNET_free (logfile_copy);
  300. }
  301. if (0 == strcmp (fn, last_fn))
  302. return GNUNET_OK; /* no change */
  303. log_rotate (last_fn);
  304. strcpy (last_fn, fn);
  305. if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (fn))
  306. {
  307. fprintf (stderr,
  308. "Failed to create directory for `%s': %s\n",
  309. fn,
  310. strerror (errno));
  311. return GNUNET_SYSERR;
  312. }
  313. altlog_fd = open (fn,
  314. O_APPEND | O_WRONLY | O_CREAT,
  315. S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  316. if (-1 != altlog_fd)
  317. {
  318. if (NULL != GNUNET_stderr)
  319. fclose (GNUNET_stderr);
  320. dup_return = dup2 (altlog_fd, 2);
  321. (void) close (altlog_fd);
  322. if (-1 != dup_return)
  323. {
  324. altlog = fdopen (2, "ab");
  325. if (NULL == altlog)
  326. {
  327. (void) close (2);
  328. altlog_fd = -1;
  329. }
  330. }
  331. else
  332. {
  333. altlog_fd = -1;
  334. }
  335. }
  336. if (-1 == altlog_fd)
  337. {
  338. GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn);
  339. return GNUNET_SYSERR;
  340. }
  341. GNUNET_stderr = altlog;
  342. return GNUNET_OK;
  343. }
  344. /**
  345. * Utility function - adds a parsed definition to logdefs array.
  346. *
  347. * @param component see struct LogDef, can't be NULL
  348. * @param file see struct LogDef, can't be NULL
  349. * @param function see struct LogDef, can't be NULL
  350. * @param from_line see struct LogDef
  351. * @param to_line see struct LogDef
  352. * @param level see struct LogDef, must be >= 0
  353. * @param force see struct LogDef
  354. * @return 0 on success, regex-specific error otherwise
  355. */
  356. static int
  357. add_definition (const char *component,
  358. const char *file,
  359. const char *function,
  360. int from_line,
  361. int to_line,
  362. int level,
  363. int force)
  364. {
  365. struct LogDef n;
  366. int r;
  367. if (logdefs_size == logdefs_len)
  368. resize_logdefs ();
  369. memset (&n, 0, sizeof(n));
  370. if (0 == strlen (component))
  371. component = (char *) ".*";
  372. r = regcomp (&n.component_regex, (const char *) component, REG_NOSUB);
  373. if (0 != r)
  374. {
  375. return r;
  376. }
  377. if (0 == strlen (file))
  378. file = (char *) ".*";
  379. r = regcomp (&n.file_regex, (const char *) file, REG_NOSUB);
  380. if (0 != r)
  381. {
  382. regfree (&n.component_regex);
  383. return r;
  384. }
  385. if ((NULL == function) || (0 == strlen (function)))
  386. function = (char *) ".*";
  387. r = regcomp (&n.function_regex, (const char *) function, REG_NOSUB);
  388. if (0 != r)
  389. {
  390. regfree (&n.component_regex);
  391. regfree (&n.file_regex);
  392. return r;
  393. }
  394. n.from_line = from_line;
  395. n.to_line = to_line;
  396. n.level = level;
  397. n.force = force;
  398. logdefs[logdefs_len++] = n;
  399. return 0;
  400. }
  401. /**
  402. * Decides whether a particular logging call should or should not be allowed
  403. * to be made. Used internally by GNUNET_log*()
  404. *
  405. * @param caller_level loglevel the caller wants to use
  406. * @param comp component name the caller uses (NULL means that global
  407. * component name is used)
  408. * @param file file name containing the logging call, usually __FILE__
  409. * @param function function which tries to make a logging call,
  410. * usually __FUNCTION__
  411. * @param line line at which the call is made, usually __LINE__
  412. * @return 0 to disallow the call, 1 to allow it
  413. */
  414. int
  415. GNUNET_get_log_call_status (int caller_level,
  416. const char *comp,
  417. const char *file,
  418. const char *function,
  419. int line)
  420. {
  421. struct LogDef *ld;
  422. int i;
  423. int force_only;
  424. if (NULL == comp)
  425. /* Use default component */
  426. comp = component_nopid;
  427. /* We have no definitions to override globally configured log level,
  428. * so just use it right away.
  429. */
  430. if ((min_level >= 0) && (GNUNET_NO == gnunet_force_log_present))
  431. return caller_level <= min_level;
  432. /* Only look for forced definitions? */
  433. force_only = min_level >= 0;
  434. for (i = 0; i < logdefs_len; i++)
  435. {
  436. ld = &logdefs[i];
  437. if (((! force_only) || ld->force) &&
  438. ((line >= ld->from_line) && (line <= ld->to_line) ) &&
  439. (0 == regexec (&ld->component_regex, comp, 0, NULL, 0)) &&
  440. (0 == regexec (&ld->file_regex, file, 0, NULL, 0)) &&
  441. (0 == regexec (&ld->function_regex, function, 0, NULL, 0)))
  442. {
  443. /* We're finished */
  444. return caller_level <= ld->level;
  445. }
  446. }
  447. /* No matches - use global level, if defined */
  448. if (min_level >= 0)
  449. return caller_level <= min_level;
  450. /* All programs/services previously defaulted to WARNING.
  451. * Now *we* default to WARNING, and THEY default to NULL.
  452. * Or rather we default to MESSAGE, since things aren't always bad.
  453. */
  454. return caller_level <= GNUNET_ERROR_TYPE_MESSAGE;
  455. }
  456. /**
  457. * Utility function - parses a definition
  458. *
  459. * Definition format:
  460. * component;file;function;from_line-to_line;level[/component...]
  461. * All entries are mandatory, but may be empty.
  462. * Empty entries for component, file and function are treated as
  463. * "matches anything".
  464. * Empty line entry is treated as "from 0 to INT_MAX"
  465. * Line entry with only one line is treated as "this line only"
  466. * Entry for level MUST NOT be empty.
  467. * Entries for component, file and function that consist of a
  468. * single character "*" are treated (at the moment) the same way
  469. * empty entries are treated (wildcard matching is not implemented (yet?)).
  470. * file entry is matched to the end of __FILE__. That is, it might be
  471. * a base name, or a base name with leading directory names (some compilers
  472. * define __FILE__ to absolute file path).
  473. *
  474. * @param constname name of the environment variable from which to get the
  475. * string to be parsed
  476. * @param force 1 if definitions found in constname are to be forced
  477. * @return number of added definitions
  478. */
  479. static int
  480. parse_definitions (const char *constname, int force)
  481. {
  482. char *def;
  483. const char *tmp;
  484. char *comp = NULL;
  485. char *file = NULL;
  486. char *function = NULL;
  487. char *p;
  488. char *start;
  489. char *t;
  490. short state;
  491. int level;
  492. int from_line, to_line;
  493. int counter = 0;
  494. int keep_looking = 1;
  495. tmp = getenv (constname);
  496. if (NULL == tmp)
  497. return 0;
  498. def = GNUNET_strdup (tmp);
  499. from_line = 0;
  500. to_line = INT_MAX;
  501. for (p = def, state = 0, start = def; keep_looking; p++)
  502. {
  503. switch (p[0])
  504. {
  505. case ';': /* found a field separator */
  506. p[0] = '\0';
  507. switch (state)
  508. {
  509. case 0: /* within a component name */
  510. comp = start;
  511. break;
  512. case 1: /* within a file name */
  513. file = start;
  514. break;
  515. case 2: /* within a function name */
  516. /* after a file name there must be a function name */
  517. function = start;
  518. break;
  519. case 3: /* within a from-to line range */
  520. if (strlen (start) > 0)
  521. {
  522. errno = 0;
  523. from_line = strtol (start, &t, 10);
  524. if ((0 != errno) || (from_line < 0))
  525. {
  526. GNUNET_free (def);
  527. return counter;
  528. }
  529. if ((t < p) && ('-' == t[0]))
  530. {
  531. errno = 0;
  532. start = t + 1;
  533. to_line = strtol (start, &t, 10);
  534. if ((0 != errno) || (to_line < 0) || (t != p))
  535. {
  536. GNUNET_free (def);
  537. return counter;
  538. }
  539. }
  540. else /* one number means "match this line only" */
  541. to_line = from_line;
  542. }
  543. else /* default to 0-max */
  544. {
  545. from_line = 0;
  546. to_line = INT_MAX;
  547. }
  548. break;
  549. default:
  550. fprintf (
  551. stderr,
  552. _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
  553. p);
  554. break;
  555. }
  556. start = p + 1;
  557. state++;
  558. break;
  559. case '\0': /* found EOL */
  560. keep_looking = 0;
  561. /* fall through to '/' */
  562. case '/': /* found a definition separator */
  563. switch (state)
  564. {
  565. case 4: /* within a log level */
  566. p[0] = '\0';
  567. state = 0;
  568. level = get_type ((const char *) start);
  569. if ((GNUNET_ERROR_TYPE_INVALID == level) ||
  570. (GNUNET_ERROR_TYPE_UNSPECIFIED == level) ||
  571. (0 != add_definition (comp,
  572. file,
  573. function,
  574. from_line,
  575. to_line,
  576. level,
  577. force)))
  578. {
  579. GNUNET_free (def);
  580. return counter;
  581. }
  582. counter++;
  583. start = p + 1;
  584. break;
  585. default:
  586. fprintf (
  587. stderr,
  588. _ ("ERROR: Unable to parse log definition: Syntax error at `%s'.\n"),
  589. p);
  590. break;
  591. }
  592. default:
  593. break;
  594. }
  595. }
  596. GNUNET_free (def);
  597. return counter;
  598. }
  599. /**
  600. * Utility function - parses GNUNET_LOG and GNUNET_FORCE_LOG.
  601. */
  602. static void
  603. parse_all_definitions ()
  604. {
  605. if (GNUNET_NO == gnunet_force_log_parsed)
  606. gnunet_force_log_present =
  607. parse_definitions ("GNUNET_FORCE_LOG", 1) > 0 ? GNUNET_YES : GNUNET_NO;
  608. gnunet_force_log_parsed = GNUNET_YES;
  609. if (GNUNET_NO == gnunet_log_parsed)
  610. parse_definitions ("GNUNET_LOG", 0);
  611. gnunet_log_parsed = GNUNET_YES;
  612. }
  613. #endif
  614. /**
  615. * Setup logging.
  616. *
  617. * @param comp default component to use
  618. * @param loglevel what types of messages should be logged
  619. * @param logfile which file to write log messages to (can be NULL)
  620. * @return #GNUNET_OK on success
  621. */
  622. int
  623. GNUNET_log_setup (const char *comp,
  624. const char *loglevel,
  625. const char *logfile)
  626. {
  627. const char *env_logfile;
  628. min_level = get_type (loglevel);
  629. #if ! defined(GNUNET_CULL_LOGGING)
  630. parse_all_definitions ();
  631. #endif
  632. GNUNET_free (component);
  633. GNUNET_asprintf (&component, "%s-%d", comp, getpid ());
  634. GNUNET_free (component_nopid);
  635. component_nopid = GNUNET_strdup (comp);
  636. env_logfile = getenv ("GNUNET_FORCE_LOGFILE");
  637. if ((NULL != env_logfile) && (strlen (env_logfile) > 0))
  638. logfile = env_logfile;
  639. if (NULL == logfile)
  640. return GNUNET_OK;
  641. GNUNET_free (log_file_name);
  642. log_file_name = GNUNET_STRINGS_filename_expand (logfile);
  643. if (NULL == log_file_name)
  644. return GNUNET_SYSERR;
  645. #if defined(GNUNET_CULL_LOGGING)
  646. /* log file option not allowed for wallet logic */
  647. GNUNET_assert (NULL == logfile);
  648. return GNUNET_OK;
  649. #else
  650. {
  651. time_t t;
  652. const struct tm *tm;
  653. t = time (NULL);
  654. tm = gmtime (&t);
  655. return setup_log_file (tm);
  656. }
  657. #endif
  658. }
  659. /**
  660. * Add a custom logger. Note that installing any custom logger
  661. * will disable the standard logger. When multiple custom loggers
  662. * are installed, all will be called. The standard logger will
  663. * only be used if no custom loggers are present.
  664. *
  665. * @param logger log function
  666. * @param logger_cls closure for @a logger
  667. */
  668. void
  669. GNUNET_logger_add (GNUNET_Logger logger, void *logger_cls)
  670. {
  671. struct CustomLogger *entry;
  672. entry = GNUNET_new (struct CustomLogger);
  673. entry->logger = logger;
  674. entry->logger_cls = logger_cls;
  675. entry->next = loggers;
  676. loggers = entry;
  677. }
  678. /**
  679. * Remove a custom logger.
  680. *
  681. * @param logger log function
  682. * @param logger_cls closure for @a logger
  683. */
  684. void
  685. GNUNET_logger_remove (GNUNET_Logger logger, void *logger_cls)
  686. {
  687. struct CustomLogger *pos;
  688. struct CustomLogger *prev;
  689. prev = NULL;
  690. pos = loggers;
  691. while ((NULL != pos) &&
  692. ((pos->logger != logger) || (pos->logger_cls != logger_cls)))
  693. {
  694. prev = pos;
  695. pos = pos->next;
  696. }
  697. GNUNET_assert (NULL != pos);
  698. if (NULL == prev)
  699. loggers = pos->next;
  700. else
  701. prev->next = pos->next;
  702. GNUNET_free (pos);
  703. }
  704. /**
  705. * Actually output the log message.
  706. *
  707. * @param kind how severe was the issue
  708. * @param comp component responsible
  709. * @param datestr current date/time
  710. * @param msg the actual message
  711. */
  712. static void
  713. output_message (enum GNUNET_ErrorType kind,
  714. const char *comp,
  715. const char *datestr,
  716. const char *msg)
  717. {
  718. struct CustomLogger *pos;
  719. /* only use the standard logger if no custom loggers are present */
  720. if ((NULL != GNUNET_stderr) && (NULL == loggers))
  721. {
  722. if (kind == GNUNET_ERROR_TYPE_MESSAGE)
  723. {
  724. /* The idea here is to produce "normal" output messages
  725. * for end users while still having the power of the
  726. * logging engine for developer needs. So ideally this
  727. * is what it should look like when CLI tools are used
  728. * interactively, yet the same message shouldn't look
  729. * this way if the output is going to logfiles or robots
  730. * instead.
  731. */fprintf (GNUNET_stderr, "* %s", msg);
  732. }
  733. else if (GNUNET_YES == current_async_scope.have_scope)
  734. {
  735. static GNUNET_THREAD_LOCAL char id_buf[27];
  736. char *end;
  737. /* We're logging, so skip_log must be currently 0. */
  738. skip_log = 100;
  739. end = GNUNET_STRINGS_data_to_string (&current_async_scope.scope_id,
  740. sizeof(struct GNUNET_AsyncScopeId),
  741. id_buf,
  742. sizeof(id_buf) - 1);
  743. GNUNET_assert (NULL != end);
  744. *end = '\0';
  745. skip_log = 0;
  746. fprintf (GNUNET_stderr,
  747. "%s %s(%s) %s %s",
  748. datestr,
  749. comp,
  750. id_buf,
  751. GNUNET_error_type_to_string (kind),
  752. msg);
  753. }
  754. else
  755. {
  756. fprintf (GNUNET_stderr,
  757. "%s %s %s %s",
  758. datestr,
  759. comp,
  760. GNUNET_error_type_to_string (kind),
  761. msg);
  762. }
  763. fflush (GNUNET_stderr);
  764. }
  765. pos = loggers;
  766. while (NULL != pos)
  767. {
  768. pos->logger (pos->logger_cls, kind, comp, datestr, msg);
  769. pos = pos->next;
  770. }
  771. }
  772. /**
  773. * Flush an existing bulk report to the output.
  774. *
  775. * @param datestr our current timestamp
  776. */
  777. static void
  778. flush_bulk (const char *datestr)
  779. {
  780. char msg[DATE_STR_SIZE + BULK_TRACK_SIZE + 256];
  781. int rev;
  782. char *last;
  783. const char *ft;
  784. if ((0 == last_bulk_time.abs_value_us) || (0 == last_bulk_repeat))
  785. return;
  786. rev = 0;
  787. last = memchr (last_bulk, '\0', BULK_TRACK_SIZE);
  788. if (last == NULL)
  789. last = &last_bulk[BULK_TRACK_SIZE - 1];
  790. else if (last != last_bulk)
  791. last--;
  792. if (last[0] == '\n')
  793. {
  794. rev = 1;
  795. last[0] = '\0';
  796. }
  797. ft =
  798. GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (
  799. last_bulk_time),
  800. GNUNET_YES);
  801. snprintf (msg,
  802. sizeof(msg),
  803. _ ("Message `%.*s' repeated %u times in the last %s\n"),
  804. BULK_TRACK_SIZE,
  805. last_bulk,
  806. last_bulk_repeat,
  807. ft);
  808. if (rev == 1)
  809. last[0] = '\n';
  810. output_message (last_bulk_kind, last_bulk_comp, datestr, msg);
  811. last_bulk_time = GNUNET_TIME_absolute_get ();
  812. last_bulk_repeat = 0;
  813. }
  814. /**
  815. * Ignore the next n calls to the log function.
  816. *
  817. * @param n number of log calls to ignore (could be negative)
  818. * @param check_reset #GNUNET_YES to assert that the log skip counter is currently zero
  819. */
  820. void
  821. GNUNET_log_skip (int n, int check_reset)
  822. {
  823. int ok;
  824. if (0 == n)
  825. {
  826. ok = (0 == skip_log);
  827. skip_log = 0;
  828. if (check_reset)
  829. GNUNET_break (ok);
  830. }
  831. else
  832. {
  833. skip_log += n;
  834. }
  835. }
  836. /**
  837. * Get the number of log calls that are going to be skipped
  838. *
  839. * @return number of log calls to be ignored
  840. */
  841. int
  842. GNUNET_get_log_skip ()
  843. {
  844. return skip_log;
  845. }
  846. /**
  847. * Output a log message using the default mechanism.
  848. *
  849. * @param kind how severe was the issue
  850. * @param comp component responsible
  851. * @param message the actual message
  852. * @param va arguments to the format string "message"
  853. */
  854. static void
  855. mylog (enum GNUNET_ErrorType kind,
  856. const char *comp,
  857. const char *message,
  858. va_list va)
  859. {
  860. char date[DATE_STR_SIZE];
  861. char date2[DATE_STR_SIZE];
  862. struct tm *tmptr;
  863. size_t size;
  864. va_list vacp;
  865. va_copy (vacp, va);
  866. size = vsnprintf (NULL, 0, message, vacp) + 1;
  867. GNUNET_assert (0 != size);
  868. va_end (vacp);
  869. memset (date, 0, DATE_STR_SIZE);
  870. {
  871. char buf[size];
  872. long long offset;
  873. struct timeval timeofday;
  874. gettimeofday (&timeofday, NULL);
  875. offset = GNUNET_TIME_get_offset ();
  876. if (offset > 0)
  877. {
  878. timeofday.tv_sec += offset / 1000LL;
  879. timeofday.tv_usec += (offset % 1000LL) * 1000LL;
  880. if (timeofday.tv_usec > 1000000LL)
  881. {
  882. timeofday.tv_usec -= 1000000LL;
  883. timeofday.tv_sec++;
  884. }
  885. }
  886. else
  887. {
  888. timeofday.tv_sec += offset / 1000LL;
  889. if (timeofday.tv_usec > -(offset % 1000LL) * 1000LL)
  890. {
  891. timeofday.tv_usec += (offset % 1000LL) * 1000LL;
  892. }
  893. else
  894. {
  895. timeofday.tv_usec += 1000000LL + (offset % 1000LL) * 1000LL;
  896. timeofday.tv_sec--;
  897. }
  898. }
  899. tmptr = localtime (&timeofday.tv_sec);
  900. if (NULL == tmptr)
  901. {
  902. strcpy (date, "localtime error");
  903. }
  904. else
  905. {
  906. if (0 == strftime (date2, DATE_STR_SIZE, "%b %d %H:%M:%S-%%06u", tmptr))
  907. abort ();
  908. if (0 > snprintf (date, sizeof(date), date2, timeofday.tv_usec))
  909. abort ();
  910. }
  911. vsnprintf (buf, size, message, va);
  912. #if ! defined(GNUNET_CULL_LOGGING)
  913. if (NULL != tmptr)
  914. (void) setup_log_file (tmptr);
  915. #endif
  916. if ((0 != (kind & GNUNET_ERROR_TYPE_BULK)) &&
  917. (0 != last_bulk_time.abs_value_us) &&
  918. (0 == strncmp (buf, last_bulk, sizeof(last_bulk))))
  919. {
  920. last_bulk_repeat++;
  921. if ((GNUNET_TIME_absolute_get_duration (last_bulk_time).rel_value_us >
  922. BULK_DELAY_THRESHOLD) ||
  923. (last_bulk_repeat > BULK_REPEAT_THRESHOLD))
  924. flush_bulk (date);
  925. return;
  926. }
  927. flush_bulk (date);
  928. GNUNET_strlcpy (last_bulk, buf, sizeof(last_bulk));
  929. last_bulk_repeat = 0;
  930. last_bulk_kind = kind;
  931. last_bulk_time = GNUNET_TIME_absolute_get ();
  932. GNUNET_strlcpy (last_bulk_comp, comp, sizeof(last_bulk_comp));
  933. output_message (kind, comp, date, buf);
  934. }
  935. }
  936. /**
  937. * Main log function.
  938. *
  939. * @param kind how serious is the error?
  940. * @param message what is the message (format string)
  941. * @param ... arguments for format string
  942. */
  943. void
  944. GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...)
  945. {
  946. va_list va;
  947. va_start (va, message);
  948. mylog (kind, component, message, va);
  949. va_end (va);
  950. }
  951. /**
  952. * Log function that specifies an alternative component.
  953. * This function should be used by plugins.
  954. *
  955. * @param kind how serious is the error?
  956. * @param comp component responsible for generating the message
  957. * @param message what is the message (format string)
  958. * @param ... arguments for format string
  959. */
  960. void
  961. GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind,
  962. const char *comp,
  963. const char *message,
  964. ...)
  965. {
  966. va_list va;
  967. char comp_w_pid[128];
  968. if (comp == NULL)
  969. comp = component_nopid;
  970. va_start (va, message);
  971. GNUNET_snprintf (comp_w_pid, sizeof(comp_w_pid), "%s-%d", comp, getpid ());
  972. mylog (kind, comp_w_pid, message, va);
  973. va_end (va);
  974. }
  975. /**
  976. * Convert error type to string.
  977. *
  978. * @param kind type to convert
  979. * @return string corresponding to the type
  980. */
  981. const char *
  982. GNUNET_error_type_to_string (enum GNUNET_ErrorType kind)
  983. {
  984. if ((kind & GNUNET_ERROR_TYPE_ERROR) > 0)
  985. return _ ("ERROR");
  986. if ((kind & GNUNET_ERROR_TYPE_WARNING) > 0)
  987. return _ ("WARNING");
  988. if ((kind & GNUNET_ERROR_TYPE_MESSAGE) > 0)
  989. return _ ("MESSAGE");
  990. if ((kind & GNUNET_ERROR_TYPE_INFO) > 0)
  991. return _ ("INFO");
  992. if ((kind & GNUNET_ERROR_TYPE_DEBUG) > 0)
  993. return _ ("DEBUG");
  994. if ((kind & ~GNUNET_ERROR_TYPE_BULK) == 0)
  995. return _ ("NONE");
  996. return _ ("INVALID");
  997. }
  998. /**
  999. * Convert a hash to a string (for printing debug messages).
  1000. *
  1001. * @param hc the hash code
  1002. * @return string form; will be overwritten by next call to GNUNET_h2s.
  1003. */
  1004. const char *
  1005. GNUNET_h2s (const struct GNUNET_HashCode *hc)
  1006. {
  1007. static GNUNET_THREAD_LOCAL struct GNUNET_CRYPTO_HashAsciiEncoded ret;
  1008. GNUNET_CRYPTO_hash_to_enc (hc, &ret);
  1009. ret.encoding[8] = '\0';
  1010. return (const char *) ret.encoding;
  1011. }
  1012. /**
  1013. * Convert a hash to a string (for printing debug messages).
  1014. * This is one of the very few calls in the entire API that is
  1015. * NOT reentrant! Identical to #GNUNET_h2s(), except that another
  1016. * buffer is used so both #GNUNET_h2s() and #GNUNET_h2s2() can be
  1017. * used within the same log statement.
  1018. *
  1019. * @param hc the hash code
  1020. * @return string form; will be overwritten by next call to GNUNET_h2s.
  1021. */
  1022. const char *
  1023. GNUNET_h2s2 (const struct GNUNET_HashCode *hc)
  1024. {
  1025. static GNUNET_THREAD_LOCAL struct GNUNET_CRYPTO_HashAsciiEncoded ret;
  1026. GNUNET_CRYPTO_hash_to_enc (hc, &ret);
  1027. ret.encoding[8] = '\0';
  1028. return (const char *) ret.encoding;
  1029. }
  1030. /**
  1031. * @ingroup logging
  1032. * Convert a public key value to a string (for printing debug messages).
  1033. * This is one of the very few calls in the entire API that is
  1034. * NOT reentrant!
  1035. *
  1036. * @param hc the hash code
  1037. * @return string
  1038. */
  1039. const char *
  1040. GNUNET_p2s (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
  1041. {
  1042. static GNUNET_THREAD_LOCAL struct GNUNET_CRYPTO_HashAsciiEncoded ret;
  1043. struct GNUNET_HashCode hc;
  1044. GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
  1045. GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
  1046. ret.encoding[6] = '\0';
  1047. return (const char *) ret.encoding;
  1048. }
  1049. /**
  1050. * @ingroup logging
  1051. * Convert a public key value to a string (for printing debug messages).
  1052. * This is one of the very few calls in the entire API that is
  1053. * NOT reentrant!
  1054. *
  1055. * @param hc the hash code
  1056. * @return string
  1057. */
  1058. const char *
  1059. GNUNET_p2s2 (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
  1060. {
  1061. static GNUNET_THREAD_LOCAL struct GNUNET_CRYPTO_HashAsciiEncoded ret;
  1062. struct GNUNET_HashCode hc;
  1063. GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
  1064. GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
  1065. ret.encoding[6] = '\0';
  1066. return (const char *) ret.encoding;
  1067. }
  1068. /**
  1069. * @ingroup logging
  1070. * Convert a public key value to a string (for printing debug messages).
  1071. * This is one of the very few calls in the entire API that is
  1072. * NOT reentrant!
  1073. *
  1074. * @param hc the hash code
  1075. * @return string
  1076. */
  1077. const char *
  1078. GNUNET_e2s (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
  1079. {
  1080. static GNUNET_THREAD_LOCAL struct GNUNET_CRYPTO_HashAsciiEncoded ret;
  1081. struct GNUNET_HashCode hc;
  1082. GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
  1083. GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
  1084. ret.encoding[6] = '\0';
  1085. return (const char *) ret.encoding;
  1086. }
  1087. /**
  1088. * @ingroup logging
  1089. * Convert a public key value to a string (for printing debug messages).
  1090. * This is one of the very few calls in the entire API that is
  1091. * NOT reentrant!
  1092. *
  1093. * @param hc the hash code
  1094. * @return string
  1095. */
  1096. const char *
  1097. GNUNET_e2s2 (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
  1098. {
  1099. static GNUNET_THREAD_LOCAL struct GNUNET_CRYPTO_HashAsciiEncoded ret;
  1100. struct GNUNET_HashCode hc;
  1101. GNUNET_CRYPTO_hash (p, sizeof(*p), &hc);
  1102. GNUNET_CRYPTO_hash_to_enc (&hc, &ret);
  1103. ret.encoding[6] = '\0';
  1104. return (const char *) ret.encoding;
  1105. }
  1106. /**
  1107. * @ingroup logging
  1108. * Convert a short hash value to a string (for printing debug messages).
  1109. * This is one of the very few calls in the entire API that is
  1110. * NOT reentrant!
  1111. *
  1112. * @param shc the hash code
  1113. * @return string
  1114. */
  1115. const char *
  1116. GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc)
  1117. {
  1118. static GNUNET_THREAD_LOCAL char buf[64];
  1119. GNUNET_STRINGS_data_to_string (shc, sizeof(*shc), buf, sizeof(buf));
  1120. buf[6] = '\0';
  1121. return (const char *) buf;
  1122. }
  1123. /**
  1124. * @ingroup logging
  1125. * Convert a UUID to a string (for printing debug messages).
  1126. * This is one of the very few calls in the entire API that is
  1127. * NOT reentrant!
  1128. *
  1129. * @param uuid the UUID
  1130. * @return string
  1131. */
  1132. const char *
  1133. GNUNET_uuid2s (const struct GNUNET_Uuid *uuid)
  1134. {
  1135. static GNUNET_THREAD_LOCAL char buf[32];
  1136. GNUNET_STRINGS_data_to_string (uuid, sizeof(*uuid), buf, sizeof(buf));
  1137. buf[6] = '\0';
  1138. return (const char *) buf;
  1139. }
  1140. /**
  1141. * Convert a hash to a string (for printing debug messages).
  1142. * This is one of the very few calls in the entire API that is
  1143. * NOT reentrant!
  1144. *
  1145. * @param hc the hash code
  1146. * @return string form; will be overwritten by next call to GNUNET_h2s_full.
  1147. */
  1148. const char *
  1149. GNUNET_h2s_full (const struct GNUNET_HashCode *hc)
  1150. {
  1151. static GNUNET_THREAD_LOCAL struct GNUNET_CRYPTO_HashAsciiEncoded ret;
  1152. GNUNET_CRYPTO_hash_to_enc (hc, &ret);
  1153. ret.encoding[sizeof(ret) - 1] = '\0';
  1154. return (const char *) ret.encoding;
  1155. }
  1156. /**
  1157. * Convert a peer identity to a string (for printing debug messages).
  1158. *
  1159. * @param pid the peer identity
  1160. * @return string form of the pid; will be overwritten by next
  1161. * call to #GNUNET_i2s.
  1162. */
  1163. const char *
  1164. GNUNET_i2s (const struct GNUNET_PeerIdentity *pid)
  1165. {
  1166. static GNUNET_THREAD_LOCAL char buf[5];
  1167. char *ret;
  1168. if (NULL == pid)
  1169. return "NULL";
  1170. ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
  1171. GNUNET_strlcpy (buf, ret, sizeof(buf));
  1172. GNUNET_free (ret);
  1173. return buf;
  1174. }
  1175. /**
  1176. * Convert a peer identity to a string (for printing debug messages).
  1177. * Identical to #GNUNET_i2s(), except that another
  1178. * buffer is used so both #GNUNET_i2s() and #GNUNET_i2s2() can be
  1179. * used within the same log statement.
  1180. *
  1181. * @param pid the peer identity
  1182. * @return string form of the pid; will be overwritten by next
  1183. * call to #GNUNET_i2s.
  1184. */
  1185. const char *
  1186. GNUNET_i2s2 (const struct GNUNET_PeerIdentity *pid)
  1187. {
  1188. static GNUNET_THREAD_LOCAL char buf[5];
  1189. char *ret;
  1190. if (NULL == pid)
  1191. return "NULL";
  1192. ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
  1193. GNUNET_strlcpy (buf, ret, sizeof(buf));
  1194. GNUNET_free (ret);
  1195. return buf;
  1196. }
  1197. /**
  1198. * Convert a peer identity to a string (for printing debug messages).
  1199. *
  1200. * @param pid the peer identity
  1201. * @return string form of the pid; will be overwritten by next
  1202. * call to #GNUNET_i2s_full.
  1203. */
  1204. const char *
  1205. GNUNET_i2s_full (const struct GNUNET_PeerIdentity *pid)
  1206. {
  1207. static GNUNET_THREAD_LOCAL char buf[256];
  1208. char *ret;
  1209. ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
  1210. strcpy (buf, ret);
  1211. GNUNET_free (ret);
  1212. return buf;
  1213. }
  1214. /**
  1215. * Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string
  1216. * (for printing debug messages). This is one of the very few calls
  1217. * in the entire API that is NOT reentrant!
  1218. *
  1219. * @param addr the address
  1220. * @param addrlen the length of the address in @a addr
  1221. * @return nicely formatted string for the address
  1222. * will be overwritten by next call to #GNUNET_a2s.
  1223. */
  1224. const char *
  1225. GNUNET_a2s (const struct sockaddr *addr, socklen_t addrlen)
  1226. {
  1227. #define LEN \
  1228. GNUNET_MAX ((INET6_ADDRSTRLEN + 8), \
  1229. (1 + sizeof(struct sockaddr_un) - sizeof(sa_family_t)))
  1230. static GNUNET_THREAD_LOCAL char buf[LEN];
  1231. #undef LEN
  1232. static GNUNET_THREAD_LOCAL char b2[6];
  1233. const struct sockaddr_in *v4;
  1234. const struct sockaddr_un *un;
  1235. const struct sockaddr_in6 *v6;
  1236. unsigned int off;
  1237. if (addr == NULL)
  1238. return _ ("unknown address");
  1239. switch (addr->sa_family)
  1240. {
  1241. case AF_INET:
  1242. if (addrlen != sizeof(struct sockaddr_in))
  1243. return "<invalid v4 address>";
  1244. v4 = (const struct sockaddr_in *) addr;
  1245. inet_ntop (AF_INET, &v4->sin_addr, buf, INET_ADDRSTRLEN);
  1246. if (0 == ntohs (v4->sin_port))
  1247. return buf;
  1248. strcat (buf, ":");
  1249. GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v4->sin_port));
  1250. strcat (buf, b2);
  1251. return buf;
  1252. case AF_INET6:
  1253. if (addrlen != sizeof(struct sockaddr_in6))
  1254. return "<invalid v6 address>";
  1255. v6 = (const struct sockaddr_in6 *) addr;
  1256. buf[0] = '[';
  1257. inet_ntop (AF_INET6, &v6->sin6_addr, &buf[1], INET6_ADDRSTRLEN);
  1258. if (0 == ntohs (v6->sin6_port))
  1259. return &buf[1];
  1260. strcat (buf, "]:");
  1261. GNUNET_snprintf (b2, sizeof(b2), "%u", ntohs (v6->sin6_port));
  1262. strcat (buf, b2);
  1263. return buf;
  1264. case AF_UNIX:
  1265. if (addrlen <= sizeof(sa_family_t))
  1266. return "<unbound UNIX client>";
  1267. un = (const struct sockaddr_un *) addr;
  1268. off = 0;
  1269. if ('\0' == un->sun_path[0])
  1270. off++;
  1271. memset (buf, 0, sizeof(buf));
  1272. GNUNET_snprintf (buf,
  1273. sizeof(buf),
  1274. "%s%.*s",
  1275. (1 == off) ? "@" : "",
  1276. (int) (addrlen - sizeof(sa_family_t) - off),
  1277. &un->sun_path[off]);
  1278. return buf;
  1279. default:
  1280. return _ ("invalid address");
  1281. }
  1282. }
  1283. /**
  1284. * Log error message about missing configuration option.
  1285. *
  1286. * @param kind log level
  1287. * @param section section with missing option
  1288. * @param option name of missing option
  1289. */
  1290. void
  1291. GNUNET_log_config_missing (enum GNUNET_ErrorType kind,
  1292. const char *section,
  1293. const char *option)
  1294. {
  1295. GNUNET_log (kind,
  1296. _ (
  1297. "Configuration fails to specify option `%s' in section `%s'!\n"),
  1298. option,
  1299. section);
  1300. }
  1301. /**
  1302. * Log error message about invalid configuration option value.
  1303. *
  1304. * @param kind log level
  1305. * @param section section with invalid option
  1306. * @param option name of invalid option
  1307. * @param required what is required that is invalid about the option
  1308. */
  1309. void
  1310. GNUNET_log_config_invalid (enum GNUNET_ErrorType kind,
  1311. const char *section,
  1312. const char *option,
  1313. const char *required)
  1314. {
  1315. GNUNET_log (
  1316. kind,
  1317. _ (
  1318. "Configuration specifies invalid value for option `%s' in section `%s': %s\n"),
  1319. option,
  1320. section,
  1321. required);
  1322. }
  1323. /**
  1324. * Set the async scope for the current thread.
  1325. *
  1326. * @param aid the async scope identifier
  1327. * @param old_scope[out] location to save the old scope
  1328. */
  1329. void
  1330. GNUNET_async_scope_enter (const struct GNUNET_AsyncScopeId *aid,
  1331. struct GNUNET_AsyncScopeSave *old_scope)
  1332. {
  1333. *old_scope = current_async_scope;
  1334. current_async_scope.have_scope = GNUNET_YES;
  1335. current_async_scope.scope_id = *aid;
  1336. }
  1337. /**
  1338. * Clear the current thread's async scope.
  1339. *
  1340. * @param old_scope scope to restore
  1341. */
  1342. void
  1343. GNUNET_async_scope_restore (struct GNUNET_AsyncScopeSave *old_scope)
  1344. {
  1345. current_async_scope = *old_scope;
  1346. }
  1347. /**
  1348. * Generate a fresh async scope identifier.
  1349. *
  1350. * @param[out] aid_ret pointer to where the result is stored
  1351. */
  1352. void
  1353. GNUNET_async_scope_fresh (struct GNUNET_AsyncScopeId *aid_ret)
  1354. {
  1355. GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
  1356. aid_ret,
  1357. sizeof(struct GNUNET_AsyncScopeId));
  1358. }
  1359. /**
  1360. * Get the current async scope.
  1361. *
  1362. * @param[out] scope_ret pointer to where the result is stored
  1363. */
  1364. void
  1365. GNUNET_async_scope_get (struct GNUNET_AsyncScopeSave *scope_ret)
  1366. {
  1367. *scope_ret = current_async_scope;
  1368. }
  1369. /**
  1370. * Initializer
  1371. */
  1372. void __attribute__ ((constructor))
  1373. GNUNET_util_cl_init ()
  1374. {
  1375. GNUNET_stderr = stderr;
  1376. }
  1377. /**
  1378. * Destructor
  1379. */
  1380. void __attribute__ ((destructor))
  1381. GNUNET_util_cl_fini ()
  1382. {
  1383. }
  1384. /* end of common_logging.c */