State now tracks whether its been opened, rather than segving.
Showing
1 changed file
with
47 additions
and
24 deletions
... | @@ -59,7 +59,7 @@ struct _sendmail | ... | @@ -59,7 +59,7 @@ struct _sendmail |
59 | pid_t pid; | 59 | pid_t pid; |
60 | off_t offset; | 60 | off_t offset; |
61 | int fd; | 61 | int fd; |
62 | enum sendmail_state { SENDMAIL_NO_STATE, SENDMAIL_SEND } state; | 62 | enum sendmail_state { SENDMAIL_CLOSED, SENDMAIL_OPEN, SENDMAIL_SEND } state; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | typedef struct _sendmail * sendmail_t; | 65 | typedef struct _sendmail * sendmail_t; |
... | @@ -78,7 +78,7 @@ _mailer_sendmail_init (mailer_t mailer) | ... | @@ -78,7 +78,7 @@ _mailer_sendmail_init (mailer_t mailer) |
78 | sendmail = mailer->data = calloc (1, sizeof (*sendmail)); | 78 | sendmail = mailer->data = calloc (1, sizeof (*sendmail)); |
79 | if (mailer->data == NULL) | 79 | if (mailer->data == NULL) |
80 | return ENOMEM; | 80 | return ENOMEM; |
81 | sendmail->state = SENDMAIL_NO_STATE; | 81 | sendmail->state = SENDMAIL_CLOSED; |
82 | mailer->_destroy = sendmail_destroy; | 82 | mailer->_destroy = sendmail_destroy; |
83 | mailer->_open = sendmail_open; | 83 | mailer->_open = sendmail_open; |
84 | mailer->_close = sendmail_close; | 84 | mailer->_close = sendmail_close; |
... | @@ -134,6 +134,7 @@ sendmail_open (mailer_t mailer, int flags) | ... | @@ -134,6 +134,7 @@ sendmail_open (mailer_t mailer, int flags) |
134 | return errno; | 134 | return errno; |
135 | } | 135 | } |
136 | sendmail->path = path; | 136 | sendmail->path = path; |
137 | sendmail->state = SENDMAIL_OPEN; | ||
137 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, "sendmail (%s)\n", sendmail->path); | 138 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, "sendmail (%s)\n", sendmail->path); |
138 | return 0; | 139 | return 0; |
139 | } | 140 | } |
... | @@ -141,12 +142,24 @@ sendmail_open (mailer_t mailer, int flags) | ... | @@ -141,12 +142,24 @@ sendmail_open (mailer_t mailer, int flags) |
141 | static int | 142 | static int |
142 | sendmail_close (mailer_t mailer) | 143 | sendmail_close (mailer_t mailer) |
143 | { | 144 | { |
144 | (void)mailer; | 145 | sendmail_t sendmail = mailer->data; |
146 | |||
147 | /* Sanity checks. */ | ||
148 | if (sendmail == NULL) | ||
149 | return EINVAL; | ||
150 | |||
151 | if(sendmail->path) | ||
152 | free(sendmail->path); | ||
153 | |||
154 | sendmail->path = NULL; | ||
155 | sendmail->state = SENDMAIL_CLOSED; | ||
156 | |||
145 | return 0; | 157 | return 0; |
146 | } | 158 | } |
147 | 159 | ||
148 | static int | 160 | static int |
149 | sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t to) | 161 | sendmail_send_message (mailer_t mailer, message_t msg, address_t from, |
162 | address_t to) | ||
150 | { | 163 | { |
151 | sendmail_t sendmail = mailer->data; | 164 | sendmail_t sendmail = mailer->data; |
152 | int status = 0; | 165 | int status = 0; |
... | @@ -156,7 +169,9 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -156,7 +169,9 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
156 | 169 | ||
157 | switch (sendmail->state) | 170 | switch (sendmail->state) |
158 | { | 171 | { |
159 | case SENDMAIL_NO_STATE: | 172 | case SENDMAIL_CLOSED: |
173 | return EINVAL; | ||
174 | case SENDMAIL_OPEN: | ||
160 | { | 175 | { |
161 | int tunnel[2]; | 176 | int tunnel[2]; |
162 | int argc = 0; | 177 | int argc = 0; |
... | @@ -173,7 +188,7 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -173,7 +188,7 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
173 | if (from) | 188 | if (from) |
174 | { | 189 | { |
175 | if ((status = address_aget_email (from, 1, &emailfrom)) != 0) | 190 | if ((status = address_aget_email (from, 1, &emailfrom)) != 0) |
176 | goto NO_STATE_CLEANUP; | 191 | goto OPEN_STATE_CLEANUP; |
177 | 192 | ||
178 | if (!emailfrom) | 193 | if (!emailfrom) |
179 | { | 194 | { |
... | @@ -181,9 +196,10 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -181,9 +196,10 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
181 | status = EINVAL; | 196 | status = EINVAL; |
182 | 197 | ||
183 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, | 198 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, |
184 | "envelope from (%s) not fully qualifed\n", emailfrom); | 199 | "envelope from (%s) not fully qualifed\n", |
200 | emailfrom); | ||
185 | 201 | ||
186 | goto NO_STATE_CLEANUP; | 202 | goto OPEN_STATE_CLEANUP; |
187 | } | 203 | } |
188 | 204 | ||
189 | argc += 2; /* -f from */ | 205 | argc += 2; /* -f from */ |
... | @@ -206,7 +222,7 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -206,7 +222,7 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
206 | if ((argvec = calloc (argc, sizeof (*argvec))) == 0) | 222 | if ((argvec = calloc (argc, sizeof (*argvec))) == 0) |
207 | { | 223 | { |
208 | status = ENOMEM; | 224 | status = ENOMEM; |
209 | goto NO_STATE_CLEANUP; | 225 | goto OPEN_STATE_CLEANUP; |
210 | } | 226 | } |
211 | 227 | ||
212 | argc = 0; | 228 | argc = 0; |
... | @@ -214,20 +230,20 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -214,20 +230,20 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
214 | if ((argvec[argc++] = strdup (sendmail->path)) == 0) | 230 | if ((argvec[argc++] = strdup (sendmail->path)) == 0) |
215 | { | 231 | { |
216 | status = ENOMEM; | 232 | status = ENOMEM; |
217 | goto NO_STATE_CLEANUP; | 233 | goto OPEN_STATE_CLEANUP; |
218 | } | 234 | } |
219 | 235 | ||
220 | if ((argvec[argc++] = strdup ("-oi")) == 0) | 236 | if ((argvec[argc++] = strdup ("-oi")) == 0) |
221 | { | 237 | { |
222 | status = ENOMEM; | 238 | status = ENOMEM; |
223 | goto NO_STATE_CLEANUP; | 239 | goto OPEN_STATE_CLEANUP; |
224 | } | 240 | } |
225 | if (from) | 241 | if (from) |
226 | { | 242 | { |
227 | if ((argvec[argc++] = strdup ("-f")) == 0) | 243 | if ((argvec[argc++] = strdup ("-f")) == 0) |
228 | { | 244 | { |
229 | status = ENOMEM; | 245 | status = ENOMEM; |
230 | goto NO_STATE_CLEANUP; | 246 | goto OPEN_STATE_CLEANUP; |
231 | } | 247 | } |
232 | argvec[argc++] = emailfrom; | 248 | argvec[argc++] = emailfrom; |
233 | } | 249 | } |
... | @@ -236,7 +252,7 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -236,7 +252,7 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
236 | if ((argvec[argc++] = strdup ("-t")) == 0) | 252 | if ((argvec[argc++] = strdup ("-t")) == 0) |
237 | { | 253 | { |
238 | status = ENOMEM; | 254 | status = ENOMEM; |
239 | goto NO_STATE_CLEANUP; | 255 | goto OPEN_STATE_CLEANUP; |
240 | } | 256 | } |
241 | } | 257 | } |
242 | else | 258 | else |
... | @@ -250,16 +266,17 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -250,16 +266,17 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
250 | { | 266 | { |
251 | char *email = 0; | 267 | char *email = 0; |
252 | if ((status = address_aget_email (to, i, &email)) != 0) | 268 | if ((status = address_aget_email (to, i, &email)) != 0) |
253 | goto NO_STATE_CLEANUP; | 269 | goto OPEN_STATE_CLEANUP; |
254 | if (!email) | 270 | if (!email) |
255 | { | 271 | { |
256 | /* the address wasn't fully qualified, choke (for now) */ | 272 | /* the address wasn't fully qualified, choke (for now) */ |
257 | status = EINVAL; | 273 | status = EINVAL; |
258 | 274 | ||
259 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, | 275 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, |
260 | "envelope to (%s) not fully qualifed\n", email); | 276 | "envelope to (%s) not fully qualifed\n", |
277 | email); | ||
261 | 278 | ||
262 | goto NO_STATE_CLEANUP; | 279 | goto OPEN_STATE_CLEANUP; |
263 | } | 280 | } |
264 | argvec[argc++] = email; | 281 | argvec[argc++] = email; |
265 | } | 282 | } |
... | @@ -286,17 +303,17 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -286,17 +303,17 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
286 | status = errno; | 303 | status = errno; |
287 | 304 | ||
288 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, | 305 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, |
289 | "vfork() failed: %s\n", strerror(status)); | 306 | "vfork() failed: %s\n", strerror (status)); |
290 | } | 307 | } |
291 | } | 308 | } |
292 | else | 309 | else |
293 | { | 310 | { |
294 | status = errno; | 311 | status = errno; |
295 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, | 312 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, |
296 | "pipe() failed: %s\n", strerror(status)); | 313 | "pipe() failed: %s\n", strerror (status)); |
297 | } | 314 | } |
298 | 315 | ||
299 | NO_STATE_CLEANUP: | 316 | OPEN_STATE_CLEANUP: |
300 | MAILER_DEBUG0 (mailer, MU_DEBUG_TRACE, "exec argv:"); | 317 | MAILER_DEBUG0 (mailer, MU_DEBUG_TRACE, "exec argv:"); |
301 | for (argc = 0; argvec && argvec[argc]; argc++) | 318 | for (argc = 0; argvec && argvec[argc]; argc++) |
302 | { | 319 | { |
... | @@ -315,7 +332,7 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -315,7 +332,7 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
315 | sendmail->state = SENDMAIL_SEND; | 332 | sendmail->state = SENDMAIL_SEND; |
316 | } | 333 | } |
317 | 334 | ||
318 | case SENDMAIL_SEND: /* Parent. */ | 335 | case SENDMAIL_SEND: |
319 | { | 336 | { |
320 | stream_t stream = NULL; | 337 | stream_t stream = NULL; |
321 | char buffer[512]; | 338 | char buffer[512]; |
... | @@ -332,7 +349,7 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -332,7 +349,7 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
332 | status = errno; | 349 | status = errno; |
333 | 350 | ||
334 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, | 351 | MAILER_DEBUG1 (mailer, MU_DEBUG_TRACE, |
335 | "write() failed: %s\n", strerror(status)); | 352 | "write() failed: %s\n", strerror (status)); |
336 | 353 | ||
337 | break; | 354 | break; |
338 | } | 355 | } |
... | @@ -340,21 +357,24 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -340,21 +357,24 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
340 | } | 357 | } |
341 | if (status == EAGAIN) | 358 | if (status == EAGAIN) |
342 | return status; | 359 | return status; |
360 | |||
343 | close (sendmail->fd); | 361 | close (sendmail->fd); |
362 | |||
344 | rc = waitpid (sendmail->pid, &status, 0); | 363 | rc = waitpid (sendmail->pid, &status, 0); |
364 | |||
345 | if (rc < 0) | 365 | if (rc < 0) |
346 | { | 366 | { |
347 | status = errno; | 367 | status = errno; |
348 | MAILER_DEBUG2 (mailer, MU_DEBUG_TRACE, | 368 | MAILER_DEBUG2 (mailer, MU_DEBUG_TRACE, |
349 | "waitpid(%d) failed: %s\n", | 369 | "waitpid(%d) failed: %s\n", |
350 | sendmail->pid, strerror(status)); | 370 | sendmail->pid, strerror (status)); |
351 | } | 371 | } |
352 | else if (WIFEXITED (status)) | 372 | else if (WIFEXITED (status)) |
353 | { | 373 | { |
354 | status = WEXITSTATUS (status); | 374 | status = WEXITSTATUS (status); |
355 | MAILER_DEBUG2 (mailer, MU_DEBUG_TRACE, | 375 | MAILER_DEBUG2 (mailer, MU_DEBUG_TRACE, |
356 | "%s exited with: %s\n", | 376 | "%s exited with: %s\n", |
357 | sendmail->path, strerror(status)); | 377 | sendmail->path, strerror (status)); |
358 | } | 378 | } |
359 | /* Shouldn't this notification only happen on success? */ | 379 | /* Shouldn't this notification only happen on success? */ |
360 | observable_notify (mailer->observable, MU_EVT_MAILER_MESSAGE_SENT); | 380 | observable_notify (mailer->observable, MU_EVT_MAILER_MESSAGE_SENT); |
... | @@ -363,6 +383,9 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t | ... | @@ -363,6 +383,9 @@ sendmail_send_message (mailer_t mailer, message_t msg, address_t from, address_t |
363 | break; | 383 | break; |
364 | } | 384 | } |
365 | 385 | ||
366 | sendmail->state = SENDMAIL_NO_STATE; | 386 | sendmail->state = SENDMAIL_OPEN; |
387 | |||
367 | return status; | 388 | return status; |
368 | } | 389 | } |
390 | |||
391 | ... | ... |
-
Please register or sign in to post a comment