/* GNU Mailutils -- a suite of utilities for electronic mail Copyright (C) 2010-2012, 2014-2017 Free Software Foundation, Inc. GNU Mailutils is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Mailutils is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Mailutils. If not, see . */ #if defined(HAVE_CONFIG_H) # include #endif #include #include "mu.h" char logger_docstring[] = N_("log data using Mailutils log facility"); static char logger_args_doc[] = N_("[TEXT]"); static char *input_file = NULL; static int logger_type = MU_STRERR_STDERR; static int log_severity = MU_LOG_ERROR; static struct mu_locus_range locus = MU_LOCUS_RANGE_INITIALIZER; static int syslog_facility = LOG_USER; static int syslog_priority = LOG_ERR; static char *syslog_tag = NULL; static void set_priority (struct mu_parseopt *po, struct mu_option *opt, char const *arg) { char *s = strchr (arg, '.'); if (s) *s++ = 0; if (mu_string_to_syslog_facility (arg, &syslog_facility)) { mu_parseopt_error (po, _("unknown facility: %s"), arg); exit (po->po_exit_error); } if (s && mu_string_to_syslog_priority (s, &syslog_priority)) { mu_parseopt_error (po, _("unknown priority: %s"), s); exit (po->po_exit_error); } logger_type = MU_STRERR_SYSLOG; } static void set_syslog (struct mu_parseopt *po, struct mu_option *opt, char const *arg) { logger_type = MU_STRERR_SYSLOG; } static void set_stderr (struct mu_parseopt *po, struct mu_option *opt, char const *arg) { logger_type = MU_STRERR_STDERR; } static void set_severity (struct mu_parseopt *po, struct mu_option *opt, char const *arg) { int i; for (i = 0; i < _mu_severity_num; i++) if (mu_c_strcasecmp (_mu_severity_str[i], arg) == 0) { log_severity = i; return; } mu_parseopt_error (po, _("unknown severity: %s"), arg); exit (po->po_exit_error); } static void parse_locus_point (char **ptr, struct mu_locus_point *pt, struct mu_parseopt *po) { char *str = *ptr; char *s; s = strchr (str, ':'); if (s) { char *end; *s++ = 0; if (*str) mu_locus_point_set_file (pt, str); pt->mu_line = strtoul (s, &end, 10); if (end == s) { mu_parseopt_error (po, _("bad line number: %s"), s); exit (po->po_exit_error); } s = end; if (*s == '.' || *s == ':') { s++; pt->mu_col = strtoul (s, &end, 10); if (end == s) { mu_parseopt_error (po, _("bad column number: %s"), s); exit (po->po_exit_error); } s = end; } } else { mu_parseopt_error (po, _("missing line number after %s"), s); exit (po->po_exit_error); } *ptr = s; } static void set_locus (struct mu_parseopt *po, struct mu_option *opt, char const *arg) { char *s; char *tmp; tmp = mu_strdup (arg); s = tmp; parse_locus_point (&s, &locus.beg, po); if (*s == '-') { mu_locus_point_set_file (&locus.end, locus.beg.mu_file); locus.end.mu_line = locus.beg.mu_line; locus.end.mu_col = locus.end.mu_col; s++; parse_locus_point (&s, &locus.end, po); } if (*s) mu_parseopt_error (po, _("locus format error near %s"), s); } static struct mu_option logger_options[] = { { "file", 'f', N_("FILE"), MU_OPTION_DEFAULT, N_("read message from FILE"), mu_c_string, &input_file }, { "priority", 'p', N_("FACILITY[.LEVEL]"), MU_OPTION_DEFAULT, N_("log at the specified syslog priority (implies --syslog)"), mu_c_string, NULL, set_priority }, { "syslog", 0, NULL, MU_OPTION_DEFAULT, N_("log via syslog"), mu_c_string, NULL, set_syslog }, { "stderr", 0, NULL, MU_OPTION_DEFAULT, N_("log to the standard error"), mu_c_string, NULL, set_stderr }, { "severity", 's', N_("SEV"), MU_OPTION_DEFAULT, N_("log at Mailutils severity level SEV"), mu_c_string, NULL, set_severity }, { "locus", 'l', N_("FILE:LINE[.COL][-FILE:LINE[.COL]]"), MU_OPTION_DEFAULT, N_("set locus for logging"), mu_c_string, NULL, set_locus }, { "tag", 't', N_("TAG"), MU_OPTION_DEFAULT, N_("set syslog tag"), mu_c_string, &syslog_tag }, MU_OPTION_END }; int main (int argc, char **argv) { mu_stream_t logger, input; int rc, mode; mu_action_getopt (&argc, &argv, logger_options, logger_docstring, logger_args_doc); if (argc && input_file) { mu_error (_("both input file and message text given")); exit (1); } if (!syslog_tag) syslog_tag = "mu-logger"; rc = mu_stdstream_strerr_create (&logger, logger_type, syslog_facility, syslog_priority, syslog_tag, NULL); if (rc) { mu_error (_("cannot create log stream: %s"), mu_strerror (rc)); exit (1); } mode = MU_LOGMODE_SEVERITY | MU_LOGMODE_LOCUS; mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_MODE, &mode); if (locus.beg.mu_file) mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &locus); mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_SEVERITY, &log_severity); if (argc) { int i; for (i = 0; i < argc; i++) { if (i > 0) mu_stream_write (logger, " ", 1, NULL); mu_stream_write (logger, argv[i], strlen (argv[i]), NULL); } mu_stream_write (logger, "\n", 1, NULL); return 0; } else if (!input_file || strcmp (input_file, "-") == 0) { mu_stream_ref (mu_strin); input = mu_strin; } else { rc = mu_file_stream_create (&input, input_file, MU_STREAM_READ); if (rc) { mu_error (_("cannot open input stream %s: %s"), input_file, mu_strerror (rc)); return 1; } } rc = mu_stream_copy (logger, input, 0, NULL); mu_stream_unref (input); mu_stream_unref (logger); return !!rc; }