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/message.c
2001-08-17 05:46:24 +00:00

883 lines
26 KiB
C

/*****************************************************************************
*
* File ..................: mbmail/message.c
* Purpose ...............: MBSE BBS Mail Gate
* Last modification date : 02-May-2001
*
*****************************************************************************
* Copyright (C) 1997-2001
*
* 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/records.h"
#include "../lib/common.h"
#include "../lib/clcomm.h"
#include "../lib/dbcfg.h"
#include "../lib/dbuser.h"
/* ### Modified by P.Saratxaga on 7 Aug 1995 ###
* - Newsgroups: line is now gated if there is more than one newsgroup
* - Added support for X-FTN-To and X-FTN-From generated by other gates
* - modified removemime to kludgerise lines if charset != us-ascii
* - creation of ^aACUPDATE kludges from Supersedes: and cancel's
* - added charset support (see Changelog for details)
* - added recognition of X-Fsc-
* - added support to dequote MIME quoted printable messages. Code by T.Tanaka
* - added removemsgid and removeinreply
*/
#include "bread.h"
#include "bwrite.h"
#include "hash.h"
#include "mkftnhdr.h"
#include "tracker.h"
#include "viadate.h"
#include "importnet.h"
#define MAXHDRSIZE 2048
#define MAXSEEN 70
#define MAXPATH 73
extern time_t now;
extern char *replyaddr;
extern faddr *bestaka;
extern int pgpsigned;
extern int net_bad;
extern int net_out;
extern char *ftnmsgidstyle;
char *subj;
char *localdomain=NULL;
static int removemime;
static int removeorg;
static int removemsgid;
static int removeref;
static int removeinreply;
static int removesupersedes;
static int removeapproved;
static int removefrom;
static int removereplyto;
static int removereturnto;
static int ftnorigin;
void StatAdd(statcnt *S, unsigned long V)
{
S->total += V;
S->tweek += V;
S->tdow[Diw] += V;
S->month[Miy] += V;
}
int needputrfc(rfcmsg *msg)
{
faddr *ta;
/* 0-junk, 1-kludge, 2-pass */
if (!strcasecmp(msg->key,"X-UUCP-From"))
return 0;
if (!strcasecmp(msg->key,"X-Body-Start"))
return 0;
if (!strncasecmp(msg->key,".",1))
return 0;
if (!strncasecmp(msg->key,"X-FTN-",6))
return 0;
if (!strncasecmp(msg->key,"X-Fsc-",6))
return 0;
if (!strncasecmp(msg->key,"X-ZC-",5))
return 0;
if (!strcasecmp(msg->key,"X-Gateway"))
return 0;
if (!strcasecmp(msg->key,"Path"))
return 0;
if (!strcasecmp(msg->key,"Newsgroups")) {
if ((hdr((char *)"X-Origin-Newsgroups",msg)))
return 0;
else
return 1;
}
if (!strcasecmp(msg->key,"X-Origin-Newsgroups")) {
return 1;
}
if (!strcasecmp(msg->key,"Control")) {
if (CFG.allowcontrol) {
if (strstr(msg->val,"cancel"))
return 1;
else
return 0;
} else
return 0;
}
if (!strcasecmp(msg->key,"Return-Path"))
return 1;
if (!strcasecmp(msg->key,"Xref"))
return 0;
if (!strcasecmp(msg->key,"Approved"))
return removeapproved ?0:2;
if (!strcasecmp(msg->key,"X-URL"))
return 0;
if (!strcasecmp(msg->key,"Return-Receipt-To"))
return removereturnto ?0:1;
if (!strcasecmp(msg->key,"Notice-Requested-Upon-Delivery-To"))
return 0;
if (!strcasecmp(msg->key,"Received")) {
return ftnorigin ?0:1;
}
if (!strcasecmp(msg->key,"From")) {
if ((ta=parsefaddr(msg->val))) {
tidy_faddr(ta);
return 0;
} else
return removefrom ?0:2;
}
if (!strcasecmp(msg->key,"To")) {
if ((ta=parsefaddr(msg->val))) {
tidy_faddr(ta);
return 0;
} else
return 2;
}
if (!strcasecmp(msg->key,"Cc"))
return 2;
if (!strcasecmp(msg->key,"Bcc"))
return 0;
if (!strcasecmp(msg->key,"Reply-To")) {
if ((ta=parsefaddr(msg->val))) {
tidy_faddr(ta);
return 0;
} else
return removereplyto ?0:2;
}
if (!strcasecmp(msg->key,"Lines"))
return 0;
if (!strcasecmp(msg->key,"Date"))
return 0;
if (!strcasecmp(msg->key,"Subject")) {
if ((msg->val) && (strlen(msg->val) > MAXSUBJ))
return 2;
else
return 0;
}
if (!strcasecmp(msg->key,"Organization"))
return removeorg ?0:1;
if (!strcasecmp(msg->key,"Comment-To"))
return 0;
if (!strcasecmp(msg->key,"X-Comment-To"))
return 0;
if (!strcasecmp(msg->key,"X-Apparently-To"))
return 0;
if (!strcasecmp(msg->key,"Apparently-To"))
return 0;
if (!strcasecmp(msg->key,"X-Fidonet-Comment-To"))
return 0;
if (!strcasecmp(msg->key,"Keywords"))
return 2;
if (!strcasecmp(msg->key,"Summary"))
return 2;
if (!strcasecmp(msg->key,"MIME-Version"))
return removemime ?0:1;
if (!strcasecmp(msg->key,"Content-Type"))
return removemime ?0:1;
if (!strcasecmp(msg->key,"Content-Length"))
return removemime ?0:1;
if (!strcasecmp(msg->key,"Content-Transfer-Encoding"))
return removemime ?0:1;
if (!strcasecmp(msg->key,"Content-Name"))
return 2;
if (!strcasecmp(msg->key,"Content-Description"))
return 2;
if (!strcasecmp(msg->key,"Message-ID"))
return removemsgid ?0:1;
if (!strcasecmp(msg->key,"References"))
return removeref ?0:1;
if (!strcasecmp(msg->key,"In-Reply-To"))
return removeinreply ?0:1;
if (!strcasecmp(msg->key,"Supersedes"))
return removesupersedes ?0:1;
if (!strcasecmp(msg->key,"Distribution"))
return 0;
if (!strcasecmp(msg->key,"X-Newsreader"))
return 0;
if (!strcasecmp(msg->key,"X-Mailer"))
return 0;
if (!strcasecmp(msg->key,"User-Agent"))
return 0;
if (!strncasecmp(msg->key,"NNTP-",5))
return 0;
if (!strncasecmp(msg->key,"X-Trace",7))
return 0;
if (!strncasecmp(msg->key,"X-Complaints",12))
return 0;
if (!strncasecmp(msg->key,"X-MSMail",9))
return 0;
if (!strncasecmp(msg->key,"X-MimeOLE",9))
return 0;
if (!strncasecmp(msg->key,"X-MIME-Autoconverted",20))
return 0;
if (!strcasecmp(msg->key,"X-Origin-Date"))
return 0;
if (!strncasecmp(msg->key,"X-PGP-",6))
return 0;
if (!strncasecmp(msg->key,"Resent-",7))
return 0;
if (!strcasecmp(msg->key,"X-Mailing-List"))
return 0;
if (!strcasecmp(msg->key,"X-Loop"))
return 0;
if (!strcasecmp(msg->key,"Precedence"))
return 0;
/*if (!strcasecmp(msg->key,"")) return ;*/
return 1;
}
int putmessage(rfcmsg *msg, ftnmsg *fmsg, FILE *fp, faddr *route, char flavor,fa_list **sbl, int incode, int outcode)
{
char buf[BUFSIZ],*p,*q,newsubj[4 * (MAXSUBJ+1)],*oldsubj;
rfcmsg *tmp;
int rfcheaders, postlocal;
int needsplit,hdrsize,datasize,splitpart,forbidsplit;
int sot_kludge, eot_kludge;
int qp_or_base64; /* 0=plain text, 1=quoted-printable, 2=base64 */
int html_message;
int tinyorigin=0;
fa_list *ptl=NULL;
faddr *ta;
int i;
FILE *pkt;
fidoaddr Dest, Route, *dest;
time_t Now;
Syslog('m', "putmessage from %s",ascfnode(fmsg->from,0x7f));
Syslog('m', "putmessage to %s",ascfnode(fmsg->to,0x7f));
Syslog('m', "putmessage subj %s",MBSE_SS(fmsg->subj));
Syslog('m', "putmessage flags %04x",fmsg->flags);
Syslog('m', "putmessage msgid %s %lx",MBSE_SS(fmsg->msgid_a),fmsg->msgid_n);
Syslog('m', "putmessage reply %s %lx",MBSE_SS(fmsg->reply_a),fmsg->reply_n);
Syslog('m', "putmessage date %s",ftndate(fmsg->date));
removemime = FALSE;
removeorg = FALSE;
removemsgid = FALSE;
removeref = FALSE;
removeinreply = FALSE;
removesupersedes = FALSE;
removeapproved = FALSE;
removefrom = TRUE;
removereplyto = TRUE;
removereturnto = TRUE;
ftnorigin=fmsg->ftnorigin;
sot_kludge = 0;
eot_kludge = 0;
qp_or_base64 = 0;
html_message = 0;
if ((hdr((char *)"X-PGP-Signed",msg)))
pgpsigned = TRUE;
Syslog('m', "pgpsigned = %s", pgpsigned ? "True":"False");
q = hdr((char *)"Content-Transfer-Encoding",msg);
if (q)
while (*q && isspace(*q))
q++;
if (!(q))
q = (char *)"8bit";
if ((p = hdr((char *)"Content-Type",msg))) {
while (*p && isspace(*p))
p++;
/*
* turn the quoted-printable decode mode on; remember FTN is virtually 8-bit clean
*/
if ((strncasecmp(p, "text/plain", 10) == 0) && (strncasecmp(q, "quoted-printable", 16) == 0))
qp_or_base64 = 1;
/*
* turn the base64 decode mode on
*/
else if ((strncasecmp(p, "text/plain", 10) == 0) && (strncasecmp(q, "base64", 6) == 0))
qp_or_base64 = 2;
/*
* text/html support from FSC-HTML 001 proposal of Odinn Sorensen (2:236/77)
*/
if (strncasecmp(p, "text/html", 9) == 0)
html_message = TRUE;
for (tmp=msg;tmp;tmp=tmp->next)
if (((strcasecmp(tmp->key,"X-FTN-KLUDGE") == 0) && (strcasecmp(tmp->val,"FSCHTML") == 0)) ||
(strcasecmp(tmp->key,"X-FTN-HTML") == 0))
html_message = FALSE;
if ((readcharset(p) != CHRS_NOTSET ) && ((q == NULL) || (strncasecmp(q,"7bit",4) == 0) ||
((!pgpsigned) && (qp_or_base64==1)) || ((!pgpsigned) && (qp_or_base64==2)) || (strncasecmp(q,"8bit",4) == 0)))
removemime = TRUE; /* no need in MIME headers */
/*
* some old MUA puts "text" instead of "text/plain; charset=..."
*/
else if ((strcasecmp(p,"text\n") == 0))
removemime = TRUE;
}
Syslog('m', "removemime=%s, qp_or_base64 = %d, html_message=%s", removemime ? "True":"False", qp_or_base64,
html_message ? "True":"False");
if ((p = hdr((char *)"Message-ID",msg))) {
if (!removemsgid)
removemsgid = chkftnmsgid(p);
}
Syslog('m', "removemsgid = %s", removemsgid ? "True":"False");
if ((p = hdr((char *)"In-Reply-To",msg))) {
p = xstrcpy(p);
q = strtok(p," \t\n");
if ((q) && (strtok(NULL," \t\n") == NULL))
removeinreply = chkftnmsgid(q);
free(p);
}
Syslog('m', "removeinreply = %s", removeinreply ? "True":"False");
if ((p = hdr((char *)"Reply-To",msg))) {
removereplyto = FALSE;
if ((!removereplyto) && (q = hdr((char *)"From",msg))) {
char *r;
r = xstrcpy(p);
p = r;
while(*p && isspace(*p))
p++;
if (p[strlen(p)-1] == '\n')
p[strlen(p)-1]='\0';
if (strcasestr(q,p))
removereplyto = TRUE;
free(r);
}
}
Syslog('m', "removereplyto = %s", removereplyto ? "True":"False");
if ((p = hdr((char *)"Return-Receipt-To",msg))) {
removereturnto = FALSE;
if ((!removereturnto) && (q=hdr((char *)"From",msg))) {
char *r;
r = xstrcpy(p); p = r;
while(*p && isspace(*p))
p++;
if (p[strlen(p)-1] == '\n')
p[strlen(p)-1]='\0';
if (strcasestr(q,p))
removereturnto = TRUE;
// free(r);
}
}
Syslog('m', "removereturnto = %s", removereturnto ? "True":"False");
p = ascfnode(fmsg->from,0x1f);
i = 79-11-3-strlen(p);
if (ftnorigin && fmsg->origin && (strlen(fmsg->origin) > i)) {
/* This is a kludge... I don't like it too much. But well,
if this is a message of FTN origin, the original origin (:)
line MUST have been short enough to fit in 79 chars...
So we give it a try. Probably it would be better to keep
the information about the address format from the origin
line in a special X-FTN-... header, but this seems even
less elegant. Any _good_ ideas, anyone? */
/* OK, I am keeping this, though if should never be used
al long as X-FTN-Origin is used now */
p = ascfnode(fmsg->from,0x0f);
i = 79-11-3-strlen(p);
tinyorigin = TRUE;
}
Syslog('m', "tinyorigin = %s", tinyorigin ? "True":"False");
if ((fmsg->origin) && (strlen(fmsg->origin) > i))
fmsg->origin[i]='\0';
forbidsplit=(ftnorigin || (hdr((char *)"X-FTN-Split",msg)));
needsplit = 0;
splitpart = 0;
hdrsize = 20;
hdrsize += (fmsg->subj)?strlen(fmsg->subj):0;
if (fmsg->from)
hdrsize += (fmsg->from->name)?strlen(fmsg->from->name):0;
if (fmsg->to)
hdrsize += (fmsg->to->name)?strlen(fmsg->to->name):0;
do {
Syslog('m', "split loop, splitpart = %d", splitpart);
datasize=0;
if (splitpart) {
sprintf(newsubj,"[part %d] ",splitpart+1);
strncat(newsubj,fmsg->subj,MAXSUBJ-strlen(newsubj));
} else {
strncpy(newsubj,fmsg->subj,MAXSUBJ);
}
strcpy(newsubj, hdrnconv(newsubj, incode, outcode, MAXSUBJ));
newsubj[MAXSUBJ]='\0';
if (splitpart) {
hash_update_n(&fmsg->msgid_n,splitpart);
}
oldsubj=fmsg->subj;
fmsg->subj=newsubj;
/*
* We got the routing address from the mailer which was given by our Host's sendmail.
* This is probably our address so we need to get the address for the next hop.
*/
dest = faddr2fido(fmsg->to);
memcpy(&Dest, dest, sizeof(fidoaddr));
free(dest);
if (TrackMail(Dest, &Route) == R_LOCAL) {
/*
* Mail for our local system. Instead of adding the message to a .pkt create
* a temporary file which later will be send via the importnet function.
*/
postlocal = TRUE;
pkt = tmpfile();
} else {
/*
* New outbound route.
*/
route = fido2faddr(Route);
postlocal = FALSE;
if ((pkt = ftnmsghdr(fmsg, NULL, route, flavor, (char *)"MBSE-FIDO")) == NULL) {
return 1;
}
}
fmsg->subj=oldsubj;
Syslog('m', "replyaddr=%s removereplyto=%s removefrom=%s",
printable(replyaddr, 0), removereplyto?"True":"False", removefrom?"True":"False");
/*
* Add FTN MSGID: and REPLY: if needed.
*/
Now = time(NULL) - (gmt_offset((time_t)0) * 60);
if (postlocal) {
fprintf(pkt, "\001MSGID: %s %08lx\n", MBSE_SS(fmsg->msgid_a),fmsg->msgid_n);
if (fmsg->reply_s)
fprintf(pkt, "\1REPLY: %s\n", fmsg->reply_s);
else if (fmsg->reply_a)
fprintf(pkt, "\1REPLY: %s %08lx\n", fmsg->reply_a, fmsg->reply_n);
fprintf(pkt, "\001TZUTC: %s\n", gmtoffset(Now));
} else {
fprintf(pkt, "\001MSGID: %s %08lx\r", MBSE_SS(fmsg->msgid_a),fmsg->msgid_n);
if (fmsg->reply_s)
fprintf(pkt, "\1REPLY: %s\r", fmsg->reply_s);
else if (fmsg->reply_a)
fprintf(pkt, "\1REPLY: %s %08lx\r", fmsg->reply_a, fmsg->reply_n);
fprintf(pkt, "\001TZUTC: %s\r", gmtoffset(Now));
}
if ((p=hdr((char *)"X-FTN-REPLYADDR",msg))) {
hdrsize += 10+strlen(p);
fprintf(pkt,"\1REPLYADDR:");
kwrite(p,pkt,postlocal);
} else if ((replyaddr) && ((!removereplyto) || (!removefrom))) {
hdrsize += 10+strlen(replyaddr);
fprintf(pkt,"\1REPLYADDR: ");
kwrite(replyaddr,pkt,postlocal);
}
if ((p=hdr((char *)"X-FTN-REPLYTO",msg))) {
hdrsize += 8+strlen(p);
fprintf(pkt,"\1REPLYTO:");
kwrite(p,pkt,postlocal);
} else if ((replyaddr) && ((!removereplyto) || (!removefrom))) {
hdrsize += 15;
if (postlocal)
fprintf(pkt,"\1REPLYTO: %s UUCP\n", ascfnode(bestaka,0x1f));
else
fprintf(pkt,"\1REPLYTO: %s UUCP\r", ascfnode(bestaka,0x1f));
} else if ((p=hdr((char *)"Reply-To",msg))) {
if ((ta=parsefaddr(p))) {
if ((q=hdr((char *)"From",msg))) {
if (!strcasestr(q,p)) {
if (postlocal)
fprintf(pkt,"\1REPLYTO: %s %s\n", ascfnode(ta,0x1f), ta->name);
else
fprintf(pkt,"\1REPLYTO: %s %s\r", ascfnode(ta,0x1f), ta->name);
}
tidy_faddr(ta);
}
}
/* Added 15-Apr-2001 MB. Add UUCP reply info if there is nothing. */
} else if ((p=hdr((char *)"X-UUCP-From",msg)) && (q=hdr((char *)"From",msg))) {
hdrsize += 15;
Striplf(q);
if (postlocal) {
fprintf(pkt,"\1REPLYADDR: %s\n", q);
fprintf(pkt,"\1REPLYTO: %s UUCP\n", ascfnode(bestaka,0x1f));
} else {
fprintf(pkt,"\1REPLYADDR: %s\r", q);
fprintf(pkt,"\1REPLYTO: %s UUCP\r", ascfnode(bestaka,0x1f));
}
}
if ((p=strip_flags(hdr((char *)"X-FTN-FLAGS",msg)))) {
hdrsize += 15;
if (postlocal)
fprintf(pkt,"\1FLAGS:%s\n",p);
else
fprintf(pkt,"\1FLAGS:%s\r",p);
free(p);
}
if (!hdr((char *)"X-FTN-PID", msg)) {
p = hdr((char *)"User-Agent", msg);
if (p == NULL)
p = hdr((char *)"X-Newsreader", msg);
if (p == NULL)
p = hdr((char *)"X-Mailer", msg);
if (p) {
hdrsize += 4 + strlen(p);
fprintf(pkt, "\1PID:");
kwrite(p, pkt, postlocal);
} else {
if (postlocal)
fprintf(pkt, "\001PID: MBSE-MAIL %s\n", VERSION);
else
fprintf(pkt, "\001PID: MBSE-MAIL %s\r", VERSION);
}
}
hdrsize += 15;
if (postlocal)
writechrs(outcode,pkt,3);
else
writechrs(outcode,pkt,1);
if (html_message) {
hdrsize += 9;
if (postlocal)
fprintf(pkt, "\1HTML: 5\n");
else
fprintf(pkt, "\1HTML: 5\r");
}
#ifdef FSC_0070
/* FSC-0070 */
if ((p = hdr((char *)"Message-ID", msg)) && !(hdr((char *)"X-FTN-RFCID", msg))) {
q = strdup(p);
fprintf(pkt,"\1RFCID:");
if ((l = strrchr(q, '<')) && (r = strchr(q, '>')) && (l < r)) {
*l++ = ' ';
while(*l && isspace(*l))
l++;
l--; /* leading ' ' */
*r-- = '\0';
while(*r && isspace(*r))
*r-- = '\0';
} else
l = q;
kwrite(l, pkt, postlocal);
hdrsize += 6 + strlen(l);
free(q);
}
#endif /* FSC_0070 */
if (!(hdr((char *)"X-FTN-Tearline", msg)) && !(hdr((char *)"X-FTN-TID", msg))) {
sprintf(buf, " mbmail %s", VERSION);
hdrsize += 4 + strlen(buf);
fprintf(pkt, "\1TID:");
kwrite(buf, pkt, postlocal);
}
if ((splitpart == 0) || (hdrsize < MAXHDRSIZE)) {
for (tmp=msg;tmp;tmp=tmp->next)
if ((!strncmp(tmp->key,"X-Fsc-",6)) ||
(!strncmp(tmp->key,"X-FTN-",6) &&
strcasecmp(tmp->key,"X-FTN-Tearline") &&
strcasecmp(tmp->key,"X-FTN-Origin") &&
strcasecmp(tmp->key,"X-FTN-Sender") &&
strcasecmp(tmp->key,"X-FTN-Split") &&
strcasecmp(tmp->key,"X-FTN-FLAGS") &&
strcasecmp(tmp->key,"X-FTN-AREA") &&
strcasecmp(tmp->key,"X-FTN-MSGID") &&
strcasecmp(tmp->key,"X-FTN-REPLY") &&
strcasecmp(tmp->key,"X-FTN-SEEN-BY") &&
strcasecmp(tmp->key,"X-FTN-PATH") &&
strcasecmp(tmp->key,"X-FTN-REPLYADDR") &&
strcasecmp(tmp->key,"X-FTN-REPLYTO") &&
strcasecmp(tmp->key,"X-FTN-To") &&
strcasecmp(tmp->key,"X-FTN-From") &&
strcasecmp(tmp->key,"X-FTN-CHARSET") &&
strcasecmp(tmp->key,"X-FTN-CHRS") &&
strcasecmp(tmp->key,"X-FTN-CODEPAGE") &&
strcasecmp(tmp->key,"X-FTN-ORIGCHRS") &&
strcasecmp(tmp->key,"X-FTN-SOT") &&
strcasecmp(tmp->key,"X-FTN-EOT") &&
strcasecmp(tmp->key,"X-FTN-Via"))) {
if (strcasecmp(tmp->key,"X-FTN-KLUDGE") == 0) {
if (!strcasecmp(tmp->val," SOT:\n"))
sot_kludge = 1;
else if (!strcasecmp(tmp->val," EOT:\n"))
eot_kludge = 1;
else {
hdrsize += strlen(tmp->val);
fprintf(pkt,"\1");
/* we should have restored the original string here... */
kwrite((tmp->val)+1, pkt, postlocal);
}
} else {
hdrsize += strlen(tmp->key)+strlen(tmp->val);
fprintf(pkt,"\1%s:",tmp->key+6);
kwrite(tmp->val, pkt, postlocal);
}
}
/* ZConnect are X-ZC-*: in usenet, \1ZC-*: in FTN */
for (tmp=msg;tmp;tmp=tmp->next)
if ((!strncmp(tmp->key,"X-ZC-",5))) {
hdrsize += strlen(tmp->key)+strlen(tmp->val);
fprintf(pkt, "\1%s:", tmp->key+2);
kwrite(tmp->val, pkt, postlocal);
}
/* mondo.org gateway uses ".MSGID: ..." in usenet */
for (tmp=msg;tmp;tmp=tmp->next)
if ((!strncmp(tmp->key,".",1)) && (strcasecmp(tmp->key,".MSGID"))) {
hdrsize += strlen(tmp->key)+strlen(tmp->val);
fprintf(pkt,"\1%s:",tmp->key+1);
kwrite(tmp->val, pkt, postlocal);
}
rfcheaders = 0;
for (tmp=msg;tmp;tmp=tmp->next)
if ((needputrfc(tmp) == 1)) {
if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) {
hdrsize += 10+strlen(tmp->val);
fprintf(pkt,"\1RFC-Newsgroups:");
} else {
hdrsize += strlen(tmp->key)+strlen(tmp->val);
fprintf(pkt,"\1RFC-%s:",tmp->key);
}
kwrite(hdrconv(tmp->val, incode, outcode),pkt, postlocal);
}
for (tmp=msg;tmp;tmp=tmp->next)
if ((needputrfc(tmp) > 1)) {
rfcheaders++;
if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) {
hdrsize += 10+strlen(tmp->val);
fprintf(pkt,"Newsgroups:");
} else {
hdrsize += strlen(tmp->key)+strlen(tmp->val);
fprintf(pkt,"%s:",tmp->key);
}
cwrite(hdrconv(tmp->val, incode, outcode),pkt,postlocal);
}
if (rfcheaders)
cwrite((char *)"\n",pkt, postlocal);
if ((hdr((char *)"X-FTN-SOT",msg)) || (sot_kludge)) {
if (postlocal)
fprintf(pkt,"\1SOT:\n");
else
fprintf(pkt,"\1SOT:\r");
}
if ((splitpart == 0) && (hdr((char *)"X-PGP-Signed",msg))) {
if (postlocal)
fprintf(pkt,PGP_SIGNED_BEGIN"\n");
else
fprintf(pkt,PGP_SIGNED_BEGIN"\r");
}
}
if (replyaddr) {
// free(replyaddr); /* Gives SIGSEGV */
replyaddr=NULL;
}
if (needsplit) {
if (postlocal)
fprintf(pkt," * Continuation %d of a split message *\n\n", splitpart);
else
fprintf(pkt," * Continuation %d of a split message *\r\r", splitpart);
needsplit=0;
} else if ((p=hdr((char *)"X-Body-Start",msg))) {
datasize += strlen(p);
if (qp_or_base64==1)
cwrite(strkconv(qp_decode(p), incode, outcode), pkt, postlocal);
else if (qp_or_base64==2)
cwrite(strkconv(b64_decode(p), incode, outcode), pkt, postlocal);
else
cwrite(strkconv(p, incode, outcode), pkt, postlocal);
}
while (!(needsplit=(!forbidsplit) && (((splitpart && (datasize > (CFG.new_split * 1024))) ||
(!splitpart && ((datasize+hdrsize) > (CFG.new_split * 1024)))))) && (bgets(buf,sizeof(buf)-1,fp))) {
// Syslog('m', "putmessage body %s",buf);
datasize += strlen(buf);
if (qp_or_base64==1)
cwrite(strkconv(qp_decode(buf), incode, outcode), pkt, postlocal);
else if (qp_or_base64==2)
cwrite(strkconv(b64_decode(buf), incode, outcode), pkt, postlocal);
else
cwrite(strkconv(buf, incode, outcode), pkt, postlocal);
}
if (needsplit) {
if (postlocal)
fprintf(pkt,"\n * Message split, to be continued *\n");
else
fprintf(pkt,"\r * Message split, to be continued *\r");
splitpart++;
} else if ((p=hdr((char *)"X-PGP-Signed",msg))) {
if (postlocal)
fprintf(pkt,PGP_SIG_BEGIN"\n");
else
fprintf(pkt,PGP_SIG_BEGIN"\r");
if ((q=hdr((char *)"X-PGP-Version",msg))) {
fprintf(pkt,"Version:");
cwrite(q,pkt, postlocal);
}
if ((q=hdr((char *)"X-PGP-Charset",msg))) {
fprintf(pkt,"Charset:");
cwrite(q,pkt, postlocal);
}
if ((q=hdr((char *)"X-PGP-Comment",msg))) {
fprintf(pkt,"Comment:");
cwrite(q,pkt, postlocal);
}
if (postlocal)
fprintf(pkt,"\n");
else
fprintf(pkt,"\r");
p=xstrcpy(p);
q=strtok(p," \t\n");
if (postlocal)
fprintf(pkt,"%s\n",q);
else
fprintf(pkt,"%s\r",q);
while ((q=(strtok(NULL," \t\n")))) {
if (postlocal)
fprintf(pkt,"%s\n",q);
else
fprintf(pkt,"%s\r",q);
}
if (postlocal)
fprintf(pkt,PGP_SIG_END"\n");
else
fprintf(pkt,PGP_SIG_END"\r");
}
if ((p=hdr((char *)"X-FTN-EOT",msg)) || (eot_kludge)) {
if (postlocal)
fprintf(pkt,"\1EOT:\n");
else
fprintf(pkt,"\1EOT:\r");
}
if ((p=hdr((char *)"X-FTN-Tearline",msg))) {
fprintf(pkt,"---");
if (strcasecmp(p," (none)\n") == 0)
cwrite((char *)"\n",pkt,postlocal);
else
cwrite(p,pkt,postlocal);
} else {
if (postlocal)
fprintf(pkt,"--- MBSE BBSv.%s\n",VERSION);
else
fprintf(pkt,"--- MBSE BBSv.%s\r",VERSION);
}
if ((p=hdr((char *)"X-FTN-Origin",msg))) {
if (*(q=p+strlen(p)-1) == '\n')
*q='\0';
fprintf(pkt," * Origin:");
cwrite(hdrconv(p, incode, outcode),pkt, postlocal);
if (postlocal)
fprintf(pkt, "\n");
else
fprintf(pkt,"\r");
} else {
fprintf(pkt," * Origin: ");
if (fmsg->origin)
cwrite(hdrconv(fmsg->origin, incode, outcode), pkt, postlocal);
else
fprintf(pkt, "%s", CFG.origin);
if (postlocal)
fprintf(pkt, " (%s)\n", ascfnode(fmsg->from,tinyorigin?0x0f:0x1f));
else
fprintf(pkt, " (%s)\r", ascfnode(fmsg->from,tinyorigin?0x0f:0x1f));
}
for (tmp = msg; tmp; tmp = tmp->next)
if (!strcasecmp(tmp->key,"X-FTN-Via")) {
datasize += strlen(tmp->key)+strlen(tmp->val);
fprintf(pkt,"\1Via");
kwrite(tmp->val,pkt, postlocal);
}
/*
* @Via mbmail 2:293/2219@fidonet, Wed Jan 3 1996 at 07:49 (2.8c)
*/
if (postlocal)
fprintf(pkt,"\1Via mbmail %s, %s (%s)\n", ascfnode(bestaka,0x1f), viadate(),VERSION);
else
fprintf(pkt,"\1Via mbmail %s, %s (%s)\r", ascfnode(bestaka,0x1f), viadate(),VERSION);
if (postlocal) {
subj = xstrcpy(fmsg->subj);
/*
* Check userlist real names, handles, unix names.
* Import if one fits.
*/
if (!SearchUser(fmsg->to->name)) {
Syslog('+', " \"%s\" is not a known BBS user", fmsg->to->name);
/*
* Unknown, readdress it to the sysop.
*/
net_bad++;
Syslog('+', " Readdress from %s to %s", fmsg->to->name, CFG.sysop_name);
fmsg->to->name = xstrcpy(CFG.sysop_name);
}
if (SearchUser(fmsg->to->name)) {
Syslog('m', "importnet(%s, %s, %s, %04x)", ascfnode(fmsg->from,0x7f),
ascfnode(fmsg->to,0x7f), ftndate(fmsg->date), fmsg->flags);
if (importnet(fmsg->from, fmsg->to, fmsg->date, fmsg->flags, pkt))
return 2;
} else {
WriteError("Unknown bbs user");
return 2;
}
} else {
awrite((char *)"",pkt); /* trailing zero byte */
if (ferror(pkt)) {
WriteError("$error writing to ftn packet");
return 1;
}
net_out++;
}
tidy_falist(&ptl);
}
while (needsplit);
Syslog('m', "putmessage exiting...");
return 0;
}