diff -u ssmtp-2.61/ssmtp.c ssmtp-2.61.1/ssmtp.c
--- ssmtp-2.61/ssmtp.c 2007-09-15 19:07:01.000000000 +0200
+++ ssmtp-2.61.1/ssmtp.c 2007-09-16 22:17:40.000000000 +0200
@@ -48,6 +48,7 @@
bool_t minus_v = False;
bool_t override_from = False;
bool_t rewrite_domain = False;
+bool_t send_to = False;
bool_t use_tls = False; /* Use SSL to transfer mail to HUB */
bool_t use_starttls = False; /* SSL only after STARTTLS (RFC2487) */
bool_t use_cert = False; /* Use a certificate to transfer SSL mail */
@@ -59,10 +60,13 @@
char *auth_method = (char)NULL; /* Mechanism for SMTP authentication */
char *mail_domain = (char)NULL;
char *from = (char)NULL; /* Use this as the From: address */
+char *to = (char)NULL; /* Send the mail to this address */
+char *to_header = (char)NULL;
char hostname[MAXHOSTNAMELEN] = "localhost";
char *mailhost = "mailhub";
char *minus_f = (char)NULL;
char *minus_F = (char)NULL;
+char *minus_T = (char)NULL;
char *gecos;
char *prog = (char)NULL;
char *root = NULL;
@@ -340,6 +344,30 @@
}
/*
+ * append_to_domain() -- Fix up address with @domain.com
+ *
+ */
+char *append_to_domain(char *str)
+{
+ char buf[(BUF_SZ + 1)];
+
+ if(strchr(str, '@') == (char *)NULL) {
+ if(snprintf(buf, BUF_SZ, "%s@%s", str,
+#ifdef REWRITE_DOMAIN
+ send_to == True ? to : hostname
+#else
+ hostname
+#endif
+ ) == -1) {
+ die("append_to_domain() -- snprintf() failed");
+ }
+ return(strdup(buf));
+ }
+
+ return(strdup(str));
+}
+
+/*
standardise() -- Trim off '\n's and double leading dots
*/
void standardise(char *str)
@@ -358,7 +386,7 @@
if(*str == '.') {
if((sl + 2) > BUF_SZ) {
- die("standardise() -- Buffer overflow");
+ die("standardise() -- Buffer overflow -- line too long in mail body");
}
(void)memmove((str + 1), str, (sl + 1)); /* Copy trailing \0 */
@@ -494,6 +522,24 @@
return(strdup(buf));
}
+char *to_format(char *str)
+{
+ char buf[(BUF_SZ + 1)];
+
+ if(minus_T) {
+ if(snprintf(buf, BUF_SZ, "\"%s\" <%s>", minus_T, str) == -1) {
+ die("to_format() -- snprintf() failed");
+ }
+ }
+ else {
+ if(snprintf(buf, BUF_SZ, "%s", str) == -1) {
+ die("to_format() -- snprintf() failed");
+ }
+ }
+
+ return(strdup(buf));
+
+}
/*
rcpt_save() -- Store entry into RCPT list
*/
@@ -647,10 +693,10 @@
struct passwd *pw;
if((root==NULL) || strlen(root)==0 || strchr(str, '@') ||
((pw = getpwnam(str)) == NULL) || (pw->pw_uid > MAXSYSUID)) {
- return(append_domain(str)); /* It's not a local systems-level user */
+ return(append_to_domain(str)); /* It's not a local systems-level user */
}
else {
- return(append_domain(root));
+ return(append_to_domain(root));
}
}
@@ -866,6 +912,30 @@
"Set RewriteDomain=\"%s\"\n", mail_domain);
}
}
+
+ else if(strcasecmp(p, "SendTo") == 0) {
+ if((p = strrchr(q, '@'))) {
+ to = strdup(++p);
+
+ log_event(LOG_ERR,
+ "Set SendTo=\"%s\" is invalid\n", q);
+ log_event(LOG_ERR,
+ "Set SendTo=\"%s\" used\n", to);
+ }
+ else {
+ to = strdup(q);
+ }
+
+ if(to == (char *)NULL) {
+ die("parse_config() -- strdup() failed (SendTo)");
+ }
+ send_to = True;
+
+ if(log_level > 0) {
+ log_event(LOG_INFO,
+ "Set SendTo=\"%s\"\n", to);
+ }
+ }
#endif
else if(strcasecmp(p, "FromLineOverride") == 0) {
if(strcasecmp(q, "YES") == 0) {
@@ -1410,9 +1480,14 @@
die("No recipients specified although -t option used");
}
rt = &rcpt_list;
+ int tohead = (int)NULL;
while(rt->next) {
p = rcpt_remap(rt->string);
+ if(!tohead) {
+ to_header = p;
+ tohead = 1;
+ }
smtp_write(sock, "RCPT TO:<%s>", p);
(void)alarm((unsigned)MEDWAIT);
@@ -1427,9 +1502,15 @@
else {
for(i = 1; (argv[i] != NULL); i++) {
p = strtok(argv[i], ",");
+ int tohead = (int)NULL;
+
while(p) {
/* RFC822 Address -> "foo@bar" */
q = rcpt_remap(addr_parse(p));
+ if(!tohead) {
+ to_header = q;
+ tohead = 1;
+ }
smtp_write(sock, "RCPT TO:<%s>", q);
(void)alarm((unsigned) MEDWAIT);
@@ -1442,6 +1523,7 @@
}
}
}
+ // Keep to_header in mind for later use!
/* Send DATA */
smtp_write(sock, "DATA");
@@ -1467,6 +1549,8 @@
if(have_to == False) {
smtp_write(sock, "To: postmaster");
}
+#else
+ smtp_write(sock, "To: %s", to_format(to_header));
#endif
ht = &headers;
@@ -1687,6 +1771,23 @@
}
goto exit;
+ /* Fullname of receiver */
+ case 'T':
+ if((!argv[i][(j + 1)]) && argv[(i + 1)]) {
+ minus_T = strdup(argv[(i + 1)]);
+ if(minus_T == (char *)NULL) {
+ die("parse_options() -- strdup() failed");
+ }
+ add++;
+ }
+ else {
+ minus_T = strdup(argv[i]+j+1);
+ if(minus_T == (char *)NULL) {
+ die("parse_options() -- strdup() failed");
+ }
+ }
+ goto exit;
+
/* Set from/sender address */
case 'f':
/* Obsolete -f flag */