Mercurial > masqmail
comparison src/local.c @ 10:26e34ae9a3e3
changed indention and line wrapping to a more consistent style
author | meillo@marmaro.de |
---|---|
date | Mon, 27 Oct 2008 16:23:10 +0100 |
parents | 08114f7dcc23 |
children | f671821d8222 |
comparison
equal
deleted
inserted
replaced
9:31cc8a89cb74 | 10:26e34ae9a3e3 |
---|---|
18 | 18 |
19 #include "masqmail.h" | 19 #include "masqmail.h" |
20 #include "peopen.h" | 20 #include "peopen.h" |
21 #include <sys/wait.h> | 21 #include <sys/wait.h> |
22 | 22 |
23 static | 23 static void |
24 void message_stream(FILE *out, message *msg, GList *hdr_list, guint flags) | 24 message_stream(FILE * out, message * msg, GList * hdr_list, guint flags) |
25 { | 25 { |
26 time_t now = time(NULL); | 26 time_t now = time(NULL); |
27 GList *node; | 27 GList *node; |
28 | 28 |
29 if(flags & MSGSTR_FROMLINE){ | 29 if (flags & MSGSTR_FROMLINE) { |
30 fprintf(out, "From <%s@%s> %s", msg->return_path->local_part, | 30 fprintf(out, "From <%s@%s> %s", msg->return_path->local_part, msg->return_path->domain, ctime(&now)); |
31 msg->return_path->domain, ctime(&now)); | 31 } |
32 } | 32 |
33 | 33 foreach(hdr_list, node) { |
34 foreach(hdr_list, node){ | 34 header *hdr = (header *) (node->data); |
35 header *hdr = (header *)(node->data); | 35 fputs(hdr->header, out); |
36 fputs(hdr->header, out); | 36 } |
37 } | 37 putc('\n', out); |
38 putc('\n', out); | 38 foreach(msg->data_list, node) { |
39 foreach(msg->data_list, node){ | 39 /* From hack: */ |
40 /* From hack: */ | 40 if (flags & MSGSTR_FROMHACK) { |
41 if(flags & MSGSTR_FROMHACK){ | 41 if (strncmp(node->data, "From ", 5) == 0) |
42 if(strncmp(node->data, "From ", 5) == 0) | 42 putc('>', out); |
43 putc('>', out); | 43 } |
44 } | 44 fputs(node->data, out); |
45 fputs(node->data, out); | 45 } |
46 } | 46 putc('\n', out); |
47 putc('\n', out); | |
48 } | 47 } |
49 | 48 |
50 gboolean append_file(message *msg, GList *hdr_list, gchar *user) | 49 gboolean |
50 append_file(message * msg, GList * hdr_list, gchar * user) | |
51 { | 51 { |
52 struct passwd *pw; | 52 struct passwd *pw; |
53 gboolean ok = FALSE; | 53 gboolean ok = FALSE; |
54 | 54 |
55 /* headers may be special for a local delivery */ | 55 /* headers may be special for a local delivery */ |
56 if(hdr_list == NULL) | 56 if (hdr_list == NULL) |
57 hdr_list = msg->hdr_list; | 57 hdr_list = msg->hdr_list; |
58 | 58 |
59 if((pw = getpwnam(user))){ | 59 if ((pw = getpwnam(user))) { |
60 uid_t saved_uid = geteuid(); | 60 uid_t saved_uid = geteuid(); |
61 gid_t saved_gid = getegid(); | 61 gid_t saved_gid = getegid(); |
62 gboolean uid_ok = TRUE, gid_ok = TRUE; | 62 gboolean uid_ok = TRUE, gid_ok = TRUE; |
63 | 63 |
64 if(!conf.run_as_user){ | 64 if (!conf.run_as_user) { |
65 uid_ok = (seteuid(0) == 0); | 65 uid_ok = (seteuid(0) == 0); |
66 if(uid_ok){ | 66 if (uid_ok) { |
67 gid_ok = (setegid(conf.mail_gid) == 0); | 67 gid_ok = (setegid(conf.mail_gid) == 0); |
68 uid_ok = (seteuid(pw->pw_uid) == 0); | 68 uid_ok = (seteuid(pw->pw_uid) == 0); |
69 } | 69 } |
70 } | 70 } |
71 | 71 |
72 DEBUG(5) debugf("running as euid %d\n", geteuid()); | 72 DEBUG(5) debugf("running as euid %d\n", geteuid()); |
73 DEBUG(5) debugf("running as egid %d\n", getegid()); | 73 DEBUG(5) debugf("running as egid %d\n", getegid()); |
74 | 74 |
75 if(uid_ok && gid_ok){ | 75 if (uid_ok && gid_ok) { |
76 gchar *filename; | 76 gchar *filename; |
77 FILE *out; | 77 FILE *out; |
78 | 78 |
79 filename = g_strdup_printf("%s/%s", conf.mail_dir, user); | 79 filename = g_strdup_printf("%s/%s", conf.mail_dir, user); |
80 if((out = fopen(filename, "a"))){ | 80 if ((out = fopen(filename, "a"))) { |
81 #ifdef USE_LIBLOCKFILE | 81 #ifdef USE_LIBLOCKFILE |
82 gint err; | 82 gint err; |
83 /* lock file using liblockfile */ | 83 /* lock file using liblockfile */ |
84 err = maillock(user,3); | 84 err = maillock(user, 3); |
85 if(err == 0){ | 85 if (err == 0) { |
86 #else | 86 #else |
87 /* lock file: */ | 87 /* lock file: */ |
88 struct flock lock; | 88 struct flock lock; |
89 lock.l_type = F_WRLCK; | 89 lock.l_type = F_WRLCK; |
90 lock.l_whence = SEEK_END; | 90 lock.l_whence = SEEK_END; |
91 lock.l_start = lock.l_len = 0; | 91 lock.l_start = lock.l_len = 0; |
92 if(fcntl(fileno(out), F_SETLK, &lock) != -1){ | 92 if (fcntl(fileno(out), F_SETLK, &lock) != -1) { |
93 #endif | 93 #endif |
94 fchmod(fileno(out), 0600); | 94 fchmod(fileno(out), 0600); |
95 | 95 |
96 message_stream(out, msg, hdr_list, MSGSTR_FROMLINE|MSGSTR_FROMHACK); | 96 message_stream(out, msg, hdr_list, MSGSTR_FROMLINE | MSGSTR_FROMHACK); |
97 | 97 |
98 ok = TRUE; | 98 ok = TRUE; |
99 | 99 |
100 /* close when still user */ | 100 /* close when still user */ |
101 fclose(out); | 101 fclose(out); |
102 #ifdef USE_LIBLOCKFILE | 102 #ifdef USE_LIBLOCKFILE |
103 mailunlock(); | 103 mailunlock(); |
104 #endif | 104 #endif |
105 }else{ | 105 } else { |
106 fclose(out); | 106 fclose(out); |
107 #ifdef USE_LIBLOCKFILE | 107 #ifdef USE_LIBLOCKFILE |
108 DEBUG(3) debugf("could not lock file %s: error %d\n", | 108 DEBUG(3) debugf("could not lock file %s: error %d\n", filename, err); |
109 filename, err); | 109 } /* XEmacs indenting convenience... */ |
110 } /* XEmacs indenting convenience... */ | |
111 #else | 110 #else |
112 DEBUG(3) debugf("could not lock file %s: %s\n", | 111 DEBUG(3) debugf("could not lock file %s: %s\n", filename, strerror(errno)); |
113 filename, strerror(errno)); | 112 } |
114 } | |
115 #endif | 113 #endif |
116 }else{ | 114 } else { |
117 logwrite(LOG_ALERT, "could not open file %s: %s\n", | 115 logwrite(LOG_ALERT, "could not open file %s: %s\n", filename, strerror(errno)); |
118 filename, strerror(errno)); | 116 } |
119 } | 117 g_free(filename); |
120 g_free(filename); | 118 |
121 | 119 if (!conf.run_as_user) { |
122 if(!conf.run_as_user){ | 120 uid_ok = (seteuid(0) == 0); |
123 uid_ok = (seteuid(0) == 0); | 121 if (uid_ok) { |
124 if(uid_ok){ | 122 gid_ok = (setegid(saved_gid) == 0); |
125 gid_ok = (setegid(saved_gid) == 0); | 123 uid_ok = (seteuid(saved_uid) == 0); |
126 uid_ok = (seteuid(saved_uid) == 0); | 124 } |
127 } | 125 } |
128 } | 126 |
129 | 127 if (!uid_ok || !gid_ok) { |
130 if(!uid_ok || !gid_ok){ | 128 /* FIXME: if this fails we HAVE to exit, because we shall not run |
131 /* FIXME: if this fails we HAVE to exit, because we shall not run | 129 with some users id. But we do not return, and so this message |
132 with some users id. But we do not return, and so this message | 130 will not be finished, so the user will get the message again |
133 will not be finished, so the user will get the message again | 131 next time a delivery is attempted... */ |
134 next time a delivery is attempted... */ | 132 logwrite(LOG_ALERT, "could not set back uid or gid after local delivery: %s\n", strerror(errno)); |
135 logwrite(LOG_ALERT, | 133 logwrite(LOG_ALERT, "uid=%d, gid=%d, euid=%d, egid=%d, want = %d, %d\n", |
136 "could not set back uid or gid after local delivery: %s\n", | 134 getuid(), getgid(), geteuid(), getegid(), saved_uid, saved_gid); |
137 strerror(errno)); | 135 exit(EXIT_FAILURE); |
138 logwrite(LOG_ALERT, | 136 } |
139 "uid=%d, gid=%d, euid=%d, egid=%d, want = %d, %d\n", | 137 } else { |
140 getuid(), getgid(), geteuid(), getegid(), saved_uid, saved_gid); | 138 logwrite(LOG_ALERT, "could not set uid or gid for local delivery, uid = %d: %s\n", pw->pw_uid, strerror(errno)); |
141 exit(EXIT_FAILURE); | 139 } |
142 } | 140 } else { |
143 }else{ | 141 logwrite(LOG_ALERT, "could not find password entry for user %s\n", user); |
144 logwrite(LOG_ALERT, | 142 errno = ENOENT; /* getpwnam does not set errno correctly */ |
145 "could not set uid or gid for local delivery, uid = %d: %s\n", | 143 } |
146 pw->pw_uid, strerror(errno)); | 144 |
147 } | 145 return ok; |
148 }else{ | |
149 logwrite(LOG_ALERT, "could not find password entry for user %s\n", user); | |
150 errno = ENOENT; /* getpwnam does not set errno correctly */ | |
151 } | |
152 | |
153 return ok; | |
154 } | 146 } |
155 | 147 |
156 #ifdef ENABLE_MAILDIR | 148 #ifdef ENABLE_MAILDIR |
157 gboolean maildir_out(message *msg, GList *hdr_list, gchar *user, guint flags) | 149 gboolean |
150 maildir_out(message * msg, GList * hdr_list, gchar * user, guint flags) | |
158 { | 151 { |
159 struct passwd *pw; | 152 struct passwd *pw; |
160 gboolean ok = FALSE; | 153 gboolean ok = FALSE; |
161 | 154 |
162 /* headers may be special for a local delivery */ | 155 /* headers may be special for a local delivery */ |
163 if(hdr_list == NULL) | 156 if (hdr_list == NULL) |
164 hdr_list = msg->hdr_list; | 157 hdr_list = msg->hdr_list; |
165 | 158 |
166 if((pw = getpwnam(user))){ | 159 if ((pw = getpwnam(user))) { |
167 uid_t saved_uid = geteuid(); | 160 uid_t saved_uid = geteuid(); |
168 gid_t saved_gid = getegid(); | 161 gid_t saved_gid = getegid(); |
169 gboolean uid_ok = TRUE, gid_ok = TRUE; | 162 gboolean uid_ok = TRUE, gid_ok = TRUE; |
170 | 163 |
171 if(!conf.run_as_user){ | 164 if (!conf.run_as_user) { |
172 uid_ok = (seteuid(0) == 0); | 165 uid_ok = (seteuid(0) == 0); |
173 if(uid_ok){ | 166 if (uid_ok) { |
174 gid_ok = (setegid(conf.mail_gid) == 0); | 167 gid_ok = (setegid(conf.mail_gid) == 0); |
175 uid_ok = (seteuid(pw->pw_uid) == 0); | 168 uid_ok = (seteuid(pw->pw_uid) == 0); |
176 } | 169 } |
177 } | 170 } |
178 | 171 |
179 DEBUG(5) debugf("running as euid %d\n", geteuid()); | 172 DEBUG(5) debugf("running as euid %d\n", geteuid()); |
180 DEBUG(5) debugf("running as egid %d\n", getegid()); | 173 DEBUG(5) debugf("running as egid %d\n", getegid()); |
181 | 174 |
182 if(uid_ok && gid_ok){ | 175 if (uid_ok && gid_ok) { |
183 char *path = g_strdup_printf("%s/Maildir", pw->pw_dir); | 176 char *path = g_strdup_printf("%s/Maildir", pw->pw_dir); |
184 struct stat statbuf; | 177 struct stat statbuf; |
185 int ret; | 178 int ret; |
186 | 179 |
187 DEBUG(5) debugf("path = %s\n", path); | 180 DEBUG(5) debugf("path = %s\n", path); |
188 | 181 |
189 ok = TRUE; | 182 ok = TRUE; |
190 ret = stat(path, &statbuf); | 183 ret = stat(path, &statbuf); |
191 if(ret != 0){ | 184 if (ret != 0) { |
192 ok = FALSE; | 185 ok = FALSE; |
193 if(errno == ENOENT){ | 186 if (errno == ENOENT) { |
194 logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path); | 187 logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path); |
195 if(mkdir(path, 0700) == 0) | 188 if (mkdir(path, 0700) == 0) |
196 ok = TRUE; | 189 ok = TRUE; |
197 }else | 190 } else |
198 logwrite(LOG_ALERT, "stat of %s failed: %s\n", path, strerror(errno)); | 191 logwrite(LOG_ALERT, "stat of %s failed: %s\n", path, strerror(errno)); |
199 } | 192 } |
200 if(ok){ | 193 if (ok) { |
201 ok = FALSE; | 194 ok = FALSE; |
202 ret = stat(path, &statbuf); | 195 ret = stat(path, &statbuf); |
203 if(S_ISDIR(statbuf.st_mode)){ | 196 if (S_ISDIR(statbuf.st_mode)) { |
204 gchar *subdirs[] = {"tmp", "new", "cur"}; | 197 gchar *subdirs[] = { "tmp", "new", "cur" }; |
205 int i; | 198 int i; |
206 for(i = 0; i < 3; i++){ | 199 for (i = 0; i < 3; i++) { |
207 char *path1 = g_strdup_printf("%s/%s", path, subdirs[i]); | 200 char *path1 = g_strdup_printf("%s/%s", path, subdirs[i]); |
208 ret = stat(path1, &statbuf); | 201 ret = stat(path1, &statbuf); |
209 if(ret != 0){ | 202 if (ret != 0) { |
210 if(errno == ENOENT){ | 203 if (errno == ENOENT) { |
211 logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path1); | 204 logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path1); |
212 if(mkdir(path1, 0700) != 0) break; | 205 if (mkdir(path1, 0700) != 0) |
213 } | 206 break; |
214 } | 207 } |
215 g_free(path1); | 208 } |
216 } | 209 g_free(path1); |
217 if(i == 3){ | 210 } |
218 FILE *out; | 211 if (i == 3) { |
219 mode_t saved_mode = umask(066); | 212 FILE *out; |
220 /* the qmail style unique works only if delivering | 213 mode_t saved_mode = umask(066); |
221 with different process. We do not fork for each delivery, | 214 /* the qmail style unique works only if delivering |
222 so our uid is more unique. Hope it is compatible with all | 215 with different process. We do not fork for each delivery, |
223 MUAs. | 216 so our uid is more unique. Hope it is compatible with all |
224 */ | 217 MUAs. |
225 gchar *filename = g_strdup_printf("%s/tmp/%s.%s", path, msg->uid, conf.host_name); | 218 */ |
226 | 219 gchar *filename = g_strdup_printf("%s/tmp/%s.%s", path, msg->uid, conf.host_name); |
227 DEBUG(5) debugf("filename = %s\n", filename); | 220 |
228 | 221 DEBUG(5) debugf("filename = %s\n", filename); |
229 if((out = fopen(filename, "w"))){ | 222 |
230 gchar *newname = | 223 if ((out = fopen(filename, "w"))) { |
231 g_strdup_printf("%s/new/%s.%s", path, msg->uid, conf.host_name); | 224 gchar *newname = g_strdup_printf("%s/new/%s.%s", path, msg->uid, conf.host_name); |
232 message_stream(out, msg, hdr_list, flags); | 225 message_stream(out, msg, hdr_list, flags); |
233 ok = TRUE; | 226 ok = TRUE; |
234 if(fflush(out) == EOF) ok = FALSE; | 227 if (fflush(out) == EOF) |
235 else if(fdatasync(fileno(out)) != 0){ | 228 ok = FALSE; |
236 if(errno != EINVAL) /* some fs do not support this.. | 229 else if (fdatasync(fileno(out)) != 0) { |
237 I hope this also means that it is not necessary */ | 230 if (errno != EINVAL) /* some fs do not support this.. I hope this also means that it is not necessary */ |
238 ok = FALSE; | 231 ok = FALSE; |
239 } | 232 } |
240 fclose(out); | 233 fclose(out); |
241 if(rename(filename, newname) != 0){ | 234 if (rename(filename, newname) != 0) { |
242 ok = FALSE; | 235 ok = FALSE; |
243 logwrite(LOG_ALERT, "moving %s to %s failed: %s", | 236 logwrite(LOG_ALERT, "moving %s to %s failed: %s", filename, newname, strerror(errno)); |
244 filename, newname, strerror(errno)); | 237 } |
245 } | 238 g_free(newname); |
246 g_free(newname); | 239 } |
247 } | 240 umask(saved_mode); |
248 umask(saved_mode); | 241 g_free(filename); |
249 g_free(filename); | 242 } |
250 } | 243 } else { |
251 }else{ | 244 logwrite(LOG_ALERT, "%s is not a directory\n", path); |
252 logwrite(LOG_ALERT, "%s is not a directory\n", path); | 245 errno = ENOTDIR; |
253 errno = ENOTDIR; | 246 } |
254 } | 247 } |
255 } | 248 if (!conf.run_as_user) { |
256 if(!conf.run_as_user){ | 249 uid_ok = (seteuid(0) == 0); |
257 uid_ok = (seteuid(0) == 0); | 250 if (uid_ok) { |
258 if(uid_ok){ | 251 gid_ok = (setegid(saved_gid) == 0); |
259 gid_ok = (setegid(saved_gid) == 0); | 252 uid_ok = (seteuid(saved_uid) == 0); |
260 uid_ok = (seteuid(saved_uid) == 0); | 253 } |
261 } | 254 } |
262 } | 255 if (!uid_ok || !gid_ok) { |
263 if(!uid_ok || !gid_ok){ | 256 /* FIXME: if this fails we HAVE to exit, because we shall not run |
264 /* FIXME: if this fails we HAVE to exit, because we shall not run | 257 with some users id. But we do not return, and so this message |
265 with some users id. But we do not return, and so this message | 258 will not be finished, so the user will get the message again |
266 will not be finished, so the user will get the message again | 259 next time a delivery is attempted... */ |
267 next time a delivery is attempted... */ | 260 logwrite(LOG_ALERT, "could not set back uid or gid after local delivery: %s\n", strerror(errno)); |
268 logwrite(LOG_ALERT, | 261 exit(EXIT_FAILURE); |
269 "could not set back uid or gid after local delivery: %s\n", | 262 } |
270 strerror(errno)); | 263 g_free(path); |
271 exit(EXIT_FAILURE); | 264 } else { |
272 } | 265 logwrite(LOG_ALERT, "could not set uid or gid for local delivery, uid = %d: %s\n", pw->pw_uid, strerror(errno)); |
273 g_free(path); | 266 } |
274 }else{ | 267 } else { |
275 logwrite(LOG_ALERT, | 268 logwrite(LOG_ALERT, "could not find password entry for user %s\n", user); |
276 "could not set uid or gid for local delivery, uid = %d: %s\n", | 269 errno = ENOENT; /* getpwnam does not set errno correctly */ |
277 pw->pw_uid, strerror(errno)); | 270 } |
278 } | 271 return ok; |
279 }else{ | |
280 logwrite(LOG_ALERT, "could not find password entry for user %s\n", user); | |
281 errno = ENOENT; /* getpwnam does not set errno correctly */ | |
282 } | |
283 return ok; | |
284 } | 272 } |
285 #endif | 273 #endif |
286 | 274 |
287 gboolean | 275 gboolean |
288 pipe_out(message *msg, GList *hdr_list, address *rcpt, gchar *cmd, guint flags) | 276 pipe_out(message * msg, GList * hdr_list, address * rcpt, gchar * cmd, guint flags) |
289 { | 277 { |
290 gchar *envp[40]; | 278 gchar *envp[40]; |
291 FILE *out; | 279 FILE *out; |
292 uid_t saved_uid = geteuid(); | 280 uid_t saved_uid = geteuid(); |
293 gid_t saved_gid = getegid(); | 281 gid_t saved_gid = getegid(); |
294 gboolean ok = FALSE; | 282 gboolean ok = FALSE; |
295 gint i, n; | 283 gint i, n; |
296 pid_t pid; | 284 pid_t pid; |
297 void (*old_signal)(int); | 285 void (*old_signal) (int); |
298 int status; | 286 int status; |
299 | 287 |
300 /* set uid and gid to the mail ids */ | 288 /* set uid and gid to the mail ids */ |
301 if(!conf.run_as_user){ | 289 if (!conf.run_as_user) { |
302 set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); | 290 set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); |
303 } | 291 } |
304 | 292 |
305 /* set environment */ | 293 /* set environment */ |
306 { | 294 { |
307 gint i = 0; | 295 gint i = 0; |
308 address *ancestor = addr_find_ancestor(rcpt); | 296 address *ancestor = addr_find_ancestor(rcpt); |
309 | 297 |
310 envp[i++] = g_strdup_printf("SENDER=%s@%s", msg->return_path->local_part, msg->return_path->domain); | 298 envp[i++] = g_strdup_printf("SENDER=%s@%s", msg->return_path->local_part, msg->return_path->domain); |
311 envp[i++] = g_strdup_printf("SENDER_DOMAIN=%s", msg->return_path->domain); | 299 envp[i++] = g_strdup_printf("SENDER_DOMAIN=%s", msg->return_path->domain); |
312 envp[i++] = g_strdup_printf("SENDER_LOCAL=%s", msg->return_path->local_part); | 300 envp[i++] = g_strdup_printf("SENDER_LOCAL=%s", msg->return_path->local_part); |
313 envp[i++] = g_strdup_printf("RECEIVED_HOST=%s", msg->received_host ? msg->received_host : ""); | 301 envp[i++] = g_strdup_printf("RECEIVED_HOST=%s", msg->received_host ? msg->received_host : ""); |
314 | 302 |
315 envp[i++] = g_strdup_printf("RETURN_PATH=%s@%s", | 303 envp[i++] = g_strdup_printf("RETURN_PATH=%s@%s", msg->return_path->local_part, msg->return_path->domain); |
316 msg->return_path->local_part, msg->return_path->domain); | 304 envp[i++] = g_strdup_printf("DOMAIN=%s", ancestor->domain); |
317 envp[i++] = g_strdup_printf("DOMAIN=%s", ancestor->domain); | 305 |
318 | 306 envp[i++] = g_strdup_printf("LOCAL_PART=%s", ancestor->local_part); |
319 envp[i++] = g_strdup_printf("LOCAL_PART=%s", ancestor->local_part); | 307 envp[i++] = g_strdup_printf("USER=%s", ancestor->local_part); |
320 envp[i++] = g_strdup_printf("USER=%s", ancestor->local_part); | 308 envp[i++] = g_strdup_printf("LOGNAME=%s", ancestor->local_part); |
321 envp[i++] = g_strdup_printf("LOGNAME=%s", ancestor->local_part); | 309 |
322 | 310 envp[i++] = g_strdup_printf("MESSAGE_ID=%s", msg->uid); |
323 envp[i++] = g_strdup_printf("MESSAGE_ID=%s", msg->uid); | 311 envp[i++] = g_strdup_printf("QUALIFY_DOMAIN=%s", conf.host_name); |
324 envp[i++] = g_strdup_printf("QUALIFY_DOMAIN=%s", conf.host_name); | 312 |
325 | 313 envp[i] = NULL; |
326 envp[i] = NULL; | 314 n = i; |
327 n = i; | 315 } |
328 } | 316 |
329 | 317 old_signal = signal(SIGCHLD, SIG_DFL); |
330 old_signal = signal(SIGCHLD, SIG_DFL); | 318 |
331 | 319 out = peidopen(cmd, "w", envp, &pid, conf.mail_uid, conf.mail_gid); |
332 out = peidopen(cmd, "w", envp, &pid, conf.mail_uid, conf.mail_gid); | 320 if (out != NULL) { |
333 if(out != NULL){ | 321 message_stream(out, msg, hdr_list, flags); |
334 message_stream(out, msg, hdr_list, flags); | 322 |
335 | 323 fclose(out); |
336 fclose(out); | 324 |
337 | 325 waitpid(pid, &status, 0); |
338 waitpid(pid, &status, 0); | 326 |
339 | 327 if (WEXITSTATUS(status) != 0) { |
340 if(WEXITSTATUS(status) != 0){ | 328 int exstat = WEXITSTATUS(status); |
341 int exstat = WEXITSTATUS(status); | 329 logwrite(LOG_ALERT, "process returned %d (%s)\n", exstat, ext_strerror(1024 + exstat)); |
342 logwrite(LOG_ALERT, "process returned %d (%s)\n", exstat, ext_strerror(1024 + exstat)); | 330 errno = 1024 + exstat; |
343 errno = 1024 + exstat; | 331 } else if (WIFSIGNALED(status)) { |
344 }else if(WIFSIGNALED(status)){ | 332 logwrite(LOG_ALERT, "process got signal %d\n", WTERMSIG(status)); |
345 logwrite(LOG_ALERT, "process got signal %d\n", WTERMSIG(status)); | 333 } else |
346 }else | 334 ok = TRUE; |
347 ok = TRUE; | 335 |
348 | 336 } else |
349 }else | 337 logwrite(LOG_ALERT, "could not open pipe '%s': %s\n", cmd, strerror(errno)); |
350 logwrite(LOG_ALERT, "could not open pipe '%s': %s\n", cmd, strerror(errno)); | 338 |
351 | 339 signal(SIGCHLD, old_signal); |
352 signal(SIGCHLD, old_signal); | 340 |
353 | 341 /* free environment */ |
354 /* free environment */ | 342 for (i = 0; i < n; i++) { |
355 for(i = 0; i < n; i++){ | 343 g_free(envp[i]); |
356 g_free(envp[i]); | 344 } |
357 } | 345 |
358 | 346 /* set uid and gid back */ |
359 /* set uid and gid back */ | 347 if (!conf.run_as_user) { |
360 if(!conf.run_as_user){ | 348 set_euidgid(saved_uid, saved_gid, NULL, NULL); |
361 set_euidgid(saved_uid, saved_gid, NULL, NULL); | 349 } |
362 } | 350 |
363 | 351 return ok; |
364 return ok; | |
365 } | 352 } |
366 |