log.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /* $OpenBSD: log.c,v 1.17 2017/03/21 12:06:56 bluhm Exp $ */
  2. /*
  3. * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <stdarg.h>
  20. #include <string.h>
  21. #include <syslog.h>
  22. #include <errno.h>
  23. #include <time.h>
  24. #include "log.h"
  25. static int dest;
  26. static int verbose;
  27. const char *log_procname;
  28. void
  29. log_init(int n_dest, int n_verbose, int facility)
  30. {
  31. dest = n_dest;
  32. verbose = n_verbose;
  33. log_procinit(getprogname());
  34. if (dest & LOG_TO_SYSLOG)
  35. openlog(getprogname(), LOG_PID | LOG_NDELAY, facility);
  36. tzset();
  37. }
  38. void
  39. log_procinit(const char *procname)
  40. {
  41. if (procname != NULL)
  42. log_procname = procname;
  43. }
  44. void
  45. log_setverbose(int v)
  46. {
  47. verbose = v;
  48. }
  49. int
  50. log_getverbose(void)
  51. {
  52. return (verbose);
  53. }
  54. void
  55. logit(int pri, const char *fmt, ...)
  56. {
  57. va_list ap;
  58. va_start(ap, fmt);
  59. vlog(pri, fmt, ap);
  60. va_end(ap);
  61. }
  62. void
  63. vlog(int pri, const char *fmt, va_list ap)
  64. {
  65. char *nfmt;
  66. int saved_errno = errno;
  67. va_list ap2;
  68. va_copy(ap2, ap);
  69. if (dest & LOG_TO_STDERR) {
  70. /* best effort in out of mem situations */
  71. if (asprintf(&nfmt, "%s\n", fmt) == -1) {
  72. vfprintf(stderr, fmt, ap);
  73. fprintf(stderr, "\n");
  74. } else {
  75. vfprintf(stderr, nfmt, ap);
  76. free(nfmt);
  77. }
  78. fflush(stderr);
  79. }
  80. if (dest & LOG_TO_SYSLOG)
  81. vsyslog(pri, fmt, ap2);
  82. va_end(ap2);
  83. errno = saved_errno;
  84. }
  85. void
  86. log_warn(const char *emsg, ...)
  87. {
  88. char *nfmt;
  89. va_list ap;
  90. int saved_errno = errno;
  91. /* best effort to even work in out of memory situations */
  92. if (emsg == NULL)
  93. logit(LOG_ERR, "%s", strerror(saved_errno));
  94. else {
  95. va_start(ap, emsg);
  96. if (asprintf(&nfmt, "%s: %s", emsg,
  97. strerror(saved_errno)) == -1) {
  98. /* we tried it... */
  99. vlog(LOG_ERR, emsg, ap);
  100. logit(LOG_ERR, "%s", strerror(saved_errno));
  101. } else {
  102. vlog(LOG_ERR, nfmt, ap);
  103. free(nfmt);
  104. }
  105. va_end(ap);
  106. }
  107. errno = saved_errno;
  108. }
  109. void
  110. log_warnx(const char *emsg, ...)
  111. {
  112. va_list ap;
  113. va_start(ap, emsg);
  114. vlog(LOG_ERR, emsg, ap);
  115. va_end(ap);
  116. }
  117. void
  118. log_info(const char *emsg, ...)
  119. {
  120. va_list ap;
  121. va_start(ap, emsg);
  122. vlog(LOG_INFO, emsg, ap);
  123. va_end(ap);
  124. }
  125. void
  126. log_debug(const char *emsg, ...)
  127. {
  128. va_list ap;
  129. if (verbose > 1) {
  130. va_start(ap, emsg);
  131. vlog(LOG_DEBUG, emsg, ap);
  132. va_end(ap);
  133. }
  134. }
  135. static void
  136. vfatalc(int code, const char *emsg, va_list ap)
  137. {
  138. static char s[BUFSIZ];
  139. const char *sep;
  140. if (emsg != NULL) {
  141. (void)vsnprintf(s, sizeof(s), emsg, ap);
  142. sep = ": ";
  143. } else {
  144. s[0] = '\0';
  145. sep = "";
  146. }
  147. if (code)
  148. logit(LOG_CRIT, "%s: %s%s%s",
  149. log_procname, s, sep, strerror(code));
  150. else
  151. logit(LOG_CRIT, "%s%s%s", log_procname, sep, s);
  152. }
  153. void
  154. fatal(const char *emsg, ...)
  155. {
  156. va_list ap;
  157. va_start(ap, emsg);
  158. vfatalc(errno, emsg, ap);
  159. va_end(ap);
  160. exit(1);
  161. }
  162. void
  163. fatalx(const char *emsg, ...)
  164. {
  165. va_list ap;
  166. va_start(ap, emsg);
  167. vfatalc(0, emsg, ap);
  168. va_end(ap);
  169. exit(1);
  170. }