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
2001-07-05 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.
2001-07-05 Alain Magloire
We can send a message and if the address starts with '|'
the message is pipe to the cmd and if starts with '/' it is
save to a file.
......
......@@ -182,8 +182,9 @@ main (int argc, char **argv)
list_append (bookie, path_record);
list_append (bookie, pop_record);
list_append (bookie, imap_record);
/* Only use sendmail for mail ?? */
/* Possible supported mailers. */
list_append (bookie, sendmail_record);
list_append (bookie, smtp_record);
}
interactive = isatty (fileno(stdin));
......@@ -253,6 +254,14 @@ main (int argc, char **argv)
util_do_command ("set toplines=5");
util_do_command ("set autoinc");
/* Set the default mailer to sendmail. */
{
char *mailer_name = alloca (strlen ("sendmail:")
+ strlen (_PATH_SENDMAIL) + 1);
sprintf (mailer_name, "sendmail:%s", _PATH_SENDMAIL);
util_setenv ("sendmail", mailer_name, 0);
}
/* GNU extensions to the environment, for sparky's sanity */
util_do_command ("set mode=read");
util_do_command ("set nobyname");
......
......@@ -221,8 +221,9 @@ struct mail_command_entry util_find_entry __P((const struct mail_command_entry *
int util_getcols __P((void));
int util_getlines __P((void));
int util_screen_lines __P((void));
struct mail_env_entry *util_find_env __P((char *var));
struct mail_env_entry *util_find_env __P((const char *var));
int util_printenv __P((int set));
int util_setenv __P((const char *name, const char *value, int overwrite));
int util_isdeleted __P((int message));
char *util_get_homedir __P((void));
char *util_fullpath __P((char *inpath));
......
......@@ -25,6 +25,8 @@
#include "mail.h"
static int isfilename __P ((const char *));
static void msg_to_pipe __P ((const char *cmd, message_t msg));
/*
* m[ail] address...
if address is starting with
......@@ -113,12 +115,20 @@ free_env_headers (struct send_environ *env)
If the variable "record" is set, the outgoing message is
saved after being sent. If "save_to" argument is non-zero,
the name of the save file is derived from "to" argument. Otherwise,
it is taken from the value of "record" variable. */
it is taken from the value of "record" variable.
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.
*/
int
mail_send0 (struct send_environ *env, int save_to)
{
size_t n = 0;
int done = 0;
int fd;
char *filename;
......@@ -220,6 +230,7 @@ mail_send0 (struct send_environ *env, int save_to)
free (buf);
}
/* If interrupted dumpt the file to dead.letter. */
if (int_cnt)
{
if (util_find_env ("save")->set)
......@@ -259,17 +270,6 @@ mail_send0 (struct send_environ *env, int save_to)
mailer_t mailer;
message_t msg = NULL;
int status;
char *mailer_name = alloca (strlen ("sendmail:")
+ strlen (_PATH_SENDMAIL) + 1);
sprintf (mailer_name, "sendmail:%s", _PATH_SENDMAIL);
if ((status = mailer_create (&mailer, mailer_name)) != 0
|| (status = mailer_open (mailer, MU_STREAM_RDWR)) != 0)
{
util_error ("%s: %s", mailer_name, strerror (status));
remove (filename);
free (filename);
return 1;
}
message_create (&msg, NULL);
/* Fill the header. */
......@@ -284,7 +284,7 @@ mail_send0 (struct send_environ *env, int save_to)
header_set_value (header, MU_HEADER_BCC , strdup (env->bcc), 0);
if (env->subj && *env->subj != '\0')
header_set_value (header, MU_HEADER_SUBJECT, strdup (env->subj), 1);
header_set_value (header, "X-Mailer", strdup (argp_program_version), 1);
header_set_value (header, "X-Mailer", strdup(argp_program_version), 1);
}
/* Fill the body. */
......@@ -293,6 +293,7 @@ mail_send0 (struct send_environ *env, int save_to)
stream_t stream = NULL;
off_t offset = 0;
char *buf = NULL;
size_t n = 0;
message_get_body (msg, &body);
body_get_stream (body, &stream);
while (getline (&buf, &n, file) >= 0)
......@@ -325,10 +326,7 @@ mail_send0 (struct send_environ *env, int save_to)
if (savefile)
free (savefile);
/* Send the message. */
mailer_send_message (mailer, msg);
/* Save the message to files or pipes */
/* Check if we need to save the message to files or pipes. */
if (env->outfiles)
{
int i;
......@@ -336,27 +334,7 @@ mail_send0 (struct send_environ *env, int save_to)
{
/* Pipe to a cmd. */
if (env->outfiles[i][0] == '|')
{
FILE *fp = popen (&(env->outfiles[i][1]), "w");
if (fp)
{
stream_t stream = NULL;
char buffer[512];
off_t off = 0;
message_get_stream (msg, &stream);
while (stream_read (stream, buffer,
sizeof (buffer) - 1, off, &n) == 0
&& n != 0)
{
buffer[n] = '\0';
fprintf (fp, "%s", buffer);
off += n;
}
fclose (fp);
}
else
util_error ("Piping %s failed", env->outfiles[i]);
}
msg_to_pipe (&(env->outfiles[i][1]), msg);
/* Save to a file. */
else
{
......@@ -379,8 +357,33 @@ mail_send0 (struct send_environ *env, int save_to)
}
}
}
/* Do we need to Send the message on the wire? */
if ((env->to && *env->to != '\0')
|| (env->cc && *env->cc != '\0')
|| (env->bcc && *env->bcc != '\0'))
{
if (util_find_env ("sendmail")->set)
{
char *sendmail = util_find_env ("sendmail")->value;
status = mailer_create (&mailer, sendmail);
if (status == 0)
{
status = mailer_open (mailer, MU_STREAM_RDWR);
if (status == 0)
{
mailer_send_message (mailer, msg);
mailer_close (mailer);
}
mailer_destroy (&mailer);
}
if (status != 0)
msg_to_pipe (sendmail, msg);
}
else
util_error ("variable sendmail not set: no mailer");
}
message_destroy (&msg, NULL);
mailer_destroy (&mailer);
remove (filename);
free (filename);
return 0;
......@@ -401,3 +404,29 @@ isfilename (const char *p)
return 1;
return 0;
}
/* FIXME: Should probably be in util.c. */
/* Call pope(cmd) and write the message to it. */
static void
msg_to_pipe (const char *cmd, message_t msg)
{
FILE *fp = popen (cmd, "w");
if (fp)
{
stream_t stream = NULL;
char buffer[512];
off_t off = 0;
int n = 0;
message_get_stream (msg, &stream);
while (stream_read (stream, buffer, sizeof (buffer) - 1, off, &n) == 0
&& n != 0)
{
buffer[n] = '\0';
fprintf (fp, "%s", buffer);
off += n;
}
fclose (fp);
}
else
util_error ("Piping %s failed", cmd);
}
......
......@@ -47,6 +47,7 @@ mail_set (int argc, char **argv)
entry->set = 0;
if (entry->value)
free (entry->value);
entry->value = NULL;
}
else if (i+1 < argc && argv[i+1][0] == '=')
{
......
......@@ -452,23 +452,28 @@ util_screen_lines()
/*
* find environment entry var
* Find environment entry var
FIXME: We should probably call this util_getenv to be consitent with
util_printenv(), util_setenv() etc ..
*/
struct mail_env_entry *
util_find_env (char *variable)
util_find_env (const char *variable)
{
char *var = variable;
int len = strlen (var), need_free = 0;
/* Annoying, variable "ask" is equivalent to "asksub". */
static const char *asksub = "asksub";
const char *var = variable;
int len = strlen (var);
node *t;
if (len < 1)
return NULL;
/* Catch "ask" --> "asksub". */
if (len == strlen ("ask") && !strcmp ("ask", var))
{
var = strdup ("asksub");
var = asksub;
len = strlen (var);
need_free = 1;
}
if (environment == NULL)
......@@ -486,8 +491,6 @@ util_find_env (char *variable)
if (strlen (env_cursor->env_entry.var) == len &&
!strcmp (var, env_cursor->env_entry.var))
{
if (need_free)
free (var);
return &(env_cursor->env_entry);
}
}
......@@ -497,8 +500,6 @@ util_find_env (char *variable)
env_cursor->env_entry.value = NULL;
t = env_cursor;
env_cursor = util_ll_add (env_cursor, 0);
if (need_free)
free (var);
return &(t->env_entry);
}
......@@ -523,6 +524,46 @@ util_printenv (int set)
}
/*
* Set environement
* The util_setenv() function adds the variable name to the envi-
* ronment with the value value, if name does not already
* exist. If name does exist in the environment, then its
* value is changed to value if overwrite is non-zero; if
* overwrite is zero, then the value of name is not changed.
*
* A side effect of the code is if value is null the variable name
* will be unset.
*/
int
util_setenv (const char *variable, const char *value, int overwrite)
{
struct mail_env_entry *ep = util_find_env (variable);
if (ep->set)
{
if (overwrite)
{
ep->set = 0;
if (ep->value)
free (ep->value);
ep->value = NULL;
if (value)
{
ep->set = 1;
ep->value = strdup (value);
}
}
}
else
{
ep->set = 1;
if (ep->value)
free (ep->value);
ep->value = strdup (value);
}
return 0;
}
/*
* return 1 if a message is deleted
*/
int
......
......@@ -27,6 +27,7 @@
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <pwd.h>
#include "md5-rsa.h"
......@@ -917,13 +918,21 @@ message_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
else if (status == EAGAIN)
return status;
/* oops */
n = (7 > len) ? len: 7;
if (buf && len > 0)
{
memcpy (buf, "unknown", n);
buf [n] = '\0';
}
/* oops! We are still here */
{
struct passwd *pw;
const char *sender;
pw = getpwuid (getuid ());
sender = (pw) ? pw->pw_name : "unknown";
n = strlen (sender);
if (buf && len > 0)
{
len--; /* One for the null. */
n = (n < len) ? n : len;
memcpy (buf, pw->pw_name, n);
buf[n] = '\0';
}
}
if (pnwrite)
*pnwrite = n;
......