1 /* logging.c - Useful logging functions
2 * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
3 * 2009, 2010 Free Software Foundation, Inc.
5 * This file is part of JNLIB, which is a subsystem of GnuPG.
7 * JNLIB is free software; you can redistribute it and/or modify it
8 * under the terms of either
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.
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.
20 * or both in parallel, as here.
22 * JNLIB 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.
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/>.
41 #include <sys/types.h>
43 #ifdef HAVE_W32_SYSTEM
44 # ifdef HAVE_WINSOCK2_H
45 # include <winsock2.h>
48 #else /*!HAVE_W32_SYSTEM*/
49 # include <sys/socket.h>
51 # include <netinet/in.h>
52 # include <arpa/inet.h>
53 #endif /*!HAVE_W32_SYSTEM*/
59 #define JNLIB_NEED_LOG_LOGV 1
60 #define JNLIB_NEED_AFLOCAL 1
61 #include "libjnlib-config.h"
64 #ifdef HAVE_W32_SYSTEM
65 # define S_IRGRP S_IRUSR
66 # define S_IROTH S_IRUSR
67 # define S_IWGRP S_IWUSR
68 # define S_IWOTH S_IWUSR
72 #ifdef HAVE_W32CE_SYSTEM
73 # define isatty(a) (0)
77 #if defined (AF_INET6) && defined(PF_INET) \
78 && defined (INET6_ADDRSTRLEN) && defined(HAVE_INET_PTON)
83 # define EAFNOSUPPORT EINVAL
85 #ifndef INADDR_NONE /* Slowaris is missing that. */
86 #define INADDR_NONE ((unsigned long)(-1))
87 #endif /*INADDR_NONE*/
89 #ifdef HAVE_W32_SYSTEM
90 #define sock_close(a) closesocket(a)
92 #define sock_close(a) close(a)
96 static estream_t logstream;
97 static int log_socket = -1;
98 static char prefix_buffer[80];
100 static int with_prefix;
102 #ifdef HAVE_W32_SYSTEM
103 static int no_registry;
105 static int (*get_pid_suffix_cb)(unsigned long *r_value);
106 static int running_detached;
107 static int force_prefixes;
109 static int missing_lf;
110 static int errorcount;
114 log_get_errorcount (int clear)
123 log_inc_errorcount (void)
129 /* The following 3 functions are used by es_fopencookie to write logs
137 #ifdef HAVE_W32CE_SYSTEM
144 /* Write NBYTES of BUFFER to file descriptor FD. */
146 writen (int fd, const void *buffer, size_t nbytes, int is_socket)
148 const char *buf = buffer;
149 size_t nleft = nbytes;
151 #ifndef HAVE_W32_SYSTEM
152 (void)is_socket; /* Not required. */
157 #ifdef HAVE_W32_SYSTEM
159 nwritten = send (fd, buf, nleft, 0);
162 nwritten = write (fd, buf, nleft);
164 if (nwritten < 0 && errno == EINTR)
169 buf = buf + nwritten;
176 /* Returns true if STR represents a valid port number in decimal
177 notation and no garbage is following. */
179 parse_portno (const char *str, unsigned short *r_port)
183 for (value=0; *str && (*str >= '0' && *str <= '9'); str++)
185 value = value * 10 + (*str - '0');
198 fun_writer (void *cookie_arg, const void *buffer, size_t size)
200 struct fun_cookie_s *cookie = cookie_arg;
202 /* FIXME: Use only estream with a callback for socket writing. This
203 avoids the ugly mix of fd and estream code. */
205 /* Note that we always try to reconnect to the socket but print
206 error messages only the first time an error occured. If
207 RUNNING_DETACHED is set we don't fall back to stderr and even do
208 not print any error messages. This is needed because detached
209 processes often close stderr and by writing to file descriptor 2
210 we might send the log message to a file not intended for logging
211 (e.g. a pipe or network connection). */
212 if (cookie->want_socket && cookie->fd == -1)
215 struct sockaddr_in6 srvr_addr_in6;
217 struct sockaddr_in srvr_addr_in;
218 #ifndef HAVE_W32_SYSTEM
219 struct sockaddr_un srvr_addr_un;
222 struct sockaddr *srvr_addr = NULL;
223 unsigned short port = 0;
226 const char *name = cookie->name;
228 /* Not yet open or meanwhile closed due to an error. */
229 cookie->is_socket = 0;
231 /* Check whether this is a TCP socket or a local socket. */
232 if (!strncmp (name, "tcp://", 6) && name[6])
238 #ifndef HAVE_W32_SYSTEM
239 else if (!strncmp (name, "socket://", 9) && name[9])
245 #ifdef HAVE_W32_SYSTEM
248 memset (&srvr_addr, 0, sizeof srvr_addr);
249 srvr_addr_un.sun_family = af;
250 strncpy (srvr_addr_un.sun_path,
251 name, sizeof (srvr_addr_un.sun_path)-1);
252 srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path)-1] = 0;
253 srvr_addr = (struct sockaddr *)&srvr_addr_un;
254 addrlen = SUN_LEN (&srvr_addr_un);
260 #ifdef HAVE_INET_PTON
261 void *addrbuf = NULL;
262 #endif /*HAVE_INET_PTON*/
264 addrstr = jnlib_malloc (strlen (name) + 1);
266 addrlen = 0; /* This indicates an error. */
267 else if (*name == '[')
269 /* Check for IPv6 literal address. */
270 strcpy (addrstr, name+1);
271 p = strchr (addrstr, ']');
272 if (!p || p[1] != ':' || !parse_portno (p+2, &port))
274 jnlib_set_errno (EINVAL);
283 memset (&srvr_addr_in6, 0, sizeof srvr_addr_in6);
284 srvr_addr_in6.sin6_family = af;
285 srvr_addr_in6.sin6_port = htons (port);
286 #ifdef HAVE_INET_PTON
287 addrbuf = &srvr_addr_in6.sin6_addr;
288 #endif /*HAVE_INET_PTON*/
289 srvr_addr = (struct sockaddr *)&srvr_addr_in6;
290 addrlen = sizeof srvr_addr_in6;
292 jnlib_set_errno (EAFNOSUPPORT);
299 /* Check for IPv4 literal address. */
300 strcpy (addrstr, name);
301 p = strchr (addrstr, ':');
302 if (!p || !parse_portno (p+1, &port))
304 jnlib_set_errno (EINVAL);
310 memset (&srvr_addr_in, 0, sizeof srvr_addr_in);
311 srvr_addr_in.sin_family = af;
312 srvr_addr_in.sin_port = htons (port);
313 #ifdef HAVE_INET_PTON
314 addrbuf = &srvr_addr_in.sin_addr;
315 #endif /*HAVE_INET_PTON*/
316 srvr_addr = (struct sockaddr *)&srvr_addr_in;
317 addrlen = sizeof srvr_addr_in;
323 #ifdef HAVE_INET_PTON
324 if (inet_pton (af, addrstr, addrbuf) != 1)
326 #else /*!HAVE_INET_PTON*/
327 /* We need to use the old function. If we are here v6
328 support isn't enabled anyway and thus we can do fine
329 without. Note that Windows has a compatible inet_pton
330 function named inetPton, but only since Vista. */
331 srvr_addr_in.sin_addr.s_addr = inet_addr (addrstr);
332 if (srvr_addr_in.sin_addr.s_addr == INADDR_NONE)
334 #endif /*!HAVE_INET_PTON*/
337 jnlib_free (addrstr);
340 cookie->fd = addrlen? socket (pf, SOCK_STREAM, 0) : -1;
341 if (cookie->fd == -1)
343 if (!cookie->quiet && !running_detached
344 && isatty (es_fileno (es_stderr)))
345 es_fprintf (es_stderr, "failed to create socket for logging: %s\n",
350 if (connect (cookie->fd, srvr_addr, addrlen) == -1)
352 if (!cookie->quiet && !running_detached
353 && isatty (es_fileno (es_stderr)))
354 es_fprintf (es_stderr, "can't connect to '%s': %s\n",
355 cookie->name, strerror(errno));
356 sock_close (cookie->fd);
361 if (cookie->fd == -1)
363 if (!running_detached)
365 /* Due to all the problems with apps not running
366 detached but being called with stderr closed or used
367 for a different purposes, it does not make sense to
368 switch to stderr. We therefore disable it. */
371 /* fputs ("switching logging to stderr\n", stderr);*/
374 cookie->fd = -1; /*fileno (stderr);*/
377 else /* Connection has been established. */
380 cookie->is_socket = 1;
384 log_socket = cookie->fd;
385 if (cookie->fd != -1)
387 #ifdef HAVE_W32CE_SYSTEM
388 if (cookie->use_writefile)
392 WriteFile ((HANDLE)cookie->fd, buffer, size, &nwritten, NULL);
393 return (ssize_t)size; /* Okay. */
396 if (!writen (cookie->fd, buffer, size, cookie->is_socket))
397 return (ssize_t)size; /* Okay. */
400 if (!running_detached && cookie->fd != -1
401 && isatty (es_fileno (es_stderr)))
404 es_fprintf (es_stderr, "error writing to '%s': %s\n",
405 cookie->name, strerror(errno));
407 es_fprintf (es_stderr, "error writing to file descriptor %d: %s\n",
408 cookie->fd, strerror(errno));
410 if (cookie->is_socket && cookie->fd != -1)
412 sock_close (cookie->fd);
417 return (ssize_t)size;
422 fun_closer (void *cookie_arg)
424 struct fun_cookie_s *cookie = cookie_arg;
426 if (cookie->fd != -1 && cookie->fd != 2)
427 sock_close (cookie->fd);
434 /* Common function to either set the logging to a file or a file
437 set_file_fd (const char *name, int fd)
441 #ifdef HAVE_W32CE_SYSTEM
442 int use_writefile = 0;
444 struct fun_cookie_s *cookie;
446 /* Close an open log stream. */
449 es_fclose (logstream);
453 /* Figure out what kind of logging we want. */
454 if (name && !strcmp (name, "-"))
457 fd = es_fileno (es_stderr);
461 if (name && !strncmp (name, "tcp://", 6) && name[6])
463 #ifndef HAVE_W32_SYSTEM
464 else if (name && !strncmp (name, "socket://", 9) && name[9])
466 #endif /*HAVE_W32_SYSTEM*/
467 #ifdef HAVE_W32CE_SYSTEM
468 else if (name && !strcmp (name, "GPG2:"))
472 ActivateDevice (L"Drivers\\"GNUPG_NAME"_Log", 0);
473 /* Ignore a filename and write the debug output to the GPG2:
475 hd = CreateFile (L"GPG2:", GENERIC_WRITE,
476 FILE_SHARE_READ | FILE_SHARE_WRITE,
477 NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
478 fd = (hd == INVALID_HANDLE_VALUE)? -1 : (int)hd;
483 #endif /*HAVE_W32CE_SYSTEM*/
485 /* Setup a new stream. */
487 /* The xmalloc below is justified because we can expect that this
488 function is called only during initialization and there is no
489 easy way out of this error condition. */
490 cookie = jnlib_xmalloc (sizeof *cookie + (name? strlen (name):0));
491 strcpy (cookie->name, name? name:"");
493 cookie->is_socket = 0;
494 cookie->want_socket = want_socket;
495 #ifdef HAVE_W32CE_SYSTEM
496 cookie->use_writefile = use_writefile;
500 else if (want_socket)
505 cookie->fd = open (name, O_WRONLY|O_APPEND|O_CREAT,
506 (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH));
507 while (cookie->fd == -1 && errno == EINTR);
509 log_socket = cookie->fd;
512 es_cookie_io_functions_t io = { NULL };
513 io.func_write = fun_writer;
514 io.func_close = fun_closer;
516 fp = es_fopencookie (cookie, "w", io);
519 /* On error default to a stderr based estream. */
523 es_setvbuf (fp, NULL, _IOLBF, 0);
527 /* We always need to print the prefix and the pid for socket mode,
528 so that the server reading the socket can do something
530 force_prefixes = want_socket;
536 /* Set the file to write log to. The special names NULL and "-" may
537 be used to select stderr and names formatted like
538 "socket:///home/foo/mylogs" may be used to write the logging to the
539 socket "/home/foo/mylogs". If the connection to the socket fails
540 or a write error is detected, the function writes to stderr and
541 tries the next time again to connect the socket.
544 log_set_file (const char *name)
546 set_file_fd (name? name: "-", -1);
552 set_file_fd (NULL, fd);
557 log_set_pid_suffix_cb (int (*cb)(unsigned long *r_value))
559 get_pid_suffix_cb = cb;
564 log_set_prefix (const char *text, unsigned int flags)
568 strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1);
569 prefix_buffer[sizeof (prefix_buffer)-1] = 0;
572 with_prefix = (flags & JNLIB_LOG_WITH_PREFIX);
573 with_time = (flags & JNLIB_LOG_WITH_TIME);
574 with_pid = (flags & JNLIB_LOG_WITH_PID);
575 running_detached = (flags & JNLIB_LOG_RUN_DETACHED);
576 #ifdef HAVE_W32_SYSTEM
577 no_registry = (flags & JNLIB_LOG_NO_REGISTRY);
583 log_get_prefix (unsigned int *flags)
589 *flags |= JNLIB_LOG_WITH_PREFIX;
591 *flags |= JNLIB_LOG_WITH_TIME;
593 *flags |= JNLIB_LOG_WITH_PID;
594 if (running_detached)
595 *flags |= JNLIB_LOG_RUN_DETACHED;
596 #ifdef HAVE_W32_SYSTEM
598 *flags |= JNLIB_LOG_NO_REGISTRY;
601 return prefix_buffer;
604 /* This function returns true if the file descriptor FD is in use for
605 logging. This is preferable over a test using log_get_fd in that
606 it allows the logging code to use more then one file descriptor. */
612 int tmp = es_fileno (logstream);
613 if ( tmp != -1 && tmp == fd)
616 if (log_socket != -1 && log_socket == fd)
624 return logstream? es_fileno(logstream) : -1;
632 log_set_file (NULL); /* Make sure a log stream has been set. */
639 do_logv (int level, int ignore_arg_ptr, const char *fmt, va_list arg_ptr)
643 #ifdef HAVE_W32_SYSTEM
648 : read_w32_registry_string (NULL, GNUPG_REGISTRY_DIR,
650 log_set_file (tmp && *tmp? tmp : NULL);
653 log_set_file (NULL); /* Make sure a log stream has been set. */
658 es_flockfile (logstream);
659 if (missing_lf && level != JNLIB_LOG_CONT)
660 es_putc_unlocked ('\n', logstream );
663 if (level != JNLIB_LOG_CONT)
664 { /* Note this does not work for multiple line logging as we would
665 * need to print to a buffer first */
666 if (with_time && !force_prefixes)
669 time_t atime = time (NULL);
671 tp = localtime (&atime);
672 es_fprintf_unlocked (logstream, "%04d-%02d-%02d %02d:%02d:%02d ",
673 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
674 tp->tm_hour, tp->tm_min, tp->tm_sec );
676 if (with_prefix || force_prefixes)
677 es_fputs_unlocked (prefix_buffer, logstream);
678 if (with_pid || force_prefixes)
680 unsigned long pidsuf;
683 if (get_pid_suffix_cb && (pidfmt=get_pid_suffix_cb (&pidsuf)))
684 es_fprintf_unlocked (logstream, pidfmt == 1? "[%u.%lu]":"[%u.%lx]",
685 (unsigned int)getpid (), pidsuf);
687 es_fprintf_unlocked (logstream, "[%u]", (unsigned int)getpid ());
689 if (!with_time || force_prefixes)
690 es_putc_unlocked (':', logstream);
691 /* A leading backspace suppresses the extra space so that we can
692 correctly output, programname, filename and linenumber. */
693 if (fmt && *fmt == '\b')
696 es_putc_unlocked (' ', logstream);
701 case JNLIB_LOG_BEGIN: break;
702 case JNLIB_LOG_CONT: break;
703 case JNLIB_LOG_INFO: break;
704 case JNLIB_LOG_WARN: break;
705 case JNLIB_LOG_ERROR: break;
706 case JNLIB_LOG_FATAL: es_fputs_unlocked ("Fatal: ",logstream ); break;
707 case JNLIB_LOG_BUG: es_fputs_unlocked ("Ohhhh jeeee: ", logstream); break;
708 case JNLIB_LOG_DEBUG: es_fputs_unlocked ("DBG: ", logstream ); break;
710 es_fprintf_unlocked (logstream,"[Unknown log level %d]: ", level);
717 es_fputs_unlocked (fmt, logstream);
719 es_vfprintf_unlocked (logstream, fmt, arg_ptr);
720 if (*fmt && fmt[strlen(fmt)-1] != '\n')
724 if (level == JNLIB_LOG_FATAL)
727 es_putc_unlocked ('\n', logstream);
728 es_funlockfile (logstream);
731 else if (level == JNLIB_LOG_BUG)
734 es_putc_unlocked ('\n', logstream );
735 es_funlockfile (logstream);
739 es_funlockfile (logstream);
744 log_log (int level, const char *fmt, ...)
748 va_start (arg_ptr, fmt) ;
749 do_logv (level, 0, fmt, arg_ptr);
755 log_logv (int level, const char *fmt, va_list arg_ptr)
757 do_logv (level, 0, fmt, arg_ptr);
762 do_log_ignore_arg (int level, const char *str, ...)
765 va_start (arg_ptr, str);
766 do_logv (level, 1, str, arg_ptr);
772 log_string (int level, const char *string)
774 /* We need a dummy arg_ptr, but there is no portable way to create
775 one. So we call the do_logv function through a variadic wrapper.
776 MB: Why not just use "%s"? */
777 do_log_ignore_arg (level, string);
782 log_info (const char *fmt, ...)
786 va_start (arg_ptr, fmt);
787 do_logv (JNLIB_LOG_INFO, 0, fmt, arg_ptr);
793 log_error (const char *fmt, ...)
797 va_start (arg_ptr, fmt);
798 do_logv (JNLIB_LOG_ERROR, 0, fmt, arg_ptr);
800 /* Protect against counter overflow. */
801 if (errorcount < 30000)
807 log_fatal (const char *fmt, ...)
811 va_start (arg_ptr, fmt);
812 do_logv (JNLIB_LOG_FATAL, 0, fmt, arg_ptr);
814 abort (); /* Never called; just to make the compiler happy. */
819 log_bug (const char *fmt, ...)
823 va_start (arg_ptr, fmt);
824 do_logv (JNLIB_LOG_BUG, 0, fmt, arg_ptr);
826 abort (); /* Never called; just to make the compiler happy. */
831 log_debug (const char *fmt, ...)
835 va_start (arg_ptr, fmt);
836 do_logv (JNLIB_LOG_DEBUG, 0, fmt, arg_ptr);
842 log_printf (const char *fmt, ...)
846 va_start (arg_ptr, fmt);
847 do_logv (fmt ? JNLIB_LOG_CONT : JNLIB_LOG_BEGIN, 0, fmt, arg_ptr);
852 /* Flush the log - this is useful to make sure that the trailing
853 linefeed has been printed. */
857 do_log_ignore_arg (JNLIB_LOG_CONT, NULL);
861 /* Print a hexdump of BUFFER. With TEXT of NULL print just the raw
862 dump, with TEXT just an empty string, print a trailing linefeed,
863 otherwise print an entire debug line. */
865 log_printhex (const char *text, const void *buffer, size_t length)
868 log_debug ("%s ", text);
871 const unsigned char *p = buffer;
872 log_printf ("%02X", *p);
873 for (length--, p++; length--; p++)
874 log_printf (" %02X", *p);
884 is found in sexputils.c
890 is found in sexputils.c
895 log_clock (const char *string)
898 static unsigned long long initial;
900 unsigned long long now;
902 if (clock_gettime (CLOCK_REALTIME, &tv))
904 log_debug ("error getting the realtime clock value\n");
907 now = tv.tv_sec * 1000000000ull;
913 log_debug ("[%6llu] %s", (now - initial)/1000, string);
915 /* You need to link with -ltr to enable the above code. */
916 log_debug ("[not enabled in the source] %s", string);
921 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
923 bug_at( const char *file, int line, const char *func )
925 log_log (JNLIB_LOG_BUG, ("... this is a bug (%s:%d:%s)\n"), file, line, func);
926 abort (); /* Never called; just to make the compiler happy. */
930 bug_at( const char *file, int line )
932 log_log (JNLIB_LOG_BUG, _("you found a bug ... (%s:%d)\n"), file, line);
933 abort (); /* Never called; just to make the compiler happy. */