Commit 203c6eb3 203c6eb363274b8463ff114b3e382952a2cff8b7 by Alain Magloire

supporting CC BCC when mailing.

1 parent ad9f147e
...@@ -47,8 +47,7 @@ extern void mailer_destroy __P ((mailer_t *)); ...@@ -47,8 +47,7 @@ extern void mailer_destroy __P ((mailer_t *));
47 extern int mailer_open __P ((mailer_t, int flags)); 47 extern int mailer_open __P ((mailer_t, int flags));
48 extern int mailer_close __P ((mailer_t)); 48 extern int mailer_close __P ((mailer_t));
49 49
50 extern int mailer_send_message __P ((mailer_t, const char *from, 50 extern int mailer_send_message __P ((mailer_t, message_t));
51 const char *rcpt, int dsn, message_t));
52 /* stream settings */ 51 /* stream settings */
53 extern int mailer_get_stream __P ((mailer_t, stream_t *)); 52 extern int mailer_get_stream __P ((mailer_t, stream_t *));
54 extern int mailer_set_stream __P ((mailer_t, stream_t)); 53 extern int mailer_set_stream __P ((mailer_t, stream_t));
......
...@@ -50,6 +50,9 @@ extern int message_create __P ((message_t *, void *owner)); ...@@ -50,6 +50,9 @@ extern int message_create __P ((message_t *, void *owner));
50 extern void message_destroy __P ((message_t *, void *owner)); 50 extern void message_destroy __P ((message_t *, void *owner));
51 extern void * message_get_owner __P ((message_t)); 51 extern void * message_get_owner __P ((message_t));
52 52
53 extern int message_ref __P ((message_t));
54 #define message_unref(msg) message_destroy (&msg)
55
53 extern int message_get_header __P ((message_t, header_t *)); 56 extern int message_get_header __P ((message_t, header_t *));
54 extern int message_set_header __P ((message_t, header_t, void *owner)); 57 extern int message_set_header __P ((message_t, header_t, void *owner));
55 58
......
...@@ -74,8 +74,7 @@ struct _mailer ...@@ -74,8 +74,7 @@ struct _mailer
74 void (*_destroy) __P ((mailer_t)); 74 void (*_destroy) __P ((mailer_t));
75 int (*_open) __P ((mailer_t, int flags)); 75 int (*_open) __P ((mailer_t, int flags));
76 int (*_close) __P ((mailer_t)); 76 int (*_close) __P ((mailer_t));
77 int (*_send_message) __P ((mailer_t, const char *from, const char *rcpt, 77 int (*_send_message) __P ((mailer_t, message_t));
78 int dsn, message_t));
79 }; 78 };
80 79
81 /* Mail locks. */ 80 /* Mail locks. */
......
...@@ -52,6 +52,9 @@ struct _message ...@@ -52,6 +52,9 @@ struct _message
52 mime_t mime; 52 mime_t mime;
53 observable_t observable; 53 observable_t observable;
54 54
55 /* Reference count. */
56 int ref;
57
55 /* Holder for message_write. */ 58 /* Holder for message_write. */
56 char *hdr_buf; 59 char *hdr_buf;
57 size_t hdr_buflen; 60 size_t hdr_buflen;
......
...@@ -156,12 +156,11 @@ mailer_close (mailer_t mailer) ...@@ -156,12 +156,11 @@ mailer_close (mailer_t mailer)
156 156
157 /* messages */ 157 /* messages */
158 int 158 int
159 mailer_send_message (mailer_t mailer, const char *from, const char *rcpt, 159 mailer_send_message (mailer_t mailer, message_t msg)
160 int dsn, message_t msg)
161 { 160 {
162 if (mailer == NULL || mailer->_send_message == NULL) 161 if (mailer == NULL || mailer->_send_message == NULL)
163 return ENOSYS; 162 return ENOSYS;
164 return mailer->_send_message (mailer, from, rcpt, dsn, msg); 163 return mailer->_send_message (mailer, msg);
165 } 164 }
166 165
167 int 166 int
......
...@@ -50,6 +50,7 @@ message_create (message_t *pmsg, void *owner) ...@@ -50,6 +50,7 @@ message_create (message_t *pmsg, void *owner)
50 if (msg == NULL) 50 if (msg == NULL)
51 return ENOMEM; 51 return ENOMEM;
52 msg->owner = owner; 52 msg->owner = owner;
53 msg->ref = 1;
53 *pmsg = msg; 54 *pmsg = msg;
54 return 0; 55 return 0;
55 } 56 }
...@@ -61,6 +62,7 @@ message_destroy (message_t *pmsg, void *owner) ...@@ -61,6 +62,7 @@ message_destroy (message_t *pmsg, void *owner)
61 { 62 {
62 message_t msg = *pmsg; 63 message_t msg = *pmsg;
63 64
65 msg->ref--;
64 if (msg->owner == owner) 66 if (msg->owner == owner)
65 { 67 {
66 /* Notify the listeners. */ 68 /* Notify the listeners. */
...@@ -91,6 +93,7 @@ message_destroy (message_t *pmsg, void *owner) ...@@ -91,6 +93,7 @@ message_destroy (message_t *pmsg, void *owner)
91 if (msg->mime) 93 if (msg->mime)
92 mime_destroy (&(msg->mime)); 94 mime_destroy (&(msg->mime));
93 95
96 if (msg->ref <= 0)
94 free (msg); 97 free (msg);
95 } 98 }
96 /* Loose the link */ 99 /* Loose the link */
...@@ -98,6 +101,14 @@ message_destroy (message_t *pmsg, void *owner) ...@@ -98,6 +101,14 @@ message_destroy (message_t *pmsg, void *owner)
98 } 101 }
99 } 102 }
100 103
104 int
105 message_ref (message_t msg)
106 {
107 if (msg)
108 msg->ref++;
109 return 0;
110 }
111
101 void * 112 void *
102 message_get_owner (message_t msg) 113 message_get_owner (message_t msg)
103 { 114 {
...@@ -132,7 +143,7 @@ message_set_header (message_t msg, header_t hdr, void *owner) ...@@ -132,7 +143,7 @@ message_set_header (message_t msg, header_t hdr, void *owner)
132 return EACCES; 143 return EACCES;
133 /* Make sure we destoy the old if it was own by the mesg */ 144 /* Make sure we destoy the old if it was own by the mesg */
134 /* FIXME: I do not know if somebody has already a ref on this ? */ 145 /* FIXME: I do not know if somebody has already a ref on this ? */
135 /* header_destroy (&(msg->header), msg); */ 146 header_destroy (&(msg->header), msg);
136 msg->header = hdr; 147 msg->header = hdr;
137 return 0; 148 return 0;
138 } 149 }
...@@ -165,7 +176,7 @@ message_set_body (message_t msg, body_t body, void *owner) ...@@ -165,7 +176,7 @@ message_set_body (message_t msg, body_t body, void *owner)
165 return EACCES; 176 return EACCES;
166 /* Make sure we destoy the old if it was own by the mesg. */ 177 /* Make sure we destoy the old if it was own by the mesg. */
167 /* FIXME: I do not know if somebody has already a ref on this ? */ 178 /* FIXME: I do not know if somebody has already a ref on this ? */
168 /* body_destroy (&(msg->body), msg); */ 179 body_destroy (&(msg->body), msg);
169 msg->body = body; 180 msg->body = body;
170 return 0; 181 return 0;
171 } 182 }
...@@ -177,6 +188,9 @@ message_set_stream (message_t msg, stream_t stream, void *owner) ...@@ -177,6 +188,9 @@ message_set_stream (message_t msg, stream_t stream, void *owner)
177 return EINVAL; 188 return EINVAL;
178 if (msg->owner != owner) 189 if (msg->owner != owner)
179 return EACCES; 190 return EACCES;
191 /* Make sure we destoy the old if it was own by the mesg. */
192 /* FIXME: I do not know if somebody has already a ref on this ? */
193 stream_destroy (&(msg->stream), msg);
180 msg->stream = stream; 194 msg->stream = stream;
181 return 0; 195 return 0;
182 } 196 }
......
...@@ -72,8 +72,7 @@ typedef struct _sendmail * sendmail_t; ...@@ -72,8 +72,7 @@ typedef struct _sendmail * sendmail_t;
72 static void sendmail_destroy (mailer_t); 72 static void sendmail_destroy (mailer_t);
73 static int sendmail_open (mailer_t, int); 73 static int sendmail_open (mailer_t, int);
74 static int sendmail_close (mailer_t); 74 static int sendmail_close (mailer_t);
75 static int sendmail_send_message (mailer_t, const char *from, const char *rcpt, 75 static int sendmail_send_message (mailer_t, message_t);
76 int dsn, message_t);
77 76
78 int 77 int
79 sendmail_init (mailer_t mailer) 78 sendmail_init (mailer_t mailer)
...@@ -148,8 +147,7 @@ sendmail_close (mailer_t mailer) ...@@ -148,8 +147,7 @@ sendmail_close (mailer_t mailer)
148 } 147 }
149 148
150 static int 149 static int
151 sendmail_send_message (mailer_t mailer, const char *from, const char *rcpt, 150 sendmail_send_message (mailer_t mailer, message_t msg)
152 int dsn, message_t msg)
153 { 151 {
154 sendmail_t sendmail = mailer->data; 152 sendmail_t sendmail = mailer->data;
155 int status = 0; 153 int status = 0;
...@@ -157,8 +155,6 @@ sendmail_send_message (mailer_t mailer, const char *from, const char *rcpt, ...@@ -157,8 +155,6 @@ sendmail_send_message (mailer_t mailer, const char *from, const char *rcpt,
157 if (sendmail == NULL || msg == NULL) 155 if (sendmail == NULL || msg == NULL)
158 return EINVAL; 156 return EINVAL;
159 157
160 sendmail->dsn = dsn;
161
162 switch (sendmail->state) 158 switch (sendmail->state)
163 { 159 {
164 case SENDMAIL_NO_STATE: 160 case SENDMAIL_NO_STATE:
...@@ -173,45 +169,6 @@ sendmail_send_message (mailer_t mailer, const char *from, const char *rcpt, ...@@ -173,45 +169,6 @@ sendmail_send_message (mailer_t mailer, const char *from, const char *rcpt,
173 argvec[1] = strdup ("-oi"); 169 argvec[1] = strdup ("-oi");
174 argvec[2] = strdup ("-t"); 170 argvec[2] = strdup ("-t");
175 171
176 if (from)
177 {
178 size_t len = strlen (from) + 1;
179 char *addr = calloc (len, sizeof (char));
180 if (parseaddr (from, addr, len) == 0)
181 {
182 argc++;
183 argvec = realloc (argvec, argc * (sizeof (*argvec)));
184 argvec[argc - 1] = strdup ("-f");
185 argc++;
186 argvec = realloc (argvec, argc * (sizeof (*argvec)));
187 argvec[argc - 1] = addr;
188 }
189 else
190 free (addr);
191 }
192
193 if (rcpt)
194 {
195 const char *p = rcpt;
196 do
197 {
198 size_t len = strlen (p) + 1;
199 char *addr = calloc (len, sizeof (char));
200 if (parseaddr (rcpt, addr, len) == 0)
201 {
202 argc++;
203 argvec = realloc (argvec, argc * (sizeof (*argvec)));
204 argvec[argc - 1] = addr;
205 }
206 else
207 free (addr);
208 p = strchr (p, ',');
209 if (p != NULL)
210 p++;
211 }
212 while (p != NULL && *p != '\0');
213 }
214
215 argc++; 172 argc++;
216 argvec = realloc (argvec, argc * (sizeof (*argvec))); 173 argvec = realloc (argvec, argc * (sizeof (*argvec)));
217 argvec[argc - 1] = NULL; 174 argvec[argc - 1] = NULL;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
29 #include <netdb.h> 29 #include <netdb.h>
30 30
31 #include <mailutils/stream.h> 31 #include <mailutils/stream.h>
32 #include <mailutils/address.h>
32 #include <mailer0.h> 33 #include <mailer0.h>
33 #include <registrar0.h> 34 #include <registrar0.h>
34 #include <bio.h> 35 #include <bio.h>
...@@ -77,8 +78,9 @@ struct _smtp ...@@ -77,8 +78,9 @@ struct _smtp
77 SMTP_SEND_DOT 78 SMTP_SEND_DOT
78 } state; 79 } state;
79 int extended; 80 int extended;
80 char *from; 81 address_t mail_from;
81 char *to; 82 address_t rcpt_to;
83 size_t rcpt_index;
82 off_t offset; 84 off_t offset;
83 int dsn; 85 int dsn;
84 message_t message; 86 message_t message;
...@@ -133,13 +135,15 @@ while (0) ...@@ -133,13 +135,15 @@ while (0)
133 static void smtp_destroy (mailer_t); 135 static void smtp_destroy (mailer_t);
134 static int smtp_open (mailer_t, int); 136 static int smtp_open (mailer_t, int);
135 static int smtp_close (mailer_t); 137 static int smtp_close (mailer_t);
136 static int smtp_send_message (mailer_t, const char *from, const char *rcpt, 138 static int smtp_send_message (mailer_t, message_t);
137 int dsn, message_t);
138 static int smtp_writeline (smtp_t smtp, const char *format, ...); 139 static int smtp_writeline (smtp_t smtp, const char *format, ...);
139 static int smtp_readline (smtp_t); 140 static int smtp_readline (smtp_t);
140 static int smtp_read_ack (smtp_t); 141 static int smtp_read_ack (smtp_t);
141 static int smtp_write (smtp_t); 142 static int smtp_write (smtp_t);
142 143
144 static int get_rcpt (message_t , address_t *);
145 static int get_from (message_t , char *, address_t *);
146
143 int 147 int
144 smtp_init (mailer_t mailer) 148 smtp_init (mailer_t mailer)
145 { 149 {
...@@ -173,10 +177,10 @@ smtp_destroy(mailer_t mailer) ...@@ -173,10 +177,10 @@ smtp_destroy(mailer_t mailer)
173 bio_destroy (&(smtp->bio)); 177 bio_destroy (&(smtp->bio));
174 if (smtp->buffer) 178 if (smtp->buffer)
175 free (smtp->buffer); 179 free (smtp->buffer);
176 if (smtp->from) 180 if (smtp->mail_from)
177 free (smtp->from); 181 address_destroy (&(smtp->mail_from));
178 if (smtp->to) 182 if (smtp->rcpt_to)
179 free (smtp->to); 183 address_destroy (&(smtp->rcpt_to));
180 free (smtp); 184 free (smtp);
181 mailer->data = NULL; 185 mailer->data = NULL;
182 } 186 }
...@@ -404,8 +408,7 @@ smtp_close (mailer_t mailer) ...@@ -404,8 +408,7 @@ smtp_close (mailer_t mailer)
404 } 408 }
405 409
406 static int 410 static int
407 smtp_send_message(mailer_t mailer, const char *from, const char *rcpt, 411 smtp_send_message(mailer_t mailer, message_t msg)
408 int dsn, message_t msg)
409 { 412 {
410 smtp_t smtp = mailer->data; 413 smtp_t smtp = mailer->data;
411 int status; 414 int status;
...@@ -416,127 +419,30 @@ smtp_send_message(mailer_t mailer, const char *from, const char *rcpt, ...@@ -416,127 +419,30 @@ smtp_send_message(mailer_t mailer, const char *from, const char *rcpt,
416 switch (smtp->state) 419 switch (smtp->state)
417 { 420 {
418 case SMTP_NO_STATE: 421 case SMTP_NO_STATE:
419 smtp->dsn = dsn;
420 smtp->state = SMTP_ENV_FROM; 422 smtp->state = SMTP_ENV_FROM;
423 status = get_from (msg, smtp->localhost, &smtp->mail_from);
424 CHECK_ERROR (smtp, status);
425 status = get_rcpt (msg, &smtp->rcpt_to);
426 CHECK_ERROR (smtp, status);
421 427
422 case SMTP_ENV_FROM: 428 case SMTP_ENV_FROM:
423 if (smtp->from)
424 { 429 {
425 free (smtp->from); 430 size_t len = 0;
426 smtp->from = NULL; 431 char *from;
427 } 432 address_get_email (smtp->mail_from, 1, NULL, 0, &len);
428 /* Try to fetch it from the header. */ 433 if (len == 0)
434 CHECK_ERROR (smtp, EINVAL);
435 from = calloc (len + 1, sizeof (char));
429 if (from == NULL) 436 if (from == NULL)
430 {
431 header_t header;
432 size_t size;
433 message_get_header (msg, &header);
434 status = header_get_value (header, MU_HEADER_FROM, NULL, 0, &size);
435 if (status == EAGAIN)
436 return status;
437 /* If it's not in the header create one form the passwd. */
438 if (status != 0)
439 {
440 struct passwd *pwd = getpwuid (getuid ());
441 /* Not in the passwd ???? We have a problem. */
442 if (pwd == 0 || pwd->pw_name == NULL)
443 {
444 size_t len = 10 + strlen (smtp->localhost) + 1;
445 smtp->from = calloc (len, sizeof (char));
446 if (smtp->from == NULL)
447 {
448 CHECK_ERROR (smtp, ENOMEM);
449 }
450 snprintf (smtp->from, len, "%d@%s", getuid(),
451 smtp->localhost);
452 }
453 else
454 {
455 smtp->from = calloc (strlen (pwd->pw_name) + 1
456 + strlen (smtp->localhost) + 1,
457 sizeof (char));
458 if (smtp->from == NULL)
459 {
460 CHECK_ERROR (smtp, ENOMEM);
461 }
462 sprintf(smtp->from, "%s@%s", pwd->pw_name, smtp->localhost);
463 }
464 }
465 else
466 {
467 smtp->from = calloc (size + 1, sizeof (char));
468 if (smtp->from == NULL)
469 {
470 CHECK_ERROR (smtp, ENOMEM);
471 }
472 status = header_get_value (header, MU_HEADER_FROM, smtp->from,
473 size + 1, NULL);
474 CHECK_EAGAIN (smtp, status);
475 }
476 }
477 else
478 {
479 smtp->from = strdup (from);
480 if (smtp->from == NULL)
481 {
482 CHECK_ERROR (smtp, ENOMEM); 437 CHECK_ERROR (smtp, ENOMEM);
483 } 438 address_get_email (smtp->mail_from, 1, from, len + 1, NULL);
484 } 439 status = smtp_writeline (smtp, "MAIL FROM: %s\r\n", from);
485 /* Check if a Fully Qualified Name, some smtp servers 440 free (from);
486 notably sendmail insists on it, for good reasons. */ 441 address_destroy (&smtp->mail_from);
487 if (strchr (smtp->from, '@') == NULL)
488 {
489 char *tmp;
490 tmp = malloc (strlen (smtp->from) + 1 +strlen (smtp->localhost) + 1);
491 if (tmp == NULL)
492 {
493 free (smtp->from);
494 smtp->from = NULL;
495 CHECK_ERROR (smtp, ENOMEM);
496 }
497 sprintf (tmp, "%s@%s", smtp->from, smtp->localhost);
498 free (smtp->from);
499 smtp->from = tmp;
500 }
501 smtp->state = SMTP_ENV_RCPT;
502
503 case SMTP_ENV_RCPT:
504 if (smtp->to)
505 {
506 free (smtp->to);
507 smtp->to = NULL;
508 }
509 if (rcpt == NULL)
510 {
511 header_t header;
512 size_t size;
513 message_get_header (msg, &header);
514 status = header_get_value (header, MU_HEADER_TO, NULL, 0, &size);
515 CHECK_EAGAIN (smtp, status);
516 smtp->to = calloc (size + 1, sizeof (char));
517 if (smtp->to == NULL)
518 {
519 CHECK_ERROR (smtp, ENOMEM);
520 }
521 status = header_get_value (header, MU_HEADER_TO, smtp->to,
522 size + 1, NULL);
523 CHECK_EAGAIN (smtp, status);
524 }
525 else
526 {
527 smtp->to = strdup (rcpt);
528 if (smtp->to == NULL)
529 {
530 CHECK_ERROR (smtp, ENOMEM);
531 }
532 }
533
534 status = smtp_writeline (smtp, "MAIL FROM: %s\r\n", smtp->from);
535 free (smtp->from);
536 smtp->from = NULL;
537 CHECK_ERROR (smtp, status); 442 CHECK_ERROR (smtp, status);
538 MAILER_DEBUG0 (mailer, MU_DEBUG_PROT, smtp->buffer); 443 MAILER_DEBUG0 (mailer, MU_DEBUG_PROT, smtp->buffer);
539 smtp->state = SMTP_MAIL_FROM; 444 smtp->state = SMTP_MAIL_FROM;
445 }
540 446
541 case SMTP_MAIL_FROM: 447 case SMTP_MAIL_FROM:
542 status = smtp_write (smtp); 448 status = smtp_write (smtp);
...@@ -553,37 +459,51 @@ smtp_send_message(mailer_t mailer, const char *from, const char *rcpt, ...@@ -553,37 +459,51 @@ smtp_send_message(mailer_t mailer, const char *from, const char *rcpt,
553 CLEAR_STATE (smtp); 459 CLEAR_STATE (smtp);
554 return EACCES; 460 return EACCES;
555 } 461 }
462
556 /* We use a goto, since we may have multiple recipients, 463 /* We use a goto, since we may have multiple recipients,
557 we come back here and doit all over again ... Not pretty. */ 464 we come back here and doit all over again ... Not pretty. */
465 case SMTP_ENV_RCPT:
558 RCPT_TO: 466 RCPT_TO:
559 { 467 {
560 char *buf; 468 size_t i = 0;
561 size_t len = strlen (smtp->to) + 1; 469 smtp->rcpt_index++;
562 buf = calloc (len, sizeof (char)); 470 address_get_count (smtp->rcpt_to, &i);
563 if (buf == NULL) 471 if (smtp->rcpt_index <= i)
564 {
565 CHECK_ERROR (smtp, ENOMEM);
566 }
567 if (parseaddr (smtp->to, buf, len) != 0)
568 { 472 {
569 free (buf); 473 size_t len = 0;
474 char *to;
475 address_get_email (smtp->rcpt_to, smtp->rcpt_index, NULL, 0, &len);
476 if (len == 0)
570 CHECK_ERROR (smtp, EINVAL); 477 CHECK_ERROR (smtp, EINVAL);
571 } 478 to = calloc (len + 1, sizeof (char));
572 status = smtp_writeline (smtp, "RCPT TO: %s\r\n", buf); 479 if (to == NULL)
573 free (buf); 480 CHECK_ERROR (smtp, ENOMEM);
481 address_get_email (smtp->rcpt_to, smtp->rcpt_index, to, len + 1, NULL);
482 status = smtp_writeline (smtp, "RCPT TO: %s\r\n", to);
483 free (to);
574 CHECK_ERROR (smtp, status); 484 CHECK_ERROR (smtp, status);
575 MAILER_DEBUG0 (mailer, MU_DEBUG_PROT, smtp->buffer); 485 MAILER_DEBUG0 (mailer, MU_DEBUG_PROT, smtp->buffer);
576 smtp->state = SMTP_RCPT_TO; 486 smtp->state = SMTP_RCPT_TO;
577 } 487 }
488 else
489 {
490 address_destroy (&(smtp->rcpt_to));
491 smtp->rcpt_index = 0;
492 smtp->state = SMTP_DATA;
493 }
494 }
578 495
579 case SMTP_RCPT_TO: 496 case SMTP_RCPT_TO:
497 if (smtp->rcpt_to)
498 {
580 status = smtp_write (smtp); 499 status = smtp_write (smtp);
581 CHECK_EAGAIN (smtp, status); 500 CHECK_EAGAIN (smtp, status);
582 smtp->state = SMTP_RCPT_TO_ACK; 501 smtp->state = SMTP_RCPT_TO_ACK;
502 }
583 503
584 case SMTP_RCPT_TO_ACK: 504 case SMTP_RCPT_TO_ACK:
505 if (smtp->rcpt_to)
585 { 506 {
586 char *p;
587 status = smtp_read_ack (smtp); 507 status = smtp_read_ack (smtp);
588 CHECK_EAGAIN (smtp, status); 508 CHECK_EAGAIN (smtp, status);
589 MAILER_DEBUG0 (mailer, MU_DEBUG_PROT, smtp->buffer); 509 MAILER_DEBUG0 (mailer, MU_DEBUG_PROT, smtp->buffer);
...@@ -593,28 +513,13 @@ smtp_send_message(mailer_t mailer, const char *from, const char *rcpt, ...@@ -593,28 +513,13 @@ smtp_send_message(mailer_t mailer, const char *from, const char *rcpt,
593 CLEAR_STATE (smtp); 513 CLEAR_STATE (smtp);
594 return EACCES; 514 return EACCES;
595 } 515 }
596 /* Do we have multiple recipients ? */
597 p = strchr (smtp->to, ',');
598 if (p != NULL)
599 {
600 char *tmp = smtp->to;
601 smtp->to = strdup (p++);
602 if (smtp->to == NULL)
603 {
604 free (tmp);
605 CHECK_ERROR (smtp, ENOMEM);
606 }
607 free (tmp);
608 goto RCPT_TO; 516 goto RCPT_TO;
609 } 517 }
610 /* We are done with the rcpt. */ 518 /* We are done with the rcpt. */
611 free (smtp->to);
612 smtp->to = NULL;
613 status = smtp_writeline (smtp, "DATA\r\n"); 519 status = smtp_writeline (smtp, "DATA\r\n");
614 CHECK_ERROR (smtp, status); 520 CHECK_ERROR (smtp, status);
615 MAILER_DEBUG0 (mailer, MU_DEBUG_PROT, smtp->buffer); 521 MAILER_DEBUG0 (mailer, MU_DEBUG_PROT, smtp->buffer);
616 smtp->state = SMTP_DATA; 522 smtp->state = SMTP_DATA;
617 }
618 523
619 case SMTP_DATA: 524 case SMTP_DATA:
620 status = smtp_write (smtp); 525 status = smtp_write (smtp);
...@@ -693,6 +598,125 @@ smtp_send_message(mailer_t mailer, const char *from, const char *rcpt, ...@@ -693,6 +598,125 @@ smtp_send_message(mailer_t mailer, const char *from, const char *rcpt,
693 } 598 }
694 599
695 static int 600 static int
601 get_from (message_t msg, char *localhost, address_t *pmail_from)
602 {
603 int status;
604 size_t size = 0;
605 char *from;
606 header_t header = NULL;
607
608 message_get_header (msg, &header);
609 status = header_get_value (header, MU_HEADER_FROM, NULL, 0, &size);
610 /* If it's not in the header create one form the passwd. */
611 if (status != 0 || size == 0)
612 {
613 struct passwd *pwd = getpwuid (getuid ());
614 /* Not in the passwd ???? We have a problem. */
615 if (pwd == 0 || pwd->pw_name == NULL)
616 {
617 size = 10 + strlen (localhost) + 1;
618 from = calloc (size, sizeof (char));
619 if (from == NULL)
620 return ENOMEM;
621 snprintf (from, size, "%d@%s", getuid(), localhost);
622 }
623 else
624 {
625 from = calloc (strlen (pwd->pw_name) + 1
626 + strlen (localhost) + 1, sizeof (char));
627 if (from == NULL)
628 return ENOMEM;
629 sprintf(from, "%s@%s", pwd->pw_name, localhost);
630 }
631 }
632 else
633 {
634 from = calloc (size + 1, sizeof (char));
635 if (from == NULL)
636 return ENOMEM;
637 header_get_value (header, MU_HEADER_FROM, from, size + 1, NULL);
638 }
639 /* Check if a Fully Qualified Name, some smtp servers
640 notably sendmail insists on it, for good reasons. */
641 if (strchr (from, '@') == NULL)
642 {
643 char *tmp;
644 tmp = malloc (strlen (from) + 1 +strlen (localhost) + 1);
645 if (tmp == NULL)
646 {
647 free (from);
648 return ENOMEM;
649 }
650 sprintf (tmp, "%s@%s", from, localhost);
651 free (from);
652 from = tmp;
653 }
654 status = address_create (pmail_from, from);
655 free (from);
656 return status;
657 }
658
659 static int
660 get_rcpt (message_t msg, address_t *prcpt_to)
661 {
662 char *rcpt;
663 int status;
664 size_t size = 0;
665 header_t header = NULL;
666
667 message_get_header (msg, &header);
668 status = header_get_value (header, MU_HEADER_TO, NULL, 0, &size);
669 if (status == 0 && size != 0)
670 {
671 char *tmp;
672 size_t len;
673 rcpt = calloc (size + 1, sizeof (char));
674 if (rcpt == NULL)
675 return ENOMEM;
676 header_get_value (header, MU_HEADER_TO, rcpt, size + 1, NULL);
677
678 size = 0;
679 status = header_get_value (header, MU_HEADER_CC, NULL, 0, &size);
680 if (status == 0 && size != 0)
681 {
682 len = strlen (rcpt);
683 tmp = realloc (rcpt, (len + 1 + size + 1) * sizeof (char));
684 if (tmp == NULL)
685 {
686 free (rcpt);
687 return ENOMEM;
688 }
689 else
690 rcpt = tmp;
691 rcpt[len] = ',';
692 header_get_value (header, MU_HEADER_CC, rcpt + len + 1,
693 size + 1, NULL);
694
695 size = 0;
696 status = header_get_value (header, MU_HEADER_BCC, NULL, 0, &size);
697 if (status == 0 && size != 0)
698 {
699 len = strlen (rcpt);
700 tmp = realloc (rcpt, (len + 1 + size + 1) * sizeof (char));
701 if (tmp == NULL)
702 {
703 free (rcpt);
704 return ENOMEM;
705 }
706 else
707 rcpt = tmp;
708 rcpt[len] = ',';
709 header_get_value (header, MU_HEADER_BCC, rcpt + len + 1,
710 size + 1, NULL);
711 }
712 }
713 status = address_create (prcpt_to, rcpt);
714 free (rcpt);
715 return status;
716 }
717 return EINVAL;
718 }
719 static int
696 smtp_writeline (smtp_t smtp, const char *format, ...) 720 smtp_writeline (smtp_t smtp, const char *format, ...)
697 { 721 {
698 int len; 722 int len;
......