According to the man page:
"sendmail contains a command, possibly with options, that mailx invokes to send mail. You must manually set the default for this environment variable by editing ROOTDIR/etc/mailx.rc to specify the mail agent of your choice. The default is sendmail, but it can be any command that takes addresses on the command line and message contents on standard input." * mail/mail.c (main): Register smtp_record too as a mailer. Set variable sendmail to _PATH_SENDMAIL as the default mailer. * mail/mail.h: New proto util_setenv(), util_find_env() change to be const char *. * mail/send.c (msg_to_pipe): New function, open a pipe() and write a message to it. (mail_send0): Now create the mailer according to util_find_env("sendmail")->value. Use a pipe() if mailer_create() fails. * mail/set.c (mail_set): After free(entry->value) set the value to NULL. * mail/util.c (util_find_env): Change the prototype to be const. Remove hack about need_free and use a static variable to hold "asksub". * mail/util.c (util_setenv): New function to set environment model on libc call setenv(). * mailbox/message.c (message_sender): Set the default sender base on the passwd entry.
Showing
7 changed files
with
176 additions
and
56 deletions
1 | 2001-07-05 Alain Magloire | 1 | 2001-07-05 Alain Magloire |
2 | 2 | ||
3 | According to the man page: | ||
4 | "sendmail contains a command, possibly with options, that mailx | ||
5 | invokes to send mail. You must manually set the default for this | ||
6 | environment variable by editing ROOTDIR/etc/mailx.rc to specify the | ||
7 | mail agent of your choice. The default is sendmail, but it can be any | ||
8 | command that takes addresses on the command line and message contents | ||
9 | on standard input." | ||
10 | |||
11 | * mail/mail.c (main): Register smtp_record too as a mailer. | ||
12 | Set variable sendmail to _PATH_SENDMAIL as the default mailer. | ||
13 | * mail/mail.h: New proto util_setenv(), util_find_env() | ||
14 | change to be const char *. | ||
15 | * mail/send.c (msg_to_pipe): New function, open a pipe() | ||
16 | and write a message to it. | ||
17 | (mail_send0): Now create the mailer according to | ||
18 | util_find_env("sendmail")->value. Use a pipe() if mailer_create() | ||
19 | fails. | ||
20 | * mail/set.c (mail_set): After free(entry->value) set the value | ||
21 | to NULL. | ||
22 | * mail/util.c (util_find_env): Change the prototype to be const. | ||
23 | Remove hack about need_free and use a static variable to hold | ||
24 | "asksub". | ||
25 | * mail/util.c (util_setenv): New function to set environment | ||
26 | model on libc call setenv(). | ||
27 | |||
28 | * mailbox/message.c (message_sender): Set the default sender base on | ||
29 | the passwd entry. | ||
30 | |||
31 | 2001-07-05 Alain Magloire | ||
32 | |||
3 | We can send a message and if the address starts with '|' | 33 | We can send a message and if the address starts with '|' |
4 | the message is pipe to the cmd and if starts with '/' it is | 34 | the message is pipe to the cmd and if starts with '/' it is |
5 | save to a file. | 35 | save to a file. | ... | ... |
... | @@ -182,8 +182,9 @@ main (int argc, char **argv) | ... | @@ -182,8 +182,9 @@ main (int argc, char **argv) |
182 | list_append (bookie, path_record); | 182 | list_append (bookie, path_record); |
183 | list_append (bookie, pop_record); | 183 | list_append (bookie, pop_record); |
184 | list_append (bookie, imap_record); | 184 | list_append (bookie, imap_record); |
185 | /* Only use sendmail for mail ?? */ | 185 | /* Possible supported mailers. */ |
186 | list_append (bookie, sendmail_record); | 186 | list_append (bookie, sendmail_record); |
187 | list_append (bookie, smtp_record); | ||
187 | } | 188 | } |
188 | 189 | ||
189 | interactive = isatty (fileno(stdin)); | 190 | interactive = isatty (fileno(stdin)); |
... | @@ -253,6 +254,14 @@ main (int argc, char **argv) | ... | @@ -253,6 +254,14 @@ main (int argc, char **argv) |
253 | util_do_command ("set toplines=5"); | 254 | util_do_command ("set toplines=5"); |
254 | util_do_command ("set autoinc"); | 255 | util_do_command ("set autoinc"); |
255 | 256 | ||
257 | /* Set the default mailer to sendmail. */ | ||
258 | { | ||
259 | char *mailer_name = alloca (strlen ("sendmail:") | ||
260 | + strlen (_PATH_SENDMAIL) + 1); | ||
261 | sprintf (mailer_name, "sendmail:%s", _PATH_SENDMAIL); | ||
262 | util_setenv ("sendmail", mailer_name, 0); | ||
263 | } | ||
264 | |||
256 | /* GNU extensions to the environment, for sparky's sanity */ | 265 | /* GNU extensions to the environment, for sparky's sanity */ |
257 | util_do_command ("set mode=read"); | 266 | util_do_command ("set mode=read"); |
258 | util_do_command ("set nobyname"); | 267 | util_do_command ("set nobyname"); | ... | ... |
... | @@ -221,8 +221,9 @@ struct mail_command_entry util_find_entry __P((const struct mail_command_entry * | ... | @@ -221,8 +221,9 @@ struct mail_command_entry util_find_entry __P((const struct mail_command_entry * |
221 | int util_getcols __P((void)); | 221 | int util_getcols __P((void)); |
222 | int util_getlines __P((void)); | 222 | int util_getlines __P((void)); |
223 | int util_screen_lines __P((void)); | 223 | int util_screen_lines __P((void)); |
224 | struct mail_env_entry *util_find_env __P((char *var)); | 224 | struct mail_env_entry *util_find_env __P((const char *var)); |
225 | int util_printenv __P((int set)); | 225 | int util_printenv __P((int set)); |
226 | int util_setenv __P((const char *name, const char *value, int overwrite)); | ||
226 | int util_isdeleted __P((int message)); | 227 | int util_isdeleted __P((int message)); |
227 | char *util_get_homedir __P((void)); | 228 | char *util_get_homedir __P((void)); |
228 | char *util_fullpath __P((char *inpath)); | 229 | char *util_fullpath __P((char *inpath)); | ... | ... |
... | @@ -25,6 +25,8 @@ | ... | @@ -25,6 +25,8 @@ |
25 | #include "mail.h" | 25 | #include "mail.h" |
26 | 26 | ||
27 | static int isfilename __P ((const char *)); | 27 | static int isfilename __P ((const char *)); |
28 | static void msg_to_pipe __P ((const char *cmd, message_t msg)); | ||
29 | |||
28 | /* | 30 | /* |
29 | * m[ail] address... | 31 | * m[ail] address... |
30 | if address is starting with | 32 | if address is starting with |
... | @@ -113,12 +115,20 @@ free_env_headers (struct send_environ *env) | ... | @@ -113,12 +115,20 @@ free_env_headers (struct send_environ *env) |
113 | If the variable "record" is set, the outgoing message is | 115 | If the variable "record" is set, the outgoing message is |
114 | saved after being sent. If "save_to" argument is non-zero, | 116 | saved after being sent. If "save_to" argument is non-zero, |
115 | the name of the save file is derived from "to" argument. Otherwise, | 117 | the name of the save file is derived from "to" argument. Otherwise, |
116 | it is taken from the value of "record" variable. */ | 118 | it is taken from the value of "record" variable. |
119 | |||
120 | sendmail | ||
121 | |||
122 | contains a command, possibly with options, that mailx invokes to send | ||
123 | mail. You must manually set the default for this environment variable | ||
124 | by editing ROOTDIR/etc/mailx.rc to specify the mail agent of your | ||
125 | choice. The default is sendmail, but it can be any command that takes | ||
126 | addresses on the command line and message contents on standard input. | ||
127 | */ | ||
117 | 128 | ||
118 | int | 129 | int |
119 | mail_send0 (struct send_environ *env, int save_to) | 130 | mail_send0 (struct send_environ *env, int save_to) |
120 | { | 131 | { |
121 | size_t n = 0; | ||
122 | int done = 0; | 132 | int done = 0; |
123 | int fd; | 133 | int fd; |
124 | char *filename; | 134 | char *filename; |
... | @@ -220,6 +230,7 @@ mail_send0 (struct send_environ *env, int save_to) | ... | @@ -220,6 +230,7 @@ mail_send0 (struct send_environ *env, int save_to) |
220 | free (buf); | 230 | free (buf); |
221 | } | 231 | } |
222 | 232 | ||
233 | /* If interrupted dumpt the file to dead.letter. */ | ||
223 | if (int_cnt) | 234 | if (int_cnt) |
224 | { | 235 | { |
225 | if (util_find_env ("save")->set) | 236 | if (util_find_env ("save")->set) |
... | @@ -259,17 +270,6 @@ mail_send0 (struct send_environ *env, int save_to) | ... | @@ -259,17 +270,6 @@ mail_send0 (struct send_environ *env, int save_to) |
259 | mailer_t mailer; | 270 | mailer_t mailer; |
260 | message_t msg = NULL; | 271 | message_t msg = NULL; |
261 | int status; | 272 | int status; |
262 | char *mailer_name = alloca (strlen ("sendmail:") | ||
263 | + strlen (_PATH_SENDMAIL) + 1); | ||
264 | sprintf (mailer_name, "sendmail:%s", _PATH_SENDMAIL); | ||
265 | if ((status = mailer_create (&mailer, mailer_name)) != 0 | ||
266 | || (status = mailer_open (mailer, MU_STREAM_RDWR)) != 0) | ||
267 | { | ||
268 | util_error ("%s: %s", mailer_name, strerror (status)); | ||
269 | remove (filename); | ||
270 | free (filename); | ||
271 | return 1; | ||
272 | } | ||
273 | message_create (&msg, NULL); | 273 | message_create (&msg, NULL); |
274 | 274 | ||
275 | /* Fill the header. */ | 275 | /* Fill the header. */ |
... | @@ -284,7 +284,7 @@ mail_send0 (struct send_environ *env, int save_to) | ... | @@ -284,7 +284,7 @@ mail_send0 (struct send_environ *env, int save_to) |
284 | header_set_value (header, MU_HEADER_BCC , strdup (env->bcc), 0); | 284 | header_set_value (header, MU_HEADER_BCC , strdup (env->bcc), 0); |
285 | if (env->subj && *env->subj != '\0') | 285 | if (env->subj && *env->subj != '\0') |
286 | header_set_value (header, MU_HEADER_SUBJECT, strdup (env->subj), 1); | 286 | header_set_value (header, MU_HEADER_SUBJECT, strdup (env->subj), 1); |
287 | header_set_value (header, "X-Mailer", strdup (argp_program_version), 1); | 287 | header_set_value (header, "X-Mailer", strdup(argp_program_version), 1); |
288 | } | 288 | } |
289 | 289 | ||
290 | /* Fill the body. */ | 290 | /* Fill the body. */ |
... | @@ -293,6 +293,7 @@ mail_send0 (struct send_environ *env, int save_to) | ... | @@ -293,6 +293,7 @@ mail_send0 (struct send_environ *env, int save_to) |
293 | stream_t stream = NULL; | 293 | stream_t stream = NULL; |
294 | off_t offset = 0; | 294 | off_t offset = 0; |
295 | char *buf = NULL; | 295 | char *buf = NULL; |
296 | size_t n = 0; | ||
296 | message_get_body (msg, &body); | 297 | message_get_body (msg, &body); |
297 | body_get_stream (body, &stream); | 298 | body_get_stream (body, &stream); |
298 | while (getline (&buf, &n, file) >= 0) | 299 | while (getline (&buf, &n, file) >= 0) |
... | @@ -325,10 +326,7 @@ mail_send0 (struct send_environ *env, int save_to) | ... | @@ -325,10 +326,7 @@ mail_send0 (struct send_environ *env, int save_to) |
325 | if (savefile) | 326 | if (savefile) |
326 | free (savefile); | 327 | free (savefile); |
327 | 328 | ||
328 | /* Send the message. */ | 329 | /* Check if we need to save the message to files or pipes. */ |
329 | mailer_send_message (mailer, msg); | ||
330 | |||
331 | /* Save the message to files or pipes */ | ||
332 | if (env->outfiles) | 330 | if (env->outfiles) |
333 | { | 331 | { |
334 | int i; | 332 | int i; |
... | @@ -336,27 +334,7 @@ mail_send0 (struct send_environ *env, int save_to) | ... | @@ -336,27 +334,7 @@ mail_send0 (struct send_environ *env, int save_to) |
336 | { | 334 | { |
337 | /* Pipe to a cmd. */ | 335 | /* Pipe to a cmd. */ |
338 | if (env->outfiles[i][0] == '|') | 336 | if (env->outfiles[i][0] == '|') |
339 | { | 337 | msg_to_pipe (&(env->outfiles[i][1]), msg); |
340 | FILE *fp = popen (&(env->outfiles[i][1]), "w"); | ||
341 | if (fp) | ||
342 | { | ||
343 | stream_t stream = NULL; | ||
344 | char buffer[512]; | ||
345 | off_t off = 0; | ||
346 | message_get_stream (msg, &stream); | ||
347 | while (stream_read (stream, buffer, | ||
348 | sizeof (buffer) - 1, off, &n) == 0 | ||
349 | && n != 0) | ||
350 | { | ||
351 | buffer[n] = '\0'; | ||
352 | fprintf (fp, "%s", buffer); | ||
353 | off += n; | ||
354 | } | ||
355 | fclose (fp); | ||
356 | } | ||
357 | else | ||
358 | util_error ("Piping %s failed", env->outfiles[i]); | ||
359 | } | ||
360 | /* Save to a file. */ | 338 | /* Save to a file. */ |
361 | else | 339 | else |
362 | { | 340 | { |
... | @@ -379,8 +357,33 @@ mail_send0 (struct send_environ *env, int save_to) | ... | @@ -379,8 +357,33 @@ mail_send0 (struct send_environ *env, int save_to) |
379 | } | 357 | } |
380 | } | 358 | } |
381 | } | 359 | } |
382 | message_destroy (&msg, NULL); | 360 | |
361 | /* Do we need to Send the message on the wire? */ | ||
362 | if ((env->to && *env->to != '\0') | ||
363 | || (env->cc && *env->cc != '\0') | ||
364 | || (env->bcc && *env->bcc != '\0')) | ||
365 | { | ||
366 | if (util_find_env ("sendmail")->set) | ||
367 | { | ||
368 | char *sendmail = util_find_env ("sendmail")->value; | ||
369 | status = mailer_create (&mailer, sendmail); | ||
370 | if (status == 0) | ||
371 | { | ||
372 | status = mailer_open (mailer, MU_STREAM_RDWR); | ||
373 | if (status == 0) | ||
374 | { | ||
375 | mailer_send_message (mailer, msg); | ||
376 | mailer_close (mailer); | ||
377 | } | ||
383 | mailer_destroy (&mailer); | 378 | mailer_destroy (&mailer); |
379 | } | ||
380 | if (status != 0) | ||
381 | msg_to_pipe (sendmail, msg); | ||
382 | } | ||
383 | else | ||
384 | util_error ("variable sendmail not set: no mailer"); | ||
385 | } | ||
386 | message_destroy (&msg, NULL); | ||
384 | remove (filename); | 387 | remove (filename); |
385 | free (filename); | 388 | free (filename); |
386 | return 0; | 389 | return 0; |
... | @@ -401,3 +404,29 @@ isfilename (const char *p) | ... | @@ -401,3 +404,29 @@ isfilename (const char *p) |
401 | return 1; | 404 | return 1; |
402 | return 0; | 405 | return 0; |
403 | } | 406 | } |
407 | |||
408 | /* FIXME: Should probably be in util.c. */ | ||
409 | /* Call pope(cmd) and write the message to it. */ | ||
410 | static void | ||
411 | msg_to_pipe (const char *cmd, message_t msg) | ||
412 | { | ||
413 | FILE *fp = popen (cmd, "w"); | ||
414 | if (fp) | ||
415 | { | ||
416 | stream_t stream = NULL; | ||
417 | char buffer[512]; | ||
418 | off_t off = 0; | ||
419 | int n = 0; | ||
420 | message_get_stream (msg, &stream); | ||
421 | while (stream_read (stream, buffer, sizeof (buffer) - 1, off, &n) == 0 | ||
422 | && n != 0) | ||
423 | { | ||
424 | buffer[n] = '\0'; | ||
425 | fprintf (fp, "%s", buffer); | ||
426 | off += n; | ||
427 | } | ||
428 | fclose (fp); | ||
429 | } | ||
430 | else | ||
431 | util_error ("Piping %s failed", cmd); | ||
432 | } | ... | ... |
... | @@ -47,6 +47,7 @@ mail_set (int argc, char **argv) | ... | @@ -47,6 +47,7 @@ mail_set (int argc, char **argv) |
47 | entry->set = 0; | 47 | entry->set = 0; |
48 | if (entry->value) | 48 | if (entry->value) |
49 | free (entry->value); | 49 | free (entry->value); |
50 | entry->value = NULL; | ||
50 | } | 51 | } |
51 | else if (i+1 < argc && argv[i+1][0] == '=') | 52 | else if (i+1 < argc && argv[i+1][0] == '=') |
52 | { | 53 | { | ... | ... |
... | @@ -452,23 +452,28 @@ util_screen_lines() | ... | @@ -452,23 +452,28 @@ util_screen_lines() |
452 | 452 | ||
453 | 453 | ||
454 | /* | 454 | /* |
455 | * find environment entry var | 455 | * Find environment entry var |
456 | |||
457 | FIXME: We should probably call this util_getenv to be consitent with | ||
458 | util_printenv(), util_setenv() etc .. | ||
456 | */ | 459 | */ |
457 | struct mail_env_entry * | 460 | struct mail_env_entry * |
458 | util_find_env (char *variable) | 461 | util_find_env (const char *variable) |
459 | { | 462 | { |
460 | char *var = variable; | 463 | /* Annoying, variable "ask" is equivalent to "asksub". */ |
461 | int len = strlen (var), need_free = 0; | 464 | static const char *asksub = "asksub"; |
465 | const char *var = variable; | ||
466 | int len = strlen (var); | ||
462 | node *t; | 467 | node *t; |
463 | 468 | ||
464 | if (len < 1) | 469 | if (len < 1) |
465 | return NULL; | 470 | return NULL; |
466 | 471 | ||
472 | /* Catch "ask" --> "asksub". */ | ||
467 | if (len == strlen ("ask") && !strcmp ("ask", var)) | 473 | if (len == strlen ("ask") && !strcmp ("ask", var)) |
468 | { | 474 | { |
469 | var = strdup ("asksub"); | 475 | var = asksub; |
470 | len = strlen (var); | 476 | len = strlen (var); |
471 | need_free = 1; | ||
472 | } | 477 | } |
473 | 478 | ||
474 | if (environment == NULL) | 479 | if (environment == NULL) |
... | @@ -486,8 +491,6 @@ util_find_env (char *variable) | ... | @@ -486,8 +491,6 @@ util_find_env (char *variable) |
486 | if (strlen (env_cursor->env_entry.var) == len && | 491 | if (strlen (env_cursor->env_entry.var) == len && |
487 | !strcmp (var, env_cursor->env_entry.var)) | 492 | !strcmp (var, env_cursor->env_entry.var)) |
488 | { | 493 | { |
489 | if (need_free) | ||
490 | free (var); | ||
491 | return &(env_cursor->env_entry); | 494 | return &(env_cursor->env_entry); |
492 | } | 495 | } |
493 | } | 496 | } |
... | @@ -497,8 +500,6 @@ util_find_env (char *variable) | ... | @@ -497,8 +500,6 @@ util_find_env (char *variable) |
497 | env_cursor->env_entry.value = NULL; | 500 | env_cursor->env_entry.value = NULL; |
498 | t = env_cursor; | 501 | t = env_cursor; |
499 | env_cursor = util_ll_add (env_cursor, 0); | 502 | env_cursor = util_ll_add (env_cursor, 0); |
500 | if (need_free) | ||
501 | free (var); | ||
502 | return &(t->env_entry); | 503 | return &(t->env_entry); |
503 | } | 504 | } |
504 | 505 | ||
... | @@ -523,6 +524,46 @@ util_printenv (int set) | ... | @@ -523,6 +524,46 @@ util_printenv (int set) |
523 | } | 524 | } |
524 | 525 | ||
525 | /* | 526 | /* |
527 | * Set environement | ||
528 | * The util_setenv() function adds the variable name to the envi- | ||
529 | * ronment with the value value, if name does not already | ||
530 | * exist. If name does exist in the environment, then its | ||
531 | * value is changed to value if overwrite is non-zero; if | ||
532 | * overwrite is zero, then the value of name is not changed. | ||
533 | * | ||
534 | * A side effect of the code is if value is null the variable name | ||
535 | * will be unset. | ||
536 | */ | ||
537 | int | ||
538 | util_setenv (const char *variable, const char *value, int overwrite) | ||
539 | { | ||
540 | struct mail_env_entry *ep = util_find_env (variable); | ||
541 | if (ep->set) | ||
542 | { | ||
543 | if (overwrite) | ||
544 | { | ||
545 | ep->set = 0; | ||
546 | if (ep->value) | ||
547 | free (ep->value); | ||
548 | ep->value = NULL; | ||
549 | if (value) | ||
550 | { | ||
551 | ep->set = 1; | ||
552 | ep->value = strdup (value); | ||
553 | } | ||
554 | } | ||
555 | } | ||
556 | else | ||
557 | { | ||
558 | ep->set = 1; | ||
559 | if (ep->value) | ||
560 | free (ep->value); | ||
561 | ep->value = strdup (value); | ||
562 | } | ||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | /* | ||
526 | * return 1 if a message is deleted | 567 | * return 1 if a message is deleted |
527 | */ | 568 | */ |
528 | int | 569 | int | ... | ... |
... | @@ -27,6 +27,7 @@ | ... | @@ -27,6 +27,7 @@ |
27 | #include <time.h> | 27 | #include <time.h> |
28 | #include <string.h> | 28 | #include <string.h> |
29 | #include <ctype.h> | 29 | #include <ctype.h> |
30 | #include <pwd.h> | ||
30 | 31 | ||
31 | #include "md5-rsa.h" | 32 | #include "md5-rsa.h" |
32 | 33 | ||
... | @@ -917,12 +918,20 @@ message_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite) | ... | @@ -917,12 +918,20 @@ message_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite) |
917 | else if (status == EAGAIN) | 918 | else if (status == EAGAIN) |
918 | return status; | 919 | return status; |
919 | 920 | ||
920 | /* oops */ | 921 | /* oops! We are still here */ |
921 | n = (7 > len) ? len: 7; | 922 | { |
923 | struct passwd *pw; | ||
924 | const char *sender; | ||
925 | pw = getpwuid (getuid ()); | ||
926 | sender = (pw) ? pw->pw_name : "unknown"; | ||
927 | n = strlen (sender); | ||
922 | if (buf && len > 0) | 928 | if (buf && len > 0) |
923 | { | 929 | { |
924 | memcpy (buf, "unknown", n); | 930 | len--; /* One for the null. */ |
925 | buf [n] = '\0'; | 931 | n = (n < len) ? n : len; |
932 | memcpy (buf, pw->pw_name, n); | ||
933 | buf[n] = '\0'; | ||
934 | } | ||
926 | } | 935 | } |
927 | 936 | ||
928 | if (pnwrite) | 937 | if (pnwrite) | ... | ... |
-
Please register or sign in to post a comment