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