This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-mbse/mbfido/ftn2rfc.c
2002-02-16 23:16:42 +00:00

1633 lines
47 KiB
C

/*****************************************************************************
*
* $Id$
* Purpose ...............: Gate netmail->email or echomail->news
*
*****************************************************************************
* Copyright (C) 1997-2002
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
* 1971 BV IJmuiden
* the Netherlands
*
* This file is part of MBSE BBS.
*
* This BBS is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* MBSE BBS is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MBSE BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*****************************************************************************/
#include "../lib/libs.h"
#include "../lib/structs.h"
#include "../lib/users.h"
#include "../lib/records.h"
#include "../lib/dbftn.h"
#include "../lib/dbdupe.h"
#include "../lib/dbuser.h"
#include "../lib/common.h"
#include "../lib/clcomm.h"
#include "rollover.h"
#include "aliasdb.h"
#include "postemail.h"
#include "backalias.h"
#include "ftn2rfc.h"
#define KWDCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
#define MAXPATH 73
#define BOUNDARY 79
/*
* Global variables
*/
extern int news_in; /* Total news articles */
extern int news_out; /* News articles posted */
extern int news_bad; /* News articles refused */
extern int defaultrfcchar; /* Default RFC charset */
extern int defaultftnchar; /* Default FTN charset */
int newsopen = FALSE; /* News tempfile status */
FILE *nfp; /* News tempfile */
void fill_rlist(fa_list **, char *);
void fill_rlist(fa_list **fap, char *str)
{
fa_list *tmp;
faddr *ta;
static unsigned int oldnet;
char *buf, *p, *q;
if ((str == NULL) || (*str == '\0'))
return;
Syslog('N' ,"fill_rlist %s",str);
buf = xstrcpy(str);
for (p = buf, q = strchr(p,'!'); *p; p = q, q = strchr(p,'!')) {
if (q)
*q++='\0';
else
q=p+strlen(p);
if ((ta=parsefaddr(p))) {
if (ta->net == 0)
ta->net=oldnet;
else
oldnet=ta->net;
tmp=(fa_list *)malloc(sizeof(fa_list));
tmp->next=*fap;
tmp->addr=ta;
*fap=tmp;
}
}
free(buf);
for (tmp=*fap;tmp;tmp=tmp->next)
Syslog('N', "fill_rlist returns: %s",ascfnode(tmp->addr,0x06));
return;
}
static char *rbuf;
char *rfcmsgid(char *, faddr *);
char *rfcmsgid(char *msgid, faddr *bestaka)
{
char *p, *q, *r;
unsigned long id = 0L;
faddr *ta = NULL;
if (msgid == NULL)
return NULL;
/*
* +40 for the additionnal stuff we need to write, should be enough
*/
rbuf = malloc(strlen(msgid) + 40);
if ((r = strrchr(msgid,'\n')))
*r = '\0';
/*
* sometimes there is "^aMSGID: 1:23/45@@domain 152ad589"
*/
if ((p = strstr(msgid, "@@"))) {
*p='\0';
strcat(msgid, p+1);
} else if ((p = strstr(msgid,"@ "))) {
/*
* other times there is "^aMSGID: 1:23/45@ 152ad589"
*/
*p='\0';
strcat(msgid,p+1);
}
if ((p=strrchr(msgid,' '))) {
/*
* here we have a parseable address
*/
*p = '\0';
sscanf(p+1, "%lx", &id);
ta = parsefnode(msgid);
*p=' ';
}
if (id != 0L) {
/* if we only check for (ta) a Message-ID like
* <123456.7890@internet.domain> will be recognized as
* a fidonet one (ta->node=123456, ta->point=7890,
* ta->domain="internet", but ta->net=0) which obviously
* isn't the case. By cheking also (ta->net) we avoid that
*/
if ((ta) && (ta->net)) {
sprintf(rbuf, "<%lu@%s.ftn>", id, ascinode(ta,0x1f));
} else {
p = xstrcpy(msgid);
if ((q = strchr(p,' ')))
*q = '\0';
/* ### Modified by P.Saratxaga on 18 Aug 1995 */
if (strstr(p, "@")) {
/* "mid__<local@domain>" are generated by gigo */
if (!strncmp(p, "mid__<", 6)) {
sprintf(rbuf, "%s", p+6);
while ((q = strstr(rbuf, ">_<")))
*(q+1) = ' ';
}
/* "mid__local@domain" are also generated by gigo */
else if (!strncmp(p, "mid__", 5))
sprintf(rbuf, "<%s>", p+5);
/* "wgmid$<local@domain>" */
else if (!strncmp(p, "wgmid$<", 7))
sprintf(rbuf, "%s", p+6);
/* in case we have "<local@domain>" */
else if (!strncmp(p, "<", 1))
sprintf(rbuf, "%s", p);
/* or "local@domain" */
else
sprintf(rbuf, "<%s>", p);
while ((q = strchr(rbuf, '@')) != strrchr(rbuf, '@')) {
/* we (still) have more than one @ */
*q = '%';
}
} else {
sprintf(rbuf, "<%lu@%s>", id, p);
}
free(p);
}
} else {
sprintf(rbuf, "<%lu@%s.ftn>", (unsigned long)sequencer(), ascinode(bestaka,0x1f));
}
tidy_faddr(ta);
if (r)
*r='\n';
return rbuf;
}
/*
* check address for localness, substitute alises and replace it *in place*
*/
void substitude(char *);
void substitute(char *buf)
{
faddr *fa;
char *l,*r,*p=NULL;
int inquotes,inbrackets;
Syslog('m', "to address before subst: \"%s\"",buf);
if ((l=strchr(buf,'<')) && (r=strchr(buf,'>')) && (l < r)) {
l++;
*r='\0';
} else
l=buf;
while (*l == ' ')
l++;
for (r=l,inquotes=0,inbrackets=0;*r;r++)
switch (*r) {
case '"': inquotes=(!inquotes); break;
case ',':
case ' ': if (!inquotes && !inbrackets) *r='\0'; break;
case '(': if (!inquotes) inbrackets++; break;
case ')': if (!inquotes && inbrackets) inbrackets--; break;
default: break;
}
if ((fa=parsefaddr(l))) {
Syslog('m', "it is an ftn address: %s",ascfnode(fa,0x7f));
if (is_local(fa)) {
Syslog('m', "it is local");
sprintf(buf,"%s",fa->name);
if (!strchr(buf,'@') && (p=strrchr(buf,'%')))
*p='@';
if (!strchr(buf,'@')) {
/*
* Lookup the name first in the alias database, then
* the userbase and finally check the password file
* (gecos->username). If not found it's and error.
*/
if ((p = lookup(buf)))
strcpy(buf, p);
else if (SearchUser(buf))
sprintf(buf, "%s@%s", usr.Name, CFG.sysdomain);
else if (!strcasecmp(buf,"sysop"))
strcpy(buf,"postmaster");
else
sprintf(buf,"%s",ascinode(fa,0x7f));
}
} else {
WriteError("substitute(%s) it is not local, may not happen", buf);
sprintf(buf,"%s",ascinode(fa,0x7f));
}
tidy_faddr(fa);
} else {
Syslog('m', "it is not ftn address");
for (r=buf;*l;l++,r++)
*r=*l;
*r='\0';
}
if (buf[0] == '\0')
strcpy(buf,"postmaster");
Syslog('m', "to address after subst: \"%s\"",buf);
return;
}
/*
* Lines to send, if it is a newsarticle, the Message-Id is checked.
*/
void Send(int, char *);
void Send(int newsmode, char *outstr)
{
char *p;
unsigned long crc;
fwrite(outstr, 1, strlen(outstr), nfp);
if (newsmode) {
Striplf(outstr);
if (strncmp(outstr, (char*)"Message-ID: ", 12) == 0) {
/*
* The Message-ID that is sent to the newsserver is stored in
* the dupes database. The database isn't checked for dupes, this
* message is already checked for dupes. The function that will
* pull news articles from the news server will check the dupes
* database and thus will not fetch this local posted article.
*/
p = xstrcpy(outstr+12);
p = xstrcat(p, msgs.Newsgroup);
crc = str_crc32(p);
CheckDupe(crc, D_NEWS, CFG.nntpdupes);
free(p);
}
}
}
/*
* Gate FTN style netmail->email or echomail->news.
*
* 0 - All seems well.
* 1 - Something went wrong.
* 4 - Unable to open temporary file
*
*/
int ftn2rfc(faddr *f, faddr *t, char *subj, char *origline, time_t mdate, int flags, FILE *pkt)
{
int rrq, result = 1, modtype = 0;
int incode = CHRS_NOTSET, outcode = CHRS_NOTSET;
int waskludge = FALSE, badkludge, pgpsigned = FALSE;
int bNeedToGetAddressFromMsgid = (int)NULL;
int newsmode = 0, lines, pass, count, first;
char *newsgroup = NULL, *distribution = NULL, *moderator = NULL;
char *temp, *p, *q, *r, *l, *b;
char *To = NULL, buf[4096], *charset, c;
time_t now;
rfcmsg *kmsg = NULL, **tmsg, *qmsg, *msg = NULL;
off_t endmsg_off, tear_off, orig_off, via_off;
faddr *o, *bestaka, *ta, *tfaddr;
FILE *fp;
fa_list *rlist, *tfa, *ftnpath = NULL;
int dirtyoutcode = CHRS_NOTSET;
struct utsname utsbuf;
char MailFrom[128], MailTo[128];
temp = calloc(32768, sizeof(char));
tmsg = &kmsg;
tear_off = orig_off = via_off = 0L;
rbuf = NULL;
if ((fp = tmpfile()) == NULL) {
WriteError("$Unable to open temporary file");
free(temp);
return 4;
}
Syslog('M', "Message input start =============");
rewind(pkt);
while ((fgets(buf, sizeof(buf)-2, pkt)) != NULL) {
/*
* Simple test to see how large the buffer must be. 2048 bytes has been seen.
*/
if (strlen(buf) > (sizeof(buf) /2))
Syslog('+', "FTN: Possible bufferoverflow: line read %d bytes", strlen(buf));
if (strlen(buf) > 200) {
Syslog('M', "FTN: Next line should be %d characters", strlen(buf));
Syslogp('M', printable(buf, 200));
} else {
Syslogp('M', printable(buf, 0));
}
if ((buf[0] == '\1') || !strncmp(buf,"AREA:",5) || !strncmp(buf,"SEEN-BY",7)) { /* This is a kluge line */
waskludge = TRUE;
badkludge = FALSE;
if (buf[0] == '\1') {
l = buf+1;
if (!strncmp(l,"AREA:",5) || !strncmp(l,"SEEN-BY",7))
badkludge = TRUE;
} else
l = buf;
if (*l == '\n')
badkludge = TRUE;
else
while (isspace(*l))
l++;
if (strncmp(l, "RFC-", 4))
for (p = l; *p; p++)
if ((*p != '\n') && (((*p)&0x7f) < ' '))
badkludge = TRUE;
p = strchr(l,':');
r = strchr(l,' ');
if (p && (!r || (r > p)))
r = p;
else
p = r;
if (r == NULL)
badkludge = TRUE;
else if (!*(p+1) || (*(p+1)=='\n'))
badkludge = TRUE;
else {
c = *r;
*r = '\0';
if (strspn(l,KWDCHARS) != strlen(l))
badkludge = TRUE;
*r = c;
}
*tmsg = (rfcmsg *)malloc(sizeof(rfcmsg));
(*tmsg)->next = NULL;
if (badkludge) {
(*tmsg)->key = xstrcpy((char *)"KLUDGE");
p = printable(l,0);
r = p+strlen(p)-2;
if (strcmp(r,"\\n") == 0) {
*r++ = '\n';
*r = '\0';
}
(*tmsg)->val = xstrcpy(p);
} else {
*r++ = '\0';
while (isspace(*r))
r++;
(*tmsg)->key = xstrcpy(l);
(*tmsg)->val = xstrcpy(r);
}
tmsg = &((*tmsg)->next);
if (!strcmp(l,"Via") && (via_off == 0L)) {
via_off = ftell(fp);
Syslog('m', "^AVia \"%s\" at offset %ld", printable(buf, 0), (long)via_off);
}
} else {
/*
* this is not a kludge line
*/
if (waskludge && (isspace(buf[0])))
fputs("\n",fp); /* first body line is not RFC hdr */
waskludge=0;
if (!strncmp(buf,PGP_SIGNED_BEGIN, strlen(PGP_SIGNED_BEGIN)))
pgpsigned = TRUE;
else if ((!strncmp(buf,"---",3)) && ((buf[3] == '\r') || (buf[3] == ' ') || (buf[3] == '\n'))) {
tear_off=ftell(fp);
if ((hdr((char *)"Tearline",kmsg) == NULL)) {
*tmsg=(rfcmsg *)malloc(sizeof(rfcmsg));
(*tmsg)->next=NULL;
(*tmsg)->key=xstrcpy((char *)"Tearline");
if (strlen(buf+3) == strspn(buf+3," \t\r\n"))
(*tmsg)->val=xstrcpy((char *)"(none)\n");
else
(*tmsg)->val=xstrcpy(buf+4);
tmsg=&((*tmsg)->next);
}
Syslog('M', "tearline \"%s\" at offset %ld", buf,(long)tear_off);
} else if (!strncmp(buf," * Origin:",10)) {
orig_off = ftell(fp);
*tmsg = (rfcmsg *)malloc(sizeof(rfcmsg));
(*tmsg)->next = NULL;
(*tmsg)->key = xstrcpy((char *)"Origin");
(*tmsg)->val = xstrcpy(buf+11);
tmsg = &((*tmsg)->next);
Syslog('M', "origin \"%s\" at offset %ld", buf,(long)orig_off);
p = buf+10;
while (*p == ' ')
p++;
if ((l = strrchr(p,'(')) && (r = strrchr(p,')')) && (l < r)) {
/*
* Extract origin address from the Origin line.
*/
*l = '\0';
*r = '\0';
l++;
if ((o = parsefnode(l))) {
f->point = o->point;
f->node = o->node;
f->net = o->net;
f->zone = o->zone;
if (o->domain)
f->domain = o->domain;
o->domain = NULL;
tidy_faddr(o);
}
} else {
bNeedToGetAddressFromMsgid = !NULL;
Syslog('+', "Couldn't find address in origin line (%s of %s, [%s])",
f->name, ascfnode(f, 0x1f), hdr((char *)"Origin", kmsg));
if (*(l = p+strlen(p)-1) == '\n')
*l = '\0';
}
for (l = p+strlen(p)-1; *l == ' '; l--)
*l = '\0';
origline = xstrcpy(p);
} else if (!strncmp(buf," * Message split",16)) {
*tmsg = (rfcmsg *)malloc(sizeof(rfcmsg));
(*tmsg)->next = NULL;
(*tmsg)->key = xstrcpy((char *)"Split");
(*tmsg)->val = xstrcpy((char *)"already\n");
tmsg=&((*tmsg)->next);
Syslog('m', "Split indicator found");
}
fputs(buf,fp);
}
}
Syslog('M', "Message input end ===============");
if (bNeedToGetAddressFromMsgid && (p = hdr((char *)"MSGID", kmsg))) {
Syslog('m', "Need To Get Address From Msgid start...");
l = p;
while(isspace(*l) && *l)
l++;
r = strchr(l, ' ');
if(r) {
*r-- = '\0';
while(isspace(*r) && *r)
r--;
}
if (l && r && l > r) {
if ((o = parsefnode(l))) {
f->point = o->point;
f->node = o->node;
f->net = o->net;
f->zone = o->zone;
if (o->domain)
f->domain = o->domain;
o->domain = NULL;
tidy_faddr(o);
Syslog('+', "Origin from: %s (src MSGID)", ascfnode(f,0x7f));
}
}
}
endmsg_off=ftell(fp);
if ((tear_off) && (tear_off < endmsg_off))
endmsg_off = tear_off;
if ((orig_off) && (orig_off < endmsg_off))
endmsg_off = orig_off;
if ((via_off) && (via_off < endmsg_off))
endmsg_off = via_off;
Syslog('M', "end message offset %ld",(long)endmsg_off);
rewind(fp);
msg = parsrfc(fp);
bestaka = bestaka_s(f);
rewind(fp);
p = hdr((char *)"CHRS", kmsg);
if (p == NULL)
p = hdr((char *)"CHARSET", kmsg);
if (p == NULL)
p = hdr((char *)"CODEPAGE", kmsg);
if (p)
outcode = readchrs(p);
else {
p=hdr((char *)"Content-Type",msg);
if (p == NULL)
p=hdr((char *)"RFC-Content-Type",kmsg);
if (p == NULL)
p=hdr((char *)"Content-Type",kmsg);
if (p)
outcode=readcharset(p);
else {
q = rfcmsgid(hdr((char *)"MSGID",kmsg),bestaka);
if ((hdr((char *)"Message-ID",msg)) || (hdr((char *)"RFC-Message-ID",kmsg)) ||
(hdr((char *)"Message-ID",kmsg)) || (hdr((char *)"RFCID",kmsg)) ||
(hdr((char *)"ORIGID",kmsg)) || ((hdr((char *)"MSGID",kmsg)) && (!chkftnmsgid(q))))
outcode = defaultrfcchar;
else
outcode = defaultftnchar;
if (q)
free(q);
q = NULL;
}
}
/*
* A hack for TerMail
*/
p = hdr((char *)"PID", kmsg);
if ((p) && (!strncmp(p, "TerMail", 7)) && (outcode == defaultrfcchar))
outcode = defaultftnchar;
if (dirtyoutcode != CHRS_NOTSET)
outcode = dirtyoutcode;
if (pgpsigned)
incode = outcode;
if (kmsg && !strcmp(kmsg->key,"AREA")) {
/*
* The msgs record is already loaded.
*/
newsgroup = xstrcpy(msgs.Newsgroup);
if (strlen(msgs.Distribution))
distribution = xstrcpy(msgs.Distribution);
// if (strlen(msgs.Moderator)) {
// moderator = xstrcpy(msgs.Moderator);
// if (msgs.MsgKinds == USEMOD)
// modtype = 1;
// }
Syslog('M', "newsgroup %s, distribution %s", printable(newsgroup, 0), printable(distribution, 0));
newsmode = TRUE;
if ((modtype == 1) && (!hdr((char *)"Approved",msg)) &&
(!hdr((char *)"RFC-Approved",kmsg)) && (!hdr((char *)"Approved",kmsg)))
newsmode = TRUE;
} else
newsmode = FALSE;
Syslog('m', "Got %s message", newsmode?"echo":"netmail");
if ((outcode == CHRS_NOTSET) && (hdr((char *)"MSGID", kmsg))) {
p = rfcmsgid(hdr((char *)"MSGID",kmsg),bestaka);
if ((hdr((char *)"Message-ID",msg)) || (hdr((char *)"RFC-Message-ID",kmsg)) ||
(hdr((char *)"Message-ID",kmsg)) || (hdr((char *)"RFCID",kmsg)) ||
(hdr((char *)"ORIGID",kmsg)) || ((hdr((char *)"MSGID",kmsg)) && (!chkftnmsgid(p))))
outcode = defaultrfcchar;
else
outcode = defaultftnchar;
free(p);
}
if (pgpsigned)
incode = outcode;
else if (incode == CHRS_NOTSET)
incode = getincode(outcode);
/*
* fsc-0038 defines "^aDOMAIN: othernet 99:12/34 fidonet 2:293/2219"
*/
if ((p=hdr((char *)"DOMAIN",kmsg)) && (!strchr(p,'@'))) {
strncpy(buf,p,sizeof(buf)-1);
buf[sizeof(buf)-1]='\0';
l=strtok(buf," \n");
p=strtok(NULL," \n");
r=strtok(NULL," \n");
q=strtok(NULL," \n");
if ((ta=parsefnode(p))) {
t->point=ta->point;
t->node=ta->node;
t->net=ta->net;
t->zone=ta->zone;
tidy_faddr(ta);
}
t->domain=xstrcpy(l);
if ((ta=parsefnode(q))) {
f->point=ta->point;
f->node=ta->node;
f->net=ta->net;
f->zone=ta->zone;
tidy_faddr(ta);
}
f->domain=xstrcpy(r);
} else if ((p=hdr((char *)"INTL",kmsg))) {
strncpy(buf,p,sizeof(buf)-1);
buf[sizeof(buf)-1]='\0';
l=strtok(buf," \n");
r=strtok(NULL," \n");
if ((ta=parsefnode(l))) {
t->point=ta->point;
t->node=ta->node;
t->net=ta->net;
t->zone=ta->zone;
if (ta->domain) {
if (t->domain)
free(t->domain);
t->domain=ta->domain;
ta->domain=NULL;
}
tidy_faddr(ta);
}
if ((ta=parsefnode(r))) {
f->point=ta->point;
f->node=ta->node;
f->net=ta->net;
f->zone=ta->zone;
if (ta->domain) {
if (f->domain)
free(f->domain);
f->domain=ta->domain;
ta->domain=NULL;
}
tidy_faddr(ta);
}
}
/*
* fidogate generates "^aDOMAIN: Z2@fidonet"
*/
if ((f->domain==NULL) && ((p=hdr((char *)"DOMAIN",kmsg)) && (q=strchr(p,'@')))) {
*q='\0';
f->domain=xstrcpy(q+1);
*q='@';
}
if ((p=hdr((char *)"FMPT",kmsg)))
f->point=atoi(p);
if ((p=hdr((char *)"TOPT",kmsg)))
t->point=atoi(p);
if (!newsmode) {
Syslog('m', "final from: %s",ascfnode(f,0xff));
Syslog('m', "final to: %s",ascfnode(t,0xff));
}
if (!newsmode) {
p=hdr((char *)"Resent-To",msg);
if (p == NULL)
p=hdr((char *)"To",msg);
if (p == NULL)
p=hdr((char *)"RFC-Resent-To",kmsg);
if (p == NULL)
p=hdr((char *)"RFC-To",kmsg);
if (p && is_local(t)) {
while (*p == ' ')
p++;
strncpy(buf, p, sizeof(buf) -1);
if (*(p = buf + strlen(buf) -1) == '\n')
*p='\0';
} else if (modtype == 1)
sprintf(buf,"%s",moderator);
else
sprintf(buf,"%s",ascinode(t,0x7f));
substitute(buf);
Syslog('+', "mail from %s to %s",ascfnode(f,0x7f),buf);
To = xstrcpy(buf);
// if (p)
// free(p);
p = NULL;
p = hdr((char *)"Return-Path",msg);
if (p == NULL)
p=hdr((char *)"RFC-Return-Path",kmsg);
if (p == NULL)
p=hdr((char *)"Return-Path",kmsg);
if ((CFG.EmailMode == E_PRMISP) && (p == NULL))
p=hdr((char *)"From",msg);
if (p)
sprintf(MailFrom, "%s", p);
else
sprintf(MailFrom, "%s", ascinode(f,0x7f));
Syslog('m', "MailFrom: %s", MailFrom);
if (To)
sprintf(MailTo, "%s", To);
else
sprintf(MailTo, "%s", t->name);
Syslog('m', "MailTo: %s", MailTo);
/*
* Because we need the same stream for news and email
* we need to check if the newsfile is already open.
*/
if (newsopen) {
fclose(nfp);
newsopen = FALSE;
}
if ((nfp = tmpfile()) == NULL) {
WriteError("$Unable to open temporary file");
return 4;
}
Syslog('m', "Prepare is ready");
if (modtype == 1)
newsmode = TRUE;
}
if (newsmode) {
/*
* Open temporary newsfile, append messages if it already exists.
*/
if (!newsopen) {
p = calloc(PATH_MAX, sizeof(char));
sprintf(p, "%s/tmp/newsout", getenv("MBSE_ROOT"));
if ((nfp = fopen(p, "a")) == NULL) {
WriteError("$Can't open %s", p);
free(p);
return 2;
}
free(p);
newsopen = TRUE;
}
if ((p=hdr((char *)"Path",msg)) == NULL)
p=hdr((char *)"RFC-Path",kmsg);
rlist=NULL;
fill_rlist(&rlist, p);
for (qmsg = kmsg; qmsg; qmsg = qmsg->next)
if (strcasecmp(qmsg->key, "SPTH") == 0)
fill_list(&ftnpath, qmsg->val, &rlist);
for (qmsg = kmsg; qmsg; qmsg = qmsg->next)
if (strcasecmp(qmsg->key, "PATH") == 0)
fill_list(&ftnpath, qmsg->val, &rlist);
tidy_falist(&rlist);
/*
* Build Path: headerline
*/
q = xstrcpy((char *)"Path: ");
if (CFG.newsfeed == FEEDUUCP) {
/*
* If we don't run our own newsserver we have to simulate and
* add the UUCP nodename here.
*/
memset(&utsbuf, 0, sizeof(utsbuf));
if (uname(&utsbuf)) {
WriteError("Can't get system nodename");
} else {
q = xstrcat(q, utsbuf.nodename);
q = xstrcat(q, (char *)"!");
}
}
tfaddr = fido2faddr(msgs.Aka);
q = xstrcat(q, ascinode(tfaddr, 0x07));
tidy_faddr(tfaddr);
q = xstrcat(q, (char *)"!");
if (ftnpath)
for (tfa=ftnpath->next;tfa;tfa=tfa->next) {
/* FIXME: possible memory leak */
q = xstrcat(q, ascinode(tfa->addr,0x1f));
q = xstrcat(q, (char *)"!");
}
tidy_falist(&ftnpath);
if (p) {
while (isspace(*p))
p++;
q = xstrcat(q, p);
} else
q = xstrcat(q, (char *)"not-for-mail");
sprintf(temp, "%s\n", q);
Send(newsmode, temp);
free(q);
if ((p = hdr((char *)"Newsgroups",msg))) {
/*
* The gate at puddle.fidonet.org put spaces in Newsgroups header
*/
if ((strstr(p,", "))) {
while ((r = strchr(p, ' '))) {
*r = '\0';
strcat(p,r+1);
}
}
}
if (p == NULL)
p=hdr((char *)"RFC-Newsgroups",kmsg);
if (p == NULL)
p=hdr((char *)"Newsgroups",kmsg);
if (p) {
while (*p && isspace(*p))
p++;
sprintf(temp,"Newsgroups: %s\n",newsgroup);
Send(newsmode, temp);
sprintf(temp,"X-Origin-Newsgroups: %s",p);
Send(newsmode, temp);
} else {
sprintf(temp,"Newsgroups: %s\n",newsgroup);
Send(newsmode, temp);
}
if ((p=hdr((char *)"Distribution",msg))) {
sprintf(temp,"Distribution:%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-Distribution",kmsg))) {
sprintf(temp,"Distribution: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"Distribution",kmsg))) {
sprintf(temp,"Distribution: %s",p);
Send(newsmode, temp);
} else if (distribution) {
sprintf(temp,"Distribution: %s\n",distribution);
Send(newsmode, temp);
}
p = hdr((char *)"Comment-To",msg);
if (p == NULL)
p=hdr((char *)"X-Comment-To",msg);
if (p == NULL)
p=hdr((char *)"To",msg);
if ((p) && (strcasecmp(p,"All\n"))) {
sprintf(temp,"X-Comment-To:%s",hdrconv(p,outcode,incode));
Send(newsmode, temp);
} else {
if (p == NULL)
p=hdr((char *)"RFC-X-Comment-To",kmsg);
if (p == NULL)
p=hdr((char *)"RFC-Comment-To",kmsg);
if (p == NULL)
p=hdr((char *)"RFC-To",kmsg);
if ((p) && (strcasecmp(p,"All\n"))) {
sprintf(temp,"X-Comment-To: %s",hdrconv(p,outcode,incode));
Send(newsmode, temp);
} else if ((t) && (t->name) && (strcasecmp(t->name,"All"))) {
sprintf(temp,"X-Comment-To: %s\n",hdrconv(t->name,outcode,incode));
Send(newsmode, temp);
} else {
sprintf(temp,"X-Comment-To: All\n");
Send(newsmode, temp);
}
}
// for (tmpml=approve;tmpml;tmpml=tmpml->next) {
// if ((strncmp(newsgroup,tmpml->prefix, strlen(tmpml->prefix)) == 0)) {
// modtype=2;
// moderator=xstrcpy(tmpml->address);
// break;
// }
// }
if ((p=hdr((char *)"Approved",msg))) {
sprintf(temp,"Approved:%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-Approved",kmsg))) {
sprintf(temp,"Approved: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"Approved",kmsg))) {
sprintf(temp,"Approved: %s",p);
Send(newsmode, temp);
} else if (modtype==2) {
sprintf(temp,"Approved: %s\n",moderator);
Send(newsmode, temp);
}
} else { /* if newsmode */
now = time(NULL);
// if (CFG.EmailMode == E_NOISP) {
// /*
// * Probaly not needed as messages for systems without ISP never get here.
// * Perhaps only news to moderators.
// */
// Syslog('m', "We should not be here");
// sprintf(temp, "From %s!%s %s", ascinode(f,0x3f), ascinode(f,0x40), ctime(&mdate));
// Send(FALSE, temp);
// }
Syslog('m', "Should send Received: header for mbfido");
sprintf(temp, "Received: from %s\n", ascinode(f, 0x3f));
Send(FALSE, temp);
sprintf(temp, "\tby %s with FTN (mbfido v.%s) id AA%u\n", ascinode(bestaka,0x3f), VERSION, getpid());
Send(FALSE, temp);
sprintf(temp, "\t%s\n", rfcdate(now));
Send(FALSE, temp);
Syslog('m', "Is done now");
for (qmsg = kmsg; qmsg; qmsg = qmsg->next)
if (!strcasecmp(qmsg->key,"RFC-Received")) {
sprintf(temp, "%s: %s", qmsg->key+4, qmsg->val);
Send(FALSE, temp);
}
for (qmsg = msg; qmsg; qmsg = qmsg->next)
if (!strcasecmp(qmsg->key,"Received")) {
sprintf(temp, "%s:%s", qmsg->key, qmsg->val);
Send(FALSE, temp);
}
if ((p=hdr((char *)"Apparently-To",msg))) {
sprintf(temp, "Apparently-To: %s\n",p);
Send(FALSE, temp);
} else if ((p=hdr((char *)"RFC-Apparently-To",kmsg))) {
sprintf(temp, "Apparently-To: %s\n",p);
Send(FALSE, temp);
} else if ((p=hdr((char *)"Apparently-To",kmsg))) {
sprintf(temp, "Apparently-To: %s\n",p);
Send(FALSE, temp);
} else if ((is_local(t))) {
sprintf(temp, "Apparently-To: %s\n",buf);
Send(FALSE, temp);
}
if (flags & M_RRQ)
rrq=TRUE;
else
rrq=FALSE;
if (rrq && !hdr((char *)"RFC-Return-Receipt-To",kmsg) &&
!hdr((char *)"Return-Receipt-To",msg) &&
!hdr((char *)"RFC-Notice-Requested-Upon-Delivery-To",kmsg) &&
!hdr((char *)"Notice-Requested-Upon-Delivery-To",msg)) {
sprintf(temp,"Notice-Requested-Upon-Delivery-To: %s\n",buf);
Send(FALSE, temp);
}
if (t->name == NULL)
t->name=xstrcpy((char *)"Postmaster");
p=hdr((char *)"Resent-To",msg);
if (p == NULL)
p=hdr((char *)"To",msg);
if (p) {
sprintf(temp,"To:%s",p);
Send(FALSE, temp);
} else {
if (p == NULL)
p=hdr((char *)"RFC-Resent-To",kmsg);
if (p == NULL)
p=hdr((char *)"RFC-To",kmsg);
if (p) {
Syslog('m', "2");
sprintf(temp,"To: %s\n",p);
Send(FALSE, temp);
} else if (modtype == 1) {
sprintf(temp,"To: %s\n",moderator);
Send(FALSE, temp);
} else if (is_local(t)) {
Syslog('m', "3");
sprintf(temp, "To: %s <%s>\n", t->name, buf);
Send(FALSE, temp);
} else {
Syslog('m', "4");
sprintf(temp,"To: %s\n",ascinode(t,0xff));
Send(FALSE, temp);
}
}
}
if ((p = hdr((char *)"From",msg))) {
sprintf(temp, "From:%s", hdrconv(p,outcode,incode));
Send(newsmode, temp);
} else if ((p = hdr((char *)"RFC-From",kmsg))) {
Syslog('m', "b");
sprintf(temp, "From: %s", hdrconv(p,outcode,incode));
Send(newsmode, temp);
} else if ((p = hdr((char *)"From\n",kmsg))) {
Syslog('m', "c");
sprintf(temp, "From: %s", hdrconv(p,outcode,incode));
Send(newsmode, temp);
} else if ((p = hdr((char *)"X-PcBoard-FROM",msg))) {
if (f->name) {
while (isspace(*p))
p++;
p[strlen(p)-1] = '\0';
sprintf(temp,"From: %s <%s>\n", hdrconv(f->name,outcode,incode), p);
} else {
sprintf(temp,"From:%s\n", p);
}
Send(newsmode, temp);
} else if ((hdr((char *)"REPLYADDR",kmsg)) && (p=xstrcpy(hdr((char *)"REPLYADDR",kmsg)))) {
if (*(r=p+strlen(p)-1) == '\n')
*(r--)='\0';
while (isspace(*r))
*(r--)='\0';
q=xstrcpy(hdr((char *)"X-RealName",msg));
if (q == NULL)
q=xstrcpy(hdr((char *)"RealName",msg));
if (q == NULL)
q=xstrcpy(hdr((char *)"X-RealName",kmsg));
if (q == NULL)
q=xstrcpy(hdr((char *)"RealName",kmsg));
if (q) {
if (*(r=q+strlen(q)-1) == '\n')
*(r--)='\0';
while (isspace(*r))
*(r--)='\0';
for (l=q; isspace(*l); )
l++;
if ((*l == '\"') && (*r == '\"')) {
l++;
*r--='\0';
}
Syslog('m', "d");
sprintf(temp,"From: \"%s\" <%s>\n",hdrconv(l,outcode,incode),p);
Send(newsmode, temp);
free(q);
} else if (f->name) {
Syslog('m', "e");
sprintf(temp,"From: \"%s\" <%s>\n",hdrconv(f->name,outcode,incode),p);
Send(newsmode, temp);
} else {
Syslog('m', "f");
sprintf(temp,"From: %s\n",p);
Send(newsmode, temp);
}
free(p);
}
if (p)
sprintf(temp,"X-FTN-Sender: %s\n",hdrconv(ascinode(f,0xff),outcode,incode));
else
sprintf(temp,"From: %s\n",hdrconv(ascinode(f,0xff),outcode,incode));
Send(newsmode, temp);
if ((p=hdr((char *)"Reply-To",msg))) {
sprintf(temp,"Reply-To:%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-Reply-To",kmsg))) {
sprintf(temp,"Reply-To: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"Reply-To",kmsg))) {
sprintf(temp,"Reply-To: %s",p);
Send(newsmode, temp);
} else if (((p=backalias(f))) && strlen(CFG.sysdomain)) {
sprintf(temp,"Reply-To: %s@%s\n",p,CFG.sysdomain);
Send(newsmode, temp);
} else if ((p=hdr((char *)"REPLYADDR",kmsg))) {
sprintf(temp,"Reply-To: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"REPLYTO",kmsg))) {
sprintf(temp,"Reply-To: %s\n",ascinode(parsefaddr(p),0xff));
Send(newsmode, temp);
}
if ((p=hdr((char *)"Date",msg))) {
sprintf(temp,"Date:%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-Date",kmsg))) {
sprintf(temp,"Date: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"Date",kmsg))) {
sprintf(temp,"Date: %s",p);
Send(newsmode, temp);
} else if (newsmode) {
/*
* Restamp future postings
*/
now = time(NULL);
if (mdate > now) {
Syslog('+', "Future posting: %s", rfcdate(mdate));
sprintf(temp,"Date: %s\n", rfcdate(now));
Send(newsmode, temp);
sprintf(temp,"X-Origin-Date: %s\n", rfcdate(mdate));
Send(newsmode, temp);
} else if ((mdate < now-14*24*60*60) && (mdate > time(&now)-RESTAMP_OLD_POSTINGS*24*60*60)) {
/*
* Restamp old postings
*/
Syslog('+', "Article too old, restamped: %s", rfcdate(mdate));
sprintf(temp,"Date: %s\n", rfcdate(now));
Send(newsmode, temp);
sprintf(temp,"X-Origin-Date: %s\n", rfcdate(mdate));
Send(newsmode, temp);
} else {
sprintf(temp,"Date: %s\n",rfcdate(mdate));
Send(newsmode, temp);
}
} else {
sprintf(temp,"Date: %s\n",rfcdate(mdate));
Send(newsmode, temp);
}
if ((p = hdr((char *)"Subject",msg)))
sprintf(temp, "Subject:%s", hdrconv(p,outcode,incode));
else if ((p = hdr((char *)"RFC-Subject",kmsg)))
sprintf(temp, "Subject: %s", hdrconv(p,outcode,incode));
else if ((p = hdr((char *)"Subject",kmsg)))
sprintf(temp, "Subject: %s", hdrconv(p,outcode,incode));
else if ((p = hdr((char *)"X-PcBoard-SUBJECT",msg)))
sprintf(temp, "Subject:%s", hdrconv(p,outcode,incode));
else if (subj && (strspn(subj," \t\n\r") != strlen(subj)))
sprintf(temp, "Subject: %s\n", hdrconv(subj,outcode,incode));
else
sprintf(temp, "Subject: <none>\n");
Send(newsmode, temp);
if ((p=hdr((char *)"Message-ID",msg)))
sprintf(temp,"Message-ID:%s",p);
else if ((p=hdr((char *)"RFC-Message-ID",kmsg)))
sprintf(temp,"Message-ID: %s",p);
else if ((p=hdr((char *)"Message-ID",kmsg)))
sprintf(temp,"Message-ID: %s",p);
else if ((p=hdr((char *)"RFCID",kmsg)))
if ((p[0]=='<')) {
/* "^aRFCID: <local@machine>" */
if ((p[strlen(p)-2]=='>'))
sprintf(temp,"Message-ID: %s",p);
/* "^aRFCID: <local@machine" */
/* I saw it on some IntToss gated articles
* it seems to be a bug on the program or something
* like that, because in the majority of IntToss gated
* articles it is "^aRFCID: local@machine"
*/
else {
p[strlen(p)-1]='\0';
sprintf(temp,"Message-ID: %s>\n",p);
}
/* "^aRFCID: local@machine" */
} else {
p[strlen(p)-1]='\0';
sprintf(temp,"Message-ID: <%s>\n",p);
} else if ((p=hdr((char *)"ORIGID",kmsg))) {
sprintf(temp,"Message-ID: %s",p);
} else if ((p = hdr((char *)"MSGID",kmsg))) {
q = rfcmsgid(p, bestaka);
sprintf(temp,"Message-ID: %s\n", q);
free(q);
} else
sprintf(temp,"Message-ID: <%lu@%s.ftn>\n", mdate^(subj?str_crc32(subj):0L), ascinode(f,0x1f));
Send(newsmode, temp);
if (newsmode) {
if ((p=hdr((char *)"References",msg))) {
sprintf(temp,"References:%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-References",kmsg))) {
sprintf(temp,"References: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"References",kmsg))) {
sprintf(temp,"References: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"ORIGREF",kmsg))) {
sprintf(temp,"References: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"REPLY",kmsg))) {
q = rfcmsgid(p, bestaka);
sprintf(temp,"References: %s\n", q);
Send(newsmode, temp);
free(q);
}
} else {
if ((p=hdr((char *)"In-Reply-To",msg))) {
sprintf(temp,"In-Reply-To:%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-In-Reply-To",kmsg))) {
sprintf(temp,"In-Reply-To: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"REPLY",kmsg))) {
q = rfcmsgid(p,bestaka);
sprintf(temp,"In-Reply-To: %s\n", q);
Send(newsmode, temp);
free(q);
}
}
if ((p=hdr((char *)"Organization",msg))) {
sprintf(temp,"Organization:%s",hdrconv(p,outcode,incode));
Send(newsmode, temp);
} else if ((p=hdr((char *)"Organisation",msg))) {
sprintf(temp,"Organization:%s",hdrconv(p,outcode,incode));
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-Organization",kmsg))) {
sprintf(temp,"Organization: %s",hdrconv(p,outcode,incode));
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-Organisation",kmsg))) {
sprintf(temp,"Organization: %s",hdrconv(p,outcode,incode));
Send(newsmode, temp);
} else if ((p=hdr((char *)"Organization",kmsg))) {
sprintf(temp,"Organization: %s",hdrconv(p,outcode,incode));
Send(newsmode, temp);
} else if ((p=hdr((char *)"Organisation",kmsg))) {
sprintf(temp,"Organization: %s",hdrconv(p,outcode,incode));
Send(newsmode, temp);
} else if (origline) {
sprintf(temp,"Organization: %s\n",hdrconv(origline,outcode,incode));
Send(newsmode, temp);
}
if ((p=hdr((char *)"Supersedes",msg))) {
sprintf(temp,"Supersedes:%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-Supersedes",kmsg))) {
sprintf(temp,"Supersedes: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"Supersedes",kmsg))) {
sprintf(temp,"Supersedes: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"ACUPDATE",kmsg)) && (strstr(p,"MODIFY"))) {
q = rfcmsgid(p+8,bestaka);
sprintf(temp,"Supersedes: %s\n", q);
Send(newsmode, temp);
free(q);
}
if (CFG.allowcontrol) {
if ((p=hdr((char *)"Control",msg))) {
sprintf(temp,"Control:%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-Control",kmsg))) {
sprintf(temp,"Control: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"Control",kmsg))) {
sprintf(temp,"Control: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"ACUPDATE",kmsg)) && (strstr(p,"DELETE"))) {
q = rfcmsgid(p+8,bestaka);
sprintf(temp,"Control: cancel %s\n", q);
Send(newsmode, temp);
free(q);
}
}
sprintf(temp, "X-FTN-CHRS: %s\n", getchrs(incode));
Send(newsmode, temp);
if (incode != outcode) {
sprintf(temp, "X-FTN-ORIGCHRS: %s\n", getchrs(outcode));
Send(newsmode, temp);
}
charset = getcharset(incode);
if ((p=hdr((char *)"Mime-Version",msg))) {
sprintf(temp,(char *)"Mime-Version:%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-Mime-Version",kmsg))) {
sprintf(temp,(char *)"Mime-Version: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"Mime-Version",kmsg))) {
sprintf(temp,(char *)"Mime-Version: %s",p);
Send(newsmode, temp);
} else if ((charset) && (incode != CHRS_NOTSET)) {
sprintf(temp,"Mime-Version: 1.0\n");
Send(newsmode, temp);
}
if ((p=hdr((char *)"Content-Type",msg))) {
sprintf(temp,"Content-Type:%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-Content-Type",kmsg))) {
sprintf(temp,"Content-Type: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"Content-Type",kmsg))) {
sprintf(temp,"Content-Type: %s",p);
Send(newsmode, temp);
} else if ((charset) && (incode != CHRS_NOTSET)) {
if ((p=hdr((char *)"FSCHTML",kmsg)) || (p=hdr((char *)"HTML",kmsg)))
sprintf(temp,"Content-Type: text/html; charset=%s\n",charset);
else
sprintf(temp,"Content-Type: text/plain; charset=%s\n",charset);
Send(newsmode, temp);
}
if ((p=hdr((char *)"Content-Length",msg))) {
sprintf(temp,"Content-Length%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-Content-Length",kmsg))) {
sprintf(temp,"Content-Length: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"Content-Length",kmsg))) {
sprintf(temp,"Content-Length: %s",p);
Send(newsmode, temp);
}
temp[0] = '\0';
if ((p=hdr((char *)"Content-Transfer-Encoding",msg)))
sprintf(temp,"Content-Transfer-Encoding:%s",p);
else if ((p=hdr((char *)"RFC-Content-Transfer-Encoding",kmsg)))
sprintf(temp,"Content-Transfer-Encoding: %s",p);
else if ((p=hdr((char *)"Content-Transfer-Encoding",kmsg)))
sprintf(temp,"Content-Transfer-Encoding: %s",p);
else if ((charset) && (incode == CHRS_ISO_8859_1_QP))
sprintf(temp,"Content-Transfer-Encoding: quoted-printable\n");
else if ((charset) && (incode != CHRS_NOTSET)) {
if ((incode == CHRS_ASCII || incode == CHRS_UTF_7))
sprintf(temp,"Content-Transfer-Encoding: 7bit\n");
else if (strncasecmp(charset,"iso-2022-",9) == 0)
sprintf(temp,"Content-Transfer-Encoding: 7bit\n");
else
sprintf(temp,"Content-Transfer-Encoding: 8bit\n"); /* all others are 8 bit */
}
if (temp[0])
Send(newsmode, temp);
if (newsmode) {
if ((p=hdr((char *)"X-Newsreader",msg))) {
sprintf(temp,"X-Newsreader: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-X-Newsreader",kmsg))) {
sprintf(temp,"X-Newsreader: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"X-Newsreader",kmsg))) {
sprintf(temp,"X-Newsreader: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"PID",kmsg))) {
sprintf(temp,"X-Newsreader: %s",p);
Send(newsmode, temp);
}
} else {
if ((p=hdr((char *)"X-Mailer",msg))) {
sprintf(temp,"X-Mailer:%s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"RFC-X-Mailer",kmsg))) {
sprintf(temp,"X-Mailer: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"X-Mailer",kmsg))) {
sprintf(temp,"X-Mailer: %s",p);
Send(newsmode, temp);
} else if ((p=hdr((char *)"PID",kmsg))) {
sprintf(temp,"X-Mailer: %s",p);
Send(newsmode, temp);
}
}
for (qmsg=msg;qmsg;qmsg=qmsg->next) {
if (strcasecmp(qmsg->key,"X-Body-Start") &&
strcasecmp(qmsg->key,"X-PcBoard-FROM") &&
strcasecmp(qmsg->key,"X-PcBoard-SUBJECT") &&
strcasecmp(qmsg->key,"X-PcBoard-PACKOUT") &&
(strcasecmp(qmsg->key,"Control") || !CFG.allowcontrol) &&
strcasecmp(qmsg->key,"Supersedes") &&
strcasecmp(qmsg->key,"Mime-Version") &&
strcasecmp(qmsg->key,"Content-Type") &&
strcasecmp(qmsg->key,"Content-Lenght") &&
strcasecmp(qmsg->key,"Content-Transfer-Encoding") &&
strcasecmp(qmsg->key,"Lines") &&
strcasecmp(qmsg->key,"Path") &&
strcasecmp(qmsg->key,"Received") &&
strcasecmp(qmsg->key,"From") &&
strcasecmp(qmsg->key,"To") &&
strcasecmp(qmsg->key,"Comment-To") &&
strcasecmp(qmsg->key,"X-Comment-To") &&
strcasecmp(qmsg->key,"Date") &&
strcasecmp(qmsg->key,"Subject") &&
strcasecmp(qmsg->key,"Reply-To") &&
strcasecmp(qmsg->key,"In-Reply-To") &&
strcasecmp(qmsg->key,"References") &&
strcasecmp(qmsg->key,"Organization") &&
strcasecmp(qmsg->key,"Organisation") &&
strcasecmp(qmsg->key,"X-Mailer") &&
strcasecmp(qmsg->key,"X-Newsreader") &&
(strcasecmp(qmsg->key,"Newsgroups") || !newsmode) &&
strcasecmp(qmsg->key,"Apparently-To") &&
strcasecmp(qmsg->key,"Distribution") &&
strcasecmp(qmsg->key,"Approved") &&
strcasecmp(qmsg->key,"Message-ID")) {
sprintf(temp,"%s:%s",qmsg->key,hdrconv(qmsg->val,outcode,incode));
Send(newsmode, temp);
}
}
if ((p=compose_flags(flags,hdr((char *)"FLAGS",kmsg)))) {
sprintf(temp,"X-FTN-FLAGS:%s\n",p);
Send(newsmode, temp);
free(p);
}
for (qmsg=kmsg;qmsg;qmsg=qmsg->next) {
if (strcasecmp(qmsg->key,"INTL") &&
strcasecmp(qmsg->key,"FMPT") &&
strcasecmp(qmsg->key,"TOPT") &&
strcasecmp(qmsg->key,"FLAGS") &&
strcasecmp(qmsg->key,"CHARSET") &&
strcasecmp(qmsg->key,"CHRS") &&
strcasecmp(qmsg->key,"CODEPAGE") &&
strcasecmp(qmsg->key,"ORIGCHRS") &&
/*
* RFC: is used by fidogate to tell how completly RFC headers were
* gated (0=no headers at all; 1=some headers; 2=all headers)
*/
strcasecmp(qmsg->key,"RFC") &&
strcasecmp(qmsg->key,"RFCID") &&
strcasecmp(qmsg->key,"ORIGID") &&
strcasecmp(qmsg->key,"ORIGREF") &&
strcasecmp(qmsg->key,"X-GATEWAY") &&
strcasecmp(qmsg->key,"Lines") &&
/* strcmp(qmsg->key,"Path") && */
strcasecmp(qmsg->key,"PATH") &&
strcasecmp(qmsg->key,"Received") &&
strcasecmp(qmsg->key,"From") &&
strcasecmp(qmsg->key,"To") &&
strcasecmp(qmsg->key,"Comment-To") &&
strcasecmp(qmsg->key,"X-Comment-To") &&
strcasecmp(qmsg->key,"Date") &&
strcasecmp(qmsg->key,"Subject") &&
strcasecmp(qmsg->key,"Reply-To") &&
strcasecmp(qmsg->key,"In-Reply-To") &&
strcasecmp(qmsg->key,"References") &&
strcasecmp(qmsg->key,"Organization") &&
strcasecmp(qmsg->key,"Organisation") &&
strcasecmp(qmsg->key,"X-Mailer") &&
strcasecmp(qmsg->key,"X-Newsreader") &&
(strcasecmp(qmsg->key,"Newsgroups") || !newsmode) &&
strcasecmp(qmsg->key,"Apparently-To") &&
strcasecmp(qmsg->key,"Message-ID") &&
strcasecmp(qmsg->key,"Mime-Version") &&
strcasecmp(qmsg->key,"Content-Type") &&
strcasecmp(qmsg->key,"Content-Lenght") &&
strcasecmp(qmsg->key,"Content-Transfer-Encoding") &&
(strcasecmp(qmsg->key,"RFC-Control") || !CFG.allowcontrol) &&
strcasecmp(qmsg->key,"RFC-Supersedes") &&
strcasecmp(qmsg->key,"RFC-Mime-Version") &&
strcasecmp(qmsg->key,"RFC-Content-Type") &&
strcasecmp(qmsg->key,"RFC-Content-Lenght") &&
strcasecmp(qmsg->key,"RFC-Content-Transfer-Encoding") &&
strcasecmp(qmsg->key,"RFC-Lines") &&
strcasecmp(qmsg->key,"RFC-Path") &&
strcasecmp(qmsg->key,"RFC-Received") &&
strcasecmp(qmsg->key,"RFC-From") &&
strcasecmp(qmsg->key,"RFC-To") &&
strcasecmp(qmsg->key,"RFC-Comment-To") &&
strcasecmp(qmsg->key,"RFC-X-Comment-To") &&
strcasecmp(qmsg->key,"RFC-Date") &&
strcasecmp(qmsg->key,"RFC-Subject") &&
strcasecmp(qmsg->key,"RFC-Reply-To") &&
strcasecmp(qmsg->key,"RFC-In-Reply-To") &&
strcasecmp(qmsg->key,"RFC-References") &&
strcasecmp(qmsg->key,"RFC-Organization") &&
strcasecmp(qmsg->key,"RFC-X-Mailer") &&
strcasecmp(qmsg->key,"RFC-X-Newsreader") &&
(strcasecmp(qmsg->key,"RFC-Newsgroups") || !newsmode) &&
strcasecmp(qmsg->key,"RFC-Apparently-To") &&
strcasecmp(qmsg->key,"RFC-Distribution") &&
strcasecmp(qmsg->key,"RFC-Approved") &&
strcasecmp(qmsg->key,"RFC-Message-ID")) {
if (!strncmp(qmsg->key,"RFC-",4)) {
sprintf(temp,"%s: %s",qmsg->key+4,hdrconv(qmsg->val,outcode,incode));
Send(newsmode, temp);
} else if ((!strncasecmp(qmsg->key,"X-",2)) || (!strncasecmp(qmsg->key,"NNTP-",5))) {
sprintf(temp,"%s: %s",qmsg->key,hdrconv(qmsg->val,outcode,incode));
Send(newsmode, temp);
} else if ((!strncasecmp(qmsg->key,"ZC-",3))) {
sprintf(temp,"X-%s: %s",qmsg->key,qmsg->val);
Send(newsmode, temp);
} else if ((!strcasecmp(qmsg->key,"Origin")) || (!strcasecmp(qmsg->key,"MOOD"))) {
sprintf(temp,"X-FTN-%s: %s",qmsg->key,hdrconv(qmsg->val,outcode,incode));
Send(newsmode, temp);
} else {
sprintf(temp,"X-FTN-%s: %s",qmsg->key,qmsg->val);
Send(newsmode, temp);
}
}
}
if (newsmode) {
fa_list *tmpl,*ptl=NULL;
char sbe[16];
int seenlen=0,oldnet;
for (qmsg = kmsg; qmsg; qmsg = qmsg->next)
if (!strcmp(qmsg->key, "PATH")) {
fill_path(&ptl, qmsg->val);
}
uniq_list(&ptl);
/*
* ensure it will not match for the first entry
*/
oldnet = ptl->addr->net-1;
q = xstrcpy((char*)"X-FTN-PATH:");
for (tmpl = ptl; tmpl; tmpl = tmpl->next) {
if (tmpl->addr->net == oldnet)
sprintf(sbe," %u",tmpl->addr->node);
else
sprintf(sbe," %u/%u",tmpl->addr->net, tmpl->addr->node);
oldnet=tmpl->addr->net;
seenlen+=strlen(sbe);
if (seenlen > MAXPATH) {
seenlen=0;
sprintf(temp, "%s\n", q);
Send(newsmode, temp);
free(q);
q = xstrcpy((char *)"X-FTN-PATH:");
sprintf(sbe," %u/%u",tmpl->addr->net, tmpl->addr->node);
seenlen=strlen(sbe);
}
q = xstrcat(q, sbe);
}
sprintf(temp,"%s\n", q);
Send(newsmode, temp);
free(q);
tidy_falist(&ptl);
if ((hdr((char *)"X-FTN-SPTH", msg))) {
sprintf(temp,"X-FTN-SPTH: %s\n", ascfnode(bestaka,0x1f));
Send(newsmode, temp);
}
}
/*
* Search past RFC headers.
*/
while (fgets(buf,sizeof(buf)-1,fp)) {
if ((strlen(buf) == 1) && (buf[0] == '\n')) {
break;
}
}
/*
* Send the message body
*/
pass=1;
count = lines = 0;
first = TRUE;
Syslog('m', "Start sending message body");
while (fgets(buf,sizeof(buf)-1,fp) && pass) {
if (first) {
p = xstrcpy((char *)"\n");
Send(newsmode, p);
free(p);
first = FALSE;
/* FIXME: Maybe scan now for repeating headers and drop them as they will appear in the message text */
if ((p=hdr((char *)"X-Body-Start",msg))) {
lines++;
q = xstrcpy(strkconv(p, outcode, incode));
Send(newsmode, q);
free(q);
}
}
if (ftell(fp) > endmsg_off) {
Syslog('m', "line \"%s\" past message end %ld %ld", buf,(long)endmsg_off, ftell(fp));
pass=0;
}
if (pass) {
p=buf;
b=NULL;
while ((c=*p++)) {
switch (c) {
case ' ': b=p-1; break;
case '\n': b=NULL; count=0; lines++; break;
}
if ((count++ > BOUNDARY) && (!pgpsigned)) {
if (b) {
// *b++='\r';
// *b = '\n';
*b++='\n'; // Replace space.
p = b + 1;
// p=b+2;
b=NULL;
lines++;
count=0;
}
}
}
if (strncmp(buf, ".\r\n", 3))
q = xstrcpy(strkconv(buf, outcode, incode));
else
q = xstrcpy((char *)" .\n");
Send(newsmode, q);
free(q);
}
}
Syslog('m', "End sending message body");
if ((modtype==1) && (!hdr((char *)"Approved",msg)) &&
(!hdr((char *)"RFC-Approved",kmsg)) && (!hdr((char *)"Approved",kmsg)))
newsmode = FALSE;
tidyrfc(msg);
fclose(fp);
tidyrfc(kmsg);
if (!newsmode) {
result = postemail(nfp, MailFrom, MailTo);
fclose(nfp);
} else {
news_in++;
/*
* The newsfile stays open and will be closed later after processing
* all echomail.
*/
fprintf(nfp, ".\n");
}
// if (p) Geeft segfault
// free(p);
if (newsgroup)
free(newsgroup);
if (distribution)
free(distribution);
if (moderator)
free(moderator);
rbuf = NULL;
free(temp);
return result;
}