Postfix3.3.1
msg_syslog.c
[詳解]
1 /*++
2 /* NAME
3 /* msg_syslog 3
4 /* SUMMARY
5 /* direct diagnostics to syslog daemon
6 /* SYNOPSIS
7 /* #include <msg_syslog.h>
8 /*
9 /* void msg_syslog_init(progname, log_opt, facility)
10 /* const char *progname;
11 /* int log_opt;
12 /* int facility;
13 /*
14 /* int msg_syslog_facility(facility_name)
15 /* const char *facility_name;
16 /* DESCRIPTION
17 /* This module implements support to report msg(3) diagnostics
18 /* via the syslog daemon.
19 /*
20 /* msg_syslog_init() is a wrapper around the openlog(3) routine
21 /* that directs subsequent msg(3) output to the syslog daemon.
22 /*
23 /* msg_syslog_facility() is a helper routine that overrides the
24 /* logging facility that is specified with msg_syslog_init().
25 /* The result is zero in case of an unknown facility name.
26 /* SEE ALSO
27 /* syslog(3) syslog library
28 /* msg(3) diagnostics module
29 /* BUGS
30 /* Output records are truncated to 2000 characters. This is done in
31 /* order to defend against a buffer overflow problem in some
32 /* implementations of the syslog() library routine.
33 /* LICENSE
34 /* .ad
35 /* .fi
36 /* The Secure Mailer license must be distributed with this software.
37 /* AUTHOR(S)
38 /* Wietse Venema
39 /* IBM T.J. Watson Research
40 /* P.O. Box 704
41 /* Yorktown Heights, NY 10598, USA
42 /*
43 /* Wietse Venema
44 /* Google, Inc.
45 /* 111 8th Avenue
46 /* New York, NY 10011, USA
47 /*--*/
48 
49 /* System libraries. */
50 
51 #include <sys_defs.h>
52 #include <stdlib.h> /* 44BSD stdarg.h uses abort() */
53 #include <stdarg.h>
54 #include <errno.h>
55 #include <syslog.h>
56 #include <string.h>
57 #include <time.h>
58 
59 /* Application-specific. */
60 
61 #include "vstring.h"
62 #include "stringops.h"
63 #include "msg.h"
64 #include "msg_output.h"
65 #include "msg_syslog.h"
66 #include "safe.h"
67 
68  /*
69  * Stay a little below the 2048-byte limit of older syslog()
70  * implementations.
71  */
72 #define MSG_SYSLOG_RECLEN 2000
73 
74 struct facility_list {
75  const char *name;
76  int facility;
77 };
78 
79 static struct facility_list facility_list[] = {
80 #ifdef LOG_AUTH
81  "auth", LOG_AUTH,
82 #endif
83 #ifdef LOG_AUTHPRIV
84  "authpriv", LOG_AUTHPRIV,
85 #endif
86 #ifdef LOG_CRON
87  "cron", LOG_CRON,
88 #endif
89 #ifdef LOG_DAEMON
90  "daemon", LOG_DAEMON,
91 #endif
92 #ifdef LOG_FTP
93  "ftp", LOG_FTP,
94 #endif
95 #ifdef LOG_KERN
96  "kern", LOG_KERN,
97 #endif
98 #ifdef LOG_LPR
99  "lpr", LOG_LPR,
100 #endif
101 #ifdef LOG_MAIL
102  "mail", LOG_MAIL,
103 #endif
104 #ifdef LOG_NEWS
105  "news", LOG_NEWS,
106 #endif
107 #ifdef LOG_SECURITY
108  "security", LOG_SECURITY,
109 #endif
110 #ifdef LOG_SYSLOG
111  "syslog", LOG_SYSLOG,
112 #endif
113 #ifdef LOG_USER
114  "user", LOG_USER,
115 #endif
116 #ifdef LOG_UUCP
117  "uucp", LOG_UUCP,
118 #endif
119 #ifdef LOG_LOCAL0
120  "local0", LOG_LOCAL0,
121 #endif
122 #ifdef LOG_LOCAL1
123  "local1", LOG_LOCAL1,
124 #endif
125 #ifdef LOG_LOCAL2
126  "local2", LOG_LOCAL2,
127 #endif
128 #ifdef LOG_LOCAL3
129  "local3", LOG_LOCAL3,
130 #endif
131 #ifdef LOG_LOCAL4
132  "local4", LOG_LOCAL4,
133 #endif
134 #ifdef LOG_LOCAL5
135  "local5", LOG_LOCAL5,
136 #endif
137 #ifdef LOG_LOCAL6
138  "local6", LOG_LOCAL6,
139 #endif
140 #ifdef LOG_LOCAL7
141  "local7", LOG_LOCAL7,
142 #endif
143  0,
144 };
145 
146 static int syslog_facility;
147 
148 /* msg_syslog_print - log info to syslog daemon */
149 
150 static void msg_syslog_print(int level, const char *text)
151 {
152  static int log_level[] = {
153  LOG_INFO, LOG_WARNING, LOG_ERR, LOG_CRIT, LOG_CRIT,
154  };
155  static char *severity_name[] = {
156  "info", "warning", "error", "fatal", "panic",
157  };
158 
159  if (level < 0 || level >= (int) (sizeof(log_level) / sizeof(log_level[0])))
160  msg_panic("msg_syslog_print: invalid severity level: %d", level);
161 
162  if (level == MSG_INFO) {
163  syslog(syslog_facility | log_level[level], "%.*s",
164  (int) MSG_SYSLOG_RECLEN, text);
165  } else {
166  syslog(syslog_facility | log_level[level], "%s: %.*s",
167  severity_name[level], (int) MSG_SYSLOG_RECLEN, text);
168  }
169 }
170 
171 /* msg_syslog_init - initialize */
172 
173 void msg_syslog_init(const char *name, int logopt, int facility)
174 {
175  static int first_call = 1;
176  extern char **environ;
177 
178  /*
179  * XXX If this program is set-gid, then TZ must not be trusted. This
180  * scrubbing code is in the wrong place.
181  */
182  if (unsafe())
183  while (getenv("TZ")) /* There may be multiple. */
184  if (unsetenv("TZ") < 0) { /* Desperate measures. */
185  environ[0] = 0;
186  msg_fatal("unsetenv: %m");
187  }
188  tzset();
189  openlog(name, LOG_NDELAY | logopt, facility);
190  if (first_call) {
191  first_call = 0;
192  msg_output(msg_syslog_print);
193  }
194 }
195 
196 /* msg_syslog_facility - set logging facility by name */
197 
198 int msg_syslog_facility(const char *facility_name)
199 {
200  struct facility_list *fnp;
201 
202  for (fnp = facility_list; fnp->name; ++fnp) {
203  if (!strcmp(fnp->name, facility_name)) {
204  syslog_facility = fnp->facility;
205  return (1);
206  }
207  }
208  return 0;
209 }
210 
211 #ifdef TEST
212 
213  /*
214  * Proof-of-concept program to test the syslogging diagnostics interface
215  *
216  * Usage: msg_syslog_test text...
217  */
218 
219 int main(int argc, char **argv)
220 {
221  VSTRING *vp = vstring_alloc(256);
222 
223  msg_syslog_init(argv[0], LOG_PID, LOG_MAIL);
224  if (argc < 2)
225  msg_error("usage: %s text to be logged", argv[0]);
226  while (--argc && *++argv) {
227  vstring_strcat(vp, *argv);
228  if (argv[1])
229  vstring_strcat(vp, " ");
230  }
231  msg_warn("static text");
232  msg_warn("dynamic text: >%s<", vstring_str(vp));
233  msg_warn("dynamic numeric: >%d<", 42);
234  msg_warn("error text: >%m<");
235  msg_warn("dynamic: >%s<: error: >%m<", vstring_str(vp));
236  vstring_free(vp);
237  return (0);
238 }
239 
240 #endif
void msg_error(const char *fmt,...)
Definition: msg.c:231
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
void msg_output(MSG_OUTPUT_FN output_fn)
Definition: msg_output.c:115
#define vstring_str(vp)
Definition: vstring.h:71
int main(int argc, char **argv)
Definition: anvil.c:1010
const char * name
Definition: msg_syslog.c:75
int unsafe(void)
Definition: unsafe.c:59
#define MSG_INFO
Definition: msg_output.h:28
void msg_warn(const char *fmt,...)
Definition: msg.c:215
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
void msg_syslog_init(const char *name, int logopt, int facility)
Definition: msg_syslog.c:173
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
VSTRING * vstring_strcat(VSTRING *vp, const char *src)
Definition: vstring.c:459
#define MSG_SYSLOG_RECLEN
Definition: msg_syslog.c:72
int msg_syslog_facility(const char *facility_name)
Definition: msg_syslog.c:198