Imported Upstream version 2.1.13
[platform/upstream/gpg2.git] / common / logging.c
1 /* logging.c - Useful logging functions
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
3  *               2009, 2010 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify it
8  * under the terms of either
9  *
10  *   - the GNU Lesser General Public License as published by the Free
11  *     Software Foundation; either version 3 of the License, or (at
12  *     your option) any later version.
13  *
14  * or
15  *
16  *   - the GNU General Public License as published by the Free
17  *     Software Foundation; either version 2 of the License, or (at
18  *     your option) any later version.
19  *
20  * or both in parallel, as here.
21  *
22  * GnuPG is distributed in the hope that it will be useful, but
23  * WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * General Public License for more details.
26  *
27  * You should have received a copies of the GNU General Public License
28  * and the GNU Lesser General Public License along with this program;
29  * if not, see <http://www.gnu.org/licenses/>.
30  */
31
32
33 #include <config.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <stdarg.h>
38 #include <stddef.h>
39 #include <errno.h>
40 #include <time.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #ifdef HAVE_W32_SYSTEM
44 # ifdef HAVE_WINSOCK2_H
45 #  include <winsock2.h>
46 # endif
47 # include <windows.h>
48 #else /*!HAVE_W32_SYSTEM*/
49 # include <sys/socket.h>
50 # include <sys/un.h>
51 # include <netinet/in.h>
52 # include <arpa/inet.h>
53 #endif /*!HAVE_W32_SYSTEM*/
54 #include <unistd.h>
55 #include <fcntl.h>
56 #include <assert.h>
57 /* #include <execinfo.h> */
58
59 #define GNUPG_COMMON_NEED_AFLOCAL 1
60 #include "util.h"
61 #include "i18n.h"
62 #include "common-defs.h"
63 #include "logging.h"
64
65 #ifdef HAVE_W32_SYSTEM
66 # define S_IRGRP S_IRUSR
67 # define S_IROTH S_IRUSR
68 # define S_IWGRP S_IWUSR
69 # define S_IWOTH S_IWUSR
70 #endif
71
72
73 #ifdef HAVE_W32CE_SYSTEM
74 # define isatty(a)  (0)
75 #endif
76
77 #undef WITH_IPV6
78 #if defined (AF_INET6) && defined(PF_INET) \
79     && defined (INET6_ADDRSTRLEN) && defined(HAVE_INET_PTON)
80 # define WITH_IPV6 1
81 #endif
82
83 #ifndef EAFNOSUPPORT
84 # define EAFNOSUPPORT EINVAL
85 #endif
86 #ifndef INADDR_NONE  /* Slowaris is missing that.  */
87 #define INADDR_NONE  ((unsigned long)(-1))
88 #endif /*INADDR_NONE*/
89
90 #ifdef HAVE_W32_SYSTEM
91 #define sock_close(a)  closesocket(a)
92 #else
93 #define sock_close(a)  close(a)
94 #endif
95
96
97 static estream_t logstream;
98 static int log_socket = -1;
99 static char prefix_buffer[80];
100 static int with_time;
101 static int with_prefix;
102 static int with_pid;
103 #ifdef HAVE_W32_SYSTEM
104 static int no_registry;
105 #endif
106 static int (*get_pid_suffix_cb)(unsigned long *r_value);
107 static int running_detached;
108 static int force_prefixes;
109
110 static int missing_lf;
111 static int errorcount;
112
113
114 int
115 log_get_errorcount (int clear)
116 {
117     int n = errorcount;
118     if( clear )
119         errorcount = 0;
120     return n;
121 }
122
123 void
124 log_inc_errorcount (void)
125 {
126    errorcount++;
127 }
128
129
130 /* The following 3 functions are used by es_fopencookie to write logs
131    to a socket.  */
132 struct fun_cookie_s
133 {
134   int fd;
135   int quiet;
136   int want_socket;
137   int is_socket;
138 #ifdef HAVE_W32CE_SYSTEM
139   int use_writefile;
140 #endif
141   char name[1];
142 };
143
144
145 /* Write NBYTES of BUFFER to file descriptor FD. */
146 static int
147 writen (int fd, const void *buffer, size_t nbytes, int is_socket)
148 {
149   const char *buf = buffer;
150   size_t nleft = nbytes;
151   int nwritten;
152 #ifndef HAVE_W32_SYSTEM
153   (void)is_socket; /* Not required.  */
154 #endif
155
156   while (nleft > 0)
157     {
158 #ifdef HAVE_W32_SYSTEM
159       if (is_socket)
160         nwritten = send (fd, buf, nleft, 0);
161       else
162 #endif
163         nwritten = write (fd, buf, nleft);
164
165       if (nwritten < 0 && errno == EINTR)
166         continue;
167       if (nwritten < 0)
168         return -1;
169       nleft -= nwritten;
170       buf = buf + nwritten;
171     }
172
173   return 0;
174 }
175
176
177 /* Returns true if STR represents a valid port number in decimal
178    notation and no garbage is following.  */
179 static int
180 parse_portno (const char *str, unsigned short *r_port)
181 {
182   unsigned int value;
183
184   for (value=0; *str && (*str >= '0' && *str <= '9'); str++)
185     {
186       value = value * 10 + (*str - '0');
187       if (value > 65535)
188         return 0;
189     }
190   if (*str || !value)
191     return 0;
192
193   *r_port = value;
194   return 1;
195 }
196
197
198 static gpgrt_ssize_t
199 fun_writer (void *cookie_arg, const void *buffer, size_t size)
200 {
201   struct fun_cookie_s *cookie = cookie_arg;
202
203   /* FIXME: Use only estream with a callback for socket writing.  This
204      avoids the ugly mix of fd and estream code.  */
205
206   /* Note that we always try to reconnect to the socket but print
207      error messages only the first time an error occurred.  If
208      RUNNING_DETACHED is set we don't fall back to stderr and even do
209      not print any error messages.  This is needed because detached
210      processes often close stderr and by writing to file descriptor 2
211      we might send the log message to a file not intended for logging
212      (e.g. a pipe or network connection). */
213   if (cookie->want_socket && cookie->fd == -1)
214     {
215 #ifdef WITH_IPV6
216       struct sockaddr_in6 srvr_addr_in6;
217 #endif
218       struct sockaddr_in srvr_addr_in;
219 #ifndef HAVE_W32_SYSTEM
220       struct sockaddr_un srvr_addr_un;
221 #endif
222       size_t addrlen;
223       struct sockaddr *srvr_addr = NULL;
224       unsigned short port = 0;
225       int af = AF_LOCAL;
226       int pf = PF_LOCAL;
227       const char *name = cookie->name;
228
229       /* Not yet open or meanwhile closed due to an error. */
230       cookie->is_socket = 0;
231
232       /* Check whether this is a TCP socket or a local socket.  */
233       if (!strncmp (name, "tcp://", 6) && name[6])
234         {
235           name += 6;
236           af = AF_INET;
237           pf = PF_INET;
238         }
239 #ifndef HAVE_W32_SYSTEM
240       else if (!strncmp (name, "socket://", 9) && name[9])
241         name += 9;
242 #endif
243
244       if (af == AF_LOCAL)
245         {
246 #ifdef HAVE_W32_SYSTEM
247           addrlen = 0;
248 #else
249           memset (&srvr_addr, 0, sizeof srvr_addr);
250           srvr_addr_un.sun_family = af;
251           strncpy (srvr_addr_un.sun_path,
252                    name, sizeof (srvr_addr_un.sun_path)-1);
253           srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path)-1] = 0;
254           srvr_addr = (struct sockaddr *)&srvr_addr_un;
255           addrlen = SUN_LEN (&srvr_addr_un);
256 #endif
257         }
258       else
259         {
260           char *addrstr, *p;
261 #ifdef HAVE_INET_PTON
262           void *addrbuf = NULL;
263 #endif /*HAVE_INET_PTON*/
264
265           addrstr = xtrymalloc (strlen (name) + 1);
266           if (!addrstr)
267             addrlen = 0; /* This indicates an error.  */
268           else if (*name == '[')
269             {
270               /* Check for IPv6 literal address.  */
271               strcpy (addrstr, name+1);
272               p = strchr (addrstr, ']');
273               if (!p || p[1] != ':' || !parse_portno (p+2, &port))
274                 {
275                   gpg_err_set_errno (EINVAL);
276                   addrlen = 0;
277                 }
278               else
279                 {
280                   *p = 0;
281 #ifdef WITH_IPV6
282                   af = AF_INET6;
283                   pf = PF_INET6;
284                   memset (&srvr_addr_in6, 0, sizeof srvr_addr_in6);
285                   srvr_addr_in6.sin6_family = af;
286                   srvr_addr_in6.sin6_port = htons (port);
287 #ifdef HAVE_INET_PTON
288                   addrbuf = &srvr_addr_in6.sin6_addr;
289 #endif /*HAVE_INET_PTON*/
290                   srvr_addr = (struct sockaddr *)&srvr_addr_in6;
291                   addrlen = sizeof srvr_addr_in6;
292 #else
293                   gpg_err_set_errno (EAFNOSUPPORT);
294                   addrlen = 0;
295 #endif
296                 }
297             }
298           else
299             {
300               /* Check for IPv4 literal address.  */
301               strcpy (addrstr, name);
302               p = strchr (addrstr, ':');
303               if (!p || !parse_portno (p+1, &port))
304                 {
305                   gpg_err_set_errno (EINVAL);
306                   addrlen = 0;
307                 }
308               else
309                 {
310                   *p = 0;
311                   memset (&srvr_addr_in, 0, sizeof srvr_addr_in);
312                   srvr_addr_in.sin_family = af;
313                   srvr_addr_in.sin_port = htons (port);
314 #ifdef HAVE_INET_PTON
315                   addrbuf = &srvr_addr_in.sin_addr;
316 #endif /*HAVE_INET_PTON*/
317                   srvr_addr = (struct sockaddr *)&srvr_addr_in;
318                   addrlen = sizeof srvr_addr_in;
319                 }
320             }
321
322           if (addrlen)
323             {
324 #ifdef HAVE_INET_PTON
325               if (inet_pton (af, addrstr, addrbuf) != 1)
326                 addrlen = 0;
327 #else /*!HAVE_INET_PTON*/
328               /* We need to use the old function.  If we are here v6
329                  support isn't enabled anyway and thus we can do fine
330                  without.  Note that Windows has a compatible inet_pton
331                  function named inetPton, but only since Vista.  */
332               srvr_addr_in.sin_addr.s_addr = inet_addr (addrstr);
333               if (srvr_addr_in.sin_addr.s_addr == INADDR_NONE)
334                 addrlen = 0;
335 #endif /*!HAVE_INET_PTON*/
336             }
337
338           xfree (addrstr);
339         }
340
341       cookie->fd = addrlen? socket (pf, SOCK_STREAM, 0) : -1;
342       if (cookie->fd == -1)
343         {
344           if (!cookie->quiet && !running_detached
345               && isatty (es_fileno (es_stderr)))
346             es_fprintf (es_stderr, "failed to create socket for logging: %s\n",
347                         strerror(errno));
348         }
349       else
350         {
351           if (connect (cookie->fd, srvr_addr, addrlen) == -1)
352             {
353               if (!cookie->quiet && !running_detached
354                   && isatty (es_fileno (es_stderr)))
355                 es_fprintf (es_stderr, "can't connect to '%s': %s\n",
356                             cookie->name, strerror(errno));
357               sock_close (cookie->fd);
358               cookie->fd = -1;
359             }
360         }
361
362       if (cookie->fd == -1)
363         {
364           if (!running_detached)
365             {
366               /* Due to all the problems with apps not running
367                  detached but being called with stderr closed or used
368                  for a different purposes, it does not make sense to
369                  switch to stderr.  We therefore disable it. */
370               if (!cookie->quiet)
371                 {
372                   /* fputs ("switching logging to stderr\n", stderr);*/
373                   cookie->quiet = 1;
374                 }
375               cookie->fd = -1; /*fileno (stderr);*/
376             }
377         }
378       else /* Connection has been established. */
379         {
380           cookie->quiet = 0;
381           cookie->is_socket = 1;
382         }
383     }
384
385   log_socket = cookie->fd;
386   if (cookie->fd != -1)
387     {
388 #ifdef HAVE_W32CE_SYSTEM
389       if (cookie->use_writefile)
390         {
391           DWORD nwritten;
392
393           WriteFile ((HANDLE)cookie->fd, buffer, size, &nwritten, NULL);
394           return (gpgrt_ssize_t)size; /* Okay.  */
395         }
396 #endif
397       if (!writen (cookie->fd, buffer, size, cookie->is_socket))
398         return (gpgrt_ssize_t)size; /* Okay. */
399     }
400
401   if (!running_detached && cookie->fd != -1
402       && isatty (es_fileno (es_stderr)))
403     {
404       if (*cookie->name)
405         es_fprintf (es_stderr, "error writing to '%s': %s\n",
406                     cookie->name, strerror(errno));
407       else
408         es_fprintf (es_stderr, "error writing to file descriptor %d: %s\n",
409                     cookie->fd, strerror(errno));
410     }
411   if (cookie->is_socket && cookie->fd != -1)
412     {
413       sock_close (cookie->fd);
414       cookie->fd = -1;
415       log_socket = -1;
416     }
417
418   return (gpgrt_ssize_t)size;
419 }
420
421
422 static int
423 fun_closer (void *cookie_arg)
424 {
425   struct fun_cookie_s *cookie = cookie_arg;
426
427   if (cookie->fd != -1 && cookie->fd != 2)
428     sock_close (cookie->fd);
429   xfree (cookie);
430   log_socket = -1;
431   return 0;
432 }
433
434
435 /* Common function to either set the logging to a file or a file
436    descriptor. */
437 static void
438 set_file_fd (const char *name, int fd)
439 {
440   estream_t fp;
441   int want_socket;
442 #ifdef HAVE_W32CE_SYSTEM
443   int use_writefile = 0;
444 #endif
445   struct fun_cookie_s *cookie;
446
447   /* Close an open log stream.  */
448   if (logstream)
449     {
450       es_fclose (logstream);
451       logstream = NULL;
452     }
453
454   /* Figure out what kind of logging we want.  */
455   if (name && !strcmp (name, "-"))
456     {
457       name = NULL;
458       fd = es_fileno (es_stderr);
459     }
460
461   want_socket = 0;
462   if (name && !strncmp (name, "tcp://", 6) && name[6])
463     want_socket = 1;
464 #ifndef HAVE_W32_SYSTEM
465   else if (name && !strncmp (name, "socket://", 9) && name[9])
466     want_socket = 2;
467 #endif /*HAVE_W32_SYSTEM*/
468 #ifdef HAVE_W32CE_SYSTEM
469   else if (name && !strcmp (name, "GPG2:"))
470     {
471       HANDLE hd;
472
473       ActivateDevice (L"Drivers\\"GNUPG_NAME"_Log", 0);
474       /* Ignore a filename and write the debug output to the GPG2:
475          device.  */
476       hd = CreateFile (L"GPG2:", GENERIC_WRITE,
477                        FILE_SHARE_READ | FILE_SHARE_WRITE,
478                        NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
479       fd = (hd == INVALID_HANDLE_VALUE)? -1 : (int)hd;
480       name = NULL;
481       force_prefixes = 1;
482       use_writefile = 1;
483     }
484 #endif /*HAVE_W32CE_SYSTEM*/
485
486   /* Setup a new stream.  */
487
488   /* The xmalloc below is justified because we can expect that this
489      function is called only during initialization and there is no
490      easy way out of this error condition.  */
491   cookie = xmalloc (sizeof *cookie + (name? strlen (name):0));
492   strcpy (cookie->name, name? name:"");
493   cookie->quiet = 0;
494   cookie->is_socket = 0;
495   cookie->want_socket = want_socket;
496 #ifdef HAVE_W32CE_SYSTEM
497   cookie->use_writefile = use_writefile;
498 #endif
499   if (!name)
500     cookie->fd = fd;
501   else if (want_socket)
502     cookie->fd = -1;
503   else
504     {
505       do
506         cookie->fd = open (name, O_WRONLY|O_APPEND|O_CREAT,
507                            (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH));
508       while (cookie->fd == -1 && errno == EINTR);
509     }
510   log_socket = cookie->fd;
511
512   {
513     es_cookie_io_functions_t io = { NULL };
514     io.func_write = fun_writer;
515     io.func_close = fun_closer;
516
517     fp = es_fopencookie (cookie, "w", io);
518   }
519
520   /* On error default to a stderr based estream.  */
521   if (!fp)
522     fp = es_stderr;
523
524   es_setvbuf (fp, NULL, _IOLBF, 0);
525
526   logstream = fp;
527
528   /* We always need to print the prefix and the pid for socket mode,
529      so that the server reading the socket can do something
530      meaningful. */
531   force_prefixes = want_socket;
532
533   missing_lf = 0;
534 }
535
536
537 /* Set the file to write log to.  The special names NULL and "-" may
538    be used to select stderr and names formatted like
539    "socket:///home/foo/mylogs" may be used to write the logging to the
540    socket "/home/foo/mylogs".  If the connection to the socket fails
541    or a write error is detected, the function writes to stderr and
542    tries the next time again to connect the socket.
543   */
544 void
545 log_set_file (const char *name)
546 {
547   set_file_fd (name? name: "-", -1);
548 }
549
550 void
551 log_set_fd (int fd)
552 {
553   set_file_fd (NULL, fd);
554 }
555
556
557 void
558 log_set_pid_suffix_cb (int (*cb)(unsigned long *r_value))
559 {
560   get_pid_suffix_cb = cb;
561 }
562
563
564 void
565 log_set_prefix (const char *text, unsigned int flags)
566 {
567   if (text)
568     {
569       strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1);
570       prefix_buffer[sizeof (prefix_buffer)-1] = 0;
571     }
572
573   with_prefix = (flags & GPGRT_LOG_WITH_PREFIX);
574   with_time = (flags & GPGRT_LOG_WITH_TIME);
575   with_pid  = (flags & GPGRT_LOG_WITH_PID);
576   running_detached = (flags & GPGRT_LOG_RUN_DETACHED);
577 #ifdef HAVE_W32_SYSTEM
578   no_registry = (flags & GPGRT_LOG_NO_REGISTRY);
579 #endif
580 }
581
582
583 const char *
584 log_get_prefix (unsigned int *flags)
585 {
586   if (flags)
587     {
588       *flags = 0;
589       if (with_prefix)
590         *flags |= GPGRT_LOG_WITH_PREFIX;
591       if (with_time)
592         *flags |= GPGRT_LOG_WITH_TIME;
593       if (with_pid)
594         *flags |= GPGRT_LOG_WITH_PID;
595       if (running_detached)
596         *flags |= GPGRT_LOG_RUN_DETACHED;
597 #ifdef HAVE_W32_SYSTEM
598       if (no_registry)
599         *flags |= GPGRT_LOG_NO_REGISTRY;
600 #endif
601     }
602   return prefix_buffer;
603 }
604
605 /* This function returns true if the file descriptor FD is in use for
606    logging.  This is preferable over a test using log_get_fd in that
607    it allows the logging code to use more then one file descriptor.  */
608 int
609 log_test_fd (int fd)
610 {
611   if (logstream)
612     {
613       int tmp = es_fileno (logstream);
614       if ( tmp != -1 && tmp == fd)
615         return 1;
616     }
617   if (log_socket != -1 && log_socket == fd)
618     return 1;
619   return 0;
620 }
621
622 int
623 log_get_fd ()
624 {
625   return logstream? es_fileno(logstream) : -1;
626 }
627
628 estream_t
629 log_get_stream ()
630 {
631   if (!logstream)
632     {
633       log_set_file (NULL); /* Make sure a log stream has been set.  */
634       assert (logstream);
635     }
636   return logstream;
637 }
638
639 static void
640 do_logv (int level, int ignore_arg_ptr, const char *fmt, va_list arg_ptr)
641 {
642   if (!logstream)
643     {
644 #ifdef HAVE_W32_SYSTEM
645       char *tmp;
646
647       tmp = (no_registry
648              ? NULL
649              : read_w32_registry_string (NULL, GNUPG_REGISTRY_DIR,
650                                          "DefaultLogFile"));
651       log_set_file (tmp && *tmp? tmp : NULL);
652       xfree (tmp);
653 #else
654       log_set_file (NULL); /* Make sure a log stream has been set.  */
655 #endif
656       assert (logstream);
657     }
658
659   es_flockfile (logstream);
660   if (missing_lf && level != GPGRT_LOG_CONT)
661     es_putc_unlocked ('\n', logstream );
662   missing_lf = 0;
663
664   if (level != GPGRT_LOG_CONT)
665     { /* Note this does not work for multiple line logging as we would
666        * need to print to a buffer first */
667       if (with_time && !force_prefixes)
668         {
669           struct tm *tp;
670           time_t atime = time (NULL);
671
672           tp = localtime (&atime);
673           es_fprintf_unlocked (logstream, "%04d-%02d-%02d %02d:%02d:%02d ",
674                                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
675                                tp->tm_hour, tp->tm_min, tp->tm_sec );
676         }
677       if (with_prefix || force_prefixes)
678         es_fputs_unlocked (prefix_buffer, logstream);
679       if (with_pid || force_prefixes)
680         {
681           unsigned long pidsuf;
682           int pidfmt;
683
684           if (get_pid_suffix_cb && (pidfmt=get_pid_suffix_cb (&pidsuf)))
685             es_fprintf_unlocked (logstream, pidfmt == 1? "[%u.%lu]":"[%u.%lx]",
686                                  (unsigned int)getpid (), pidsuf);
687           else
688             es_fprintf_unlocked (logstream, "[%u]", (unsigned int)getpid ());
689         }
690       if (!with_time || force_prefixes)
691         es_putc_unlocked (':', logstream);
692       /* A leading backspace suppresses the extra space so that we can
693          correctly output, programname, filename and linenumber. */
694       if (fmt && *fmt == '\b')
695         fmt++;
696       else
697         es_putc_unlocked (' ', logstream);
698     }
699
700   switch (level)
701     {
702     case GPGRT_LOG_BEGIN: break;
703     case GPGRT_LOG_CONT: break;
704     case GPGRT_LOG_INFO: break;
705     case GPGRT_LOG_WARN: break;
706     case GPGRT_LOG_ERROR: break;
707     case GPGRT_LOG_FATAL: es_fputs_unlocked ("Fatal: ",logstream ); break;
708     case GPGRT_LOG_BUG:   es_fputs_unlocked ("Ohhhh jeeee: ", logstream); break;
709     case GPGRT_LOG_DEBUG: es_fputs_unlocked ("DBG: ", logstream ); break;
710     default:
711       es_fprintf_unlocked (logstream,"[Unknown log level %d]: ", level);
712       break;
713     }
714
715   if (fmt)
716     {
717       if (ignore_arg_ptr)
718         { /* This is used by log_string and comes with the extra
719            * feature that after a LF the next line is indent at the
720            * length of the prefix.  Note that we do not yet include
721            * the length of the timestamp and pid in the indent
722            * computation.  */
723           const char *p, *pend;
724
725           for (p = fmt; (pend = strchr (p, '\n')); p = pend+1)
726             es_fprintf_unlocked (logstream, "%*s%.*s",
727                                  (int)((p != fmt
728                                         && (with_prefix || force_prefixes))
729                                        ?strlen (prefix_buffer)+2:0), "",
730                                  (int)(pend - p)+1, p);
731           es_fputs_unlocked (p, logstream);
732         }
733       else
734         es_vfprintf_unlocked (logstream, fmt, arg_ptr);
735       if (*fmt && fmt[strlen(fmt)-1] != '\n')
736         missing_lf = 1;
737     }
738
739   if (level == GPGRT_LOG_FATAL)
740     {
741       if (missing_lf)
742         es_putc_unlocked ('\n', logstream);
743       es_funlockfile (logstream);
744       exit (2);
745     }
746   else if (level == GPGRT_LOG_BUG)
747     {
748       if (missing_lf)
749         es_putc_unlocked ('\n', logstream );
750       es_funlockfile (logstream);
751       /* Using backtrace requires a configure test and to pass
752        * -rdynamic to gcc.  Thus we do not enable it now.  */
753       /* { */
754       /*   void *btbuf[20]; */
755       /*   int btidx, btlen; */
756       /*   char **btstr; */
757
758       /*   btlen = backtrace (btbuf, DIM (btbuf)); */
759       /*   btstr = backtrace_symbols (btbuf, btlen); */
760       /*   if (btstr) */
761       /*     for (btidx=0; btidx < btlen; btidx++) */
762       /*       log_debug ("[%d] %s\n", btidx, btstr[btidx]); */
763       /* } */
764       abort ();
765     }
766   else
767     es_funlockfile (logstream);
768 }
769
770
771 void
772 log_log (int level, const char *fmt, ...)
773 {
774   va_list arg_ptr ;
775
776   va_start (arg_ptr, fmt) ;
777   do_logv (level, 0, fmt, arg_ptr);
778   va_end (arg_ptr);
779 }
780
781
782 void
783 log_logv (int level, const char *fmt, va_list arg_ptr)
784 {
785   do_logv (level, 0, fmt, arg_ptr);
786 }
787
788
789 static void
790 do_log_ignore_arg (int level, const char *str, ...)
791 {
792   va_list arg_ptr;
793   va_start (arg_ptr, str);
794   do_logv (level, 1, str, arg_ptr);
795   va_end (arg_ptr);
796 }
797
798
799 /* Log STRING at LEVEL but indent from the second line on by the
800  * length of the prefix.  */
801 void
802 log_string (int level, const char *string)
803 {
804   /* We need a dummy arg_ptr, but there is no portable way to create
805    * one.  So we call the do_logv function through a variadic wrapper. */
806   do_log_ignore_arg (level, string);
807 }
808
809
810 void
811 log_info (const char *fmt, ...)
812 {
813   va_list arg_ptr ;
814
815   va_start (arg_ptr, fmt);
816   do_logv (GPGRT_LOG_INFO, 0, fmt, arg_ptr);
817   va_end (arg_ptr);
818 }
819
820
821 void
822 log_error (const char *fmt, ...)
823 {
824   va_list arg_ptr ;
825
826   va_start (arg_ptr, fmt);
827   do_logv (GPGRT_LOG_ERROR, 0, fmt, arg_ptr);
828   va_end (arg_ptr);
829   /* Protect against counter overflow.  */
830   if (errorcount < 30000)
831     errorcount++;
832 }
833
834
835 void
836 log_fatal (const char *fmt, ...)
837 {
838   va_list arg_ptr ;
839
840   va_start (arg_ptr, fmt);
841   do_logv (GPGRT_LOG_FATAL, 0, fmt, arg_ptr);
842   va_end (arg_ptr);
843   abort (); /* Never called; just to make the compiler happy.  */
844 }
845
846
847 void
848 log_bug (const char *fmt, ...)
849 {
850   va_list arg_ptr ;
851
852   va_start (arg_ptr, fmt);
853   do_logv (GPGRT_LOG_BUG, 0, fmt, arg_ptr);
854   va_end (arg_ptr);
855   abort (); /* Never called; just to make the compiler happy.  */
856 }
857
858
859 void
860 log_debug (const char *fmt, ...)
861 {
862   va_list arg_ptr ;
863
864   va_start (arg_ptr, fmt);
865   do_logv (GPGRT_LOG_DEBUG, 0, fmt, arg_ptr);
866   va_end (arg_ptr);
867 }
868
869
870 void
871 log_printf (const char *fmt, ...)
872 {
873   va_list arg_ptr;
874
875   va_start (arg_ptr, fmt);
876   do_logv (fmt ? GPGRT_LOG_CONT : GPGRT_LOG_BEGIN, 0, fmt, arg_ptr);
877   va_end (arg_ptr);
878 }
879
880
881 /* Flush the log - this is useful to make sure that the trailing
882    linefeed has been printed.  */
883 void
884 log_flush (void)
885 {
886   do_log_ignore_arg (GPGRT_LOG_CONT, NULL);
887 }
888
889
890 /* Print a hexdump of BUFFER.  With TEXT of NULL print just the raw
891    dump, with TEXT just an empty string, print a trailing linefeed,
892    otherwise print an entire debug line. */
893 void
894 log_printhex (const char *text, const void *buffer, size_t length)
895 {
896   if (text && *text)
897     log_debug ("%s ", text);
898   if (length)
899     {
900       const unsigned char *p = buffer;
901       log_printf ("%02X", *p);
902       for (length--, p++; length--; p++)
903         log_printf (" %02X", *p);
904     }
905   if (text)
906     log_printf ("\n");
907 }
908
909
910 /*
911 void
912 log_printcanon () {}
913 is found in sexputils.c
914 */
915
916 /*
917 void
918 log_printsexp () {}
919 is found in sexputils.c
920 */
921
922
923 void
924 log_clock (const char *string)
925 {
926 #if 0
927   static unsigned long long initial;
928   struct timespec tv;
929   unsigned long long now;
930
931   if (clock_gettime (CLOCK_REALTIME, &tv))
932     {
933       log_debug ("error getting the realtime clock value\n");
934       return;
935     }
936   now = tv.tv_sec * 1000000000ull;
937   now += tv.tv_nsec;
938
939   if (!initial)
940     initial = now;
941
942   log_debug ("[%6llu] %s", (now - initial)/1000, string);
943 #else
944   /* You need to link with -ltr to enable the above code.  */
945   log_debug ("[not enabled in the source] %s", string);
946 #endif
947 }
948
949
950 #ifdef GPGRT_HAVE_MACRO_FUNCTION
951 void
952 bug_at( const char *file, int line, const char *func )
953 {
954   log_log (GPGRT_LOG_BUG, "... this is a bug (%s:%d:%s)\n", file, line, func);
955   abort (); /* Never called; just to make the compiler happy.  */
956 }
957 #else /*!GPGRT_HAVE_MACRO_FUNCTION*/
958 void
959 bug_at( const char *file, int line )
960 {
961   log_log (GPGRT_LOG_BUG, "you found a bug ... (%s:%d)\n", file, line);
962   abort (); /* Never called; just to make the compiler happy.  */
963 }
964 #endif /*!GPGRT_HAVE_MACRO_FUNCTION*/
965
966
967 #ifdef GPGRT_HAVE_MACRO_FUNCTION
968 void
969 _log_assert (const char *expr, const char *file, int line, const char *func)
970 {
971   log_log (GPGRT_LOG_BUG, "Assertion \"%s\" in %s failed (%s:%d)\n",
972            expr, func, file, line);
973   abort (); /* Never called; just to make the compiler happy.  */
974 }
975 #else /*!GPGRT_HAVE_MACRO_FUNCTION*/
976 void
977 _log_assert (const char *expr, const char *file, int line)
978 {
979   log_log (GPGRT_LOG_BUG, "Assertion \"%s\" failed (%s:%d)\n",
980            file, line, func);
981   abort (); /* Never called; just to make the compiler happy.  */
982 }
983 #endif /*!GPGRT_HAVE_MACRO_FUNCTION*/