Commit b3937510 b3937510f35b02b746ba9e8be659b328da7400be by Alain Magloire

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.
1 parent 2f77683c
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)
......