#include "substdio.h"
#include "subfd.h"
#include "getln.h"
#include "mess822.h"
#include "strerr.h"
#include "exit.h"
#include "caltime.h"
#include "leapsecs.h"
#include "tai.h"
#include "sgetopt.h"
#include "stralloc.h"
#include "config.h"
#include "auto_qmail.h"
#include "case.h"
#include "constmap.h"
#include "qmail.h"
#include "sig.h"
#include "rewritehost.h"
#include "rwhconfig.h"
#define FATAL "new-inject: fatal: "
void nomem()
{
strerr_die2x(111,FATAL,"out of memory");
}
config_str qmailinject = CONFIG_STR;
config_str name = CONFIG_STR;
config_str user = CONFIG_STR;
config_str host = CONFIG_STR;
config_str suser = CONFIG_STR;
config_str shost = CONFIG_STR;
config_str fnmft = CONFIG_STR;
config_str mft = CONFIG_STR;
struct constmap mapmft;
config_str fnrewrite = CONFIG_STR;
config_str rewrite = CONFIG_STR;
stralloc idappend = {0};
struct tai start;
stralloc tmp = {0};
stralloc tmp2 = {0};
void rewritelist(list)
stralloc *list;
{
if (!rewritehost_list(&tmp,list->s,list->len,config_data(&rewrite))) nomem();
if (!stralloc_copy(list,&tmp)) nomem();
}
int recipstrategy = 'A';
int flagkillfrom = 0;
int flagkillmsgid = 0;
int flagkillreturnpath = 0;
int flagverpmess = 0;
int flagverprecip = 0;
stralloc sender = {0};
stralloc recipients = {0};
void recipient_add(addr)
char *addr;
{
if (!rewritehost_addr(&tmp,addr,str_len(addr),config_data(&rewrite))) nomem();
if (!stralloc_cat(&recipients,&tmp)) nomem();
if (!stralloc_0(&recipients)) nomem();
}
void recipient_addlist(list)
stralloc *list;
{
int i;
int j;
for (j = i = 0;j < list->len;++j)
if (!list->s[j]) {
if (list->s[i] == '+')
if (!stralloc_catb(&recipients,list->s + i + 1,j - i)) nomem();
i = j + 1;
}
}
void sender_get(list)
stralloc *list;
{
int i;
int j;
for (j = i = 0;j < list->len;++j)
if (!list->s[j]) {
if (list->s[i] == '+')
if (!stralloc_copyb(&sender,list->s + i + 1,j - i)) nomem();
i = j + 1;
}
}
int flagqueue = 1;
struct qmail qq;
void put(buf,len)
char *buf;
int len;
{
if (flagqueue)
qmail_put(&qq,buf,len);
else
substdio_put(subfdoutsmall,buf,len);
}
void puts(buf)
char *buf;
{
put(buf,str_len(buf));
}
void putlist(name,list)
char *name;
stralloc *list;
{
if (!list->len) return;
if (!mess822_quotelist(&tmp,list)) nomem();
if (!mess822_fold(&tmp2,&tmp,name,78)) nomem();
put(tmp2.s,tmp2.len);
}
mess822_time date;
stralloc enveloperecipients = {0}; int flagenveloperecipients;
stralloc envelopesender = {0}; int flagenvelopesender;
stralloc to = {0};
stralloc cc = {0};
stralloc bcc = {0};
stralloc nrudt = {0};
stralloc returnpath = {0};
stralloc from = {0};
stralloc headersender = {0};
stralloc replyto = {0};
stralloc mailreplyto = {0};
stralloc followupto = {0};
stralloc msgid = {0};
stralloc top = {0};
stralloc bottom = {0};
mess822_header h = MESS822_HEADER;
mess822_action a[] = {
{ "date", 0, 0, 0, 0, &date }
, { "to", 0, 0, 0, &to, 0 }
, { "cc", 0, 0, 0, &cc, 0 }
, { "bcc", 0, 0, 0, &bcc, 0 }
, { "apparently-to", 0, 0, 0, &bcc, 0 }
, { "notice-requested-upon-delivery-to", 0, 0, 0, &nrudt, 0 }
, { "from", 0, 0, 0, &from, 0 }
, { "sender", 0, 0, 0, &headersender, 0 }
, { "reply-to", 0, 0, 0, &replyto, 0 }
, { "mail-reply-to", 0, 0, 0, &mailreplyto, 0 }
, { "mail-followup-to", 0, 0, 0, &followupto, 0 }
, { "return-path", 0, 0, 0, &returnpath, 0 }
, { "envelope-recipients", &flagenveloperecipients, 0, 0, &enveloperecipients, 0 }
, { "envelope-sender", &flagenvelopesender, 0, 0, &envelopesender, 0 }
, { "message-id", 0, &msgid, 0, 0, 0 }
, { "received", 0, &top, 0, 0, 0 }
, { "delivered-to", 0, &top, 0, 0, 0 }
, { "errors-to", 0, &top, 0, 0, 0 }
, { "return-receipt-to", 0, &top, 0, 0, 0 }
, { "resent-sender", 0, &top, 0, 0, 0 }
, { "resent-from", 0, &top, 0, 0, 0 }
, { "resent-reply-to", 0, &top, 0, 0, 0 }
, { "resent-to", 0, &top, 0, 0, 0 }
, { "resent-cc", 0, &top, 0, 0, 0 }
, { "resent-bcc", 0, &top, 0, 0, 0 }
, { "resent-date", 0, &top, 0, 0, 0 }
, { "resent-message-id", 0, &top, 0, 0, 0 }
, { "content-length", 0, 0, 0, 0, 0 }
, { 0, 0, &bottom, 0, 0, 0 }
} ;
void envelope_make()
{
if (recipstrategy != 'a')
if (flagenveloperecipients)
recipient_addlist(&enveloperecipients);
else {
recipient_addlist(&to);
recipient_addlist(&cc);
recipient_addlist(&bcc);
}
if (!sender.len)
sender_get(&envelopesender);
if (!sender.len)
sender_get(&returnpath);
if (!sender.len) {
if (!rewritehost_addr(&sender,config_data(&suser)->s,config_data(&suser)->len,config_data(&rewrite))) nomem();
if (flagverprecip)
if (!stralloc_cats(&sender,"-@[]")) nomem();
if (!stralloc_0(&sender)) nomem();
}
}
void envelope_print()
{
int i;
int j;
puts("Envelope-Sender: ");
if (!mess822_quote(&tmp,sender.s,(char *) 0)) nomem();
put(tmp.s,tmp.len);
puts("\n");
puts("Envelope-Recipients:\n");
for (j = i = 0;j < recipients.len;++j)
if (!recipients.s[j]) {
if (!mess822_quote(&tmp,recipients.s + i,(char *) 0)) nomem();
puts(" ");
put(tmp.s,tmp.len);
puts(",\n");
i = j + 1;
}
}
void datemsgid_print()
{
if (!date.known) {
caltime_utc(&date.ct,&start,(int *) 0,(int *) 0);
date.known = 1;
}
if (!mess822_date(&tmp,&date)) nomem();
puts("Date: ");
put(tmp.s,tmp.len);
puts("\n");
if (!msgid.len) {
if (!stralloc_copys(&msgid,"Message-ID: <")) nomem();
if (!stralloc_catlong(&msgid,date.ct.date.year)) nomem();
if (!stralloc_catint0(&msgid,date.ct.date.month,2)) nomem();
if (!stralloc_catint0(&msgid,date.ct.date.day,2)) nomem();
if (!stralloc_catint0(&msgid,date.ct.hour,2)) nomem();
if (!stralloc_catint0(&msgid,date.ct.minute,2)) nomem();
if (!stralloc_catint0(&msgid,date.ct.second,2)) nomem();
if (!stralloc_cat(&msgid,&idappend)) nomem();
if (!stralloc_cats(&msgid,">\n")) nomem();
}
put(msgid.s,msgid.len);
}
void from_print()
{
putlist("From: ",&from);
if (!from.len) {
if (!rewritehost_addr(&tmp2,config_data(&user)->s,config_data(&user)->len,config_data(&rewrite))) nomem();
if (!stralloc_0(&tmp2)) nomem();
puts("From: ");
if (!mess822_quote(&tmp,tmp2.s,config(&name) ? config_data(&name)->s : (char *) 0)) nomem();
put(tmp.s,tmp.len);
puts("\n");
}
putlist("Sender: ",&headersender);
}
int inmft(list)
stralloc *list;
{
int i;
int j;
for (j = i = 0;j < list->len;++j)
if (!list->s[j]) {
if (list->s[i] == '+')
if (constmap(&mapmft,list->s + i + 1,j - i - 1))
return 1;
i = j + 1;
}
return 0;
}
void response_print()
{
putlist("Reply-To: ",&replyto);
putlist("Mail-Reply-To: ",&mailreplyto);
if (!followupto.len)
if (config(&mft))
if (inmft(&to) || inmft(&cc)) {
if (!stralloc_cat(&followupto,&to)) nomem();
if (!stralloc_cat(&followupto,&cc)) nomem();
}
putlist("Mail-Followup-To: ",&followupto);
}
void to_print()
{
if (!to.len && !cc.len)
puts("Cc: recipient list not shown: ;\n");
putlist("To: ",&to);
putlist("Cc: ",&cc);
putlist("Notice-Requested-Upon-Delivery-To: ",&nrudt);
}
void finishheader()
{
if (!mess822_end(&h)) nomem();
if (flagqueue)
if (qmail_open(&qq) == -1)
strerr_die2sys(111,FATAL,"unable to run qmail-queue: ");
if (flagkillreturnpath) returnpath.len = 0;
if (flagkillmsgid) msgid.len = 0;
if (flagkillfrom) from.len = 0;
rewritelist(&to);
rewritelist(&cc);
rewritelist(&bcc);
rewritelist(&nrudt);
rewritelist(&from);
rewritelist(&headersender);
rewritelist(&replyto);
rewritelist(&mailreplyto);
rewritelist(&followupto);
rewritelist(&returnpath);
rewritelist(&enveloperecipients);
rewritelist(&envelopesender);
envelope_make();
if (!flagqueue)
envelope_print();
put(top.s,top.len);
datemsgid_print();
from_print();
response_print();
to_print();
put(bottom.s,bottom.len);
}
void finishmessage()
{
char *qqx;
int i;
int j;
if (!flagqueue)
substdio_flush(subfdoutsmall);
else {
qmail_from(&qq,sender.s);
for (j = i = 0;j < recipients.len;++j)
if (!recipients.s[j]) {
qmail_to(&qq,recipients.s + i);
i = j + 1;
}
qqx = qmail_close(&qq);
if (*qqx)
strerr_die2x(*qqx == 'D' ? 100 : 111,FATAL,qqx + 1);
}
_exit(0);
}
char *argsender = 0;
stralloc line = {0};
int match;
void main(argc,argv)
int argc;
char **argv;
{
int i;
int flagheader = 1;
int opt;
sig_pipeignore();
tai_now(&start);
if (config_env(&qmailinject,"QMAILINJECT") == -1) nomem();
if (config(&qmailinject))
for (i = 0;i < config_data(&qmailinject)->len;++i)
switch(config_data(&qmailinject)->s[i]) {
case 'F': case 'f': flagkillfrom = 1; break;
case 'I': case 'i': flagkillmsgid = 1; break;
case 'M': case 'm': flagverpmess = 1; break;
case 'R': case 'r': flagverprecip = 1; break;
case 'S': case 's': flagkillreturnpath = 1; break;
}
while ((opt = getopt(argc,argv,"nNaAhHFIMRSf:")) != opteof)
switch(opt) {
case 'n': flagqueue = 0; break;
case 'N': flagqueue = 1; break;
case 'a': case 'A': case 'h': case 'H': recipstrategy = opt; break;
case 'F': flagkillfrom = 1; break;
case 'I': flagkillmsgid = 1; break;
case 'M': flagverpmess = 1; break;
case 'R': flagverprecip = 1; break;
case 'S': flagkillreturnpath = 1; break;
case 'f': argsender = optarg; break;
default:
strerr_die1x(100,"new-inject: usage: new-inject [ -nNaAhHFIMRS ] [ -f sender ] [ recip ... ]\n");
}
argv += optind;
if (leapsecs_init() == -1)
strerr_die2sys(111,FATAL,"unable to init leapsecs: ");
if (config_env(&fnmft,"QMAILMFTFILE") == -1) nomem();
if (config(&fnmft)) {
if (!stralloc_0(config_data(&fnmft))) nomem();
if (config_readfile(&mft,config_data(&fnmft)->s) == -1)
strerr_die2sys(111,FATAL,"unable to read $QMAILMFTFILE: ");
if (config(&mft))
if (!constmap_init(&mapmft,config_data(&mft)->s,config_data(&mft)->len,0)) nomem();
}
if (config_env(&fnrewrite,"QMAILREWRITEFILE") == -1) nomem();
if (config(&fnrewrite)) {
if (!stralloc_0(config_data(&fnrewrite))) nomem();
if (config_readfile(&rewrite,config_data(&fnrewrite)->s) == -1)
strerr_die2sys(111,FATAL,"unable to read $QMAILREWRITEFILE: ");
}
if (chdir(auto_qmail) == -1)
strerr_die4sys(111,FATAL,"unable to switch to ",auto_qmail,": ");
if (config_env(&name,"QMAILNAME") == -1) nomem();
if (config_env(&name,"MAILNAME") == -1) nomem();
if (config_env(&name,"NAME") == -1) nomem();
if (config(&name))
if (!stralloc_0(config_data(&name))) nomem();
if (config_env(&user,"QMAILUSER") == -1) nomem();
if (config_env(&user,"MAILUSER") == -1) nomem();
if (config_env(&user,"USER") == -1) nomem();
if (config_env(&user,"LOGNAME") == -1) nomem();
if (config_default(&user,"anonymous") == -1) nomem();
if (config_env(&suser,"QMAILSUSER") == -1) nomem();
if (config_copy(&suser,&user) == -1) nomem();
if (config_env(&host,"QMAILHOST") == -1) nomem();
if (config_env(&host,"MAILHOST") == -1) nomem();
if (config_default(&host,"") == -1) nomem();
if (rwhconfig(&rewrite,&idappend) == -1)
strerr_die1(111,FATAL,&rwhconfig_err);
if (config_env(&shost,"QMAILSHOST") == -1) nomem();
if (config_copy(&shost,&host) == -1) nomem();
if (!stralloc_copys(&sender,"")) nomem();
if (argsender) {
if (!rewritehost_addr(&sender,argsender,str_len(argsender),config_data(&rewrite))) nomem();
if (!stralloc_0(&sender)) nomem();
}
if (recipstrategy == 'A')
recipstrategy = (*argv ? 'a' : 'h');
if (!stralloc_copys(&recipients,"")) nomem();
if (recipstrategy != 'h')
while (*argv)
recipient_add(*argv++);
if (flagverpmess) {
unsigned char nowpack[TAI_PACK];
int i;
unsigned long u;
tai_pack(nowpack,&start);
u = nowpack[4]; u <<= 8;
u += nowpack[5]; u <<= 8;
u += nowpack[6]; u <<= 8;
u += nowpack[7];
if (!stralloc_cats(config_data(&suser),"-")) nomem();
if (!stralloc_catulong0(config_data(&suser),u,0)) nomem();
u = getpid();
if (!stralloc_cats(config_data(&suser),".")) nomem();
if (!stralloc_catulong0(config_data(&suser),u,0)) nomem();
}
if (flagverprecip)
if (!stralloc_cats(config_data(&suser),"-")) nomem();
if (!stralloc_cats(config_data(&suser),"@")) nomem();
if (!stralloc_cat(config_data(&suser),config_data(&shost))) nomem();
if (!stralloc_cats(config_data(&user),"@")) nomem();
if (!stralloc_cat(config_data(&user),config_data(&host))) nomem();
if (!mess822_begin(&h,a)) nomem();
for (;;) {
if (getln(subfdinsmall,&line,&match,'\n') == -1)
strerr_die2sys(111,FATAL,"unable to read input: ");
if (!match && !line.len) break;
if (!match)
if (!stralloc_append(&line,"\n")) nomem();
if (flagheader)
if (!mess822_ok(&line)) {
finishheader();
flagheader = 0;
if (line.len != 1) put("\n",1);
}
if (!flagheader)
put(line.s,line.len);
else
if (!mess822_line(&h,&line)) nomem();
if (!match) break;
}
if (flagheader)
finishheader();
finishmessage();
}
syntax highlighted by Code2HTML, v. 0.9.1