No empty .Rs/.Re
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / postlog / postlog.c
blob7dcc296dfa11271b895cf2ab315d2545b08ce14c
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* postlog 1
6 /* SUMMARY
7 /* Postfix-compatible logging utility
8 /* SYNOPSIS
9 /* .fi
10 /* .ad
11 /* \fBpostlog\fR [\fB-iv\fR] [\fB-c \fIconfig_dir\fR]
12 /* [\fB-p \fIpriority\fB] [\fB-t \fItag\fR] [\fItext...\fR]
13 /* DESCRIPTION
14 /* The \fBpostlog\fR(1) command implements a Postfix-compatible logging
15 /* interface for use in, for example, shell scripts.
17 /* By default, \fBpostlog\fR(1) logs the \fItext\fR given on the command
18 /* line as one record. If no \fItext\fR is specified on the command
19 /* line, \fBpostlog\fR(1) reads from standard input and logs each input
20 /* line as one record.
22 /* Logging is sent to \fBsyslogd\fR(8); when the standard error stream
23 /* is connected to a terminal, logging is sent there as well.
25 /* The following options are implemented:
26 /* .IP "\fB-c \fIconfig_dir\fR"
27 /* Read the \fBmain.cf\fR configuration file in the named directory
28 /* instead of the default configuration directory.
29 /* .IP \fB-i\fR
30 /* Include the process ID in the logging tag.
31 /* .IP "\fB-p \fIpriority\fR"
32 /* Specifies the logging severity: \fBinfo\fR (default), \fBwarn\fR,
33 /* \fBerror\fR, \fBfatal\fR, or \fBpanic\fR.
34 /* .IP "\fB-t \fItag\fR"
35 /* Specifies the logging tag, that is, the identifying name that
36 /* appears at the beginning of each logging record. A default tag
37 /* is used when none is specified.
38 /* .IP \fB-v\fR
39 /* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
40 /* options make the software increasingly verbose.
41 /* ENVIRONMENT
42 /* .ad
43 /* .fi
44 /* .IP MAIL_CONFIG
45 /* Directory with the \fBmain.cf\fR file.
46 /* CONFIGURATION PARAMETERS
47 /* .ad
48 /* .fi
49 /* The following \fBmain.cf\fR parameters are especially relevant to
50 /* this program.
52 /* The text below provides only a parameter summary. See
53 /* \fBpostconf\fR(5) for more details including examples.
54 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
55 /* The default location of the Postfix main.cf and master.cf
56 /* configuration files.
57 /* .IP "\fBsyslog_facility (mail)\fR"
58 /* The syslog facility of Postfix logging.
59 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
60 /* The mail system name that is prepended to the process name in syslog
61 /* records, so that "smtpd" becomes, for example, "postfix/smtpd".
62 /* SEE ALSO
63 /* postconf(5), configuration parameters
64 /* syslogd(8), syslog daemon
65 /* LICENSE
66 /* .ad
67 /* .fi
68 /* The Secure Mailer license must be distributed with this software.
69 /* AUTHOR(S)
70 /* Wietse Venema
71 /* IBM T.J. Watson Research
72 /* P.O. Box 704
73 /* Yorktown Heights, NY 10598, USA
74 /*--*/
76 /* System library. */
78 #include <sys_defs.h>
79 #include <sys/stat.h>
80 #include <string.h>
81 #include <syslog.h>
82 #include <fcntl.h>
83 #include <stdlib.h>
84 #include <unistd.h>
86 #ifdef STRCASECMP_IN_STRINGS_H
87 #include <strings.h>
88 #endif
90 /* Utility library. */
92 #include <msg.h>
93 #include <vstring.h>
94 #include <vstream.h>
95 #include <vstring_vstream.h>
96 #include <msg_output.h>
97 #include <msg_vstream.h>
98 #include <msg_syslog.h>
100 /* Global library. */
102 #include <mail_params.h> /* XXX right place for LOG_FACILITY? */
103 #include <mail_version.h>
104 #include <mail_conf.h>
105 #include <mail_task.h>
107 /* Application-specific. */
110 * Support for the severity level mapping.
112 struct level_table {
113 char *name;
114 int level;
117 static struct level_table level_table[] = {
118 "info", MSG_INFO,
119 "warn", MSG_WARN,
120 "warning", MSG_WARN,
121 "error", MSG_ERROR,
122 "err", MSG_ERROR,
123 "fatal", MSG_FATAL,
124 "crit", MSG_FATAL,
125 "panic", MSG_PANIC,
129 /* level_map - lookup facility or severity value */
131 static int level_map(char *name)
133 struct level_table *t;
135 for (t = level_table; t->name; t++)
136 if (strcasecmp(t->name, name) == 0)
137 return (t->level);
138 msg_fatal("bad severity: \"%s\"", name);
141 /* log_argv - log the command line */
143 static void log_argv(int level, char **argv)
145 VSTRING *buf = vstring_alloc(100);
147 while (*argv) {
148 vstring_strcat(buf, *argv++);
149 if (*argv)
150 vstring_strcat(buf, " ");
152 msg_text(level, vstring_str(buf));
153 vstring_free(buf);
156 /* log_stream - log lines from a stream */
158 static void log_stream(int level, VSTREAM *fp)
160 VSTRING *buf = vstring_alloc(100);
162 while (vstring_get_nonl(buf, fp) != VSTREAM_EOF)
163 msg_text(level, vstring_str(buf));
164 vstring_free(buf);
167 MAIL_VERSION_STAMP_DECLARE;
169 /* main - logger */
171 int main(int argc, char **argv)
173 struct stat st;
174 char *slash;
175 int fd;
176 int ch;
177 const char *tag;
178 int log_flags = 0;
179 int level = MSG_INFO;
182 * Fingerprint executables and core dumps.
184 MAIL_VERSION_STAMP_ALLOCATE;
187 * Be consistent with file permissions.
189 umask(022);
192 * To minimize confusion, make sure that the standard file descriptors
193 * are open before opening anything else. XXX Work around for 44BSD where
194 * fstat can return EBADF on an open file descriptor.
196 for (fd = 0; fd < 3; fd++)
197 if (fstat(fd, &st) == -1
198 && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
199 msg_fatal("open /dev/null: %m");
202 * Set up diagnostics.
204 if ((slash = strrchr(argv[0], '/')) != 0 && slash[1])
205 tag = mail_task(slash + 1);
206 else
207 tag = mail_task(argv[0]);
208 if (isatty(STDERR_FILENO))
209 msg_vstream_init(tag, VSTREAM_ERR);
210 msg_syslog_init(tag, LOG_PID, LOG_FACILITY);
211 tag = 0;
214 * Parse switches.
216 while ((ch = GETOPT(argc, argv, "c:ip:t:v")) > 0) {
217 switch (ch) {
218 default:
219 msg_fatal("usage: %s [-c config_dir] [-i] [-p priority] [-t tag] [-v] [text]", tag);
220 break;
221 case 'c':
222 if (setenv(CONF_ENV_PATH, optarg, 1) < 0)
223 msg_fatal("out of memory");
224 break;
225 case 'i':
226 log_flags |= LOG_PID;
227 break;
228 case 'p':
229 level = level_map(optarg);
230 break;
231 case 't':
232 tag = optarg;
233 break;
234 case 'v':
235 msg_verbose++;
236 break;
241 * Process the main.cf file. This overrides any logging facility that was
242 * specified with msg_syslog_init();
244 mail_conf_read();
245 if (tag == 0 && strcmp(var_syslog_name, DEF_SYSLOG_NAME) != 0) {
246 if ((slash = strrchr(argv[0], '/')) != 0 && slash[1])
247 tag = mail_task(slash + 1);
248 else
249 tag = mail_task(argv[0]);
253 * Re-initialize the logging, this time with the tag specified in main.cf
254 * or on the command line.
256 if (tag != 0) {
257 if (isatty(STDERR_FILENO))
258 msg_vstream_init(tag, VSTREAM_ERR);
259 msg_syslog_init(tag, LOG_PID, LOG_FACILITY);
263 * Log the command line or log lines from standard input.
265 if (argc > optind) {
266 log_argv(level, argv + optind);
267 } else {
268 log_stream(level, VSTREAM_IN);
270 exit(0);