meillo@0: /* MasqMail meillo@0: Copyright (C) 1999-2001 Oliver Kurth meillo@0: meillo@0: This program is free software; you can redistribute it and/or modify meillo@0: it under the terms of the GNU General Public License as published by meillo@0: the Free Software Foundation; either version 2 of the License, or meillo@0: (at your option) any later version. meillo@0: meillo@0: This program is distributed in the hope that it will be useful, meillo@0: but WITHOUT ANY WARRANTY; without even the implied warranty of meillo@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the meillo@0: GNU General Public License for more details. meillo@0: meillo@0: You should have received a copy of the GNU General Public License meillo@0: along with this program; if not, write to the Free Software meillo@0: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. meillo@0: */ meillo@0: meillo@0: #include "masqmail.h" meillo@0: meillo@0: #include "sysexits.h" meillo@0: meillo@0: static char *_sysexit_strings[] = { meillo@10: "command line usage error", meillo@10: "data format error", meillo@10: "cannot open input", meillo@10: "addressee unknown", meillo@10: "host name unknown", meillo@10: "service unavailable", meillo@10: "internal software error", meillo@10: "system error (e.g., can't fork)", meillo@10: "critical OS file missing", meillo@10: "can't create (user) output file", meillo@10: "input/output error", meillo@10: "temp failure; user is invited to retry", meillo@10: "remote error in protocol", meillo@10: "permission denied", meillo@10: "configuration error" meillo@0: }; meillo@0: meillo@10: gchar* meillo@10: ext_strerror(int err) meillo@0: { meillo@10: if (err < 1024) meillo@10: return strerror(err); meillo@10: else if (err > 1024 + EX__BASE meillo@10: && (err - 1024 - EX__BASE < sizeof(_sysexit_strings) / sizeof(_sysexit_strings[0]))) meillo@10: return _sysexit_strings[err - 1024 - EX__BASE]; meillo@0: meillo@10: return "unknown error"; meillo@0: } meillo@0: meillo@0: static FILE *logfile = NULL; meillo@0: static FILE *debugfile = NULL; meillo@0: meillo@10: gboolean meillo@10: logopen() meillo@0: { meillo@10: gchar *filename; meillo@10: mode_t saved_mode = umask(066); meillo@0: meillo@10: if (conf.use_syslog) { meillo@10: openlog(PACKAGE, LOG_PID, LOG_MAIL); meillo@10: } else { meillo@10: uid_t saved_uid; meillo@10: gid_t saved_gid; meillo@0: meillo@10: saved_gid = setegid(conf.mail_gid); meillo@10: saved_uid = seteuid(conf.mail_uid); meillo@0: meillo@10: filename = g_strdup_printf("%s/masqmail.log", conf.log_dir); meillo@10: logfile = fopen(filename, "a"); meillo@10: if (!logfile) { meillo@10: fprintf(stderr, "could not open log '%s': %s\n", filename, strerror(errno)); meillo@10: return FALSE; meillo@10: } meillo@10: g_free(filename); meillo@10: meillo@10: seteuid(saved_uid); meillo@10: setegid(saved_gid); meillo@10: } meillo@0: meillo@0: #ifdef ENABLE_DEBUG meillo@10: if (conf.debug_level > 0) { meillo@10: filename = g_strdup_printf("%s/debug.log", conf.log_dir); meillo@10: debugfile = fopen(filename, "a"); meillo@10: if (!debugfile) { meillo@10: fprintf(stderr, "could not open debug log '%s'\n", filename); meillo@10: return FALSE; meillo@10: } meillo@10: g_free(filename); meillo@10: } meillo@0: #endif meillo@10: umask(saved_mode); meillo@10: return TRUE; meillo@0: } meillo@0: meillo@10: void meillo@10: logclose() meillo@0: { meillo@10: if (conf.use_syslog) meillo@10: closelog(); meillo@10: else if (logfile) meillo@10: fclose(logfile); meillo@10: if (debugfile) meillo@10: fclose(debugfile); meillo@0: } meillo@0: meillo@10: void meillo@10: vlogwrite(int pri, const char *fmt, va_list args) meillo@0: { meillo@10: if ((conf.do_verbose && (pri & LOG_VERBOSE)) || (pri == LOG_ALERT) meillo@10: || (pri == LOG_WARNING)) { meillo@10: va_list args_copy; meillo@10: va_copy(args_copy, args); meillo@10: vfprintf(stdout, fmt, args_copy); meillo@10: va_end(args_copy); meillo@10: fflush(stdout); /* is this necessary? */ meillo@10: } meillo@0: meillo@10: pri &= ~LOG_VERBOSE; meillo@10: if (pri) { meillo@0: meillo@10: if (conf.use_syslog) meillo@10: vsyslog(pri, fmt, args); meillo@10: else { meillo@10: if (pri <= conf.log_max_pri) { meillo@10: FILE *file = logfile ? logfile : stderr; meillo@10: time_t now = time(NULL); meillo@10: struct tm *t = localtime(&now); meillo@10: gchar buf[24]; meillo@10: uid_t saved_uid; meillo@10: gid_t saved_gid; meillo@10: meillo@10: saved_gid = setegid(conf.mail_gid); meillo@10: saved_uid = seteuid(conf.mail_uid); meillo@10: meillo@10: strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t); meillo@10: fprintf(file, "%s [%d] ", buf, getpid()); meillo@10: meillo@10: vfprintf(file, fmt, args); meillo@10: fflush(file); meillo@10: meillo@10: seteuid(saved_uid); meillo@10: setegid(saved_gid); meillo@10: } meillo@10: } meillo@10: } meillo@10: } meillo@10: meillo@10: #ifdef ENABLE_DEBUG meillo@10: void meillo@10: vdebugwrite(int pri, const char *fmt, va_list args) meillo@10: { meillo@0: time_t now = time(NULL); meillo@0: struct tm *t = localtime(&now); meillo@0: gchar buf[24]; meillo@10: strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t); meillo@0: meillo@10: if (debugfile) { meillo@10: fprintf(debugfile, "%s [%d] ", buf, getpid()); meillo@0: meillo@10: vfprintf(debugfile, fmt, args); meillo@10: fflush(debugfile); meillo@10: } else { meillo@10: fprintf(stderr, "no debug file, msg was:\n"); meillo@10: vfprintf(stderr, fmt, args); meillo@10: } meillo@0: } meillo@0: #endif meillo@0: meillo@10: void meillo@10: logwrite(int pri, const char *fmt, ...) meillo@0: { meillo@10: va_list args, args_copy; meillo@10: int saved_errno = errno; /* somewhere this is changed to EBADF */ meillo@0: meillo@10: va_start(args, fmt); meillo@0: #ifdef ENABLE_DEBUG meillo@10: va_copy(args_copy, args); meillo@0: #endif meillo@10: vlogwrite(pri, fmt, args); meillo@0: #ifdef ENABLE_DEBUG meillo@10: if (debugfile) meillo@10: vdebugwrite(pri, fmt, args_copy); meillo@10: va_end(args_copy); meillo@0: #endif meillo@10: va_end(args); meillo@0: meillo@10: errno = saved_errno; meillo@0: } meillo@0: meillo@0: #ifdef ENABLE_DEBUG meillo@10: void meillo@10: debugf(const char *fmt, ...) meillo@0: { meillo@10: va_list args; meillo@10: va_start(args, fmt); meillo@0: meillo@10: vdebugwrite(LOG_DEBUG, fmt, args); meillo@0: meillo@10: va_end(args); meillo@0: } meillo@0: meillo@10: void meillo@10: vdebugf(const char *fmt, va_list args) meillo@0: { meillo@10: vdebugwrite(LOG_DEBUG, fmt, args); meillo@0: } meillo@0: #endif meillo@0: meillo@10: void meillo@10: maillog(const char *fmt, ...) meillo@0: { meillo@10: va_list args; meillo@10: va_start(args, fmt); meillo@0: meillo@10: vlogwrite(LOG_NOTICE, fmt, args); meillo@0: meillo@10: va_end(args); meillo@0: }