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@0: "command line usage error", meillo@0: "data format error", meillo@0: "cannot open input", meillo@0: "addressee unknown", meillo@0: "host name unknown", meillo@0: "service unavailable", meillo@0: "internal software error", meillo@0: "system error (e.g., can't fork)", meillo@0: "critical OS file missing", meillo@0: "can't create (user) output file", meillo@0: "input/output error", meillo@0: "temp failure; user is invited to retry", meillo@0: "remote error in protocol", meillo@0: "permission denied", meillo@0: "configuration error" meillo@0: }; meillo@0: meillo@0: gchar *ext_strerror(int err) meillo@0: { meillo@0: if(err < 1024) meillo@0: return strerror(err); meillo@0: else meillo@0: if(err > 1024 + EX__BASE && meillo@0: (err - 1024 - EX__BASE < sizeof(_sysexit_strings)/sizeof(_sysexit_strings[0]))) meillo@0: return _sysexit_strings[err - 1024 - EX__BASE]; meillo@0: meillo@0: return "unknown error"; meillo@0: } meillo@0: meillo@0: static FILE *logfile = NULL; meillo@0: static FILE *debugfile = NULL; meillo@0: meillo@0: gboolean logopen() meillo@0: { meillo@0: gchar *filename; meillo@0: mode_t saved_mode = umask(066); meillo@0: meillo@0: if(conf.use_syslog){ meillo@0: openlog(PACKAGE, LOG_PID, LOG_MAIL); meillo@0: }else{ meillo@0: uid_t saved_uid; meillo@0: gid_t saved_gid; meillo@0: meillo@0: saved_gid = setegid(conf.mail_gid); meillo@0: saved_uid = seteuid(conf.mail_uid); meillo@0: meillo@0: filename = g_strdup_printf("%s/masqmail.log", conf.log_dir); meillo@0: logfile = fopen(filename, "a"); meillo@0: if(!logfile){ meillo@0: fprintf(stderr, "could not open log '%s': %s\n", filename, strerror(errno)); meillo@0: return FALSE; meillo@0: } meillo@0: g_free(filename); meillo@0: meillo@0: seteuid(saved_uid); meillo@0: setegid(saved_gid); meillo@0: } meillo@0: meillo@0: #ifdef ENABLE_DEBUG meillo@0: if(conf.debug_level > 0){ meillo@0: filename = g_strdup_printf("%s/debug.log", conf.log_dir); meillo@0: debugfile = fopen(filename, "a"); meillo@0: if(!debugfile){ meillo@0: fprintf(stderr, "could not open debug log '%s'\n", filename); meillo@0: return FALSE; meillo@0: } meillo@0: g_free(filename); meillo@0: } meillo@0: #endif meillo@0: umask(saved_mode); meillo@0: return TRUE; meillo@0: } meillo@0: meillo@0: void logclose() meillo@0: { meillo@0: if(conf.use_syslog) meillo@0: closelog(); meillo@0: else meillo@0: if(logfile) fclose(logfile); meillo@0: if(debugfile) fclose(debugfile); meillo@0: } meillo@0: meillo@0: void vlogwrite(int pri, const char *fmt, va_list args) meillo@0: { meillo@0: if((conf.do_verbose && (pri & LOG_VERBOSE)) || (pri == LOG_ALERT) || (pri == LOG_WARNING)){ meillo@0: va_list args_copy; meillo@0: va_copy(args_copy, args); meillo@0: vfprintf(stdout, fmt, args_copy); meillo@0: va_end(args_copy); meillo@0: fflush(stdout); /* is this necessary? */ meillo@0: } meillo@0: meillo@0: pri &= ~LOG_VERBOSE; meillo@0: if(pri){ meillo@0: meillo@0: if(conf.use_syslog) meillo@0: vsyslog(pri, fmt, args); meillo@0: else{ meillo@0: if(pri <= conf.log_max_pri){ meillo@0: FILE *file = logfile ? logfile : stderr; meillo@0: time_t now = time(NULL); meillo@0: struct tm *t = localtime(&now); meillo@0: gchar buf[24]; meillo@0: uid_t saved_uid; meillo@0: gid_t saved_gid; meillo@0: meillo@0: saved_gid = setegid(conf.mail_gid); meillo@0: saved_uid = seteuid(conf.mail_uid); meillo@0: meillo@0: strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t); meillo@0: fprintf(file, "%s [%d] ", buf, getpid()); meillo@0: meillo@0: vfprintf(file, fmt, args); meillo@0: fflush(file); meillo@0: meillo@0: seteuid(saved_uid); meillo@0: setegid(saved_gid); meillo@0: } meillo@0: } meillo@0: } meillo@0: } meillo@0: meillo@0: #ifdef ENABLE_DEBUG meillo@0: void vdebugwrite(int pri, const char *fmt, va_list args) meillo@0: { meillo@0: time_t now = time(NULL); meillo@0: struct tm *t = localtime(&now); meillo@0: gchar buf[24]; meillo@0: strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t); meillo@0: meillo@0: if(debugfile){ meillo@0: fprintf(debugfile, "%s [%d] ", buf, getpid()); meillo@0: meillo@0: vfprintf(debugfile, fmt, args); meillo@0: fflush(debugfile); meillo@0: }else{ meillo@0: fprintf(stderr, "no debug file, msg was:\n"); meillo@0: vfprintf(stderr, fmt, args); meillo@0: } meillo@0: } meillo@0: #endif meillo@0: meillo@0: void logwrite(int pri, const char *fmt, ...) meillo@0: { meillo@0: va_list args, args_copy; meillo@0: int saved_errno = errno; /* somewhere this is changed to EBADF */ meillo@0: meillo@0: va_start(args, fmt); meillo@0: #ifdef ENABLE_DEBUG meillo@0: va_copy(args_copy, args); meillo@0: #endif meillo@0: vlogwrite(pri, fmt, args); meillo@0: #ifdef ENABLE_DEBUG meillo@0: if(debugfile) meillo@0: vdebugwrite(pri, fmt, args_copy); meillo@0: va_end(args_copy); meillo@0: #endif meillo@0: va_end(args); meillo@0: meillo@0: errno = saved_errno; meillo@0: } meillo@0: meillo@0: #ifdef ENABLE_DEBUG meillo@0: void debugf(const char *fmt, ...) meillo@0: { meillo@0: va_list args; meillo@0: va_start(args, fmt); meillo@0: meillo@0: vdebugwrite(LOG_DEBUG, fmt, args); meillo@0: meillo@0: va_end(args); meillo@0: } meillo@0: meillo@0: void vdebugf(const char *fmt, va_list args) meillo@0: { meillo@0: vdebugwrite(LOG_DEBUG, fmt, args); meillo@0: } meillo@0: #endif meillo@0: meillo@0: void maillog(const char *fmt, ...) meillo@0: { meillo@0: va_list args; meillo@0: va_start(args, fmt); meillo@0: meillo@0: vlogwrite(LOG_NOTICE, fmt, args); meillo@0: meillo@0: va_end(args); meillo@0: }