masqmail-0.2

annotate src/log.c @ 179:ec3fe72a3e99

Fixed an important bug with folded headers! g_strconcat() returns a *copy* of the string, but hdr->value still pointed to the old header (which probably was a memory leak, too). If the folded part had been quite small it was likely that the new string was at the same position as the old one, thus making everything go well. But if pretty long headers were folded several times it was likely that the new string was allocated somewhere else in memory, thus breaking things. In result mails to lots of recipients (folded header) were frequently only sent to the ones in the first line. Sorry for the inconvenience.
author meillo@marmaro.de
date Fri, 03 Jun 2011 09:52:17 +0200
parents 26e34ae9a3e3
children b3835b6b834b
rev   line source
meillo@0 1 /* MasqMail
meillo@0 2 Copyright (C) 1999-2001 Oliver Kurth
meillo@0 3
meillo@0 4 This program is free software; you can redistribute it and/or modify
meillo@0 5 it under the terms of the GNU General Public License as published by
meillo@0 6 the Free Software Foundation; either version 2 of the License, or
meillo@0 7 (at your option) any later version.
meillo@0 8
meillo@0 9 This program is distributed in the hope that it will be useful,
meillo@0 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
meillo@0 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
meillo@0 12 GNU General Public License for more details.
meillo@0 13
meillo@0 14 You should have received a copy of the GNU General Public License
meillo@0 15 along with this program; if not, write to the Free Software
meillo@0 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
meillo@0 17 */
meillo@0 18
meillo@15 19 #include <sysexits.h>
meillo@15 20
meillo@0 21 #include "masqmail.h"
meillo@0 22
meillo@0 23 static char *_sysexit_strings[] = {
meillo@10 24 "command line usage error",
meillo@10 25 "data format error",
meillo@10 26 "cannot open input",
meillo@10 27 "addressee unknown",
meillo@10 28 "host name unknown",
meillo@10 29 "service unavailable",
meillo@10 30 "internal software error",
meillo@10 31 "system error (e.g., can't fork)",
meillo@10 32 "critical OS file missing",
meillo@10 33 "can't create (user) output file",
meillo@10 34 "input/output error",
meillo@10 35 "temp failure; user is invited to retry",
meillo@10 36 "remote error in protocol",
meillo@10 37 "permission denied",
meillo@10 38 "configuration error"
meillo@0 39 };
meillo@0 40
meillo@10 41 gchar*
meillo@10 42 ext_strerror(int err)
meillo@0 43 {
meillo@10 44 if (err < 1024)
meillo@10 45 return strerror(err);
meillo@10 46 else if (err > 1024 + EX__BASE
meillo@10 47 && (err - 1024 - EX__BASE < sizeof(_sysexit_strings) / sizeof(_sysexit_strings[0])))
meillo@10 48 return _sysexit_strings[err - 1024 - EX__BASE];
meillo@0 49
meillo@10 50 return "unknown error";
meillo@0 51 }
meillo@0 52
meillo@0 53 static FILE *logfile = NULL;
meillo@0 54 static FILE *debugfile = NULL;
meillo@0 55
meillo@10 56 gboolean
meillo@10 57 logopen()
meillo@0 58 {
meillo@10 59 gchar *filename;
meillo@10 60 mode_t saved_mode = umask(066);
meillo@0 61
meillo@10 62 if (conf.use_syslog) {
meillo@10 63 openlog(PACKAGE, LOG_PID, LOG_MAIL);
meillo@10 64 } else {
meillo@10 65 uid_t saved_uid;
meillo@10 66 gid_t saved_gid;
meillo@0 67
meillo@10 68 saved_gid = setegid(conf.mail_gid);
meillo@10 69 saved_uid = seteuid(conf.mail_uid);
meillo@0 70
meillo@10 71 filename = g_strdup_printf("%s/masqmail.log", conf.log_dir);
meillo@10 72 logfile = fopen(filename, "a");
meillo@10 73 if (!logfile) {
meillo@10 74 fprintf(stderr, "could not open log '%s': %s\n", filename, strerror(errno));
meillo@10 75 return FALSE;
meillo@10 76 }
meillo@10 77 g_free(filename);
meillo@10 78
meillo@10 79 seteuid(saved_uid);
meillo@10 80 setegid(saved_gid);
meillo@10 81 }
meillo@0 82
meillo@0 83 #ifdef ENABLE_DEBUG
meillo@10 84 if (conf.debug_level > 0) {
meillo@10 85 filename = g_strdup_printf("%s/debug.log", conf.log_dir);
meillo@10 86 debugfile = fopen(filename, "a");
meillo@10 87 if (!debugfile) {
meillo@10 88 fprintf(stderr, "could not open debug log '%s'\n", filename);
meillo@10 89 return FALSE;
meillo@10 90 }
meillo@10 91 g_free(filename);
meillo@10 92 }
meillo@0 93 #endif
meillo@10 94 umask(saved_mode);
meillo@10 95 return TRUE;
meillo@0 96 }
meillo@0 97
meillo@10 98 void
meillo@10 99 logclose()
meillo@0 100 {
meillo@10 101 if (conf.use_syslog)
meillo@10 102 closelog();
meillo@10 103 else if (logfile)
meillo@10 104 fclose(logfile);
meillo@10 105 if (debugfile)
meillo@10 106 fclose(debugfile);
meillo@0 107 }
meillo@0 108
meillo@10 109 void
meillo@10 110 vlogwrite(int pri, const char *fmt, va_list args)
meillo@0 111 {
meillo@15 112 if ((conf.do_verbose && (pri & LOG_VERBOSE)) || (pri == LOG_ALERT) || (pri == LOG_WARNING)) {
meillo@10 113 va_list args_copy;
meillo@10 114 va_copy(args_copy, args);
meillo@10 115 vfprintf(stdout, fmt, args_copy);
meillo@10 116 va_end(args_copy);
meillo@10 117 fflush(stdout); /* is this necessary? */
meillo@10 118 }
meillo@0 119
meillo@10 120 pri &= ~LOG_VERBOSE;
meillo@10 121 if (pri) {
meillo@10 122 if (conf.use_syslog)
meillo@10 123 vsyslog(pri, fmt, args);
meillo@10 124 else {
meillo@10 125 if (pri <= conf.log_max_pri) {
meillo@10 126 FILE *file = logfile ? logfile : stderr;
meillo@10 127 time_t now = time(NULL);
meillo@10 128 struct tm *t = localtime(&now);
meillo@10 129 gchar buf[24];
meillo@10 130 uid_t saved_uid;
meillo@10 131 gid_t saved_gid;
meillo@10 132
meillo@10 133 saved_gid = setegid(conf.mail_gid);
meillo@10 134 saved_uid = seteuid(conf.mail_uid);
meillo@10 135
meillo@10 136 strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t);
meillo@10 137 fprintf(file, "%s [%d] ", buf, getpid());
meillo@10 138
meillo@10 139 vfprintf(file, fmt, args);
meillo@10 140 fflush(file);
meillo@10 141
meillo@10 142 seteuid(saved_uid);
meillo@10 143 setegid(saved_gid);
meillo@10 144 }
meillo@10 145 }
meillo@10 146 }
meillo@10 147 }
meillo@10 148
meillo@10 149 #ifdef ENABLE_DEBUG
meillo@10 150 void
meillo@10 151 vdebugwrite(int pri, const char *fmt, va_list args)
meillo@10 152 {
meillo@0 153 time_t now = time(NULL);
meillo@0 154 struct tm *t = localtime(&now);
meillo@0 155 gchar buf[24];
meillo@10 156 strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t);
meillo@0 157
meillo@10 158 if (debugfile) {
meillo@10 159 fprintf(debugfile, "%s [%d] ", buf, getpid());
meillo@10 160 vfprintf(debugfile, fmt, args);
meillo@10 161 fflush(debugfile);
meillo@10 162 } else {
meillo@10 163 fprintf(stderr, "no debug file, msg was:\n");
meillo@10 164 vfprintf(stderr, fmt, args);
meillo@10 165 }
meillo@0 166 }
meillo@0 167 #endif
meillo@0 168
meillo@10 169 void
meillo@10 170 logwrite(int pri, const char *fmt, ...)
meillo@0 171 {
meillo@10 172 va_list args, args_copy;
meillo@10 173 int saved_errno = errno; /* somewhere this is changed to EBADF */
meillo@0 174
meillo@10 175 va_start(args, fmt);
meillo@0 176 #ifdef ENABLE_DEBUG
meillo@10 177 va_copy(args_copy, args);
meillo@0 178 #endif
meillo@10 179 vlogwrite(pri, fmt, args);
meillo@0 180 #ifdef ENABLE_DEBUG
meillo@10 181 if (debugfile)
meillo@10 182 vdebugwrite(pri, fmt, args_copy);
meillo@10 183 va_end(args_copy);
meillo@0 184 #endif
meillo@10 185 va_end(args);
meillo@0 186
meillo@10 187 errno = saved_errno;
meillo@0 188 }
meillo@0 189
meillo@0 190 #ifdef ENABLE_DEBUG
meillo@10 191 void
meillo@10 192 debugf(const char *fmt, ...)
meillo@0 193 {
meillo@10 194 va_list args;
meillo@10 195 va_start(args, fmt);
meillo@0 196
meillo@10 197 vdebugwrite(LOG_DEBUG, fmt, args);
meillo@0 198
meillo@10 199 va_end(args);
meillo@0 200 }
meillo@0 201
meillo@10 202 void
meillo@10 203 vdebugf(const char *fmt, va_list args)
meillo@0 204 {
meillo@10 205 vdebugwrite(LOG_DEBUG, fmt, args);
meillo@0 206 }
meillo@0 207 #endif
meillo@0 208
meillo@10 209 void
meillo@10 210 maillog(const char *fmt, ...)
meillo@0 211 {
meillo@10 212 va_list args;
meillo@10 213 va_start(args, fmt);
meillo@0 214
meillo@10 215 vlogwrite(LOG_NOTICE, fmt, args);
meillo@0 216
meillo@10 217 va_end(args);
meillo@0 218 }