Updated post command

This commit is contained in:
Michiel Broek 2004-05-10 13:44:21 +00:00
parent a30295d56b
commit 1ea27d4a80
23 changed files with 3309 additions and 5 deletions

View File

@ -3,9 +3,15 @@
include ../Makefile.global
SRCS = mbnntp.c openport.c ttyio.c auth.c commands.c
HDRS = mbnntp.h openport.h ttyio.h auth.h commands.h
OBJS = mbnntp.o openport.o ttyio.o auth.o commands.o
SRCS = mbnntp.c openport.c ttyio.c auth.c commands.c rfc2ftn.c \
hash.c lhash.c msgflags.c postecho.c addpkt.c qualify.c \
storeecho.c rollover.c mkftnhdr.c atoul.c
HDRS = mbnntp.h openport.h ttyio.h auth.h commands.h rfc2ftn.h \
hash.h lhash.h msgflags.h postecho.h addpkt.h qualify.h \
storeecho.h rollover.h mkftnhdr.h atoul.h
OBJS = mbnntp.o openport.o ttyio.o auth.o commands.o rfc2ftn.o \
hash.o lhash.o msgflags.o postecho.o addpkt.o qualify.o \
storeecho.o rollover.o mkftnhdr.o atoul.o
LIBS += ../lib/libmbse.a ../lib/libmsgbase.a ../lib/libdbase.a
OTHER = Makefile
@ -56,8 +62,19 @@ depend:
# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT
# Dependencies generated by make depend
mbnntp.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/msg.h openport.h ttyio.h auth.h commands.h mbnntp.h
openport.o: ../config.h ../lib/mbselib.h openport.h
openport.o: ../config.h ../lib/mbselib.h ttyio.h openport.h
ttyio.o: ../config.h ../lib/mbselib.h ttyio.h
auth.o: ../config.h ../lib/mbselib.h ../lib/users.h mbnntp.h auth.h
commands.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ttyio.h mbnntp.h commands.h
commands.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ttyio.h mbnntp.h rfc2ftn.h commands.h
rfc2ftn.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbinet.h ../lib/mbsedb.h ../lib/msg.h ../lib/msgtext.h mkftnhdr.h hash.h postecho.h msgflags.h rfc2ftn.h
hash.o: ../config.h ../lib/mbselib.h hash.h lhash.h
lhash.o: ../config.h ../lib/mbselib.h lhash.h
msgflags.o: ../config.h ../lib/mbselib.h msgflags.h
postecho.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h postecho.h storeecho.h addpkt.h rollover.h qualify.h
addpkt.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h addpkt.h
qualify.o: ../config.h ../lib/mbselib.h qualify.h
storeecho.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h rollover.h storeecho.h
rollover.o: ../config.h ../lib/mbselib.h rollover.h
mkftnhdr.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h atoul.h hash.h msgflags.h mkftnhdr.h
atoul.o: ../config.h ../lib/mbselib.h atoul.h
# End of generated dependencies

296
mbnntp/addpkt.c Normal file
View File

@ -0,0 +1,296 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: Add mail to .pkt
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* 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/mbselib.h"
#include "../lib/users.h"
#include "../lib/mbsedb.h"
#include "addpkt.h"
static char *months[]={(char *)"Jan",(char *)"Feb",(char *)"Mar",
(char *)"Apr",(char *)"May",(char *)"Jun",
(char *)"Jul",(char *)"Aug",(char *)"Sep",
(char *)"Oct",(char *)"Nov",(char *)"Dec"};
/*
* Prepare ARCmail, this is actually just a rename of the temporary
* .pkt file on the queue to a permanent .pkt name that will later
* be added to the real ARCmail bundle.
*/
int PrepARC(char *, fidoaddr);
int PrepARC(char *Queue, fidoaddr Dest)
{
char *pktfile;
FILE *fp;
Syslog('p', "Prepare ARCmail for %s", aka2str(Dest));
if (!SearchNode(Dest)) {
WriteError("Downlink %s not found", aka2str(Dest));
return FALSE;
}
pktfile = calloc(PATH_MAX, sizeof(char));
sprintf(pktfile, "%s/%d.%d.%d.%d/%08lx.pkt", CFG.out_queue, Dest.zone, Dest.net, Dest.node, Dest.point, sequencer());
Syslog('p', "Rename .pkt to %s", pktfile);
if (rename(Queue, pktfile)) {
WriteError("$Can't rename %s to %s", Queue, pktfile);
free(pktfile);
return FALSE;
}
/*
* Add zero word to end of .pkt file
*/
if ((fp = fopen(pktfile, "a+")) == NULL) {
WriteError("$Can't open %s", pktfile);
free(pktfile);
return FALSE;
}
putc('\0', fp);
putc('\0', fp);
fsync(fileno(fp));
fclose(fp);
free(pktfile);
return TRUE;
}
FILE *CreatePkt(char *, fidoaddr, fidoaddr, char *);
FILE *CreatePkt(char *Queue, fidoaddr Orig, fidoaddr Dest, char *Extension)
{
static FILE *qp;
unsigned char buffer[0x3a];
time_t Now;
int i;
struct tm *Tm;
char str[81];
if ((qp = fopen(Queue, "a")) == NULL) {
WriteError("$Can't create Queue %s", Queue);
return NULL;
}
/*
* Write .PKT header, see FSC-0039 rev. 4
*/
memset(&buffer, 0, sizeof(buffer));
Now = time(NULL);
Tm = localtime(&Now);
if (Tm->tm_sec > 59)
Tm->tm_sec = 59;
buffer[0x00] = (Orig.node & 0x00ff);
buffer[0x01] = (Orig.node & 0xff00) >> 8;
buffer[0x02] = (Dest.node & 0x00ff);
buffer[0x03] = (Dest.node & 0xff00) >> 8;
buffer[0x04] = ((Tm->tm_year + 1900) & 0x00ff);
buffer[0x05] = ((Tm->tm_year + 1900) & 0xff00) >> 8;
buffer[0x06] = Tm->tm_mon;
buffer[0x08] = Tm->tm_mday;
buffer[0x0a] = Tm->tm_hour;
buffer[0x0c] = Tm->tm_min;
buffer[0x0e] = Tm->tm_sec;
buffer[0x12] = 2;
buffer[0x14] = (Orig.net & 0x00ff);
buffer[0x15] = (Orig.net & 0xff00) >> 8;
buffer[0x16] = (Dest.net & 0x00ff);
buffer[0x17] = (Dest.net & 0xff00) >> 8;
buffer[0x18] = (PRODCODE & 0x00ff);
buffer[0x19] = (VERSION_MAJOR & 0x00ff);
memset(&str, 0, 8); /* Packet password */
if (SearchNode(Dest)) {
if (strlen(nodes.Epasswd)) {
sprintf(str, "%s", nodes.Epasswd);
}
}
for (i = 0; i < 8; i++)
buffer[0x1a + i] = toupper(str[i]); /* FSC-0039 only talks about A-Z, 0-9, so force uppercase */
buffer[0x22] = (Orig.zone & 0x00ff);
buffer[0x23] = (Orig.zone & 0xff00) >> 8;
buffer[0x24] = (Dest.zone & 0x00ff);
buffer[0x25] = (Dest.zone & 0xff00) >> 8;
buffer[0x29] = 1;
buffer[0x2a] = (PRODCODE & 0xff00) >> 8;
buffer[0x2b] = (VERSION_MINOR & 0x00ff);
buffer[0x2c] = 1;
buffer[0x2e] = buffer[0x22];
buffer[0x2f] = buffer[0x23];
buffer[0x30] = buffer[0x24];
buffer[0x31] = buffer[0x25];
buffer[0x32] = (Orig.point & 0x00ff);
buffer[0x33] = (Orig.point & 0xff00) >> 8;
buffer[0x34] = (Dest.point & 0x00ff);
buffer[0x35] = (Dest.point & 0xff00) >> 8;
buffer[0x36] = 'm';
buffer[0x37] = 'b';
buffer[0x38] = 's';
buffer[0x39] = 'e';
fwrite(buffer, 1, 0x3a, qp);
fsync(fileno(qp));
return qp;
}
/*
* Open a .pkt file on the queue, create a fresh one if needed.
* If CFG.maxpktsize is set then it will add the .pkt to the
* ARCmail archive when possible.
*/
FILE *OpenPkt(fidoaddr Orig, fidoaddr Dest, char *Extension)
{
char *Queue;
static FILE *qp;
Queue = calloc(PATH_MAX, sizeof(char));
sprintf(Queue, "%s/%d.%d.%d.%d/mailpkt.%s", CFG.out_queue, Dest.zone, Dest.net, Dest.node, Dest.point, Extension);
mkdirs(Queue, 0750);
if (file_exist(Queue, R_OK))
qp = CreatePkt(Queue, Orig, Dest, Extension);
else {
if ((qp = fopen(Queue, "a")) == NULL) {
WriteError("$Can't reopen Queue %s", Queue);
free(Queue);
return NULL;
}
if (CFG.maxpktsize && (ftell(qp) >= (CFG.maxpktsize * 1024)) && (strcmp(Extension, "qqq") == 0)) {
/*
* It's a pkt that's meant to be send archived and it's
* bigger then maxpktsize. Try to add this pkt to the
* outbound archive for this node.
*/
fsync(fileno(qp));
fclose(qp);
if (PrepARC(Queue, Dest) == TRUE) {
/*
* If the pack succeeded create a fresh packet.
*/
qp = CreatePkt(Queue, Orig, Dest, Extension);
} else {
/*
* If the pack failed the existing queue is
* reopened and we continue adding to that
* existing packet.
*/
Syslog('s', "PrepARC failed");
qp = fopen(Queue, "a");
}
/*
* Go back to the original inbound directory.
*/
chdir(CFG.inbound);
}
}
free(Queue);
return qp;
}
int AddMsgHdr(FILE *fp, faddr *f, faddr *t, int flags, int cost, time_t date, char *tname, char *fname, char *subj)
{
unsigned char buffer[0x0e];
struct tm *Tm;
if ((tname == NULL) || (strlen(tname) > 36) ||
(fname == NULL) || (strlen(fname) > 36) ||
(subj == NULL) || (strlen(subj) > 72)) {
if (tname == NULL)
WriteError("AddMsgHdr() error, To name is NULL");
else if (strlen(tname) > 36)
WriteError("AddMsgHdr() error, To name length %d", strlen(tname));
if (fname == NULL)
WriteError("AddMsgHdr() error, From name is NULL");
else if (strlen(fname) > 36)
WriteError("AddMsgHdr() error, From name length %d", strlen(fname));
if (subj == NULL)
WriteError("AddMsgHdr() error, Subject is NULL");
else if (strlen(subj) > 72)
WriteError("AddMsgHdr() error, Subject length %d", strlen(subj));
return 1;
}
buffer[0x00] = 2;
buffer[0x01] = 0;
buffer[0x02] = (f->node & 0x00ff);
buffer[0x03] = (f->node & 0xff00) >> 8;
buffer[0x04] = (t->node & 0x00ff);
buffer[0x05] = (t->node & 0xff00) >> 8;
buffer[0x06] = (f->net & 0x00ff);
buffer[0x07] = (f->net & 0xff00) >> 8;
buffer[0x08] = (t->net & 0x00ff);
buffer[0x09] = (t->net & 0xff00) >> 8;
buffer[0x0a] = (flags & 0x00ff);
buffer[0x0b] = (flags & 0xff00) >> 8;
buffer[0x0c] = (cost & 0x00ff);
buffer[0x0d] = (cost & 0xff00) >> 8;
fwrite(buffer, 1, sizeof(buffer), fp);
if (date == (time_t)0) {
date = time(NULL);
Tm = localtime(&date);
} else
Tm = gmtime(&date);
/*
* According to the manpage the tm_sec value is in the range 0..61
* to allow leap seconds. FTN networks don't allow this, so if this
* happens we reset the leap seconds.
*/
if (Tm->tm_sec > 59)
Tm->tm_sec = 59;
fprintf(fp, "%02d %-3.3s %02d %02d:%02d:%02d%c",
Tm->tm_mday % 100, months[Tm->tm_mon], Tm->tm_year % 100,
Tm->tm_hour % 100, Tm->tm_min % 100, Tm->tm_sec % 100, '\0');
fprintf(fp, "%s%c", tname, '\0');
fprintf(fp, "%s%c", fname, '\0');
fprintf(fp, "%s%c", subj, '\0');
fsync(fileno(fp));
return 0;
}

9
mbnntp/addpkt.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _ADDPKT_H
#define _ADDPKT_H
/* $Id$ */
FILE *OpenPkt(fidoaddr, fidoaddr, char *);
int AddMsgHdr(FILE *, faddr *, faddr *, int, int, time_t, char *, char *, char *);
#endif

45
mbnntp/atoul.c Normal file
View File

@ -0,0 +1,45 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: MBSE BBS Mail Gate
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* 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/mbselib.h"
#include "atoul.h"
unsigned long atoul(char *str)
{
unsigned long x;
if (sscanf(str,"%lu",&x) == 1)
return x;
else
return 0xffffffff;
}

8
mbnntp/atoul.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _ATOUL_H
#define _ATOUL_H
/* $Id$ */
unsigned long atoul(char*);
#endif

View File

@ -34,6 +34,7 @@
#include "../lib/msgtext.h"
#include "ttyio.h"
#include "mbnntp.h"
#include "rfc2ftn.h"
#include "commands.h"
@ -48,6 +49,10 @@ void send_xlat(char *);
char *make_msgid(char *);
#define POST_MAXSIZE 10000
/*
* Safe sending to the client with charset translation.
*/
@ -373,6 +378,48 @@ void command_list(char *cmd)
/*
* POST
*/
void command_post(char *cmd)
{
FILE *fp = NULL;
int rc, Done = FALSE;
char buf[1024];
if ((fp = tmpfile()) == NULL) {
WriteError("$Can't create tmpfile");
send_nntp("503 Out of memory");
return;
}
send_nntp("340 Send article to be posted. End with <CR-LF>.<CR-LF>");
while (Done == FALSE) {
rc = get_nntp(buf, sizeof(buf) -1);
if (rc < 0) {
WriteError("nntp_get failed, abort");
return;
}
if ((rc == 1) && (buf[0] == '.')) {
Done = TRUE;
} else {
fwrite(&buf, strlen(buf), 1, fp);
fputc('\n', fp);
}
}
rc = rfc2ftn(fp);
fclose(fp);
if (rc)
send_nntp("503 Post failed:");
else
send_nntp("240 Article posted");
}
/*
* XOVER
*/

View File

@ -6,6 +6,7 @@
void command_abhs(char *); /* ARTICLE/BODY/HEADER/STAT */
void command_group(char *); /* GROUP */
void command_list(char *); /* LIST */
void command_post(char *); /* POST */
void command_xover(char *); /* XOVER */
#endif

52
mbnntp/hash.c Normal file
View File

@ -0,0 +1,52 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: MBSE BBS Mail Gate
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* 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/mbselib.h"
#include "hash.h"
#include "lhash.h"
void hash_update_s(unsigned long *id, char *mod)
{
*id ^= lh_strhash(mod);
}
void hash_update_n(unsigned long *id, unsigned long mod)
{
char buf[32];
sprintf(buf,"%030lu",mod);
*id ^= lh_strhash(buf);
}

8
mbnntp/hash.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef HASH_H
#define HASH_H
void hash_update_s(unsigned long *, char *);
void hash_update_n(unsigned long *, unsigned long);
#endif

500
mbnntp/lhash.c Normal file
View File

@ -0,0 +1,500 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: MBSE BBS Mail Gate
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* 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/mbselib.h"
#include "lhash.h"
/* crypto/lhash/lhash.c */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
char *lh_version=(char *)"lhash part of SSLeay 0.6.4 30-Aug-1996";
/* Code for dynamic hash table routines
* Author - Eric Young v 2.0
*
* 2.0 eay - Fixed a bug that occured when using lh_delete
* from inside lh_doall(). As entries were deleted,
* the 'table' was 'contract()ed', making some entries
* jump from the end of the table to the start, there by
* skiping the lh_doall() processing. eay - 4/12/95
*
* 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs
* were not being free()ed. 21/11/95
*
* 1.8 eay - Put the stats routines into a seperate file, lh_stats.c
* 19/09/95
*
* 1.7 eay - Removed the fputs() for realloc failures - the code
* should silently tolerate them. I have also fixed things
* lint complained about 04/05/95
*
* 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92
*
* 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992
*
* 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91
*
* 1.3 eay - Fixed a few lint problems 19/3/1991
*
* 1.2 eay - Fixed lh_doall problem 13/3/1991
*
* 1.1 eay - Added lh_doall
*
* 1.0 eay - First version
*/
#undef MIN_NODES
#define MIN_NODES 16
#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */
#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */
#ifndef NOPROTO
#define P_CP char *
#define P_CPP char *,char *
static void expand(LHASH *lh);
static void contract(LHASH *lh);
static LHASH_NODE **getrn(LHASH *lh, char *data, unsigned long *rhash);
#else
#define P_CP
#define P_CPP
static void expand();
static void contract();
static LHASH_NODE **getrn();
#endif
LHASH *lh_new(unsigned long (*h)(char *), int (*c)(char *, char *))
{
LHASH *ret;
int i;
if ((ret=(LHASH *)malloc(sizeof(LHASH))) == NULL)
goto err0;
if ((ret->b=(LHASH_NODE **)malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL)
goto err1;
for (i=0; i<MIN_NODES; i++)
ret->b[i]=NULL;
ret->comp=((c == NULL)?(int (*)(char *, char *))strcmp:c);
ret->hash=((h == NULL)?(unsigned long (*)(char *))lh_strhash:h);
ret->num_nodes=MIN_NODES/2;
ret->num_alloc_nodes=MIN_NODES;
ret->p=0;
ret->pmax=MIN_NODES/2;
ret->up_load=UP_LOAD;
ret->down_load=DOWN_LOAD;
ret->num_items=0;
ret->num_expands=0;
ret->num_expand_reallocs=0;
ret->num_contracts=0;
ret->num_contract_reallocs=0;
ret->num_hash_calls=0;
ret->num_comp_calls=0;
ret->num_insert=0;
ret->num_replace=0;
ret->num_delete=0;
ret->num_no_delete=0;
ret->num_retreve=0;
ret->num_retreve_miss=0;
ret->num_hash_comps=0;
return(ret);
err1:
free((char *)ret);
err0:
return(NULL);
}
void lh_free(LHASH *lh)
{
unsigned int i;
LHASH_NODE *n,*nn;
for (i=0; i<lh->num_nodes; i++)
{
n=lh->b[i];
while (n != NULL)
{
nn=n->next;
free(n);
n=nn;
}
}
free((char *)lh->b);
free((char *)lh);
}
char *lh_insert(LHASH *lh, char *data)
{
unsigned long hash;
LHASH_NODE *nn,**rn;
char *ret;
if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))
expand(lh);
rn=getrn(lh,data,&hash);
if (*rn == NULL)
{
if ((nn=(LHASH_NODE *)malloc(sizeof(LHASH_NODE))) == NULL)
return(NULL);
nn->data=data;
nn->next=NULL;
nn->hash=hash;
*rn=nn;
ret=NULL;
lh->num_insert++;
lh->num_items++;
}
else /* replace same key */
{
ret= (*rn)->data;
(*rn)->data=data;
lh->num_replace++;
}
return(ret);
}
char *lh_delete(LHASH *lh, char *data)
{
unsigned long hash;
LHASH_NODE *nn,**rn;
char *ret;
rn=getrn(lh,data,&hash);
if (*rn == NULL)
{
lh->num_no_delete++;
return(NULL);
}
else
{
nn= *rn;
*rn=nn->next;
ret=nn->data;
free((char *)nn);
lh->num_delete++;
}
lh->num_items--;
if ((lh->num_nodes > MIN_NODES) &&
(lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)))
contract(lh);
return(ret);
}
char *lh_retrieve(LHASH *lh, char *data)
{
unsigned long hash;
LHASH_NODE **rn;
char *ret;
rn=getrn(lh,data,&hash);
if (*rn == NULL)
{
lh->num_retreve_miss++;
return(NULL);
}
else
{
ret= (*rn)->data;
lh->num_retreve++;
}
return(ret);
}
void lh_doall(LHASH *lh, void (*func)(char *, char *))
{
lh_doall_arg(lh,func,NULL);
}
void lh_doall_arg(LHASH *lh, void(*func)(char *, char *), char *arg)
{
int i;
LHASH_NODE *a,*n;
/* reverse the order so we search from 'top to bottom'
* We were having memory leaks otherwise */
for (i=lh->num_nodes-1; i>=0; i--)
{
a=lh->b[i];
while (a != NULL)
{
/* 28/05/91 - eay - n added so items can be deleted
* via lh_doall */
n=a->next;
func(a->data,arg);
a=n;
}
}
}
static void expand(LHASH *lh)
{
LHASH_NODE **n,**n1,**n2,*np;
unsigned int p,i,j;
unsigned long hash,nni;
lh->num_nodes++;
lh->num_expands++;
p=(int)lh->p++;
n1= &(lh->b[p]);
n2= &(lh->b[p+(int)lh->pmax]);
*n2=NULL; /* 27/07/92 - eay - undefined pointer bug */
nni=lh->num_alloc_nodes;
for (np= *n1; np != NULL; )
{
hash=np->hash;
if ((hash%nni) != p)
{ /* move it */
*n1= (*n1)->next;
np->next= *n2;
*n2=np;
}
else
n1= &((*n1)->next);
np= *n1;
}
if ((lh->p) >= lh->pmax)
{
j=(int)lh->num_alloc_nodes*2;
n=(LHASH_NODE **)realloc((char *)lh->b,
(unsigned int)sizeof(LHASH_NODE *)*j);
if (n == NULL)
{
WriteError("lhash: realloc error in expand()");
lh->p=0;
return;
}
/* else */
for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */
n[i]=NULL; /* 02/03/92 eay */
lh->pmax=lh->num_alloc_nodes;
lh->num_alloc_nodes=j;
lh->num_expand_reallocs++;
lh->p=0;
lh->b=n;
}
}
static void contract(LHASH *lh)
{
LHASH_NODE **n,*n1,*np;
np=lh->b[lh->p+lh->pmax-1];
lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */
if (lh->p == 0)
{
n=(LHASH_NODE **)realloc((char *)lh->b,
(unsigned int)(sizeof(LHASH_NODE *)*lh->pmax));
if (n == NULL)
{
WriteError("lhash: realloc error in contract()");
return;
}
lh->num_contract_reallocs++;
lh->num_alloc_nodes/=2;
lh->pmax/=2;
lh->p=lh->pmax-1;
lh->b=n;
}
else
lh->p--;
lh->num_nodes--;
lh->num_contracts++;
n1=lh->b[(int)lh->p];
if (n1 == NULL)
lh->b[(int)lh->p]=np;
else
{
while (n1->next != NULL)
n1=n1->next;
n1->next=np;
}
}
static LHASH_NODE **getrn(LHASH *lh, char *data, unsigned long *rhash)
{
LHASH_NODE **ret,*n1;
unsigned long hash,nn;
int (*cf)(char *, char *);
hash=(*(lh->hash))(data);
lh->num_hash_calls++;
*rhash=hash;
nn=hash%lh->pmax;
if (nn < lh->p)
nn=hash%lh->num_alloc_nodes;
cf=lh->comp;
ret= &(lh->b[(int)nn]);
for (n1= *ret; n1 != NULL; n1=n1->next)
{
lh->num_hash_comps++;
if (n1->hash != hash)
{
ret= &(n1->next);
continue;
}
lh->num_comp_calls++;
if ((*cf)(n1->data,data) == 0)
break;
ret= &(n1->next);
}
return(ret);
}
/*
static unsigned long lh_strhash(str)
char *str;
{
int i,l;
unsigned long ret=0;
unsigned short *s;
if (str == NULL) return(0);
l=(strlen(str)+1)/2;
s=(unsigned short *)str;
for (i=0; i<l; i++)
ret^=(s[i]<<(i&0x0f));
return(ret);
} */
/* The following hash seems to work very well on normal text strings
* no collisions on /usr/dict/words and it distributes on %2^n quite
* well, not as good as MD5, but still good.
*/
unsigned long lh_strhash(char *c)
{
unsigned long ret=0;
long n;
unsigned long v;
int r;
if ((c == NULL) || (*c == '\0'))
return(ret);
/*
unsigned char b[16];
MD5(c,strlen(c),b);
return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));
*/
n=0x100;
while (*c)
{
v=n|(*c);
n+=0x100;
r= (int)((v>>2)^v)&0x0f;
ret=(ret<<r)|(ret>>(32-r));
ret&=0xFFFFFFFFL;
ret^=v*v;
c++;
}
return((ret>>16)^ret);
}

147
mbnntp/lhash.h Normal file
View File

@ -0,0 +1,147 @@
/* crypto/lhash/lhash.h */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* Header for dynamic hash table routines
* Author - Eric Young
*/
#ifndef HEADER_LHASH_H
#define HEADER_LHASH_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct lhash_node_st
{
char *data;
struct lhash_node_st *next;
#ifndef NO_HASH_COMP
unsigned long hash;
#endif
} LHASH_NODE;
typedef struct lhash_st
{
LHASH_NODE **b;
int (*comp)(char *, char *);
unsigned long (*hash)(char *);
unsigned int num_nodes;
unsigned int num_alloc_nodes;
unsigned int p;
unsigned int pmax;
unsigned long up_load; /* load times 256 */
unsigned long down_load; /* load times 256 */
unsigned long num_items;
unsigned long num_expands;
unsigned long num_expand_reallocs;
unsigned long num_contracts;
unsigned long num_contract_reallocs;
unsigned long num_hash_calls;
unsigned long num_comp_calls;
unsigned long num_insert;
unsigned long num_replace;
unsigned long num_delete;
unsigned long num_no_delete;
unsigned long num_retreve;
unsigned long num_retreve_miss;
unsigned long num_hash_comps;
} LHASH;
#define LH_LOAD_MULT 256
#ifndef NOPROTO
LHASH *lh_new(unsigned long (*h)(char *), int (*c)(char *, char *));
void lh_free(LHASH *lh);
char *lh_insert(LHASH *lh, char *data);
char *lh_delete(LHASH *lh, char *data);
char *lh_retrieve(LHASH *lh, char *data);
void lh_doall(LHASH *lh, void (*func)(char *, char *));
void lh_doall_arg(LHASH *lh, void (*func)(char *, char *),char *arg);
unsigned long lh_strhash(char *c);
#ifndef WIN16
void lh_stats(LHASH *lh, FILE *out);
void lh_node_stats(LHASH *lh, FILE *out);
void lh_node_usage_stats(LHASH *lh, FILE *out);
#endif
#ifdef HEADER_BUFFER_H
void lh_stats_bio(LHASH *lh, BIO *out);
void lh_node_stats_bio(LHASH *lh, BIO *out);
void lh_node_usage_stats_bio(LHASH *lh, BIO *out);
#else
void lh_stats_bio(LHASH *lh, char *out);
void lh_node_stats_bio(LHASH *lh, char *out);
void lh_node_usage_stats_bio(LHASH *lh, char *out);
#endif
#else
LHASH *lh_new();
void lh_free();
char *lh_insert();
char *lh_delete();
char *lh_retrieve();
void lh_doall();
void lh_doall_arg();
unsigned long lh_strhash();
#ifndef WIN16
void lh_stats();
void lh_node_stats();
void lh_node_usage_stats();
#endif
void lh_stats_bio();
void lh_node_stats_bio();
void lh_node_usage_stats_bio();
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -276,6 +276,9 @@ void nntp(void)
} else if (strncasecmp(buf, "HEAD", 4) == 0) {
if (check_auth(buf))
command_abhs(buf);
} else if (strncasecmp(buf, "HEAD", 4) == 0) {
if (check_auth(buf))
command_post(buf);
} else if (strncasecmp(buf, "IHAVE", 5) == 0) {
send_nntp("435 Article not wanted - do not send it");
} else if (strncasecmp(buf, "NEWGROUPS", 9) == 0) {
@ -312,6 +315,7 @@ void nntp(void)
send_nntp("LIST");
send_nntp("NEWGROUPS (not implemented, always returns an empty list)");
send_nntp("NEWNEWS (not implemented, always returns an empty list)");
send_nntp("POST");
send_nntp("QUIT");
send_nntp("SLAVE (has no effect)");
send_nntp("STAT");

594
mbnntp/mkftnhdr.c Normal file
View File

@ -0,0 +1,594 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: MBSE BBS Mail Gate
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* 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.
*****************************************************************************/
/* Base on E.C. Crosser's ifmail.
*
* ### Modified by P.Saratxaga on 19 Sep 1995 ###
* - Added X-FTN-From and X-FTN-To support
* - added code by T.Tanaka, dated 13 Mar 1995, to put the freename in the ftn
* header, instead of the userid, when the address is fido parseable
* - modified ^aREPLY: code, to look in In-Reply-To:
* - support to decode MSGID from fidogate "Message-ID: <MSGID_....>"
* - suport for X-Apparently-To: (generated by the french fido->usenet gate)
* - added don't regate code by Wim Van Sebroeck <vsebro@medelec.uia.ac.be>
* - corriged a bug when Organization: has only blanks
*/
#include "../config.h"
#include "../lib/mbselib.h"
#include "../lib/users.h"
#include "../lib/mbsedb.h"
#include "atoul.h"
#include "hash.h"
#include "msgflags.h"
//#include "aliasdb.h"
#include "mkftnhdr.h"
#ifndef ULONG_MAX
#define ULONG_MAX 4294967295
#endif
char *replyaddr=NULL;
char *ftnmsgidstyle=NULL;
faddr *bestaka;
int ftnmsgid(char *msgid, char **s, unsigned long *n, char *areaname)
{
char *buf, *l, *r, *p;
unsigned long nid = 0L;
faddr *tmp;
static int ftnorigin = 0;
if (msgid == NULL) {
*s = NULL;
*n = 0L;
return ftnorigin;
}
buf = malloc(strlen(msgid)+65);
strcpy(buf, msgid);
if ((l = strchr(buf,'<')))
l++;
else
l = buf;
while (isspace(*l))
l++;
if ((r = strchr(l,'>')))
*r = '\0';
r = l + strlen(l) - 1;
while (isspace(*r) && (r > l))
(*r--)='\0';
if ((tmp = parsefaddr(l))) {
if (tmp->name) {
if (strspn(tmp->name,"0123456789") == strlen(tmp->name))
nid = atoul(tmp->name);
else
nid = ULONG_MAX;
if (nid == ULONG_MAX) {
hash_update_s(&nid, tmp->name);
} else
ftnorigin = 1;
} else {
hash_update_s(&nid,l);
}
*s = xstrcpy(ascfnode(tmp, 0x1f));
tidy_faddr(tmp);
} else {
if ((r=strchr(l,'@')) == NULL) { /* should never happen */
Syslog('!', "ftnmsgid: should never happen");
*s = xstrcpy(l);
hash_update_s(&nid,l);
/* <MSGID_mimeanything_abcd1234@ftn.domain> */
} else if (strncmp(l,"MSGID_",6) == 0) {
*r = '\0';
r = strrchr(l+6,'_');
if (r)
*r++ = '\0';
*s = xstrcpy(l+6);
if (r)
sscanf(r,"%lx",&nid);
ftnorigin = 1;
/* <NOMSGID_mimeanything_abcd1234@ftn.domain> */
} else if (strncmp(l,"NOMSGID_",8) == 0) {
*s = NULL;
*n = 0L;
ftnorigin = 1;
return ftnorigin;
/* <ftn_2.204.226$fidonet_1d17b3b3_Johan.Olofsson@magnus.ct.se> */
} else if (strncmp(l,"ftn_",4) == 0) {
*r = '\0';
if ((r = strchr(l+4,'$')) || (r=strchr(l+4,'#'))) {
if (*r=='$')
*r='@';
if ((r=strchr(l+4,'.')))
*r=':';
if ((r=strchr(l+4,'.')))
*r='/';
}
while ((r=strrchr(l+4,'_')) != strchr(l+4,'_'))
*r='\0';
r=strchr(l+4,'_');
*r++='\0';
*s=xstrcpy(l+4);
sscanf(r,"%lx",&nid);
ftnorigin=1;
/* <wgcid$3$g712$h610$i22$kfidonet$j6596dbf5@brazerko.com> */
} else if (strncmp(l,"wgcid$",6) == 0) {
*r='\0';
if ((r=strstr(l+6,"$g"))) {
*r='\0';
*s=xstrcpy(l+6);
*s=xstrcat(*s,(char *)":");
l=r+2;
}
if ((r=strstr(l,"$h"))) {
*r++='\0';
*s=xstrcat(*s,l);
*s=xstrcat(*s,(char *)"/");
l=r+2;
}
if ((r=strstr(l,"$i"))) {
*r='\0';
*s=xstrcat(*s,l);
*s=xstrcat(*s,(char *)".");
l=r+2;
}
if ((r=strstr(l,"$k"))) {
*r='\0';
*s=xstrcat(*s,l);
*s=xstrcat(*s,(char *)"@");
l=r+2;
}
if ((r=strstr(l,"$j"))) {
*r='\0';
*s=xstrcat(*s,l);
sscanf(r+2,"%lx",&nid);
}
} else {
*r='\0';
if ((p=strchr(l,'%'))) {
*p='\0';
if (strspn(l,"0123456789") == strlen(l)) {
*r='@';
r=p;
} else
*p='%';
}
r++;
if (strspn(l,"0123456789") == strlen(l))
nid = atoul(l);
else
nid = ULONG_MAX;
if (nid == ULONG_MAX)
hash_update_s(&nid,l);
*s=xstrcpy(r);
}
}
*n=nid;
free(buf);
return ftnorigin;
}
ftnmsg *mkftnhdr(rfcmsg *msg, int newsmode, faddr *recipient)
{
char *freename = NULL, *rfcfrom = NULL, *p, *q, *l, *r;
char *fbuf = NULL, *ftnfrom=NULL;
static ftnmsg *tmsg;
int needreplyaddr = 1;
faddr *tmp, *tmp2;
tmsg=(ftnmsg *)malloc(sizeof(ftnmsg));
memset(tmsg, 0, sizeof(ftnmsg));
if (newsmode) {
p = xstrcpy(hdr((char *)"Comment-To",msg));
if (p == NULL)
p = xstrcpy(hdr((char *)"X-Comment-To",msg));
if (p == NULL)
p = xstrcpy(hdr((char *)"X-FTN-To",msg));
if (p == NULL)
p = xstrcpy(hdr((char *)"X-Fidonet-Comment-To",msg));
if (p == NULL)
p = xstrcpy(hdr((char *)"X-Apparently-To",msg));
if (p == NULL)
p = xstrcpy(hdr((char *)"To", msg)); /* 14-Aug-2001 MB */
if (p) {
if ((tmsg->to = parsefaddr(p)) == NULL)
tmsg->to = parsefaddr((char *)"All@p0.f0.n0.z0");
if ((l = strrchr(p,'<')) && (r = strchr(p,'>')) && (l < r)) {
r = l;
*r-- = '\0';
if ((l = strchr(p,'"')) && (r = strrchr(p,'"')) && (l < r)) {
l++;
*r-- = '\0';
}
while (isspace(*r))
*r-- = '\0';
if (!l)
l = p;
while (isspace(*l))
l++;
} else if ((l = strrchr(p,'(')) && (r = strchr(p,')')) && (l < r)) {
*r-- = '\0';
while (isspace(*r))
*r-- = '\0';
l++;
while (isspace(*l))
l++;
} else {
l = p;
while (isspace(*l))
l++;
r = p + strlen(p) -1;
if (*r == '\n')
*r-- = '\0';
while (isspace(*r))
*r-- = '\0';
}
if (*l) {
if (strlen(l) > MAXNAME)
l[MAXNAME]='\0';
free(tmsg->to->name);
tmsg->to->name=xstrcpy(l);
}
free(p);
/*
* It will become echomail, the destination FTN address must
* be our address. 14-Aug-2001 MB.
*/
tmsg->to->zone = msgs.Aka.zone;
tmsg->to->net = msgs.Aka.net;
tmsg->to->node = msgs.Aka.node;
tmsg->to->point = msgs.Aka.point;
tmsg->to->domain = xstrcpy(msgs.Aka.domain);
} else {
/*
* Filling a default To: address.
*/
tmsg->to = (faddr*)malloc(sizeof(faddr));
tmsg->to->name = xstrcpy((char *)"All");
tmsg->to->zone = msgs.Aka.zone;
tmsg->to->net = msgs.Aka.net;
tmsg->to->node = msgs.Aka.node;
tmsg->to->point = msgs.Aka.point;
tmsg->to->domain = xstrcpy(msgs.Aka.domain);
}
Syslog('N', "TO: %s",ascfnode(tmsg->to,0xff));
} else {
if (recipient) {
/*
* In mbmail mode the recipient is valid and must be used
* as the destination address. The To: field is probably
* an RFC address an cannot be used to route the message.
*/
tmsg->to = (faddr *)malloc(sizeof(faddr));
tmsg->to->point = recipient->point;
tmsg->to->node = recipient->node;
tmsg->to->net = recipient->net;
tmsg->to->zone = recipient->zone;
tmsg->to->name = xstrcpy(recipient->name);
if (tmsg->to->name && (strlen(tmsg->to->name) > MAXNAME))
tmsg->to->name[MAXNAME]='\0';
tmsg->to->domain = xstrcpy(recipient->domain);
Syslog('m', "Recipient TO: %s", ascfnode(tmsg->to,0xff));
} else {
p = xstrcpy(hdr((char *)"To",msg));
if (p == NULL)
p = xstrcpy(hdr((char *)"X-Apparently-To",msg));
if (p) {
if ((tmsg->to = parsefaddr(p)) == NULL)
WriteError("Unparsable destination address");
else
Syslog('m', "RFC parsed TO: %s",ascfnode(tmsg->to,0xff));
}
}
} /* else (newsmode) */
p = fbuf = xstrcpy(hdr((char *)"Reply-To", msg));
if (fbuf == NULL)
p = fbuf = xstrcpy(hdr((char *)"From", msg));
if (fbuf == NULL)
p = fbuf = xstrcpy(hdr((char *)"X-UUCP-From", msg));
if (p) {
q = p;
while (isspace(*q))
q++;
fbuf = parserfcaddr(q).remainder;
if (parserfcaddr(q).target) {
fbuf = xstrcat(fbuf, (char *)"@");
fbuf = xstrcat(fbuf, parserfcaddr(q).target);
}
rfcfrom = fbuf;
}
if (p)
free(p);
p = NULL;
if (!rfcfrom)
rfcfrom = xstrcpy((char *)"postmaster");
p = fbuf = xstrcpy(hdr((char *)"From", msg));
if (fbuf == NULL)
p = fbuf = xstrcpy(hdr((char *)"X-UUCP-From", msg));
if (p) {
q = p;
while (isspace(*q))
q++;
if ((q) && (*q != '\0'))
freename = parserfcaddr(q).comment;
else
freename = NULL;
} else
freename = xstrcpy((char *)"Unidentified User");
if (freename) {
while (isspace(*freename))
freename++;
}
if (rfcfrom) {
while (isspace(*rfcfrom))
rfcfrom++;
p = rfcfrom + strlen(rfcfrom) -1;
while ((isspace(*p)) || (*p == '\n'))
*(p--)='\0';
}
if ((freename) && (*freename != '\0')) {
while (isspace(*freename))
freename++;
p = freename + strlen(freename) -1;
while ((isspace(*p)) || (*p == '\n'))
*(p--)='\0';
if ((*freename == '\"') && (*(p=freename+strlen(freename)-1) == '\"')) {
freename++;
*p='\0';
}
}
// if (*freename == '\0') freename=rfcfrom;
if ((!freename) || ((freename) && (*freename == '\0')) || (strcmp(freename,".")==0))
freename=rfcfrom;
if (newsmode)
Syslog('M', "FROM: %s <%s>", freename, rfcfrom);
else
Syslog('+', "from: %s <%s>",freename,rfcfrom);
needreplyaddr = 1;
if ((tmsg->from=parsefaddr(rfcfrom)) == NULL) {
if (freename && rfcfrom)
Syslog('-', "at removed registrate()");
// if (!strchr(freename,'@') && !strchr(freename,'%') &&
// strncasecmp(freename,rfcfrom,MAXNAME) &&
// strncasecmp(freename,"uucp",4) &&
// strncasecmp(freename,"usenet",6) &&
// strncasecmp(freename,"news",4) &&
// strncasecmp(freename,"super",5) &&
// strncasecmp(freename,"admin",5) &&
// strncasecmp(freename,"postmaster",10) &&
// strncasecmp(freename,"sys",3))
// needreplyaddr=registrate(freename,rfcfrom);
} else {
tmsg->ftnorigin = 1;
tmsg->from->name = xstrcpy(freename);
if (strlen(tmsg->from->name) > MAXNAME)
tmsg->from->name[MAXNAME]='\0';
}
if (replyaddr) {
free(replyaddr);
replyaddr=NULL;
}
if (needreplyaddr && (tmsg->from == NULL)) {
Syslog('M', "fill replyaddr with \"%s\"",rfcfrom);
replyaddr=xstrcpy(rfcfrom);
}
if (tmsg->from)
Syslog('m', "From address was%s distinguished as ftn", tmsg->from ? "" : " not");
if (newsmode) {
tmp2 = fido2faddr(msgs.Aka);
bestaka = bestaka_s(tmp2);
tidy_faddr(tmp2);
} else
bestaka = bestaka_s(tmsg->to);
if ((tmsg->from == NULL) && (bestaka)) {
if (CFG.dontregate) {
p = xstrcpy(hdr((char *)"X-FTN-Sender",msg));
if (p == NULL) {
if ((p = hdr((char *)"X-FTN-From",msg))) {
tmp = parsefnode(p);
p = xstrcpy(ascinode(tmp, 0xff));
tidy_faddr(tmp);
}
}
if (p) {
q = p;
while (isspace(*q))
q++;
ftnfrom = parserfcaddr(q).remainder;
if (parserfcaddr(q).target) {
ftnfrom = xstrcat(ftnfrom,(char *)"@");
ftnfrom = xstrcat(ftnfrom,parserfcaddr(q).target);
}
Syslog('m', "Ftn gateway: \"%s\"", ftnfrom);
Syslog('+', "Ftn sender: %s",ftnfrom);
if (ftnfrom)
tmsg->from = parsefaddr(ftnfrom);
if ((tmsg->from) && (!tmsg->from->name))
tmsg->from->name = xstrcpy(rfcfrom);
}
if (p)
free(p);
p = NULL;
if (tmsg->from == NULL) {
tmsg->from=(faddr *)malloc(sizeof(faddr));
tmsg->from->name=xstrcpy(freename);
if (tmsg->from->name && (strlen(tmsg->from->name) > MAXNAME))
tmsg->from->name[MAXNAME]='\0';
tmsg->from->point=bestaka->point;
tmsg->from->node=bestaka->node;
tmsg->from->net=bestaka->net;
tmsg->from->zone=bestaka->zone;
tmsg->from->domain=xstrcpy(bestaka->domain);
}
} else {
tmsg->from=(faddr *)xmalloc(sizeof(faddr));
tmsg->from->name=xstrcpy(freename);
if (tmsg->from->name && (strlen(tmsg->from->name) > MAXNAME))
tmsg->from->name[MAXNAME]='\0';
tmsg->from->point=bestaka->point;
tmsg->from->node=bestaka->node;
tmsg->from->net=bestaka->net;
tmsg->from->zone=bestaka->zone;
tmsg->from->domain=xstrcpy(bestaka->domain);
}
}
if (fbuf)
free(fbuf);
fbuf = NULL;
p = hdr((char *)"Subject", msg);
if (p) {
while (isspace(*p))
p++;
tmsg->subj = xstrcpy(p);
if (*(p=tmsg->subj+strlen(tmsg->subj)-1) == '\n')
*p='\0';
if (strlen(tmsg->subj) > MAXSUBJ)
tmsg->subj[MAXSUBJ]='\0';
} else {
tmsg->subj = xstrcpy((char *)" ");
}
Syslog('M', "SUBJ: \"%s\"", tmsg->subj);
if ((p = hdr((char *)"X-FTN-FLAGS",msg)))
tmsg->flags |= flagset(p);
if (hdr((char *)"Return-Receipt-To",msg))
tmsg->flags |= M_RRQ;
if (hdr((char *)"Notice-Requested-Upon-Delivery-To",msg))
tmsg->flags |= M_RRQ;
if (!newsmode) {
tmsg->flags |= M_PVT;
tmsg->flags |= M_KILLSENT;
}
if ((p = hdr((char *)"X-Origin-Date",msg)))
tmsg->date = parsedate(p, NULL);
else if ((p = hdr((char *)"Date",msg)))
tmsg->date = parsedate(p, NULL);
else
tmsg->date = time((time_t *)NULL);
/*
* SunMail 1.0 creates invalid date formats like: Wed, 19 Jun 2002 18:21:07 GMT-08:00
* ^---- not allowed.
*/
if (tmsg->date == -1) {
Syslog('!', "Parsing date \"%s\" failed, using current date", p);
tmsg->date = time((time_t *)NULL);
}
if ((p = hdr((char *)"X-FTN-MSGID", msg))) {
tmsg->ftnorigin &= 1;
while (isspace(*p))
p++;
tmsg->msgid_s = xstrcpy(p);
if (*(p = tmsg->msgid_s + strlen(tmsg->msgid_s) -1) == '\n')
*p='\0';
} else if ((p = hdr((char *)".MSGID",msg))) {
tmsg->ftnorigin &= 1;
while (isspace(*p))
p++;
tmsg->msgid_s = xstrcpy(p);
if (*(p = tmsg->msgid_s + strlen(tmsg->msgid_s) -1) == '\n')
*p='\0';
} else if ((p = hdr((char *)"Message-ID",msg))) {
tmsg->ftnorigin &= ftnmsgid(p,&(tmsg->msgid_a),&(tmsg->msgid_n),tmsg->area);
} else
tmsg->msgid_a = NULL;
if ((p = hdr((char *)"X-FTN-REPLY",msg))) {
while (isspace(*p))
p++;
tmsg->reply_s = xstrcpy(p);
if (*(p=tmsg->reply_s + strlen(tmsg->reply_s) -1) == '\n')
*p='\0';
} else {
if (newsmode) {
p = hdr((char *)"References",msg);
if (p) {
l = xstrcpy(p);
r = strtok(l," \t\n");
while ((l=strtok(NULL," \t\n")) != NULL)
r = l;
p = r;
free(l);
}
} else
p = hdr((char *)"In-Reply-To",msg);
}
if (p)
(void)ftnmsgid(p,&(tmsg->reply_a),&(tmsg->reply_n),NULL);
else
tmsg->reply_a=NULL;
Syslog('M', "DATE: %s, MSGID: %s %lx, REPLY: %s %lx",
ftndate(tmsg->date), MBSE_SS(tmsg->msgid_a),tmsg->msgid_n, MBSE_SS(tmsg->reply_a),tmsg->reply_n);
p = hdr((char *)"Organization",msg);
if (p == NULL)
p = hdr((char *)"Organisation",msg);
if (p) {
while (isspace(*p))
p++;
tmsg->origin = xstrcpy(p);
if (tmsg->origin)
if (*(p = tmsg->origin + strlen(tmsg->origin)-1) == '\n')
*p='\0';
} else {
/*
* No Organization header, insert the default BBS origin.
*/
tmsg->origin = xstrcpy(CFG.origin);
}
Syslog('M', "ORIGIN: %s", MBSE_SS(tmsg->origin));
return tmsg;
}

10
mbnntp/mkftnhdr.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef _MKFTNHDR_H
#define _MKFTNHDR_H
int ftnmsgid(char *,char **,unsigned long *,char *);
ftnmsg *mkftnhdr(rfcmsg *, int, faddr *);
#endif

133
mbnntp/msgflags.c Normal file
View File

@ -0,0 +1,133 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: MBSE BBS Mail Gate
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* 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/mbselib.h"
#include "msgflags.h"
static char *flnm[] = {
(char *)"PVT",(char *)"CRS",(char *)"RCV",(char *)"SNT",
(char *)"ATT",(char *)"TRN",(char *)"ORP",(char *)"K/S",
(char *)"LOC",(char *)"HLD",(char *)"RSV",(char *)"FRQ",
(char *)"RRQ",(char *)"RRC",(char *)"ARQ",(char *)"FUP"
};
int flagset(char *s)
{
char *buf,*p;
int i;
int fl=0;
buf=xstrcpy(s);
for (p=strtok(buf," ,\t\n"); p; p=strtok(NULL," ,\t\n")) {
for (i=0;i<16;i++)
if (!strcasecmp(p,flnm[i])) {
fl |= (1 << i);
}
}
free(buf);
return fl;
}
char *compose_flags(int flags, char *fkludge)
{
int i;
char *buf = NULL, *p;
if ((fkludge == NULL) && (!flags))
return buf;
if (fkludge) {
if (!isspace(fkludge[0]))
buf=xstrcpy((char *)" ");
buf=xstrcat(buf,fkludge);
p=buf+strlen(buf)-1;
while (isspace(*p))
*p--='\0';
}
for (i = 0; i < 16; i++)
if ((flags & (1 << i)) && (!flag_on(flnm[i],buf))) {
buf=xstrcat(buf,(char *)" ");
buf=xstrcat(buf,flnm[i]);
}
return buf;
}
char *strip_flags(char *flags)
{
char *p,*q=NULL,*tok;
int canonic,i;
if (flags == NULL)
return NULL;
p=xstrcpy(flags);
for (tok=strtok(flags,", \t\n");tok;tok=strtok(NULL,", \t\n")) {
canonic=0;
for (i=0;i<16;i++)
if (strcasecmp(tok,flnm[i]) == 0)
canonic=1;
if (!canonic) {
q=xstrcat(q,(char *)" ");
q=xstrcat(q,tok);
}
}
free(p);
return q;
}
int flag_on(char *flag, char *flags)
{
char *p, *tok;
int up = FALSE;
if (flags == NULL)
return FALSE;
p = xstrcpy(flags);
for (tok = strtok(p, ", \t\n"); tok; tok = strtok(NULL, ", \t\n")) {
if (strcasecmp(flag, tok) == 0)
up = TRUE;
}
free(p);
return up;
}

13
mbnntp/msgflags.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef _MSGFLAGS_H
#define _MSGFLAGS_H
/* $Id$ */
int flag_on(char *,char *);
int flagset(char *);
char *compose_flags(int,char *);
char *strip_flags(char *);
int flag_on(char *,char *);
#endif

480
mbnntp/postecho.c Normal file
View File

@ -0,0 +1,480 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: Post echomail message.
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* 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/mbselib.h"
#include "../lib/users.h"
#include "../lib/msg.h"
#include "../lib/msgtext.h"
#include "../lib/mbsedb.h"
#include "postecho.h"
#include "storeecho.h"
#include "addpkt.h"
#include "rollover.h"
#include "qualify.h"
#define MAXPATH 73
#define MAXSEEN 70
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, ext[4];
FILE *qp;
faddr *From, *To;
int rc;
/*
* Pack flavor for echomail packets.
*/
memset(&ext, 0, sizeof(ext));
if (nodes.PackNetmail)
sprintf(ext, (char *)"qqq");
else if (nodes.Crash)
sprintf(ext, (char *)"ccc");
else if (nodes.Hold)
sprintf(ext, (char *)"hhh");
else
sprintf(ext, (char *)"nnn");
if ((qp = OpenPkt(msgs.Aka, aka, (char *)ext)) == 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(MAX_LINE_LENGTH +1, sizeof(char));
while ((fgets(buf, MAX_LINE_LENGTH, fp)) != NULL) {
Striplf(buf);
fprintf(qp, "%s\r", buf);
}
free(buf);
putc(0, qp);
fsync(fileno(qp));
fclose(qp);
return 0;
}
/*
* 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, sbe[16];
int First = TRUE, rc = 0, i, 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;
time_t ddate;
memset(&Link, 0, sizeof(Link));
crc = 0xffffffff;
/*
* 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) {
bad = FALSE;
memset(&Link, 0, sizeof(Link));
Syslog('!', "Warning, unsecure echomail from %s accepted in area %s", ascfnode(p_from, 0x1f), msgs.Tag);
}
if (bad) {
Syslog('+', "Node %s not connected to area %s", ascfnode(p_from, 0x1f), msgs.Tag);
return 4;
}
if (Link.cutoff && !bad) {
Syslog('+', "Echomail from %s in %s refused, cutoff", ascfnode(p_from, 0x1f), msgs.Tag);
bad = TRUE;
return 4;
}
if (!Link.receivefrom && !bad) {
Syslog('+', "Echomail from %s in %s refused, read only", ascfnode(p_from, 0x1f), msgs.Tag);
bad = TRUE;
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;
}
/*
* Read the message for kludges we need.
*/
buf = calloc(MAX_LINE_LENGTH +1, sizeof(char));
First = TRUE;
rewind(fp);
while ((fgets(buf, MAX_LINE_LENGTH, fp)) != NULL) {
Striplf(buf);
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)) {
p = xstrcpy(buf + 9);
fill_list(&sbl, p, NULL);
free(p);
}
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));
/*
* Some tossers don't bother the seconds in the message, also some
* rescanning software changes the seconds of a message. Do the
* timestamp check without the seconds.
*/
ddate = mdate - (mdate % 60);
crc = upd_crc32((char *)&ddate, crc, sizeof(ddate));
if (msgid != NULL) {
crc = upd_crc32(msgid, crc, strlen(msgid));
} else {
/*
* 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, MAX_LINE_LENGTH, 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));
}
}
dupe = CheckDupe(crc, D_ECHOMAIL, CFG.toss_dupes);
if (!dupe && !msgs.UnSecure) {
/*
* 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) {
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) && (CFG.aka[i].point == 0) &&
!((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, MAX_LINE_LENGTH, 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 ((rc = storeecho(f, t, mdate, flags, subj, msgid, reply, bad, dupe, nfp)) || bad || dupe) {
/*
* Store failed or it was bad or a dupe. Only log failed store.
*/
if (rc)
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);
fclose(nfp);
return rc;
}
/*
* 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);
if (EchoOut(tmpq->aka, t->name, f->name, subj, nfp, flags, cost, mdate))
WriteError("Forward echomail to %s failed", aka2str(tmpq->aka));
} else {
WriteError("Forward echomail to %s failed, noderecord not found", aka2str(tmpq->aka));
}
}
}
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;
}

8
mbnntp/postecho.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _POSTECHO_H
#define _POSTECHO_H
/* $Id$ */
int postecho(faddr *, faddr *, faddr *, char *, char *, time_t, int, int, FILE *, int);
#endif

63
mbnntp/qualify.c Normal file
View File

@ -0,0 +1,63 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: List of qualified systems
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* 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/mbselib.h"
#include "qualify.h"
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;
}

23
mbnntp/qualify.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _QUALIFY_H
#define _QUALIFY_H
/* $Id$ */
/*
* Structure for qualified systems to receive a echomail message/tic file
*/
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;
void tidy_qualify(qualify **);
void fill_qualify(qualify **, fidoaddr, int, int);
#endif

795
mbnntp/rfc2ftn.c Normal file
View File

@ -0,0 +1,795 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: Convert RFC to FTN
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* 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/mbselib.h"
#include "../lib/users.h"
#include "../lib/mbinet.h"
#include "../lib/mbsedb.h"
#include "../lib/msg.h"
#include "../lib/msgtext.h"
#include "mkftnhdr.h"
#include "hash.h"
#include "postecho.h"
#include "msgflags.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 removereplyto;
static int removereturnto;
/*
* External variables
*/
extern char *replyaddr;
/*
* Internal functions
*/
int needputrfc(rfcmsg *, int);
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 news message.
*/
int rfc2ftn(FILE *fp)
{
char sbe[16], *p, *q, *temp, *origin, newsubj[4 * (MAXSUBJ+1)], *oldsubj;
int i, rc, newsmode, seenlen, oldnet;
rfcmsg *msg = NULL, *tmsg, *tmp;
ftnmsg *fmsg = NULL;
FILE *ofp;
fa_list *sbl = NULL, *ptl = NULL, *tmpl;
faddr *ta, *fta;
unsigned long svmsgid, svreply;
int sot_kludge = FALSE, eot_kludge = FALSE, tinyorigin = FALSE;
int needsplit, hdrsize, datasize, splitpart, forbidsplit, rfcheaders;
time_t Now;
temp = calloc(4097, sizeof(char));
Syslog('m', "Entering rfc2ftn");
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);
newsmode = hdr((char *)"Newsgroups", msg) ?TRUE:FALSE;
if (newsmode == FALSE) {
WriteError("Not a news article");
return 1;
}
if ((fmsg = mkftnhdr(msg, newsmode, NULL)) == NULL) {
WriteError("Unable to create FTN headers from RFC ones, aborting");
tidyrfc(msg);
return 1;
}
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);
}
}
chkftnmsgid(hdr((char *)"Message-ID",msg)); // ??
removemime = FALSE;
removemsgid = FALSE;
removeref = FALSE;
removeinreply = FALSE;
removereplyto = TRUE;
removereturnto = TRUE;
ftnorigin = fmsg->ftnorigin;
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++;
/*
* Check for mime to remove.
*/
if ((strncasecmp(p, "text/plain", 10) == 0) && ((q == NULL) ||
(strncasecmp(q,"7bit",4) == 0) || (strncasecmp(q,"8bit",4) == 0))) {
removemime = TRUE; /* no need in MIME headers */
Syslog('m', "removemime=%s", removemime ? "True":"False");
}
}
if ((p = hdr((char *)"Message-ID",msg))) {
if (!removemsgid)
removemsgid = chkftnmsgid(p);
}
Syslog('m', "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('m', "removeref = %s", removeref ? "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;
}
}
Syslog('m', "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;
}
}
if (!removereturnto)
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);
Syslog('m', "checkorigin 3");
i = 79-11-3-strlen(p);
tinyorigin = TRUE;
}
if (tinyorigin)
Syslog('m', "tinyorigin = %s", tinyorigin ? "True":"False");
if ((fmsg->origin) && (strlen(fmsg->origin) > i))
fmsg->origin[i]='\0';
forbidsplit = (ftnorigin || ((p = hdr((char *)"X-FTN-Split",msg)) && (strcasecmp(p," already\n") == 0)));
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);
}
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))) {
hdrsize += 10+strlen(p);
fprintf(ofp,"\1REPLYADDR:");
kludgewrite(p,ofp);
} else if (replyaddr) {
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 {
fta = bestaka_s(fmsg->to);
fprintf(ofp,"\1REPLYTO: %s UUCP\n", ascfnode(fta, 0x1f));
tidy_faddr(fta);
}
} 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-NNTPD %s (%s-%s)\n", VERSION, OsName(), OsCPU());
}
}
if (!(hdr((char *)"X-FTN-Tearline", msg)) && !(hdr((char *)"X-FTN-TID", msg))) {
sprintf(temp, " MBSE-FIDO %s (%s-%s)", VERSION, OsName(), OsCPU());
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, newsmode) == 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(tmp->val, ofp);
}
}
rfcheaders=0;
for (tmp=msg;tmp;tmp=tmp->next) {
if ((needputrfc(tmp, newsmode) > 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(tmp->val, ofp);
}
}
if (rfcheaders)
charwrite((char *)"\n",ofp);
if ((hdr((char *)"X-FTN-SOT",msg)) || (sot_kludge))
fprintf(ofp,"\1SOT:\n");
}
if (replyaddr) {
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);
charwrite(p, 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);
charwrite(temp, ofp);
}
if (needsplit) {
fprintf(ofp,"\n * Message split, to be continued *\n");
splitpart++;
}
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,"%s\n", TearLine());
if ((p = hdr((char *)"X-FTN-Origin",msg))) {
if (*(q=p+strlen(p)-1) == '\n')
*q='\0';
origin = xstrcpy((char *)" * Origin: ");
origin = xstrcat(origin, p);
} else {
origin = xstrcpy((char *)" * Origin: ");
if (fmsg->origin)
origin = xstrcat(origin, fmsg->origin);
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('m', "========== 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('m', printable(temp, 0));
}
}
Syslog('m', "========== Fido end");
rc = postecho(NULL, fmsg->from, fmsg->to, origin, fmsg->subj, fmsg->date, fmsg->flags, 0, ofp, 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, int newsmode)
{
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 1;
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 newsmode?0:2;
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,"X-Originating-IP")) return 0;
if (!strcasecmp(msg->key,"X-Virus-Scanned")) return 0;
if (!strcasecmp(msg->key,"X-AntiVirus")) return 0;
if (!strcasecmp(msg->key,"X-Delivery-Agent")) return 0;
if (!strcasecmp(msg->key,"X-Virtual-Domain")) 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 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 (!strncasecmp(msg->key,"X-MS-",5)) return -1;
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,"X-Face")) return 0;
if (!strcasecmp(msg->key,"X-Accept-Language")) return 0;
if (!strncasecmp(msg->key,"X-Spam-", 7)) return 0;
/*if (!strcasecmp(msg->key,"")) return ;*/
return 1;
}

8
mbnntp/rfc2ftn.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _RFC2FTN_H
#define _RFC2FTN_H
/* $Id$ */
int rfc2ftn(FILE *fp);
#endif

43
mbnntp/rollover.c Normal file
View File

@ -0,0 +1,43 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: Statistic rollover util.
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* 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/mbselib.h"
#include "rollover.h"
void StatAdd(statcnt *S, unsigned long V)
{
S->total += V;
S->tweek += V;
S->tdow[Diw] += V;
S->month[Miy] += V;
}