log.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. static int debug;
  25. static int verbose;
  26. const char *log_procname;
  27. void log_init(int, int);
  28. void log_procinit(const char *);
  29. void log_setverbose(int);
  30. int log_getverbose(void);
  31. void log_warn(const char *, ...)
  32. __attribute__((__format__ (printf, 1, 2)));
  33. void log_warnx(const char *, ...)
  34. __attribute__((__format__ (printf, 1, 2)));
  35. void log_info(const char *, ...)
  36. __attribute__((__format__ (printf, 1, 2)));
  37. void log_debug(const char *, ...)
  38. __attribute__((__format__ (printf, 1, 2)));
  39. void logit(int, const char *, ...)
  40. __attribute__((__format__ (printf, 2, 3)));
  41. void vlog(int, const char *, va_list)
  42. __attribute__((__format__ (printf, 2, 0)));
  43. __dead void fatal(const char *, ...)
  44. __attribute__((__format__ (printf, 1, 2)));
  45. __dead void fatalx(const char *, ...)
  46. __attribute__((__format__ (printf, 1, 2)));
  47. void
  48. log_init(int n_debug, int facility)
  49. {
  50. debug = n_debug;
  51. verbose = n_debug;
  52. log_procinit(getprogname());
  53. if (!debug)
  54. openlog(getprogname(), LOG_PID | LOG_NDELAY, facility);
  55. tzset();
  56. }
  57. void
  58. log_procinit(const char *procname)
  59. {
  60. if (procname != NULL)
  61. log_procname = procname;
  62. }
  63. void
  64. log_setverbose(int v)
  65. {
  66. verbose = v;
  67. }
  68. int
  69. log_getverbose(void)
  70. {
  71. return (verbose);
  72. }
  73. void
  74. logit(int pri, const char *fmt, ...)
  75. {
  76. va_list ap;
  77. va_start(ap, fmt);
  78. vlog(pri, fmt, ap);
  79. va_end(ap);
  80. }
  81. void
  82. vlog(int pri, const char *fmt, va_list ap)
  83. {
  84. char *nfmt;
  85. int saved_errno = errno;
  86. if (debug) {
  87. /* best effort in out of mem situations */
  88. if (asprintf(&nfmt, "%s\n", fmt) == -1) {
  89. vfprintf(stderr, fmt, ap);
  90. fprintf(stderr, "\n");
  91. } else {
  92. vfprintf(stderr, nfmt, ap);
  93. free(nfmt);
  94. }
  95. fflush(stderr);
  96. } else
  97. vsyslog(pri, fmt, ap);
  98. errno = saved_errno;
  99. }
  100. void
  101. log_warn(const char *emsg, ...)
  102. {
  103. char *nfmt;
  104. va_list ap;
  105. int saved_errno = errno;
  106. /* best effort to even work in out of memory situations */
  107. if (emsg == NULL)
  108. logit(LOG_ERR, "%s", strerror(saved_errno));
  109. else {
  110. va_start(ap, emsg);
  111. if (asprintf(&nfmt, "%s: %s", emsg,
  112. strerror(saved_errno)) == -1) {
  113. /* we tried it... */
  114. vlog(LOG_ERR, emsg, ap);
  115. logit(LOG_ERR, "%s", strerror(saved_errno));
  116. } else {
  117. vlog(LOG_ERR, nfmt, ap);
  118. free(nfmt);
  119. }
  120. va_end(ap);
  121. }
  122. errno = saved_errno;
  123. }
  124. void
  125. log_warnx(const char *emsg, ...)
  126. {
  127. va_list ap;
  128. va_start(ap, emsg);
  129. vlog(LOG_ERR, emsg, ap);
  130. va_end(ap);
  131. }
  132. void
  133. log_info(const char *emsg, ...)
  134. {
  135. va_list ap;
  136. va_start(ap, emsg);
  137. vlog(LOG_INFO, emsg, ap);
  138. va_end(ap);
  139. }
  140. void
  141. log_debug(const char *emsg, ...)
  142. {
  143. va_list ap;
  144. if (verbose > 1) {
  145. va_start(ap, emsg);
  146. vlog(LOG_DEBUG, emsg, ap);
  147. va_end(ap);
  148. }
  149. }
  150. static void
  151. vfatalc(int code, const char *emsg, va_list ap)
  152. {
  153. static char s[BUFSIZ];
  154. const char *sep;
  155. if (emsg != NULL) {
  156. (void)vsnprintf(s, sizeof(s), emsg, ap);
  157. sep = ": ";
  158. } else {
  159. s[0] = '\0';
  160. sep = "";
  161. }
  162. if (code)
  163. logit(LOG_CRIT, "%s: %s%s%s",
  164. log_procname, s, sep, strerror(code));
  165. else
  166. logit(LOG_CRIT, "%s%s%s", log_procname, sep, s);
  167. }
  168. void
  169. fatal(const char *emsg, ...)
  170. {
  171. va_list ap;
  172. va_start(ap, emsg);
  173. vfatalc(errno, emsg, ap);
  174. va_end(ap);
  175. exit(1);
  176. }
  177. void
  178. fatalx(const char *emsg, ...)
  179. {
  180. va_list ap;
  181. va_start(ap, emsg);
  182. vfatalc(0, emsg, ap);
  183. va_end(ap);
  184. exit(1);
  185. }