7 /* Postfix-compatible logging utility
11 /* \fBpostlog\fR [\fB-iv\fR] [\fB-c \fIconfig_dir\fR]
12 /* [\fB-p \fIpriority\fB] [\fB-t \fItag\fR] [\fItext...\fR]
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.
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.
39 /* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
40 /* options make the software increasingly verbose.
45 /* Directory with the \fBmain.cf\fR file.
46 /* CONFIGURATION PARAMETERS
49 /* The following \fBmain.cf\fR parameters are especially relevant to
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".
63 /* postconf(5), configuration parameters
64 /* syslogd(8), syslog daemon
68 /* The Secure Mailer license must be distributed with this software.
71 /* IBM T.J. Watson Research
73 /* Yorktown Heights, NY 10598, USA
86 #ifdef STRCASECMP_IN_STRINGS_H
90 /* Utility library. */
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.
117 static struct level_table level_table
[] = {
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)
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);
148 vstring_strcat(buf
, *argv
++);
150 vstring_strcat(buf
, " ");
152 msg_text(level
, vstring_str(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
));
167 MAIL_VERSION_STAMP_DECLARE
;
171 int main(int argc
, char **argv
)
179 int level
= MSG_INFO
;
182 * Fingerprint executables and core dumps.
184 MAIL_VERSION_STAMP_ALLOCATE
;
187 * Be consistent with file permissions.
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);
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
);
216 while ((ch
= GETOPT(argc
, argv
, "c:ip:t:v")) > 0) {
219 msg_fatal("usage: %s [-c config_dir] [-i] [-p priority] [-t tag] [-v] [text]", tag
);
222 if (setenv(CONF_ENV_PATH
, optarg
, 1) < 0)
223 msg_fatal("out of memory");
226 log_flags
|= LOG_PID
;
229 level
= level_map(optarg
);
241 * Process the main.cf file. This overrides any logging facility that was
242 * specified with msg_syslog_init();
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);
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.
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.
266 log_argv(level
, argv
+ optind
);
268 log_stream(level
, VSTREAM_IN
);