Structure changes in mbfido
This commit is contained in:
parent
60786db623
commit
004b2e6410
1499
mbfido/ftn2rfc.c
Normal file
1499
mbfido/ftn2rfc.c
Normal file
File diff suppressed because it is too large
Load Diff
8
mbfido/ftn2rfc.h
Normal file
8
mbfido/ftn2rfc.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _FTN2RFC_H
|
||||
#define _FTN2RFC_H
|
||||
|
||||
|
||||
int ftn2rfc(faddr *, faddr *, char *, char *, time_t, int, FILE *);
|
||||
|
||||
#endif
|
||||
|
584
mbfido/postecho.c
Normal file
584
mbfido/postecho.c
Normal file
@ -0,0 +1,584 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbfido/postecho.c
|
||||
* Purpose ...............: Post echomail message.
|
||||
* Last modification date : 25-Aug-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/msg.h"
|
||||
#include "../lib/msgtext.h"
|
||||
#include "../lib/dbcfg.h"
|
||||
#include "../lib/dbnode.h"
|
||||
#include "../lib/dbmsgs.h"
|
||||
#include "../lib/dbdupe.h"
|
||||
#include "../lib/dbuser.h"
|
||||
#include "../lib/dbftn.h"
|
||||
#include "ftn2rfc.h"
|
||||
#include "postecho.h"
|
||||
#include "storeecho.h"
|
||||
#include "addpkt.h"
|
||||
#include "rollover.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* External declarations
|
||||
*/
|
||||
extern int do_quiet; /* No tty output */
|
||||
extern int do_unsec; /* Toss unsecure */
|
||||
extern int check_dupe; /* Check dupes */
|
||||
extern time_t t_start; /* Reference time */
|
||||
extern int most_debug; /* Heavy debugging */
|
||||
extern int echo_in; /* Echomail processed */
|
||||
extern int echo_out; /* Echomail forwarded */
|
||||
extern int echo_bad; /* Bad echomail */
|
||||
|
||||
|
||||
#define MAXPATH 73
|
||||
#define MAXSEEN 70
|
||||
|
||||
|
||||
void tidy_qualify(qualify **);
|
||||
void fill_qualify(qualify **, fidoaddr, int, int);
|
||||
void dlog_qualify(qualify **, char *);
|
||||
int EchoOut(fidoaddr, char *, char *, char *, FILE *, int, int, time_t);
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Add echomail mesage to the queue.
|
||||
*/
|
||||
int EchoOut(fidoaddr aka, char *toname, char *fromname, char *subj, FILE *fp, int flags, int cost, time_t date)
|
||||
{
|
||||
char *buf;
|
||||
FILE *qp;
|
||||
faddr *From, *To;
|
||||
int rc;
|
||||
|
||||
if ((qp = OpenPkt(msgs.Aka, aka, (char *)"qqq")) == NULL) {
|
||||
WriteError("EchoOut(): OpenPkt failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
From = fido2faddr(msgs.Aka);
|
||||
To = fido2faddr(aka);
|
||||
rc = AddMsgHdr(qp, From, To, flags, cost, date, toname, fromname, subj);
|
||||
tidy_faddr(To);
|
||||
tidy_faddr(From);
|
||||
if (rc) {
|
||||
WriteError("EchoOut(): AddMsgHdr failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
rewind(fp);
|
||||
buf = calloc(2048, sizeof(char));
|
||||
|
||||
while ((fgets(buf, 2048, fp)) != NULL) {
|
||||
Striplf(buf);
|
||||
fprintf(qp, "%s\r", buf);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
putc(0, qp);
|
||||
fsync(fileno(qp));
|
||||
fclose(qp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void tidy_qualify(qualify **qal)
|
||||
{
|
||||
qualify *tmp, *old;
|
||||
|
||||
for (tmp = *qal; tmp; tmp = old) {
|
||||
old = tmp->next;
|
||||
free(tmp);
|
||||
}
|
||||
*qal = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fill_qualify(qualify **qal, fidoaddr aka, int orig, int insb)
|
||||
{
|
||||
qualify *tmp;
|
||||
|
||||
tmp = (qualify *)malloc(sizeof(qualify));
|
||||
tmp->next = *qal;
|
||||
tmp->aka = aka;
|
||||
tmp->inseenby = insb;
|
||||
tmp->send = ((!insb) && (!orig));
|
||||
tmp->orig = orig;
|
||||
*qal = tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void dlog_qualify(qualify **qal, char *msg)
|
||||
{
|
||||
qualify *tmpl;
|
||||
|
||||
for (tmpl = *qal; tmpl; tmpl = tmpl->next) {
|
||||
Syslog('m', "%s InSB=%s Snd=%s Org=%s",
|
||||
aka2str(tmpl->aka), tmpl->inseenby ? "True":"False",
|
||||
tmpl->send ? "True":"False",
|
||||
tmpl->orig ? "True":"False");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Post echomail message, forward if needed.
|
||||
* pkt_from, from, to, subj, orig, mdate, flags, cost, file
|
||||
* The msgs record must be in memory.
|
||||
*
|
||||
* 1 - Cannot open message base.
|
||||
* 4 - Rejected echomail message.
|
||||
*
|
||||
* For echomail, the crc32 is calculated over the ^AREA kludge, subject,
|
||||
* message date, origin line, message id.
|
||||
*/
|
||||
int postecho(faddr *p_from, faddr *f, faddr *t, char *orig, char *subj,
|
||||
time_t mdate, int flags, int cost, FILE *fp, int tonews)
|
||||
{
|
||||
char *buf, *msgid = NULL, *reply = NULL, *p, *q, sbe[16];
|
||||
int First = TRUE, rc = 0, i, kludges = TRUE;
|
||||
int dupe = FALSE, bad = TRUE, seenlen, oldnet;
|
||||
faddr *Faddr;
|
||||
unsigned long crc;
|
||||
sysconnect Link;
|
||||
fa_list *sbl = NULL, *ptl = NULL, *tmpl;
|
||||
qualify *qal = NULL, *tmpq;
|
||||
FILE *nfp, *qp;
|
||||
|
||||
Syslog('M', "Entering postecho, area %s %s", msgs.Tag, msgs.Name);
|
||||
Syslog('M', "p_from: %s", ascfnode(p_from, 0xff));
|
||||
Syslog('M', "from : %s", ascfnode(f, 0xff));
|
||||
Syslog('M', "to : %s", ascfnode(t, 0xff));
|
||||
Syslog('M', "subj : %s", printable(subj, 0));
|
||||
Syslog('M', "origin: %s", orig);
|
||||
Syslog('M', "date : %s", rfcdate(mdate));
|
||||
Syslog('M', "flags : %08x", flags);
|
||||
Syslog('M', "cost : %d", cost);
|
||||
Syslog('M', "tonews: %s", tonews ? "True":"False");
|
||||
|
||||
memset(&Link, 0, sizeof(Link));
|
||||
crc = 0xffffffff;
|
||||
echo_in++;
|
||||
|
||||
/*
|
||||
* p_from is set for tossed echomail, it is NULL for local posted echomail and gated news.
|
||||
*/
|
||||
if (p_from) {
|
||||
while (GetMsgSystem(&Link, First)) {
|
||||
First = FALSE;
|
||||
if ((p_from->zone == Link.aka.zone) && (p_from->net == Link.aka.net) && (p_from->node == Link.aka.node)) {
|
||||
bad = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bad && (msgs.UnSecure || do_unsec)) {
|
||||
bad = FALSE;
|
||||
memset(&Link, 0, sizeof(Link));
|
||||
}
|
||||
if (bad) {
|
||||
Syslog('+', "Node %s not connected to area %s", ascfnode(p_from, 0x1f), msgs.Tag);
|
||||
echo_bad++;
|
||||
return 4;
|
||||
}
|
||||
if (Link.cutoff && !bad) {
|
||||
Syslog('+', "Echomail from %s in %s refused, cutoff", ascfnode(p_from, 0x1f), msgs.Tag);
|
||||
bad = TRUE;
|
||||
echo_bad++;
|
||||
return 4;
|
||||
}
|
||||
if (!Link.receivefrom && !bad) {
|
||||
Syslog('+', "Echomail from %s in %s refused, read only", ascfnode(p_from, 0x1f), msgs.Tag);
|
||||
bad = TRUE;
|
||||
echo_bad++;
|
||||
return 4;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Fake the zone entry to be our own zone, this prevents
|
||||
* zonegate behaviour. It's also not a bad message yet.
|
||||
*/
|
||||
Link.aka.zone = msgs.Aka.zone;
|
||||
bad = FALSE;
|
||||
}
|
||||
|
||||
if (CFG.toss_old && ((t_start - mdate) / 86400) > CFG.toss_old) {
|
||||
Syslog('+', "Rejecting msg: too old, %s", rfcdate(mdate));
|
||||
bad = TRUE;
|
||||
echo_bad++;
|
||||
return 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the message for kludges we need.
|
||||
*/
|
||||
buf = calloc(2048, sizeof(char));
|
||||
First = TRUE;
|
||||
rewind(fp);
|
||||
while ((fgets(buf, 2048, fp)) != NULL) {
|
||||
|
||||
Striplf(buf);
|
||||
Syslogp('M', printable(buf, 0));
|
||||
|
||||
if (First && (!strncmp(buf, "AREA:", 5))) {
|
||||
crc = upd_crc32(buf, crc, strlen(buf));
|
||||
First = FALSE;
|
||||
}
|
||||
if (!strncmp(buf, "\001MSGID: ", 8))
|
||||
msgid = xstrcpy(buf + 8);
|
||||
if (!strncmp(buf, "\001REPLY: ", 8))
|
||||
reply = xstrcpy(buf + 8);
|
||||
if (!strncmp(buf, "SEEN-BY:", 8)) {
|
||||
if (Link.aka.zone == msgs.Aka.zone) {
|
||||
p = xstrcpy(buf + 9);
|
||||
fill_list(&sbl, p, NULL);
|
||||
free(p);
|
||||
} else
|
||||
Syslog('m', "Strip zone SB lines");
|
||||
}
|
||||
if (!strncmp(buf, "\001PATH:", 6)) {
|
||||
p = xstrcpy(buf + 7);
|
||||
fill_path(&ptl, p);
|
||||
free(p);
|
||||
}
|
||||
} /* end of checking kludges */
|
||||
|
||||
|
||||
/*
|
||||
* Further dupe checking.
|
||||
*/
|
||||
crc = upd_crc32(subj, crc, strlen(subj));
|
||||
if (orig == NULL)
|
||||
Syslog('!', "No origin line found");
|
||||
else
|
||||
crc = upd_crc32(orig, crc, strlen(orig));
|
||||
crc = upd_crc32((char *)&mdate, crc, sizeof(mdate));
|
||||
if (msgid != NULL) {
|
||||
crc = upd_crc32(msgid, crc, strlen(msgid));
|
||||
} else {
|
||||
if (check_dupe) {
|
||||
/*
|
||||
* If a MSGID is missing it is possible that dupes from some offline
|
||||
* readers slip through because these readers use the same date for
|
||||
* each message. In this case the message text is included in the
|
||||
* dupecheck. Redy Rodriguez.
|
||||
*/
|
||||
rewind(fp);
|
||||
while ((fgets(buf, 2048, fp)) != NULL) {
|
||||
Striplf(buf);
|
||||
if (strncmp(buf, "---", 3) == 0)
|
||||
break;
|
||||
if ((strncmp(buf, "\001", 1) != 0 ) && (strncmp(buf,"AREA:",5) != 0 ))
|
||||
crc = upd_crc32(buf, crc , strlen(buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (check_dupe)
|
||||
dupe = CheckDupe(crc, D_ECHOMAIL, CFG.toss_dupes);
|
||||
else
|
||||
dupe = FALSE;
|
||||
|
||||
|
||||
if (!dupe && !msgs.UnSecure && !do_unsec) {
|
||||
/*
|
||||
* Check if the message is for us. Don't check point address,
|
||||
* echomail messages don't have point destination set.
|
||||
*/
|
||||
if ((msgs.Aka.zone != t->zone) || (msgs.Aka.net != t->net) || (msgs.Aka.node != t->node)) {
|
||||
bad = TRUE;
|
||||
/*
|
||||
* If we are a hub or host and have all our echomail
|
||||
* connected to the hub/host aka, echomail from points
|
||||
* under a nodenumber aka isn't accepted. The match
|
||||
* must be further tested.
|
||||
*/
|
||||
if ((msgs.Aka.zone == t->zone) && (msgs.Aka.net == t->net)) {
|
||||
for (i = 0; i < 40; i++) {
|
||||
if ((CFG.akavalid[i]) &&
|
||||
(CFG.aka[i].zone == t->zone) &&
|
||||
(CFG.aka[i].net == t->net) &&
|
||||
(CFG.aka[i].node == t->node))
|
||||
bad = FALSE; /* Undo the result */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bad) {
|
||||
echo_bad++;
|
||||
WriteError("Msg in %s not for us (%s) but for %s", msgs.Tag, aka2str(msgs.Aka), ascfnode(t,0x1f));
|
||||
free(buf);
|
||||
if (msgid)
|
||||
free(msgid);
|
||||
if (reply)
|
||||
free(reply);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The echomail message is accepted for post/forward/gate
|
||||
*/
|
||||
if (!dupe) {
|
||||
|
||||
if (msgs.Aka.zone != Link.aka.zone) {
|
||||
/*
|
||||
* If it is a zonegated echomailmessage the SEEN-BY lines
|
||||
* are stripped off including that of the other zone's
|
||||
* gate. Add the gate's aka to the SEEN-BY
|
||||
*/
|
||||
Syslog('m', "Gated echomail, clean SB");
|
||||
tidy_falist(&sbl);
|
||||
sprintf(sbe, "%u/%u", Link.aka.net, Link.aka.node);
|
||||
Syslog('m', "Add gate SB %s", sbe);
|
||||
fill_list(&sbl, sbe, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add more aka's to SEENBY if in the same zone as our system.
|
||||
* When ready filter dupe's, there is at least one.
|
||||
*/
|
||||
for (i = 0; i < 40; i++) {
|
||||
if (CFG.akavalid[i] && (msgs.Aka.zone == CFG.aka[i].zone) &&
|
||||
!((msgs.Aka.net == CFG.aka[i].net) && (msgs.Aka.node == CFG.aka[i].node))) {
|
||||
sprintf(sbe, "%u/%u", CFG.aka[i].net, CFG.aka[i].node);
|
||||
fill_list(&sbl, sbe, NULL);
|
||||
}
|
||||
}
|
||||
uniq_list(&sbl);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add our system to the path for later export.
|
||||
*/
|
||||
sprintf(sbe, "%u/%u", msgs.Aka.net, msgs.Aka.node);
|
||||
fill_path(&ptl, sbe);
|
||||
uniq_list(&ptl); /* remove possible duplicate own aka */
|
||||
|
||||
/*
|
||||
* Build a list of qualified systems to receive this message.
|
||||
* Complete the SEEN-BY lines.
|
||||
*/
|
||||
First = TRUE;
|
||||
while (GetMsgSystem(&Link, First)) {
|
||||
First = FALSE;
|
||||
if ((Link.aka.zone) && (Link.sendto) && (!Link.pause) && (!Link.cutoff)) {
|
||||
Faddr = fido2faddr(Link.aka);
|
||||
if (p_from == NULL) {
|
||||
fill_qualify(&qal, Link.aka, FALSE, in_list(Faddr, &sbl, FALSE));
|
||||
} else {
|
||||
fill_qualify(&qal, Link.aka, ((p_from->zone == Link.aka.zone) &&
|
||||
(p_from->net == Link.aka.net) && (p_from->node == Link.aka.node) &&
|
||||
(p_from->point == Link.aka.point)), in_list(Faddr, &sbl, FALSE));
|
||||
}
|
||||
tidy_faddr(Faddr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add SEEN-BY for nodes qualified to receive this message.
|
||||
* When ready, filter the dupes and sort the SEEN-BY entries.
|
||||
*/
|
||||
for (tmpq = qal; tmpq; tmpq = tmpq->next) {
|
||||
if (tmpq->send) {
|
||||
sprintf(sbe, "%u/%u", tmpq->aka.net, tmpq->aka.node);
|
||||
fill_list(&sbl, sbe, NULL);
|
||||
}
|
||||
}
|
||||
uniq_list(&sbl);
|
||||
sort_list(&sbl);
|
||||
|
||||
|
||||
/*
|
||||
* Create a new tmpfile with a copy of the message
|
||||
* without original PATH and SEENBY lines, add the
|
||||
* new PATH and SEENBY lines.
|
||||
*/
|
||||
rewind(fp);
|
||||
if ((nfp = tmpfile()) == NULL)
|
||||
WriteError("$Unable to open tmpfile");
|
||||
while ((fgets(buf, 2048, fp)) != NULL) {
|
||||
Striplf(buf);
|
||||
fprintf(nfp, "%s", buf);
|
||||
/*
|
||||
* Don't write SEEN-BY and PATH lines
|
||||
*/
|
||||
if (strncmp(buf, " * Origin:", 10) == 0)
|
||||
break;
|
||||
fprintf(nfp, "\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Now add new SEEN-BY and PATH lines
|
||||
*/
|
||||
seenlen = MAXSEEN + 1;
|
||||
/*
|
||||
* Ensure that it will not match for the first entry.
|
||||
*/
|
||||
oldnet = sbl->addr->net - 1;
|
||||
for (tmpl = sbl; 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 > MAXSEEN) {
|
||||
seenlen = 0;
|
||||
fprintf(nfp, "\nSEEN-BY:");
|
||||
sprintf(sbe, " %u/%u", tmpl->addr->net, tmpl->addr->node);
|
||||
seenlen = strlen(sbe);
|
||||
}
|
||||
fprintf(nfp, "%s", sbe);
|
||||
}
|
||||
|
||||
seenlen = MAXPATH + 1;
|
||||
/*
|
||||
* Ensure it will not match for the first entry
|
||||
*/
|
||||
oldnet = ptl->addr->net - 1;
|
||||
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;
|
||||
fprintf(nfp, "\n\001PATH:");
|
||||
sprintf(sbe, " %u/%u", tmpl->addr->net, tmpl->addr->node);
|
||||
seenlen = strlen(sbe);
|
||||
}
|
||||
fprintf(nfp, "%s", sbe);
|
||||
}
|
||||
fprintf(nfp, "\n");
|
||||
fflush(nfp);
|
||||
rewind(nfp);
|
||||
|
||||
|
||||
/*
|
||||
* Import this echomail, even if it's bad or a dupe.
|
||||
*/
|
||||
if (storeecho(f, t, mdate, flags, subj, msgid, reply, bad, dupe, nfp) || bad || dupe) {
|
||||
/*
|
||||
* Store failed or it was bad or a dupe.
|
||||
*/
|
||||
WriteError("Store echomail in JAM base failed");
|
||||
tidy_falist(&sbl);
|
||||
tidy_falist(&ptl);
|
||||
tidy_qualify(&qal);
|
||||
free(buf);
|
||||
if (msgid)
|
||||
free(msgid);
|
||||
if (reply)
|
||||
free(reply);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Forward to other links
|
||||
*/
|
||||
for (tmpq = qal; tmpq; tmpq = tmpq->next) {
|
||||
if (tmpq->send) {
|
||||
if (SearchNode(tmpq->aka)) {
|
||||
StatAdd(&nodes.MailSent, 1L);
|
||||
UpdateNode();
|
||||
SearchNode(tmpq->aka);
|
||||
}
|
||||
echo_out++;
|
||||
if (EchoOut(tmpq->aka, t->name, f->name, subj, nfp, flags, cost, mdate))
|
||||
WriteError("Forward echomail to %s failed", aka2str(tmpq->aka));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Gate to newsserver
|
||||
*/
|
||||
if (strlen(msgs.Newsgroup) && tonews) {
|
||||
rewind(nfp);
|
||||
qp = tmpfile();
|
||||
while ((fgets(buf, 2048, nfp)) != NULL) {
|
||||
Striplf(buf);
|
||||
if (kludges && (buf[0] != '\001') && strncmp(buf, "AREA:", 5)) {
|
||||
kludges = FALSE;
|
||||
q = xstrcpy(Msg.From);
|
||||
for (i = 0; i < strlen(q); i++)
|
||||
if (q[i] == ' ')
|
||||
q[i] = '_';
|
||||
fprintf(qp, "From: %s@%s\n", q, ascinode(f, 0x1f));
|
||||
fprintf(qp, "Subject: %s\n", Msg.Subject);
|
||||
fprintf(qp, "To: %s\n", Msg.To);
|
||||
|
||||
// FIXME: hier nog X-...-To: ??
|
||||
|
||||
fprintf(qp, "\n");
|
||||
}
|
||||
fprintf(qp, "%s\n", buf);
|
||||
}
|
||||
rewind(qp);
|
||||
most_debug = TRUE;
|
||||
ftn2rfc(f, t, subj, orig, mdate, flags, qp);
|
||||
most_debug = FALSE;
|
||||
fclose(qp);
|
||||
}
|
||||
fclose(nfp);
|
||||
|
||||
/*
|
||||
* Free memory used by SEEN-BY, ^APATH and Qualified lines.
|
||||
*/
|
||||
tidy_falist(&sbl);
|
||||
tidy_falist(&ptl);
|
||||
tidy_qualify(&qal);
|
||||
|
||||
if (rc < 0)
|
||||
rc =-rc;
|
||||
free(buf);
|
||||
if (msgid)
|
||||
free(msgid);
|
||||
if (reply)
|
||||
free(reply);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
21
mbfido/postecho.h
Normal file
21
mbfido/postecho.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef _POSTECHO_H
|
||||
#define _POSTECHO_H
|
||||
|
||||
|
||||
/*
|
||||
* Structure for qualified systems to receive a echomail message
|
||||
*/
|
||||
typedef struct _qualify {
|
||||
struct _qualify *next; /* Linked list */
|
||||
fidoaddr aka; /* AKA of the linked system */
|
||||
unsigned inseenby : 1; /* System is in SEEN-BY */
|
||||
unsigned send : 1; /* Send message to link */
|
||||
unsigned orig : 1; /* Is originator of message */
|
||||
} qualify;
|
||||
|
||||
|
||||
int postecho(faddr *, faddr *, faddr *, char *, char *, time_t, int, int, FILE *, int);
|
||||
|
||||
|
||||
#endif
|
||||
|
987
mbfido/rfc2ftn.c
Normal file
987
mbfido/rfc2ftn.c
Normal file
@ -0,0 +1,987 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbfido/rfc2ftn.c
|
||||
* Purpose ...............: Convert RFC to FTN
|
||||
* Last modification date : 14-Aug-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/mbinet.h"
|
||||
#include "../lib/dbdupe.h"
|
||||
#include "../lib/dbnode.h"
|
||||
#include "../lib/dbmsgs.h"
|
||||
#include "../lib/msg.h"
|
||||
#include "../lib/msgtext.h"
|
||||
#include "mkftnhdr.h"
|
||||
#include "hash.h"
|
||||
#include "rollover.h"
|
||||
#include "pack.h"
|
||||
#include "postnetmail.h"
|
||||
#include "postecho.h"
|
||||
#include "rfc2ftn.h"
|
||||
|
||||
|
||||
#define MAXHDRSIZE 2048
|
||||
#define MAXSEEN 70
|
||||
#define MAXPATH 73
|
||||
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static int ftnorigin;
|
||||
static int removemime;
|
||||
static int removemsgid;
|
||||
static int removeref;
|
||||
static int removeinreply;
|
||||
static int removesupersedes;
|
||||
static int removeapproved;
|
||||
static int removereplyto;
|
||||
static int removereturnto;
|
||||
static int dirtyoutcode = CHRS_NOTSET;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* External variables
|
||||
*/
|
||||
extern int do_quiet;
|
||||
extern int do_learn;
|
||||
extern int most_debug;
|
||||
extern int news_in;
|
||||
extern int email_in;
|
||||
extern char *replyaddr;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Internal functions
|
||||
*/
|
||||
int needputrfc(rfcmsg *);
|
||||
|
||||
|
||||
|
||||
int charwrite(char *, FILE *);
|
||||
int charwrite(char *s, FILE *fp)
|
||||
{
|
||||
if ((strlen(s) >= 3) && (strncmp(s,"---",3) == 0) && (s[3] != '-')) {
|
||||
putc('-',fp);
|
||||
putc(' ',fp);
|
||||
}
|
||||
while (*s) {
|
||||
putc(*s, fp);
|
||||
s++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* write (multiline) header to kluge: change \n to ' ' and end line with \n
|
||||
*/
|
||||
int kludgewrite(char *, FILE *);
|
||||
int kludgewrite(char *s, FILE *fp)
|
||||
{
|
||||
while (*s) {
|
||||
if (*s == '\r')
|
||||
putc('\n', fp);
|
||||
else {
|
||||
if (*s != '\n')
|
||||
putc(*s, fp);
|
||||
else if (*(s+1))
|
||||
putc(' ',fp);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
putc('\n',fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Input a RFC message.
|
||||
*/
|
||||
int rfc2ftn(FILE *fp, faddr *recipient)
|
||||
{
|
||||
char sbe[16], *p, *q, *temp, *origin;
|
||||
int i, rc, incode, outcode, pgpsigned, newsmode;
|
||||
int seenlen, oldnet;
|
||||
rfcmsg *msg = NULL, *tmsg, *tmp;
|
||||
ftnmsg *fmsg = NULL;
|
||||
FILE *ofp;
|
||||
fa_list *sbl = NULL, *ptl = NULL, *tmpl;
|
||||
faddr *ta;
|
||||
unsigned long svmsgid, svreply;
|
||||
int sot_kludge = FALSE, eot_kludge = FALSE, qp_or_base64 = FALSE, tinyorigin = FALSE;
|
||||
int needsplit, hdrsize, datasize, splitpart, forbidsplit, rfcheaders;
|
||||
char newsubj[4 * (MAXSUBJ+1)], *oldsubj, *acup_a = NULL;
|
||||
unsigned long acup_n = 0;
|
||||
int html_message = FALSE;
|
||||
time_t Now;
|
||||
|
||||
temp = calloc(4096, sizeof(char));
|
||||
Syslog('m', "Entering rfc2ftn");
|
||||
if (recipient)
|
||||
Syslog('m', "Recipient: %s", ascfnode(recipient, 0xff));
|
||||
rewind(fp);
|
||||
Syslog('m', "========== RFC Start");
|
||||
while ((fgets(temp, 4095, fp)) != NULL) {
|
||||
Syslogp('m', printable(temp, 0));
|
||||
}
|
||||
Syslog('m', "========== RFC end");
|
||||
rewind(fp);
|
||||
msg = parsrfc(fp);
|
||||
incode = outcode = CHRS_NOTSET;
|
||||
pgpsigned = FALSE;
|
||||
|
||||
newsmode = hdr((char *)"Newsgroups", msg) ?TRUE:FALSE;
|
||||
Syslog('m', "RFC message is %s", newsmode ? "news article":"e-mail message");
|
||||
|
||||
if (newsmode)
|
||||
news_in++;
|
||||
else
|
||||
email_in++;
|
||||
|
||||
p = hdr((char *)"Content-Type",msg);
|
||||
if (p)
|
||||
incode = readcharset(p);
|
||||
if (incode == CHRS_NOTSET) {
|
||||
p = hdr((char *)"X-FTN-CHRS",msg);
|
||||
if (p == NULL)
|
||||
p = hdr((char *)"X-FTN-CHARSET", msg);
|
||||
if (p == NULL)
|
||||
p = hdr((char *)"X-FTN-CODEPAGE", msg);
|
||||
if (p)
|
||||
incode = readchrs(p);
|
||||
}
|
||||
|
||||
if ((p = hdr((char *)"Content-Type",msg)) && ((strcasestr(p,(char *)"multipart/signed")) ||
|
||||
(strcasestr(p,(char *)"application/pgp")))) {
|
||||
pgpsigned = TRUE;
|
||||
outcode = incode;
|
||||
} else if ((p = hdr((char *)"X-FTN-ORIGCHRS", msg)))
|
||||
outcode = readchrs(p);
|
||||
else if (dirtyoutcode != CHRS_NOTSET)
|
||||
outcode = dirtyoutcode;
|
||||
else
|
||||
outcode = getoutcode(incode);
|
||||
|
||||
if (!CFG.allowcontrol) {
|
||||
if (hdr((char *)"Control",msg)) {
|
||||
Syslog('n', "skipping news message");
|
||||
tidyrfc(msg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((fmsg = mkftnhdr(msg, incode, outcode, newsmode, recipient)) == NULL) {
|
||||
WriteError("Unable to create FTN headers from RFC ones, aborting");
|
||||
tidyrfc(msg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (newsmode)
|
||||
fmsg->area = xstrcpy(msgs.Tag);
|
||||
svmsgid = fmsg->msgid_n;
|
||||
svreply = fmsg->reply_n;
|
||||
if ((p = hdr((char *)"Message-ID",msg))) {
|
||||
ftnmsgid(p, &fmsg->msgid_a, &fmsg->msgid_n, fmsg->area);
|
||||
hash_update_s(&fmsg->msgid_n, fmsg->area);
|
||||
}
|
||||
|
||||
if ((p = hdr((char *)"References",msg))) {
|
||||
p = strrchr(p,' ');
|
||||
ftnmsgid(p,&fmsg->reply_a, &fmsg->reply_n,fmsg->area);
|
||||
if (!chkftnmsgid(p)) {
|
||||
hash_update_s(&fmsg->reply_n, fmsg->area);
|
||||
}
|
||||
} else if ((p = hdr((char *)"In-Reply-To",msg))) {
|
||||
ftnmsgid(p,&fmsg->reply_a, &fmsg->reply_n,fmsg->area);
|
||||
if (!chkftnmsgid(p)) {
|
||||
hash_update_s(&fmsg->reply_n, fmsg->area);
|
||||
}
|
||||
}
|
||||
|
||||
if (incode == CHRS_NOTSET && newsmode)
|
||||
incode = msgs.Rfccode;
|
||||
if (outcode == CHRS_NOTSET) {
|
||||
if (newsmode)
|
||||
outcode = msgs.Ftncode;
|
||||
else
|
||||
outcode = CHRS_DEFAULT_FTN;
|
||||
}
|
||||
if ((incode == CHRS_NOTSET) && (hdr((char *)"Message-ID",msg))) {
|
||||
if (chkftnmsgid(hdr((char *)"Message-ID",msg)))
|
||||
incode = CHRS_DEFAULT_FTN;
|
||||
else
|
||||
incode = CHRS_DEFAULT_RFC;
|
||||
}
|
||||
removemime = FALSE;
|
||||
removemsgid = FALSE;
|
||||
removeref = FALSE;
|
||||
removeinreply = FALSE;
|
||||
removesupersedes = FALSE;
|
||||
removeapproved = FALSE;
|
||||
removereplyto = TRUE;
|
||||
removereturnto = TRUE;
|
||||
ftnorigin = fmsg->ftnorigin;
|
||||
if ((hdr((char *)"X-PGP-Signed",msg)))
|
||||
pgpsigned = TRUE;
|
||||
if (pgpsigned)
|
||||
Syslog('n', "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=1; /* no need in MIME headers */
|
||||
/*
|
||||
* some old MUA puts "text" instead of "text/plain; charset=..."
|
||||
*/
|
||||
else if ((strcasecmp(p,"text\n") == 0))
|
||||
removemime = TRUE;
|
||||
}
|
||||
if (removemime || qp_or_base64 || html_message)
|
||||
Syslog('n', "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('n', "removemsgid = %s", removemsgid ? "True":"False");
|
||||
|
||||
if ((!removeref) && (p = hdr((char *)"References",msg))) {
|
||||
p = xstrcpy(p);
|
||||
q = strtok(p," \t\n");
|
||||
if ((q) && (strtok(NULL," \t\n") == NULL))
|
||||
removeref = chkftnmsgid(q);
|
||||
free(p);
|
||||
}
|
||||
if (removeref)
|
||||
Syslog('n', "removeref = %s", removeref ? "True":"False");
|
||||
|
||||
if ((p = hdr((char *)"Supersedes",msg)))
|
||||
removesupersedes = chkftnmsgid(p);
|
||||
if (removesupersedes)
|
||||
Syslog('n', "removesupersedes = %s", removesupersedes ? "True":"False");
|
||||
|
||||
if ((p = hdr((char *)"Approved",msg))) {
|
||||
while (*p && isspace(*p))
|
||||
p++;
|
||||
if ((q = strchr(p,'\n')))
|
||||
*q='\0';
|
||||
if (newsmode && strlen(msgs.Moderator) && (strcasestr(msgs.Moderator,p)))
|
||||
removeapproved = TRUE;
|
||||
if (q)
|
||||
*q='\n';
|
||||
}
|
||||
if (removeapproved)
|
||||
Syslog('n', "removeapproved = %s", removeapproved ? "True":"False");
|
||||
|
||||
if ((p = hdr((char *)"Reply-To",msg))) {
|
||||
removereplyto = FALSE;
|
||||
if ((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('n', "removereplyto = %s", removereplyto ? "True":"False");
|
||||
|
||||
if ((p = hdr((char *)"Return-Receipt-To",msg))) {
|
||||
removereturnto = FALSE;
|
||||
if ((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);
|
||||
}
|
||||
}
|
||||
if (!removereturnto)
|
||||
Syslog('n', "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);
|
||||
Syslog('n', "checkorigin 3");
|
||||
i = 79-11-3-strlen(p);
|
||||
tinyorigin = TRUE;
|
||||
}
|
||||
if (tinyorigin)
|
||||
Syslog('n', "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('n', "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;
|
||||
|
||||
/*
|
||||
* Create a new temp message in FTN style format
|
||||
*/
|
||||
if ((ofp = tmpfile()) == NULL) {
|
||||
WriteError("$Can't open second tmpfile");
|
||||
tidyrfc(msg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (newsmode) {
|
||||
fprintf(ofp, "AREA:%s\n", msgs.Tag);
|
||||
} else {
|
||||
if (fmsg->to->point != 0)
|
||||
fprintf(ofp, "\001TOPT %d\n", fmsg->to->point);
|
||||
if (fmsg->from->point != 0)
|
||||
fprintf(ofp, "\001FMPT %d\n", fmsg->from->point);
|
||||
fprintf(ofp, "\001INTL %d:%d/%d %d:%d/%d\n", fmsg->to->zone, fmsg->to->net, fmsg->to->node,
|
||||
fmsg->from->zone, fmsg->from->net, fmsg->from->node);
|
||||
}
|
||||
|
||||
fprintf(ofp, "\001MSGID: %s %08lx\n", MBSE_SS(fmsg->msgid_a),fmsg->msgid_n);
|
||||
if (fmsg->reply_s)
|
||||
fprintf(ofp, "\1REPLY: %s\n", fmsg->reply_s);
|
||||
else if (fmsg->reply_a)
|
||||
fprintf(ofp, "\1REPLY: %s %08lx\n", fmsg->reply_a, fmsg->reply_n);
|
||||
Now = time(NULL) - (gmt_offset((time_t)0) * 60);
|
||||
fprintf(ofp, "\001TZUTC: %s\n", gmtoffset(Now));
|
||||
fmsg->subj = oldsubj;
|
||||
if ((p = hdr((char *)"X-FTN-REPLYADDR",msg))) {
|
||||
Syslog('n', "replyaddr 1 %s", p);
|
||||
hdrsize += 10+strlen(p);
|
||||
fprintf(ofp,"\1REPLYADDR:");
|
||||
kludgewrite(p,ofp);
|
||||
} else if (replyaddr) {
|
||||
Syslog('n', "replyaddr 2");
|
||||
hdrsize += 10+strlen(replyaddr);
|
||||
fprintf(ofp,"\1REPLYADDR: ");
|
||||
kludgewrite(replyaddr,ofp);
|
||||
}
|
||||
if ((p = hdr((char *)"X-FTN-REPLYTO",msg))) {
|
||||
hdrsize += 8+strlen(p);
|
||||
fprintf(ofp,"\1REPLYTO:");
|
||||
kludgewrite(p,ofp);
|
||||
} else if (replyaddr) {
|
||||
hdrsize += 15;
|
||||
if (newsmode)
|
||||
fprintf(ofp,"\1REPLYTO: %s UUCP\n", aka2str(msgs.Aka));
|
||||
else
|
||||
fprintf(ofp,"\1REPLYTO: %s UUCP\n", ascfnode(bestaka_s(fmsg->to), 0x1f));
|
||||
} else if ((p = hdr((char *)"Reply-To",msg))) {
|
||||
if ((ta = parsefaddr(p))) {
|
||||
if ((q = hdr((char *)"From",msg))) {
|
||||
if (!strcasestr(q,p)) {
|
||||
fprintf(ofp,"\1REPLYTO: %s %s\n", ascfnode(ta,0x1f), ta->name);
|
||||
}
|
||||
tidy_faddr(ta);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((p=strip_flags(hdr((char *)"X-FTN-FLAGS",msg)))) {
|
||||
hdrsize += 15;
|
||||
fprintf(ofp,"\1FLAGS:%s\n",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(ofp, "\1PID:");
|
||||
kludgewrite(p, ofp);
|
||||
} else {
|
||||
fprintf(ofp, "\001PID: MBSE-FIDO %s\n", VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
hdrsize += 8 + strlen(getchrs(outcode));
|
||||
fprintf(ofp, "\001CHRS: %s\n", getchrs(outcode));
|
||||
if (html_message) {
|
||||
hdrsize += 9;
|
||||
fprintf(ofp, "\1HTML: 5\n");
|
||||
}
|
||||
|
||||
if (CFG.allowcontrol && (!hdr((char *)"X-FTN-ACUPDATE",msg)) && (p=hdr((char *)"Control",msg))) {
|
||||
if (strstr(p,"cancel")) {
|
||||
ftnmsgid(p,&acup_a,&acup_n,fmsg->area);
|
||||
if (acup_a) {
|
||||
hash_update_s(&acup_n,fmsg->area);
|
||||
hdrsize += 26 + strlen(acup_a);
|
||||
fprintf(ofp,"\1ACUPDATE: DELETE %s %08lx\n", acup_a,acup_n);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((!hdr((char *)"X-FTN-ACUPDATE",msg)) && (p=hdr((char *)"Supersedes",msg))) {
|
||||
ftnmsgid(p,&acup_a,&acup_n,fmsg->area);
|
||||
if (acup_a) {
|
||||
hash_update_s(&acup_n,fmsg->area);
|
||||
hdrsize += 26 + strlen(acup_a);
|
||||
fprintf(ofp,"\1ACUPDATE: MODIFY %s %08lx\n", acup_a,acup_n);
|
||||
}
|
||||
}
|
||||
#ifdef FSC_0070
|
||||
/* FSC-0070 */
|
||||
if((p = hdr((char *)"Message-ID", msg)) && !(hdr((char *)"X-FTN-RFCID", msg))) {
|
||||
q = strdup(p);
|
||||
fprintf(ofp,"\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;
|
||||
kludgewrite(l, ofp);
|
||||
hdrsize += 6 + strlen(l);
|
||||
free(q);
|
||||
}
|
||||
#endif /* FSC_0070 */
|
||||
|
||||
if (!(hdr((char *)"X-FTN-Tearline", msg)) && !(hdr((char *)"X-FTN-TID", msg))) {
|
||||
sprintf(temp, " MBSE-FIDO %s", VERSION);
|
||||
hdrsize += 4 + strlen(temp);
|
||||
fprintf(ofp, "\1TID:");
|
||||
kludgewrite(temp, ofp);
|
||||
}
|
||||
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 = TRUE;
|
||||
else if (!strcasecmp(tmp->val," EOT:\n"))
|
||||
eot_kludge = TRUE;
|
||||
else {
|
||||
hdrsize += strlen(tmp->val);
|
||||
fprintf(ofp,"\1");
|
||||
/* we should have restored the original string here... */
|
||||
kludgewrite((tmp->val)+1,ofp);
|
||||
}
|
||||
} else {
|
||||
hdrsize += strlen(tmp->key)+strlen(tmp->val);
|
||||
fprintf(ofp,"\1%s:",tmp->key+6);
|
||||
kludgewrite(tmp->val,ofp);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 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(ofp,"\1%s:",tmp->key+2);
|
||||
kludgewrite(tmp->val,ofp);
|
||||
}
|
||||
|
||||
/* 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(ofp,"\1%s:",tmp->key+1);
|
||||
kludgewrite(tmp->val,ofp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the Received: header from this system to the mesage.
|
||||
*/
|
||||
if (!newsmode) {
|
||||
Now = time(NULL);
|
||||
fprintf(ofp, "\1RFC-Received: by %s (mbfido) via RFC2FTN; %s\n", CFG.sysdomain, rfcdate(Now));
|
||||
hdrsize += 72+strlen(CFG.sysdomain);
|
||||
}
|
||||
|
||||
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(ofp,"\1RFC-Newsgroups:");
|
||||
} else {
|
||||
hdrsize += strlen(tmp->key)+strlen(tmp->val);
|
||||
fprintf(ofp,"\1RFC-%s:",tmp->key);
|
||||
}
|
||||
kludgewrite(hdrconv(tmp->val, incode, outcode),ofp);
|
||||
}
|
||||
}
|
||||
|
||||
rfcheaders=0;
|
||||
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(ofp,"Newsgroups:");
|
||||
} else {
|
||||
hdrsize += strlen(tmp->key)+strlen(tmp->val);
|
||||
fprintf(ofp,"%s:",tmp->key);
|
||||
}
|
||||
charwrite(hdrconv(tmp->val, incode, outcode),ofp);
|
||||
}
|
||||
}
|
||||
if (rfcheaders)
|
||||
charwrite((char *)"\n",ofp);
|
||||
if ((hdr((char *)"X-FTN-SOT",msg)) || (sot_kludge))
|
||||
fprintf(ofp,"\1SOT:\n");
|
||||
if ((splitpart == 0) && (hdr((char *)"X-PGP-Signed",msg)))
|
||||
fprintf(ofp,PGP_SIGNED_BEGIN"\n");
|
||||
}
|
||||
if (replyaddr) {
|
||||
// free(replyaddr); /* Gives SIGSEGV */
|
||||
replyaddr = NULL;
|
||||
}
|
||||
if (needsplit) {
|
||||
fprintf(ofp," * Continuation %d of a split message *\n\n", splitpart);
|
||||
needsplit = FALSE;
|
||||
} else if ((p=hdr((char *)"X-Body-Start",msg))) {
|
||||
datasize += strlen(p);
|
||||
if (qp_or_base64==1)
|
||||
charwrite(strkconv(qp_decode(p), incode, outcode), ofp);
|
||||
else if (qp_or_base64==2)
|
||||
charwrite(strkconv(b64_decode(p), incode, outcode), ofp);
|
||||
else
|
||||
charwrite(strkconv(p, incode, outcode), ofp);
|
||||
}
|
||||
while (!(needsplit=(!forbidsplit) && (((splitpart && (datasize > (CFG.new_split * 1024))) ||
|
||||
(!splitpart && ((datasize+hdrsize) > (CFG.new_split * 1024)))))) && (bgets(temp,4096-1,fp))) {
|
||||
datasize += strlen(temp);
|
||||
if (qp_or_base64==1)
|
||||
charwrite(strkconv(qp_decode(temp), incode, outcode), ofp);
|
||||
else if (qp_or_base64==2)
|
||||
charwrite(strkconv(b64_decode(temp), incode, outcode), ofp);
|
||||
else
|
||||
charwrite(strkconv(temp, incode, outcode), ofp);
|
||||
}
|
||||
if (needsplit) {
|
||||
fprintf(ofp,"\n * Message split, to be continued *\n");
|
||||
splitpart++;
|
||||
} else if ((p=hdr((char *)"X-PGP-Signed",msg))) {
|
||||
fprintf(ofp,PGP_SIG_BEGIN"\n");
|
||||
if ((q=hdr((char *)"X-PGP-Version",msg))) {
|
||||
fprintf(ofp,"Version:");
|
||||
charwrite(q,ofp);
|
||||
}
|
||||
if ((q=hdr((char *)"X-PGP-Charset",msg))) {
|
||||
fprintf(ofp,"Charset:");
|
||||
charwrite(q,ofp);
|
||||
}
|
||||
if ((q=hdr((char *)"X-PGP-Comment",msg))) {
|
||||
fprintf(ofp,"Comment:");
|
||||
charwrite(q,ofp);
|
||||
}
|
||||
fprintf(ofp,"\n");
|
||||
p=xstrcpy(p);
|
||||
q=strtok(p," \t\n");
|
||||
fprintf(ofp,"%s\n",q);
|
||||
while ((q=(strtok(NULL," \t\n"))))
|
||||
fprintf(ofp,"%s\n",q);
|
||||
fprintf(ofp,PGP_SIG_END"\n");
|
||||
}
|
||||
if ((p=hdr((char *)"X-FTN-EOT",msg)) || (eot_kludge))
|
||||
fprintf(ofp,"\1EOT:\n");
|
||||
|
||||
if ((p=hdr((char *)"X-FTN-Tearline",msg))) {
|
||||
fprintf(ofp,"---");
|
||||
if (strcasecmp(p," (none)\n") == 0)
|
||||
charwrite((char *)"\n",ofp);
|
||||
else
|
||||
charwrite(p,ofp);
|
||||
} else
|
||||
fprintf(ofp,"--- MBSE BBSv.%s\n",VERSION);
|
||||
|
||||
if ((p = hdr((char *)"X-FTN-Origin",msg))) {
|
||||
if (*(q=p+strlen(p)-1) == '\n')
|
||||
*q='\0';
|
||||
origin = xstrcpy((char *)" * Origin: ");
|
||||
origin = xstrcat(origin, hdrconv(p, incode, outcode));
|
||||
} else {
|
||||
origin = xstrcpy((char *)" * Origin: ");
|
||||
if (fmsg->origin)
|
||||
origin = xstrcat(origin, hdrconv(fmsg->origin, incode, outcode));
|
||||
else
|
||||
origin = xstrcat(origin, CFG.origin);
|
||||
origin = xstrcat(origin, (char *)" (");
|
||||
origin = xstrcat(origin, ascfnode(fmsg->from,tinyorigin?0x0f:0x1f));
|
||||
origin = xstrcat(origin, (char *)")");
|
||||
}
|
||||
fprintf(ofp, "%s", origin);
|
||||
|
||||
if (newsmode) {
|
||||
/*
|
||||
* Setup SEEN-BY lines, first SEEN-BY from RFC message, then all matching AKA's
|
||||
*/
|
||||
for (tmsg = msg; tmsg; tmsg = tmsg->next)
|
||||
if (strcasecmp(tmsg->key, "X-FTN-SEEN-BY") == 0)
|
||||
fill_list(&sbl, tmsg->val, NULL);
|
||||
for (i = 0; i < 40; i++) {
|
||||
if (CFG.akavalid[i] && (CFG.aka[i].point == 0) && (msgs.Aka.zone == CFG.aka[i].zone) &&
|
||||
!((msgs.Aka.net == CFG.aka[i].net) && (msgs.Aka.node == CFG.aka[i].node))) {
|
||||
sprintf(sbe, "%u/%u", CFG.aka[i].net, CFG.aka[i].node);
|
||||
fill_list(&sbl, sbe, NULL);
|
||||
}
|
||||
}
|
||||
if (msgs.Aka.point == 0) {
|
||||
sprintf(sbe, "%u/%u", msgs.Aka.net, msgs.Aka.node);
|
||||
fill_list(&sbl, sbe, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only add SEEN-BY lines if there are any
|
||||
*/
|
||||
if (sbl != NULL) {
|
||||
uniq_list(&sbl);
|
||||
sort_list(&sbl);
|
||||
seenlen = MAXSEEN + 1;
|
||||
memset(&sbe, 0, sizeof(sbe));
|
||||
/* ensure it will not match for the first entry */
|
||||
oldnet = sbl->addr->net-1;
|
||||
for (tmpl = sbl; 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 > MAXSEEN) {
|
||||
seenlen = 0;
|
||||
fprintf(ofp,"\nSEEN-BY:");
|
||||
sprintf(sbe," %u/%u",tmpl->addr->net, tmpl->addr->node);
|
||||
seenlen = strlen(sbe);
|
||||
}
|
||||
fprintf(ofp,"%s",sbe);
|
||||
}
|
||||
tidy_falist(&sbl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup PATH lines
|
||||
*/
|
||||
for (tmp = msg; tmp; tmp = tmp->next)
|
||||
if (!strcasecmp(tmp->key,"X-FTN-PATH"))
|
||||
fill_path(&ptl,tmp->val);
|
||||
if (msgs.Aka.point == 0) {
|
||||
sprintf(sbe,"%u/%u",msgs.Aka.net, msgs.Aka.node);
|
||||
fill_path(&ptl,sbe);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only add PATH line if there is something
|
||||
*/
|
||||
if (ptl != NULL) {
|
||||
uniq_list(&ptl);
|
||||
seenlen = MAXPATH+1;
|
||||
/* ensure it will not match for the first entry */
|
||||
oldnet = ptl->addr->net-1;
|
||||
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;
|
||||
fprintf(ofp,"\n\1PATH:");
|
||||
sprintf(sbe," %u/%u",tmpl->addr->net, tmpl->addr->node);
|
||||
seenlen = strlen(sbe);
|
||||
}
|
||||
fprintf(ofp,"%s",sbe);
|
||||
}
|
||||
tidy_falist(&ptl);
|
||||
}
|
||||
} /* if (newsmode) */
|
||||
|
||||
/*
|
||||
* Add newline and message is ready.
|
||||
*/
|
||||
fprintf(ofp,"\n");
|
||||
fflush(ofp);
|
||||
rewind(ofp);
|
||||
|
||||
Syslog('n', "========== Fido start");
|
||||
while (fgets(temp, 4096, ofp) != NULL) {
|
||||
/*
|
||||
* Only log kludges, skip the body
|
||||
*/
|
||||
// if ((temp[0] == '\001') || !strncmp(temp, "AREA:", 5) || !strncmp(temp, "SEEN-BY", 7)) {
|
||||
// Striplf(temp);
|
||||
Syslogp('n', printable(temp, 0));
|
||||
// }
|
||||
}
|
||||
Syslog('n', "========== Fido end");
|
||||
|
||||
if (newsmode)
|
||||
rc = postecho(NULL, fmsg->from, fmsg->to, origin, fmsg->subj, fmsg->date, fmsg->flags, 0, ofp, FALSE);
|
||||
else
|
||||
rc = postnetmail(ofp, fmsg->from, fmsg->to, origin, fmsg->subj, fmsg->date, fmsg->flags, FALSE);
|
||||
|
||||
free(origin);
|
||||
fclose(ofp);
|
||||
} while (needsplit);
|
||||
free(temp);
|
||||
tidyrfc(msg);
|
||||
tidy_ftnmsg(fmsg);
|
||||
UpdateMsgs();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Test which kludges to add;
|
||||
* <1 junk
|
||||
* 1 make kludge
|
||||
* >1 pass
|
||||
*/
|
||||
int needputrfc(rfcmsg *msg)
|
||||
{
|
||||
faddr *ta;
|
||||
|
||||
// Syslog('M', "needputrfc(%s)", printable(msg->key,0));
|
||||
if ((msg->key == NULL) || (strlen(msg->key) == 0)) return 0;
|
||||
|
||||
if (!strcasecmp(msg->key,"X-UUCP-From")) return -1;
|
||||
if (!strcasecmp(msg->key,"X-Body-Start")) return -1;
|
||||
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 if (strstr(msg->val,","))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcasecmp(msg->key,"X-Origin-Newsgroups")) {
|
||||
if (strstr(msg->val,","))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 ? -1: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 1; /* 28-Jul-2001 MB (was 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 -1;
|
||||
} else
|
||||
return removereplyto ?0:4;
|
||||
}
|
||||
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 1;
|
||||
if (!strcasecmp(msg->key,"Organisation")) return 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,"Supersedes")) return removesupersedes ?0:1;
|
||||
if (!strcasecmp(msg->key,"Distribution")) return ftnorigin ?0: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;
|
||||
}
|
||||
|
||||
|
7
mbfido/rfc2ftn.h
Normal file
7
mbfido/rfc2ftn.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef _RFC2FTN_H
|
||||
#define _RFC2FTN_H
|
||||
|
||||
int rfc2ftn(FILE *fp, faddr *);
|
||||
|
||||
#endif
|
||||
|
172
mbfido/storeecho.c
Normal file
172
mbfido/storeecho.c
Normal file
@ -0,0 +1,172 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: tosser/storenet.c
|
||||
* Purpose ...............: Import a netmail message
|
||||
* Last modification date : 28-Jul-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/msg.h"
|
||||
#include "../lib/msgtext.h"
|
||||
#include "../lib/dbmsgs.h"
|
||||
#include "../lib/dbuser.h"
|
||||
#include "rollover.h"
|
||||
#include "storeecho.h"
|
||||
|
||||
|
||||
|
||||
extern int echo_in; /* Total echomails */
|
||||
extern int echo_imp; /* Imported echomails */
|
||||
extern int echo_dupe; /* Dupe echomails */
|
||||
extern int echo_bad; /* Bad echomails */
|
||||
extern int do_quiet; /* Quiet flag */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Store echomail into the JAM base.
|
||||
*
|
||||
* 0 - All seems well.
|
||||
* 1 - Can't access messagebase.
|
||||
*
|
||||
*/
|
||||
int storeecho(faddr *f, faddr *t, time_t mdate, int flags, char *subj, char *msgid, char *reply, int bad, int dupe, FILE *fp)
|
||||
{
|
||||
int result;
|
||||
unsigned long crc2;
|
||||
char *buf;
|
||||
|
||||
/*
|
||||
* Update import counters
|
||||
*/
|
||||
if (!bad && !dupe) {
|
||||
StatAdd(&msgs.Received, 1L);
|
||||
time(&msgs.LastRcvd);
|
||||
StatAdd(&mgroup.MsgsRcvd, 1L);
|
||||
time(&mgroup.LastDate);
|
||||
UpdateMsgs();
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
if (strlen(CFG.badboard) == 0) {
|
||||
Syslog('+', "Killing bad message");
|
||||
return 0;
|
||||
} else {
|
||||
if ((result = Msg_Open(CFG.badboard)))
|
||||
Syslog('+', "Tossing in bad board");
|
||||
}
|
||||
} else if (dupe) {
|
||||
if (strlen(CFG.dupboard) == 0) {
|
||||
Syslog('+', "Killing dupe message");
|
||||
return 0;
|
||||
} else {
|
||||
if ((result = Msg_Open(CFG.dupboard)))
|
||||
Syslog('+', "Tossing in dupe board");
|
||||
}
|
||||
} else {
|
||||
result = Msg_Open(msgs.Base);
|
||||
}
|
||||
if (!result) {
|
||||
WriteError("Can't open JAMmb %s", msgs.Base);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (Msg_Lock(30L)) {
|
||||
if (dupe)
|
||||
echo_dupe++;
|
||||
else if (bad)
|
||||
echo_bad++;
|
||||
else
|
||||
echo_imp++;
|
||||
|
||||
if (!do_quiet) {
|
||||
colour(3, 0);
|
||||
printf("\r%6u => %-40s\r", echo_in, msgs.Name);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
Msg_New();
|
||||
|
||||
/*
|
||||
* Fill subfields
|
||||
*/
|
||||
strcpy(Msg.From, f->name);
|
||||
strcpy(Msg.To, t->name);
|
||||
strcpy(Msg.FromAddress, ascfnode(f,0x1f));
|
||||
strcpy(Msg.Subject, subj);
|
||||
Msg.Written = mdate;
|
||||
Msg.Arrived = time(NULL) - (gmt_offset((time_t)0) * 60);
|
||||
Msg.Echomail = TRUE;
|
||||
|
||||
/*
|
||||
* These are the only usefull flags in echomail
|
||||
*/
|
||||
if ((flags & M_PVT) && ((msgs.MsgKinds == BOTH) || (msgs.MsgKinds == PRIVATE)))
|
||||
Msg.Private = TRUE;
|
||||
if (flags & M_FILE)
|
||||
Msg.FileAttach = TRUE;
|
||||
|
||||
/*
|
||||
* Set MSGID and REPLY crc.
|
||||
*/
|
||||
if (msgid != NULL) {
|
||||
crc2 = -1;
|
||||
Msg.MsgIdCRC = upd_crc32(msgid, crc2, strlen(msgid));
|
||||
}
|
||||
if (reply != NULL) {
|
||||
crc2 = -1;
|
||||
Msg.ReplyCRC = upd_crc32(reply, crc2, strlen(reply));
|
||||
}
|
||||
|
||||
/*
|
||||
* Start write the message
|
||||
* If not a bad or dupe message, eat the first
|
||||
* line (AREA:tag).
|
||||
*/
|
||||
buf = calloc(2048, sizeof(char));
|
||||
rewind(fp);
|
||||
if (!dupe && !bad)
|
||||
fgets(buf , 2048, fp);
|
||||
Msg_Write(fp);
|
||||
Msg_AddMsg();
|
||||
Msg_UnLock();
|
||||
Msg_Close();
|
||||
free(buf);
|
||||
return 0;
|
||||
} else {
|
||||
Syslog('+', "Can't lock msgbase %s", msgs.Base);
|
||||
Msg_UnLock();
|
||||
Msg_Close();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
7
mbfido/storeecho.h
Normal file
7
mbfido/storeecho.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef _STOREECHO_H
|
||||
#define _STOREECHO_H
|
||||
|
||||
int storeecho(faddr *, faddr *, time_t, int, char *, char *, char *, int, int, FILE *);
|
||||
|
||||
#endif
|
||||
|
171
mbfido/storenet.c
Normal file
171
mbfido/storenet.c
Normal file
@ -0,0 +1,171 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: tosser/storenet.c
|
||||
* Purpose ...............: Import a netmail message
|
||||
* Last modification date : 27-Jul-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/msg.h"
|
||||
#include "../lib/msgtext.h"
|
||||
#include "../lib/dbmsgs.h"
|
||||
#include "../lib/dbuser.h"
|
||||
#include "rollover.h"
|
||||
#include "storenet.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
extern int net_imp; /* Netmails imported */
|
||||
extern int net_bad; /* Bad netmails (tracking errors */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Store netmail into the JAM base.
|
||||
*
|
||||
* 0 - All seems well.
|
||||
* 1 - Can't access messagebase.
|
||||
* 2 - Can't find a netmail board.
|
||||
*
|
||||
*/
|
||||
int storenet(faddr *f, faddr *t, time_t mdate, int flags, char *Subj, char *msgid, char *reply, FILE *fp)
|
||||
{
|
||||
int result, i, empty = TRUE;
|
||||
unsigned long crc2;
|
||||
char *Buf;
|
||||
|
||||
if (SearchNetBoard(t->zone, t->net)) {
|
||||
StatAdd(&msgs.Received, 1L);
|
||||
time(&msgs.LastRcvd);
|
||||
UpdateMsgs();
|
||||
|
||||
result = Msg_Open(msgs.Base);
|
||||
if (!result) {
|
||||
WriteError("Can't open msgbase %s", msgs.Base);
|
||||
net_bad++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (Msg_Lock(30L)) {
|
||||
Msg_New();
|
||||
|
||||
Syslog('m', "Flagfield 0x%04x", flags);
|
||||
strcpy(Msg.From, f->name);
|
||||
strcpy(Msg.To, usr.sUserName);
|
||||
strcpy(Msg.FromAddress, ascfnode(f,0x1f));
|
||||
strcpy(Msg.ToAddress, ascfnode(t,0x1f));
|
||||
strcpy(Msg.Subject, Subj);
|
||||
Msg.Written = mdate;
|
||||
Msg.Arrived = time(NULL) - (gmt_offset((time_t)0) * 60);
|
||||
Msg.Netmail = TRUE;
|
||||
|
||||
/*
|
||||
* These are the only usefull flags in netmail
|
||||
*/
|
||||
if ((msgs.MsgKinds == BOTH) || (msgs.MsgKinds == PRIVATE))
|
||||
Msg.Private = (flags & M_PVT) ? TRUE:FALSE;
|
||||
else
|
||||
Msg.Private = TRUE; /* Allways */
|
||||
if (flags & M_CRASH)
|
||||
Msg.Crash = TRUE;
|
||||
if (flags & M_FILE)
|
||||
Msg.FileAttach = TRUE;
|
||||
if (flags & M_TRANSIT)
|
||||
Msg.Intransit = TRUE;
|
||||
if (flags & M_REQ)
|
||||
Msg.FileRequest = TRUE;
|
||||
if (flags & M_RRQ)
|
||||
Msg.ReceiptRequest = TRUE;
|
||||
|
||||
/*
|
||||
* Set MSGID and REPLY crc.
|
||||
*/
|
||||
if (msgid != NULL) {
|
||||
crc2 = -1;
|
||||
Msg.MsgIdCRC = upd_crc32(msgid, crc2, strlen(msgid));
|
||||
}
|
||||
if (reply != NULL) {
|
||||
crc2 = -1;
|
||||
Msg.ReplyCRC = upd_crc32(reply, crc2, strlen(reply));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if this is an empty netmail
|
||||
*/
|
||||
rewind(fp);
|
||||
Buf = calloc(2049, sizeof(char));
|
||||
while ((fgets(Buf, 2048, fp)) != NULL) {
|
||||
|
||||
for (i = 0; i < strlen(Buf); i++) {
|
||||
if (*(Buf + i) == '\0')
|
||||
break;
|
||||
if (*(Buf + i) == '\n')
|
||||
*(Buf + i) = '\0';
|
||||
if (*(Buf + i) == '\r')
|
||||
*(Buf + i) = '\0';
|
||||
}
|
||||
if (*(Buf) != '\0') {
|
||||
if ((*(Buf) != '\001') &&
|
||||
(strcmp(Buf, (char *)"--- ")))
|
||||
empty = FALSE;
|
||||
}
|
||||
}
|
||||
free(Buf);
|
||||
|
||||
if (!empty) {
|
||||
Syslog('+', "Import netmail to %s", usr.sUserName);
|
||||
rewind(fp);
|
||||
Msg_Write(fp);
|
||||
Msg_AddMsg();
|
||||
net_imp++;
|
||||
} else {
|
||||
Syslog('+', "Empty netmail for %s dropped", usr.sUserName);
|
||||
}
|
||||
Msg_UnLock();
|
||||
Msg_Close();
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
WriteError("Can't lock msgbase %s", msgs.Base);
|
||||
Msg_Close();
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
WriteError("Can't find a netmail board");
|
||||
net_bad++;
|
||||
return 2;
|
||||
} /* if SearchNetBoard() */
|
||||
}
|
||||
|
||||
|
8
mbfido/storenet.h
Normal file
8
mbfido/storenet.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _STORENET_H
|
||||
#define _STORENET_H
|
||||
|
||||
|
||||
int storenet(faddr *, faddr *, time_t, int, char *, char *, char *, FILE *);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user