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