/*****************************************************************************
 *
 * $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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *****************************************************************************/

#include "../config.h"
#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 "msgflags.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             waskludge = FALSE, badkludge;
	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], 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;
	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,"---",3)) && (buf[3] != '-')) {
				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", p);
			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", p);
				Send(newsmode, temp);
			} else if ((t) && (t->name) && (strcasecmp(t->name,"All"))) {
				sprintf(temp,"X-Comment-To: %s\n", t->name);
				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", p);
		Send(newsmode, temp);
	} else if ((p = hdr((char *)"RFC-From",kmsg))) {
		Syslog('m', "b");
		sprintf(temp, "From: %s", p);
		Send(newsmode, temp);
	} else if ((p = hdr((char *)"From\n",kmsg))) {
		Syslog('m', "c");
		sprintf(temp, "From: %s", p);
		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", f->name, 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", l, p);
			Send(newsmode, temp);
			free(q);
		} else if (f->name) {
			Syslog('m', "e");
			sprintf(temp,"From: \"%s\" <%s>\n", f->name, 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", ascinode(f,0xff));
	else 
		sprintf(temp,"From: %s\n", ascinode(f,0xff));
	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))) {
		ta = parsefaddr(p);
		sprintf(temp,"Reply-To: %s\n",ascinode(ta, 0xff));
		tidy_faddr(ta);
		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", p);
	else if ((p = hdr((char *)"RFC-Subject",kmsg))) 
		sprintf(temp, "Subject: %s", p);
	else if ((p = hdr((char *)"Subject",kmsg))) 
		sprintf(temp, "Subject: %s", p);
	else if ((p = hdr((char *)"X-PcBoard-SUBJECT",msg))) 
		sprintf(temp, "Subject:%s", p);
	else if (subj && (strspn(subj," \t\n\r") != strlen(subj)))
		sprintf(temp, "Subject: %s\n", subj);
	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",p);
		Send(newsmode, temp);
	} else if ((p=hdr((char *)"Organisation",msg))) {
		sprintf(temp,"Organization:%s",p);
		Send(newsmode, temp);
	} else if ((p=hdr((char *)"RFC-Organization",kmsg))) {
		sprintf(temp,"Organization: %s",p);
		Send(newsmode, temp);
	} else if ((p=hdr((char *)"RFC-Organisation",kmsg))) {
		sprintf(temp,"Organization: %s",p);
		Send(newsmode, temp);
	} else if ((p=hdr((char *)"Organization",kmsg))) {
		sprintf(temp,"Organization: %s",p);
		Send(newsmode, temp);
	} else if ((p=hdr((char *)"Organisation",kmsg))) {
		sprintf(temp,"Organization: %s",p);
		Send(newsmode, temp);
	} else if (origline) {
		sprintf(temp,"Organization: %s\n",origline);
		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,qmsg->val);
			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,qmsg->val);
				Send(newsmode, temp);
			} else if ((!strncasecmp(qmsg->key,"X-",2)) || (!strncasecmp(qmsg->key,"NNTP-",5))) {
				sprintf(temp,"%s: %s",qmsg->key,qmsg->val);
				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,qmsg->val);
				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(p);
				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(buf);
			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;
}