Converted from CVS

This commit is contained in:
Mercurial Repos
2009-05-15 22:01:56 +02:00
commit 142f5b6943
900 changed files with 203942 additions and 0 deletions

1
mbfido/.cvsignore Normal file
View File

@@ -0,0 +1 @@
filelist mbaff mbdiff mbfido mbfile mbindex mbmsg mbseq

205
mbfido/Makefile Normal file
View File

@@ -0,0 +1,205 @@
# Makefile for MBSE BBS under Linux
# Copyright (c) 1998, 2001 by M. Broek.
# $Id: Makefile,v 1.74 2008/02/17 17:50:14 mbse Exp $
include ../Makefile.global
SRCS = addbbs.c backalias.c flock.c hatch.c mbdiff.c mgrutil.c qualify.c \
ptic.c sendmail.c tracker.c addpkt.c bwrite.c forward.c lhash.c \
mbfido.c mkftnhdr.c ping.c rfc2ftn.c storeecho.c unpack.c aliasdb.c \
fsort.c magic.c mbfile.c mover.c post.c rnews.c storenet.c mbfrearc.c \
utic.c announce.c fflist.c ftn2rfc.c makestat.c mbindex.c msgutil.c \
postecho.c rollover.c tic.c areamgr.c filefind.c grlist.c maketags.c \
mbmsg.c newspost.c postemail.c scan.c toberep.c atoul.c filemgr.c \
hash.c mbaff.c mbseq.c notify.c postnetmail.c scannews.c tosspkt.c \
mbfkill.c mbfutil.c mbfindex.c mbfcheck.c mbfpack.c mbflist.c mbfadopt.c \
mbfimport.c mbfsort.c mbftoberep.c mbfmove.c mbfdel.c bounce.c \
createm.c createf.c msgflags.c dirsession.c queue.c dirlock.c msg.c orphans.c
HDRS = addbbs.h backalias.h flock.h hatch.h mbdiff.h mgrutil.h qualify.h \
postnetmail.h scannews.h tosspkt.h addpkt.h bwrite.h forward.h \
lhash.h mbfido.h mkftnhdr.h ptic.h sendmail.h tracker.h \
aliasdb.h fsort.h magic.h mbfile.h mover.h ping.h rfc2ftn.h \
storeecho.h unpack.h announce.h fflist.h ftn2rfc.h makestat.h mbindex.h \
msgutil.h post.h rnews.h storenet.h utic.h areamgr.h filefind.h \
grlist.h maketags.h mbmsg.h newspost.h postecho.h rollover.h tic.h mbfrearc.h \
atoul.h filemgr.h hash.h mbaff.h mbseq.h notify.h postemail.h scan.h toberep.h \
mbfkill.h mbfutil.h mbfindex.h mbfcheck.h mbfpack.h mbflist.h mbfadopt.h \
mbfimport.h mbfsort.h mbftoberep.h mbfmove.h mbfdel.h bounce.h \
createm.h createf.h msgflags.h dirsession.h queue.h dirlock.h msg.h orphans.h
MBFIDO_OBJS = flock.o tosspkt.o mbfido.o hatch.o maketags.o tracker.o \
makestat.o scannews.o lhash.o bounce.o unpack.o tic.o ptic.o \
utic.o mover.o hash.o mkftnhdr.o addbbs.o magic.o fsort.o toberep.o \
ftn2rfc.o atoul.o ping.o forward.o sendmail.o scan.o addpkt.o \
storenet.o storeecho.o areamgr.o filemgr.o notify.o mgrutil.o rollover.o \
bwrite.o rfc2ftn.o rnews.o newspost.o aliasdb.o postemail.o postnetmail.o \
postecho.o backalias.o createm.o createf.o msgflags.o dirsession.o \
queue.o dirlock.o qualify.o msg.o orphans.o
MBSEQ_OBJS = mbseq.o
MBAFF_OBJS = announce.o fflist.o filefind.o grlist.o mbaff.o msgutil.o toberep.o
MBINDEX_OBJS = mbindex.o
MBDIFF_OBJS = mbdiff.o
MBFILE_OBJS = mbfile.o mbfkill.o mbfutil.o mbfindex.o mbfcheck.o mbfpack.o mbflist.o mbfadopt.o \
mbfimport.o mbftoberep.o mbfmove.o mbfdel.o mbfsort.o mbfrearc.o
MBMSG_OBJS = post.o mbmsg.o
MBFIDO_LIBS = ../lib/libmbse.a ../lib/libmsgbase.a ../lib/libdbase.a ../lib/libdiesel.a ../lib/libmbinet.a ../lib/libnodelist.a
MBSEQ_LIBS = ../lib/libmbse.a ../lib/libdbase.a
MBAFF_LIBS = ../lib/libmbse.a ../lib/libmsgbase.a ../lib/libdbase.a ../lib/libdiesel.a
MBINDEX_LIBS = ../lib/libmbse.a ../lib/libdbase.a
MBDIFF_LIBS = ../lib/libmbse.a ../lib/libdbase.a
MBFILE_LIBS = ../lib/libmbse.a ../lib/libdbase.a ../lib/libdiesel.a
MBMSG_LIBS = ../lib/libmbse.a ../lib/libmsgbase.a ../lib/libdbase.a
OTHER = Makefile README
TARGET = mbfido mbseq mbaff mbindex mbdiff mbfile mbmsg
####################################################################################################################
.c.o:
${CC} ${CFLAGS} ${INCLUDES} ${DEFINES} -c $<
all: ${TARGET}
mbfido: ${MBFIDO_OBJS} ${MBFIDO_LIBS}
${CC} -o mbfido ${MBFIDO_OBJS} ${LDFLAGS} ${LIBS} ${MBFIDO_LIBS}
mbseq: ${MBSEQ_OBJS} ${MBSEQ_LIBS}
${CC} -o mbseq ${MBSEQ_OBJS} ${LDFLAGS} ${LIBS} ${MBSEQ_LIBS}
mbaff: ${MBAFF_OBJS} ${MBAFF_LIBS}
${CC} -o mbaff ${MBAFF_OBJS} ${LDFLAGS} ${LIBS} ${MBAFF_LIBS}
mbindex: ${MBINDEX_OBJS} ${MBINDEX_LIBS}
${CC} -o mbindex ${MBINDEX_OBJS} ${LDFLAGS} ${LIBS} ${MBINDEX_LIBS}
mbdiff: ${MBDIFF_OBJS} ${MBDIFF_LIBS}
${CC} -o mbdiff ${MBDIFF_OBJS} ${LDFLAGS} ${LIBS} ${MBDIFF_LIBS}
mbfile: ${MBFILE_OBJS} ${MBFILE_LIBS}
${CC} -o mbfile ${MBFILE_OBJS} ${LDFLAGS} ${LIBS} ${MBFILE_LIBS}
mbmsg: ${MBMSG_OBJS} ${MBMSG_LIBS}
${CC} -o mbmsg ${MBMSG_OBJS} ${LDFLAGS} ${LIBS} ${MBMSG_LIBS}
clean:
rm -f ${TARGET} *.o *.h~ *.c~ core filelist Makefile.bak
install: all
${INSTALL} -c -s -o ${OWNER} -g ${GROUP} -m 4750 mbfido ${BINDIR}
${INSTALL} -c -s -o ${OWNER} -g ${GROUP} -m 0750 mbseq ${BINDIR}
${INSTALL} -c -s -o ${OWNER} -g ${GROUP} -m 0700 mbaff ${BINDIR}
${INSTALL} -c -s -o ${OWNER} -g ${GROUP} -m 0700 mbindex ${BINDIR}
${INSTALL} -c -s -o ${OWNER} -g ${GROUP} -m 0700 mbdiff ${BINDIR}
${INSTALL} -c -s -o ${OWNER} -g ${GROUP} -m 0700 mbfile ${BINDIR}
${INSTALL} -c -s -o ${OWNER} -g ${GROUP} -m 0750 mbmsg ${BINDIR}
rm -f ${BINDIR}/mbmail
${LN_S} ${BINDIR}/mbfido ${BINDIR}/mbmail
rm -f ${BINDIR}/mbnews
${LN_S} ${BINDIR}/mbfido ${BINDIR}/mbnews
filelist: Makefile
BASE=`pwd`; \
BASE=`basename $${BASE}`; \
(for f in ${SRCS} ${HDRS} ${OTHER} ;do echo ${PACKAGE}-${VERSION}/$${BASE}/$$f; done) >filelist
depend:
@rm -f Makefile.bak; \
mv Makefile Makefile.bak; \
sed -e '/^# DO NOT DELETE/,$$d' Makefile.bak >Makefile; \
${ECHO} '# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT' \
>>Makefile; \
${ECHO} '# Dependencies generated by make depend' >>Makefile; \
for f in ${SRCS}; \
do \
${ECHO} "Dependencies for $$f:\c"; \
${ECHO} "`basename $$f .c`.o:\c" >>Makefile; \
for h in `sed -n -e \
's/^#[ ]*include[ ]*"\([^"]*\)".*/\1/p' $$f`; \
do \
${ECHO} " $$h\c"; \
${ECHO} " $$h\c" >>Makefile; \
done; \
${ECHO} " done."; \
${ECHO} "" >>Makefile; \
done; \
${ECHO} '# End of generated dependencies' >>Makefile
# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT
# Dependencies generated by make depend
addbbs.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h orphans.h tic.h fsort.h qualify.h addbbs.h
backalias.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h backalias.h
flock.o: ../config.h ../lib/mbselib.h flock.h
hatch.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h utic.h rollover.h hatch.h
mbdiff.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbdiff.h
mgrutil.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/diesel.h sendmail.h rollover.h addpkt.h createm.h createf.h mgrutil.h
qualify.o: ../config.h ../lib/mbselib.h qualify.h
ptic.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h unpack.h mover.h toberep.h orphans.h tic.h utic.h magic.h forward.h rollover.h ptic.h magic.h createf.h qualify.h addbbs.h
sendmail.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h addpkt.h rollover.h sendmail.h
tracker.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/nodelist.h ../lib/mbsedb.h tracker.h
addpkt.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h addpkt.h
bwrite.o: ../config.h ../lib/mbselib.h bwrite.h
forward.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/diesel.h orphans.h tic.h sendmail.h rollover.h mgrutil.h forward.h
lhash.o: ../config.h ../lib/mbselib.h lhash.h
mbfido.o: ../config.h ../lib/mbselib.h ../lib/mbse.h ../lib/users.h ../lib/nodelist.h ../lib/mbsedb.h ../lib/msg.h flock.h tosspkt.h unpack.h orphans.h tic.h fsort.h scan.h mbfido.h tracker.h notify.h rollover.h hatch.h scannews.h maketags.h makestat.h newspost.h rnews.h mgrutil.h backalias.h rfc2ftn.h dirsession.h dirlock.h queue.h msg.h createm.h
mkftnhdr.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h atoul.h hash.h msgflags.h aliasdb.h mkftnhdr.h
ping.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h sendmail.h postnetmail.h ping.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 rollover.h postnetmail.h postecho.h msgflags.h rfc2ftn.h
storeecho.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h rollover.h storeecho.h
unpack.o: ../config.h ../lib/mbselib.h flock.h unpack.h
aliasdb.o: ../config.h ../lib/mbselib.h aliasdb.h
fsort.o: ../config.h ../lib/mbselib.h fsort.h
magic.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h orphans.h tic.h utic.h magic.h
mbfile.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfkill.h mbfadopt.h mbfindex.h mbfcheck.h mbfpack.h mbflist.h mbfimport.h mbftoberep.h mbfmove.h mbfdel.h mbfutil.h mbfsort.h mbfile.h mbfrearc.h
mover.o: ../config.h ../lib/mbselib.h orphans.h tic.h mover.h
post.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/msg.h ../lib/msgtext.h post.h
rnews.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbinet.h ../lib/mbsedb.h ../lib/msg.h ../lib/msgtext.h rfc2ftn.h mbfido.h ../paths.h rnews.h
storenet.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h msgflags.h rollover.h storenet.h
mbfrearc.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfutil.h mbfmove.h
utic.o: ../config.h ../lib/mbselib.h orphans.h tic.h mover.h tic.h utic.h
announce.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/msg.h ../lib/msgtext.h ../lib/diesel.h grlist.h msgutil.h toberep.h announce.h
fflist.o: ../config.h ../lib/mbselib.h ../lib/msg.h fflist.h
ftn2rfc.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h rollover.h aliasdb.h postemail.h backalias.h msgflags.h rfc2ftn.h ftn2rfc.h
makestat.o: ../config.h ../lib/mbselib.h ../lib/diesel.h ../lib/msg.h mgrutil.h makestat.h
mbindex.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbindex.h
msgutil.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/msg.h ../lib/msgtext.h ../lib/diesel.h msgutil.h
postecho.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h ftn2rfc.h postecho.h storeecho.h addpkt.h rollover.h qualify.h
rollover.o: ../config.h ../lib/mbselib.h rollover.h
tic.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h unpack.h fsort.h orphans.h ptic.h mover.h tic.h
areamgr.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h ../lib/diesel.h sendmail.h mgrutil.h scan.h createm.h areamgr.h
filefind.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/msg.h ../lib/msgtext.h ../lib/diesel.h fflist.h filefind.h msgutil.h
grlist.o: ../config.h ../lib/mbselib.h grlist.h
maketags.o: ../config.h ../lib/mbselib.h maketags.h
mbmsg.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/mbsedb.h post.h mbmsg.h
newspost.o: ../config.h ../lib/mbselib.h ../lib/mbinet.h newspost.h
postemail.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/mbinet.h ../lib/msg.h postemail.h
scan.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h addpkt.h tracker.h ftn2rfc.h rfc2ftn.h rollover.h postemail.h scan.h
toberep.o: ../config.h ../lib/mbselib.h orphans.h tic.h toberep.h
atoul.o: ../config.h ../lib/mbselib.h atoul.h
filemgr.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h ../lib/diesel.h sendmail.h mgrutil.h createf.h filemgr.h
hash.o: ../config.h ../lib/mbselib.h hash.h lhash.h
mbaff.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/msg.h announce.h filefind.h mbaff.h
mbseq.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbseq.h
notify.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h filemgr.h areamgr.h sendmail.h mgrutil.h notify.h
postnetmail.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/msg.h tracker.h addpkt.h storenet.h ftn2rfc.h areamgr.h filemgr.h ping.h bounce.h postemail.h
scannews.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 rollover.h storeecho.h rfc2ftn.h scannews.h
tosspkt.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h tosspkt.h postnetmail.h postecho.h rollover.h createm.h
mbfkill.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfkill.h mbfutil.h
mbfutil.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfutil.h mbfile.h
mbfindex.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/diesel.h mbfutil.h mbfindex.h
mbfcheck.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfutil.h mbfcheck.h
mbfpack.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfutil.h mbfpack.h
mbflist.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfutil.h mbflist.h
mbfadopt.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfutil.h mbflist.h
mbfimport.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfutil.h mbfimport.h
mbfsort.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfutil.h mbfsort.h
mbftoberep.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfutil.h mbftoberep.h
mbfmove.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfutil.h mbfmove.h
mbfdel.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mbfutil.h mbfmove.h
bounce.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/msg.h ../lib/msgtext.h ../lib/mbsedb.h sendmail.h postnetmail.h ping.h
createm.o: ../config.h ../lib/mbselib.h ../lib/msg.h ../lib/users.h ../lib/mbsedb.h mgrutil.h createm.h
createf.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h mgrutil.h createf.h
msgflags.o: ../config.h ../lib/mbselib.h msgflags.h
dirsession.o: ../config.h ../lib/mbselib.h dirsession.h
queue.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h fsort.h dirsession.h queue.h
dirlock.o: ../config.h ../lib/mbselib.h flock.h dirlock.h
msg.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h ../lib/msgtext.h ../lib/msg.h msgflags.h msg.h
orphans.o: ../config.h ../lib/mbselib.h orphans.h
# End of generated dependencies

37
mbfido/README Normal file
View File

@@ -0,0 +1,37 @@
Mailflow roadmap since version 0.33.18
+-------------------<------------------+
+-----------+ | +-------------+ |
| toss +----------------------------------------------------------------+ | +-> AreaMgr/FileMgr >-+
| inbound | FTN format | | postnetmail |
| mail +-------------------------------------------------------------+ | | +-> storenet >-------> Messagebase
+-----------+ | +--+ check PING |
| | | +---------------+
+-----------+ +-----------+ | | | email/UUCP +--+ |
| stdin | | +---------+ +-------------+ | v
| pipe +-----------------------+------------------+ rfc2ftn | | | |
| rnews | | | +------+ | +----> mailer
+-----------+ | +-----------+ | v | outbound
RFC | | | ^
+-----------+ format | | +-------------+ | |
| scan news | | | | +---------------+
| from inn +-----------------------+ +-----+ postecho +-> storeecho >------> Messagebase
| server | | | +--+ |
+-----------+ | +-------------+ | |
| | |
+-------------+ | +---------------------------<-----------------+ |
+-----------+ | no ISP +-+ | ^
| scan JAM +-------+ email ISP +------------------------------------------+ +-------------+ |
| msgbase +-----+ +-------------+ | | | | |
| for new +---+ | | +--+ postemail +--------------------> SMTP
| messages +-+ | | +-------------+ v | | | |
+-----------+ | | +-+ echomail +------------------------------------+ | +-------------+ |
| | +-------------+ | +--------------------------------------+
| | | +-----------+ | |
| | +-------------+ FTN format | | +---------+ +-------------+ |
| +---+ news gate +----------------+---+ ftn2rfc | | | internal +--------------------> INN feed
| +-------------+ | +------------+ newsspool +--------------------> pipe rnews
| +-----------+ | | +--------------------> UUCP batch
| +-------------+ | +-------------+ |
+-----+ to UUCP +------------------------------------------+ |
| netmail +-> tracker >---------------------------------------------------------------+
+-------------+

322
mbfido/addbbs.c Normal file
View File

@@ -0,0 +1,322 @@
/*****************************************************************************
*
* $Id: addbbs.c,v 1.39 2007/03/07 20:05:30 mbse Exp $
* Purpose ...............: Add TIC file to the BBS
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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 "orphans.h"
#include "tic.h"
#include "fsort.h"
#include "qualify.h"
#include "addbbs.h"
extern int tic_imp;
/*
* Add file to the BBS file database and place it in the download
* directory. If it is replacing a file, a file with a matching name
* will be deleted. If there is a limit on the number of files with
* the same name pattern, the oldest files will be deleted. The
* files database will be packed if necessary. All modifications are
* done on temp files first.
*/
int Add_BBS(qualify **qal)
{
struct FILE_record frec;
int rc, i, Found = FALSE, Keep = 0, DidDelete = FALSE;
char temp1[PATH_MAX], temp2[PATH_MAX], *fname, *lname, *p;
fd_list *fdl = NULL;
struct _fdbarea *fdb_area = NULL;
qualify *tmpq;
faddr *taka;
/*
* First check for an existing record with the same filename,
* if it exists, update the record and we are ready. This will
* prevent for example allfiles.zip to get a new record everytime
* and thus the download counters will be reset after a new update.
*/
if ((fdb_area = mbsedb_OpenFDB(tic.FileArea, 30))) {
while (fread(&frec, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (strcmp(frec.Name, TIC.NewFile) == 0) {
snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.NewFile);
snprintf(temp2, PATH_MAX, "%s/%s", TIC.BBSpath, TIC.NewFile);
mkdirs(temp2, 0755);
if ((rc = file_cp(temp1, temp2))) {
WriteError("Copy to %s failed: %s", temp2, strerror(rc));
mbsedb_CloseFDB(fdb_area);
return FALSE;
}
chmod(temp2, 0644);
strncpy(frec.TicArea, TIC.TicIn.Area, sizeof(frec.TicArea) -1);
frec.Size = TIC.FileSize;
frec.Crc32 = TIC.Crc_Int;
frec.Announced = TRUE;
frec.FileDate = TIC.FileDate;
frec.UploadDate = time(NULL);
for (i = 0; i <= TIC.File_Id_Ct; i++) {
strcpy(frec.Desc[i], TIC.File_Id[i]);
if (i == 24)
break;
}
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp, 0 - fdbhdr.recsize, SEEK_CUR);
fwrite(&frec, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
}
mbsedb_CloseFDB(fdb_area);
tic_imp++;
if ((i = file_rm(temp1)))
WriteError("file_rm(%s): %s", temp1, strerror(i));
return TRUE;
}
}
mbsedb_CloseFDB(fdb_area);
}
/*
* Create filedatabase record.
*/
memset(&frec, 0, sizeof(frec));
strncpy(frec.Name, TIC.NewFile, sizeof(frec.Name) -1);
if (strlen(TIC.NewFullName)) {
strncpy(frec.LName, TIC.NewFullName, sizeof(frec.LName) -1);
} else {
/*
* No LFN, fake it with a lowercase copy of the 8.3 filename.
*/
strncpy(frec.LName, TIC.NewFile, sizeof(frec.LName) -1);
for (i = 0; i < strlen(frec.LName); i++)
frec.LName[i] = tolower(frec.LName[i]);
}
strncpy(frec.TicArea, TIC.TicIn.Area, 20);
frec.Size = TIC.FileSize;
frec.Crc32 = TIC.Crc_Int;
frec.Announced = TRUE;
snprintf(frec.Uploader, 36, "Filemgr");
frec.UploadDate = time(NULL);
frec.FileDate = TIC.FileDate;
for (i = 0; i <= TIC.File_Id_Ct; i++) {
strcpy(frec.Desc[i], TIC.File_Id[i]);
if (i == 24)
break;
}
if (strlen(TIC.TicIn.Magic)) {
strncpy(frec.Magic, TIC.TicIn.Magic, sizeof(frec.Magic) -1);
}
snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.NewFile);
snprintf(temp2, PATH_MAX, "%s/%s", TIC.BBSpath, frec.Name);
mkdirs(temp2, 0755);
if ((rc = file_cp(temp1, temp2))) {
WriteError("Copy to %s failed: %s", temp2, strerror(rc));
return FALSE;
}
chmod(temp2, 0644);
/*
* If LFN = 8.3 name and is DOS 8.3 format, change the LFN to lowercase.
*/
if (strcmp(frec.Name, frec.LName) == 0) {
p = frec.LName;
while (*p) {
if (islower(*p))
Found = TRUE;
p++;
}
if (!Found) {
/*
* All uppercase, change to lowercase.
*/
tl(frec.LName);
Syslog('f', "Converted LFN to lowercase: \"%s\"", frec.LName);
}
}
Found = FALSE;
lname = calloc(PATH_MAX, sizeof(char));
if (getcwd(lname, PATH_MAX -1)) {
if (chdir(TIC.BBSpath)) {
WriteError("$Can't chdir %s", TIC.BBSpath);
} else {
// snprintf(lname, PATH_MAX, "%s/%s", TIC.BBSpath, frec.LName);
if (symlink(frec.Name, frec.LName)) {
WriteError("$Create link %s to %s failed", frec.Name, frec.LName);
}
}
}
free(lname);
if ((fdb_area = mbsedb_OpenFDB(tic.FileArea, 30)) == NULL)
return FALSE;
mbsedb_InsertFDB(fdb_area, frec, area.AddAlpha);
mbsedb_CloseFDB(fdb_area);
/*
* Delete file from the inbound
*/
if ((i = file_rm(temp1)))
WriteError("file_rm(%s): %s", temp1, strerror(i));
/*
* Handle the replace option.
*/
if ((strlen(TIC.TicIn.Replace)) && (tic.Replace)) {
Syslog('f', "Must Replace: %s", TIC.TicIn.Replace);
if ((fdb_area = mbsedb_OpenFDB(tic.FileArea, 30))) {
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (strlen(fdb.LName) == strlen(frec.LName)) {
// FIXME: Search must be based on a reg_exp search
if (strcasecmp(fdb.LName, frec.LName) != 0) {
Found = TRUE;
for (i = 0; i < strlen(frec.LName); i++) {
if ((TIC.TicIn.Replace[i] != '?') && (toupper(TIC.TicIn.Replace[i]) != toupper(fdb.LName[i])))
Found = FALSE;
}
if (Found) {
Syslog('+', "Replace: Deleting: %s", fdb.LName);
fdb.Deleted = TRUE;
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp , - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
}
DidDelete = TRUE;
}
}
}
}
mbsedb_CloseFDB(fdb_area);
}
}
/*
* Handle the Keep number of files option
*/
if (TIC.KeepNum) {
if ((fdb_area = mbsedb_OpenFDB(tic.FileArea, 30))) {
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if ((strlen(fdb.LName) == strlen(frec.LName)) && (!fdb.Deleted)) {
Found = TRUE;
for (i = 0; i < strlen(fdb.LName); i++) {
if ((frec.LName[i] < '0') || (frec.LName[i] > '9')) {
if (frec.LName[i] != fdb.LName[i]) {
Found = FALSE;
}
}
}
if (Found) {
Keep++;
fill_fdlist(&fdl, fdb.LName, fdb.UploadDate);
}
}
}
mbsedb_CloseFDB(fdb_area);
}
/*
* If there are files to delete, mark them.
*/
if (Keep > TIC.KeepNum) {
sort_fdlist(&fdl);
if ((fdb_area = mbsedb_OpenFDB(tic.FileArea, 30))) {
for (i = 0; i < (Keep - TIC.KeepNum); i++) {
fname = pull_fdlist(&fdl);
fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET);
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (strcmp(fdb.LName, fname) == 0) {
Syslog('+', "Keep %d files, deleting: %s", TIC.KeepNum, fdb.LName);
fdb.Deleted = TRUE;
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp , - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
}
DidDelete = TRUE;
}
}
}
mbsedb_CloseFDB(fdb_area);
}
}
tidy_fdlist(&fdl);
}
/*
* Now realy delete the marked files and clean the file
* database.
*/
if (DidDelete) {
if ((fdb_area = mbsedb_OpenFDB(tic.FileArea, 30))) {
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (fdb.Deleted) {
snprintf(temp2, PATH_MAX, "%s/%s", area.Path, fdb.LName);
if (unlink(temp2) != 0)
WriteError("$Can't unlink file %s", temp2);
snprintf(temp2, PATH_MAX, "%s/%s", area.Path, fdb.Name);
/*
* With the path to the 8.3 name, we can check if this file
* is attached for any possible downlink. We use the qualify
* list created by the ptic function to check connected nodes
* only.
*/
for (tmpq = *qal; tmpq; tmpq = tmpq->next) {
if (tmpq->send) {
taka = fido2faddr(tmpq->aka);
un_attach(taka, temp2);
tidy_faddr(taka);
}
}
if (unlink(temp2) != 0)
WriteError("$Can't unlink file %s", temp2);
snprintf(temp2, PATH_MAX, "%s/.%s", area.Path, fdb.Name);
unlink(temp2); /* Thumbnail, no logging if there is an error */
}
}
mbsedb_PackFDB(fdb_area);
mbsedb_CloseFDB(fdb_area);
DidDelete = FALSE;
}
}
tic_imp++;
return TRUE;
}

9
mbfido/addbbs.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _ADDBBS_H
#define _ADDBBS_H
/* $Id: addbbs.h,v 1.2 2004/07/16 20:21:23 mbse Exp $ */
int Add_BBS(qualify **);
#endif

310
mbfido/addpkt.c Normal file
View File

@@ -0,0 +1,310 @@
/*****************************************************************************
*
* $Id: addpkt.c,v 1.17 2005/10/11 20:49:46 mbse Exp $
* Purpose ...............: Add mail to .pkt
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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"
extern int do_flush;
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"};
extern int do_unprot;
/*
* 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));
snprintf(pktfile, PATH_MAX, "%s/%d.%d.%d.%d/%08x.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)) {
snprintf(str, 81, "%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));
snprintf(Queue, PATH_MAX, "%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.
*/
if (do_unprot)
chdir(CFG.inbound);
else
chdir(CFG.pinbound);
}
}
free(Queue);
do_flush = TRUE;
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');
if (flags & M_FILE) {
/*
* Strip path of filenames in the subject line.
*/
fprintf(fp, "%s%c", basename(subj), '\0');
} else {
fprintf(fp, "%s%c", subj, '\0');
}
fsync(fileno(fp));
return 0;
}

10
mbfido/addpkt.h Normal file
View File

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

213
mbfido/aliasdb.c Normal file
View File

@@ -0,0 +1,213 @@
/*****************************************************************************
*
* $Id: aliasdb.c,v 1.10 2008/11/26 22:12:28 mbse Exp $
* Purpose ...............: Alias Database
*
*****************************************************************************
* Copyright (C) 1997-2008
*
* 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 "aliasdb.h"
typedef struct _aliasrec {
char freename[MAXNAME]; /* Internet address */
char address[128]; /* Fidonet address */
time_t dtime; /* Time the record is added/updated */
} aliasrec;
static int opened = 0;
FILE *afp = NULL;
static int alias_db_init(void);
void close_alias_db(void);
static int alias_db_init(void)
{
char buf[PATH_MAX];
struct stat stbuf;
int tries = 0;
struct flock txflock;
txflock.l_type = F_WRLCK;
txflock.l_whence = SEEK_SET;
txflock.l_start = 0L;
txflock.l_len = 0L;
if (opened == -1)
return -1;
if (opened)
return 0;
snprintf(buf, PATH_MAX, "%s/var/aliases.data", getenv("MBSE_ROOT"));
if (stat(buf, &stbuf) != 0) {
afp = fopen(buf,"a");
if (afp)
fclose(afp);
}
if ((afp = fopen(buf, "r+")) == NULL) {
WriteError("$Can't open %s", buf);
return -1;
}
/*
* Now lock it.
*/
while (fcntl(fileno(afp), F_SETLK, &txflock) != 0) {
if (tries > 4)
Syslog('+', "Alias database locked %d errno=%d %s", tries +1, errno, strerror(errno));
msleep(250);
if (++tries >= 60) {
fclose(afp);
afp = NULL;
WriteError("$Error locking alias database");
return -1;
}
}
opened = 1;
return 0;
}
int registrate(char *freename, char *address)
{
char buf[128], *p, *q;
int first;
aliasrec key;
if (alias_db_init())
return 1;
if (strlen(freename) > MAXNAME)
freename[MAXNAME] = '\0';
strncpy(buf, freename, sizeof(buf)-1);
first = TRUE;
for (p = buf, q = buf; *p; p++)
switch (*p) {
case '.': *p=' '; /* fallthrough */
case ' ': if (first) {
*(q++) = *p;
first = FALSE;
}
break;
default: *(q++) = *p;
first = 1;
break;
}
*q = '\0';
Syslog('m', "Registrate \"%s\" \"%s\"", buf, MBSE_SS(address));
while (fread(&key, sizeof(key), 1, afp)) {
if (!strcmp(key.freename, buf)) {
/*
* Already present, update date/time.
*/
key.dtime = time(NULL);
fseek(afp, - sizeof(key), SEEK_CUR);
fwrite(&key, sizeof(key), 1, afp);
close_alias_db();
return 1;
}
}
snprintf(key.freename, MAXNAME, "%s", buf);
snprintf(key.address, 128, "%s", address);
key.dtime = time(NULL);
if (fwrite(&key, sizeof(key), 1, afp) != 1) {
WriteError("$Cannot store: \"%s\" \"%s\"", buf, MBSE_SS(address));
} else {
Syslog('m', "Registered \"%s\" as \"%s\"", buf, MBSE_SS(address));
}
close_alias_db();
return 1;
}
char *lookup(char *freename)
{
static char buf[128], *p, *q;
int first;
aliasrec key;
if (alias_db_init())
return NULL;
strncpy(buf, freename, sizeof(buf) -1);
first = TRUE;
for (p = buf, q = buf; *p; p++)
switch (*p) {
case '.': *p=' '; /* fallthrough */
case ' ': if (first) {
*(q++) = *p;
first = FALSE;
}
break;
default: *(q++) = *p;
first = TRUE;
break;
}
*q = '\0';
Syslog('m', "Lookup \"%s\"", MBSE_SS(freename));
while (fread(&key, sizeof(key), 1, afp)) {
if (!strcmp(key.freename, buf)) {
/*
* Already present
*/
close_alias_db();
Syslog('m',"Found: \"%s\"",buf);
return buf;
}
}
Syslog('m',"Not found: \"%s\"",buf);
close_alias_db();
return NULL;
}
void close_alias_db(void)
{
if (opened != 1)
return;
fclose(afp);
afp = NULL;
opened = 0;
}

12
mbfido/aliasdb.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _ALIASDB_H
#define _ALIASDB_H
#define MAXNAME 35
int registrate(char *, char *);
char *lookup(char *);
#endif

495
mbfido/announce.c Normal file
View File

@@ -0,0 +1,495 @@
/*****************************************************************************
*
* $Id: announce.c,v 1.37 2007/03/02 13:23:36 mbse Exp $
* Purpose ...............: Announce new files and FileFind
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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 "../lib/msg.h"
#include "../lib/msgtext.h"
#include "../lib/diesel.h"
#include "grlist.h"
#include "msgutil.h"
#include "toberep.h"
#include "announce.h"
extern int do_quiet; /* Suppress screen output */
struct _filerecord T_File; /* Internal announce record */
int TotalFiles; /* Total announced files */
unsigned int TotalSize; /* Total size in KBytes. */
int MsgCount; /* Message counter */
/*
* Check for uploads, these are files in the files database with
* the announced flag not yet set.
*/
void Uploads(void);
void Uploads()
{
FILE *pAreas;
char *sAreas;
int Count = 0, i = 0, j, k;
struct _fdbarea *fdb_area = NULL;
sAreas = calloc(PATH_MAX, sizeof(char));
Syslog('+', "Checking for uploads");
IsDoing("Check uploads");
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf(" Checking uploads...\n");
}
snprintf(sAreas, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen(sAreas, "r")) == NULL) {
WriteError("$Can't open %s", sAreas);
free(sAreas);
return;
}
fread(&areahdr, sizeof(areahdr), 1, pAreas);
while (fread(&area, areahdr.recsize, 1, pAreas) == 1) {
i++;
if (CFG.slow_util && do_quiet)
msleep(1);
if ((area.Available) && strlen(area.NewGroup)) {
if (!do_quiet) {
printf("\r %4d => %-44s", i, area.Name);
fflush(stdout);
}
if ((fdb_area = mbsedb_OpenFDB(i, 30))) {
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
Nopper();
if (!fdb.Announced) {
Syslog('m', " %d %s", i, fdb.Name);
memset(&T_File, 0, sizeof(T_File));
if (strlen(fdb.TicArea))
strncpy(T_File.Echo, fdb.TicArea, sizeof(T_File.Echo) -1);
else
snprintf(T_File.Echo, 21, "AREA %d", i);
strncpy(T_File.Group, area.NewGroup, sizeof(T_File.Group) -1);
strncpy(T_File.Comment, area.Name, sizeof(T_File.Comment) -1);
strncpy(T_File.Name, fdb.Name, sizeof(T_File.Name) -1);
strncpy(T_File.LName, fdb.LName, sizeof(T_File.LName) -1);
if (strlen(fdb.Magic))
strncpy(T_File.Magic, fdb.Magic, sizeof(T_File.Magic) -1);
T_File.Size = fdb.Size;
T_File.SizeKb = fdb.Size / 1024;
T_File.Fdate = fdb.FileDate;
snprintf(T_File.Crc, 9, "%08x", fdb.Crc32);
snprintf(T_File.Desc, 256, "%s %s %s %s", fdb.Desc[0], fdb.Desc[1], fdb.Desc[2], fdb.Desc[3]);
k = 0;
for (j = 0; j < 25; j++) {
if (strlen(fdb.Desc[j])) {
snprintf(T_File.LDesc[k], 49, "%s", fdb.Desc[j]);
T_File.LDesc[k][49] = '\0';
k++;
}
}
T_File.TotLdesc = k;
T_File.Announce = TRUE;
if (Add_ToBeRep(T_File))
Count++;
/*
* Mark file is announced.
*/
fdb.Announced = TRUE;
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp, - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
}
}
}
mbsedb_CloseFDB(fdb_area);
}
}
}
if (!do_quiet) {
printf("\r \r");
if (Count)
printf(" %d new uploads\n", Count);
fflush(stdout);
}
if (Count)
Syslog('+', "%d new uploads", Count);
fclose(pAreas);
free(sAreas);
}
int StartMsg(void);
int StartMsg(void)
{
Syslog('m', "StartMsg()");
if (!Msg_Open(newfiles.Area))
return -1;
if (!Msg_Lock(30L)) {
Msg_Close();
return -1;
}
Msg_New();
CountPosted(newfiles.Area);
chartran_init((char *)"CP437", get_ic_ftn(newfiles.charset), 'f');
snprintf(Msg.From, 101, "%s", chartran(newfiles.From));
snprintf(Msg.To, 101, "%s", chartran(newfiles.Too));
if (MsgCount == 1) {
snprintf(Msg.Subject, 101, "%s", chartran(newfiles.Subject));
TotalSize = TotalFiles = 0;
} else
snprintf(Msg.Subject, 101, "%s #%d", chartran(newfiles.Subject), MsgCount);
snprintf(Msg.FromAddress, 101, "%s", aka2str(newfiles.UseAka));
Msg.Written = time(NULL);
Msg.Arrived = time(NULL);
Msg.Local = TRUE;
Msg.Echomail = TRUE;
/*
* Start message text including kludges
*/
Msg_Id(newfiles.UseAka);
Msg_Pid(newfiles.charset);
return Msg_Top(newfiles.Template, newfiles.Language, newfiles.UseAka);
}
void FinishMsg(int, int);
void FinishMsg(int Final, int filepos)
{
char *temp;
FILE *fp, *fi;
Syslog('m', "FinishMsg(%s, %d)", Final ? "TRUE":"FALSE", filepos);
temp = calloc(PATH_MAX, sizeof(char));
if (Final && ((fi = OpenMacro(newfiles.Template, newfiles.Language, FALSE)) != NULL)) {
/*
* Message footer
*/
MacroVars("CD", "dd", TotalFiles, TotalSize);
fseek(fi, filepos, SEEK_SET);
Msg_Macro(fi);
fclose(fi);
MacroClear();
}
if (strlen(newfiles.Origin))
Msg_Bot(newfiles.UseAka, newfiles.Origin, newfiles.Template);
else
Msg_Bot(newfiles.UseAka, CFG.origin, newfiles.Template);
Msg_AddMsg();
Msg_UnLock();
Syslog('+', "Posted message %ld, %d bytes", Msg.Id, Msg.Size);
chartran_close();
snprintf(temp, PATH_MAX, "%s/tmp/echomail.jam", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "a")) != NULL) {
fprintf(fp, "%s %u\n", newfiles.Area, Msg.Id);
fclose(fp);
}
Msg_Close();
free(temp);
}
/*
* Report one group block of new files.
*/
int Report(gr_list *, int);
int Report(gr_list *ta, int filepos)
{
FILE *fp, *fi;
char *temp, *line;
int i, Total = 0;
unsigned int Size = 0;
int filepos1 = 0, filepos2, filepos3 = 0, finalpos = 0;
time_t ftime;
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/toberep.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r")) == NULL) {
WriteError("$Can't open %s", temp);
return 0;
}
MacroVars("GJZ", "ssd", "", "", 0);
MacroVars("slbkdt", "ssddss", "", "", 0, 0, "", "");
MacroVars("ABZ", "ddd", 0, 0, 0);
while (fread(&T_File, sizeof(T_File), 1, fp) == 1) {
if ((!strcmp(T_File.Echo, ta->echo)) && (!strcmp(T_File.Group, ta->group)))
break;
}
Syslog('m', "Announce %s %s %s", T_File.Echo, T_File.Name, chartran(T_File.LName));
if ((fi = OpenMacro(newfiles.Template, newfiles.Language, FALSE)) != NULL) {
/*
* Area block header
*/
MacroVars("GJZ", "ssd", T_File.Echo, chartran(T_File.Comment), 0);
fseek(fi, filepos, SEEK_SET);
Msg_Macro(fi);
filepos1 = ftell(fi);
} else {
free(temp);
return 0;
}
fseek(fp, 0, SEEK_SET);
while (fread(&T_File, sizeof(T_File), 1, fp) == 1) {
if ((!strcmp(T_File.Echo, ta->echo)) && (!strcmp(T_File.Group, ta->group))) {
if (CFG.slow_util && do_quiet)
msleep(1);
/*
* Report one newfile, first line.
*/
fseek(fi, filepos1, SEEK_SET);
ftime = T_File.Fdate;
MacroVars("sl", "ss", T_File.Name, T_File.LName);
MacroVars("bk", "dd", T_File.Size, T_File.SizeKb);
MacroVars("dt", "ss", rfcdate(ftime), chartran(T_File.LDesc[0]));
Msg_Macro(fi);
filepos2 = ftell(fi);
/*
* Extra description lines follow
*/
for (i = 1; i < 24; i++) {
fseek(fi, filepos2, SEEK_SET);
if (strlen(T_File.LDesc[i])) {
MacroVars("t", "s", chartran(T_File.LDesc[i]));
Msg_Macro(fi);
} else {
line = calloc(MAXSTR, sizeof(char));
while ((fgets(line, MAXSTR-2, fi) != NULL) && ((line[0]!='@') || (line[1]!='|'))) {}
free(line);
}
filepos3 = ftell(fi);
}
/*
* Magic request
*/
if (strlen(T_File.Magic)) {
MacroVars("u", "s", T_File.Magic);
Msg_Macro(fi);
} else {
line = calloc(MAXSTR, sizeof(char));
while ((fgets(line, MAXSTR-2, fi) != NULL) && ((line[0]!='@') || (line[1]!='|'))) {}
free(line);
}
filepos3 = ftell(fi);
Total++;
Size += T_File.SizeKb;
}
}
/*
* Area block footer
*/
if (Msg.Size > (CFG.new_split * 1024))
MacroVars("ABZ", "ddd", Total, Size, 1);
else
MacroVars("ABZ", "ddd", Total, Size, 0);
fseek(fi, filepos3, SEEK_SET);
Msg_Macro(fi);
finalpos = ftell(fi);
fclose(fp);
free(temp);
/*
* Split messages if too big.
*/
if (Msg.Size > (CFG.new_split * 1024)) {
MsgCount++;
Syslog('m', "Report() splitting report");
FinishMsg(FALSE, finalpos);
StartMsg();
}
TotalFiles += Total;
TotalSize += Size;
if (fi != NULL) {
fclose(fi);
}
return finalpos;
}
int Announce()
{
gr_list *fgr = NULL, *tmp;
char *temp;
FILE *fp;
int Count = 0, rc = FALSE;
int filepos, filepos1, filepos2;
char group[13];
int i, groups, any;
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("Announce new files\n");
}
Uploads();
IsDoing("Announce files");
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/toberep.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r")) == NULL) {
Syslog('+', "No new files to announce");
free(temp);
if (!do_quiet) {
printf(" No new files.\n");
}
return FALSE;
}
if (!do_quiet)
printf(" Preparing reports...\n");
while (fread(&T_File, sizeof(T_File), 1, fp) == 1) {
if (T_File.Announce) {
fill_grlist(&fgr, T_File.Group, T_File.Echo);
Count++;
}
}
fclose(fp);
if (Count == 0) {
unlink(temp);
if (!do_quiet)
printf(" No new files.\n");
Syslog('+', "No new files to announce");
free(temp);
return FALSE;
}
if (!do_quiet)
printf(" %d new files found\n", Count);
sort_grlist(&fgr);
/*
* At this point we have a sorted list of groups with a counter
* indicating howmany files to report in each group.
*/
snprintf(temp, PATH_MAX, "%s/etc/newfiles.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r")) == NULL) {
WriteError("$Can't open %s", temp);
if (!do_quiet)
printf(" No newfile reports defined\n");
free(temp);
return FALSE;
}
fread(&newfileshdr, sizeof(newfileshdr), 1, fp);
groups = newfileshdr.grpsize / 13;
while (fread(&newfiles, newfileshdr.recsize, 1, fp) == 1) {
if (newfiles.Active) {
filepos = ftell(fp);
if (!do_quiet)
printf(" %s\n", newfiles.Comment);
any = FALSE;
for (i = 0; i < groups; i++) {
fread(&group, 13, 1, fp);
for (tmp = fgr; tmp; tmp = tmp->next)
if (strcmp(tmp->group, group) == 0)
any = TRUE;
}
if (any) {
fseek(fp, filepos, SEEK_SET);
rc = TRUE;
Syslog('+', "Create report: %s", newfiles.Comment);
MsgCount = 1;
if ((filepos1 = StartMsg()) != -1) {
filepos2 = 0;
while (fread(&group, 13, 1, fp) == 1) {
for (tmp = fgr; tmp; tmp = tmp->next) {
if (!strcmp(tmp->group, group)) {
filepos2 = Report(tmp, filepos1);
}
}
}
FinishMsg(TRUE, filepos2);
}
} else {
if (!do_quiet)
printf(" No matching groups\n");
}
fseek(fp, filepos, SEEK_SET);
}
fseek(fp, newfileshdr.grpsize, SEEK_CUR);
}
fclose(fp);
tidy_grlist(&fgr);
if (rc) {
snprintf(temp, PATH_MAX, "%s/etc/toberep.data", getenv("MBSE_ROOT"));
unlink(temp);
}
free(temp);
return rc;
}

9
mbfido/announce.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _MBAFF_H_
#define _MBAFF_H
int Announce(void); /* Announce files */
#endif

1184
mbfido/areamgr.c Normal file

File diff suppressed because it is too large Load Diff

12
mbfido/areamgr.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _AREAMGR_H
#define _AREAMGR_H
void A_Status(faddr *, char *);
void A_List(faddr *, char *, int);
void A_Flow(faddr *, char *, int);
int AreaMgr(faddr *, faddr *, char *, char *, time_t, int, FILE *);
#endif

45
mbfido/atoul.c Normal file
View File

@@ -0,0 +1,45 @@
/*****************************************************************************
*
* $Id: atoul.c,v 1.6 2005/10/11 20:49:47 mbse Exp $
* Purpose ...............: MBSE BBS Mail Gate
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 int atoul(char *str)
{
unsigned int x;
if (sscanf(str,"%u",&x) == 1)
return x;
else
return 0xffffffff;
}

9
mbfido/atoul.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _ATOUL_H
#define _ATOUL_H
/* $Id: atoul.h,v 1.2 2005/10/11 20:49:47 mbse Exp $ */
unsigned int atoul(char*);
#endif

96
mbfido/backalias.c Normal file
View File

@@ -0,0 +1,96 @@
/*****************************************************************************
*
* $Id: backalias.c,v 1.5 2004/02/21 17:22:01 mbroek Exp $
* Purpose ...............: Alias functions.
*
*****************************************************************************
* 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 "backalias.h"
static struct aliaslist {
struct aliaslist *next;
faddr *addr;
char *alias;
} *alist = NULL;
char *backalias(faddr *fa)
{
struct aliaslist *tmp;
for (tmp = alist; tmp; tmp = tmp->next)
if ((!fa->domain || !tmp->addr->domain || !strcasecmp(fa->domain,tmp->addr->domain)) &&
(!fa->zone || (fa->zone == tmp->addr->zone)) && (fa->net == tmp->addr->net) &&
(fa->node == tmp->addr->node) && (fa->point == tmp->addr->point) && (fa->name) &&
(tmp->addr->name) && (strcasecmp(fa->name,tmp->addr->name) == 0)) {
Syslog('m', "Address \"%s\" has local alias \"%s\"", ascinode(fa,0x7f), MBSE_SS(tmp->alias));
return tmp->alias;
}
return NULL;
}
void readalias(char *fn)
{
FILE *fp;
char buf[256], *k, *v;
struct aliaslist *tmp = NULL;
faddr *ta = NULL;
if ((fp = fopen(fn,"r")) == NULL) {
WriteError("$cannot open system alias file %s", MBSE_SS(fn));
return;
}
while (fgets(buf, sizeof(buf)-1, fp)) {
k = strtok(buf, " \t:");
v = strtok(NULL, " \t\n\r\0:");
if (k && v)
if ((ta = parsefaddr(v))) {
if (alist) {
tmp->next = (struct aliaslist *) xmalloc(sizeof(struct aliaslist));
tmp = tmp->next;
} else {
alist = (struct aliaslist *) xmalloc(sizeof(struct aliaslist));
tmp = alist;
}
tmp->next = NULL;
tmp->addr = ta;
ta = NULL;
tmp->alias = xstrcpy(k);
}
}
fclose(fp);
}

8
mbfido/backalias.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef _BACKALIAS_H
#define _BACKALIAS_H
char *backalias(faddr *);
void readalias(char *);
#endif

139
mbfido/bounce.c Normal file
View File

@@ -0,0 +1,139 @@
/*****************************************************************************
*
* $Id: bounce.c,v 1.11 2005/10/11 20:49:47 mbse Exp $
* Purpose ...............: Bounce Netmail
*
*****************************************************************************
* 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 "sendmail.h"
#include "postnetmail.h"
#include "ping.h"
/*
* External declarations
*/
extern int do_quiet;
/*
* Global variables
*/
extern int net_in; /* Netmails received */
extern int net_out; /* Netmails forwarded */
extern int net_bad; /* Bad netmails (tracking errors */
extern char *msgid; /* Original message id */
int Bounce(faddr *f, faddr *t, FILE *fp, char *reason)
{
int rc = 0, count = 0;
char *Buf;
FILE *np;
time_t Now;
faddr *from;
Now = time(NULL);
if (SearchFidonet(f->zone))
f->domain = xstrcpy(fidonet.domain);
Syslog('+', "Bounce msg from %s", ascfnode(f, 0xff));
Buf = calloc(MAX_LINE_LENGTH +1, sizeof(char));
rewind(fp);
np = tmpfile();
from = bestaka_s(f);
from->zone = t->zone;
from->net = t->net;
from->node = t->node;
from->point = t->point;
from->name = xstrcpy((char *)"Postmaster");
if (f->point)
fprintf(np, "\001TOPT %d\r", f->point);
if (from->point)
fprintf(np, "\001FMPT %d\r", from->point);
fprintf(np, "\001INTL %d:%d/%d %d:%d/%d\r", f->zone, f->net, f->node, from->zone, from->net, from->node);
/*
* Add MSGID, REPLY and PID
*/
fprintf(np, "\001MSGID: %s %08x\r", ascfnode(from, 0x1f), sequencer());
while ((fgets(Buf, MAX_LINE_LENGTH, fp)) != NULL) {
Striplf(Buf);
if (strncmp(Buf, "\001MSGID:", 7) == 0) {
fprintf(np, "\001REPLY:%s\r", Buf+7);
}
}
fprintf(np, "\001PID: MBSE-FIDO %s (%s-%s)\r", VERSION, OsName(), OsCPU());
fprintf(np, "\001TZUTC: %s\r", gmtoffset(Now));
fprintf(np, " Dear %s\r\r", MBSE_SS(f->name));
fprintf(np, "Your message could not be delevered, reason: %s\r\r", reason);
fprintf(np, "Here are the first lines of the original message from you:\r\r");
fprintf(np, "======================================================================\r");
rewind(fp);
while ((fgets(Buf, MAX_LINE_LENGTH, fp)) != NULL) {
Striplf(Buf);
if (Buf[0] == '\001') {
fprintf(np, "^a");
fwrite(Buf + 1, strlen(Buf) -1, 1, np);
} else {
fwrite(Buf, strlen(Buf), 1, np);
}
fputc('\r', np);
count++;
if (count == 50)
break;
}
fprintf(np, "======================================================================\r");
if (count == 50) {
fprintf(np, "\rOnly the first 50 lines are displayed\r");
}
fprintf(np, "\rWith regards, %s\r\r", CFG.sysop_name);
fprintf(np, "%s\r", TearLine());
Now = time(NULL) - (gmt_offset((time_t)0) * 60);
rc = postnetmail(np, from, f, NULL, (char *)"Bounced message", Now, 0x0000, FALSE, from->zone, f->zone);
tidy_faddr(from);
fclose(np);
free(Buf);
return rc;
}

9
mbfido/bounce.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _BOUNCEMGR_H
#define _BOUNCEMGR_H
int Bounce(faddr *, faddr *, FILE *, char *);
#endif

114
mbfido/bwrite.c Normal file
View File

@@ -0,0 +1,114 @@
/*****************************************************************************
*
* $Id: bwrite.c,v 1.6 2005/10/11 20:49:47 mbse Exp $
* Purpose ...............: MBSE BBS Mail Gate
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "bwrite.h"
/* ### Modified by P.Saratxaga on 29 Oct 1995 ###
* - deleted transcodage (outtab & intab) code (now transcodage is done by
* strconv() function.
*/
/*
* write short (16bit) integer in "standart" byte order
*/
int iwrite(int i, FILE *fp)
{
putc(i & 0xff,fp);
putc((i >> 8) & 0xff,fp);
return 0;
}
/*
* write 32bit integer in "standart" byte order
*/
int lwrite(int i, FILE *fp)
{
int c;
for (c = 0; c < 32; c += 8)
putc((i >> c) & 0xff,fp);
return 0;
}
int awrite(char *s, FILE *fp)
{
if (s)
while (*s)
putc(*(s++), fp);
putc(0,fp);
return 0;
}
/*
* write an arbitrary line to message body: change \n to \r,
*/
int cwrite(char *s, FILE *fp, int postlocal)
{
while (*s) {
if ((*s == '\n') && !postlocal)
putc('\r',fp);
else if ((*s == '\r') && postlocal)
putc('\n',fp);
else
putc(*s, fp);
s++;
}
return 0;
}
/*
* write (multiline) header to kluge: change \n to ' ' and end line with \r
*/
int kwrite(char *s, FILE *fp, int postlocal)
{
while (*s) {
if (*s != '\n')
putc(*s, fp);
else if (*(s+1))
putc(' ',fp);
s++;
}
if (postlocal)
putc('\n',fp);
else
putc('\r',fp);
return 0;
}

12
mbfido/bwrite.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _BWRITE_H
#define _BWRITE_H
/* $Id: bwrite.h,v 1.2 2005/10/11 20:49:47 mbse Exp $ */
int iwrite(int, FILE *);
int lwrite(int, FILE *);
int awrite(char *, FILE *);
int cwrite(char *, FILE *, int);
int kwrite(char *, FILE *, int);
#endif

394
mbfido/createf.c Normal file
View File

@@ -0,0 +1,394 @@
/*****************************************************************************
*
* $Id: createf.c,v 1.25 2005/10/11 20:49:47 mbse Exp $
* Purpose ...............: Create TIC Area and BBS file area.
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "mgrutil.h"
#include "createf.h"
#define MCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
int create_ticarea(char *farea, faddr *p_from)
{
char *temp;
FILE *gp;
Syslog('f', "create_ticarea(%s)", farea);
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/fgroups.data", getenv("MBSE_ROOT"));
if ((gp = fopen(temp, "r")) == NULL) {
WriteError("Can't open %s", temp);
free(temp);
return FALSE;
}
fread(&fgrouphdr, sizeof(fgrouphdr), 1, gp);
free(temp);
fseek(gp, fgrouphdr.hdrsize, SEEK_SET);
while ((fread(&fgroup, fgrouphdr.recsize, 1, gp)) == 1) {
if ((fgroup.UpLink.zone == p_from->zone) && (fgroup.UpLink.net == p_from->net) &&
(fgroup.UpLink.node == p_from->node) && (fgroup.UpLink.point == p_from->point) &&
strlen(fgroup.AreaFile)) {
if (CheckTicGroup(farea, FALSE, p_from) == 0) {
fclose(gp);
return TRUE;
}
}
}
fclose(gp);
return FALSE;
}
/*
* Check TIC group AREAS file if requested area exists.
* If so, create tic area and if SendUplink is TRUE,
* send the uplink a FileMgr request to connect this area.
* The tic group record (fgroup) must be in memory.
* Return codes:
* 0 - All Seems Well
* 1 - Some error
*
* The current nodes record may be destroyed after this,
* make sure it is saved.
*/
int CheckTicGroup(char *Area, int SendUplink, faddr *f)
{
char *temp, *buf, *tag = NULL, *desc = NULL, *p, *raid = NULL, *flow = NULL;
FILE *ap, *mp, *fp;
int offset, AreaNr;
int i, rc = 0, Found = FALSE;
sysconnect System;
faddr *From, *To;
struct _fdbarea *fdb_area = NULL;
temp = calloc(PATH_MAX, sizeof(char));
Syslog('f', "Checking file group \"%s\" \"%s\"", fgroup.Name, fgroup.Comment);
snprintf(temp, PATH_MAX, "%s/%s", CFG.alists_path , fgroup.AreaFile);
if ((ap = fopen(temp, "r")) == NULL) {
WriteError("Filegroup %s: area taglist %s not found", fgroup.Name, temp);
free(temp);
return 1;
}
buf = calloc(4097, sizeof(char));
if (fgroup.FileGate) {
/*
* filegate.zxx format
*/
while (fgets(buf, 4096, ap)) {
/*
* Each filegroup starts with "% FDN: Filegroup Description"
*/
if (strlen(buf) && !strncmp(buf, "% FDN:", 6)) {
tag = strtok(buf, "\t \r\n\0");
p = strtok(NULL, "\t \r\n\0");
p = strtok(NULL, "\r\n\0");
desc = p;
while ((*desc == ' ') || (*desc == '\t'))
desc++;
if (!strcmp(desc, fgroup.Comment)) {
while (fgets(buf, 4096, ap)) {
if (!strncasecmp(buf, "Area ", 5)) {
tag = strtok(buf, "\t \r\n\0");
tag = strtok(NULL, "\t \r\n\0");
if (!strcasecmp(tag, Area)) {
raid = strtok(NULL, "\t \r\n\0");
flow = strtok(NULL, "\t \r\n\0");
p = strtok(NULL, "\r\n\0");
desc = p;
while ((*desc == ' ') || (*desc == '\t'))
desc++;
Syslog('f', "Found area \"%s\" \"%s\" \"%s\" \"%s\"", tag, raid, flow, desc);
Found = TRUE;
break;
}
}
if (strlen(buf) && !strncmp(buf, "% FDN:", 6)) {
/*
* All entries in group are seen, the area wasn't there.
*/
break;
}
}
}
if (Found)
break;
}
}
} else {
/*
* Normal taglist format
*/
while (fgets(buf, 4096, ap)) {
if (strlen(buf) && isalnum(buf[0])) {
tag = strtok(buf, "\t \r\n\0");
p = strtok(NULL, "\r\n\0");
if (p == NULL)
p = tag; /* If no description after the TAG, use TAG as description */
desc = p;
while ((*desc == ' ') || (*desc == '\t'))
desc++;
if (strcasecmp(tag, Area) == 0) {
Syslog('f', "Found tag \"%s\" desc \"%s\"", tag, desc);
Found = TRUE;
break;
}
}
}
}
if (!Found) {
Syslog('f', "Area %s not found in taglist", Area);
free(buf);
fclose(ap);
free(temp);
return 1;
}
/*
* Some people write taglists with lowercase tagnames...
*/
for (i = 0; i < strlen(tag); i++)
tag[i] = toupper(tag[i]);
Syslog('m', "Found tag \"%s\" desc \"%s\"", tag, desc);
/*
* Area is in AREAS file, now create area.
* If needed, connect at uplink.
*/
if (SendUplink && SearchNode(fgroup.UpLink)) {
if (nodes.UplFmgrBbbs)
snprintf(temp, PATH_MAX, "file +%s", tag);
else
snprintf(temp, PATH_MAX, "+%s", tag);
From = fido2faddr(fgroup.UseAka);
To = fido2faddr(fgroup.UpLink);
if (UplinkRequest(To, From, TRUE, temp)) {
WriteError("Can't send netmail to uplink");
fclose(ap);
free(buf);
free(temp);
tidy_faddr(From);
tidy_faddr(To);
return 1;
}
tidy_faddr(From);
tidy_faddr(To);
}
/*
* Open tic area and set filepointer to the end to append
* a new record.
*/
snprintf(temp, PATH_MAX, "%s/etc/tic.data", getenv("MBSE_ROOT"));
if ((mp = fopen(temp, "r+")) == NULL) {
WriteError("$Can't open %s", temp);
fclose(ap);
free(buf);
free(temp);
return 1;
}
fread(&tichdr, sizeof(tichdr), 1, mp);
fseek(mp, 0, SEEK_END);
memset(&tic, 0, sizeof(tic));
Syslog('f', "TIC area open, filepos %ld", ftell(mp));
/*
* Open files area, and find a free slot
*/
snprintf(temp, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r+")) == NULL) {
WriteError("$Can't open %s", temp);
fclose(ap);
fclose(mp);
free(buf);
free(temp);
return 1;
}
fread(&areahdr, sizeof(areahdr), 1, fp);
Syslog('f', "File area is open");
/*
* Verify the file is large enough
*/
fseek(fp, 0, SEEK_END);
offset = areahdr.hdrsize + ((fgroup.StartArea -1) * (areahdr.recsize));
Syslog('+', "file end at %ld, offset needed %ld", ftell(fp), offset);
if (ftell(fp) < offset) {
Syslog('f', "Database too small, expanding...");
memset(&area, 0, sizeof(area));
while (TRUE) {
fwrite(&area, sizeof(area), 1, fp);
if (ftell(fp) >= areahdr.hdrsize + ((fgroup.StartArea -1) * (areahdr.recsize)))
break;
}
}
if (fseek(fp, offset, SEEK_SET)) {
WriteError("$Can't seek in %s to position %ld", temp, offset);
fclose(ap);
fclose(mp);
fclose(fp);
free(buf);
free(temp);
return 1;
}
/*
* Search a free record
*/
Syslog('f', "Start search record");
while (fread(&area, sizeof(area), 1, fp) == 1) {
if (!area.Available) {
fseek(fp, - areahdr.recsize, SEEK_CUR);
rc = 1;
break;
}
}
if (!rc) {
Syslog('f', "No free slot, append after last record");
fseek(fp, 0, SEEK_END);
if (ftell(fp) < areahdr.hdrsize + ((fgroup.StartArea -1) * (areahdr.recsize))) {
Syslog('f', "Database too small, expanding...");
memset(&area, 0, sizeof(area));
while (TRUE) {
fwrite(&area, sizeof(area), 1, fp);
if (ftell(fp) >= areahdr.hdrsize + ((fgroup.StartArea -1) * (areahdr.recsize)))
break;
}
}
rc = 1;
}
AreaNr = ((ftell(fp) - areahdr.hdrsize) / (areahdr.recsize)) + 1;
Syslog('f', "Found free slot at %ld", AreaNr);
/*
* Create the records
*/
memset(&area, 0, sizeof(area));
strncpy(area.Name, desc, 44);
strcpy(temp, tag);
temp = tl(temp);
for (i = 0; i < strlen(temp); i++)
if (temp[i] == '.')
temp[i] = '/';
snprintf(area.Path, 81, "%s/%s", fgroup.BasePath, temp);
area.DLSec = fgroup.DLSec;
area.UPSec = fgroup.UPSec;
area.LTSec = fgroup.LTSec;
area.New = area.Dupes = area.Free = area.AddAlpha = area.FileFind = area.Available = area.FileReq = TRUE;
strncpy(area.BbsGroup, fgroup.BbsGroup, 12);
strncpy(area.NewGroup, fgroup.AnnGroup, 12);
strncpy(area.Archiver, fgroup.Convert, 5);
area.Upload = fgroup.Upload;
fwrite(&area, sizeof(area), 1, fp);
fclose(fp);
/*
* Create download path
*/
snprintf(temp, PATH_MAX, "%s/foobar", area.Path);
if (!mkdirs(temp, 0775))
WriteError("Can't create %s", temp);
/*
* Create download database
*/
if ((fdb_area = mbsedb_OpenFDB(AreaNr, 30)))
mbsedb_CloseFDB(fdb_area);
/*
* Setup new TIC area.
*/
strncpy(tic.Name, tag, 20);
strncpy(tic.Comment, desc, 55);
tic.FileArea = AreaNr;
strncpy(tic.Group, fgroup.Name, 12);
tic.AreaStart = time(NULL);
tic.Aka = fgroup.UseAka;
strncpy(tic.Convert, fgroup.Convert, 5);
strncpy(tic.Banner, fgroup.Banner, 14);
tic.Replace = fgroup.Replace;
tic.DupCheck = fgroup.DupCheck;
tic.Secure = fgroup.Secure;
tic.Touch = fgroup.Touch;
tic.VirScan = fgroup.VirScan;
tic.Announce = fgroup.Announce;
tic.UpdMagic = fgroup.UpdMagic;
tic.FileId = fgroup.FileId;
tic.ConvertAll = fgroup.ConvertAll;
tic.SendOrg = fgroup.SendOrg;
tic.Active = TRUE;
tic.LinkSec.level = fgroup.LinkSec.level;
tic.LinkSec.flags = fgroup.LinkSec.flags;
tic.LinkSec.notflags = fgroup.LinkSec.notflags;
fwrite(&tic, sizeof(tic), 1, mp);
memset(&System, 0, sizeof(System));
System.aka = fgroup.UpLink;
if (flow && !strcmp(flow, "*&"))
/*
* Areas direction HQ's go the other way
*/
System.sendto = TRUE;
else
/*
* Normal distribution areas.
*/
System.receivefrom = TRUE;
fwrite(&System, sizeof(System), 1, mp);
memset(&System, 0, sizeof(System));
for (i = 1; i < (tichdr.syssize / sizeof(System)); i++)
fwrite(&System, sizeof(System), 1, mp);
fclose(mp);
fclose(ap);
free(buf);
free(temp);
if (f == NULL)
Mgrlog("Auto created TIC area %s, group %s, bbs area %ld", tic.Name, tic.Group, AreaNr);
else
Mgrlog("Auto created TIC area %s, group %s, bbs area %ld, for node %s",
tic.Name, tic.Group, AreaNr, ascfnode(f, 0x1f));
return 0;
}

12
mbfido/createf.h Normal file
View File

@@ -0,0 +1,12 @@
/* $Id: createf.h,v 1.2 2002/04/18 19:39:23 mbroek Exp $ */
#ifndef _CREATEH_H
#define _CREATEH_H
int create_ticarea(char *, faddr *);
int CheckTicGroup(char *, int, faddr *);
#endif

503
mbfido/createm.c Normal file
View File

@@ -0,0 +1,503 @@
/*****************************************************************************
*
* $Id: createm.c,v 1.32 2006/03/29 18:51:35 mbse Exp $
* Purpose ...............: Create Message Area
*
*****************************************************************************
* Copyright (C) 1997-2006
*
* 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/msg.h"
#include "../lib/users.h"
#include "../lib/mbsedb.h"
#include "mgrutil.h"
#include "createm.h"
#define MCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
extern int areas_changed;
int create_msgarea(char *marea, faddr *p_from)
{
char *temp;
FILE *gp;
Syslog('m', "create_msgarea(%s)", marea);
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/mgroups.data", getenv("MBSE_ROOT"));
if ((gp = fopen(temp, "r")) == NULL) {
WriteError("Can't open %s", temp);
free(temp);
return FALSE;
}
fread(&mgrouphdr, sizeof(mgrouphdr), 1, gp);
free(temp);
fseek(gp, mgrouphdr.hdrsize, SEEK_SET);
while ((fread(&mgroup, mgrouphdr.recsize, 1, gp)) == 1) {
if ((mgroup.UpLink.zone == p_from->zone) && (mgroup.UpLink.net == p_from->net) &&
(mgroup.UpLink.node == p_from->node) && (mgroup.UpLink.point == p_from->point) &&
strlen(mgroup.AreaFile)) {
if (CheckEchoGroup(marea, FALSE, p_from) == 0) {
fclose(gp);
return TRUE;
}
}
}
fclose(gp);
return FALSE;
}
/*
* Check echomail group AREAS file if requested area exists.
* If so, create echomail area and if SendUplink is TRUE,
* send the uplink a AreaMgr request to connect this area.
* The echomail group record (mgroup) must be in memory.
* Return codes:
* 0 - All Seems Well
* 1 - Some error
*
* The current nodes record may be destroyed after this,
* make sure it is saved.
*/
int CheckEchoGroup(char *Area, int SendUplink, faddr *f)
{
char *temp, *buf, *tag, *desc, *p;
FILE *ap, *mp;
int offset;
int i, rc = 0;
sysconnect System;
faddr *From, *To;
temp = calloc(PATH_MAX, sizeof(char));
Syslog('m', "Checking echogroup %s %s", mgroup.Name, mgroup.Comment);
snprintf(temp, PATH_MAX, "%s/%s", CFG.alists_path , mgroup.AreaFile);
if ((ap = fopen(temp, "r")) == NULL) {
WriteError("Echogroup %s: area taglist %s not found", mgroup.Name, temp);
free(temp);
return 1;
}
buf = calloc(4097, sizeof(char));
while (fgets(buf, 4096, ap)) {
if (strlen(buf) && isalnum(buf[0])) {
tag = strtok(buf, "\t \r\n\0");
p = strtok(NULL, "\r\n\0");
if (p == NULL)
p = tag; /* If no description after the TAG, use TAG as description */
desc = p;
while ((*desc == ' ') || (*desc == '\t'))
desc++;
if (strcasecmp(tag, Area) == 0) {
/*
* Make sure the tag is uppercase
*/
for (i = 0; i < strlen(tag); i++)
tag[i] = toupper(tag[i]);
Syslog('m', "Found tag \"%s\" desc \"%s\"", tag, desc);
/*
* Area is in AREAS file, now create area.
* If needed, connect at uplink.
*/
if (SendUplink && SearchNode(mgroup.UpLink)) {
if (nodes.UplAmgrBbbs)
snprintf(temp, PATH_MAX, "echo +%s", tag);
else
snprintf(temp, PATH_MAX, "+%s", tag);
From = fido2faddr(mgroup.UseAka);
To = fido2faddr(mgroup.UpLink);
if (UplinkRequest(To, From, FALSE, temp)) {
WriteError("Can't send netmail to uplink");
fclose(ap);
free(buf);
free(temp);
tidy_faddr(From);
tidy_faddr(To);
return 1;
}
tidy_faddr(From);
tidy_faddr(To);
}
snprintf(temp, PATH_MAX, "%s/etc/mareas.data", getenv("MBSE_ROOT"));
if ((mp = fopen(temp, "r+")) == NULL) {
WriteError("$Can't open %s", temp);
fclose(ap);
free(buf);
free(temp);
return 1;
}
fread(&msgshdr, sizeof(msgshdr), 1, mp);
/*
* Verify the file is large enough
*/
fseek(mp, 0, SEEK_END);
offset = msgshdr.hdrsize + ((mgroup.StartArea -1) * (msgshdr.recsize + msgshdr.syssize));
Syslog('m', "file end at %ld, start area offset at %ld", ftell(mp), offset);
if (ftell(mp) < offset) {
/*
* Start area record not in database, expand until start record exists.
*/
Syslog('m', "Database too small, expanding...");
memset(&msgs, 0, sizeof(msgs));
memset(&System, 0, sizeof(System));
while (TRUE) {
fwrite(&msgs, sizeof(msgs), 1, mp);
for (i = 0; i < (msgshdr.syssize / sizeof(System)); i++)
fwrite(&System, sizeof(System), 1, mp);
if (ftell(mp) >= msgshdr.hdrsize + ((mgroup.StartArea -1) * (msgshdr.recsize + msgshdr.syssize)))
break;
}
}
if (fseek(mp, offset, SEEK_SET)) {
WriteError("$Can't seek in %s to position %ld", temp, offset);
fclose(ap);
fclose(mp);
free(buf);
free(temp);
return 1;
}
/*
* Search a free record
*/
while (fread(&msgs, sizeof(msgs), 1, mp) == 1) {
if (!msgs.Active) {
fseek(mp, - msgshdr.recsize, SEEK_CUR);
offset = ((ftell(mp) - msgshdr.hdrsize) / (msgshdr.recsize + msgshdr.syssize)) + 1;
Syslog('m', "Found free slot at %ld", offset);
rc = 1;
break;
}
/*
* Skip systems
*/
fseek(mp, msgshdr.syssize, SEEK_CUR);
}
if (!rc) {
Syslog('m', "No free slot, append after last record");
fseek(mp, 0, SEEK_END);
if (ftell(mp) < msgshdr.hdrsize + ((mgroup.StartArea -1) * (msgshdr.recsize + msgshdr.syssize))) {
Syslog('m', "Database too small, expanding...");
memset(&msgs, 0, sizeof(msgs));
memset(&System, 0, sizeof(System));
while (TRUE) {
fwrite(&msgs, sizeof(msgs), 1, mp);
for (i = 0; i < (msgshdr.syssize / sizeof(System)); i++)
fwrite(&System, sizeof(System), 1, mp);
if (ftell(mp) >= msgshdr.hdrsize + ((mgroup.StartArea -1) * (msgshdr.recsize + msgshdr.syssize)))
break;
}
}
rc = 1;
}
/*
* Create the record with the defaults from the group record.
*/
offset = ((ftell(mp) - msgshdr.hdrsize) / (msgshdr.recsize + msgshdr.syssize)) + 1;
memset(&msgs, 0, sizeof(msgs));
strncpy(msgs.Tag, tag, 50);
strncpy(msgs.Name, desc, 40);
strncpy(msgs.QWKname, tag, 20);
msgs.MsgKinds = PUBLIC;
msgs.Type = ECHOMAIL;
msgs.DaysOld = CFG.defdays;
msgs.MaxMsgs = CFG.defmsgs;
msgs.UsrDelete = mgroup.UsrDelete;
msgs.RDSec = mgroup.RDSec;
msgs.WRSec = mgroup.WRSec;
msgs.SYSec = mgroup.SYSec;
msgs.LinkSec = mgroup.LinkSec;
strncpy(msgs.Group, mgroup.Name, 12);
msgs.Aka = mgroup.UseAka;
strncpy(msgs.Origin, CFG.origin, 50);
msgs.Aliases = mgroup.Aliases;
msgs.NetReply = mgroup.NetReply;
msgs.Active = TRUE;
msgs.Quotes = mgroup.Quotes;
msgs.Charset = mgroup.Charset;
msgs.MaxArticles = CFG.maxarticles;
msgs.Created = time(NULL);
tag = tl(tag);
for (i = 0; i < strlen(tag); i++)
if (tag[i] == '.')
tag[i] = '/';
snprintf(msgs.Base, 65, "%s/%s", mgroup.BasePath, tag);
snprintf(msgs.Newsgroup, 81, "%s.%s", GetFidoDomain(msgs.Aka.zone), tag);
for (i = 0; i < strlen(msgs.Newsgroup); i++) {
msgs.Newsgroup[i] = tolower(msgs.Newsgroup[i]);
if (msgs.Newsgroup[i] == '/')
msgs.Newsgroup[i] = '.';
if (msgs.Newsgroup[i] == '_')
msgs.Newsgroup[i] = '.';
}
fwrite(&msgs, sizeof(msgs), 1, mp);
mkdirs(msgs.Base, 0770);
if (Msg_Open(msgs.Base))
Msg_Close();
memset(&System, 0, sizeof(System));
System.aka = mgroup.UpLink;
System.sendto = System.receivefrom = TRUE;
fwrite(&System, sizeof(System), 1, mp);
memset(&System, 0, sizeof(System));
for (i = 1; i < (msgshdr.syssize / sizeof(System)); i++)
fwrite(&System, sizeof(System), 1, mp);
fclose(mp);
fclose(ap);
free(buf);
free(temp);
if (f == NULL)
Mgrlog("Auto created echo %s, group %s, area %ld", msgs.Tag, msgs.Group, offset);
else
Mgrlog("Auto created echo %s, group %s, area %ld, for node %s",
msgs.Tag, msgs.Group, offset, ascfnode(f , 0x1f));
areas_changed = TRUE;
return 0;
} /* if (strcmp(tag, Area) == 0) */
} /* if (strlen(buf) && isalnum(buf[0])) */
} /* while (fgets(buf, 4096, ap)) */
Syslog('m', "Area %s not found in taglist", Area);
free(buf);
fclose(ap);
free(temp);
return 1;
}
void msged_areas(FILE *fp)
{
char *temp, *aka;
FILE *no;
int i = 0;
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/mareas.data", getenv("MBSE_ROOT"));
if ((no = fopen(temp, "r")) == NULL) {
free(temp);
return;
}
fread(&msgshdr, sizeof(msgshdr), 1, no);
fseek(no, 0, SEEK_SET);
fread(&msgshdr, msgshdr.hdrsize, 1, no);
while (fread(&msgs, msgshdr.recsize, 1, no) == 1) {
i++;
if (msgs.Active) {
fprintf(fp, "Jam ");
switch (msgs.Type) {
case LOCALMAIL: fprintf(fp, "l"); break;
case NETMAIL: fprintf(fp, "mp"); break;
case ECHOMAIL: fprintf(fp, "e"); break;
case NEWS: fprintf(fp, "e"); break;
}
if (((msgs.Type == NEWS) || (msgs.Type == ECHOMAIL)) && strlen(msgs.Tag) && strlen(msgs.Newsgroup)) {
fprintf(fp, "u");
}
fprintf(fp, "8");
fprintf(fp, " \"%s\" %s", msgs.Name, msgs.Base);
if (msgs.Type == ECHOMAIL)
fprintf(fp, " %s", msgs.Tag);
if (msgs.Type != LOCALMAIL) {
aka = xstrcpy(strtok(aka2str(msgs.Aka), "@"));
fprintf(fp, " %s", aka);
free(aka);
}
fprintf(fp, "\n");
}
fseek(no, msgshdr.syssize, SEEK_CUR);
}
fclose(no);
free(temp);
}
void gold_areas(FILE *fp)
{
char *temp, *aka, groupid[13];
FILE *no, *fil;
int i = 0;
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/mareas.data", getenv("MBSE_ROOT"));
if ((no = fopen(temp, "r")) == NULL) {
free(temp);
return;
}
fread(&msgshdr, sizeof(msgshdr), 1, no);
fseek(no, 0, SEEK_SET);
fread(&msgshdr, msgshdr.hdrsize, 1, no);
fprintf(fp, "; Message Areas\n;\n");
fprintf(fp, "AREASCAN *\n");
fprintf(fp, "AREATYPEORDER Net Email Echo News Local\n");
while (fread(&msgs, msgshdr.recsize, 1, no) == 1) {
i++;
if (msgs.Active) {
fprintf(fp, "AREADEF ");
if (strlen(msgs.Tag))
fprintf(fp, "%s", msgs.Tag);
else
fprintf(fp, "AREA%d", i);
fprintf(fp, " \"%s\" ", msgs.Name);
/*
* Set a default groupid
*/
switch (msgs.Type) {
case LOCALMAIL : snprintf(groupid, 13, "O"); break;
case NETMAIL : snprintf(groupid, 13, "N"); break;
case ECHOMAIL : snprintf(groupid, 13, "C"); break;
case NEWS : snprintf(groupid, 13, "I"); break;
}
/*
* Now try to find a real groupid
*/
if (((msgs.Type == ECHOMAIL) || (msgs.Type == NEWS)) && strlen(msgs.Group)) {
snprintf(temp, PATH_MAX, "%s/etc/mgroups.data", getenv("MBSE_ROOT"));
if ((fil = fopen(temp, "r")) != NULL) {
fread(&mgrouphdr, sizeof(mgrouphdr), 1, fil);
while (fread(&mgroup, mgrouphdr.recsize, 1, fil) == 1) {
if (mgroup.Active && !strcmp(msgs.Group, mgroup.Name) && mgroup.GoldEDgroup) {
snprintf(groupid, 13, "#%03d", mgroup.GoldEDgroup);
break;
}
}
fclose(fil);
}
}
fprintf(fp, "%s ", groupid);
switch (msgs.Type) {
case LOCALMAIL : fprintf(fp, "Local"); break;
case NETMAIL : fprintf(fp, "Net"); break;
case ECHOMAIL : fprintf(fp, "Echo"); break;
case NEWS : fprintf(fp, "News"); break;
}
aka = xstrcpy(strtok(aka2str(msgs.Aka), "@"));
fprintf(fp, " JAM %s %s ", msgs.Base, aka);
free(aka);
if (msgs.Type == NETMAIL)
fprintf(fp, "(Loc Pvt)");
else
fprintf(fp, "(Loc)");
fprintf(fp, " \"%s\"\n", msgs.Origin);
}
fseek(no, msgshdr.syssize, SEEK_CUR);
}
fclose(no);
free(temp);
fprintf(fp, "\n");
}
void gold_akamatch(FILE *fp)
{
char temp[PATH_MAX];
FILE *fido;
faddr *want, *ta;
int i;
snprintf(temp, PATH_MAX, "%s/etc/fidonet.data", getenv("MBSE_ROOT"));
if ((fido = fopen(temp, "r")) == NULL)
return;
fprintf(fp, "; AKA Matching\n;\n");
want = (faddr *)malloc(sizeof(faddr));
fread(&fidonethdr, sizeof(fidonethdr), 1, fido);
while ((fread(&fidonet, fidonethdr.recsize, 1, fido)) == 1) {
if (fidonet.available) {
for (i = 0; i < 6; i++) {
if (fidonet.zone[i]) {
want->zone = fidonet.zone[0];
want->net = 0;
want->node = 0;
want->point = 0;
want->name = NULL;
want->domain = NULL;
ta = bestaka_s(want);
fprintf(fp, "AKAMATCH %d:* %s\n", fidonet.zone[i], ascfnode(ta, 0xf));
tidy_faddr(ta);
}
}
}
}
free(want);
fprintf(fp, ";\n");
fprintf(fp, "AKAMATCHNET YES\n");
fprintf(fp, "AKAMATCHECHO YES\n");
fprintf(fp, "AKAMATCHLOCAL NO\n\n");
fprintf(fp, "; NODELISTS\n;\n");
fprintf(fp, "NODEPATH %s/\n", CFG.nodelists);
fseek(fido, fidonethdr.hdrsize, SEEK_SET);
while ((fread(&fidonet, fidonethdr.recsize, 1, fido)) == 1) {
if (fidonet.available) {
fprintf(fp, "NODELIST %s.*\n", fidonet.nodelist);
for (i = 0; i < 6; i++)
if (strlen(fidonet.seclist[i].nodelist) || fidonet.seclist[i].zone)
fprintf(fp, "NODELIST %s.*\n", fidonet.seclist[i].nodelist);
}
}
// fprintf(fp, "USERLIST golded.lst\n");
fprintf(fp, "LOOKUPNET YES\n");
fprintf(fp, "LOOKUPECHO NO\n");
fprintf(fp, "LOOKUPLOCAL NO\n\n");
fclose(fido);
}

14
mbfido/createm.h Normal file
View File

@@ -0,0 +1,14 @@
/* $Id: createm.h,v 1.4 2005/08/10 18:57:22 mbse Exp $ */
#ifndef _CREATEM_H
#define _CREATEM_H
int create_msgarea(char *, faddr *);
int CheckEchoGroup(char *, int, faddr *);
void msged_areas(FILE *);
void gold_areas(FILE *);
void gold_akamatch(FILE *);
#endif

150
mbfido/dirlock.c Normal file
View File

@@ -0,0 +1,150 @@
/*****************************************************************************
*
* $Id: dirlock.c,v 1.7 2005/08/28 15:33:23 mbse Exp $
* Purpose ...............: Lock mbfido processing.
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "flock.h"
#include "dirlock.h"
#define TMPNAME "TMP."
#define LCKNAME "LOCKFILE"
/*
* Put a lock on a directory.
*/
int lockdir(char *directory)
{
char *Tmpfile, *lockfile;
FILE *fp;
pid_t oldpid;
Tmpfile = calloc(PATH_MAX, sizeof(char));
lockfile = calloc(PATH_MAX, sizeof(char));
snprintf(Tmpfile, PATH_MAX, "%s/", directory);
strcpy(lockfile, Tmpfile);
snprintf(Tmpfile + strlen(Tmpfile), PATH_MAX, "%s%u", TMPNAME, getpid());
snprintf(lockfile + strlen(lockfile), PATH_MAX - strlen(lockfile), "%s", LCKNAME);
if ((fp = fopen(Tmpfile, "w")) == NULL) {
WriteError("$Can't create lockfile \"%s\"", Tmpfile);
free(Tmpfile);
free(lockfile);
return FALSE;
}
fprintf(fp, "%10u\n", getpid());
fclose(fp);
while (TRUE) {
if (link(Tmpfile, lockfile) == 0) {
unlink(Tmpfile);
free(Tmpfile);
free(lockfile);
return TRUE;
}
if ((fp = fopen(lockfile, "r")) == NULL) {
WriteError("$Can't open lockfile \"%s\"", Tmpfile);
unlink(Tmpfile);
free(Tmpfile);
free(lockfile);
return FALSE;
}
if (fscanf(fp, "%u", &oldpid) != 1) {
WriteError("$Can't read old pid from \"%s\"", Tmpfile);
fclose(fp);
unlink(Tmpfile);
free(Tmpfile);
free(lockfile);
return FALSE;
}
fclose(fp);
if (kill(oldpid,0) == -1) {
if (errno == ESRCH) {
Syslog('+', "Stale lock found for pid %u", oldpid);
unlink(lockfile);
/* no return, try lock again */
} else {
WriteError("$Kill for %u failed",oldpid);
unlink(Tmpfile);
free(Tmpfile);
free(lockfile);
return FALSE;
}
} else {
Syslog('+', "mbfido already running, pid=%u", oldpid);
unlink(Tmpfile);
free(Tmpfile);
free(lockfile);
return FALSE;
}
}
}
/*
* Unlock directory, make extra check to see if it is our own lock.
*/
void ulockdir(char *directory)
{
char *lockfile;
FILE *fp;
pid_t oldpid;
lockfile = calloc(PATH_MAX, sizeof(char));
snprintf(lockfile, PATH_MAX, "%s/", directory);
snprintf(lockfile + strlen(lockfile), PATH_MAX - strlen(lockfile), "%s", LCKNAME);
if ((fp = fopen(lockfile, "r")) == NULL) {
/*
* No lockfile found, so not removed.
*/
free(lockfile);
return;
}
if (fscanf(fp, "%u", &oldpid) != 1) {
WriteError("$Can't read old pid from \"%s\"", lockfile);
} else {
if (getpid() != oldpid) {
WriteError("Attempt to remove lock %s of pid %d", lockfile, oldpid);
} else {
/*
* Only remove our own lock.
*/
unlink(lockfile);
}
}
fclose(fp);
free(lockfile);
}

7
mbfido/dirlock.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef _DIRLOCK_H
#define _DIRLOCK_H
int lockdir(char *);
void ulockdir(char *);
#endif

220
mbfido/dirsession.c Normal file
View File

@@ -0,0 +1,220 @@
/*****************************************************************************
*
* $Id: dirsession.c,v 1.10 2005/10/11 20:49:47 mbse Exp $
* Purpose ...............: Directory Mail/Files sessions
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "dirsession.h"
extern int do_unprot;
/*
* Check for lock, return TRUE if node is locked.
*/
int islocked(char *lockfile, int chklck, int waitclr, int loglvl)
{
int i;
time_t now, ftime;
if (chklck && strlen(lockfile)) {
Syslog(loglvl, "Checking lockfile %s", lockfile);
/*
* First check for stale lockfile.
*/
if (! file_exist(lockfile, R_OK)) {
ftime = file_time(lockfile);
now = time(NULL);
if ((now - ftime) > 21600) {
Syslog('+', "Removing stale lockfile %s, older then 6 hours", lockfile);
file_rm(lockfile);
}
}
/*
* Next check for lockfile with wait for clear
*/
if ((file_exist(lockfile, R_OK) == 0) && waitclr) {
Syslog('+', "Node is locked, waiting 10 minutes");
i = 120;
while (TRUE) {
sleep(5);
Nopper();
if (file_exist(lockfile, R_OK))
break;
i--;
if (i == 0) {
Syslog('+', "Timeout waiting for lock %s", lockfile);
break;
}
}
}
/*
* Check again if lockfile exists.
*/
if (file_exist(lockfile, R_OK)) {
return FALSE;
} else {
Syslog('+', "Lockfile exists, skipping this node");
return TRUE;
}
}
return FALSE;
}
/*
* Create a 1 byte lockfile if create is TRUE.
* Returns FALSE if failed.
*/
int setlock(char *lockfile, int create, int loglvl)
{
FILE *fp;
char temp[1];
if (create && strlen(lockfile)) {
Syslog(loglvl, "create lockfile %s", lockfile);
if ((fp = fopen(lockfile, "w")) == NULL) {
WriteError("$Can't create lock %s", lockfile);
return FALSE;
}
fwrite(temp, 1, sizeof(char), fp);
fsync(fileno(fp));
fclose(fp);
chmod(lockfile, 0664);
}
return TRUE;
}
/*
* Removing lockfile
*/
void remlock(char *lockfile, int create, int loglvl)
{
if (create) {
if (file_rm(lockfile))
WriteError("$Can't remove lock %s", lockfile);
else
Syslog(loglvl, "Removed lock %s", lockfile);
}
}
/*
* Process directory inbound. Return TRUE if something is moved
* to the inbound for processing.
*/
int dirinbound(void)
{
FILE *fp;
char *temp, *from, *too;
int fileptr;
struct dirent *de;
DIR *dp;
int Something = FALSE;
Syslog('m', "Starting directory inbound sessions");
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/nodes.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r")) != NULL) {
fread(&nodeshdr, sizeof(nodeshdr), 1, fp);
while (fread(&nodes, nodeshdr.recsize, 1, fp) == 1) {
if (nodes.Session_in == S_DIR && strlen(nodes.Dir_in_path)) {
fileptr = ftell(fp) - nodeshdr.recsize;
Syslog('+', "Directory inbound session for node %s", aka2str(nodes.Aka[0]));
if (! islocked(nodes.Dir_in_clock, nodes.Dir_in_chklck, nodes.Dir_in_waitclr, 'm')) {
Syslog('m', "Node is free, start processing");
setlock(nodes.Dir_in_mlock, nodes.Dir_in_mklck, 'm');
if ((dp = opendir(nodes.Dir_in_path)) == NULL) {
WriteError("$Can't open directory %s", nodes.Dir_in_path);
} else {
from = calloc(PATH_MAX, sizeof(char));
too = calloc(PATH_MAX, sizeof(char));
while ((de = readdir(dp))) {
if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {
snprintf(from, PATH_MAX, "%s/%s", nodes.Dir_in_path, de->d_name);
if (access(from, R_OK | W_OK)) {
WriteError("$No rights to move %s", from);
} else {
/*
* Inbound is set by previous toss or tic to
* protected or unprotected inbound.
*/
if (do_unprot)
snprintf(too, PATH_MAX, "%s/%s", CFG.inbound, de->d_name);
else
snprintf(too, PATH_MAX, "%s/%s", CFG.pinbound, de->d_name);
if (access(too, F_OK) == 0) {
WriteError("File %s already in inbound, skip", too);
} else {
Syslog('m', "Move %s to %s", from, too);
if (file_mv(from, too)) {
WriteError("$Move %s to %s failed", from, too);
} else {
Something = TRUE;
Syslog('+', "Moved \"%s\" to %s", de->d_name, do_unprot ? CFG.inbound : CFG.pinbound);
}
}
}
}
}
free(too);
free(from);
}
remlock(nodes.Dir_in_mlock, nodes.Dir_in_mklck, 'm');
}
/*
* Reread noderecord
*/
fseek(fp, fileptr, SEEK_SET);
fread(&nodes, nodeshdr.recsize, 1, fp);
}
fseek(fp, nodeshdr.filegrp + nodeshdr.mailgrp, SEEK_CUR);
}
fclose(fp);
}
free(temp);
Syslog('m', "Finished directory inbound sessions");
return Something;
}

12
mbfido/dirsession.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _DIRSESSION_H
#define _DIRSESSION_H
/* $Id: dirsession.h,v 1.4 2002/11/11 12:56:19 mbroek Exp $ */
int islocked(char *, int, int, int); /* Is directory locked */
int setlock(char *, int, int); /* Lock directory */
void remlock(char *, int, int); /* Unlock directory */
int dirinbound(void); /* Process nodes */
#endif

147
mbfido/fflist.c Normal file
View File

@@ -0,0 +1,147 @@
/*****************************************************************************
*
* $Id: fflist.c,v 1.8 2007/10/15 12:48:11 mbse Exp $
* Purpose ...............: Announce new files and FileFind
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* Michiel Broek FIDO: 2:2801/16
* Beekmansbos 10 Internet: mbroek@ux123.pttnwb.nl
* 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/msg.h"
#include "fflist.h"
/*
* Tidy the filefind array
*/
void tidy_fflist(ff_list ** fdp)
{
ff_list *tmp, *old;
for (tmp = *fdp; tmp; tmp = old) {
old = tmp->next;
free(tmp);
}
*fdp = NULL;
}
/*
* Add a search record to the array
*/
void fill_fflist(ff_list **fdp)
{
char *b;
ff_list *tmp, *ta;
b = calloc(44, sizeof(char));
snprintf(b, 44, "%s~", Msg.FromAddress);
/*
* Add a new record
*/
tmp = (ff_list *)malloc(sizeof(ff_list));
tmp->next = NULL;
snprintf(tmp->from, 36, "%s", Msg.From);
snprintf(tmp->subject, 72, "%s", Msg.Subject);
if (strchr(b, '.') == NULL) {
tmp->zone = atoi(strtok(b, ":"));
tmp->net = atoi(strtok(NULL, "/"));
tmp->node = atoi(strtok(NULL, "~"));
} else {
tmp->zone = atoi(strtok(b, ":"));
tmp->net = atoi(strtok(NULL, "/"));
tmp->node = atoi(strtok(NULL, "."));
tmp->point = atoi(strtok(NULL, "~"));
}
snprintf(tmp->msgid, 81, "%s", Msg.Msgid);
tmp->msgnr = Msg.Id;
tmp->done = FALSE;
/*
* New record goes at the end.
*/
if (*fdp == NULL)
*fdp = tmp;
else
for (ta = *fdp; ta; ta = ta->next)
if (ta->next == NULL) {
ta->next = (ff_list *)tmp;
break;
}
free(b);
}
/*
* Tidy the reply files array
*/
void tidy_rflist(rf_list ** fdp)
{
rf_list *tmp, *old;
for (tmp = *fdp; tmp; tmp = old) {
old = tmp->next;
free(tmp);
}
*fdp = NULL;
}
/*
* Add a reply file to the array
*/
void fill_rflist(rf_list **fdp, char *fname, unsigned int larea)
{
rf_list *tmp, *ta;
/*
* Add a new record
*/
tmp = (rf_list *)malloc(sizeof(rf_list));
tmp->next = NULL;
snprintf(tmp->filename, 80, "%s", fname);
tmp->area = larea;
/*
* New record goes at the end.
*/
if (*fdp == NULL)
*fdp = tmp;
else
for (ta = *fdp; ta; ta = ta->next)
if (ta->next == NULL) {
ta->next = (rf_list *)tmp;
break;
}
}

34
mbfido/fflist.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef _FFLIST_H_
#define _FFLIST_H
/* $Id: fflist.h,v 1.3 2007/10/15 12:48:11 mbse Exp $ */
typedef struct _ff_list { /* Filefind array */
struct _ff_list *next;
char from[36]; /* From username */
char subject[72]; /* Search parameters */
unsigned short zone; /* Original zone */
unsigned short net; /* Original net */
unsigned short node; /* Original node */
unsigned short point; /* Original point */
char msgid[81]; /* Original msgid */
unsigned int msgnr; /* Original message number */
unsigned done : 1; /* True if processed with success */
} ff_list;
typedef struct _rf_list { /* Reply filenames array */
struct _rf_list *next;
char filename[81]; /* Filename found */
unsigned int area; /* BBS file area number */
} rf_list;
void tidy_fflist(ff_list **);
void fill_fflist(ff_list **);
void tidy_rflist(rf_list **);
void fill_rflist(rf_list **, char *, unsigned int);
#endif

530
mbfido/filefind.c Normal file
View File

@@ -0,0 +1,530 @@
/*****************************************************************************
*
* $Id: filefind.c,v 1.26 2007/10/15 12:48:11 mbse Exp $
* Purpose ...............: Announce new files and FileFind
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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 "../lib/msg.h"
#include "../lib/msgtext.h"
#include "../lib/diesel.h"
#include "fflist.h"
#include "filefind.h"
#include "msgutil.h"
/*
* The next constants are to prevent overflowing the echomail areas
* with huge replies. MAX_DESC_LINES limits the number of file description
* lines, 5 should be enough. The other two are the maximum files to report
* if in the same area or different area.
* For netmail replies there is a different limit.
*/
#define MAX_DESC_LINES 5
#define MAX_FILES_SAMEBOARD 25
#define MAX_FILES_OTHERBOARD 50
#define MAX_FILES_NETMAIL 100
extern int do_quiet; /* Suppress screen output */
struct _filerecord T_File; /* Internal announce record */
int Requests = 0; /* Total found request */
int Replies = 0; /* Total generated replies */
void Back(int);
void Back(int count)
{
int i;
if (do_quiet)
return;
for (i = 0; i < count; i++)
printf("\b");
fflush(stdout);
}
void Clean(int);
void Clean(int count)
{
int i;
if (do_quiet)
return;
for (i = 0; i < count; i++)
printf(" ");
Back(count);
}
void ScanArea(ff_list **);
void ScanArea(ff_list **ffl)
{
unsigned int Number, Highest;
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("\r %-40s", scanmgr.Comment);
mbse_colour(LIGHTRED, BLACK);
printf(" (Scanning) ");
mbse_colour(LIGHTMAGENTA, BLACK);
fflush(stdout);
}
Syslog('+', "Scanning %s", scanmgr.Comment);
if (Msg_Open(scanmgr.ScanBoard)) {
Number = Msg_Lowest();
Highest = Msg_Highest();
do {
if (!do_quiet) {
printf("%6u / %6u", Number, Highest);
Back(15);
}
if (CFG.slow_util && do_quiet)
msleep(1);
if (Msg_ReadHeader(Number) == TRUE) {
if (((!strcasecmp(Msg.To, "allfix")) || (!strcasecmp(Msg.To, "filefind"))) && (!Msg.Received)) {
Syslog('m', "Msg: %s (%u) [%s]", Msg.From, Number, Msg.Subject);
Msg.Received = TRUE;
Msg.Read = time(NULL);
if (Msg_Lock(30L)) {
Msg_WriteHeader(Number);
Msg_UnLock();
Syslog('m', "Marked message received");
}
if (strlen(Msg.Subject) && strlen(Msg.FromAddress)) {
fill_fflist(ffl);
Requests++;
}
}
}
} while (Msg_Next(&Number) == TRUE);
Msg_Close();
Clean(15);
} else
WriteError("$Can't open %s", scanmgr.ScanBoard);
Back(54);
Clean(54);
}
int StartReply(ff_list *);
int StartReply(ff_list *ffl)
{
char *temp;
unsigned int crc = -1;
if (strlen(scanmgr.ReplBoard)) {
if (!Msg_Open(scanmgr.ReplBoard))
return -1;
else
CountPosted(scanmgr.ReplBoard);
} else {
if (!Msg_Open(scanmgr.ScanBoard))
return -1;
else
CountPosted(scanmgr.ScanBoard);
}
if (!Msg_Lock(30L)) {
Msg_Close();
return -1;
}
Msg_New();
chartran_init((char *)"CP437", get_ic_ftn(scanmgr.charset), 'f');
temp = calloc(PATH_MAX, sizeof(char));
snprintf(Msg.From, 101, "%s", CFG.sysop_name);
snprintf(Msg.To, 101, "%s", chartran(ffl->from));
snprintf(Msg.Subject, 101, "Re: %s", chartran(ffl->subject));
snprintf(Msg.FromAddress, 101, "%s", aka2str(scanmgr.Aka));
Msg.Written = time(NULL);
Msg.Arrived = time(NULL);
Msg.Local = TRUE;
if (scanmgr.NetReply){
Msg.Netmail = TRUE;
snprintf(Msg.ToAddress, 101, "%d:%d/%d.%d", ffl->zone, ffl->net, ffl->node, ffl->point);
Msg.Private = TRUE;
} else
Msg.Echomail = TRUE;
/*
* Start message text including kludges
*/
Msg_Id(scanmgr.Aka);
snprintf(temp, PATH_MAX, "\001REPLY: %s", ffl->msgid);
MsgText_Add2(temp);
Msg.ReplyCRC = upd_crc32(temp, crc, strlen(temp));
free(temp);
Msg_Pid(scanmgr.charset);
return Msg_Top(scanmgr.template, scanmgr.Language, scanmgr.Aka);
}
void FinishReply(int, int, int);
void FinishReply(int Reported, int Total, int filepos)
{
char *temp;
FILE *fp, *fi;
temp = calloc(PATH_MAX, sizeof(char));
if ((fi = OpenMacro(scanmgr.template, scanmgr.Language, FALSE)) != NULL) {
MacroVars("CD", "dd", Reported, Total);
fseek(fi, filepos, SEEK_SET);
Msg_Macro(fi);
fclose(fi);
MacroClear();
}
if (strlen(scanmgr.Origin))
Msg_Bot(scanmgr.Aka, scanmgr.Origin, scanmgr.template);
else
Msg_Bot(scanmgr.Aka, CFG.origin, scanmgr.template);
Msg_AddMsg();
Msg_UnLock();
Syslog('+', "Posted message %ld", Msg.Id);
chartran_close();
snprintf(temp, PATH_MAX, "%s/tmp/%smail.jam", getenv("MBSE_ROOT"), scanmgr.NetReply?"net":"echo");
if ((fp = fopen(temp, "a")) != NULL) {
if (strlen(scanmgr.ReplBoard))
fprintf(fp, "%s %u\n", scanmgr.ReplBoard, Msg.Id);
else
fprintf(fp, "%s %u\n", scanmgr.ScanBoard, Msg.Id);
fclose(fp);
}
Msg_Close();
free(temp);
}
/*
* Scan for files for one request.
*/
void ScanFiles(ff_list *);
void ScanFiles(ff_list *tmp)
{
char *temp, *kwd, *BigDesc, *line;
FILE *pAreas, *fi;
unsigned int areanr = 0, found = 0, SubSize = 0;
int i, j, k, keywrd, Found;
rf_list *rfl = NULL, *rft;
int Rep = 0, Sub = 0, Stop = FALSE;
int filepos, filepos1 = 0, filepos2 = 0, filepos3 = 0, filepos4 = 0;
struct _fdbarea *fdb_area = NULL;
kwd = calloc(81, sizeof(char));
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s (%d:%d/%d.%d)", tmp->from, tmp->zone, tmp->net, tmp->node, tmp->point);
Syslog('+', "Search [%s] for %s", tmp->subject, temp);
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
temp[40] = '\0';
printf("\r %-40s", temp);
mbse_colour(LIGHTRED, BLACK);
printf(" (Searching)");
mbse_colour(LIGHTMAGENTA, BLACK);
fflush(stdout);
}
snprintf(temp, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen(temp, "r")) != NULL) {
fread(&areahdr, sizeof(areahdr), 1, pAreas);
while (fread(&area, areahdr.recsize, 1, pAreas) == 1) {
areanr++;
Nopper();
if (CFG.slow_util && do_quiet)
msleep(1);
if (!do_quiet) {
printf("%6u / %6u", areanr, found);
Back(15);
}
if (area.Available && area.FileFind) {
if ((fdb_area = mbsedb_OpenFDB(areanr, 30))) {
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
BigDesc = xstrcpy((char *)"");
for (i = 0; i < 25; i++)
BigDesc = xstrcat(BigDesc, fdb.Desc[i]);
snprintf(temp, PATH_MAX, "%s", tmp->subject);
Found = FALSE;
while (strlen(temp) && (!Found)) {
/*
* Split the search request in separate words.
*/
k = strlen(temp);
for (i = 0; i < k; i++)
if (temp[i] == ' ')
break;
if (i < k) {
strncpy(kwd, temp, i);
kwd[i] = '\0';
for (j = 0; j < (k - i -1); j++)
temp[j] = temp[j+i+1];
temp[j] = '\0';
} else {
snprintf(kwd, 80, "%s", temp);
temp[0] = '\0';
}
/*
* Check if it's a filename search or a keyword search.
*/
keywrd = FALSE;
if ((kwd[0] == '/') || (kwd[0] == '\\')) {
keywrd = TRUE;
for (i = 1; i < strlen(kwd); i++)
kwd[i-1] = kwd[i];
kwd[i-1] = '\0';
}
if (strlen(kwd) > scanmgr.keywordlen) {
if ((strcasestr(fdb.Name, kwd) != NULL) || (strcasestr(fdb.LName, kwd) != NULL)) {
Found = TRUE;
Syslog('m', " Found '%s' in %s in filename", kwd, fdb.LName);
}
if (keywrd && (strcasestr(BigDesc, kwd) != NULL)) {
Found = TRUE;
Syslog('m', " Found '%s' in %s in description", kwd, fdb.LName);
}
}
} /* while (strlen(temp) && (!Found)) */
if (Found) {
found++;
Syslog('+', " Found %s in area %d", fdb.LName, areanr);
fill_rflist(&rfl, fdb.LName, areanr);
}
free(BigDesc);
BigDesc = NULL;
}
mbsedb_CloseFDB(fdb_area);
} else
WriteError("$Can't open %s", temp);
}
}
fclose(pAreas);
Clean(15);
} else
WriteError("$Can't open %s", temp);
Back(12);
Clean(12);
if (found) {
if (!do_quiet) {
mbse_colour(YELLOW, BLACK);
printf(" (Replying)");
fflush(stdout);
}
if (((filepos = StartReply(tmp)) != -1) && ((fi = OpenMacro(scanmgr.template, scanmgr.Language, FALSE)) != NULL)) {
areanr = 0;
snprintf(temp, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen(temp, "r")) != NULL) {
fread(&areahdr, sizeof(areahdr), 1, pAreas);
for (rft = rfl; rft; rft = rft->next) {
/*
* Area footer
*/
if ((areanr != rft->area) && (Sub)) {
fseek(fi, filepos3, SEEK_SET);
MacroVars("AB", "dd", Sub, SubSize / 1024);
Msg_Macro(fi);
filepos4 = ftell(fi);
Sub = 0;
SubSize = 0;
}
/*
* New area header
*/
if (areanr != rft->area) {
fseek(pAreas, ((rft->area - 1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&area, areahdr.recsize, 1, pAreas);
MacroVars("GJ", "ds", rft->area, area.Name);
fseek(fi, filepos, SEEK_SET);
Msg_Macro(fi);
filepos1 = ftell(fi);
areanr = rft->area;
}
Syslog('m', "rp: %d %s", rft->area, rft->filename);
if ((fdb_area = mbsedb_OpenFDB(rft->area, 30))) {
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1)
if (!strcmp(rft->filename, fdb.LName))
break;
mbsedb_CloseFDB(fdb_area);
MacroVars("slbkdt", "ssddss", fdb.Name, fdb.LName, fdb.Size, fdb.Size / 1024, " ",
chartran(fdb.Desc[0]));
fseek(fi, filepos1, SEEK_SET);
Msg_Macro(fi);
filepos2 = ftell(fi);
SubSize += fdb.Size;
/*
* We add no more then 5 description lines
* to prevent unnecesary long messages.
*/
for (i = 1; i < MAX_DESC_LINES; i++) {
MacroVars("t", "s", chartran(fdb.Desc[i]));
fseek(fi, filepos2, SEEK_SET);
if (strlen(fdb.Desc[i])) {
Msg_Macro(fi);
} else {
line = calloc(255, sizeof(char));
while ((fgets(line, 254, fi) != NULL) && ((line[0]!='@') || (line[1]!='|'))) {}
free(line);
}
filepos3 = ftell(fi);
}
}
Rep++;
Sub++;
if (!scanmgr.NetReply) {
if (strlen(scanmgr.ReplBoard)) {
if (Rep >= MAX_FILES_OTHERBOARD)
Stop = TRUE;
} else {
if (Rep >= MAX_FILES_SAMEBOARD)
Stop = TRUE;
}
} else {
if (Rep >= MAX_FILES_NETMAIL)
Stop = TRUE;
}
if (Stop)
break;
}
if (Sub) {
fseek(fi, filepos3, SEEK_SET);
MacroVars("AB", "dd", Sub, SubSize / 1024);
Msg_Macro(fi);
filepos4 = ftell(fi);
}
fclose(pAreas);
}
FinishReply(Rep, found, filepos4);
Replies++;
}
Back(11);
Clean(11);
}
Back(42);
Clean(42);
tidy_rflist(&rfl);
free(BigDesc);
free(temp);
free(kwd);
}
int Filefind()
{
char *temp;
int rc = FALSE;
FILE *fp;
ff_list *ffl = NULL, *tmp;
IsDoing("FileFind");
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("Processing FileFind requests\n");
}
Syslog('+', "Processing FileFind requests");
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/scanmgr.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r")) == NULL) {
WriteError("$Can't open %s", temp);
free(temp);
return FALSE;
}
fread(&scanmgrhdr, sizeof(scanmgrhdr), 1, fp);
while (fread(&scanmgr, scanmgrhdr.recsize, 1, fp) == 1) {
if (scanmgr.Active) {
ScanArea(&ffl);
Nopper();
for (tmp = ffl; tmp; tmp = tmp->next) {
ScanFiles(tmp);
}
tidy_fflist(&ffl);
}
}
fclose(fp);
free(temp);
if (Requests) {
Syslog('+', "Processed %d requests, created %d replies", Requests, Replies);
if (Replies)
rc = TRUE;
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("Processed %d requests, created %d replies\n", Requests, Replies);
}
}
return rc;
}

9
mbfido/filefind.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _FILEFIND_H
#define _FILEFIND_H
int Filefind(void);
#endif

993
mbfido/filemgr.c Normal file
View File

@@ -0,0 +1,993 @@
/*****************************************************************************
*
* $Id: filemgr.c,v 1.41 2005/10/11 20:49:47 mbse Exp $
* Purpose ...............: FileMgr
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "../lib/diesel.h"
#include "sendmail.h"
#include "mgrutil.h"
#include "createf.h"
#include "filemgr.h"
/*
* External declarations
*/
extern int do_quiet;
/*
* Global variables
*/
extern int net_bad; /* Bad netmails (tracking errors */
int filemgr = 0; /* Nr of FileMgr messages */
int f_help = FALSE; /* Send FileMgr help */
int f_list = FALSE; /* Send FileMgr list */
int f_query = FALSE; /* Send FileMgr query */
int f_stat = FALSE; /* Send FileMgr status */
int f_unlnk = FALSE; /* Send FileMgr unlink */
void F_Help(faddr *, char *);
void F_Help(faddr *t, char *replyid)
{
FILE *fp, *fi;
char *subject;
Mgrlog("FileMgr: Help");
subject=calloc(255,sizeof(char));
snprintf(subject,255,"FileMgr help");
GetRpSubject("filemgr.help",subject,254);
if ((fp = SendMgrMail(t, CFG.ct_KeepMgr, FALSE, (char *)"Filemgr", subject, replyid)) != NULL) {
if ((fi = OpenMacro("filemgr.help", nodes.Language, FALSE)) != NULL ){
MacroVars("s", "s", nodes.Sysop);
MacroVars("A", "s", (char *)"Filemgr");
MacroVars("Y", "s", ascfnode(bestaka_s(t), 0xf));
MacroVars("P", "s", nodes.Fpasswd);
MacroRead(fi, fp);
MacroClear();
fclose(fi);
}
fprintf(fp, "%s\r", TearLine());
CloseMail(fp, t);
} else
WriteError("Can't create netmail");
free(subject);
}
void F_Query(faddr *, char *);
void F_Query(faddr *t, char *replyid)
{
F_List(t, replyid, LIST_QUERY);
}
void F_List(faddr *t, char *replyid, int Notify)
{
FILE *qp, *gp, *fp, *fi = NULL;
char *temp, *Group, *subject;
int i, First = TRUE, SubTot, Total = 0, Cons;
char Stat[4];
faddr *f, *g, *Temp;
sysconnect System;
int msgptr;
fpos_t fileptr,fileptr1,fileptr2;
subject = calloc(255, sizeof(char));
f = bestaka_s(t);
MacroVars("s", "s", nodes.Sysop);
MacroVars("K", "d", Notify);
MacroVars("y", "s", ascfnode(t, 0xff));
MacroVars("Y", "s", ascfnode(f, 0xff));
switch (Notify) {
case LIST_NOTIFY: Mgrlog("FileMgr: Notify to %s", ascfnode(t, 0xff));
snprintf(subject,255,"FileMgr Notify");
GetRpSubject("filemgr.notify.list",subject,255);
fi=OpenMacro("filemgr.notify.list", nodes.Language, FALSE);
break;
case LIST_LIST: Mgrlog("FileMgr: List");
snprintf(subject,255,"FileMgr list");
GetRpSubject("filemgr.list",subject,255);
fi=OpenMacro("filemgr.list", nodes.Language, FALSE);
break;
case LIST_QUERY: Mgrlog("FileMgr: Query");
snprintf(subject,255,"FileMgr Query");
GetRpSubject("filemgr.query",subject,255);
fi=OpenMacro("filemgr.query", nodes.Language, FALSE);
break;
default: Mgrlog("FileMgr: Unlinked");
snprintf(subject,255,"FileMgr: Unlinked areas");
GetRpSubject("filemgr.unlink",subject,254);
fi=OpenMacro("filemgr.unlink", nodes.Language, FALSE);
break;
}
if (fi == NULL) {
MacroClear();
free(subject);
return;
}
if ((qp = SendMgrMail(t, CFG.ct_KeepMgr, FALSE, (char *)"Filemgr", subject, replyid)) != NULL) {
/*
* Mark begin of message in .pkt
*/
msgptr = ftell(qp);
if ((Notify == LIST_LIST) || (Notify == LIST_NOTIFY))
WriteFileGroups(qp, f);
MacroRead(fi, qp);
fgetpos(fi,&fileptr);
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/tic.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r")) == NULL) {
WriteError("$Can't open %s", temp);
free(temp);
free(subject);
MacroClear();
fclose(fi);
return;
}
fread(&tichdr, sizeof(tichdr), 1, fp);
Cons = tichdr.syssize / sizeof(System);
snprintf(temp, PATH_MAX, "%s/etc/fgroups.data", getenv("MBSE_ROOT"));
if ((gp = fopen(temp, "r")) == NULL) {
WriteError("$Can't open %s", temp);
free(temp);
free(subject);
MacroClear();
fclose(fp);
fclose(fi);
return;
}
fread(&fgrouphdr, sizeof(fgrouphdr), 1, gp);
free(temp);
while (TRUE) {
Group = GetNodeFileGrp(First);
if (Group == NULL)
break;
First = FALSE;
fseek(gp, fgrouphdr.hdrsize, SEEK_SET);
while (fread(&fgroup, fgrouphdr.recsize, 1, gp) == 1) {
Temp = fido2faddr(fgroup.UseAka);
g = bestaka_s(Temp);
if ((!strcmp(fgroup.Name, Group)) &&
(g->zone == f->zone) && (g->net == f->net) && (g->node == f->node) && (g->point == f->point)) {
SubTot = 0;
MacroVars("G", "s", fgroup.Name);
MacroVars("J", "s", fgroup.Comment);
MacroVars("I", "s", aka2str(fgroup.UseAka));
fsetpos(fi,&fileptr);
MacroRead(fi, qp);
fgetpos(fi,&fileptr1);
fseek(fp, tichdr.hdrsize, SEEK_SET);
while (fread(&tic, tichdr.recsize, 1, fp) == 1) {
if (!strcmp(Group, tic.Group) && tic.Active && Access(nodes.Security, tic.LinkSec)) {
memset(&Stat, ' ', sizeof(Stat));
Stat[sizeof(Stat)-1] = '\0';
/*
* Now check if this node is connected, if so, set the Stat bits.
*/
for (i = 0; i < Cons; i++) {
fread(&System, sizeof(System), 1, fp);
if ((t->zone == System.aka.zone) && (t->net == System.aka.net) &&
(t->node == System.aka.node) && (t->point == System.aka.point)) {
if (System.receivefrom)
Stat[0] = 'S';
if (System.sendto)
Stat[1] = 'R';
if (System.pause)
Stat[2] = 'P';
}
}
if ( (Notify == LIST_LIST)
|| (Notify == LIST_NOTIFY)
|| ((Notify == LIST_QUERY) && ((Stat[0]=='S') || (Stat[1]=='R')))
|| ((Notify >= LIST_UNLINK) && ((Stat[0]!='S') && (Stat[1]!='R')))) {
MacroVars("X", "s", Stat);
MacroVars("D", "s", tic.Name);
MacroVars("E", "s", tic.Comment);
MacroVars("s", "d", (Stat[0] == 'S'));
MacroVars("r", "d", (Stat[1] == 'R'));
MacroVars("p", "d", (Stat[2] == 'P'));
fsetpos(fi,&fileptr1);
MacroRead(fi, qp);
fgetpos(fi,&fileptr2);
SubTot++;
Total++;
/*
* Panic message split
*/
if (((ftell(qp) - msgptr) / 1024) >= CFG.new_force) {
MacroVars("Z","d",1);
Syslog('-', " Forced splitting message at %ld bytes", ftell(qp) - msgptr);
CloseMail(qp, t);
qp = SendMgrMail(t, CFG.ct_KeepMgr, FALSE, (char *)"Filemgr", subject, replyid);
msgptr = ftell(qp);
}
}
} else
fseek(fp, tichdr.syssize, SEEK_CUR);
}
MacroVars("ZA", "dd", (int) 0 , SubTot );
fsetpos(fi,&fileptr2);
if (((ftell(qp) - msgptr) / 1024) >= CFG.new_split) {
MacroVars("Z","d",1);
Syslog('-', " Splitting message at %ld bytes", ftell(qp) - msgptr);
CloseMail(qp, t);
qp = SendMgrMail(t, CFG.ct_KeepMgr, FALSE, (char *)"Filemgr", subject, replyid);
msgptr = ftell(qp);
}
MacroRead(fi, qp);
}
tidy_faddr(Temp);
}
}
MacroVars("B", "d", Total );
MacroRead(fi, qp);
MacroClear();
fclose(fi);
fclose(fp);
fclose(gp);
fprintf(qp, "%s\r", TearLine());
CloseMail(qp, t);
} else
WriteError("Can't create netmail");
free(subject);
MacroClear();
}
void F_Status(faddr *, char *);
void F_Status(faddr *t, char *replyid)
{
FILE *fp, *fi;
int i;
char *subject;
subject = calloc(255, sizeof(char));
snprintf(subject,255,"FileMgr Status");
Mgrlog("FileMgr: Status");
if (Miy == 0)
i = 11;
else
i = Miy - 1;
MacroVars("A", "d", nodes.Message);
MacroVars("B", "d", nodes.Tic);
MacroVars("C", "d", nodes.AdvTic);
MacroVars("D", "d", nodes.Notify);
MacroVars("a", "d", nodes.FilesSent.lweek);
MacroVars("b", "d", nodes.FilesSent.month[i]);
MacroVars("c", "d", nodes.FilesSent.total);
MacroVars("d", "d", nodes.F_KbSent.lweek);
MacroVars("e", "d", nodes.F_KbSent.month[i]);
MacroVars("f", "d", nodes.F_KbSent.total);
MacroVars("g", "d", nodes.FilesRcvd.lweek);
MacroVars("h", "d", nodes.FilesRcvd.month[i]);
MacroVars("i", "d", nodes.FilesRcvd.total);
MacroVars("j", "d", nodes.F_KbRcvd.lweek);
MacroVars("k", "d", nodes.F_KbRcvd.month[i]);
MacroVars("l", "d", nodes.F_KbRcvd.total);
MacroVars("s", "s", nodes.Sysop);
GetRpSubject("filemgr.status",subject,254);
if ((fi = OpenMacro("filemgr.status", nodes.Language, FALSE)) == NULL ) {
free(subject);
MacroClear();
return;
}
if ((fp = SendMgrMail(t, CFG.ct_KeepMgr, FALSE, (char *)"Filemgr", subject, replyid)) != NULL) {
MacroRead(fi, fp);
MacroClear();
fclose(fi);
fprintf(fp, "%s\r", TearLine());
CloseMail(fp, t);
} else
WriteError("Can't create netmail");
MacroClear();
free(subject);
}
void F_Unlinked(faddr *, char *);
void F_Unlinked(faddr *t, char *replyid)
{
F_List(t, replyid, LIST_UNLINK);
}
void F_Disconnect(faddr *, char *, FILE *);
void F_Disconnect(faddr *t, char *Area, FILE *tmp)
{
int i, First;
char *Group;
faddr *b, *Temp;
sysconnect Sys;
Mgrlog("FileMgr: disconnect %s", Area);
ShiftBuf(Area, 1);
for (i = 0; i < strlen(Area); i++)
Area[i] = toupper(Area[i]);
if (!SearchTic(Area)) {
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop, "Filemgr");
MacroVars("RABCDE", "ssssss","ERR_DISC_NOTFOUND",Area,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
Syslog('+', " Area not found");
MacroClear();
return;
}
Syslog('m', " Found %s group %s", tic.Name, fgroup.Name);
First = TRUE;
while ((Group = GetNodeFileGrp(First)) != NULL) {
First = FALSE;
if (strcmp(Group, fgroup.Name) == 0)
break;
}
if (Group == NULL) {
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop, "Filemgr");
MacroVars("RABCDE", "ssssss","ERR_DISC_NOTGROUP",Area,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
Mgrlog(" Group %s not available for %s", fgroup.Name, ascfnode(t, 0x1f));
MacroClear();
return;
}
b = bestaka_s(t);
Temp = fido2faddr(tic.Aka);
i = metric(b, Temp);
tidy_faddr(Temp);
Syslog('m', "Aka match level is %d", i);
if (i >= METRIC_NET) {
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop, "Filemgr");
MacroVars("RABCDE", "ssssss","ERR_DISC_BADADD",Area,ascfnode(t, 0x1f),"","","");
MsgResult("filemgr.responses",tmp,'\n');
Mgrlog(" %s may not disconnect from group %s", ascfnode(t, 0x1f), fgroup.Name);
MacroClear();
return;
}
memset(&Sys, 0, sizeof(Sys));
memcpy(&Sys.aka, faddr2fido(t), sizeof(fidoaddr));
Sys.sendto = FALSE;
Sys.receivefrom = FALSE;
if (!TicSystemConnected(Sys)) {
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "ssssss","ERR_DISC_NC",Area,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
Mgrlog(" %s is not connected to %s", ascfnode(t, 0x1f), Area);
MacroClear();
return;
}
if (TicSystemConnect(&Sys, FALSE)) {
/*
* Make sure to write an overview afterwards
*/
f_list = TRUE;
Mgrlog("Disconnected file area %s", Area);
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "ssssss","OK_DISC",Area,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
MacroClear();
return;
}
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "ssssss","ERR_DISC_NOTAVAIL",Area,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
Mgrlog("Didn't disconnect %s from mandatory file area %s", ascfnode(t, 0x1f), Area);
MacroClear();
}
void F_Connect(faddr *, char *, FILE *);
void F_Connect(faddr *t, char *Area, FILE *tmp)
{
int i, First;
char *Group, *temp;
faddr *b, *Temp;
sysconnect Sys;
FILE *gp;
Mgrlog("FileMgr: connect %s", Area);
if (Area[0] == '+')
ShiftBuf(Area, 1);
for (i = 0; i < strlen(Area); i++)
Area[i] = toupper(Area[i]);
if (!SearchTic(Area)) {
/*
* Close noderecord, autocreate will destroy it.
*/
UpdateNode();
Syslog('f', " Area not found, trying to create");
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/fgroups.data", getenv("MBSE_ROOT"));
if ((gp = fopen(temp, "r")) == NULL) {
WriteError("$Can't open %s", temp);
free(temp);
return;
}
fread(&fgrouphdr, sizeof(fgrouphdr), 1, gp);
fseek(gp, fgrouphdr.hdrsize, SEEK_SET);
while ((fread(&fgroup, fgrouphdr.recsize, 1, gp)) == 1) {
if ((fgroup.UseAka.zone == t->zone) && (fgroup.UseAka.net == t->net) && fgroup.UpLink.zone &&
strlen(fgroup.AreaFile) && fgroup.Active && fgroup.UserChange) {
if (CheckTicGroup(Area, fgroup.UpLink.zone, t) == 0) {
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "ssssss","ERR_CONN_FORWARD",Area,aka2str(fgroup.UpLink),"","","");
MsgResult("filemgr.responses",tmp,'\n');
break;
}
}
}
fclose(gp);
free(temp);
/*
* Restore noderecord and try to load area again
*/
SearchNodeFaddr(t);
if (!SearchTic(Area)) {
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop, "Filemgr");
MacroVars("RABCDE", "ssssss","ERR_CONN_NOTFOUND",Area,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
Mgrlog("Area %s not found", Area);
MacroClear();
return;
}
}
Syslog('m', " Found %s group %s", tic.Name, fgroup.Name);
First = TRUE;
while ((Group = GetNodeFileGrp(First)) != NULL) {
First = FALSE;
if (strcmp(Group, fgroup.Name) == 0)
break;
}
if (Group == NULL) {
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop, "Filemgr");
MacroVars("RABCDE", "ssssss","ERR_CONN_NOTGROUP",Area,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
Mgrlog(" Group %s not available for %s", fgroup.Name, ascfnode(t, 0x1f));
MacroClear();
return;
}
b = bestaka_s(t);
Temp = fido2faddr(tic.Aka);
i = metric(b, Temp);
tidy_faddr(Temp);
Syslog('m', "Aka match level is %d", i);
if (i >= METRIC_NET) {
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "ssssss","ERR_CONN_BADADD",Area,ascfnode(t, 0x1f),"","","");
MsgResult("filemgr.responses",tmp,'\n');
Mgrlog(" Node %s may not connect to group %s", ascfnode(t, 0x1f), fgroup.Name);
MacroClear();
return;
}
if (! Access(nodes.Security, tic.LinkSec)) {
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
/*
* If node has no access by flags, we lie and say "Area not found"
*/
MacroVars("RABCDE", "ssssss","ERR_CONN_NOTFOUND",Area,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
Mgrlog(" %s has no access to %s", ascfnode(t, 0x1f), Area);
MacroClear();
return;
}
memset(&Sys, 0, sizeof(Sys));
memcpy(&Sys.aka, faddr2fido(t), sizeof(fidoaddr));
Sys.sendto = TRUE;
if (tic.NewSR)
Sys.receivefrom = TRUE;
if (TicSystemConnected(Sys)) {
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "ssssss","ERR_CONN_ALREADY",Area,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
Mgrlog(" %s is already connected to %s", ascfnode(t, 0x1f), Area);
MacroClear();
return;
}
if (TicSystemConnect(&Sys, TRUE)) {
/*
* Make sure to write an overview afterwards
*/
f_list = TRUE;
Mgrlog("Connected to file area %s", Area);
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "ssssss","OK_CONN",Area,aka2str(tic.Aka),"","","");
MsgResult("filemgr.responses",tmp,'\n');
MacroClear();
return;
}
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "ssssss","ERR_CONN_NOTAVAIL",Area,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
WriteError("Can't connect node %s to file area %s", ascfnode(t, 0x1f), Area);
MacroClear();
}
void F_All(faddr *, int, FILE *, char *);
void F_All(faddr *t, int Connect, FILE *tmp, char *Grp)
{
FILE *fp, *gp;
char *Group, *temp;
faddr *f, *Temp;
int i, Link, First = TRUE, Cons;
sysconnect Sys;
int Pos;
if (Grp == NULL) {
if (Connect)
Mgrlog("FileMgr: Connect All");
else
Mgrlog("FileMgr: Disconnect All");
} else {
if (Connect)
Mgrlog("FileMgr: Connect group %s", Grp);
else
Mgrlog("FileMgr: Disconnect group %s", Grp);
}
f = bestaka_s(t);
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/tic.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r+")) == NULL) {
WriteError("$Can't open %s", temp);
free(temp);
return;
}
fread(&tichdr, sizeof(tichdr), 1, fp);
Cons = tichdr.syssize / sizeof(Sys);
snprintf(temp, PATH_MAX, "%s/etc/fgroups.data", getenv("MBSE_ROOT"));
if ((gp = fopen(temp, "r")) == NULL) {
WriteError("$Can't open %s", temp);
free(temp);
fclose(fp);
return;
}
fread(&fgrouphdr, sizeof(fgrouphdr), 1, gp);
free(temp);
while (TRUE) {
Group = GetNodeFileGrp(First);
if (Group == NULL)
break;
First = FALSE;
fseek(gp, fgrouphdr.hdrsize, SEEK_SET);
while (fread(&fgroup, fgrouphdr.recsize, 1, gp) == 1) {
if ((!strcmp(fgroup.Name, Group)) && ((Grp == NULL) || (!strcmp(Group, Grp)))) {
fseek(fp, tichdr.hdrsize, SEEK_SET);
while (fread(&tic, tichdr.recsize, 1, fp) == 1) {
Temp = fido2faddr(tic.Aka);
if ((!strcmp(Group, tic.Group)) && tic.Active && strlen(tic.Name) &&
(metric(Temp, f) < METRIC_NET) && Access(nodes.Security, tic.LinkSec)) {
if (Connect) {
Link = FALSE;
for (i = 0; i < Cons; i++) {
fread(&Sys, sizeof(Sys), 1, fp);
tidy_faddr(Temp);
Temp = fido2faddr(Sys.aka);
if (metric(Temp, t) == METRIC_EQUAL)
Link = TRUE;
}
if (!Link) {
Pos = ftell(fp);
fseek(fp, - tichdr.syssize, SEEK_CUR);
for (i = 0; i < Cons; i++) {
fread(&Sys, sizeof(Sys), 1, fp);
if (!Sys.aka.zone) {
memset(&Sys, 0, sizeof(Sys));
memcpy(&Sys.aka, faddr2fido(t), sizeof(fidoaddr));
Sys.sendto = TRUE;
if (tic.NewSR)
Sys.receivefrom = TRUE;
fseek(fp, - sizeof(Sys), SEEK_CUR);
fwrite(&Sys, sizeof(Sys), 1, fp);
Mgrlog("FileMgr: Connected %s", tic.Name);
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "ssssss","OK_CONN",tic.Name,aka2str(tic.Aka),"","","");
MsgResult("filemgr.responses",tmp,'\n');
MacroClear();
f_list = TRUE;
break;
}
}
fseek(fp, Pos, SEEK_SET);
}
} else {
for (i = 0; i < Cons; i++) {
fread(&Sys, sizeof(Sys), 1, fp);
tidy_faddr(Temp);
Temp = fido2faddr(Sys.aka);
if (metric(Temp, t) == METRIC_EQUAL) {
memset(&Sys, 0, sizeof(Sys));
fseek(fp, - sizeof(Sys), SEEK_CUR);
fwrite(&Sys, sizeof(Sys), 1, fp);
Mgrlog("FileMgr: Disconnected %s", tic.Name);
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "ssssss","OK_DISC",tic.Name,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
MacroClear();
f_list = TRUE;
}
}
}
} else
fseek(fp, tichdr.syssize, SEEK_CUR);
tidy_faddr(Temp);
}
}
}
}
fclose(gp);
fclose(fp);
}
void F_Group(faddr *, char *, int, FILE *);
void F_Group(faddr *t, char *Area, int Connect, FILE *tmp)
{
int i;
ShiftBuf(Area, 2);
CleanBuf(Area);
for (i = 0; i < strlen(Area); i++)
Area[i] = toupper(Area[i]);
F_All(t, Connect, tmp, Area);
}
void F_Pause(faddr *, int, FILE *);
void F_Pause(faddr *t, int Pause, FILE *tmp)
{
FILE *fp;
faddr *f, *Temp;
int i, Cons;
sysconnect Sys;
char *temp;
if (Pause)
Mgrlog("FileMgr: Pause");
else
Mgrlog("FileMgr: Resume");
f = bestaka_s(t);
Syslog('m', "Bestaka for %s is %s", ascfnode(t, 0x1f), ascfnode(f, 0x1f));
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/tic.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r+")) == NULL) {
WriteError("$Can't open %s", temp);
free(temp);
return;
}
fread(&tichdr, sizeof(tichdr), 1, fp);
Cons = tichdr.syssize / sizeof(Sys);
while (fread(&tic, tichdr.recsize, 1, fp) == 1) {
if (tic.Active) {
for (i = 0; i < Cons; i++) {
fread(&Sys, sizeof(Sys), 1, fp);
Temp = fido2faddr(Sys.aka);
if ((metric(Temp, t) == METRIC_EQUAL) && (!Sys.cutoff)) {
Sys.pause = Pause;
fseek(fp, - sizeof(Sys), SEEK_CUR);
fwrite(&Sys, sizeof(Sys), 1, fp);
Mgrlog("FileMgr: %s area %s", Pause?"Pause":"Resume", tic.Name);
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"FileMgr");
MacroVars("RABCDE", "ssdsss","OK_PAUSE",tic.Name,Pause,"","","");
MsgResult("filemgr.responses",tmp,'\n');
f_list = TRUE;
}
tidy_faddr(Temp);
}
} else {
fseek(fp, tichdr.syssize, SEEK_CUR);
}
}
fclose(fp);
}
void F_Message(faddr *t, char *Buf, FILE *tmp)
{
ShiftBuf(Buf, 8);
CleanBuf(Buf);
if (!strncasecmp(Buf, "on", 2))
nodes.Message = TRUE;
else if (!strncasecmp(Buf, "off", 3))
nodes.Message = FALSE;
else
return;
UpdateNode();
SearchNodeFaddr(t);
Mgrlog("FileMgr: Message %s", nodes.Message?"Yes":"No");
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "sdssss","OK_MESSAGE",nodes.Message,"","","","");
MsgResult("filemgr.responses",tmp,'\n');
MacroClear();
}
void F_Tick(faddr *t, char *Buf, FILE *tmp)
{
ShiftBuf(Buf, 5);
CleanBuf(Buf);
if (!strncasecmp(Buf, "on", 2)) {
nodes.Tic = TRUE;
nodes.AdvTic = FALSE;
} else if (!strncasecmp(Buf, "off", 3)) {
nodes.Tic = nodes.AdvTic = FALSE;
} else if (!strncasecmp(Buf, "advanced", 8)) {
nodes.Tic = nodes.AdvTic = TRUE;
} else
return;
UpdateNode();
SearchNodeFaddr(t);
Mgrlog("FileMgr: Tick %s, Advanced %s", nodes.Tic?"Yes":"No", nodes.AdvTic?"Yes":"No");
if (nodes.Tic)
if (nodes.AdvTic){
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "sddsss","OK_TIC_ADV",nodes.Tic,nodes.AdvTic,"","","");
MsgResult("filemgr.responses",tmp,'\n');
}else{
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "sddsss","OK_TIC_NORM",nodes.Tic,nodes.AdvTic,"","","");
MsgResult("filemgr.responses",tmp,'\n');
}else{
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "sddsss","OK_TIC_OFF",nodes.Tic,nodes.AdvTic,"","","");
MsgResult("filemgr.responses",tmp,'\n');
}
MacroClear();
}
int FileMgr(faddr *f, faddr *t, char *replyid, char *subj, time_t mdate, int flags, FILE *fp)
{
int i, rc = 0, spaces;
char *Buf, *subject;
FILE *tmp, *np;
f_help = f_stat = f_unlnk = f_list = f_query = FALSE;
filemgr++;
if (SearchFidonet(f->zone))
f->domain = xstrcpy(fidonet.domain);
Mgrlog("FileMgr request from %s start", ascfnode(f, 0xff));
/*
* If the password failed, we return silently and don't respond.
*/
if ((!strlen(subj)) || (strcasecmp(subj, nodes.Fpasswd))) {
WriteError("FileMgr: password expected \"%s\", got \"%s\"", nodes.Fpasswd, subj);
Mgrlog("FileMgr: password expected \"%s\", got \"%s\"", nodes.Fpasswd, subj);
Mgrlog("FileMgr request from %s finished", ascfnode(f, 0xff));
net_bad++;
return FALSE;
}
if ((tmp = tmpfile()) == NULL) {
WriteError("$FileMsr: Can't open tmpfile()");
net_bad++;
return FALSE;
}
Buf = calloc(MAX_LINE_LENGTH +1, sizeof(char));
rewind(fp);
while ((fgets(Buf, MAX_LINE_LENGTH, fp)) != NULL) {
/*
* Make sure we refresh the nodes record.
*/
SearchNodeFaddr(f);
spaces = 0;
for (i = 0; i < strlen(Buf); i++) {
if (*(Buf + i) == ' ')
spaces++;
if (*(Buf + i) == '\t')
spaces++;
if (*(Buf + i) == '\0')
break;
if (*(Buf + i) == '\n')
*(Buf + i) = '\0';
if (*(Buf + i) == '\r')
*(Buf + i) = '\0';
}
if (!strncmp(Buf, "---", 3))
break;
if (strlen(Buf) && (*(Buf) != '\001') && (spaces <= 1)) {
if (!strncasecmp(Buf, "%help", 5))
f_help = TRUE;
else if (!strncasecmp(Buf, "%query", 6))
f_query = TRUE;
else if (!strncasecmp(Buf, "%linked", 7))
f_query = TRUE;
else if (!strncasecmp(Buf, "%list", 5))
f_list = TRUE;
else if (!strncasecmp(Buf, "%status", 7))
f_stat = TRUE;
else if (!strncasecmp(Buf, "%unlinked", 9))
f_unlnk = TRUE;
else if (!strncasecmp(Buf, "%+all", 5) && CFG.ct_PlusAll)
F_All(f, TRUE, tmp, NULL);
else if (!strncasecmp(Buf, "%-all", 5) && CFG.ct_PlusAll)
F_All(f, FALSE, tmp, NULL);
else if (!strncasecmp(Buf, "%+*", 3) && CFG.ct_PlusAll)
F_All(f, TRUE, tmp, NULL);
else if (!strncasecmp(Buf, "%-*", 3) && CFG.ct_PlusAll)
F_All(f, FALSE, tmp, NULL);
else if (!strncasecmp(Buf, "%+", 2))
F_Group(f, Buf, TRUE, tmp);
else if (!strncasecmp(Buf, "%-", 2))
F_Group(f, Buf, FALSE, tmp);
else if (!strncasecmp(Buf, "%pause", 6) && CFG.ct_Pause)
F_Pause(f, TRUE, tmp);
else if (!strncasecmp(Buf, "%passive", 8) && CFG.ct_Pause)
F_Pause(f, TRUE, tmp);
else if (!strncasecmp(Buf, "%resume", 7) && CFG.ct_Pause)
F_Pause(f, FALSE, tmp);
else if (!strncasecmp(Buf, "%active", 7) && CFG.ct_Pause)
F_Pause(f, FALSE, tmp);
else if (!strncasecmp(Buf, "%password", 9) && CFG.ct_Passwd)
MgrPasswd(f, Buf, tmp, 9, 1);
else if (!strncasecmp(Buf, "%pwd", 4) && CFG.ct_Passwd)
MgrPasswd(f, Buf, tmp, 4, 1);
else if (!strncasecmp(Buf, "%notify", 7) && CFG.ct_Notify)
MgrNotify(f, Buf, tmp, 1);
else if (!strncasecmp(Buf, "%message", 8) && CFG.ct_Message)
F_Message(f, Buf, tmp);
else if (!strncasecmp(Buf, "%tick", 5) && CFG.ct_TIC)
F_Tick(f, Buf, tmp);
else if (*(Buf) == '-')
F_Disconnect(f, Buf, tmp);
else
F_Connect(f, Buf, tmp);
}
}
if (ftell(tmp)) {
subject=calloc(256,sizeof(char));
MacroVars("SsP", "sss", CFG.sysop_name, nodes.Sysop,"Filemgr");
MacroVars("RABCDE", "ssssss","","","","","","");
snprintf(subject,256,"Your FileMgr request");
GetRpSubject("filemgr.responses",subject,256);
if ((np = SendMgrMail(f, CFG.ct_KeepMgr, FALSE, (char *)"Filemgr", subject, replyid)) != NULL) {
MacroVars("RABCDE", "ssssss","WELLCOME","","","","","");
MsgResult("filemgr.responses",np,'\r');
fprintf(np, "\r");
fseek(tmp, 0, SEEK_SET);
while ((fgets(Buf, MAX_LINE_LENGTH, tmp)) != NULL) {
while ((Buf[strlen(Buf) - 1]=='\n') || (Buf[strlen(Buf) - 1]=='\r')) {
Buf[strlen(Buf) - 1] = '\0';
}
fprintf(np, "%s\r", Buf);
}
fprintf(np, "\r");
MacroVars("RABCDE", "ssssss","GOODBYE","","","","","");
MsgResult("filemgr.responses",np,'\r');
fprintf(np, "\r%s\r", TearLine());
CloseMail(np, t);
} else
WriteError("Can't create netmail");
free(subject);
}
MacroClear();
free(Buf);
fclose(tmp);
if (f_stat)
F_Status(f, replyid);
if (f_query)
F_Query(f, replyid);
if (f_list)
F_List(f, replyid, LIST_LIST);
if (f_unlnk)
F_Unlinked(f, replyid);
if (f_help)
F_Help(f, replyid);
Mgrlog("FileMgr request from %s finished", ascfnode(f, 0xff));
return rc;
}

11
mbfido/filemgr.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef _FILEMGR_H
#define _FILEMGR_H
void F_Status(faddr *, char *);
void F_List(faddr *, char *, int);
int FileMgr(faddr *, faddr *, char *, char *, time_t, int, FILE *);
#endif

81
mbfido/flock.c Normal file
View File

@@ -0,0 +1,81 @@
/*****************************************************************************
*
* $Id: flock.c,v 1.5 2004/02/21 17:22:02 mbroek Exp $
* Purpose ...............: File locker
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* Michiel Broek FIDO: 2:2801/16
* Beekmansbos 10 Internet: mbroek@ux123.pttnwb.nl
* 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 "flock.h"
int f_lock(char *fn)
{
int lfd=-1;
struct flock fl;
struct stat st;
if (fn) {
if ((lfd = open(fn,O_RDWR | O_CREAT)) < 0) {
perror("");
WriteError("Error opening file %s", fn);
return -1;
}
fl.l_type=F_WRLCK;
fl.l_whence=0;
fl.l_start=0L;
fl.l_len=0L;
fl.l_pid=getpid();
if (fcntl(lfd,F_SETLK,&fl) != 0) {
if (errno != EAGAIN)
Syslog('+', "Error locking file %s",fn);
close(lfd);
return -1;
}
if (stat(fn,&st) != 0) {
perror("");
WriteError("Error accessing file %s",fn);
close(lfd);
return -1;
}
}
return lfd;
}
void funlock(int fd)
{
close(fd);
return;
}

10
mbfido/flock.h Normal file
View File

@@ -0,0 +1,10 @@
/* flock.h */
#ifndef _FLOCK_H
#define _FLOCK_H
int f_lock(char *);
void funlock(int);
#endif

291
mbfido/forward.c Normal file
View File

@@ -0,0 +1,291 @@
/*****************************************************************************
*
* $Id: forward.c,v 1.52 2006/03/27 18:48:27 mbse Exp $
* Purpose ...............: File forward to a node
*
*****************************************************************************
* Copyright (C) 1997-2006
*
* 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 "../lib/diesel.h"
#include "orphans.h"
#include "tic.h"
#include "sendmail.h"
#include "rollover.h"
#include "mgrutil.h"
#include "forward.h"
void ForwardFile(fidoaddr Node, fa_list *sbl)
{
char *subject = NULL, *fwdfile = NULL, *queuedir, *listfile, *ticfile = NULL, *ticname, flavor;
FILE *fp, *fi, *fl, *net;
faddr *dest, *routeto, *Fa, *Temp, *ba;
int i, z, n;
time_t now, ftime;
fa_list *tmp;
if (!SearchNode(Node)) {
WriteError("TIC forward in %s, node %s not in setup but defined in area setup", TIC.TicIn.Area, aka2str(Node));
return;
}
Syslog('+', "Forward file to %s %s netmail", aka2str(Node), nodes.Message?"with":"without");
fwdfile = calloc(PATH_MAX, sizeof(char));
queuedir = calloc(PATH_MAX, sizeof(char));
listfile = calloc(PATH_MAX, sizeof(char));
snprintf(queuedir, PATH_MAX, "%s/%d.%d.%d.%d", CFG.out_queue, Node.zone, Node.net, Node.node, Node.point);
snprintf(listfile, PATH_MAX, "%s/.filelist", queuedir);
mkdirs(listfile, 0750);
if ((fl = fopen(listfile, "a+")) == NULL) {
WriteError("$Can't open %s", listfile);
free(fwdfile);
free(listfile);
free(queuedir);
return;
}
/*
* Create the full filename
*/
if (TIC.PassThru || TIC.SendOrg) {
snprintf(fwdfile, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File);
subject = xstrcpy(TIC.TicIn.File);
} else {
/*
* Make sure the file attach is the 8.3 filename
*/
snprintf(fwdfile, PATH_MAX, "%s/%s", TIC.BBSpath, TIC.NewFile);
subject = xstrcpy(TIC.NewFile);
}
flavor = 'f';
if (nodes.Crash)
flavor = 'c';
if (nodes.Hold)
flavor = 'h';
fprintf(fl, "%c LEAVE FDN %s\n", flavor, fwdfile);
if (nodes.RouteVia.zone)
routeto = fido2faddr(nodes.RouteVia);
else
routeto = fido2faddr(Node);
dest = fido2faddr(Node);
ticfile = calloc(PATH_MAX, sizeof(char));
ticname = calloc(15, sizeof(char));
if (nodes.Tic) {
snprintf(ticname, 15, "%08x.tic", sequencer());
subject = xstrcat(subject, (char *)" ");
subject = xstrcat(subject, ticname);
snprintf(ticfile, PATH_MAX, "%s/%s", CFG.ticout, ticname);
}
free(ticname);
/*
* Send netmail message if the node has it turned on.
*/
if (nodes.Message) {
Temp = fido2faddr(Node);
if ((net = SendMgrMail(Temp, CFG.ct_KeepMgr, TRUE, (char *)"Filemgr", subject, NULL)) != NULL) {
if ((fi = OpenMacro("forward.tic", nodes.Language, FALSE)) != NULL) {
ftime = TIC.FileDate;
MacroVars("a", "s", TIC.TicIn.Area);
MacroVars("b", "s", tic.Comment);
MacroVars("c", "d", TIC.FileCost);
MacroVars("d", "s", fgroup.Comment);
if (TIC.PassThru || TIC.SendOrg)
MacroVars("f", "s", TIC.TicIn.FullName);
else
MacroVars("f", "s", TIC.NewFullName);
MacroVars("g", "d", TIC.FileSize);
MacroVars("h", "d", (TIC.FileSize / 1024));
MacroVars("i", "s", TIC.TicIn.Crc);
MacroVars("j", "s", TIC.TicIn.Origin);
MacroVars("m", "s", rfcdate(ftime));
MacroVars("n", "s", TIC.TicIn.Desc);
MacroVars("s", "s", nodes.Sysop);
if (TIC.PassThru || TIC.SendOrg)
MacroVars("e", "s", TIC.TicIn.File);
else
MacroVars("e", "s", TIC.NewFile);
if (strlen(TIC.TicIn.Magic))
MacroVars("k", "s", TIC.TicIn.Magic);
if (strlen(TIC.TicIn.Replace))
MacroVars("l", "s", TIC.TicIn.Replace);
MacroRead(fi, net);
fprintf(net, "%s\r", TearLine());
CloseMail(net, Temp);
}
} else {
WriteError("Can't create netmail");
}
tidy_faddr(Temp);
}
free(subject);
/*
* If we need a .TIC file, start creating it.
*/
if (nodes.Tic) {
mkdirs(ticfile, 0770);
if ((fp = fopen(ticfile, "a+")) != NULL) {
fprintf(fp, "Area %s\r\n", TIC.TicIn.Area);
fprintf(fp, "Origin %s\r\n", TIC.TicIn.Origin);
Fa = fido2faddr(tic.Aka);
fprintf(fp, "From %s\r\n", ascfnode(Fa, 0x0f));
free(Fa);
if (strlen(TIC.TicIn.Replace))
fprintf(fp, "Replaces %s\r\n", TIC.TicIn.Replace);
if (strlen(TIC.TicIn.Magic))
fprintf(fp, "Magic %s\r\n", TIC.TicIn.Magic);
if ((TIC.PassThru) || (TIC.SendOrg)) {
fprintf(fp, "File %s\r\n", TIC.TicIn.File);
if (strlen(TIC.TicIn.FullName))
fprintf(fp, "Fullname %s\r\n", TIC.TicIn.FullName);
} else {
fprintf(fp, "File %s\r\n", TIC.NewFile);
if (strlen(TIC.NewFullName))
fprintf(fp, "Fullname %s\r\n", TIC.NewFullName);
}
fprintf(fp, "Size %d\r\n", (int)(TIC.FileSize));
fprintf(fp, "Desc %s\r\n", TIC.TicIn.Desc);
fprintf(fp, "Crc %s\r\n", TIC.TicIn.Crc);
if (nodes.TIC_To) {
fprintf(fp, "To %s, %s\r\n", nodes.Sysop, ascfnode(dest, 0x1f));
}
if (nodes.AdvTic) {
fprintf(fp, "Areadesc %s\r\n", tic.Comment);
fprintf(fp, "Fdn %s\r\n", fgroup.Comment);
if (TIC.TicIn.TotLDesc)
for (i = 0; i < TIC.TicIn.TotLDesc; i++)
fprintf(fp, "LDesc %s\r\n", TIC.TicIn.LDesc[i]);
}
fprintf(fp, "Created by MBSE BBS %s %s\r\n", VERSION, SHORTRIGHT);
if (TIC.TicIn.TotPath)
for (i = 0; i < TIC.TicIn.TotPath; i++)
fprintf(fp, "Path %s\r\n", TIC.TicIn.Path[i]);
/*
* Add our system to the path
*/
now = time(NULL);
subject = ctime(&now);
Striplf(subject);
ba = bestaka_s(dest);
fprintf(fp, "Path %s %u %s %s\r\n", ascfnode(ba, 0x1f), (int)mktime(localtime(&now)), subject, tzname[0]);
tidy_faddr(ba);
if (nodes.TIC_AdvSB) {
/*
* In advanced TIC mode we send multiple seenby
* addresses on one line in stead of one line
* per system.
*/
z = 0;
n = 0;
subject = xstrcpy((char *)"Seenby");
for (tmp = sbl; tmp; tmp = tmp->next) {
if (strlen(subject) > 70) {
fprintf(fp, "%s\r\n", subject);
z = 0;
n = 0;
free(subject);
subject = xstrcpy((char *)"Seenby ");
} else {
subject = xstrcat(subject, (char *)" ");
}
if (z != tmp->addr->zone) {
if (nodes.Tic4d)
subject = xstrcat(subject, ascfnode(tmp->addr, 0x0f));
else
subject = xstrcat(subject, ascfnode(tmp->addr, 0x0e));
z = tmp->addr->zone;
} else {
if (n != tmp->addr->net) {
if (nodes.Tic4d)
subject = xstrcat(subject, ascfnode(tmp->addr, 0x07));
else
subject = xstrcat(subject, ascfnode(tmp->addr, 0x06));
n = tmp->addr->net;
} else {
if (nodes.Tic4d)
subject = xstrcat(subject, ascfnode(tmp->addr, 0x03));
else
subject = xstrcat(subject, ascfnode(tmp->addr, 0x02));
}
}
}
if (strlen(subject) > 7) {
fprintf(fp, "%s\r\n", subject);
free(subject);
}
} else {
/*
* Old style seenby lines
*/
for (tmp = sbl; tmp; tmp = tmp->next) {
fprintf(fp, "Seenby %s\r\n", ascfnode(tmp->addr, 0x0f));
}
}
/*
* Now append all passthru ticlines
*/
if (TIC.TicIn.Unknowns)
for (i = 0; i < TIC.TicIn.Unknowns; i++)
fprintf(fp, "%s\r\n", TIC.TicIn.Unknown[i]);
fprintf(fp, "Pw %s\r\n", nodes.Fpasswd);
fclose(fp);
fprintf(fl, "%c KFS NOR %s\n", flavor, ticfile);
} else {
WriteError("$Can't create %s", ticfile);
}
}
fsync(fileno(fl));
fclose(fl);
/*
* Update the nodes statistic counters
*/
StatAdd(&nodes.FilesSent, 1L);
StatAdd(&nodes.F_KbSent, T_File.SizeKb);
UpdateNode();
SearchNode(Node);
free(ticfile);
free(fwdfile);
free(queuedir);
free(listfile);
tidy_faddr(routeto);
}

9
mbfido/forward.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _FORWARD_H
#define _FORWARD_H
void ForwardFile(fidoaddr, fa_list *);
#endif

144
mbfido/fsort.c Normal file
View File

@@ -0,0 +1,144 @@
/*****************************************************************************
*
* $Id: fsort.c,v 1.7 2005/08/28 15:33:23 mbse Exp $
* Purpose ...............: File sort
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "fsort.h"
/*
* Tidy the filearray
*/
void tidy_fdlist(fd_list **fdp)
{
fd_list *tmp, *old;
for (tmp = *fdp; tmp; tmp = old) {
old = tmp->next;
free(tmp);
}
*fdp = NULL;
}
/*
* Add a file on the array.
*/
void fill_fdlist(fd_list **fdp, char *filename, time_t filedate)
{
fd_list *tmp;
tmp = (fd_list *)malloc(sizeof(fd_list));
tmp->next = *fdp;
snprintf(tmp->fname, 65, "%s", filename);
tmp->fdate = filedate;
*fdp = tmp;
}
int compfdate(fd_list **, fd_list **);
/*
* Sort the array of files by filedate
*/
void sort_fdlist(fd_list **fdp)
{
fd_list *ta, **vector;
size_t n = 0, i;
if (*fdp == NULL) {
return;
}
for (ta = *fdp; ta; ta = ta->next)
n++;
vector = (fd_list **)malloc(n * sizeof(fd_list *));
i = 0;
for (ta = *fdp; ta; ta = ta->next) {
vector[i++] = ta;
}
qsort(vector, n, sizeof(fd_list*), (int(*)(const void*, const void*))compfdate);
(*fdp) = vector[0];
i = 1;
for (ta = *fdp; ta; ta = ta->next) {
if (i < n)
ta->next = vector[i++];
else
ta->next = NULL;
}
free(vector);
return;
}
int compfdate(fd_list **fdp1, fd_list **fdp2)
{
return ((*fdp1)->fdate - (*fdp2)->fdate);
}
/*
* Return the name of the oldest file in the array
*/
char *pull_fdlist(fd_list **fdp)
{
static char buf[PATH_MAX];
fd_list *ta;
if (*fdp == NULL)
return NULL;
ta = *fdp;
memset(&buf, 0, sizeof(buf));
snprintf(buf, PATH_MAX, "%s", ta->fname);
if (ta->next != NULL)
*fdp = ta->next;
else
*fdp = NULL;
free(ta);
return buf;
}

20
mbfido/fsort.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef _FSORT_H
#define _FSORT_H
typedef struct _fd_list {
struct _fd_list *next;
char fname[65];
time_t fdate;
} fd_list;
void tidy_fdlist(fd_list **);
void fill_fdlist(fd_list **, char *, time_t);
void sort_fdlist(fd_list **);
char *pull_fdlist(fd_list **);
#endif

1543
mbfido/ftn2rfc.c Normal file

File diff suppressed because it is too large Load Diff

8
mbfido/ftn2rfc.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef _FTN2RFC_H
#define _FTN2RFC_H
int ftn2rfc(faddr *, faddr *, char *, char *, time_t, int, FILE *);
#endif

139
mbfido/grlist.c Normal file
View File

@@ -0,0 +1,139 @@
/*****************************************************************************
*
* $Id: grlist.c,v 1.6 2005/08/28 14:52:14 mbse Exp $
* Purpose ...............: Announce new files and FileFind
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* Michiel Broek FIDO: 2:2801/16
* Beekmansbos 10 Internet: mbroek@ux123.pttnwb.nl
* 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 "grlist.h"
/*
* Tidy the groupnames array
*/
void tidy_grlist(gr_list ** fdp)
{
gr_list *tmp, *old;
for (tmp = *fdp; tmp; tmp = old) {
old = tmp->next;
free(tmp);
}
*fdp = NULL;
}
/*
* Add a group to the array
*/
void fill_grlist(gr_list **fdp, char *groupname, char *echoname)
{
gr_list *tmp;
/*
* Count files in group if the group already exists.
*/
if (*fdp != NULL) {
for (tmp = *fdp; tmp; tmp = tmp->next)
if ((strcmp(groupname, tmp->group) == 0) &&
(strcmp(echoname, tmp->echo) == 0)) {
tmp->count++;
return;
}
}
/*
* Add a new group
*/
tmp = (gr_list *)malloc(sizeof(gr_list));
tmp->next = *fdp;
snprintf(tmp->group, 13, "%s", groupname);
snprintf(tmp->echo, 21, "%s", echoname);
tmp->count = 1;
*fdp = tmp;
}
int compgroup(gr_list **, gr_list **);
/*
* Sort the array of groups
*/
void sort_grlist(gr_list **fdp)
{
gr_list *ta, **vector;
size_t n = 0, i;
if (*fdp == NULL)
return;
for (ta = *fdp; ta; ta = ta->next)
n++;
vector = (gr_list **)malloc(n * sizeof(gr_list *));
i = 0;
for (ta = *fdp; ta; ta = ta->next) {
vector[i++] = ta;
}
qsort(vector, n, sizeof(gr_list*), (int(*)(const void*, const void*))compgroup);
(*fdp) = vector[0];
i = 1;
for (ta = *fdp; ta; ta = ta->next) {
if (i < n)
ta->next = vector[i++];
else
ta->next = NULL;
}
free(vector);
return;
}
int compgroup(gr_list **fdp1, gr_list **fdp2)
{
int rc;
rc = strcmp((*fdp1)->group, (*fdp2)->group);
if (rc != 0)
return rc;
return strcmp((*fdp1)->echo, (*fdp2)->echo);
}

19
mbfido/grlist.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef _GRLIST_H_
#define _GRLIST_H
typedef struct _gr_list { /* Announce array */
struct _gr_list *next;
char group[13]; /* Group name */
char echo[21]; /* Fileecho name */
int count; /* Number of new files */
} gr_list;
void tidy_grlist(gr_list **);
void fill_grlist(gr_list **, char *, char *);
void sort_grlist(gr_list **);
#endif

52
mbfido/hash.c Normal file
View File

@@ -0,0 +1,52 @@
/*****************************************************************************
*
* $Id: hash.c,v 1.7 2005/10/11 20:49:47 mbse Exp $
* Purpose ...............: MBSE BBS Mail Gate
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 int *id, char *mod)
{
*id ^= lh_strhash(mod);
}
void hash_update_n(unsigned int *id, unsigned int mod)
{
char buf[32];
snprintf(buf,32, "%030u",mod);
*id ^= lh_strhash(buf);
}

9
mbfido/hash.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef HASH_H
#define HASH_H
/* $Id: hash.h,v 1.2 2005/10/11 20:49:47 mbse Exp $ */
void hash_update_s(unsigned int *, char *);
void hash_update_n(unsigned int *, unsigned int);
#endif

202
mbfido/hatch.c Normal file
View File

@@ -0,0 +1,202 @@
/*****************************************************************************
*
* $Id: hatch.c,v 1.17 2005/12/03 15:09:06 mbse Exp $
* Purpose ...............: Hatch files
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "utic.h"
#include "rollover.h"
#include "hatch.h"
extern int do_quiet;
int Days[] = {31,28,31,30,31,30,31,31,30,31,30,31};
int Hatched = 0;
int CheckHatch(char *);
void Hatch()
{
char *temp;
FILE *fp;
struct tm *Tm;
time_t Now;
int LastDay;
int HatchToday;
temp = calloc(PATH_MAX, sizeof(char));
Syslog('+', "Pass: hatch files");
Now = time(NULL);
Tm = localtime(&Now);
LastDay = Days[Tm->tm_mon];
if (Tm->tm_mon == 1) {
/*
* Note that with this method each century change is a leapyear,
* but take in mind that fidonet will no longer exist in 2100.
*/
if (!(Tm->tm_year % 4))
LastDay++;
}
snprintf(temp, PATH_MAX, "%s/etc/hatch.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r")) == NULL) {
WriteError("$Can't open %s", temp);
free(temp);
return;
}
fread(&hatchhdr, sizeof(hatchhdr), 1, fp);
while (fread(&hatch, hatchhdr.recsize, 1, fp) == 1) {
if (hatch.Active) {
HatchToday = FALSE;
if (hatch.Days[Diw])
HatchToday = TRUE;
if ((hatch.Month[Tm->tm_mday -1]) || (hatch.Month[31] && (LastDay == Tm->tm_mday)))
HatchToday = TRUE;
snprintf(temp, PATH_MAX, "%s", hatch.Spec);
if (HatchToday)
CheckHatch(temp);
}
}
fclose(fp);
free(temp);
}
int CheckHatch(char *temp)
{
DIR *dp;
struct dirent *de;
char *fn, *tf, tmp[4], *temp2;
int i, hatched = FALSE;
char mask[256];
FILE *Tf;
if (mkdirs(temp, 0775) == FALSE) {
WriteError("Can't create dir %s", temp);
return FALSE;
}
fn = xstrcpy(strrchr(temp, '/') + 1);
while (temp[strlen(temp) -1] != '/')
temp[strlen(temp) -1] = '\0';
temp[strlen(temp) -1] = '\0';
if (chdir(temp)) {
WriteError("$Can't chdir(%s)", temp);
free(fn);
return FALSE;
}
if ((dp = opendir(temp)) == NULL) {
WriteError("$Can't opendir(%s)", temp);
free(fn);
return FALSE;
}
strcpy(mask, re_mask(fn, FALSE));
if ((re_comp(mask)) == NULL) {
tf = calloc(PATH_MAX, sizeof(char));
while ((de = readdir(dp))) {
if (re_exec(de->d_name)) {
hatched = TRUE;
Syslog('+', "Hatch \"%s\" in area %s", de->d_name, hatch.Name);
snprintf(tf, PATH_MAX, "%s/%s", CFG.pinbound, MakeTicName());
if ((Tf = fopen(tf, "a+")) == NULL) {
WriteError("Can't create %s", tf);
} else {
fprintf(Tf, "Hatch\r\n");
fprintf(Tf, "Created MBSE BBS v%s, %s\r\n", VERSION, SHORTRIGHT);
fprintf(Tf, "Area %s\r\n", hatch.Name);
if (SearchTic(hatch.Name)) {
fprintf(Tf, "Origin %s\r\n", aka2str(tic.Aka));
fprintf(Tf, "From %s\r\n", aka2str(tic.Aka));
} else {
fprintf(Tf, "Origin %s\r\n", aka2str(CFG.aka[0]));
fprintf(Tf, "From %s\r\n", aka2str(CFG.aka[0]));
Syslog('?', "Warning: TIC group not found");
}
if (strlen(hatch.Replace))
fprintf(Tf, "Replaces %s\r\n", hatch.Replace);
if (strlen(hatch.Magic))
fprintf(Tf, "Magic %s\r\n", hatch.Magic);
temp2 = calloc(strlen(de->d_name) + 1, sizeof(char));
snprintf(temp2, strlen(de->d_name) + 1, "%s", de->d_name);
name_mangle(temp2);
fprintf(Tf, "File %s\r\n", temp2);
free(temp2);
fprintf(Tf, "Fullname %s\r\n", de->d_name);
fprintf(Tf, "Pth %s\r\n", temp);
fprintf(Tf, "Desc ");
for (i = 0; i < strlen(hatch.Desc); i++) {
if (hatch.Desc[i] != '%') {
fprintf(Tf, "%c", hatch.Desc[i]);
} else {
i++;
memset(&tmp, 0, sizeof(tmp));
if (isdigit(hatch.Desc[i]))
tmp[0] = hatch.Desc[i];
if (isdigit(hatch.Desc[i+1])) {
tmp[1] = hatch.Desc[i+1];
i++;
}
fprintf(Tf, "%c", de->d_name[atoi(tmp) -1]);
}
}
fprintf(Tf, "\r\n");
fprintf(Tf, "Crc %08x\r\n", file_crc(de->d_name, CFG.slow_util && do_quiet));
fprintf(Tf, "Pw %s\r\n", CFG.hatchpasswd);
fclose(Tf);
Hatched++;
StatAdd(&hatch.Hatched , 1);
}
}
}
free(tf);
} else {
WriteError("Could not create regexp from %s", fn);
}
closedir(dp);
free(fn);
return hatched;
}

9
mbfido/hatch.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _HATCH_H
#define _HATCH_H
void Hatch(void);
#endif

500
mbfido/lhash.c Normal file
View File

@@ -0,0 +1,500 @@
/*****************************************************************************
*
* $Id: lhash.c,v 1.8 2005/10/11 20:49:47 mbse Exp $
* Purpose ...............: MBSE BBS Mail Gate
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 int *rhash);
#else
#define P_CP
#define P_CPP
static void expand();
static void contract();
static LHASH_NODE **getrn();
#endif
LHASH *lh_new(unsigned int (*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 int (*)(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 int 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 int 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 int 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 int 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 int *rhash)
{
LHASH_NODE **ret,*n1;
unsigned int 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 int lh_strhash(char *c)
{
unsigned int ret=0;
int n;
unsigned int 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
mbfido/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 int hash;
#endif
} LHASH_NODE;
typedef struct lhash_st
{
LHASH_NODE **b;
int (*comp)(char *, char *);
unsigned int (*hash)(char *);
unsigned int num_nodes;
unsigned int num_alloc_nodes;
unsigned int p;
unsigned int pmax;
unsigned int up_load; /* load times 256 */
unsigned int down_load; /* load times 256 */
unsigned int num_items;
unsigned int num_expands;
unsigned int num_expand_reallocs;
unsigned int num_contracts;
unsigned int num_contract_reallocs;
unsigned int num_hash_calls;
unsigned int num_comp_calls;
unsigned int num_insert;
unsigned int num_replace;
unsigned int num_delete;
unsigned int num_no_delete;
unsigned int num_retreve;
unsigned int num_retreve_miss;
unsigned int num_hash_comps;
} LHASH;
#define LH_LOAD_MULT 256
#ifndef NOPROTO
LHASH *lh_new(unsigned int (*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 int 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 int 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

374
mbfido/magic.c Normal file
View File

@@ -0,0 +1,374 @@
/*****************************************************************************
*
* $Id: magic.c,v 1.27 2005/11/12 12:52:30 mbse Exp $
* Purpose ...............: .TIC files magic processing.
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "orphans.h"
#include "tic.h"
#include "utic.h"
#include "magic.h"
int MagicNr; /* Current magic record number */
int Magics = 0; /* Processed magics */
char *Magic_Macro(int);
char *Magic_Macro(int C)
{
static char buf[PATH_MAX];
buf[0] = '\0';
switch(toupper(C)) {
case 'F': snprintf(buf, PATH_MAX, "%s/%s", TIC.BBSpath, TIC.NewFile);
break;
case 'P': snprintf(buf, PATH_MAX, "%s", TIC.BBSpath);
break;
case 'N': snprintf(buf, PATH_MAX, "%s", strtok(strdup(TIC.NewFile), "."));
break;
case 'E': snprintf(buf, PATH_MAX, "%s", strrchr(TIC.NewFile, '.'));
break;
case 'L': snprintf(buf, PATH_MAX, "%s", strrchr(TIC.NewFile, '.'));
buf[0] = buf[1];
buf[1] = buf[2];
buf[2] = '\0';
break;
case 'D': snprintf(buf, 3, "%03d", Day_Of_Year());
break;
case 'C': snprintf(buf, 3, "%03d", Day_Of_Year());
buf[0] = buf[1];
buf[1] = buf[2];
buf[2] = '\0';
break;
case 'A': snprintf(buf, PATH_MAX, "%s", TIC.TicIn.Area);
break;
}
Syslog('f', "Mgc Macro(%c): \"%s\"", C, buf);
return buf;
}
int GetMagicRec(int Typ, int First)
{
int Eof = FALSE;
char *temp, mask[256];
FILE *FeM;
if (First)
MagicNr = 0;
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/magic.data", getenv("MBSE_ROOT"));
if ((FeM = fopen(temp, "r")) == NULL) {
Syslog('+', "Huh? No magic file? (%s)", temp);
free(temp);
return FALSE;
}
fread(&magichdr, sizeof(magichdr), 1, FeM);
do {
if (fseek(FeM, magichdr.hdrsize + (MagicNr * magichdr.recsize), SEEK_SET) != 0) {
WriteError("$Can't seek record %ld in %s", MagicNr, temp);
free(temp);
fclose(FeM);
return FALSE;
}
MagicNr++;
if (fread(&magic, magichdr.recsize, 1, FeM) == 1) {
if ((magic.Active) && (magic.Attrib == Typ) && (strcasecmp(magic.From, TIC.TicIn.Area) == 0)) {
memset(&mask, 0, sizeof(mask));
strcpy(mask, re_mask(magic.Mask, FALSE));
if ((re_comp(mask)) == NULL) {
if (re_exec(TIC.NewFile)) {
fclose(FeM);
free(temp);
return TRUE;
}
} else {
WriteError("Magic: re_comp(%s) failed", mask);
}
}
} else {
Eof = TRUE;
}
} while (!Eof);
free(temp);
fclose(FeM);
return FALSE;
}
void MagicResult(char *format, ...)
{
char *outputstr;
va_list va_ptr;
outputstr = calloc(1024, sizeof(char));
va_start(va_ptr, format);
vsnprintf(outputstr, 1024, format, va_ptr);
va_end(va_ptr);
Syslog('+', "Magic: %s", outputstr);
free(outputstr);
Magics++;
}
void Magic_CheckCompile(void);
void Magic_CheckCompile(void)
{
if (magic.Compile) {
CompileNL = TRUE;
Syslog('+', "Magic: Trigger Compile Nodelists");
}
}
int Magic_MoveFile(void)
{
if (GetMagicRec(MG_MOVE, TRUE)) {
strcpy(TIC.TicIn.Area, magic.ToArea);
MagicResult((char *)"Move %s to Area %s", TIC.NewFile, TIC.TicIn.Area);
return TRUE;
} else
return FALSE;
}
void Magic_ExecCommand(void)
{
int i, j, k, Err, First = TRUE;
char Line[256], Temp[PATH_MAX], *cmd, *opts;
while (GetMagicRec(MG_EXEC, First)) {
First = FALSE;
j = 0;
memset(&Line, 0, sizeof(Line));
for (i = 0; i < strlen(magic.Cmd); i++) {
if (magic.Cmd[i] != '%') {
Line[j] = magic.Cmd[i];
j++;
} else {
i++;
if (magic.Cmd[i] == '%') {
Line[j] = '%';
j++;
} else {
Temp[0] = '\0';
snprintf(Temp, PATH_MAX, "%s", Magic_Macro(magic.Cmd[i]));
for (k = 0; k < strlen(Temp); k++) {
Line[j] = Temp[k];
j++;
}
}
}
}
cmd = xstrcpy(getenv("MBSE_ROOT"));
cmd = xstrcat(cmd, (char *)"/bin/");
cmd = xstrcat(cmd, strtok(Line, " "));
opts = strtok(NULL, "\0");
MagicResult((char *)"Exec: \"%s %s\"", cmd, opts);
if ((Err = execute_str(cmd, opts, NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null")) == 0) {
Magics++;
} else
Syslog('!', "Mgc Exec: (%s %s) returns %d", cmd, opts, Err);
Magic_CheckCompile();
}
}
void Magic_CopyFile(void)
{
int First = TRUE, rc;
char *From, *To;
From = calloc(PATH_MAX, sizeof(char));
To = calloc(PATH_MAX, sizeof(char));
while (GetMagicRec(MG_COPY, First)) {
First = FALSE;
snprintf(From, PATH_MAX, "%s/%s", TIC.BBSpath, TIC.NewFile);
snprintf(To, PATH_MAX, "%s/%s", magic.Path, TIC.NewFile);
if ((rc = file_cp(From, To) == 0)) {
MagicResult((char *)"%s copied to %s", From, To);
Magic_CheckCompile();
} else
WriteError("Magic: copy: %s to %s failed, %s", strerror(rc));
}
free(From);
free(To);
}
void Magic_UnpackFile(void)
{
int rc, First = TRUE;
char *Fn, *buf = NULL, *unarc = NULL, *cmd = NULL;
Fn = calloc(PATH_MAX, sizeof(char));
while (GetMagicRec(MG_UNPACK, First)) {
First = FALSE;
buf = calloc(PATH_MAX, sizeof(char));
getcwd(buf, 128);
if (chdir(magic.Path) == 0) {
snprintf(Fn, PATH_MAX, "%s/%s", TIC.BBSpath, TIC.NewFile);
if ((unarc = unpacker(Fn)) != NULL) {
if (getarchiver(unarc)) {
cmd = xstrcpy(archiver.munarc);
if (strlen(cmd)) {
rc = execute_str(cmd, Fn, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null");
if (rc)
WriteError("$Magic: unpack in %s, error %d", magic.Path, rc);
else
MagicResult((char *)"unpacked in %s", magic.Path);
}
free(cmd);
}
}
chdir(buf);
Magic_CheckCompile();
} else
WriteError("$Magic: unpack: can't chdir \"%s\"", magic.Path);
free(buf);
}
free(Fn);
}
void Magic_Keepnum(void)
{
if (GetMagicRec(MG_KEEPNUM, TRUE)) {
TIC.KeepNum = magic.KeepNum;
MagicResult((char *)"Keep %d files", TIC.KeepNum);
}
}
void Magic_UpDateAlias(void)
{
if (GetMagicRec(MG_UPDALIAS, TRUE)) {
magic_update(TIC.TicIn.Area, TIC.NewFile);
MagicResult((char *)"Update Alias");
}
}
void Magic_AdoptFile(void)
{
int First = TRUE;
char *temp;
FILE *Tf;
temp = calloc(PATH_MAX, sizeof(char));
while (GetMagicRec(MG_ADOPT, First)) {
First = FALSE;
if (SearchTic(magic.ToArea)) {
MagicResult((char *)"Adoptfile in %s", magic.ToArea);
snprintf(temp, PATH_MAX, "%s/%s", TIC.Inbound, MakeTicName());
if ((Tf = fopen(temp, "a+")) == NULL)
WriteError("$Can't create %s", temp);
else {
fprintf(Tf, "Hatch\r\n");
fprintf(Tf, "NoMove\r\n");
fprintf(Tf, "Created MBSE BBS v%s, %s\r\n", VERSION, SHORTRIGHT);
fprintf(Tf, "Area %s\r\n", magic.ToArea);
fprintf(Tf, "Origin %s\r\n", aka2str(tic.Aka));
fprintf(Tf, "From %s\r\n", aka2str(tic.Aka));
if (strlen(TIC.TicIn.Replace))
fprintf(Tf, "Replaces %s\r\n", TIC.TicIn.Replace);
if (strlen(TIC.TicIn.Magic))
fprintf(Tf, "Magic %s\r\n", TIC.TicIn.Magic);
fprintf(Tf, "File %s\r\n", TIC.NewFile);
if (strlen(TIC.NewFullName))
fprintf(Tf, "Fullname %s\r\n", TIC.NewFullName);
fprintf(Tf, "Pth %s\r\n", TIC.BBSpath);
fprintf(Tf, "Desc %s\r\n", TIC.TicIn.Desc);
fprintf(Tf, "Crc %s\r\n", TIC.TicIn.Crc);
fprintf(Tf, "Pw %s\r\n", CFG.hatchpasswd);
fclose(Tf);
}
SearchTic(TIC.TicIn.Area);
} else
WriteError("Mgc Adopt: Area \"%s\" not found");
}
free(temp);
}
int Magic_DeleteFile(void)
{
int Result;
if ((Result = GetMagicRec(MG_DELETE, TRUE)))
MagicResult((char *)"Delete file");
return Result;
}

18
mbfido/magic.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef _MAGIC_H
#define _MAGIC_H
int GetMagicRec(int, int);
void MagicResult(char *, ...);
int Magic_MoveFile(void);
void Magic_ExecCommand(void);
void Magic_CopyFile(void);
void Magic_UnpackFile(void);
void Magic_Keepnum(void);
void Magic_UpDateAlias(void);
void Magic_AdoptFile(void);
int Magic_DeleteFile(void);
#endif

448
mbfido/makestat.c Normal file
View File

@@ -0,0 +1,448 @@
/*****************************************************************************
*
* $Id: makestat.c,v 1.31 2007/02/25 20:28:07 mbse Exp $
* Purpose ...............: Make Web statistics
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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/diesel.h"
#include "../lib/msg.h"
#include "mgrutil.h"
#include "makestat.h"
extern int do_quiet;
FILE *newpage(char *, FILE *);
FILE *newpage(char *Name, FILE *fi)
{
char *temp;
static FILE* fa;
time_t later;
later = time(NULL) + 86400;
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/stat/%s.temp", CFG.www_root, Name);
mkdirs(temp, 0755);
if ((fa = fopen(temp, "w")) == NULL) {
WriteError("$Can't create %s", temp);
} else {
MacroVars("a", "s", rfcdate(later));
MacroRead(fi, fa);
free(temp);
return fa;
}
free(temp);
return NULL;
}
void closepage(FILE *, char *, FILE *);
void closepage(FILE *fa, char *Name, FILE *fi)
{
char *temp1, *temp2;
if (fa == NULL)
return;
temp1 = calloc(PATH_MAX, sizeof(char));
temp2 = calloc(PATH_MAX, sizeof(char));
MacroRead(fi, fa);
fclose(fa);
snprintf(temp1, PATH_MAX, "%s/stat/%s.html", CFG.www_root, Name);
snprintf(temp2, PATH_MAX, "%s/stat/%s.temp", CFG.www_root, Name);
rename(temp2, temp1);
chmod(temp1, 0644);
free(temp2);
free(temp1);
fa = NULL;
}
char *adate(time_t);
char *adate(time_t now)
{
static char buf[40];
struct tm ptm;
if (now == 0L) {
snprintf(buf, 40, "&nbsp;");
} else {
ptm = *localtime(&now);
snprintf(buf, 40, "%02d-%02d-%04d %02d:%02d", ptm.tm_mday, ptm.tm_mon +1, ptm.tm_year + 1900, ptm.tm_hour, ptm.tm_min);
}
return buf;
}
void MakeStat(void)
{
FILE *fi, *fg, *fw;
char *name, *p, *q;
int i, Total, Lm, Area;
struct _history hist;
int fileptr = 0;
if (!strlen(CFG.www_root)) {
Syslog('!', "Warning, WWW root not defined, skip statistical html creation");
return;
}
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("\rMaking statistical HTML pages");
fflush(stdout);
}
Syslog('+', "Start making statistic HTML pages");
name = calloc(PATH_MAX, sizeof(char));
if (Miy == 0)
Lm = 11;
else
Lm = Miy -1;
chartran_init((char *)"CP437", (char *)"UTF-8", 'm');
snprintf(name, PATH_MAX, "%s/etc/mgroups.data", getenv("MBSE_ROOT"));
if ((fg = fopen(name, "r")) == NULL) {
WriteError("Can't open %s", name);
} else {
fread(&mgrouphdr, sizeof(mgrouphdr), 1, fg);
if ((fi = OpenMacro("html.egroups", 'E', TRUE)) == NULL) {
Syslog('+', "Can't open macro file, skipping html pages creation");
} else {
if ((fw = newpage((char *)"mgroups", fi)) != NULL) {
fileptr = ftell(fi);
while ((fread(&mgroup, mgrouphdr.recsize, 1, fg)) == 1) {
if (mgroup.Active) {
fseek(fi, fileptr, SEEK_SET);
html_massage(chartran(mgroup.Name), name, PATH_MAX -1);
MacroVars("b", "s", name);
html_massage(chartran(mgroup.Comment), name, PATH_MAX -1);
MacroVars("c", "s", name);
MacroVars("d", "s", mgroup.UseAka.zone ? aka2str(mgroup.UseAka):"&nbsp;");
MacroVars("e", "s", adate(mgroup.LastDate));
MacroVars("f", "d", mgroup.MsgsRcvd.lweek);
MacroVars("g", "d", mgroup.MsgsRcvd.month[Lm]);
MacroVars("h", "d", mgroup.MsgsSent.lweek);
MacroVars("i", "d", mgroup.MsgsSent.month[Lm]);
MacroRead(fi, fw);
}
}
closepage(fw, (char *)"mgroups", fi);
} else {
WriteError("Can't create mgroups.html");
}
fclose(fi);
MacroClear();
}
fclose(fg);
}
if (!do_quiet) {
printf(".");
fflush(stdout);
}
snprintf(name, PATH_MAX, "%s/etc/mareas.data", getenv("MBSE_ROOT"));
if ((fg = fopen(name, "r")) == NULL) {
WriteError("$Can't open %s", name);
} else {
if ((fi = OpenMacro("html.mareas", 'E', TRUE)) == NULL) {
Syslog('+', "Can't open macro file, skipping html pages creation");
} else {
if ((fw = newpage((char *)"mareas", fi)) != NULL) {
fileptr = ftell(fi);
fread(&msgshdr, sizeof(msgshdr), 1, fg);
Area = 0;
while ((fread(&msgs, msgshdr.recsize, 1, fg)) == 1) {
Area++;
if (msgs.Active) {
if (Msg_Open(msgs.Base)) {
MacroVars("k", "d", Msg_Number());
Msg_Close();
} else {
MacroVars("k", "d", 0);
}
fseek(fi, fileptr, SEEK_SET);
MacroVars("b", "d", Area);
html_massage(chartran(msgs.Name), name, PATH_MAX -1);
MacroVars("c", "s", strlen(name) ? name:"&nbsp;");
html_massage(chartran(msgs.Tag), name, PATH_MAX -1);
MacroVars("d", "s", strlen(name) ? name:"&nbsp;");
html_massage(chartran(msgs.Group), name, PATH_MAX -1);
MacroVars("e", "s", strlen(name) ? name:"&nbsp;");
MacroVars("f", "s", adate(msgs.LastRcvd));
MacroVars("g", "d", msgs.Received.lweek);
MacroVars("h", "d", msgs.Received.month[Lm]);
MacroVars("i", "d", msgs.Posted.lweek);
MacroVars("j", "d", msgs.Posted.month[Lm]);
MacroRead(fi, fw);
}
fseek(fg, msgshdr.syssize, SEEK_CUR);
}
closepage(fw, (char *)"mareas", fi);
} else {
WriteError("Can't create mareas.html");
}
fclose(fi);
MacroClear();
}
fclose(fg);
}
if (!do_quiet) {
printf(".");
fflush(stdout);
}
snprintf(name, PATH_MAX, "%s/etc/fgroups.data", getenv("MBSE_ROOT"));
if ((fg = fopen(name, "r")) == NULL) {
WriteError("$Can't open %s", name);
} else {
fread(&fgrouphdr, sizeof(fgrouphdr), 1, fg);
if ((fi = OpenMacro("html.fgroups", 'E', TRUE)) == NULL) {
Syslog('+', "Can't open macro file, skipping html pages creation");
} else {
if ((fw = newpage((char *)"fgroups", fi)) != NULL) {
fileptr = ftell(fi);
while ((fread(&fgroup, fgrouphdr.recsize, 1, fg)) == 1) {
if (fgroup.Active) {
fseek(fi, fileptr, SEEK_SET);
html_massage(chartran(fgroup.Name), name, PATH_MAX -1);
MacroVars("b", "s", name);
html_massage(chartran(fgroup.Comment), name, PATH_MAX -1);
MacroVars("c", "s", name);
MacroVars("d", "s", fgroup.UseAka.zone ? aka2str(fgroup.UseAka):"&nbsp;");
MacroVars("e", "s", adate(fgroup.LastDate));
MacroVars("f", "d", fgroup.Files.lweek);
MacroVars("g", "d", fgroup.KBytes.lweek);
MacroVars("h", "d", fgroup.Files.month[Lm]);
MacroVars("i", "d", fgroup.KBytes.month[Lm]);
MacroRead(fi, fw);
}
}
closepage(fw, (char *)"fgroups", fi);
} else {
WriteError("Can't create fgroups.html");
}
fclose(fi);
MacroClear();
}
fclose(fg);
}
if (!do_quiet) {
printf(".");
fflush(stdout);
}
snprintf(name, PATH_MAX, "%s/etc/tic.data", getenv("MBSE_ROOT"));
if ((fg = fopen(name, "r")) == NULL) {
WriteError("$Can't open %s", name);
} else {
fread(&tichdr, sizeof(tichdr), 1, fg);
if ((fi = OpenMacro("html.tic", 'E', TRUE)) == NULL) {
Syslog('+', "Can't open macro file, skipping html pages creation");
} else {
if ((fw = newpage((char *)"tic", fi)) != NULL) {
fileptr = ftell(fi);
while ((fread(&tic, tichdr.recsize, 1, fg)) == 1) {
if (tic.Active) {
fseek(fi, fileptr, SEEK_SET);
html_massage(chartran(tic.Comment), name, PATH_MAX -1);
MacroVars("b", "s", name);
html_massage(chartran(tic.Name), name, PATH_MAX -1);
MacroVars("c", "s", name);
html_massage(chartran(tic.Group), name, PATH_MAX -1);
MacroVars("d", "s", name);
MacroVars("e", "s", adate(tic.LastAction));
MacroVars("f", "d", tic.Files.lweek);
MacroVars("g", "d", tic.KBytes.lweek);
MacroVars("h", "d", tic.Files.month[Lm]);
MacroVars("i", "d", tic.KBytes.month[Lm]);
MacroRead(fi, fw);
}
fseek(fg, tichdr.syssize, SEEK_CUR);
}
closepage(fw, (char *)"tic", fi);
} else {
WriteError("Can't create tic.html");
}
fclose(fi);
MacroClear();
}
fclose(fg);
}
if (!do_quiet) {
printf(".");
fflush(stdout);
}
snprintf(name, PATH_MAX, "%s/etc/nodes.data", getenv("MBSE_ROOT"));
if ((fg = fopen(name, "r")) == NULL) {
WriteError("$Can't open %s", name);
} else {
fread(&nodeshdr, sizeof(nodeshdr), 1, fg);
if ((fi = OpenMacro("html.nodes", 'E', TRUE)) == NULL) {
Syslog('+', "Can't open macro file, skipping html pages creation");
} else {
if ((fw = newpage((char *)"nodes", fi)) != NULL) {
fileptr = ftell(fi);
while ((fread(&nodes, nodeshdr.recsize, 1, fg)) == 1) {
fseek(fg, nodeshdr.filegrp + nodeshdr.mailgrp, SEEK_CUR);
p = xstrcpy(adate(nodes.StartDate));
fseek(fi, fileptr, SEEK_SET);
if (nodes.Crash)
q = xstrcpy((char *)"Crash");
else if (nodes.Hold)
q = xstrcpy((char *)"Hold");
else
q = xstrcpy((char *)"Normal");
MacroVars("b", "s", aka2str(nodes.Aka[0]));
html_massage(chartran(nodes.Sysop), name, PATH_MAX -1);
MacroVars("c", "s", name);
MacroVars("d", "s", q);
MacroVars("e", "s", p);
MacroVars("f", "s", adate(nodes.LastDate));
MacroVars("j", "d", nodes.F_KbSent.total);
MacroVars("k", "d", nodes.F_KbRcvd.total);
MacroVars("l", "d", nodes.MailSent.total);
MacroVars("m", "d", nodes.MailRcvd.total);
MacroRead(fi, fw);
free(p);
free(q);
}
closepage(fw, (char *)"nodes", fi);
} else {
WriteError("Can't create nodes.html");
}
fclose(fi);
MacroClear();
}
fclose(fg);
}
if (!do_quiet) {
printf(".");
fflush(stdout);
}
snprintf(name, PATH_MAX, "%s/var/mailer.hist", getenv("MBSE_ROOT"));
if ((fg = fopen(name, "r")) == NULL) {
WriteError("$Can't open %s", name);
} else {
if ((fi = OpenMacro("html.mailer", 'E', TRUE)) == NULL) {
Syslog('+', "Can't open macro file, skipping html pages creation");
} else {
fseek(fg, 0, SEEK_END);
Total = (ftell(fg) / sizeof(hist)) -1;
fseek(fg, 0, SEEK_SET);
fread(&hist, sizeof(hist), 1, fg);
MacroVars("b", "s", adate(hist.online));
if ((fw = newpage((char *)"mailhistory", fi)) != NULL) {
fileptr = ftell(fi);
for (i = Total; i > 0; i--) {
fseek(fg, i * sizeof(hist), SEEK_SET);
fread(&hist, sizeof(hist), 1, fg);
fseek(fi, fileptr, SEEK_SET);
if (!strcmp(hist.aka.domain, "(null)"))
hist.aka.domain[0] = '\0';
MacroVars("c", "s", hist.aka.zone ? aka2str(hist.aka):"&nbsp;");
html_massage(chartran(hist.system_name), name, PATH_MAX -1);
MacroVars("d", "s", strlen(name) ? name:"&nbsp;");
html_massage(chartran(hist.sysop), name, PATH_MAX -1);
MacroVars("e", "s", strlen(name) ? name:"&nbsp;");
html_massage(chartran(hist.location), name, PATH_MAX -1);
MacroVars("f", "s", strlen(name) ? name:"&nbsp;");
MacroVars("g", "s", strlen(hist.tty) ? hist.tty:"&nbsp;");
MacroVars("h", "s", adate(hist.online));
MacroVars("i", "s", t_elapsed(hist.online, hist.offline));
MacroVars("j", "d", hist.sent_bytes);
MacroVars("k", "d", hist.rcvd_bytes);
MacroVars("l", "d", hist.cost);
MacroVars("m", "s", hist.inbound ? "In":"Out");
MacroRead(fi, fw);
if (CFG.www_mailerlines && ((Total - i + 1) >= CFG.www_mailerlines))
break;
}
closepage(fw, (char *)"mailhistory", fi);
} else {
WriteError("Can't create mailhistory.html");
}
fclose(fi);
MacroClear();
}
fclose(fg);
}
if (!do_quiet) {
printf(".");
fflush(stdout);
}
snprintf(name, PATH_MAX, "%s/etc/sysinfo.data", getenv("MBSE_ROOT"));
if ((fg = fopen(name, "r")) != NULL ) {
if ((fi = OpenMacro("html.sysinfo", 'E', TRUE)) == NULL) {
Syslog('+', "Can't open macro file, skipping html pages creation");
} else {
fread(&SYSINFO, sizeof(SYSINFO), 1, fg);
MacroVars("b", "d", SYSINFO.SystemCalls);
MacroVars("c", "d", SYSINFO.Pots);
MacroVars("d", "d", SYSINFO.ISDN);
MacroVars("e", "d", SYSINFO.Network);
MacroVars("f", "d", SYSINFO.Local);
MacroVars("g", "s", adate(SYSINFO.StartDate));
MacroVars("h", "s", SYSINFO.LastCaller);
MacroVars("i", "s", adate(SYSINFO.LastTime));
if ((fw = newpage((char *)"sysinfo", fi)) != NULL) {
closepage(fw, (char *)"sysinfo", fi);
} else {
WriteError("Can't create sysinfo.html");
}
fclose(fi);
MacroClear();
}
fclose(fg);
}
free(name);
Syslog('+', "Finished making statistic HTML pages");
chartran_close();
if (!do_quiet) {
printf("\r \r");
fflush(stdout);
}
}

9
mbfido/makestat.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _MAKESTAT_H
#define _MAKESTAT_H
void MakeStat(void);
#endif

125
mbfido/maketags.c Normal file
View File

@@ -0,0 +1,125 @@
/*****************************************************************************
*
* $Id: maketags.c,v 1.8 2005/08/28 14:52:15 mbse Exp $
* Purpose ...............: Make tag files
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* Michiel Broek FIDO: 2:2801/16
* Beekmansbos 10 Internet: mbroek@ux123.pttnwb.nl
* 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 "maketags.h"
void MakeTags(void)
{
FILE *fg, *fd, *td, *ad;
char *gname, *dname, *tname, *aname;
Syslog('+', "Start making tagfiles");
gname = calloc(PATH_MAX, sizeof(char));
dname = calloc(PATH_MAX, sizeof(char));
tname = calloc(PATH_MAX, sizeof(char));
aname = calloc(PATH_MAX, sizeof(char));
snprintf(gname, PATH_MAX, "%s/etc/mgroups.data", getenv("MBSE_ROOT"));
snprintf(dname, PATH_MAX, "%s/etc/mareas.data", getenv("MBSE_ROOT"));
if (((fg = fopen(gname, "r")) == NULL) || ((fd = fopen(dname, "r")) == NULL)) {
WriteError("$Can't open data");
} else {
fread(&mgrouphdr, sizeof(mgrouphdr), 1, fg);
fread(&msgshdr, sizeof(msgshdr), 1, fd);
while ((fread(&mgroup, mgrouphdr.recsize, 1, fg)) == 1) {
if (mgroup.Active) {
snprintf(tname, PATH_MAX, "%s/share/doc/tags/%s.msgs.tag", getenv("MBSE_ROOT"), mgroup.Name);
mkdirs(tname, 0755);
td = fopen(tname, "w");
snprintf(aname, PATH_MAX, "%s/share/doc/tags/%s.msgs.are", getenv("MBSE_ROOT"), mgroup.Name);
ad = fopen(aname, "w");
fprintf(ad, "; Mail areas in group %s\n", mgroup.Name);
fprintf(ad, ";\n");
fseek(fd, msgshdr.hdrsize, SEEK_SET);
while ((fread(&msgs, msgshdr.recsize, 1, fd)) == 1) {
if (msgs.Active && strlen(msgs.Tag) && strcmp(mgroup.Name, msgs.Group) == 0) {
fprintf(ad, "%-35s %s\n", msgs.Tag, msgs.Name);
fprintf(td, "%s\n", msgs.Tag);
}
fseek(fd, msgshdr.syssize, SEEK_CUR);
}
fclose(ad);
fclose(td);
}
}
fclose(fg);
fclose(fd);
}
snprintf(gname, PATH_MAX, "%s/etc/fgroups.data", getenv("MBSE_ROOT"));
snprintf(dname, PATH_MAX, "%s/etc/tic.data", getenv("MBSE_ROOT"));
if (((fg = fopen(gname, "r")) == NULL) || ((fd = fopen(dname, "r")) == NULL)) {
WriteError("$Can't open data");
} else {
fread(&fgrouphdr, sizeof(fgrouphdr), 1, fg);
fread(&tichdr, sizeof(tichdr), 1, fd);
while ((fread(&fgroup, fgrouphdr.recsize, 1, fg)) == 1) {
if (fgroup.Active) {
snprintf(tname, PATH_MAX, "%s/share/doc/tags/%s.file.tag", getenv("MBSE_ROOT"), fgroup.Name);
td = fopen(tname, "w");
snprintf(aname, PATH_MAX, "%s/share/doc/tags/%s.file.are", getenv("MBSE_ROOT"), fgroup.Name);
ad = fopen(aname, "w");
fprintf(ad, "; TIC file areas in group %s\n", fgroup.Name);
fprintf(ad, ";\n");
fseek(fd, tichdr.hdrsize, SEEK_SET);
while ((fread(&tic, tichdr.recsize, 1, fd)) == 1) {
if (tic.Active && strlen(tic.Name) && strcmp(fgroup.Name, tic.Group) == 0) {
fprintf(ad, "%-21s %s\n", tic.Name, tic.Comment);
fprintf(td, "%s\n", tic.Name);
}
fseek(fd, tichdr.syssize, SEEK_CUR);
}
fclose(ad);
fclose(td);
}
}
fclose(fg);
fclose(fd);
}
free(aname);
free(tname);
free(dname);
free(gname);
}

9
mbfido/maketags.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _MAKETAGS_H
#define _MAKETAGS_H
void MakeTags(void);
#endif

197
mbfido/mbaff.c Normal file
View File

@@ -0,0 +1,197 @@
/*****************************************************************************
*
* $Id: mbaff.c,v 1.22 2007/09/02 11:17:32 mbse Exp $
* Purpose ...............: Announce new files and FileFind
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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 "../lib/msg.h"
#include "announce.h"
#include "filefind.h"
#include "mbaff.h"
int do_announce = FALSE; /* Announce flag */
int do_filefind = FALSE; /* FileFind flag */
extern int do_quiet; /* Suppress screen output */
extern int show_log; /* Show logging */
time_t t_start; /* Start time */
time_t t_end; /* End time */
void ProgName(void)
{
if (do_quiet)
return;
mbse_colour(WHITE, BLACK);
printf("\nMBAFF: MBSE BBS %s Announce new files and FileFind\n", VERSION);
mbse_colour(YELLOW, BLACK);
printf(" %s\n", COPYRIGHT);
}
void die(int onsig)
{
signal(onsig, SIG_IGN);
if (onsig) {
if (onsig <= NSIG)
WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]);
else
WriteError("Terminated with error %d", onsig);
}
ulockprogram((char *)"mbaff");
t_end = time(NULL);
Syslog(' ', "MBAFF finished in %s", t_elapsed(t_start, t_end));
if (!do_quiet) {
mbse_colour(LIGHTGRAY, BLACK);
printf("\n");
}
ExitClient(onsig);
}
int main(int argc, char **argv)
{
int i, Mail = FALSE;
char *cmd;
struct passwd *pw;
struct tm *t;
InitConfig();
mbse_TermInit(1, 80, 25);
t_start = time(NULL);
t = localtime(&t_start);
Diw = t->tm_wday;
Miy = t->tm_mon;
umask(002);
/*
* Catch all signals we can, and ignore the rest.
*/
for (i = 0; i < NSIG; i++) {
if ((i == SIGHUP) || (i == SIGINT) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM) || (i == SIGIOT))
signal(i, (void (*))die);
else if ((i != SIGKILL) && (i != SIGSTOP))
signal(i, SIG_IGN);
}
if (argc < 2)
Help();
cmd = xstrcpy((char *)"Command line: mbaff");
for (i = 1; i < argc; i++) {
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, tl(argv[i]));
if (!strncmp(argv[i], "a", 1))
do_announce = TRUE;
if (!strncmp(argv[i], "f", 1))
do_filefind = TRUE;
if (!strncmp(argv[i], "-q", 2))
do_quiet = TRUE;
}
ProgName();
pw = getpwuid(getuid());
InitClient(pw->pw_name, (char *)"mbaff", CFG.location, CFG.logfile,
CFG.util_loglevel, CFG.error_log, CFG.mgrlog, CFG.debuglog);
Syslog(' ', " ");
Syslog(' ', "MBAFF v%s", VERSION);
Syslog(' ', cmd);
free(cmd);
if (!do_quiet)
printf("\n");
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
if (lockprogram((char *)"mbaff")) {
if (!do_quiet)
printf("Can't lock mbaff, abort.\n");
die(MBERR_NO_PROGLOCK);
}
memset(&MsgBase, 0, sizeof(MsgBase));
if (do_announce)
if (Announce())
Mail = TRUE;
if (do_filefind)
if (Filefind())
Mail = TRUE;
if (Mail) {
CreateSema((char *)"mailout");
CreateSema((char *)"msglink");
}
die(MBERR_OK);
return 0;
}
void Help(void)
{
do_quiet = FALSE;
ProgName();
mbse_colour(LIGHTMAGENTA, BLACK);
printf("\nUsage: mbaff [command] <options>\n\n");
mbse_colour(LIGHTBLUE, BLACK);
printf(" Commands are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" a announce Announce new files\n");
printf(" f filefind FileFind service\n");
mbse_colour(LIGHTBLUE, BLACK);
printf("\n Options are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" -q -quiet Quiet mode\n");
mbse_colour(LIGHTGRAY, BLACK);
printf("\n");
die(MBERR_COMMANDLINE);
}

9
mbfido/mbaff.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _MBAFF_H_
#define _MBAFF_H
void Help(void); /* Show help screen */
#endif

574
mbfido/mbdiff.c Normal file
View File

@@ -0,0 +1,574 @@
/*****************************************************************************
*
* $Id: mbdiff.c,v 1.32 2008/11/26 22:12:28 mbse Exp $
* Purpose ...............: Nodelist diff processor
* Original ideas ........: Eugene G. Crosser.
*
*****************************************************************************
* Copyright (C) 1997-2008
*
* 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 "mbdiff.h"
#ifndef BLKSIZ
#define BLKSIZ 512
#endif
extern unsigned short crc16xmodemtab[];
#define updcrc(cp, crc) ( crc16xmodemtab[((crc >> 8) & 255) ^ cp] ^ (crc << 8))
extern int show_log;
extern int e_pid;
extern int do_quiet; /* Suppress screen output */
extern int show_log; /* Show logging */
time_t t_start; /* Start time */
time_t t_end; /* End time */
void ProgName(void)
{
if (do_quiet)
return;
mbse_colour(WHITE, BLACK);
printf("\nMBDIFF: MBSE BBS %s Nodelist diff processor\n", VERSION);
mbse_colour(YELLOW, BLACK);
printf(" %s\n", COPYRIGHT);
}
void die(int onsig)
{
/*
* First check if a child is running, if so, kill it.
*/
if (e_pid) {
if ((kill(e_pid, SIGTERM)) == 0)
Syslog('+', "SIGTERM to pid %d succeeded", e_pid);
else {
if ((kill(e_pid, SIGKILL)) == 0)
Syslog('+', "SIGKILL to pid %d succeded", e_pid);
else
WriteError("$Failed to kill pid %d", e_pid);
}
/*
* In case the child had the tty in raw mode...
*/
execute_pth((char *)"stty", (char *)"sane", (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null");
}
signal(onsig, SIG_IGN);
if (onsig) {
if (onsig <= NSIG)
WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]);
else
WriteError("Terminated with error %d", onsig);
}
t_end = time(NULL);
Syslog(' ', "MBDIFF finished in %s", t_elapsed(t_start, t_end));
if (!do_quiet) {
mbse_colour(LIGHTGRAY, BLACK);
printf("\n");
}
ExitClient(onsig);
}
int main(int argc, char **argv)
{
int i, Match, rc;
char *cmd, *nl = NULL, *nd = NULL, *nn, *p, *q, *arc, *wrk, *onl, *ond;
struct passwd *pw;
DIR *dp;
struct dirent *de;
InitConfig();
mbse_TermInit(1, 80, 25);
t_start = time(NULL);
umask(002);
/*
* Catch all signals we can, and ignore the rest.
*/
for (i = 0; i < NSIG; i++) {
if ((i == SIGHUP) || (i == SIGINT) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGIOT))
signal(i, (void (*))die);
else if (i == SIGCHLD)
signal(i, SIG_DFL);
else if ((i != SIGKILL) && (i != SIGSTOP))
signal(i, SIG_IGN);
}
if(argc < 3)
Help();
cmd = xstrcpy((char *)"Cmd: mbdiff");
for (i = 1; i < argc; i++) {
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if (i == 1)
if ((nl = argv[i]) == NULL)
Help();
if (i == 2)
if ((nd = argv[i]) == NULL)
Help();
if (!strncasecmp(argv[i], "-q", 2))
do_quiet = TRUE;
}
ProgName();
pw = getpwuid(getuid());
InitClient(pw->pw_name, (char *)"mbdiff", CFG.location, CFG.logfile,
CFG.util_loglevel, CFG.error_log, CFG.mgrlog, CFG.debuglog);
Syslog(' ', " ");
Syslog(' ', "MBDIFF v%s", VERSION);
Syslog(' ', cmd);
free(cmd);
if (!do_quiet) {
mbse_colour(LIGHTRED, BLACK);
printf("\n");
}
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
/*
* Extract work directory from the first commandline parameter
* and set that directory as default.
*/
show_log = TRUE;
wrk = xstrcpy(nl);
if (strrchr(wrk, '/') == NULL) {
WriteError("No path in nodelist name");
free(wrk);
die(MBERR_COMMANDLINE);
}
if (strrchr(wrk, '.') != NULL) {
WriteError("Filename extension given for nodelist");
free(wrk);
die(MBERR_COMMANDLINE);
}
if (strrchr(nd, '/') == NULL) {
WriteError("No path in nodediff name");
free(wrk);
die(MBERR_COMMANDLINE);
}
show_log = FALSE;
while (wrk[strlen(wrk) -1] != '/')
wrk[strlen(wrk) -1] = '\0';
wrk[strlen(wrk) -1] = '\0';
show_log = TRUE;
if (access(wrk, R_OK|W_OK)) {
WriteError("$No R/W access in %s", wrk);
free(wrk);
die(MBERR_INIT_ERROR);
}
if (chdir(wrk)) {
WriteError("$Can't chdir to %s", wrk);
free(wrk);
die(MBERR_INIT_ERROR);
}
show_log = FALSE;
onl = xstrcpy(strrchr(nl, '/') + 1);
onl = xstrcat(onl, (char *)".???");
if ((dp = opendir(wrk)) == 0) {
show_log = TRUE;
free(wrk);
WriteError("$Error opening directory %s", wrk);
die(MBERR_INIT_ERROR);
}
Match = FALSE;
while ((de = readdir(dp))) {
if (strlen(de->d_name) == strlen(onl)) {
Match = TRUE;
for (i = 0; i < strlen(onl); i++) {
if ((onl[i] != '?') && (onl[i] != de->d_name[i]))
Match = FALSE;
}
if (Match) {
free(onl);
onl = xstrcpy(de->d_name);
break;
}
}
}
closedir(dp);
if (!Match) {
show_log = TRUE;
free(wrk);
free(onl);
WriteError("Old nodelist not found");
die(MBERR_INIT_ERROR);
}
/*
* Now try to get the diff file into the workdir.
*/
if ((arc = unpacker(nd)) == NULL) {
show_log = TRUE;
WriteError("Can't get filetype for %s", nd);
free(onl);
free(wrk);
die(MBERR_CONFIG_ERROR);
}
ond = xstrcpy(strrchr(nd, '/') + 1);
if (strncmp(arc, "ASC", 3)) {
if (!getarchiver(arc)) {
show_log = TRUE;
free(onl);
free(wrk);
free(ond);
WriteError("Can't find unarchiver %s", arc);
die(MBERR_CONFIG_ERROR);
}
/*
* We may both use the unarchive command for files and mail,
* unarchiving isn't recursive anyway.
*/
if (strlen(archiver.funarc))
cmd = xstrcpy(archiver.funarc);
else
cmd = xstrcpy(archiver.munarc);
if ((cmd == NULL) || (strlen(cmd) == 0)) {
show_log = TRUE;
free(cmd);
free(onl);
free(wrk);
free(ond);
WriteError("No unarc command available for %s", arc);
die(MBERR_CONFIG_ERROR);
}
if (execute_str(cmd, nd, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null")) {
show_log = TRUE;
free(cmd);
free(onl);
free(wrk);
free(ond);
WriteError("Fatal: unpack error");
die(MBERR_EXEC_FAILED);
}
free(cmd);
Match = FALSE;
if ((dp = opendir(wrk)) != NULL) {
while ((de = readdir(dp))) {
if (strlen(ond) == strlen(de->d_name)) {
Match = TRUE;
for (i = 0; i < (strlen(ond) -3); i++)
if (toupper(ond[i]) != toupper(de->d_name[i]))
Match = FALSE;
if (Match) {
free(ond);
ond = xstrcpy(de->d_name);
break;
}
}
}
closedir(dp);
}
if (!Match) {
show_log = TRUE;
free(ond);
free(onl);
free(wrk);
WriteError("Could not find extracted file");
die(MBERR_DIFF_ERROR);
}
} else {
if ((rc = file_cp(nd, ond))) {
show_log = TRUE;
free(ond);
free(onl);
free(wrk);
WriteError("Copy %s failed, %s", nd, strerror(rc));
die(MBERR_DIFF_ERROR);
}
}
if (((p = strrchr(onl, '.'))) && ((q = strrchr(ond, '.'))) && (strlen(p) == strlen(q))) {
nn = xstrcpy(onl);
p = strrchr(nn, '.') + 1;
q++;
strcpy(p, q);
} else
nn = xstrcpy((char *)"newnodelist");
if (strcmp(onl, nn) == 0) {
show_log = TRUE;
WriteError("Attempt to update nodelist to the same version");
unlink(ond);
free(ond);
free(onl);
free(wrk);
free(nn);
die(MBERR_DIFF_ERROR);
}
Syslog('+', "Apply %s with %s to %s", onl, ond, nn);
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("Apply %s with %s to %s\n", onl, ond, nn);
}
rc = apply(onl, ond, nn);
unlink(ond);
if (rc) {
unlink(nn);
free(nn);
free(ond);
free(onl);
free(wrk);
die(MBERR_DIFF_ERROR);
} else {
unlink(onl);
cmd = xstrcpy(archiver.farc);
if ((cmd == NULL) || (!strlen(cmd))) {
free(cmd);
Syslog('+', "No archive command for %s, fallback to ZIP", arc);
if (!getarchiver((char *)"ZIP")) {
WriteError("No ZIP command available");
free(ond);
free(onl);
free(wrk);
free(nn);
die(MBERR_DIFF_ERROR);
} else {
cmd = xstrcpy(archiver.farc);
}
} else {
free(cmd);
cmd = xstrcpy(archiver.farc);
}
if ((cmd == NULL) || (!strlen(cmd))) {
WriteError("No archiver command available");
} else {
free(onl);
onl = xstrcpy(nn);
onl[strlen(onl) -3] = tolower(archiver.name[0]);
tl(onl);
p = xstrcpy(onl);
p = xstrcat(p, (char *)" ");
p = xstrcat(p, nn);
if (execute_str(cmd, p, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null"))
WriteError("Create %s failed", onl);
else {
CreateSema((char *)"mailin");
}
free(p);
free(cmd);
}
free(onl);
free(ond);
free(wrk);
free(nn);
die(MBERR_OK);
}
return 0;
}
void Help(void)
{
do_quiet = FALSE;
ProgName();
mbse_colour(LIGHTCYAN, BLACK);
printf("\nUsage: mbdiff [nodelist] [nodediff] <options>\n\n");
mbse_colour(CYAN, BLACK);
printf(" The nodelist must be the full path and filename\n");
printf(" without the dot and daynumber digits to the working\n");
printf(" directory of that nodelist.\n");
printf(" The nodediff must be the full path and filename\n");
printf(" to the (compressed) nodediff file in the download\n");
printf(" directory.\n");
mbse_colour(LIGHTBLUE, BLACK);
printf("\n Options are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" -quiet Quiet mode\n");
mbse_colour(LIGHTGRAY, BLACK);
printf("\n");
die(MBERR_COMMANDLINE);
}
int apply(char *nl, char *nd, char *nn)
{
FILE *fo, *fd, *fn;
unsigned char cmdbuf[BLKSIZ], lnbuf[BLKSIZ];
char *p;
int i, count, ac = 0, cc = 0, dc = 0, rc = 0, firstline = 1;
unsigned short theircrc = 0, mycrc = 0;
if ((fo = fopen(nl, "r")) == NULL) {
WriteError("$Can't open %s", nl);
return 2;
}
if ((fd = fopen(nd, "r")) == NULL) {
WriteError("$Can't open %s", nd);
fclose(fo);
return 2;
}
if ((fn = fopen(nn, "w")) == NULL) {
WriteError("$Can't open %s", nn);
fclose(fo);
fclose(fd);
return 2;
}
if ((fgets((char *)cmdbuf, sizeof(cmdbuf)-1, fd) == NULL) ||
(fgets((char *)lnbuf, sizeof(cmdbuf)-1, fo) == NULL) ||
(strcmp((char *)cmdbuf, (char *)lnbuf) != 0)) {
rc = 6;
} else {
rewind(fo);
rewind(fd);
while ((rc == 0) && fgets((char *)cmdbuf, sizeof(cmdbuf)-1, fd)) {
switch (cmdbuf[0]) {
case '\032': break;
case ';': Striplf((char *)cmdbuf);
break;
case 'A': count = atoi((char *)cmdbuf+1);
ac += count;
Striplf((char *)cmdbuf);
for (i = 0;(i < count) && (rc == 0); i++)
if (fgets((char *)lnbuf, sizeof(lnbuf)-1, fd)) {
if (firstline) {
firstline = 0;
if ((p = strrchr((char *)lnbuf, ':'))) {
theircrc = atoi((char *)p+1);
}
} else {
for (p = (char *)lnbuf; *p; p++)
mycrc = updcrc(*p, mycrc);
}
fputs((char *)lnbuf, fn);
} else
rc = 3;
break;
case 'D': count = atoi((char *)cmdbuf + 1);
dc += count;
Striplf((char *)cmdbuf);
for (i = 0;(i < count) && (rc == 0); i++)
if (fgets((char *)lnbuf, sizeof(lnbuf)-1, fo) == NULL)
rc = 3;
break;
case 'C': count = atoi((char *)cmdbuf+1);
cc += count;
Striplf((char *)cmdbuf);
for (i = 0; (i < count) && (rc == 0); i++)
if (fgets((char *)lnbuf, sizeof(lnbuf) - 1, fo)) {
/*
* Don't use EOF character for CRC test.
*/
if (lnbuf[0] != '\032') {
for (p = (char *)lnbuf; *p; p++)
mycrc = updcrc(*p, mycrc);
fputs((char *)lnbuf, fn);
}
} else
rc = 3;
break;
default: rc = 5;
break;
}
}
}
fclose(fo);
fclose(fd);
fputc('\032', fn);
fclose(fn);
if ((rc != 0) && !do_quiet) {
show_log = TRUE;
mbse_colour(LIGHTRED, BLACK);
}
if ((rc == 0) && (mycrc != theircrc))
rc = 4;
if (rc == 3) {
WriteError("Could not read some of the files");
if (!do_quiet)
printf("Could not read some of the files\n");
} else if (rc == 4) {
WriteError("CRC is %hu, should be %hu", mycrc, theircrc);
if (!do_quiet)
printf("CRC is %hu, should be %hu\n", mycrc, theircrc);
} else if (rc == 5) {
WriteError("Unknown input line: \"%s\"", cmdbuf);
if (!do_quiet)
printf("Unknown input line: \"%s\"\n", cmdbuf);
} else if (rc == 6) {
WriteError("Diff does not match old list");
if (!do_quiet)
printf("Diff does not match old list\n");
} else {
Syslog('+', "Copied %d, added %d, deleted %d, difference %d", cc, ac, dc, ac-dc);
if (!do_quiet)
printf("Created new nodelist\n");
}
return rc;
}

12
mbfido/mbdiff.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _MBFIFF_H
#define _MBDIFF_H
void Help(void);
int apply(char *, char *, char *);
char *unpacker(char *);
int getarchiver(char *);
#endif

303
mbfido/mbfadopt.c Normal file
View File

@@ -0,0 +1,303 @@
/*****************************************************************************
*
* $Id: mbfadopt.c,v 1.28 2008/02/17 17:50:14 mbse Exp $
* Purpose: File Database Maintenance - Adopt file
*
*****************************************************************************
* Copyright (C) 1997-2008
*
* 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 "mbfutil.h"
#include "mbflist.h"
extern int do_quiet; /* Suppress screen output */
extern int do_annon; /* Suppress announce file */
extern int do_novir; /* Suppress virus check */
void AdoptFile(int Area, char *File, char *Description)
{
FILE *fp;
char *temp, *temp2, *tmpdir, *unarc, *pwd, *lname, *fileid;
char Desc[256], TDesc[256];
int IsArchive = FALSE, MustRearc = FALSE, UnPacked = FALSE;
int IsVirus = FALSE, File_Id = FALSE;
int i, j, k, lines = 0, File_id_cnt = 0;
struct FILE_record f_db;
Syslog('f', "Adopt(%d, %s, %s)", Area, MBSE_SS(File), MBSE_SS(Description));
if (!do_quiet)
mbse_colour(CYAN, BLACK);
if (LoadAreaRec(Area) == FALSE)
die(MBERR_INIT_ERROR);
if (area.Available) {
temp = calloc(PATH_MAX, sizeof(char));
temp2 = calloc(PATH_MAX, sizeof(char));
pwd = calloc(PATH_MAX, sizeof(char));
tmpdir = calloc(PATH_MAX, sizeof(char));
if (CheckFDB(Area, area.Path))
die(MBERR_INIT_ERROR);
getcwd(pwd, PATH_MAX);
if (!do_quiet) {
printf("Adopt file: %s ", File);
printf("Unpacking \b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
snprintf(tmpdir, PATH_MAX, "%s/tmp/arc%d", getenv("MBSE_ROOT"), (int)getpid());
if (create_tmpwork()) {
WriteError("Can't create %s", tmpdir);
if (!do_quiet)
printf("\nCan't create dir %s\n", tmpdir);
die(MBERR_INIT_ERROR);
}
snprintf(temp, PATH_MAX, "%s/%s", pwd, File);
if (do_novir == FALSE) {
if (!do_quiet) {
printf("Virscan \b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
IsVirus = VirScanFile(temp);
}
if (IsVirus) {
WriteError("Virus found");
if (!do_quiet)
printf("\nVirus found\n");
die(MBERR_VIRUS_FOUND);
}
if ((unarc = unpacker(File))) {
IsArchive = TRUE;
if (strlen(area.Archiver) && (strcmp(unarc, area.Archiver) == 0))
MustRearc = TRUE;
UnPacked = UnpackFile(temp);
if (!UnPacked)
die(MBERR_INIT_ERROR);
}
if (!do_quiet) {
printf("Checking \b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
memset(&f_db, 0, sizeof(f_db));
strcpy(f_db.Uploader, CFG.sysop_name);
f_db.UploadDate = time(NULL);
if (do_annon)
f_db.Announced = TRUE;
if (UnPacked) {
/*
* Try to get a FILE_ID.DIZ
*/
fileid = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/tmp/arc%d", getenv("MBSE_ROOT"), (int)getpid());
snprintf(fileid, PATH_MAX, "FILE_ID.DIZ");
if (getfilecase(temp, fileid)) {
snprintf(temp, PATH_MAX, "%s/tmp/arc%d/%s", getenv("MBSE_ROOT"), (int)getpid(), fileid);
snprintf(temp2, PATH_MAX, "%s/tmp/FILE_ID.DIZ", getenv("MBSE_ROOT"));
if (file_cp(temp, temp2) == 0) {
File_Id = TRUE;
}
}
free(fileid);
if (File_Id) {
Syslog('f', "FILE_ID.DIZ found");
if ((fp = fopen(temp2, "r"))) {
/*
* Read no more then 25 lines
*/
while (((fgets(Desc, 255, fp)) != NULL) && (File_id_cnt < 25)) {
lines++;
/*
* Check if the FILE_ID.DIZ is in a normal layout.
* This should be max. 10 lines of max. 48 characters.
* We check at 51 characters and if the lines are longer,
* we discard the FILE_ID.DIZ file.
*/
if (strlen(Desc) > 51) {
File_id_cnt = 0;
File_Id = FALSE;
Syslog('!', "Discarding illegal formated FILE_ID.DIZ");
break;
}
if (strlen(Desc)) {
if (strlen(Desc) > 48)
Desc[48] = '\0';
j = 0;
for (i = 0; i < strlen(Desc); i++) {
if ((Desc[i] >= ' ') || (Desc[i] < 0)) {
f_db.Desc[File_id_cnt][j] = Desc[i];
j++;
}
}
File_id_cnt++;
}
}
fclose(fp);
unlink(temp2);
/*
* Strip empty lines at end of FILE_ID.DIZ
*/
while ((strlen(f_db.Desc[File_id_cnt-1]) == 0) && (File_id_cnt))
File_id_cnt--;
Syslog('f', "Got %d FILE_ID.DIZ lines", File_id_cnt);
for (i = 0; i < File_id_cnt; i++)
Syslog('f', "\"%s\"", f_db.Desc[i]);
}
}
}
if (!File_id_cnt) {
if (Description == NULL) {
WriteError("No FILE_ID.DIZ and no description on the commandline");
if (!do_quiet)
printf("\nNo FILE_ID.DIZ and no description on the commandline\n");
clean_tmpwork();
die(MBERR_COMMANDLINE);
} else {
/*
* Create description from the commandline.
*/
if (strlen(Description) < 48) {
/*
* Less then 48 chars, copy and ready.
*/
strcpy(f_db.Desc[0], Description);
File_id_cnt++;
} else {
/*
* More then 48 characters, break into multiple
* lines not longer then 48 characters.
*/
memset(&TDesc, 0, sizeof(TDesc));
strcpy(TDesc, Description);
while (strlen(TDesc) > 48) {
j = 48;
while (TDesc[j] != ' ')
j--;
strncat(f_db.Desc[File_id_cnt], TDesc, j);
File_id_cnt++;
k = strlen(TDesc);
j++; /* Correct space */
for (i = 0; i <= k; i++, j++)
TDesc[i] = TDesc[j];
}
strcpy(f_db.Desc[File_id_cnt], TDesc);
File_id_cnt++;
}
}
}
/*
* Import the file.
*/
chdir(pwd);
clean_tmpwork();
/*
* Work out the kind of filename, is it a long filename
* or a 8.3 DOS filename. The file on disk must become
* 8.3 for import.
*/
if (is_real_8_3(File)) {
Syslog('f', "Adopt, file is 8.3");
strcpy(f_db.Name, File);
strcpy(f_db.LName, File);
for (i = 0; i < strlen(File); i++)
if (isupper(f_db.LName[i]))
f_db.LName[i] = tolower(f_db.LName[i]);
} else {
Syslog('f', "Adopt, file is LFN");
strcpy(temp2, File);
name_mangle(temp2);
if (rename(File, temp2)) {
Syslog('+', "Can't rename %s to %s", File, temp2);
if (!do_quiet)
printf("\nCan't rename %s to %s\n", File, temp2);
die(MBERR_GENERAL);
}
strcpy(f_db.Name, temp2);
strcpy(f_db.LName, File);
}
f_db.Size = file_size(f_db.Name);
f_db.Crc32 = file_crc(f_db.Name, TRUE);
f_db.FileDate = file_time(f_db.Name);
snprintf(temp2, PATH_MAX, "%s/%s", area.Path, f_db.Name);
if (!do_quiet) {
printf("Adding \b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
if (strcmp(f_db.Name, f_db.LName)) {
lname = calloc(PATH_MAX, sizeof(char));
snprintf(lname, PATH_MAX, "%s/%s", area.Path, f_db.LName);
if (AddFile(f_db, Area, temp2, f_db.Name, lname) == FALSE) {
die(MBERR_GENERAL);
}
free(lname);
} else {
if (AddFile(f_db, Area, temp2, File, NULL) == FALSE) {
die(MBERR_GENERAL);
}
}
Syslog('+', "File %s added to area %d", File, Area);
if (MustRearc) {
/* Here we should call the rearc function */
}
free(pwd);
free(temp2);
free(temp);
free(tmpdir);
} else {
WriteError("Area %d is not available", Area);
if (!do_quiet)
printf("\nArea %d is not available\n", Area);
}
if (!do_quiet) {
printf("\r \r");
fflush(stdout);
}
}

8
mbfido/mbfadopt.h Normal file
View File

@@ -0,0 +1,8 @@
/* $Id: mbfadopt.h,v 1.1 2001/11/18 23:19:08 mbroek Exp $ */
#ifndef _MBFADOPT_H_
#define _MBFADOPT_H
void AdoptFile(int, char *, char *);
#endif

574
mbfido/mbfcheck.c Normal file
View File

@@ -0,0 +1,574 @@
/*****************************************************************************
*
* $Id: mbfcheck.c,v 1.39 2007/03/07 20:05:30 mbse Exp $
* Purpose: File Database Maintenance - Check filebase
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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 "mbfutil.h"
#include "mbfcheck.h"
extern int do_quiet; /* Suppress screen output */
extern int do_pack; /* Pack filebase */
int iErrors = 0;
int iTotal = 0;
int iAreasNew = 0;
void CheckArea(int); /* Check a single area */
/*
* Check file database integrity, all files in the file database must
* exist in real, the size and date/time must match, the files crc is
* checked, and if anything is wrong, the file database is updated.
* If the file is missing the entry is marked as deleted. With the
* pack option that record will be removed.
* After these checks, de database is checked for missing records, if
* there are files on disk but not in the directory these files are
* deleted. System files (beginning with a dot) are left alone and
* the files 'files.bbs', 'files.bak', '00index', 'header' 'readme'
* and 'index.html' too.
*
* Remarks: Maybe if the crc check fails, and the date and time are
* ok, the file is damaged and must be made unavailable.
*/
void Check(int AreaNr)
{
FILE *pAreas, *pFile;
char *sAreas, *fAreas, *newdir, *temp, *mname;
int i, iAreas;
DIR *dp;
struct dirent *de;
int Found;
struct FILEIndex idx;
sAreas = calloc(PATH_MAX, sizeof(char));
fAreas = calloc(PATH_MAX, sizeof(char));
temp = calloc(PATH_MAX, sizeof(char));
mname = calloc(PATH_MAX, sizeof(char));
newdir = calloc(PATH_MAX, sizeof(char));
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("Checking file database...\n");
}
iAreasNew = iTotal = iErrors = 0;
snprintf(sAreas, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen (sAreas, "r")) == NULL) {
WriteError("Can't open %s", sAreas);
die(MBERR_INIT_ERROR);
}
fread(&areahdr, sizeof(areahdr), 1, pAreas);
fseek(pAreas, 0, SEEK_END);
iAreas = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize;
if (AreaNr) {
fseek(pAreas, ((AreaNr-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&area, areahdr.recsize, 1, pAreas);
if (area.Available) {
Syslog('+', "Checking file area %ld", AreaNr);
CheckArea(AreaNr);
}
} else {
/*
* Do all areas
*/
for (i = 1; i <= iAreas; i++) {
fseek(pAreas, ((i-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&area, areahdr.recsize, 1, pAreas);
if (area.Available) {
CheckArea(i);
} else {
if (strlen(area.Name) == 0) {
snprintf(fAreas, PATH_MAX, "%s/fdb/file%d.data", getenv("MBSE_ROOT"), i);
if (unlink(fAreas) == 0) {
Syslog('+', "Removed obsolete %s", fAreas);
}
}
} /* if area.Available */
}
fclose(pAreas);
}
if (! AreaNr) {
/*
* Only if we check all areas, check magic filenames.
*/
if (!do_quiet) {
printf("\rChecking magic alias names ... \r");
fflush(stdout);
}
if (!strlen(CFG.req_magic)) {
WriteError("No magic filename path configured");
} else {
if ((dp = opendir(CFG.req_magic)) == NULL) {
WriteError("$Can't open directory %s", CFG.req_magic);
} else {
while ((de = readdir(dp))) {
if (de->d_name[0] != '.') {
snprintf(temp, PATH_MAX, "%s/%s", CFG.req_magic, de->d_name);
if (file_exist(temp, X_OK) == 0) {
Syslog('f', "%s is executable", temp);
} else if (file_exist(temp, R_OK) == 0) {
if ((pFile = fopen(temp, "r"))) {
fgets(mname, PATH_MAX -1, pFile);
fclose(pFile);
Striplf(mname);
snprintf(newdir, PATH_MAX, "%s/etc/request.index", getenv("MBSE_ROOT"));
Found = FALSE;
if ((pFile = fopen(newdir, "r"))) {
while (fread(&idx, sizeof(idx), 1, pFile)) {
if ((strcmp(idx.Name, mname) == 0) || (strcmp(idx.LName, mname) == 0)) {
Found = TRUE;
break;
}
}
fclose(pFile);
}
if (!Found) {
Syslog('+', "Error: magic alias %s (%s) is invalid, removed", de->d_name, mname);
iErrors++;
unlink(temp);
}
}
} else {
Syslog('f', "%s cannot be", temp);
}
}
}
closedir(dp);
}
}
}
if (!do_quiet) {
printf("\r \r");
fflush(stdout);
}
free(mname);
free(temp);
free(newdir);
free(sAreas);
free(fAreas);
Syslog('+', "Check Areas [%6d] Files [%6d] Errors [%6d]", iAreasNew, iTotal, iErrors);
}
void CheckArea(int Area)
{
int j, Fix, inArea, rc;
char *newdir, *temp, *mname, *tname;
DIR *dp;
struct dirent *de;
int Found, Update;
char fn[PATH_MAX];
struct stat stb;
struct passwd *pw;
struct group *gr;
struct _fdbarea *fdb_area = NULL;
newdir = calloc(PATH_MAX, sizeof(char));
temp = calloc(PATH_MAX, sizeof(char));
mname = calloc(PATH_MAX, sizeof(char));
IsDoing("Check area %ld", Area);
if (!do_quiet) {
printf("\r%4d => %-44s \b\b\b\b", Area, area.Name);
fflush(stdout);
}
/*
* Check if download directory exists,
* if not, create the directory.
*/
if (access(area.Path, R_OK) == -1) {
Syslog('!', "No dir: %s", area.Path);
snprintf(newdir, PATH_MAX, "%s/foobar", area.Path);
mkdirs(newdir, 0775);
}
if (stat(area.Path, &stb) == 0) {
/*
* Very extended directory check
*/
Fix = FALSE;
if ((stb.st_mode & S_IRUSR) == 0) {
Fix = TRUE;
WriteError("No owner read access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff);
}
if ((stb.st_mode & S_IWUSR) == 0) {
Fix = TRUE;
WriteError("No owner write access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff);
}
if ((stb.st_mode & S_IRGRP) == 0) {
Fix = TRUE;
WriteError("No group read access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff);
}
if ((stb.st_mode & S_IWGRP) == 0) {
Fix = TRUE;
WriteError("No group write access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff);
}
if ((stb.st_mode & S_IROTH) == 0) {
Fix = TRUE;
WriteError("No others read access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff);
}
if (Fix) {
iErrors++;
if (chmod(area.Path, 0775))
WriteError("Could not set mode to 0775");
else
Syslog('+', "Corrected directory mode to 0775");
}
Fix = FALSE;
pw = getpwuid(stb.st_uid);
if (strcmp(pw->pw_name, (char *)"mbse")) {
WriteError("Directory %s not owned by user mbse", area.Path);
Fix = TRUE;
}
gr = getgrgid(stb.st_gid);
if (strcmp(gr->gr_name, (char *)"bbs")) {
WriteError("Directory %s not owned by group bbs", area.Path);
Fix = TRUE;
}
if (Fix) {
iErrors++;
pw = getpwnam((char *)"mbse");
gr = getgrnam((char *)"bbs");
if (chown(area.Path, pw->pw_gid, gr->gr_gid))
WriteError("Could not set owner to mbse.bbs");
else
Syslog('+', "Corrected directory owner to mbse.bbs");
}
} else {
WriteError("Can't stat %s", area.Path);
}
if ((fdb_area = mbsedb_OpenFDB(Area, 30)) == NULL)
return;
/*
* Now start checking the files in the filedatabase
* against the contents of the directory.
*/
inArea = 0;
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (chdir(area.Path)) {
WriteError("$Can't chdir to %s", area.Path);
break;
}
iTotal++;
inArea++;
snprintf(newdir, PATH_MAX, "%s", fdb.LName);
snprintf(mname, PATH_MAX, "%s", fdb.Name);
if (file_exist(fdb.LName, R_OK) && file_exist(fdb.Name, R_OK)) {
Syslog('+', "File %s area %ld not on disk.", fdb.Name, Area);
if (!fdb.NoKill) {
fdb.Deleted = TRUE;
do_pack = TRUE;
}
iErrors++;
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp, - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
}
} else {
/*
* File exists, now check the file.
*/
Marker();
Update = FALSE;
strcpy(temp, fdb.LName);
name_mangle(temp);
snprintf(mname, PATH_MAX, "%s", temp);
if (strcmp(fdb.Name, temp)) {
Syslog('!', "Converted %s to %s", fdb.Name, temp);
tname = calloc(PATH_MAX, sizeof(char));
snprintf(tname, PATH_MAX, "%s", fdb.Name);
rename(fdb.Name, mname);
snprintf(tname, PATH_MAX, "%s", fdb.LName);
unlink(fdb.LName);
symlink(mname, fdb.LName);
free(tname);
strncpy(fdb.Name, temp, 12);
iErrors++;
Update = TRUE;
}
/*
* If 8.3 and LFN are the same, try to rename the LFN to lowercase.
*/
if (strcmp(fdb.Name, fdb.LName) == 0) {
/*
* 8.3 and LFN are the same.
*/
tname = calloc(PATH_MAX, sizeof(char));
snprintf(tname, PATH_MAX, "%s", fdb.LName);
for (j = 0; j < strlen(fdb.LName); j++)
fdb.LName[j] = tolower(fdb.LName[j]);
if (strcmp(tname, fdb.LName)) {
Syslog('+', "Rename LFN from %s to %s", tname, fdb.LName);
rename(tname, newdir);
Update = TRUE;
}
free(tname);
}
/*
* At this point we may have (depending on the upgrade level)
* a real file with a long name or a real file with a short name
* or both. One of them may also be a symbolic link or not exist
* at all. Whatever it was, make it good.
*/
if ((lstat(fdb.LName, &stb) == 0) && ((stb.st_mode & S_IFLNK) != S_IFLNK)) {
/*
* Long filename is a regular file and not a symbolic link.
*/
if (lstat(mname, &stb) == 0) {
/*
* 8.3 name exists, is it a real file?
*/
if ((stb.st_mode & S_IFLNK) != S_IFLNK) {
unlink(fdb.LName);
symlink(mname, fdb.LName);
Syslog('+', "%s changed into symbolic link", fdb.LName);
iErrors++;
} else {
/*
* 8.3 is a symbolic link.
*/
unlink(mname);
rename(fdb.LName, mname);
symlink(mname, fdb.LName);
Syslog('+', "%s changed to real file", mname);
iErrors++;
}
} else {
/*
* No 8.3 name on disk.
*/
rename(fdb.LName, mname);
symlink(mname, fdb.LName);
Syslog('+', "%s changed to real file and created symbolic link", mname);
iErrors++;
}
} else if ((lstat(mname, &stb) == 0) && ((stb.st_mode & S_IFLNK) != S_IFLNK)) {
/*
* Short filename is a real file.
*/
if (lstat(fdb.LName, &stb) == 0) {
/*
* LFN exists, is it a real file?
*/
if ((stb.st_mode & S_IFLNK) != S_IFLNK) {
/*
* LFN is a real filename too.
*/
unlink(fdb.LName);
symlink(mname, fdb.LName);
Syslog('+', "%s changed into symbolic link", fdb.LName);
iErrors++;
}
} else {
/*
* No LFN, create symbolic link
*/
symlink(mname, fdb.LName);
Syslog('+', "%s created symbolic link", fdb.LName);
iErrors++;
}
} else {
/*
* Weird, could not happen
*/
Syslog('!', "Weird problem, %s is no regular file", fdb.LName);
}
/*
* It could be that there is a thumbnail made of the 8.3 filename
*/
tname = calloc(PATH_MAX, sizeof(char));
snprintf(tname, PATH_MAX, ".%s", fdb.Name);
if (file_exist(tname, R_OK) == 0) {
Syslog('+', "Removing wrong 8.3 thumbnail %s", tname);
iErrors++;
unlink(tname);
}
free(tname);
if (file_time(fdb.LName) != fdb.FileDate) {
Syslog('!', "Date mismatch area %ld file %s", Area, fdb.LName);
fdb.FileDate = file_time(fdb.LName);
iErrors++;
Update = TRUE;
}
if (file_size(fdb.LName) != fdb.Size) {
Syslog('!', "Size mismatch area %ld file %s", Area, fdb.LName);
fdb.Size = file_size(fdb.LName);
iErrors++;
Update = TRUE;
}
if (file_crc(fdb.LName, CFG.slow_util && do_quiet) != fdb.Crc32) {
Syslog('!', "CRC error area %ld, file %s", Area, fdb.LName);
fdb.Crc32 = file_crc(fdb.LName, CFG.slow_util && do_quiet);
iErrors++;
Update = TRUE;
}
if (stat(fdb.LName, &stb) == 0) {
if (stb.st_mode != 0100644) {
if (chmod(fdb.LName, 0644) == 0) {
Syslog('!', "Fixed filemode area %ld, file %s", Area, fdb.LName);
iErrors++;
}
}
}
Marker();
if (Update) {
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp, - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
}
}
}
if (strlen(fdb.Magic)) {
rc = magic_check(fdb.Magic, fdb.Name);
if (rc == -1) {
Syslog('+', "Area %ld magic alias %s file %s is invalid", Area, fdb.Magic, fdb.Name);
memset(&fdb.Magic, 0, sizeof(fdb.Magic));
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp, - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
}
iErrors++;
}
}
}
if (inArea == 0)
Syslog('+', "Warning: area %ld (%s) is empty", Area, area.Name);
/*
* Check files in the directory against the database.
*/
if ((dp = opendir(area.Path)) != NULL) {
while ((de = readdir(dp)) != NULL) {
if (de->d_name[0] != '.') {
Marker();
Found = FALSE;
fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET);
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if ((strcmp(fdb.LName, de->d_name) == 0) || (strcmp(fdb.Name, de->d_name) == 0)) {
if (!Found) {
Found = TRUE;
} else {
/*
* Record has been found before, so this must be
* a double record.
*/
Syslog('!', "Double file record area %ld file %s", Area, fdb.LName);
iErrors++;
fdb.Double = TRUE;
do_pack = TRUE;
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp, - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
}
}
}
}
if ((!Found) && (strncmp(de->d_name, "files.bbs", 9)) &&
(strncmp(de->d_name, "files.bak", 9)) &&
(strncmp(de->d_name, "00index", 7)) &&
(strncmp(de->d_name, "header", 6)) &&
(strncmp(de->d_name, "index", 5)) &&
(strncmp(de->d_name, "readme", 6))) {
snprintf(fn, PATH_MAX, "%s/%s", area.Path, de->d_name);
if (stat(fn, &stb) == 0) {
if (S_ISREG(stb.st_mode)) {
if (unlink(fn) == 0) {
Syslog('!', "%s not in fdb, deleted from disk", fn);
iErrors++;
} else {
WriteError("$%s not in fdb, cannot delete", fn);
}
}
}
if (lstat(fn, &stb) == 0) {
if (unlink(fn) == 0) {
Syslog('!', "%s dead link removed from disk", fn);
iErrors++;
} else {
WriteError("$%s link not in fdb, cannot delete", fn);
}
}
}
}
}
closedir(dp);
} else {
WriteError("Can't open %s", area.Path);
}
mbsedb_CloseFDB(fdb_area);
iAreasNew++;
free(newdir);
free(temp);
free(mname);
}

8
mbfido/mbfcheck.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef _MBFCHECK_H
#define _MBFCHECK_H
/* $Id: mbfcheck.h,v 1.3 2005/10/11 20:49:47 mbse Exp $ */
void Check(int); /* Check file database */
#endif

118
mbfido/mbfdel.c Normal file
View File

@@ -0,0 +1,118 @@
/*****************************************************************************
*
* $Id: mbfdel.c,v 1.17 2005/08/11 21:05:15 mbse Exp $
* Purpose: File Database Maintenance - Delete/Undelete a file
*
*****************************************************************************
* 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 "mbfutil.h"
#include "mbfmove.h"
extern int do_quiet; /* Suppress screen output */
/*
* Delete a file
*/
void Delete(int UnDel, int Area, char *File)
{
char mask[256];
int rc = FALSE;
struct _fdbarea *fdb_area = NULL;
if (UnDel)
IsDoing("Undelete file");
else
IsDoing("Delete file");
mbse_colour(LIGHTRED, BLACK);
/*
* Check area
*/
if (LoadAreaRec(Area) == FALSE) {
WriteError("Can't load record %d", Area);
die(MBERR_INIT_ERROR);
}
if (!area.Available) {
WriteError("Area %d not available", Area);
if (!do_quiet)
printf("Area %d not available\n", Area);
die(MBERR_CONFIG_ERROR);
}
if ((fdb_area = mbsedb_OpenFDB(Area, 30)) == NULL)
die(MBERR_GENERAL);
mbse_colour(CYAN, BLACK);
strcpy(mask, re_mask(File, FALSE));
if (re_comp(mask))
die(MBERR_GENERAL);
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (re_exec(fdb.LName) || re_exec(fdb.Name)) {
if (UnDel && fdb.Deleted) {
fdb.Deleted = FALSE;
Syslog('+', "Marked file %s in area %d for undeletion", fdb.Name, Area);
if (!do_quiet)
printf("Marked file %s in area %d for undeletion\n", fdb.Name, Area);
rc = TRUE;
}
if (!UnDel && !fdb.Deleted) {
fdb.Deleted = TRUE;
Syslog('+', "Marked file %s in area %d for deletion", fdb.Name, Area);
if (!do_quiet)
printf("Marked file %s in area %d for deletion\n", fdb.Name, Area);
rc = TRUE;
}
if (rc) {
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp, - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
} else {
rc = FALSE;
}
}
}
}
mbsedb_CloseFDB(fdb_area);
if (!rc) {
Syslog('+', "%selete %s in area %d failed", UnDel?"Und":"D", File, Area);
if (!do_quiet)
printf("%selete %s in area %d failed\n", UnDel?"Und":"D", File, Area);
}
}

8
mbfido/mbfdel.h Normal file
View File

@@ -0,0 +1,8 @@
/* $Id: mbfdel.h,v 1.1 2001/12/02 22:36:23 mbroek Exp $ */
#ifndef _MBFDELE_H
#define _MBFDELE_H
void Delete(int, int, char *);
#endif

912
mbfido/mbfido.c Normal file
View File

@@ -0,0 +1,912 @@
/*****************************************************************************
*
* $Id: mbfido.c,v 1.50 2007/09/02 11:17:32 mbse Exp $
* Purpose: Process Fidonet style mail and files.
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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/mbse.h"
#include "../lib/users.h"
#include "../lib/nodelist.h"
#include "../lib/mbsedb.h"
#include "../lib/msg.h"
#include "flock.h"
#include "tosspkt.h"
#include "unpack.h"
#include "orphans.h"
#include "tic.h"
#include "fsort.h"
#include "scan.h"
#include "mbfido.h"
#include "tracker.h"
#include "notify.h"
#include "rollover.h"
#include "hatch.h"
#include "scannews.h"
#include "maketags.h"
#include "makestat.h"
#include "newspost.h"
#include "rnews.h"
#include "mgrutil.h"
#include "backalias.h"
#include "rfc2ftn.h"
#include "dirsession.h"
#include "dirlock.h"
#include "queue.h"
#include "msg.h"
#include "createm.h"
#define UNPACK_FACTOR 300
int do_obs_a = FALSE; /* Obsolete command used */
int do_areas = FALSE; /* Process area taglists */
int do_toss = FALSE; /* Toss flag */
int do_scan = FALSE; /* Scan flag */
int do_tic = FALSE; /* Process .tic files */
int do_notify = FALSE; /* Create notify messages */
int do_roll = FALSE; /* Rollover only */
int do_full = FALSE; /* Full mailscan */
int do_tags = FALSE; /* Create taglists */
int do_stat = FALSE; /* Create statistic HTML pages */
int do_test = FALSE; /* Test routing */
int do_news = FALSE; /* Process NNTP news */
int do_uucp = FALSE; /* Process UUCP newsbatch */
int do_mail = FALSE; /* Process MTA email message */
int do_unsec = FALSE; /* Unsecure tossing */
int do_learn = FALSE; /* News articles learnmode */
int check_crc = TRUE; /* Check .tic crc values */
int check_dupe = TRUE; /* Check duplicates */
int do_flush = FALSE; /* Flush outbound queue */
int flushed = FALSE; /* If anything was flushed */
int areas_changed = FALSE; /* If echoareas are changed */
extern int do_quiet; /* Quiet flag */
extern int e_pid; /* Pid of child process */
extern int show_log; /* Show logging on screen */
int do_unprot = FALSE; /* Unprotected inbound flag */
time_t t_start; /* Start time */
time_t t_end; /* End time */
int packets = 0; /* Tossed packets */
int packets_ok = 0; /* Tossed packets Ok. */
char *envptr = NULL;
extern int net_in, net_imp, net_out, net_bad, net_msgs;
extern int echo_in, echo_imp, echo_out, echo_bad, echo_dupe;
extern int email_in, email_imp, email_out, email_bad;
extern int news_in, news_imp, news_out, news_bad, news_dupe;
extern int tic_in, tic_imp, tic_out, tic_bad, tic_dup;
extern int Magics, Hatched;
extern int notify, filemgr, areamgr;
void editor_configs(void);
/*
* If we don't know what to type
*/
void Help(void)
{
do_quiet = FALSE;
ProgName();
mbse_colour(LIGHTCYAN, BLACK);
printf("\nUsage: mbfido [command(s)] <options>\n\n");
mbse_colour(LIGHTBLUE, BLACK);
printf(" Commands are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" a areas Process Areas taglists\n");
printf(" m mail <recipient> ... MTA Mail mode\n");
printf(" ne news Scan for new news\n");
printf(" no notify <nodes> Send notify messages\n");
printf(" r roll Rollover statistic counters\n");
printf(" s scan Scan outgoing Fido mail\n");
printf(" ta tag Create taglists\n");
printf(" te test <node> Do routing test for node\n");
printf(" ti tic Process .tic files\n");
printf(" to toss Toss incoming Fido mail\n");
printf(" u uucp Process UUCP batchfile\n");
printf(" w web Create WWW statistics\n\n");
mbse_colour(LIGHTBLUE, BLACK);
printf(" Options are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" -f -full Full Mailscan\n");
printf(" -l -learn Learn News dupes\n");
printf(" -noc -nocrc Skip CRC checking\n");
printf(" -nod -nodupe Skip dupe checking\n");
printf(" -q -quiet Quiet mode\n");
printf(" -uns -unsecure Toss unsecure\n");
printf(" -unp -unprotect Toss unprotected inbound\n");
mbse_colour(LIGHTGRAY, BLACK);
ExitClient(MBERR_COMMANDLINE);
}
/*
* Header, only if not quiet.
*/
void ProgName(void)
{
if (do_quiet)
return;
mbse_colour(WHITE, BLACK);
printf("\nMBFIDO: MBSE BBS %s - Fidonet File and Mail processor\n", VERSION);
mbse_colour(YELLOW, BLACK);
printf(" %s\n", COPYRIGHT);
}
/*
* Create ~/etc/msg.txt for MsgEd and ~/etc/golded.inc for GoldED.
*/
void editor_configs(void)
{
char *temp;
FILE *fp;
int i;
temp = calloc(PATH_MAX, sizeof(char));
/*
* Export ~/etc/msg.txt for MsgEd.
*/
snprintf(temp, PATH_MAX, "%s/etc/msg.txt", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "w")) != NULL) {
fprintf(fp, "; msg.txt -- Automatic created by mbsetup %s -- Do not edit!\n;\n", VERSION);
fprintf(fp, "; Mail areas for MsgEd.\n;\n");
msged_areas(fp);
fclose(fp);
Syslog('+', "Created new %s", temp);
} else {
WriteError("$Could not create %s", temp);
}
/*
* Export ~/etc/golded.inc for GoldED
*/
snprintf(temp, PATH_MAX, "%s/etc/golded.inc", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "w")) != NULL) {
fprintf(fp, "; GoldED.inc -- Automatic created by mbsetup %s -- Do not edit!\n\n", VERSION);
fprintf(fp, "; Basic information.\n;\n");
if (strlen(CFG.sysop_name) && CFG.akavalid[0] && CFG.aka[0].zone) {
fprintf(fp, "USERNAME %s\n\n", CFG.sysop_name);
fprintf(fp, "ADDRESS %s\n", aka2str(CFG.aka[0]));
for (i = 1; i < 40; i++)
if (CFG.akavalid[i])
fprintf(fp, "AKA %s\n", aka2str(CFG.aka[i]));
fprintf(fp, "\n");
gold_akamatch(fp);
fprintf(fp, "; JAM MessageBase Setup\n;\n");
fprintf(fp, "JAMPATH %s/tmp/\n", getenv("MBSE_ROOT"));
fprintf(fp, "JAMHARDDELETE NO\n\n");
fprintf(fp, "; Semaphore files\n;\n");
fprintf(fp, "SEMAPHORE NETSCAN %s/var/sema/mailout\n", getenv("MBSE_ROOT"));
fprintf(fp, "SEMAPHORE ECHOSCAN %s/var/sema/mailout\n\n", getenv("MBSE_ROOT"));
gold_areas(fp);
}
fclose(fp);
Syslog('+', "Created new %s", temp);
} else {
WriteError("$Could not create %s", temp);
}
free(temp);
}
void die(int onsig)
{
/*
* First check if there is a child running, if so, kill it.
*/
if (e_pid) {
if ((kill(e_pid, SIGTERM)) == 0)
Syslog('+', "SIGTERM to pid %d succeeded", e_pid);
else {
if ((kill(e_pid, SIGKILL)) == 0)
Syslog('+', "SIGKILL to pid %d succeeded", e_pid);
else
WriteError("Failed to kill pid %d", e_pid);
}
/*
* In case the child had the tty in raw mode, reset the tty.
*/
execute_pth((char *)"stty", (char *)"sane", (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null");
}
if (onsig != MBERR_NO_PROGLOCK)
CloseDupes();
/*
* Check for locked and open message base.
*/
if (MsgBase.Locked)
Msg_UnLock();
if (MsgBase.Open)
Msg_Close();
signal(onsig, SIG_IGN);
deinitnl();
clean_tmpwork();
if (!do_quiet) {
show_log = TRUE;
mbse_colour(CYAN, BLACK);
}
if (onsig) {
if (onsig <= NSIG)
WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]);
else
WriteError("Terminated with error %d", onsig);
} else {
if (areas_changed)
editor_configs();
}
if (echo_imp + net_imp + net_out + echo_out)
CreateSema((char *)"msglink");
if ((echo_out + net_out + tic_out) || flushed)
CreateSema((char *)"scanout");
if (tic_imp)
CreateSema((char *)"reqindex");
if (net_in + net_imp + net_out + net_bad + net_msgs) {
Syslog('+', "Netmail [%4d] import [%4d] out [%4d] bad [%4d] msgs [%4d]", net_in, net_imp, net_out, net_bad, net_msgs);
SockS("MSTN:3,%d,%d,%d;", net_in, net_out, net_bad);
}
if (email_in + email_imp + email_out + email_bad) {
Syslog('+', "Email [%4d] import [%4d] out [%4d] bad [%4d]", email_in, email_imp, email_out, email_bad);
SockS("MSTI:3,%d,%d,%d;", email_in, email_out, email_bad);
}
if (echo_in + echo_imp + echo_out + echo_bad + echo_dupe) {
Syslog('+', "Echomail [%4d] import [%4d] out [%4d] bad [%4d] dupe [%4d]", echo_in, echo_imp, echo_out, echo_bad, echo_dupe);
SockS("MSTE:4,%d,%d,%d,%d;", echo_in, echo_out, echo_bad, echo_dupe);
}
if (news_in + news_imp + news_out + news_bad + news_dupe) {
Syslog('+', "News [%4d] import [%4d] out [%4d] bad [%4d] dupe [%4d]", news_in, news_imp, news_out, news_bad, news_dupe);
SockS("MSTR:4,%d,%d,%d,%d;", news_in, news_out, news_bad, news_dupe);
}
if (tic_in + tic_imp + tic_out + tic_bad + tic_dup)
Syslog('+', "TICfiles [%4d] import [%4d] out [%4d] bad [%4d] dupe [%4d]", tic_in, tic_imp, tic_out, tic_bad, tic_dup);
if (Magics + Hatched)
Syslog('+', " Magics [%4d] hatch [%4d]", Magics, Hatched);
if (tic_in + tic_imp + tic_out + tic_bad + tic_dup + Magics + Hatched)
SockS("MSTF:6,%d,%d,%d,%d,%d,%d;", tic_in, tic_out, tic_bad, tic_dup, Magics, Hatched);
if (notify + areamgr + filemgr)
Syslog('+', "Notify msgs [%4d] AreaMgr [%4d] FileMgr [%4d]", notify, areamgr, filemgr);
/*
* There should be no locks anymore, but in case of a crash try to unlock
* all possible directories. Only if onsig <> 110, this was a lock error
* and there should be no lock. We prevent removing the lock of another
* mbfido this way.
*/
if (onsig != MBERR_NO_PROGLOCK) {
ulockdir(CFG.inbound);
ulockdir(CFG.pinbound);
ulockdir(CFG.out_queue);
}
t_end = time(NULL);
Syslog(' ', "MBFIDO finished in %s", t_elapsed(t_start, t_end));
if (!do_quiet)
mbse_colour(LIGHTGRAY, BLACK);
ExitClient(onsig);
}
int main(int argc, char **argv)
{
int i, x, Loop, envrecip_count = 0;
char *p, *cmd, *temp, Options[81];
struct passwd *pw;
struct tm *t;
fa_list **envrecip, *envrecip_start = NULL;
faddr *taddr = NULL;
FILE *ofp;
/*
* The next trick is to supply a fake environment variable
* MBSE_ROOT in case we are started from UUCP or the MTA.
* this will setup the variable so InitConfig() will work.
* The /etc/passwd must point to the correct homedirectory.
* Some programs can't set uid to mbse, so mbfido is installed
* setuid mbse.
*/
if (getenv("MBSE_ROOT") == NULL) {
pw = getpwuid(getuid());
if (strcmp(pw->pw_name, "mbse")) {
/*
* We are not running as user mbse.
*/
pw = getpwnam("mbse");
if (setuid(pw->pw_uid)) {
printf("Fatal error: can't set uid to user mbse\n");
}
}
envptr = xstrcpy((char *)"MBSE_ROOT=");
envptr = xstrcat(envptr, pw->pw_dir);
putenv(envptr);
}
InitConfig();
memset(&Options, 0, sizeof(Options));
/*
* Initialize global variables, data records.
*/
InitNode();
InitMsgs();
InitTic();
InitUser();
InitFidonet();
mbse_TermInit(1, 80, 25);
t_start = time(NULL);
t = localtime(&t_start);
Diw = t->tm_wday;
Miy = t->tm_mon;
umask(002);
/*
* Catch all the signals we can, and ignore the rest.
*/
for(i = 0; i < NSIG; i++) {
if ((i == SIGINT) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM) || (i == SIGIOT))
signal(i, (void (*))die);
else if (i == SIGCHLD)
signal(i, SIG_DFL);
else if ((i != SIGKILL) && (i != SIGSTOP))
signal(i, SIG_IGN);
}
if ((p = strrchr(argv[0], '/')))
p++;
else
p = argv[0];
if (!strcmp(p, "mbmail")) {
do_quiet = TRUE;
do_mail = TRUE;
cmd = xstrcpy((char *)"Cmd: mbmail");
} else if (!strcmp(p, "mbnews")) {
do_quiet = TRUE;
do_uucp = TRUE;
cmd = xstrcpy((char *)"Cmd: mbnews");
} else {
if (argc < 2)
Help();
cmd = xstrcpy((char *)"Cmd: mbfido");
}
envrecip = &envrecip_start;
for (i = 1; i < argc; i++) {
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if ((strncmp(tl(argv[i]), "ne", 2) == 0) && !do_mail)
do_news = TRUE;
else if ((strncmp(tl(argv[i]), "no", 2) == 0) && !do_mail) {
do_notify = TRUE;
if (((i + 1) < argc) &&
((strchr(argv[i + 1], ':') != NULL) ||
(atoi(argv[i + 1])) ||
(strncmp(argv[i + 1], "*", 1) == 0))) {
snprintf(Options, 81, "%s", argv[i + 1]);
i++;
}
}
else if ((strncmp(tl(argv[i]), "r", 1) == 0) && !do_mail)
do_roll = TRUE;
else if ((strncmp(tl(argv[i]), "a", 1) == 0) && !do_mail)
do_areas = TRUE;
else if ((strncmp(tl(argv[i]), "s", 1) == 0) && !do_mail)
do_scan = TRUE;
else if ((strncmp(tl(argv[i]), "ta", 2) == 0) && !do_mail)
do_tags = TRUE;
else if ((strncmp(tl(argv[i]), "ti", 2) == 0) && !do_mail)
do_tic = TRUE;
else if ((strncmp(tl(argv[i]), "te", 2) == 0) && !do_mail) {
do_test = TRUE;
if ((i + 1) < argc) {
if ((taddr = parsefaddr(argv[i + 1])) == NULL) {
Help();
}
i++;
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
}
} else if ((strncmp(tl(argv[i]), "to", 2) == 0) && !do_mail)
do_toss = TRUE;
else if ((strncmp(tl(argv[i]), "u", 1) == 0) && !do_mail)
do_uucp = TRUE;
else if ((strncmp(tl(argv[i]), "m", 1) == 0) && !do_mail)
do_mail = TRUE;
else if ((strncmp(tl(argv[i]), "w", 1) == 0) && !do_mail)
do_stat = TRUE;
else if (strncmp(tl(argv[i]), "-f", 2) == 0)
do_full = TRUE;
else if (strncmp(tl(argv[i]), "-l", 2) == 0)
do_learn = TRUE;
else if (strncmp(tl(argv[i]), "-noc", 4) == 0)
check_crc = FALSE;
else if (strncmp(tl(argv[i]), "-nod", 4) == 0)
check_dupe = FALSE;
else if (strncmp(tl(argv[i]), "-q", 2) == 0)
do_quiet = TRUE;
else if (strncmp(tl(argv[i]), "-a", 2) == 0)
do_obs_a = TRUE;
else if (strncmp(tl(argv[i]), "-unp", 4) == 0)
do_unprot = TRUE;
else if (strncmp(tl(argv[i]), "-uns", 4) == 0)
do_unsec = TRUE;
else if (do_mail) {
/*
* Possible recipient address(es).
*/
if ((taddr = parsefaddr(argv[i]))) {
(*envrecip) = (fa_list*)malloc(sizeof(fa_list));
(*envrecip)->next = NULL;
(*envrecip)->addr = taddr;
envrecip = &((*envrecip)->next);
envrecip_count++;
} else {
cmd = xstrcat(cmd, (char *)" <- unparsable recipient! ");
}
}
}
if ((!do_areas) && (!do_toss) && (!do_scan) && (!do_tic) && (!do_notify) && (!do_roll) &&
(!do_tags) && (!do_stat) && (!do_test) && (!do_news) && (!do_uucp) && (!do_mail))
Help();
ProgName();
pw = getpwuid(getuid());
InitClient(pw->pw_name, (char *)"mbfido", CFG.location, CFG.logfile,
CFG.util_loglevel, CFG.error_log, CFG.mgrlog, CFG.debuglog);
Syslog(' ', " ");
Syslog(' ', "MBFIDO v%s", VERSION);
Syslog(' ', cmd);
free(cmd);
if (do_obs_a)
WriteError("The -a option is obsolete, adjust your setup");
/*
* Not yet locked, if anything goes wrong, exit with die(MBERR_NO_PROGLOCK)
*/
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
if (do_mail) {
/*
* Try to get a lock for a long time, another mbfido may be legally
* running since mbmail is started by the MTA instead of by mbtask.
* The timeout is 10 minutes. If mbmail times out, the MTA will
* bounce the message. What happens during the time we wait is
* unknown, will the MTA be patient enough?
*/
i = 30;
while (TRUE) {
if (do_unprot) {
if (lockdir(CFG.inbound))
break;
} else {
if (lockdir(CFG.pinbound))
break;
}
i--;
if (! i) {
WriteError("Lock timeout, aborting");
die(MBERR_NO_PROGLOCK);
}
sleep(20);
Nopper();
}
} else {
/*
* Started under control of mbtask, that means if there is a lock then
* there is something wrong; abort.
*/
if (do_unprot) {
if (! lockdir(CFG.inbound))
die(MBERR_NO_PROGLOCK);
} else {
if (! lockdir(CFG.pinbound))
die(MBERR_NO_PROGLOCK);
}
}
/*
* Locking succeeded, no more abort alowed with die(110)
*/
if (initnl())
die(MBERR_INIT_ERROR);
if (!do_mail && !do_uucp)
Rollover();
if (!do_quiet)
printf("\n");
/*
* Read alias file
*/
cmd = calloc(PATH_MAX, sizeof(char));
snprintf(cmd, PATH_MAX, "%s/etc/aliases", getenv("MBSE_ROOT"));
if ((do_news || do_scan || do_toss || do_mail) && file_exist(cmd, R_OK) == 0)
readalias(cmd);
free(cmd);
if (do_mail) {
if (!envrecip_count) {
WriteError("No valid receipients specified, aborting");
die(MBERR_NO_RECIPIENTS);
}
umask(066);
if ((ofp = tmpfile()) == NULL) {
WriteError("$Can't open tmpfile for RFC message");
die(MBERR_INIT_ERROR);
}
temp = calloc(10240, sizeof(char));
while (fgets(temp, 10240, stdin))
fprintf(ofp, temp);
free(temp);
for (envrecip = &envrecip_start; *envrecip; envrecip = &((*envrecip)->next)) {
Syslog('+', "Message to: %s", ascfnode((*envrecip)->addr, 0x7f));
rfc2ftn(ofp, (*envrecip)->addr);
}
fclose(ofp);
flush_queue();
die(MBERR_OK);
}
InitDupes();
if (do_notify)
if (Notify(Options)) {
do_flush = TRUE;
}
if (do_tic || do_toss)
toss_msgs();
if (do_tic) {
if (IsSema((char *)"mailin"))
RemoveSema((char *)"mailin");
/*
* Hatch new files and process .tic files
* until nothing left to do.
*/
Loop = TRUE;
do {
toss_msgs();
Hatch();
switch (Tic()) {
case -1: die(MBERR_OK);
break;
case 0: Loop = FALSE;
break;
default: break;
}
} while (Loop);
}
if (do_news) {
ScanNews();
if (IsSema((char *)"newnews"))
RemoveSema((char *)"newnews");
}
if (do_scan) {
toss_msgs();
ScanMail(do_full);
}
if (do_toss) {
if (IsSema((char *)"mailin"))
RemoveSema((char *)"mailin");
toss_msgs();
if (TossMail() == FALSE)
die(MBERR_OK);
}
if (do_tic || do_toss) {
/*
* Do inbound direcory sessions
*/
if (dirinbound()) {
if (do_tic) {
/*
* Hatch new files and process .tic files
* until nothing left to do.
*/
Loop = TRUE;
do {
toss_msgs();
Hatch();
switch (Tic()) {
case -1: die(MBERR_OK);
break;
case 0: Loop = FALSE;
break;
default: break;
}
} while (Loop);
}
if (do_toss) {
toss_msgs();
TossMail();
}
}
}
if (!do_uucp)
newspost();
if (do_test) {
if (taddr == NULL)
Help();
TestTracker(taddr);
tidy_faddr(taddr);
}
if (do_tags)
MakeTags();
if (do_stat)
MakeStat();
if (do_uucp)
NewsUUCP();
if (do_areas) {
if (!do_quiet) {
mbse_colour(LIGHTGREEN, BLACK);
printf("Are you sure to process all area lists [y/N] ");
fflush(stdout);
x = mbse_Getone();
printf("\r \r");
fflush(stdout);
if (toupper(x) != 'Y')
die(MBERR_OK);
}
Areas();
}
if (do_flush)
flush_queue();
die(MBERR_OK);
return 0;
}
/*
* Toss Fidonet mail
*/
int TossMail(void)
{
char *inbound, *fname;
DIR *dp;
struct dirent *de;
struct stat sbuf;
int files = 0, files_ok = 0, rc = 0, maxrc = 0;
fd_list *fdl = NULL;
if (do_unprot)
inbound = xstrcpy(CFG.inbound);
else
inbound = xstrcpy(CFG.pinbound);
Syslog('+', "Pass: toss netmail (%s)", inbound);
if (chdir(inbound) == -1) {
WriteError("$Can't chdir(%s)", inbound);
die(MBERR_INIT_ERROR);
}
/*
* First toss any netmail packets.
*/
maxrc = rc = TossPkts();
chdir(inbound);
/*
* Scan the directory for ARCmail archives. The archive extension
* numbering doesn't matter, as long as there is something, so
* all kind of ARCmail naming schemes are recognized.
*/
if ((dp = opendir(inbound)) == NULL) {
WriteError("$Can't opendir(%s)", inbound);
die(MBERR_INIT_ERROR);
}
Syslog('+', "Pass: toss ARCmail (%s)", inbound);
/*
* Add all ARCmail filenames to the memory array.
*/
sync();
while ((de=readdir(dp)))
if ((strlen(de->d_name) == 12) && ((strncasecmp(de->d_name+8,".su",3) == 0) ||
(strncasecmp(de->d_name+8,".mo",3) == 0) || (strncasecmp(de->d_name+8,".tu",3) == 0) ||
(strncasecmp(de->d_name+8,".we",3) == 0) || (strncasecmp(de->d_name+8,".th",3) == 0) ||
(strncasecmp(de->d_name+8,".fr",3) == 0) || (strncasecmp(de->d_name+8,".sa",3) == 0))) {
stat(de->d_name, &sbuf);
fill_fdlist(&fdl, de->d_name, sbuf.st_mtime);
}
closedir(dp);
sort_fdlist(&fdl);
/*
* Now process the archives, the oldest first.
*/
while ((fname = pull_fdlist(&fdl)) != NULL) {
files++;
IsDoing("Unpack arcmail");
if (IsSema((char *)"upsalarm")) {
Syslog('+', "Detected upsalarm semafore, aborting toss");
break;
}
if (enoughspace(CFG.freespace) == 0) {
Syslog('+', "Low diskspace, aborting toss");
rc = MBERR_DISK_FULL;
break;
}
if (checkspace(inbound, fname, UNPACK_FACTOR))
if ((rc = unpack(fname)) == 0) {
files_ok++;
rc = TossPkts();
chdir(inbound);
} else
WriteError("Error unpacking file %s", fname);
else
Syslog('!', "Insufficient space to unpack file %s", fname);
if (rc > maxrc)
maxrc = rc;
}
free(inbound);
if ((files || packets) && ((files_ok != files) || (packets_ok != packets)))
Syslog('!', "Processed %d of %d files, %d of %d packets, rc=%d", files_ok, files, packets_ok, packets, maxrc);
return TRUE;
}
/*
* Toss all packets currently in the inbound. Tossing is sorted by
* age of the files.
*/
int TossPkts(void)
{
char *inbound = NULL, *fname;
DIR *dp;
struct dirent *de;
struct stat sbuf;
int rc = 0, maxrc = 0;
fd_list *fdl = NULL;
IsDoing("Tossing mail");
if (do_unprot)
inbound = xstrcpy(CFG.inbound);
else
inbound = xstrcpy(CFG.pinbound);
if ((dp = opendir(inbound)) == NULL) {
WriteError("$Can't opendir(%s)", inbound);
return FALSE;
}
/*
* Read all .pkt filenames, get the timestamp and add them
* to the memory array for later sort on filedate.
*/
while ((de = readdir(dp)))
if ((strlen(de->d_name) == 12) && (strncasecmp(de->d_name+8,".pkt",4) == 0)) {
stat(de->d_name, &sbuf);
fill_fdlist(&fdl, de->d_name, sbuf.st_mtime);
}
closedir(dp);
sort_fdlist(&fdl);
/*
* Get the filenames, the oldest first until nothing left.
*/
while ((fname = pull_fdlist(&fdl)) != NULL) {
if (enoughspace(CFG.freespace) == 0) {
Syslog('+', "Low diskspace, abort tossing packet");
return FALSE;
}
packets++;
/*
* See if "pktdate" from Tobias Ernst (or another preprocessor) is installed.
*/
if (strlen(CFG.pktdate)) {
rc = execute_str(CFG.pktdate, fname, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null");
if (rc)
Syslog('+', "%s preprocessing rc=%d", fname, rc);
}
if ((rc = toss(fname)) == 0)
packets_ok++;
else
WriteError("Error tossing packet %s", fname);
if (rc > maxrc)
maxrc = rc;
}
free(inbound);
do_flush = TRUE;
return maxrc;
}
/*
* Toss one packet
*/
int toss(char *fn)
{
int rc = 0, ld;
char newname[16];
/*
* Lock the packet
*/
if ((ld = f_lock(fn)) == -1)
return 1;
rc = TossPkt(fn);
if (rc == 0) {
unlink(fn);
} else {
strncpy(newname,fn,sizeof(newname)-1);
strcpy(newname+8,".bad");
rename(fn,newname);
}
funlock(ld);
return rc;
}

15
mbfido/mbfido.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef _MBFIDO_H
#define _MBFIDO_H
/* $Id: mbfido.h,v 1.2 2005/08/10 18:57:22 mbse Exp $ */
void Help(void);
void ProgName(void);
void die(int);
int TossPkts(void);
int TossMail(void);
int toss(char *);
#endif

318
mbfido/mbfile.c Normal file
View File

@@ -0,0 +1,318 @@
/*****************************************************************************
*
* $Id: mbfile.c,v 1.38 2007/09/02 11:17:32 mbse Exp $
* Purpose: File Database Maintenance
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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 "mbfkill.h"
#include "mbfadopt.h"
#include "mbfindex.h"
#include "mbfcheck.h"
#include "mbfpack.h"
#include "mbflist.h"
#include "mbfimport.h"
#include "mbftoberep.h"
#include "mbfmove.h"
#include "mbfdel.h"
#include "mbfutil.h"
#include "mbfsort.h"
#include "mbfile.h"
#include "mbfrearc.h"
extern int do_quiet; /* Suppress screen output */
int do_annon = FALSE; /* Suppress announce on new files */
int do_novir = FALSE; /* Suppress virus check */
int do_adopt = FALSE; /* Adopt a file */
int do_pack = FALSE; /* Pack filebase */
int do_check = FALSE; /* Check filebase */
int do_kill = FALSE; /* Kill/move old files */
int do_index = FALSE; /* Create request index */
int do_import= FALSE; /* Import files in area */
int do_list = FALSE; /* List fileareas */
int do_tobe = FALSE; /* List toberep database */
int do_move = FALSE; /* Move a file */
int do_del = FALSE; /* Delete/undelete a file */
int do_sort = FALSE; /* Sort a filebase */
int do_rearc = FALSE; /* ReArc a file */
int do_force = FALSE; /* Force file overwrite */
extern int e_pid; /* Pid of external process */
extern int show_log; /* Show logging */
time_t t_start; /* Start time */
time_t t_end; /* End time */
int main(int argc, char **argv)
{
int i, Area = 0, ToArea = 0, UnDel = FALSE;
char *cmd, *FileName = NULL, *Description = NULL;
struct passwd *pw;
InitConfig();
mbse_TermInit(1, 80, 25);
t_start = time(NULL);
umask(002);
/*
* Catch all signals we can, and ignore the rest.
*/
for (i = 0; i < NSIG; i++) {
if ((i == SIGHUP) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM) || (i == SIGIOT))
signal(i, (void (*))die);
else if (i == SIGCHLD)
signal(i, SIG_DFL);
else if ((i != SIGKILL) && (i != SIGSTOP))
signal(i, SIG_IGN);
}
if(argc < 2)
Help();
cmd = xstrcpy((char *)"Command line: mbfile");
for (i = 1; i < argc; i++) {
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if (!strncasecmp(argv[i], "a", 1)) {
i++;
Area = atoi(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if (Area) {
do_adopt = TRUE;
i++;
FileName = xstrcpy(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if (argc > (i + 1)) {
i++;
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if (!strncasecmp(argv[i], "-a", 2)) {
do_annon = TRUE;
} else {
Description = xstrcpy(argv[i]);
}
}
break;
}
} else if ((!strncasecmp(argv[i], "d", 1)) || (!strncasecmp(argv[i], "u", 1))) {
if (!strncasecmp(argv[i], "u", 1))
UnDel = TRUE;
if (argc > (i + 1)) {
i++;
Area = atoi(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if (argc > (i + 1)) {
i++;
FileName = xstrcpy(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
do_del = TRUE;
}
}
} else if (!strncasecmp(argv[i], "r", 1)) {
if (argc > (i + 1)) {
i++;
Area = atoi(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if (argc > (i + 1)) {
i++;
FileName = xstrcpy(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
do_rearc = TRUE;
}
}
} else if (!strncasecmp(argv[i], "in", 2)) {
do_index = TRUE;
} else if (!strncasecmp(argv[i], "im", 2)) {
if (argc > (i + 1)) {
do_import = TRUE;
i++;
Area = atoi(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
}
} else if (!strcasecmp(argv[i], "i")) {
Help();
} else if (!strncasecmp(argv[i], "l", 1)) {
do_list = TRUE;
if (argc > (i + 1)) {
i++;
Area = atoi(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
}
} else if (!strncasecmp(argv[i], "m", 1)) {
if (argc > (i + 1)) {
i++;
Area = atoi(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if (argc > (i + 1)) {
i++;
ToArea = atoi(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if (argc > (i + 1)) {
i++;
FileName = xstrcpy(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
do_move = TRUE;
}
}
}
} else if (!strncasecmp(argv[i], "s", 1)) {
if (argc > (i + 1)) {
i++;
Area = atoi(argv[i]);
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
do_sort = TRUE;
}
} else if (!strncasecmp(argv[i], "p", 1)) {
do_pack = TRUE;
} else if (!strncasecmp(argv[i], "c", 1)) {
do_check = TRUE;
if (argc > (i + 1)) {
Area = atoi(argv[i+1]);
if (Area) {
i++;
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
}
}
} else if (!strncasecmp(argv[i], "k", 1)) {
do_kill = TRUE;
} else if (!strncasecmp(argv[i], "t", 1)) {
do_tobe = TRUE;
} else if (!strncasecmp(argv[i], "-q", 2)) {
do_quiet = TRUE;
} else if (!strncasecmp(argv[i], "-a", 2)) {
do_annon = TRUE;
} else if (!strncasecmp(argv[i], "-v", 2)) {
do_novir = TRUE;
} else if (!strncasecmp(argv[i], "-f", 2)) {
do_force = TRUE;
}
}
if (!(do_pack || do_sort || do_check || do_kill || do_index || do_import ||
do_list || do_adopt || do_del || do_move || do_tobe || do_rearc))
Help();
ProgName();
pw = getpwuid(getuid());
InitClient(pw->pw_name, (char *)"mbfile", CFG.location, CFG.logfile,
CFG.util_loglevel, CFG.error_log, CFG.mgrlog, CFG.debuglog);
Syslog(' ', " ");
Syslog(' ', "MBFILE v%s", VERSION);
Syslog(' ', cmd);
if (do_novir)
Syslog('!', "WARNING: running without virus checking");
free(cmd);
if (!do_quiet)
printf("\n");
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
if (lockprogram((char *)"mbfile")) {
if (!do_quiet)
printf("Can't lock mbfile, abort.\n");
die(MBERR_NO_PROGLOCK);
}
if (do_adopt) {
AdoptFile(Area, FileName, Description);
die(MBERR_OK);
}
if (do_import) {
ImportFiles(Area);
die(MBERR_OK);
}
if (do_kill)
Kill();
if (do_sort)
SortFileBase(Area);
if (do_check) {
Check(Area);
}
if (do_rearc) {
ReArc(Area, FileName);
if (do_index)
Index();
die(MBERR_OK);
}
if (do_pack)
PackFileBase();
if (do_index)
Index();
if (do_move) {
Move(Area, ToArea, FileName);
die(MBERR_OK);
}
if (do_del) {
Delete(UnDel, Area, FileName);
die(MBERR_OK);
}
if (do_list) {
ListFileAreas(Area);
die(MBERR_OK);
}
if (do_tobe)
ToBeRep();
die(MBERR_OK);
return 0;
}

7
mbfido/mbfile.h Normal file
View File

@@ -0,0 +1,7 @@
/* $Id: mbfile.h,v 1.3 2001/11/18 23:19:08 mbroek Exp $ */
#ifndef _MBFILE_H_
#define _MBFILE_H
#endif

434
mbfido/mbfimport.c Normal file
View File

@@ -0,0 +1,434 @@
/*****************************************************************************
*
* $Id: mbfimport.c,v 1.39 2008/02/17 17:50:14 mbse Exp $
* Purpose: File Database Maintenance - Import files with files.bbs
*
*****************************************************************************
* Copyright (C) 1997-2008
*
* 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 "mbfutil.h"
#include "mbfimport.h"
extern int do_quiet; /* Suppress screen output */
extern int do_annon; /* Suppress announce files */
extern int do_novir; /* Suppress virus scanning */
void test_file(char *, char *, char *);
/*
* Test filename in a directory case insensitive.
*/
void test_file(char *dirpath, char *search, char *result)
{
DIR *dp;
struct dirent *de;
result[0] = '\0';
Syslog('f', "test_file(%s, %s)", dirpath, search);
if ((dp = opendir(dirpath)) == NULL) {
WriteError("$Can't open directory %s", dirpath);
if (!do_quiet)
printf("\nCan't open directory %s: %s\n", dirpath, strerror(errno));
die(MBERR_INIT_ERROR);
}
while ((de = readdir(dp))) {
if (strcasecmp(de->d_name, search) == 0) {
/*
* Found the right file.
*/
strncpy(result, de->d_name, 80);
break;
}
}
closedir(dp);
}
/*
* Return 1 if imported, 0 if error.
*/
int flush_file(char *source, char *dest, char *lname, struct FILE_record f_db, int Area)
{
int Doit = TRUE, rc = 0;
Syslog('f', "flush_file(%s, %s, %s, %d)", source, dest, lname, Area);
if (do_novir == FALSE) {
if (!do_quiet) {
printf("Virscan \b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
if (VirScanFile(source)) {
Doit = FALSE;
}
}
if (Doit) {
if (!do_quiet) {
printf("Adding \b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
if (strcmp(f_db.Name, f_db.LName)) {
if (AddFile(f_db, Area, dest, source, lname)) {
rc = 1;
}
} else {
if (AddFile(f_db, Area, dest, source, NULL)) {
rc = 1;
}
}
}
return rc;
}
void ImportFiles(int Area)
{
char *pwd, *temp, *fod, *temp2, *tmpdir, *String, *token, *dest, *lname;
FILE *fbbs;
int Append = FALSE, Files = 0, i, line = 0, pos, x, y, Doit;
int Imported = 0, Errors = 0, Present = FALSE;
struct FILE_record f_db;
struct stat statfile;
if (!do_quiet)
mbse_colour(CYAN, BLACK);
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "xxxxx%d", getpid());
if ((fbbs = fopen(temp, "a+")) == NULL) {
WriteError("$Can't write to directory");
if (!do_quiet)
printf("\nCan't write to this directory, cannot import\n");
free(temp);
die(MBERR_INIT_ERROR);
}
fclose(fbbs);
unlink(temp);
free(temp);
if (LoadAreaRec(Area) == FALSE)
die(MBERR_INIT_ERROR);
if (area.Available) {
temp = calloc(PATH_MAX, sizeof(char));
temp2 = calloc(PATH_MAX, sizeof(char));
pwd = calloc(PATH_MAX, sizeof(char));
tmpdir = calloc(PATH_MAX, sizeof(char));
String = calloc(4096, sizeof(char));
dest = calloc(PATH_MAX, sizeof(char));
lname = calloc(PATH_MAX, sizeof(char));
fod = calloc(PATH_MAX, sizeof(char));
getcwd(pwd, PATH_MAX);
if (CheckFDB(Area, area.Path))
die(MBERR_GENERAL);
snprintf(tmpdir, PATH_MAX, "%s/tmp/arc%d", getenv("MBSE_ROOT"), (int)getpid());
if (create_tmpwork()) {
WriteError("Can't create %s", tmpdir);
if (!do_quiet)
printf("\nCan't create %s\n", tmpdir);
die(MBERR_GENERAL);
}
IsDoing("Import files");
/*
* Find and open files.bbs
*/
snprintf(temp, PATH_MAX, "FILES.BBS");
if (getfilecase(pwd, temp) == FALSE) {
WriteError("Can't find files.bbs anywhere");
if (!do_quiet)
printf("Can't find files.bbs anywhere\n");
die(MBERR_INIT_ERROR);
}
if ((fbbs = fopen(temp, "r")) == NULL) {
WriteError("Can't open files.bbs");
if (!do_quiet)
printf("Can't open files.bbs\n");
die(MBERR_INIT_ERROR);
}
/*
* Process files.bbs
*/
while (fgets(String, 4095, fbbs) != NULL) {
/*
* Strip cr and lf characters
*/
for (i = 0; i < strlen(String); i++) {
if (*(String + i) == '\0')
break;
if (*(String + i) == '\n')
*(String + i) = '\0';
if (*(String + i) == '\r')
*(String + i) = '\0';
}
/*
* Skip empty lines.
*/
if (strlen(String) == 0)
continue;
if ((String[0] != ' ') && (String[0] != '\t')) {
/*
* New file entry, check if there has been a file that is not yet saved.
*/
if (Append && Present) {
if (flush_file(temp, dest, lname, f_db, Area))
Imported++;
else
Errors++;
Append = FALSE;
Present = FALSE;
line = 0;
pos = 0;
}
/*
* Check diskspace
*/
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
/*
* Refresh tmpwork
*/
clean_tmpwork();
create_tmpwork();
Files++;
memset(&f_db, 0, sizeof(f_db));
Present = TRUE;
token = strtok(String, " \t\r\n\0");
test_file(pwd, token, temp2);
if (strlen(temp2) == 0) {
WriteError("Can't find file on disk, skipping: %s", token);
if (!do_quiet)
printf("\nCan't find file on disk, skipping: %s\n", token);
Append = FALSE;
Present = FALSE;
Errors++;
continue;
} else {
/*
* Check type of filename and set the right values.
*/
strcpy(fod, temp2);
if (is_real_8_3(temp2)) {
Syslog('f', "%s is 8.3", temp2);
strcpy(f_db.Name, temp2);
tl(temp2);
strcpy(f_db.LName, temp2);
} else {
Syslog('f', "%s is LFN", temp2);
strcpy(f_db.LName, temp2);
name_mangle(temp2);
strcpy(f_db.Name, temp2);
}
snprintf(temp, PATH_MAX, "%s/%s", pwd, fod);
stat(temp, &statfile);
if (do_annon)
f_db.Announced = TRUE;
Syslog('f', "File: %s (%s)", f_db.Name, f_db.LName);
if (!do_quiet) {
printf("\rImport file: %s ", f_db.Name);
printf("Checking \b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
IsDoing("Import %s", f_db.Name);
token = strtok(NULL, "\0");
if (token) {
i = strlen(token);
line = pos = 0;
for (x = 0; x < i; x++) {
if ((token[x] == '\n') || (token[x] == '\r'))
token[x] = '\0';
}
i = strlen(token);
y = 0;
if (token[0] == '[') {
/*
* Skip over download counter
*/
while (token[y] != ']')
y++;
y += 2;
}
Doit = FALSE;
for (x = y; x < i; x++) {
if (!Doit) {
if (!iscntrl(token[x]) && !isblank(token[x]))
Doit = TRUE;
}
if (Doit) {
if (pos > 42) {
if (token[x] == ' ') {
f_db.Desc[line][pos] = '\0';
line++;
pos = 0;
} else {
if (pos == 49) {
f_db.Desc[line][pos] = '\0';
pos = 0;
line++;
}
f_db.Desc[line][pos] = token[x];
pos++;
}
} else {
f_db.Desc[line][pos] = token[x];
pos++;
}
if (line == 24)
break;
}
}
} else {
/*
* No file description
*/
Syslog('+', "No file description in files.bbs for %s", f_db.LName);
strcpy(f_db.Desc[0], "No description");
}
snprintf(dest, PATH_MAX, "%s/%s", area.Path, f_db.Name);
snprintf(lname, PATH_MAX, "%s/%s", area.Path, f_db.LName);
Append = TRUE;
f_db.Size = statfile.st_size;
f_db.FileDate = statfile.st_mtime;
f_db.Crc32 = file_crc(temp, FALSE);
strcpy(f_db.Uploader, CFG.sysop_name);
f_db.UploadDate = time(NULL);
}
} else if (Present) {
/*
* Add multiple description lines
*/
if (line < 25) {
token = strtok(String, "\0");
i = strlen(token);
line++;
pos = 0;
Doit = FALSE;
for (x = 0; x < i; x++) {
if ((token[x] == '\n') || (token[x] == '\r'))
token[x] = '\0';
}
for (x = 0; x < i; x++) {
if (Doit) {
if (pos > 42) {
if (token[x] == ' ') {
f_db.Desc[line][pos] = '\0';
line++;
pos = 0;
} else {
if (pos == 49) {
f_db.Desc[line][pos] = '\0';
pos = 0;
line++;
}
f_db.Desc[line][pos] = token[x];
pos++;
}
} else {
f_db.Desc[line][pos] = token[x];
pos++;
}
if (line == 25)
break;
} else {
/*
* Skip until + or | is found
*/
if ((token[x] == '+') || (token[x] == '|'))
Doit = TRUE;
}
}
}
} /* End if new file entry found */
} /* End of files.bbs */
fclose(fbbs);
/*
* Flush the last file to the database
*/
if (Append) {
if (flush_file(temp, dest, lname, f_db, Area))
Imported++;
else
Errors++;
}
clean_tmpwork();
free(fod);
free(lname);
free(dest);
free(String);
free(pwd);
free(temp2);
free(temp);
free(tmpdir);
} else {
if (!area.Available) {
WriteError("Area not available");
if (!do_quiet)
printf("Area not available\n");
}
}
if (!do_quiet) {
printf("\r \r");
fflush(stdout);
}
Syslog('+', "Import Files [%5d] Imported [%5d] Errors [%5d]", Files, Imported, Errors);
}

10
mbfido/mbfimport.h Normal file
View File

@@ -0,0 +1,10 @@
/* $Id: mbfimport.h,v 1.1 2001/11/25 12:25:59 mbroek Exp $ */
#ifndef _MBFIMPORT_H
#define _MBFIMPORT_H
void ImportFiles(int);
#endif

822
mbfido/mbfindex.c Normal file
View File

@@ -0,0 +1,822 @@
/*****************************************************************************
*
* $Id: mbfindex.c,v 1.50 2007/02/26 21:02:31 mbse Exp $
* Purpose: File Database Maintenance - Build index for request processor
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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 "../lib/diesel.h"
#include "mbfutil.h"
#include "mbfindex.h"
extern int do_quiet; /* Suppress screen output */
extern int do_force; /* Force update */
int lastfile; /* Last file number */
int gfilepos = 0; /* Global file position */
int TotalHtml = 0; /* Total html files */
int AreasHtml = 0; /* Total html areas */
int aUpdate = 0; /* Updated areas */
typedef struct _Index {
struct _Index *next;
struct FILEIndex idx;
} Findex;
static char *wdays[]= {(char *)"Sun",(char *)"Mon",(char *)"Tue",
(char *)"Wed",(char *)"Thu",(char *)"Fri",
(char *)"Sat"};
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"};
/*
* Translate a string from ANSI to safe HTML characters
*/
/*
char *To_Html(char *);
char *To_Html(char *inp)
{
static char temp[1024];
memset(&temp, 0, sizeof(temp));
strncpy(temp, chartran(inp), sizeof(temp) -1);
return temp;
}
*/
void tidy_index(Findex **);
void tidy_index(Findex **fap)
{
Findex *tmp, *old;
for (tmp = *fap; tmp; tmp = old) {
old = tmp->next;
free(tmp);
}
*fap = NULL;
}
void fill_index(struct FILEIndex, Findex **);
void fill_index(struct FILEIndex idx, Findex **fap)
{
Findex *tmp;
tmp = (Findex *)malloc(sizeof(Findex));
tmp->next = *fap;
tmp->idx = idx;
*fap = tmp;
}
int comp_index(Findex **, Findex **);
void sort_index(Findex **);
void sort_index(Findex **fap)
{
Findex *ta, **vector;
size_t n = 0, i;
if (*fap == NULL)
return;
for (ta = *fap; ta; ta = ta->next)
n++;
vector = (Findex **)malloc(n * sizeof(Findex *));
i = 0;
for (ta = *fap; ta; ta = ta->next)
vector[i++] = ta;
qsort(vector, n, sizeof(Findex *),
(int(*)(const void*, const void *))comp_index);
(*fap) = vector[0];
i = 1;
for (ta = *fap; ta; ta = ta->next) {
if (i < n)
ta->next = vector[i++];
else
ta->next = NULL;
}
free(vector);
return;
}
int comp_index(Findex **fap1, Findex **fap2)
{
return strcasecmp((*fap1)->idx.LName, (*fap2)->idx.LName);
}
void MacroRead(FILE *, FILE *);
void MacroRead(FILE *fi, FILE *fp)
{
char *line, *temp;
int res, i;
line = calloc(MAXSTR, sizeof(char));
temp = calloc(MAXSTR, sizeof(char));
while ((fgets(line, MAXSTR-2, fi) != NULL) && ((line[0]!='@') || (line[1]!='|'))) {
/*
* Skip comment lines
*/
if (line[0] != '#') {
Striplf(line);
if (strlen(line) == 0) {
/*
* Empty lines are just written
*/
fputc('\n', fp);
} else {
strncpy(temp, ParseMacro(line,&res), MAXSTR-1);
if (res)
Syslog('!', "Macro error line: \"%s\"", line);
/*
* Only output if something was evaluated
*/
if (strlen(temp)) {
for (i = 0; i < strlen(temp); i++)
fputc(temp[i], fp);
fputc('\n', fp);
}
}
}
}
free(line);
free(temp);
gfilepos = ftell(fi);
}
char *rfcdate(time_t);
char *rfcdate(time_t now)
{
static char buf[40];
struct tm ptm;
ptm = *gmtime(&now);
snprintf(buf,40,"%s, %02d %s %04d %02d:%02d:%02d GMT",
wdays[ptm.tm_wday], ptm.tm_mday, months[ptm.tm_mon],
ptm.tm_year + 1900, ptm.tm_hour, ptm.tm_min, ptm.tm_sec);
return(buf);
}
/*
* Create the macro's for the navigation bar.
*/
void pagelink(FILE *, char *, int, int);
void pagelink(FILE *fa, char *Path, int inArea, int Current)
{
char temp[256], nr[25];
if ((Current >= CFG.www_files_page) && (inArea >= CFG.www_files_page)) {
if (((Current / CFG.www_files_page) - 1) > 0) {
snprintf(nr, 25, "%d", (Current / CFG.www_files_page) -1);
} else {
nr[0] = '\0';
}
snprintf(temp, 256, "%s/%s%s/index%s.html", CFG.www_url, CFG.www_link2ftp, Path+strlen(CFG.ftp_base), nr);
MacroVars("c", "s", temp);
} else {
MacroVars("c", "s", "");
}
if ((Current < (inArea - CFG.www_files_page)) && (inArea >= CFG.www_files_page)) {
snprintf(temp, 256, "%s/%s%s/index%d.html", CFG.www_url, CFG.www_link2ftp, Path+strlen(CFG.ftp_base),
(Current / CFG.www_files_page) + 1);
MacroVars("d", "s", temp);
} else {
MacroVars("d", "s", "");
}
}
/*
* Start a new file areas page
*/
FILE *newpage(char *, char *, time_t, int, int, FILE *);
FILE *newpage(char *Path, char *Name, time_t later, int inArea, int Current, FILE *fi)
{
char linebuf[1024], outbuf[1024];
static FILE* fa;
lastfile = Current;
if (Current)
snprintf(linebuf, 1024, "%s/index%d.temp", Path, Current / CFG.www_files_page);
else
snprintf(linebuf, 1024, "%s/index.temp", Path);
if ((fa = fopen(linebuf, "w")) == NULL) {
WriteError("$Can't create %s", linebuf);
} else {
snprintf(linebuf, 1024, "%s", Name);
html_massage(linebuf, outbuf, 1024);
MacroVars("ab", "ss", rfcdate(later), outbuf);
pagelink(fa, Path, inArea, Current);
MacroRead(fi, fa);
return fa;
}
return NULL;
}
/*
* Finish a files area page
*/
void closepage(FILE *, char *, int, int, FILE *);
void closepage(FILE *fa, char *Path, int inArea, int Current, FILE *fi)
{
char *temp1, *temp2;
if (fa == NULL)
return;
temp1 = calloc(PATH_MAX, sizeof(char));
temp2 = calloc(PATH_MAX, sizeof(char));
MacroRead(fi, fa);
fclose(fa);
if (lastfile) {
snprintf(temp1, PATH_MAX, "%s/index%d.html", Path, lastfile / CFG.www_files_page);
snprintf(temp2, PATH_MAX, "%s/index%d.temp", Path, lastfile / CFG.www_files_page);
} else {
snprintf(temp1, PATH_MAX, "%s/index.html", Path);
snprintf(temp2, PATH_MAX, "%s/index.temp", Path);
}
rename(temp2, temp1);
chmod(temp1, 0644);
free(temp1);
free(temp2);
fa = NULL;
}
/*
* Build a sorted index for the file request processor.
*/
void ReqIndex(void);
void ReqIndex(void)
{
FILE *pAreas, *pIndex, *fp;
unsigned int i, iAreas, iAreasNew = 0, record;
int iTotal = 0, j, z, x = 0;
int fbAreas = 0, fbFiles = 0, fbUpdate = 0;
char *sAreas, *newdir = NULL, *sIndex, *temp;
Findex *fdx = NULL;
Findex *tmp;
struct FILEIndex idx;
struct _fdbarea *fdb_area = NULL;
time_t db_time, obj_time;
IsDoing("Index files");
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("Create index files...\n");
}
sAreas = calloc(PATH_MAX, sizeof(char));
sIndex = calloc(PATH_MAX, sizeof(char));
temp = calloc(PATH_MAX, sizeof(char));
snprintf(sAreas, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen (sAreas, "r")) == NULL) {
WriteError("$Can't open %s", sAreas);
die(MBERR_INIT_ERROR);
}
snprintf(sIndex, PATH_MAX, "%s/etc/request.index", getenv("MBSE_ROOT"));
if ((pIndex = fopen(sIndex, "w")) == NULL) {
WriteError("$Can't create %s", sIndex);
die(MBERR_GENERAL);
}
fread(&areahdr, sizeof(areahdr), 1, pAreas);
fseek(pAreas, 0, SEEK_END);
iAreas = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize;
for (i = 1; i <= iAreas; i++) {
fseek(pAreas, ((i-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&area, areahdr.recsize, 1, pAreas);
if (area.Available) {
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
if (!do_quiet) {
printf("\r%4d => %-44s \b\b\b\b", i, area.Name);
fflush(stdout);
}
/*
* Check if download directory exists,
* if not, create the directory.
*/
if (access(area.Path, W_OK) == -1) {
Syslog('!', "Create dir: %s", area.Path);
newdir = xstrcpy(area.Path);
newdir = xstrcat(newdir, (char *)"/");
mkdirs(newdir, 0755);
free(newdir);
newdir = NULL;
}
if ((fdb_area = mbsedb_OpenFDB(i, 30)) == NULL)
die(MBERR_GENERAL);
snprintf(temp, PATH_MAX, "%s/var/fdb/file%d.data", getenv("MBSE_ROOT"), i);
db_time = (int) file_time(temp);
/*
* Create file request index if requests are allowed in this area.
*/
if (area.FileReq) {
/*
* Now start creating the unsorted index.
*/
record = 0;
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
iTotal++;
if ((iTotal % 10) == 0)
Marker();
memset(&idx, 0, sizeof(idx));
snprintf(idx.Name, 13, "%s", tu(fdb.Name));
snprintf(idx.LName, 81, "%s", tu(fdb.LName));
idx.AreaNum = i;
idx.Record = record;
fill_index(idx, &fdx);
record++;
}
iAreasNew++;
} /* if area.Filereq */
/*
* Create files.bbs if needed.
*/
snprintf(temp, PATH_MAX, "%s/files.bbs", area.Path);
obj_time = (int) file_time(temp);
if (obj_time < db_time) {
/*
* File is outdated, recreate
*/
if ((fp = fopen(temp, "w")) == NULL) {
WriteError("$Can't create %s", temp);
} else {
fbAreas++;
fbUpdate++;
fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET);
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (!fdb.Deleted) {
fbFiles++;
fprintf(fp, "%-12s [%d] %s\r\n", fdb.Name, fdb.TimesDL, fdb.Desc[0]);
for (j = 1; j < 25; j++)
if (strlen(fdb.Desc[j]))
fprintf(fp, " +%s\r\n", fdb.Desc[j]);
}
}
fclose(fp);
chmod(temp, 0644);
}
} else {
/*
* Just count for statistics
*/
fbAreas++;
fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET);
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (!fdb.Deleted) {
fbFiles++;
}
}
}
/*
* Create 00index file if needed.
*/
if (strncmp(CFG.ftp_base, area.Path, strlen(CFG.ftp_base)) == 0) {
snprintf(temp, PATH_MAX, "%s/00index", area.Path);
obj_time = (int) file_time(temp);
if (obj_time < db_time) {
/*
* File is outdated, recreate
*/
if ((fp = fopen(temp, "w")) == NULL) {
WriteError("$Can't create %s", temp);
} else {
fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET);
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (!fdb.Deleted) {
/*
* The next is to reduce system load
*/
x++;
if (CFG.slow_util && do_quiet && ((x % 3) == 0))
msleep(1);
for (z = 0; z <= 25; z++) {
if (strlen(fdb.Desc[z])) {
if (z == 0)
fprintf(fp, "%-12s %7uK %s ", fdb.Name, (int)(fdb.Size / 1024),
StrDateDMY(fdb.UploadDate));
else
fprintf(fp, " ");
if ((fdb.Desc[z][0] == '@') && (fdb.Desc[z][1] == 'X'))
fprintf(fp, "%s\n", fdb.Desc[z]+4);
else
fprintf(fp, "%s\n", fdb.Desc[z]);
}
}
}
}
fclose(fp);
chmod(temp, 0644);
}
}
}
mbsedb_CloseFDB(fdb_area);
}
}
fclose(pAreas);
sort_index(&fdx);
for (tmp = fdx; tmp; tmp = tmp->next)
fwrite(&tmp->idx, sizeof(struct FILEIndex), 1, pIndex);
fclose(pIndex);
tidy_index(&fdx);
Syslog('+', "FREQ. Areas [%6d] Files [%6d] Updated [%6d]", iAreasNew, iTotal, fbUpdate);
Syslog('+', "Index Areas [%6d] Files [%6d] Updated [%6d]", fbAreas, fbFiles, fbUpdate);
free(sAreas);
free(sIndex);
free(temp);
}
/*
* Build html index pages for download.
*/
void HtmlIndex(char *);
void HtmlIndex(char *Lang)
{
FILE *pAreas, *fa, *fb = NULL, *fm, *fi = NULL;
unsigned int i, iAreas, KSize = 0L, aSize = 0;
int AreaNr = 0, j, k, x = 0, isthumb;
int aTotal = 0, inArea = 0, filenr;
char *sAreas, *fn, *temp;
char linebuf[1024], outbuf[1024], desc[19200], namebuf[1024];
time_t last = 0L, later, db_time, obj_time;
int fileptr = 0, fileptr1 = 0;
struct _fdbarea *fdb_area = NULL;
sAreas = calloc(PATH_MAX, sizeof(char));
fn = calloc(PATH_MAX, sizeof(char));
temp = calloc(PATH_MAX, sizeof(char));
AreasHtml = 0;
TotalHtml = 0;
aUpdate = 0;
later = time(NULL) + 86400;
IsDoing("Create html");
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("\rCreate html pages... \n");
}
snprintf(sAreas, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen (sAreas, "r")) == NULL) {
WriteError("$Can't open %s", sAreas);
die(MBERR_INIT_ERROR);
}
fread(&areahdr, sizeof(areahdr), 1, pAreas);
fseek(pAreas, 0, SEEK_END);
iAreas = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize;
/*
* Check if we are able to create the index.html pages in the
* download directories.
*/
if (strlen(CFG.ftp_base) && strlen(CFG.www_url) && strlen(CFG.www_author) && strlen(CFG.www_charset)) {
snprintf(fn, PATH_MAX, "%s/index.temp", CFG.ftp_base);
if ((fm = fopen(fn, "w")) == NULL) {
Syslog('+', "Can't open %s, skipping html pages creation", fn);
}
} else {
fm = NULL;
Syslog('+', "FTP/HTML not defined, skipping html pages creation");
}
if (fm) {
if ((fi = OpenMacro("html.main", 'E', TRUE)) == NULL) {
Syslog('+', "Can't open macro file, skipping html pages creation");
fclose(fm);
unlink(fn);
}
}
if (fm) {
/*
* Because these web pages are dynamic, ie. they change everytime you
* receive new files and recreates these pages, extra HTTP headers are
* send to the client about these pages. It forbids proxy servers to
* cache these pages. The pages will expire within 24 hours. The pages
* also have an author name, this is the bbs name, and a content
* description for search engines. Automatic advertising.
*/
MacroVars("acd", "sdd", rfcdate(later), 0, 0);
MacroRead(fi, fm);
fileptr = ftell(fi);
}
/*
* Setup the correct table to produce file listings for the www.
* This make ANSI grafics look a bit nicer with browsers.
*/
chartran_init((char *)"CP437", (char *)"UTF-8", 'f');
for (i = 1; i <= iAreas; i++) {
fseek(pAreas, ((i-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&area, areahdr.recsize, 1, pAreas);
AreaNr++;
if (area.Available) {
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
if (!do_quiet) {
printf("\r%4d => %-44s \b\b\b\b", i, area.Name);
fflush(stdout);
}
if ((fdb_area = mbsedb_OpenFDB(i, 30)) == NULL)
die(MBERR_GENERAL);
snprintf(temp, PATH_MAX, "%s/var/fdb/file%d.data", getenv("MBSE_ROOT"), i);
db_time = (int) file_time(temp);
snprintf(temp, PATH_MAX, "%s/index.html", area.Path);
obj_time = (int) file_time(temp);
/*
* Create index.html pages in each available download area when not up to date.
*/
if (fm && (strncmp(CFG.ftp_base, area.Path, strlen(CFG.ftp_base)) == 0)) {
fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET);
AreasHtml++;
inArea = 0;
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (!fdb.Deleted)
inArea++;
}
fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET);
aSize = 0L;
aTotal = 0;
last = 0L;
if ((obj_time < db_time) || do_force) {
/*
* If not up todate
*/
if ((fb = OpenMacro("html.areas", 'E', TRUE)) == NULL) {
fa = NULL;
} else {
fa = newpage(area.Path, area.Name, later, inArea, aTotal, fb);
fileptr1 = gfilepos;
}
aUpdate++;
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (!fdb.Deleted) {
/*
* The next is to reduce system load
*/
x++;
TotalHtml++;
aTotal++;
if (CFG.slow_util && do_quiet && ((x % 3) == 0))
msleep(1);
MacroVars("efghijklm", "ddsssssds", 0, 0, "", "", "", "", "", 0, "");
MacroVars("e", "d", aTotal);
/*
* Check if this is a .gif or .jpg file, if so then
* check if a thumbnail file exists. If not try to
* create a thumbnail file to add to the html listing.
*/
isthumb = FALSE;
if (strstr(fdb.LName, ".gif") || strstr(fdb.LName, ".jpg") ||
strstr(fdb.LName, ".GIF") || strstr(fdb.LName, ".JPG")) {
snprintf(linebuf, 1024, "%s/%s", area.Path, fdb.LName);
snprintf(outbuf, 1024, "%s/.%s", area.Path, fdb.LName);
if (file_exist(outbuf, R_OK)) {
if (strlen(CFG.www_convert)) {
if ((execute_str(CFG.www_convert, linebuf, outbuf,
(char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null"))) {
Syslog('+', "Failed to create thumbnail for %s", fdb.LName);
} else {
chmod(outbuf, 0644);
isthumb = TRUE;
}
} else {
Syslog('+', "No convert program to create thumbnail %s", outbuf);
}
} else {
isthumb = TRUE;
}
}
snprintf(outbuf, 1024, "%s/%s%s/%s", CFG.www_url, CFG.www_link2ftp,
area.Path+strlen(CFG.ftp_base), fdb.LName);
if (isthumb) {
snprintf(linebuf, 1024, "%s/%s%s/.%s", CFG.www_url, CFG.www_link2ftp,
area.Path+strlen(CFG.ftp_base), fdb.LName);
MacroVars("fghi", "dsss", 1, outbuf, fdb.LName, linebuf);
} else {
snprintf(outbuf, 1024, "%s/%s%s/%s", CFG.www_url, CFG.www_link2ftp,
area.Path+strlen(CFG.ftp_base), fdb.LName);
MacroVars("fghi", "dsss", 0, outbuf, fdb.LName, "");
}
snprintf(outbuf, 1024, "%u Kb.", (int)(fdb.Size / 1024));
MacroVars("jkl", "ssd", StrDateDMY(fdb.FileDate), outbuf, fdb.TimesDL);
memset(&desc, 0, sizeof(desc));
k = 0;
for (j = 0; j < 25; j++)
if (strlen(fdb.Desc[j])) {
if (j) {
snprintf(desc+k, 2, "\n");
k += 1;
}
html_massage(fdb.Desc[j], linebuf, 1024);
strncpy(outbuf, chartran(linebuf), 1024);
strncat(desc, outbuf, 19200 -k);
k += strlen(outbuf);
}
MacroVars("m", "s", desc);
fseek(fb, fileptr1, SEEK_SET);
MacroRead(fb, fa);
aSize += fdb.Size;
MacroVars("efghijklm", "ddsssssds", 0, 0, "", "", "", "", "", 0, "");
if (fdb.FileDate > last)
last = fdb.FileDate;
if ((aTotal % CFG.www_files_page) == 0) {
closepage(fa, area.Path, inArea, aTotal, fb);
fseek(fb, 0, SEEK_SET);
fa = newpage(area.Path, area.Name, later, inArea, aTotal, fb);
}
} /* if (!file.deleted) */
}
if (aTotal == 0) {
/*
* Nothing written, skip skip fileblock
*/
while ((fgets(linebuf, 254, fb) != NULL) && ((linebuf[0]!='@') || (linebuf[1]!='|')));
}
KSize += aSize / 1024;
closepage(fa, area.Path, inArea, aTotal, fb);
fclose(fb);
/*
* If the time before there were more files in this area then now,
* the number of html pages may de decreased. We try to delete these
* files if they should exist.
*/
filenr = lastfile / CFG.www_files_page;
while (TRUE) {
filenr++;
snprintf(linebuf, 1024, "%s/index%d.html", area.Path, filenr);
if (unlink(linebuf))
break;
Syslog('+', "Removed obsolete %s", linebuf);
}
} else {
/*
* Area was up todate, but we need some data for the main index page.
*/
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (!fdb.Deleted) {
TotalHtml++;
aTotal++;
aSize += fdb.Size;
if (fdb.FileDate > last)
last = fdb.FileDate;
}
}
KSize += aSize / 1024;
}
strcpy(linebuf, area.Name);
html_massage(linebuf, namebuf, 1024);
snprintf(linebuf, 1024, "%s/%s%s/index.html", CFG.www_url, CFG.www_link2ftp, area.Path+strlen(CFG.ftp_base));
if (aSize > 1048576)
snprintf(outbuf, 1024, "%d Mb.", aSize / 1048576);
else
snprintf(outbuf, 1024, "%d Kb.", aSize / 1024);
MacroVars("efghi", "dssds", AreaNr, linebuf, namebuf, aTotal, outbuf);
if (last == 0L)
MacroVars("j", "s", "&nbsp;");
else
MacroVars("j", "s", StrDateDMY(last));
fseek(fi, fileptr, SEEK_SET);
MacroRead(fi, fm);
}
mbsedb_CloseFDB(fdb_area);
} /* if area.Available */
}
if (fm) {
snprintf(linebuf, 1024, "%d Mb.", KSize / 1024);
MacroVars("cd", "ds", TotalHtml, linebuf);
MacroRead(fi, fm);
fclose(fi);
MacroClear();
fclose(fm);
snprintf(linebuf, 1024, "%s/index.html", CFG.ftp_base);
rename(fn, linebuf);
chmod(linebuf, 0644);
}
fclose(pAreas);
chartran_close();
if (!do_quiet) {
printf("\r \r");
fflush(stdout);
}
free(temp);
free(sAreas);
free(fn);
RemoveSema((char *)"reqindex");
}
void Index(void)
{
ReqIndex();
HtmlIndex(NULL);
Syslog('+', "HTML Areas [%6d] Files [%6d] Updated [%6d]", AreasHtml, TotalHtml, aUpdate);
}

8
mbfido/mbfindex.h Normal file
View File

@@ -0,0 +1,8 @@
/* $Id: mbfindex.h,v 1.1 2001/11/18 23:19:08 mbroek Exp $ */
#ifndef _MBFINDEX_H_
#define _MBFINDEX_H
void Index(void); /* Index filerquest */
#endif

237
mbfido/mbfkill.c Normal file
View File

@@ -0,0 +1,237 @@
/*****************************************************************************
*
* $Id: mbfkill.c,v 1.27 2005/08/28 14:10:06 mbse Exp $
* Purpose: File Database Maintenance, kill or move old files
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "mbfkill.h"
#include "mbfutil.h"
extern int do_quiet; /* Suppress screen output */
extern int do_pack; /* Perform pack */
/*
* Check files for age, and not downloaded for x days. If they match
* one of these criteria (setable in areas setup), the file will be
* move to some retire area or deleted, depending on the setup.
* If they are moved, the upload date is reset to the current date,
* so you can set new removal criteria again.
*/
void Kill(void)
{
FILE *pAreas;
int i, iAreas, iAreasNew = 0, iTotal = 0, iKilled = 0, iMoved = 0, rc, Killit;
char *sAreas, *newdir = NULL, *sTemp, from[PATH_MAX], to[PATH_MAX];
time_t Now;
struct fileareas darea;
struct _fdbarea *fdb_area = NULL, *dst_area = NULL;
sAreas = calloc(PATH_MAX, sizeof(char));
sTemp = calloc(PATH_MAX, sizeof(char));
IsDoing("Kill files");
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("Kill/move files...\n");
}
snprintf(sAreas, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen (sAreas, "r")) == NULL) {
WriteError("Can't open %s", sAreas);
die(MBERR_INIT_ERROR);
}
fread(&areahdr, sizeof(areahdr), 1, pAreas);
fseek(pAreas, 0, SEEK_END);
iAreas = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize;
Now = time(NULL);
for (i = 1; i <= iAreas; i++) {
fseek(pAreas, ((i-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&area, areahdr.recsize, 1, pAreas);
if ((area.Available) && (area.DLdays || area.FDdays)) {
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
if (!do_quiet) {
printf("\r%4d => %-44s \b\b\b\b", i, area.Name);
fflush(stdout);
}
/*
* Check if download directory exists, if not, create the directory.
*/
if (access(area.Path, R_OK) == -1) {
Syslog('!', "Create dir: %s", area.Path);
newdir = xstrcpy(area.Path);
newdir = xstrcat(newdir, (char *)"/");
mkdirs(newdir, 0755);
free(newdir);
newdir = NULL;
}
if ((fdb_area = mbsedb_OpenFDB(i, 30)) == NULL)
die(MBERR_GENERAL);
/*
* Now start checking the files in the filedatabase
* against the contents of the directory.
*/
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
iTotal++;
Marker();
Killit = FALSE;
if (!fdb.UploadDate)
Syslog('!', "Warning: file %s in area %d has no upload date", fdb.Name, i);
if (area.DLdays) {
/*
* Test last download date or never downloaded and the
* file is more then n days available for download.
*/
if ((fdb.LastDL) && (((Now - fdb.LastDL) / 84400) > area.DLdays)) {
Killit = TRUE;
}
if ((!fdb.LastDL) && fdb.UploadDate && (((Now - fdb.UploadDate) / 84400) > area.DLdays)) {
Killit = TRUE;
}
}
if (area.FDdays) {
/*
* Check filedate
*/
if (fdb.UploadDate && (((Now - fdb.UploadDate) / 84400) > area.FDdays)) {
Killit = TRUE;
}
}
if (Killit) {
do_pack = TRUE;
if (area.MoveArea) {
fseek(pAreas, ((area.MoveArea -1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&darea, areahdr.recsize, 1, pAreas);
snprintf(from, PATH_MAX, "%s/%s", area.Path, fdb.Name);
snprintf(to, PATH_MAX, "%s/%s", darea.Path, fdb.Name);
if ((rc = file_mv(from, to)) == 0) {
Syslog('+', "Move %s, area %d => %d", fdb.Name, i, area.MoveArea);
if ((dst_area = mbsedb_OpenFDB(area.MoveArea, 30))) {
fdb.UploadDate = time(NULL);
fdb.LastDL = time(NULL);
mbsedb_InsertFDB(dst_area, fdb, FALSE);
mbsedb_CloseFDB(dst_area);
}
/*
* Now again if there is a dotted version (thumbnail) of this file.
*/
snprintf(from, PATH_MAX, "%s/.%s", area.Path, fdb.Name);
snprintf(to, PATH_MAX, "%s/.%s", darea.Path, fdb.Name);
if (file_exist(from, R_OK) == 0)
file_mv(from, to);
/*
* Unlink the old symbolic link
*/
snprintf(from, PATH_MAX, "%s/%s", area.Path, fdb.LName);
unlink(from);
/*
* Create the new symbolic link
*/
snprintf(from, PATH_MAX, "%s/%s", darea.Path, fdb.Name);
snprintf(to, PATH_MAX, "%s/%s", darea.Path, fdb.LName);
symlink(from, to);
fdb.Deleted = TRUE;
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp, - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
}
iMoved++;
} else {
WriteError("Move %s to area %d failed, %s", fdb.Name, area.MoveArea, strerror(rc));
}
} else {
Syslog('+', "Delete %s, area %d", fdb.LName, i);
fdb.Deleted = TRUE;
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp, - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
}
iKilled++;
snprintf(from, PATH_MAX, "%s/%s", area.Path, fdb.LName);
unlink(from);
snprintf(from, PATH_MAX, "%s/%s", area.Path, fdb.Name);
unlink(from);
snprintf(from, PATH_MAX, "%s/.%s", area.Path, fdb.Name);
unlink(from);
}
}
}
/*
* Now we must pack this area database otherwise
* we run into trouble later on.
*/
mbsedb_PackFDB(fdb_area);
mbsedb_CloseFDB(fdb_area);
iAreasNew++;
} /* if area.Available */
}
fclose(pAreas);
Syslog('+', "Kill Areas [%6d] Files [%6d] Deleted [%6d] Moved [%6d]", iAreasNew, iTotal, iKilled, iMoved);
if (!do_quiet) {
printf("\r \r");
fflush(stdout);
}
free(sTemp);
free(sAreas);
}

8
mbfido/mbfkill.h Normal file
View File

@@ -0,0 +1,8 @@
/* $Id: mbfkill.h,v 1.1 2001/11/18 23:19:08 mbroek Exp $ */
#ifndef _MBFKILL_H
#define _MBFKILL_H
void Kill(void);
#endif

201
mbfido/mbflist.c Normal file
View File

@@ -0,0 +1,201 @@
/*****************************************************************************
*
* $Id: mbflist.c,v 1.21 2005/10/11 20:49:47 mbse Exp $
* Purpose: File Database Maintenance - List areas and totals
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "mbfutil.h"
#include "mbflist.h"
extern int do_quiet; /* Suppress screen output */
void ListFileAreas(int Area)
{
FILE *pAreas, *pTic;
int i, iAreas, fcount, tcount = 0, iTotal = 0, columns = 80;
int fsize, tsize = 0;
char *sAreas, *fAreas, *sTic, flags[6], *ticarea;
struct _fdbarea *fdb_area = NULL;
/*
* If nothing to display allowed, return at once.
*/
if (do_quiet)
return;
/*
* See if we know the width of the users screen.
*/
if (getenv("COLUMNS")) {
i = atoi(getenv("COLUMNS"));
if (i >= 80)
columns = i;
}
mbse_colour(LIGHTRED, BLACK);
sAreas = calloc(PATH_MAX, sizeof(char));
fAreas = calloc(PATH_MAX, sizeof(char));
sTic = calloc(PATH_MAX, sizeof(char));
ticarea = calloc(21, sizeof(char));
snprintf(sAreas, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen (sAreas, "r")) == NULL) {
WriteError("Can't open %s", sAreas);
printf("Can't open %s\n", sAreas);
die(MBERR_INIT_ERROR);
}
fread(&areahdr, sizeof(areahdr), 1, pAreas);
fseek(pAreas, 0, SEEK_END);
iAreas = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize;
if (Area) {
IsDoing("List area %d", Area);
snprintf(sTic, PATH_MAX, "%s/etc/tic.data", getenv("MBSE_ROOT"));
if ((pTic = fopen(sTic, "r")) == NULL) {
WriteError("Can't open %s", sTic);
printf("Can't open %s\n", sTic);
die(MBERR_GENERAL);
}
fread(&tichdr, sizeof(tichdr), 1, pTic);
if (fseek(pAreas, ((Area - 1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET)) {
WriteError("$Can't seek area %d", Area);
printf("Can't seek area %d\n", Area);
return;
}
if (fread(&area, areahdr.recsize, 1, pAreas) != 1) {
WriteError("$Can't read record for area %d", Area);
printf("Can't read record for area %d\n", Area);
return;
}
if (area.Available) {
/*
* Open the file database.
*/
fdb_area = mbsedb_OpenFDB(Area, 30);
fcount = 0;
fsize = 0L;
mbse_colour(CYAN, BLACK);
printf("File listing of area %d, %s\n\n", Area, area.Name);
printf("Short name Kb. File date Down Flg TIC Area Long name\n");
printf("------------ ----- ---------- ---- --- -------------------- ");
for (i = 60; i < columns; i++)
printf("-");
printf("\n");
mbse_colour(LIGHTGRAY, BLACK);
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
snprintf(flags, 4, "---");
if (fdb.Deleted)
flags[0] = 'D';
if (fdb.NoKill)
flags[1] = 'N';
if (fdb.Announced)
flags[2] = 'A';
fdb.LName[columns - 60] = '\0';
printf("%-12s %5d %s %4d %s %-20s %s\n", fdb.Name, (int)(fdb.Size / 1024), StrDateDMY(fdb.FileDate),
(int)(fdb.TimesDL), flags, fdb.TicArea, fdb.LName);
fcount++;
fsize = fsize + fdb.Size;
}
fsize = fsize / 1024;
mbse_colour(CYAN, BLACK);
printf("------------------------------------------------------------");
for (i = 60; i < columns; i++)
printf("-");
printf("\n");
printf("%d file%s, %d Kbytes\n", fcount, (fcount == 1) ? "":"s", fsize);
mbsedb_CloseFDB(fdb_area);
} else {
WriteError("Area %d is not available", Area);
printf("Area %d is not available\n", Area);
return;
}
fclose(pAreas);
fclose(pTic);
free(ticarea);
free(sAreas);
free(fAreas);
free(sTic);
return;
}
IsDoing("List fileareas");
mbse_colour(CYAN, BLACK);
printf(" Area Files MByte File Group Area name\n");
printf("----- ----- ----- ------------ --------------------------------------------\n");
mbse_colour(LIGHTGRAY, BLACK);
for (i = 1; i <= iAreas; i++) {
fseek(pAreas, ((i-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&area, areahdr.recsize, 1, pAreas);
if (area.Available) {
fdb_area = mbsedb_OpenFDB(i, 30);
fcount = 0;
fsize = 0L;
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
fcount++;
fsize = fsize + fdb.Size;
}
fsize = fsize / 1048576;
tcount += fcount;
tsize += fsize;
printf("%5d %5d %5d %-12s %s\n", i, fcount, fsize, area.BbsGroup, area.Name);
iTotal++;
mbsedb_CloseFDB(fdb_area);
}
}
mbse_colour(CYAN, BLACK);
printf("----- ----- ----- ---------------------------------------------------------\n");
printf("%5d %5d %5d \n", iTotal, tcount, tsize);
fclose(pAreas);
free(ticarea);
free(sAreas);
free(fAreas);
free(sTic);
}

8
mbfido/mbflist.h Normal file
View File

@@ -0,0 +1,8 @@
/* $Id: mbflist.h,v 1.2 2001/11/25 14:13:55 mbroek Exp $ */
#ifndef _MBFLIST_H_
#define _MBFLIST_H
void ListFileAreas(int); /* List fileareas */
#endif

178
mbfido/mbfmove.c Normal file
View File

@@ -0,0 +1,178 @@
/*****************************************************************************
*
* $Id: mbfmove.c,v 1.19 2005/08/11 21:05:15 mbse Exp $
* Purpose: File Database Maintenance - Move a file
*
*****************************************************************************
* 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 "mbfutil.h"
#include "mbfmove.h"
extern int do_quiet; /* Suppress screen output */
/*
* Move a file
*/
void Move(int From, int To, char *File)
{
char *frompath, *topath, *temp1, *fromlink, *tolink, *fromthumb, *tothumb;
struct FILE_record f_db;
int rc = FALSE, Found = FALSE;
struct _fdbarea *src_area = NULL;
IsDoing("Move file");
mbse_colour(LIGHTRED, BLACK);
if (From == To) {
WriteError("Area numbers are the same");
if (!do_quiet)
printf("Can't move to the same area\n");
die(MBERR_COMMANDLINE);
}
/*
* Check From area
*/
if (LoadAreaRec(From) == FALSE) {
WriteError("Can't load record %d", From);
die(MBERR_INIT_ERROR);
}
if (!area.Available) {
WriteError("Area %d not available", From);
if (!do_quiet)
printf("Area %d not available\n", From);
die(MBERR_COMMANDLINE);
}
if (CheckFDB(From, area.Path))
die(MBERR_GENERAL);
/*
* Find the file in the "from" area, check LFN and 8.3 names.
*/
if ((src_area = mbsedb_OpenFDB(From, 30)) == NULL)
die(MBERR_GENERAL);
while (fread(&f_db, fdbhdr.recsize, 1, src_area->fp) == 1) {
if ((strcmp(f_db.LName, File) == 0) || strcmp(f_db.Name, File) == 0) {
Found = TRUE;
break;
}
}
temp1 = calloc(PATH_MAX, sizeof(char)); // not serious
if (!Found) {
WriteError("File %s not found in area %d", File, From);
if (!do_quiet)
printf("File %s not found in area %d\n", File, From);
free(temp1);
die(MBERR_GENERAL);
}
frompath = xstrcpy(area.Path);
frompath = xstrcat(frompath, (char *)"/");
frompath = xstrcat(frompath, f_db.Name);
fromlink = xstrcpy(area.Path);
fromlink = xstrcat(fromlink, (char *)"/");
fromlink = xstrcat(fromlink, f_db.LName);
fromthumb = xstrcpy(area.Path);
fromthumb = xstrcat(fromthumb, (char *)"/.");
fromthumb = xstrcat(fromthumb, f_db.Name);
/*
* Check Destination area
*/
if (LoadAreaRec(To) == FALSE) {
WriteError("Can't load record %d", To);
die(MBERR_GENERAL);
}
if (!area.Available) {
WriteError("Area %d not available", To);
if (!do_quiet)
printf("Area %d not available\n", To);
die(MBERR_GENERAL);
}
if (CheckFDB(To, area.Path))
die(MBERR_GENERAL);
topath = xstrcpy(area.Path);
topath = xstrcat(topath, (char *)"/");
topath = xstrcat(topath, f_db.Name);
tolink = xstrcpy(area.Path);
tolink = xstrcat(tolink, (char *)"/");
tolink = xstrcat(tolink, f_db.LName);
tothumb = xstrcpy(area.Path);
tothumb = xstrcat(tothumb, (char *)"/.");
tothumb = xstrcat(tothumb, f_db.Name);
if (file_exist(topath, F_OK) == 0) {
WriteError("File %s already exists in area %d", File, To);
if (!do_quiet)
printf("File %s already exists in area %d\n", File, To);
die(MBERR_COMMANDLINE);
}
rc = AddFile(f_db, To, topath, frompath, tolink);
if (rc) {
unlink(fromlink);
unlink(frompath);
/*
* Try to move thumbnail if it exists
*/
if (file_exist(fromthumb, R_OK) == 0) {
file_mv(fromthumb, tothumb);
}
}
if (mbsedb_LockFDB(src_area, 30)) {
f_db.Deleted = TRUE;
fseek(src_area->fp, - fdbhdr.recsize, SEEK_CUR);
fwrite(&f_db, fdbhdr.recsize, 1, src_area->fp);
mbsedb_UnlockFDB(src_area);
}
mbsedb_PackFDB(src_area);
mbsedb_CloseFDB(src_area);
mbse_colour(CYAN, BLACK);
Syslog('+', "Move %s from %d to %d %s", File, From, To, rc ? "successfull":"failed");
if (!do_quiet)
printf("Move %s from %d to %d %s\n", File, From, To, rc ? "successfull":"failed");
free(temp1);
free(frompath);
free(fromlink);
free(fromthumb);
free(topath);
free(tolink);
free(tothumb);
}

8
mbfido/mbfmove.h Normal file
View File

@@ -0,0 +1,8 @@
/* $Id: mbfmove.h,v 1.1 2001/12/02 19:17:14 mbroek Exp $ */
#ifndef _MBFMOVE_H
#define _MBFMOVE_H
void Move(int, int, char *);
#endif

142
mbfido/mbfpack.c Normal file
View File

@@ -0,0 +1,142 @@
/*****************************************************************************
*
* $Id: mbfpack.c,v 1.26 2005/12/16 20:12:17 mbse Exp $
* Purpose: File Database Maintenance - Pack filebase
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "mbfutil.h"
#include "mbfpack.h"
extern int do_quiet; /* Suppress screen output */
extern int do_index; /* Reindex filebases */
/*
* Removes records who are marked for deletion. If there is still a file
* on disk, it will be removed too.
*/
void PackFileBase(void)
{
FILE *pAreas;
int i, iAreas, iAreasNew = 0, rc, iTotal = 0, iRemoved = 0;
char *sAreas, fn[PATH_MAX];
struct _fdbarea *fdb_area = NULL;
int purge;
sAreas = calloc(PATH_MAX, sizeof(char));
IsDoing("Pack filebase");
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("Packing file database...\n");
}
snprintf(sAreas, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen (sAreas, "r")) == NULL) {
WriteError("Can't open %s", sAreas);
die(MBERR_INIT_ERROR);
}
fread(&areahdr, sizeof(areahdr), 1, pAreas);
fseek(pAreas, 0, SEEK_END);
iAreas = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize;
for (i = 1; i <= iAreas; i++) {
fseek(pAreas, ((i-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&area, areahdr.recsize, 1, pAreas);
if (area.Available) {
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
if (!do_quiet) {
printf("\r%4d => %-44s", i, area.Name);
fflush(stdout);
}
Marker();
if ((fdb_area = mbsedb_OpenFDB(i, 30)) == NULL)
die(MBERR_GENERAL);
purge = 0;
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
iTotal++;
if ((fdb.Deleted) || (fdb.Double) || (strcmp(fdb.Name, "") == 0)) {
iRemoved++;
purge++;
if (fdb.Double) {
Syslog('+', "Removed double record file \"%s\" from area %d", fdb.LName, i);
} else {
Syslog('+', "Removed file \"%s\" from area %d", fdb.LName, i);
snprintf(fn, PATH_MAX, "%s/%s", area.Path, fdb.LName);
rc = unlink(fn);
if (rc && (errno != ENOENT))
WriteError("PackFileBase(): unlink %s failed, result %s", fn, strerror(rc));
snprintf(fn, PATH_MAX, "%s/%s", area.Path, fdb.Name);
rc = unlink(fn);
if (rc && (errno != ENOENT))
WriteError("PackFileBase(): unlink %s failed, result %s", fn, strerror(rc));
/*
* If a dotted version (thumbnail) exists, remove it silently
*/
snprintf(fn, PATH_MAX, "%s/.%s", area.Path, fdb.Name);
unlink(fn);
}
do_index = TRUE;
}
}
if (purge)
mbsedb_PackFDB(fdb_area);
mbsedb_CloseFDB(fdb_area);
iAreasNew++;
} /* if area.Available */
}
fclose(pAreas);
Syslog('+', "Pack Areas [%6d] Files [%6d] Removed [%6d]", iAreasNew, iTotal, iRemoved);
if (!do_quiet) {
printf("\r \r");
fflush(stdout);
}
free(sAreas);
}

8
mbfido/mbfpack.h Normal file
View File

@@ -0,0 +1,8 @@
/* $Id: mbfpack.h,v 1.2 2003/11/08 15:30:04 mbroek Exp $ */
#ifndef _MBFPACK_H
#define _MBFPACK_H
void PackFileBase(void); /* Pack / Compress File Base */
#endif

216
mbfido/mbfrearc.c Normal file
View File

@@ -0,0 +1,216 @@
/*****************************************************************************
*
* $Id: mbfrearc.c,v 1.11 2005/10/11 20:49:47 mbse Exp $
* Purpose: File Database Maintenance - ReArc file(s)
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "mbfutil.h"
#include "mbfmove.h"
extern int do_quiet; /* Suppress screen output */
extern int do_index; /* Rebuild index */
/*
* ReArc file(s)
*/
void ReArc(int Area, char *File)
{
char *p, *temp, *mname, *linkpath, mask[256];
int i, rc = -1, count = 0, errors = 0;
struct utimbuf ut;
struct _fdbarea *fdb_area = NULL;
time_t tt;
IsDoing("ReArc file(s)");
mbse_colour(LIGHTRED, BLACK);
/*
* Check area
*/
if (LoadAreaRec(Area) == FALSE) {
WriteError("Can't load record %d", Area);
die(MBERR_INIT_ERROR);
}
if (!area.Available) {
WriteError("Area %d not available", Area);
if (!do_quiet)
printf("Area %d not available\n", Area);
die(MBERR_CONFIG_ERROR);
}
if (strlen(area.Archiver) == 0) {
WriteError("No default archiver for area %d", Area);
if (!do_quiet)
printf("No default archiver for area %d\n", Area);
die(MBERR_COMMANDLINE);
}
if (CheckFDB(Area, area.Path))
die(MBERR_GENERAL);
temp = calloc(PATH_MAX, sizeof(char));
if ((fdb_area = mbsedb_OpenFDB(Area, 30)) == NULL)
die(MBERR_GENERAL);
mbse_colour(CYAN, BLACK);
strcpy(mask, re_mask(File, FALSE));
if (re_comp(mask))
die(MBERR_GENERAL);
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
if (re_exec(fdb.LName) || re_exec(fdb.Name)) {
Syslog('+', "Will rearc %s", fdb.LName);
snprintf(temp, PATH_MAX, "%s/%s", area.Path, fdb.Name);
count++;
rc = rearc(temp, area.Archiver, do_quiet);
if (rc == 0) {
/*
* Success, update the file entry
*/
if (!do_quiet) {
mbse_colour(LIGHTBLUE, BLACK);
printf("\r Update file %s ", temp);
fflush(stdout);
}
linkpath = calloc(PATH_MAX, sizeof(char));
snprintf(linkpath, PATH_MAX, "%s/%s", area.Path, fdb.LName);
unlink(linkpath);
Syslog('+', "New name %s", temp);
if ((p = strstr(fdb.Name, "ARC")))
*p = '\0';
else if ((p = strstr(fdb.Name, "LHA")))
*p = '\0';
else if ((p = strstr(fdb.Name, "RAR")))
*p = '\0';
else if ((p = strstr(fdb.Name, "TGZ")))
*p = '\0';
else if ((p = strstr(fdb.Name, "BZ2")))
*p = '\0';
else if ((p = strstr(fdb.Name, "TAR")))
*p = '\0';
else if ((p = strstr(fdb.Name, "ARJ")))
*p = '\0';
else if ((p = strstr(fdb.Name, "ZIP")))
*p = '\0';
else if ((p = strstr(fdb.Name, "ZOO")))
*p = '\0';
else if ((p = strstr(fdb.Name, "HA")))
*p = '\0';
snprintf(p, 6, "%s", archiver.name);
if ((p = strstr(fdb.LName, "arc")))
*p = '\0';
else if ((p = strstr(fdb.LName, "lha")))
*p = '\0';
else if ((p = strstr(fdb.LName, "rar")))
*p = '\0';
else if ((p = strstr(fdb.LName, "tar.gz")))
*p = '\0';
else if ((p = strstr(fdb.LName, "tgz")))
*p = '\0';
else if ((p = strstr(fdb.LName, "tar.bz2")))
*p = '\0';
else if ((p = strstr(fdb.LName, "bz2")))
*p = '\0';
else if ((p = strstr(fdb.LName, "tar")))
*p = '\0';
else if ((p = strstr(fdb.LName, "arj")))
*p = '\0';
else if ((p = strstr(fdb.LName, "zip")))
*p = '\0';
else if ((p = strstr(fdb.LName, "zoo")))
*p = '\0';
else if ((p = strstr(fdb.LName, "ha")))
*p = '\0';
snprintf(p, 6, "%s", tl(archiver.name));
Syslog('f', "%s %s", fdb.Name, fdb.LName);
fdb.Size = file_size(temp);
fdb.Crc32 = file_crc(temp, FALSE);
tt = fdb.FileDate;
ut.actime = mktime(localtime(&tt));
ut.modtime = mktime(localtime(&tt));
utime(temp, &ut);
/*
* Check if mangled name is changed, and if so update to the
* new name and rename the file on disk.
*/
mname = calloc(PATH_MAX, sizeof(char));
strcpy(mname, fdb.LName);
name_mangle(mname);
if (strcmp(fdb.Name, mname)) {
Syslog('+', "Converted 8.3 name to %s", mname);
strcpy(fdb.Name, mname);
snprintf(mname, PATH_MAX, "%s/%s", area.Path, fdb.Name);
rename(temp, mname);
strcpy(temp, mname);
}
free(mname);
if (mbsedb_LockFDB(fdb_area, 30)) {
fseek(fdb_area->fp, - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, fdb_area->fp);
mbsedb_UnlockFDB(fdb_area);
}
/*
* Update symbolic link to long filename
*/
snprintf(linkpath, PATH_MAX, "%s/%s", area.Path, fdb.LName);
symlink(temp, linkpath);
free(linkpath);
if (strlen(fdb.Magic))
magic_update(fdb.Magic, fdb.Name);
do_index = TRUE;
} else {
errors++;
break; // stop when something goes wrong
}
if (!do_quiet) {
mbse_colour(LIGHTGRAY, BLACK);
printf("\r");
for (i = 0; i < (strlen(temp) + 20); i++)
printf(" ");
printf("\r");
fflush(stdout);
}
}
}
mbsedb_CloseFDB(fdb_area);
free(temp);
Syslog('+', "ReArc Files [%5d] Good [%5d] Errors [%5d]", count, count - errors, errors);
}

8
mbfido/mbfrearc.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef _MBFREARC_H
#define _MBFREARC_H
/* $Id: mbfrearc.h,v 1.1 2004/03/08 20:51:05 mbroek Exp $ */
void ReArc(int, char *);
#endif

114
mbfido/mbfsort.c Normal file
View File

@@ -0,0 +1,114 @@
/*****************************************************************************
*
* $Id: mbfsort.c,v 1.11 2005/08/28 14:10:06 mbse Exp $
* Purpose: File Database Maintenance - Sort filebase
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "mbfutil.h"
#include "mbfsort.h"
extern int do_quiet; /* Suppress screen output */
extern int do_index; /* Reindex filebases */
/*
* Sort files database
*/
void SortFileBase(int Area)
{
FILE *pAreas;
int iAreas;
char *sAreas;
struct _fdbarea *fdb_area = NULL;
sAreas = calloc(PATH_MAX, sizeof(char));
IsDoing("Sort filebase");
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
}
snprintf(sAreas, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen (sAreas, "r")) == NULL) {
WriteError("Can't open %s", sAreas);
die(MBERR_INIT_ERROR);
}
fread(&areahdr, sizeof(areahdr), 1, pAreas);
fseek(pAreas, 0, SEEK_END);
iAreas = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize;
if ((Area < 1) || (Area > iAreas)) {
if (!do_quiet) {
printf("Area must be between 1 and %d\n", iAreas);
}
} else {
fseek(pAreas, ((Area - 1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&area, areahdr.recsize, 1, pAreas);
if (area.Available) {
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
if (!do_quiet) {
printf("Sorting area %d: %-44s", Area, area.Name);
fflush(stdout);
}
if ((fdb_area = mbsedb_OpenFDB(Area, 30))) {
mbsedb_SortFDB(fdb_area);
mbsedb_CloseFDB(fdb_area);
}
Syslog('+', "Sorted file area %d: %s", Area, area.Name);
do_index = TRUE;
} else {
printf("You cannot sort area %d\n", Area);
}
}
fclose(pAreas);
if (!do_quiet) {
printf("\r \r");
fflush(stdout);
}
free(sAreas);
}

8
mbfido/mbfsort.h Normal file
View File

@@ -0,0 +1,8 @@
/* $Id: mbfsort.h,v 1.1 2003/11/08 15:30:04 mbroek Exp $ */
#ifndef _MBFSORT_H
#define _MBFSORT_H
void SortFileBase(int); /* Sort File Base */
#endif

83
mbfido/mbftoberep.c Normal file
View File

@@ -0,0 +1,83 @@
/*****************************************************************************
*
* $Id: mbftoberep.c,v 1.12 2005/10/11 20:49:47 mbse Exp $
* Purpose: File Database Maintenance - Show toberep database
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "mbfutil.h"
#include "mbftoberep.h"
extern int do_quiet; /* Suppress screen output */
/*
* Show the toberep database
*/
void ToBeRep(void)
{
char *temp;
FILE *fp;
struct _filerecord rep;
if (do_quiet)
return;
IsDoing("Toberep");
mbse_colour(CYAN, BLACK);
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/etc/toberep.data", getenv("MBSE_ROOT"));
if ((fp = fopen(temp, "r")) == NULL) {
printf("No toberep database present\n");
} else {
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
printf(" File echo Group File name Kbyte Date Announce\n");
printf("-------------------- ------------ ------------ ----- ---------- --------\n");
mbse_colour(LIGHTGRAY, BLACK);
while (fread(&rep, sizeof(rep), 1, fp) == 1) {
printf("%-20s %-12s %-12s %5d %s %s\n",
rep.Echo, rep.Group, rep.Name, rep.SizeKb, StrDateDMY(rep.Fdate), rep.Announce ? "Yes":"No ");
Syslog('f', "%-20s %-12s %-12s %5d %s %s",
rep.Echo, rep.Group, rep.Name, rep.SizeKb, StrDateDMY(rep.Fdate), rep.Announce ? "Yes":"No ");
}
fclose(fp);
}
free(temp);
}

8
mbfido/mbftoberep.h Normal file
View File

@@ -0,0 +1,8 @@
/* $Id: mbftoberep.h,v 1.1 2001/11/25 16:38:06 mbroek Exp $ */
#ifndef _MBFTOBEREP_H
#define _MBFTOBEREP_H
void ToBeRep(void); /* Show toberep database */
#endif

451
mbfido/mbfutil.c Normal file
View File

@@ -0,0 +1,451 @@
/*****************************************************************************
*
* $Id: mbfutil.c,v 1.53 2008/11/26 22:12:28 mbse Exp $
* Purpose: File Database Maintenance - utilities
*
*****************************************************************************
* Copyright (C) 1997-2008
*
* 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 "mbfutil.h"
#include "mbfile.h"
extern int do_quiet; /* Suppress screen output */
extern int do_force; /* Force file overwrite */
extern int e_pid; /* Pid of external process */
extern time_t t_start; /* Start time */
extern time_t t_end; /* End time */
int marker = 0; /* Marker counter */
void ProgName(void)
{
if (do_quiet)
return;
mbse_colour(WHITE, BLACK);
printf("\nMBFILE: MBSE BBS %s File maintenance utility\n", VERSION);
mbse_colour(YELLOW, BLACK);
printf(" %s\n", COPYRIGHT);
}
void die(int onsig)
{
/*
* First check if a child is running, if so, kill it.
*/
if (e_pid) {
if ((kill(e_pid, SIGTERM)) == 0)
Syslog('+', "SIGTERM to pid %d succeeded", e_pid);
else {
if ((kill(e_pid, SIGKILL)) == 0)
Syslog('+', "SIGKILL to pid %d succeded", e_pid);
else
WriteError("$Failed to kill pid %d", e_pid);
}
/*
* In case the child had the tty in raw mode...
*/
if (!do_quiet)
execute_pth((char *)"stty", (char *)"sane", (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null");
}
signal(onsig, SIG_IGN);
if (onsig) {
if (onsig <= NSIG)
WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]);
else
WriteError("Terminated with error %d", onsig);
}
clean_tmpwork();
ulockprogram((char *)"mbfile");
t_end = time(NULL);
Syslog(' ', "MBFILE finished in %s", t_elapsed(t_start, t_end));
if (!do_quiet) {
mbse_colour(LIGHTGRAY, BLACK);
fflush(stdout);
}
ExitClient(onsig);
}
void Help(void)
{
do_quiet = FALSE;
ProgName();
mbse_colour(LIGHTCYAN, BLACK);
printf("Usage: mbfile [command] <options>\n\n");
mbse_colour(LIGHTBLUE, BLACK);
printf(" Commands are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" a adopt <area> <file> \"[desc]\" Adopt file to area\n");
printf(" c check [area] Check filebase\n");
printf(" d delete <area> \"<filemask>\" Mark file(s) in area for deletion\n");
printf(" im import <area> Import files in current dir to area\n");
printf(" in index Create filerequest index\n");
printf(" k kill Kill/move old files\n");
printf(" l list [area] List file areas or one area\n");
printf(" m move <from> <to> <file> Move file from to area\n");
printf(" p pack Pack filebase\n");
printf(" r rearc <area> \"<filemask>\" Rearc file(s) in area to area archive type\n");
printf(" s sort <area> Sort files in a file area\n");
printf(" t toberep Show toberep database\n");
printf(" u undelete <area> \"<filemask>\" Mark file(s) in area for undeletion\n");
mbse_colour(LIGHTBLUE, BLACK);
printf("\n Options are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" -a -announce Suppress announce added files\n");
printf(" -f -force Force file overwrite\n");
printf(" -q -quiet Quiet mode\n");
printf(" -v -virus Suppress virus scanning, use with care\n");
die(MBERR_COMMANDLINE);
}
void Marker(void)
{
/*
* Keep the connection with the server alive
*/
Nopper();
/*
* Release system resources when running in the background
*/
if (CFG.slow_util && do_quiet)
msleep(1);
if (do_quiet)
return;
switch (marker) {
case 0: printf(">---");
break;
case 1: printf(">>--");
break;
case 2: printf(">>>-");
break;
case 3: printf(">>>>");
break;
case 4: printf("<>>>");
break;
case 5: printf("<<>>");
break;
case 6: printf("<<<>");
break;
case 7: printf("<<<<");
break;
case 8: printf("-<<<");
break;
case 9: printf("--<<");
break;
case 10:printf("---<");
break;
case 11:printf("----");
break;
}
printf("\b\b\b\b");
fflush(stdout);
if (marker < 11)
marker++;
else
marker = 0;
}
int UnpackFile(char *File)
{
char *temp, *pwd, *unarc, *cmd;
Syslog('f', "UnpackFile(%s)", File);
if ((unarc = unpacker(File)) == NULL) {
Syslog('f', "Unknown archive format %s", File);
return FALSE;
}
temp = calloc(PATH_MAX, sizeof(char));
pwd = calloc(PATH_MAX, sizeof(char));
getcwd(pwd, PATH_MAX);
/*
* Check if there is a temp directory to unpack the archive.
*/
if (create_tmpwork()) {
snprintf(temp, PATH_MAX, "%s/tmp/arc%d", getenv("MBSE_ROOT"), (int)getpid());
if (!do_quiet)
printf("\nCan't create %s\n", temp);
die(MBERR_GENERAL);
}
if (!getarchiver(unarc)) {
WriteError("No archiver available for %s", File);
if (!do_quiet)
printf("\nNo archiver available for %s\n", File);
clean_tmpwork();
return FALSE;
}
cmd = xstrcpy(archiver.funarc);
if ((cmd == NULL) || (strlen(cmd) == 0)) {
WriteError("No unarc command available");
if (!do_quiet)
printf("\nNo unarc command available\n");
clean_tmpwork();
return FALSE;
}
snprintf(temp, PATH_MAX, "%s/tmp/arc%d", getenv("MBSE_ROOT"), (int)getpid());
if (chdir(temp) != 0) {
WriteError("$Can't change to %s", temp);
clean_tmpwork();
die(MBERR_GENERAL);
}
if (execute_str(cmd, File, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") == 0) {
chdir(pwd);
free(temp);
free(pwd);
free(cmd);
return TRUE;
}
chdir(pwd);
WriteError("Unpack error, file may be corrupt");
clean_tmpwork();
return FALSE;
}
/*
* Add file to the BBS. The file is in the current directory.
* The f_db record already has all needed information.
*/
int AddFile(struct FILE_record f_db, int Area, char *DestPath, char *FromPath, char *LinkPath)
{
int rc;
struct _fdbarea *fdb_area = NULL;
char *temp, *dest, *lnk;
Syslog('f', "AddFile Area : %d", Area);
Syslog('f', "AddFile DestPath: %s", MBSE_SS(DestPath));
Syslog('f', "AddFile FromPath: %s", MBSE_SS(FromPath));
Syslog('f', "AddFile LinkPath: %s", MBSE_SS(LinkPath));
/*
* Copy file to the final destination and make a hard link with the
* 8.3 filename to the long filename.
*/
mkdirs(DestPath, 0775);
if ((file_exist(DestPath, F_OK) == 0) || (file_exist(LinkPath, F_OK) == 0)) {
if (do_force) {
Syslog('+', "File %s (%s) already exists in area %d, forced overwrite", f_db.Name, f_db.LName, Area);
} else {
WriteError("File %s (%s) already exists in area %d", f_db.Name, f_db.LName, Area);
if (!do_quiet)
printf("\nFile %s (%s) already exists in area %d\n", f_db.Name, f_db.LName, Area);
return FALSE;
}
}
if ((rc = file_cp(FromPath, DestPath))) {
WriteError("Can't copy file to %s, %s", DestPath, strerror(rc));
if (!do_quiet)
printf("\nCan't copy file to %s, %s\n", DestPath, strerror(rc));
return FALSE;
}
chmod(DestPath, 0644);
if (LinkPath) {
temp = calloc(PATH_MAX, sizeof(char));
if (getcwd(temp, PATH_MAX-1)) {
if (chdir(area.Path)) {
WriteError("$Can't chdir to %s", area.Path);
free(temp);
return FALSE;
}
unlink(LinkPath);
dest = xstrcpy(basename(DestPath));
lnk = xstrcpy(basename(LinkPath));
if ((rc = symlink(dest, lnk))) {
WriteError("Can't create symbolic link %s", lnk);
if (!do_quiet)
printf("\nCan't create symbolic link %s, %s\n", lnk, strerror(rc));
unlink(DestPath);
return FALSE;
}
free(dest);
free(lnk);
chdir(temp);
}
free(temp);
}
if ((fdb_area = mbsedb_OpenFDB(Area, 30))) {
rc = mbsedb_InsertFDB(fdb_area, f_db, TRUE);
mbsedb_CloseFDB(fdb_area);
return rc;
} else {
return FALSE;
}
}
int CheckFDB(int Area, char *Path)
{
char *temp;
FILE *fp;
int rc = FALSE;
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s/var/fdb/file%d.data", getenv("MBSE_ROOT"), Area);
/*
* Open the file database, create new one if it doesn't excist.
*/
if ((fp = fopen(temp, "r+")) == NULL) {
Syslog('!', "Creating new %s", temp);
if ((fp = fopen(temp, "a+")) == NULL) {
WriteError("$Can't create %s", temp);
rc = TRUE;
} else {
fdbhdr.hdrsize = sizeof(fdbhdr);
fdbhdr.recsize = sizeof(fdb);
fwrite(&fdbhdr, sizeof(fdbhdr), 1, fp);
fclose(fp);
}
} else {
fread(&fdbhdr, sizeof(fdbhdr), 1, fp);
fclose(fp);
}
/*
* Set the right attributes
*/
chmod(temp, 0660);
/*
* Now check the download directory
*/
if (access(Path, W_OK) == -1) {
snprintf(temp, PATH_MAX, "%s/foobar", Path);
if (mkdirs(temp, 0775))
Syslog('+', "Created directory %s", Path);
}
free(temp);
return rc;
}
/*
* Load Area Record
*/
int LoadAreaRec(int Area)
{
FILE *pAreas;
char *sAreas;
sAreas = calloc(PATH_MAX, sizeof(char));
snprintf(sAreas, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen (sAreas, "r")) == NULL) {
WriteError("$Can't open %s", sAreas);
if (!do_quiet)
printf("\nCan't open %s\n", sAreas);
return FALSE;
}
fread(&areahdr, sizeof(areahdr), 1, pAreas);
if (fseek(pAreas, ((Area - 1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET)) {
WriteError("$Can't seek record %d in %s", Area, sAreas);
if (!do_quiet)
printf("\nCan't seek record %d in %s\n", Area, sAreas);
fclose(pAreas);
free(sAreas);
return FALSE;
}
if (fread(&area, areahdr.recsize, 1, pAreas) != 1) {
WriteError("$Can't read record %d in %s", Area, sAreas);
if (!do_quiet)
printf("\nCan't read record %d in %s\n", Area, sAreas);
fclose(pAreas);
free(sAreas);
return FALSE;
}
fclose(pAreas);
free(sAreas);
return TRUE;
}
int is_real_8_3(char *File)
{
int i;
if (! is_8_3(File))
return FALSE;
for (i = 0; i < strlen(File); i++)
if (isalpha(File[i]) && islower(File[i]))
return FALSE;
return TRUE;
}

16
mbfido/mbfutil.h Normal file
View File

@@ -0,0 +1,16 @@
/* $Id: mbfutil.h,v 1.7 2005/12/03 14:52:35 mbse Exp $ */
#ifndef _MBFUTIL_H_
#define _MBFUTIL_H
void ProgName(void); /* Program name header */
void die(int onsig); /* Shutdown and cleanup */
void Help(void); /* Show help screen */
void Marker(void); /* Eyecatcher */
int UnpackFile(char *File); /* Unpack archive */
int AddFile(struct FILE_record, int, char *, char *, char *);
int CheckFDB(int, char *); /* Check FDB of area */
int LoadAreaRec(int); /* Load Area record */
int is_real_8_3(char *); /* Check for 8.3 uppercase */
#endif

998
mbfido/mbindex.c Normal file
View File

@@ -0,0 +1,998 @@
/*****************************************************************************
*
* $Id: mbindex.c,v 1.34 2007/09/02 11:17:32 mbse Exp $
* Purpose ...............: Nodelist Compiler
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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"
typedef struct _nl_list {
struct _nl_list *next;
struct _nlidx idx;
} nl_list;
typedef struct _nl_user {
struct _nl_user *next;
struct _nlusr udx;
} nl_user;
#include "mbindex.h"
FILE *ifp, *ufp, *ffp;
int total = 0, entries = 0, users = 0;
int filenr = 0;
unsigned short regio;
nl_list *nll = NULL;
nl_user *nlu = NULL;
extern int do_quiet; /* Quiet flag */
extern int show_log; /* Show logging on screen */
time_t t_start; /* Start time */
time_t t_end; /* End time */
/*
* If we don't know what to type
*/
void Help(void)
{
do_quiet = FALSE;
ProgName();
mbse_colour(LIGHTCYAN, BLACK);
printf("\nUsage: mbindex <options>\n\n");
mbse_colour(LIGHTBLUE, BLACK);
printf(" Options are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" -quiet Quiet mode\n");
mbse_colour(LIGHTGRAY, BLACK);
printf("\n");
die(MBERR_COMMANDLINE);
}
/*
* Header, only if not quiet.
*/
void ProgName(void)
{
if (do_quiet)
return;
mbse_colour(WHITE, BLACK);
printf("\nMBINDEX: MBSE BBS %s Nodelist Index Compiler\n", VERSION);
mbse_colour(YELLOW, BLACK);
printf(" %s\n", COPYRIGHT);
mbse_colour(CYAN, BLACK);
}
void die(int onsig)
{
if (onsig && (onsig < NSIG))
signal(onsig, SIG_IGN);
ulockprogram((char *)"mbindex");
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
show_log = TRUE;
}
if (IsSema((char *)"mbindex"))
RemoveSema((char *)"mbindex");
if (onsig) {
if (onsig <= NSIG)
WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]);
else
WriteError("Terminated with error %d", onsig);
}
t_end = time(NULL);
Syslog(' ', "MBINDEX finished in %s", t_elapsed(t_start, t_end));
if (!do_quiet)
mbse_colour(LIGHTGRAY, BLACK);
ExitClient(onsig);
}
int main(int argc,char *argv[])
{
int i;
char *cmd;
struct passwd *pw;
InitConfig();
InitFidonet();
mbse_TermInit(1, 80, 25);
t_start = time(NULL);
umask(002);
/*
* Catch all the signals we can, and ignore the rest.
* Don't listen to SIGTERM.
*/
for (i = 0; i < NSIG; i++) {
if ((i == SIGHUP) || (i == SIGINT) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGIOT))
signal(i, (void (*))die);
else if ((i != SIGKILL) && (i != SIGSTOP))
signal(i, SIG_IGN);
}
cmd = xstrcpy((char *)"Command line: mbindex");
if (argc > 2)
Help();
if (argc == 2) {
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[1]);
if (strncasecmp(argv[1], "-q", 2) == 0)
do_quiet = TRUE;
else
Help();
}
ProgName();
pw = getpwuid(getuid());
InitClient(pw->pw_name, (char *)"mbindex", CFG.location, CFG.logfile,
CFG.util_loglevel, CFG.error_log, CFG.mgrlog, CFG.debuglog);
Syslog(' ', " ");
Syslog(' ', "MBINDEX v%s", VERSION);
Syslog(' ', cmd);
free(cmd);
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
if (lockprogram((char *)"mbindex")) {
if (!do_quiet)
printf("Can't lock mbindex, abort.\n");
die(MBERR_NO_PROGLOCK);
}
if (nodebld())
die(MBERR_GENERAL);
else
die(MBERR_OK);
return 0;
}
void tidy_nllist(nl_list **fap)
{
nl_list *tmp, *old;
for (tmp = *fap; tmp; tmp = old) {
old = tmp->next;
free(tmp);
}
*fap = NULL;
}
int in_nllist(struct _nlidx idx, nl_list **fap, int replace)
{
nl_list *tmp;
for (tmp = *fap; tmp; tmp = tmp->next) {
if ((tmp->idx.zone == idx.zone) && (tmp->idx.net == idx.net) &&
(tmp->idx.node == idx.node) && (tmp->idx.point == idx.point)) {
if (replace) {
tmp->idx = idx;
entries++;
}
regio = tmp->idx.region;
return TRUE;
}
}
return FALSE;
}
void fill_nllist(struct _nlidx idx, nl_list **fap)
{
nl_list *tmp;
tmp = (nl_list *)malloc(sizeof(nl_list));
tmp->next = *fap;
tmp->idx = idx;
*fap = tmp;
total++;
entries++;
}
char *fullpath(char *fname)
{
static char path[PATH_MAX];
snprintf(path, PATH_MAX, "%s/%s", CFG.nodelists, fname);
return path;
}
void sort_nllist(nl_list **fap)
{
nl_list *ta, **vector;
size_t n = 0, i;
if (*fap == NULL)
return;
for (ta = *fap; ta; ta = ta->next)
n++;
vector = (nl_list **)malloc(n * sizeof(nl_list *));
i = 0;
for (ta = *fap; ta; ta = ta->next) {
vector[i++] = ta;
}
qsort(vector, n, sizeof(nl_list *), (int(*)(const void*, const void *))comp_node);
(*fap) = vector[0];
i = 1;
for (ta = *fap; ta; ta = ta->next) {
if (i < n)
ta->next = vector[i++];
else
ta->next = NULL;
}
free(vector);
return;
}
void tidy_nluser(nl_user **fap)
{
nl_user *tmp, *old;
for (tmp = *fap; tmp; tmp = old) {
old = tmp->next;
free(tmp);
}
*fap = NULL;
}
void fill_nluser(struct _nlusr udx, nl_user **fap)
{
nl_user *tmp;
tmp = (nl_user *)malloc(sizeof(nl_user));
tmp->next = *fap;
tmp->udx = udx;
*fap = tmp;
users++;
}
void sort_nluser(nl_user **fap)
{
nl_user *ta, **vector;
size_t n = 0, i;
if (*fap == NULL)
return;
for (ta = *fap; ta; ta = ta->next)
n++;
vector = (nl_user **)malloc(n * sizeof(nl_user *));
i = 0;
for (ta = *fap; ta; ta = ta->next) {
vector[i++] = ta;
}
qsort(vector, n, sizeof(nl_user *), (int(*)(const void*, const void *))comp_user);
(*fap) = vector[0];
i = 1;
for (ta = *fap; ta; ta = ta->next) {
if (i < n)
ta->next = vector[i++];
else
ta->next = NULL;
}
free(vector);
return;
}
int comp_node(nl_list **fap1, nl_list **fap2)
{
if ((*fap1)->idx.zone != (*fap2)->idx.zone)
return ((*fap1)->idx.zone - (*fap2)->idx.zone);
else if ((*fap1)->idx.net != (*fap2)->idx.net)
return ((*fap1)->idx.net - (*fap2)->idx.net);
else if ((*fap1)->idx.node != (*fap2)->idx.node)
return ((*fap1)->idx.node - (*fap2)->idx.node);
else
return ((*fap1)->idx.point - (*fap2)->idx.point);
}
int comp_user(nl_user **fap1, nl_user **fap2)
{
return strcmp((*fap1)->udx.user, (*fap2)->udx.user);
}
int compile(char *nlname, unsigned short zo, unsigned short ne, unsigned short no)
{
int num, i, lineno, boss = FALSE, bossvalid = FALSE;
unsigned short upnet, upnode;
char buf[MAXNLLINELEN], *p, *q;
faddr *tmpa;
FILE *nl;
struct _nlidx ndx;
struct _nlusr udx;
struct stat stb;
Syslog('+', "Compiling \"%s\" (%d)", nlname, filenr);
IsDoing("Compile NL %d", filenr +1);
if (stat(fullpath(nlname), &stb) == 0) {
if (stb.st_mode != 0100664) {
if (chmod(fullpath(nlname), 0664) == 0) {
Syslog('!', "Fixed filemode nodelist %s to 0664", nlname);
} else {
/*
* Abort this list, if we cannot set the right permissions then
* netmail for bbs users doesn't work.
*/
WriteError("Can't set mode 0644 on nodelist %s", nlname);
return MBERR_INIT_ERROR;
}
}
}
if ((nl = fopen(fullpath(nlname), "r")) == NULL) {
WriteError("$Can't open %s", fullpath(nlname));
return MBERR_INIT_ERROR;
}
memset(&ndx, 0, sizeof(ndx));
ndx.type = NL_NODE;
ndx.fileno = filenr;
upnet = 0;
upnode = 0;
/*
* If zone is set, it is a overlay segment
*/
if (zo) {
ndx.zone = zo;
ndx.net = ne;
ndx.node = no;
ndx.point = 0;
}
entries = 0;
lineno = 0;
while (!feof(nl)) {
Nopper();
ndx.offset = ftell(nl);
lineno++;
if (fgets(buf, sizeof(buf)-1, nl) == NULL)
continue;
/*
* Next check at <lf> and <eof> characters
*/
if ((*(buf+strlen(buf) -1) != '\n') && (*(buf + strlen(buf) -1) != '\012')) {
while (fgets(buf, sizeof(buf) -1, nl) && (*(buf + strlen(buf) -1) != '\n')) /*void*/;
if (strlen(buf) > 1) /* Suppress EOF character */
Syslog('-', "Nodelist: too long line junked (%d)", lineno);
continue;
}
if (*(p=buf+strlen(buf) -1) == '\n')
*p-- = '\0';
if (*p == '\r')
*p = '\0';
if ((buf[0] == ';') || (buf[0] == '\032') || (buf[0] == '\0'))
continue;
if (CFG.slow_util && do_quiet) {
if (zo) {
msleep(1);
} else {
if ((lineno % 40) == 0)
msleep(1);
}
}
if ((p = strchr(buf, ',')))
*p++ = '\0';
else {
/*
* Extra check for valid datalines, there should be at least one comma.
*/
WriteError("%s(%u): invalid dataline 1", nlname,lineno);
continue;
}
if ((q = strchr(p, ',')))
*q++ = '\0';
ndx.type = NL_NONE;
ndx.pflag = 0;
if (buf[0] == '\0') {
if (boss)
ndx.type = NL_POINT;
else
ndx.type = NL_NODE;
} else {
if (strcasecmp(buf,"Boss") == 0) {
ndx.type = NL_POINT;
bossvalid = FALSE;
if ((tmpa=parsefnode(p)) == NULL) {
WriteError("%s(%u): unparsable Boss addr \"%s\"", nlname,lineno,p);
continue;
}
boss = TRUE;
if (tmpa->zone)
ndx.zone = tmpa->zone;
ndx.net = tmpa->net;
ndx.node = tmpa->node;
ndx.point = 0;
tidy_faddr(tmpa);
ndx.type = NL_NONE;
if (in_nllist(ndx, &nll, FALSE)) {
bossvalid = TRUE;
}
continue; /* no further processing */
} else {
boss = FALSE;
ndx.type = NL_NONE;
if (!strcasecmp(buf, "Down")) {
ndx.pflag |= NL_DOWN;
ndx.type = NL_NODE;
}
if (!strcasecmp(buf, "Hold")) {
ndx.pflag |= NL_HOLD;
ndx.type = NL_NODE;
}
if (!strcasecmp(buf, "Pvt")) {
ndx.pflag |= NL_PVT;
ndx.type = NL_NODE;
}
if (!strcasecmp(buf, "Zone"))
ndx.type = NL_ZONE;
if (!strcasecmp(buf, "Region"))
ndx.type = NL_REGION;
if (!strcasecmp(buf, "Host"))
ndx.type = NL_HOST;
if (!strcasecmp(buf, "Hub"))
ndx.type = NL_HUB;
if (!strcasecmp(buf, "Point")) {
ndx.type = NL_POINT;
bossvalid = TRUE;
}
}
}
if (ndx.type == NL_NONE) {
for (q = buf; *q; q++)
if (*q < ' ')
*q='.';
WriteError("%s(%u): unidentified entry \"%s\"", nlname, lineno, buf);
continue;
}
if ((num=atoi(p)) == 0) {
WriteError("%s(%u): bad numeric \"%s\"", nlname,lineno,p);
continue;
}
/*
* now update the current address
*/
switch (ndx.type) {
case NL_REGION: ndx.net = num;
ndx.node = 0;
ndx.point = 0;
ndx.upnet = ndx.zone;
ndx.upnode= 0;
ndx.region= num;
upnet = num;
upnode = 0;
break;
case NL_ZONE: ndx.zone = num;
ndx.net = num;
ndx.node = 0;
ndx.point = 0;
ndx.upnet = 0;
ndx.upnode= 0;
ndx.region= 0;
upnet = num;
upnode = 0;
break;
case NL_HOST: ndx.net = num;
ndx.node = 0;
ndx.point = 0;
ndx.upnet = ndx.region;
ndx.upnode= 0;
upnet = num;
upnode = 0;
break;
case NL_HUB: ndx.node = num;
ndx.point = 0;
ndx.upnet = ndx.net;
ndx.upnode= 0;
upnet = ndx.net;
upnode = num;
break;
case NL_NODE: ndx.node = num;
ndx.point = 0;
ndx.upnet = upnet;
ndx.upnode= upnode;
break;
case NL_POINT: ndx.point = num;
ndx.upnet = ndx.net;
ndx.upnode= ndx.node;
if ((!ndx.region) && bossvalid)
ndx.region = regio;
break;
}
if (!do_quiet) {
printf("\rZone %-6uRegion %-6uNet %-6uNode %-6uPoint %-6u",
ndx.zone, ndx.region, ndx.net, ndx.node, ndx.point);
fflush(stdout);
}
memset(&udx, 0, sizeof(udx));
/*
* Read nodelist line and extract username.
*/
for (i = 0; i < 3; i++) {
p = q;
if (p == NULL) {
WriteError("%s(%u): invalid dataline 3", nlname,lineno);
continue;
}
if ((q = strchr(p, ',')))
*q++ = '\0';
if (q == NULL)
q = p;
}
if (strlen(p) > 35)
p[36] = '\0';
strcpy(udx.user, p);
udx.zone = ndx.zone;
udx.net = ndx.net;
udx.node = ndx.node;
udx.point = ndx.point;
if (ndx.zone == 0) {
WriteError("%s(%u): no Zone entry found", nlname,lineno);
fclose(nl);
if (!do_quiet) {
printf(" %d entries\n", entries);
fflush(stdout);
}
return 1;
}
/*
* Now search for the baudrate field, just to check if it's there.
*/
for (i = 0; i < 2; i++) {
p = q;
if (p == NULL) {
WriteError("%s(%u): invalid dataline 4", nlname,lineno);
continue;
}
if ((q = strchr(p, ',')))
*q++ = '\0';
if (q == NULL)
q = p;
}
/*
* If zone, net and node given, then this list is an
* overlay so we will call in_list() to replace the
* existing records, or append them if they don't exist.
* Also, only points with a valid boss will be added.
*/
if (zo) {
if (!(in_nllist(ndx, &nll, TRUE))) {
if (ndx.point && bossvalid) {
fill_nllist(ndx, &nll);
}
if (!ndx.point)
fill_nllist(ndx, &nll);
}
} else
fill_nllist(ndx, &nll);
fill_nluser(udx, &nlu);
}
fclose(nl);
Syslog('+', "%d entries", entries);
if (!do_quiet) {
printf(" %d entries\n", entries);
fflush(stdout);
}
return 0;
}
/*
* Tidy the filearray
*/
void tidy_fdlist(fd_list **fdp)
{
fd_list *tmp, *old;
for (tmp = *fdp; tmp; tmp = old) {
old = tmp->next;
free(tmp);
}
*fdp = NULL;
}
/*
* Add a file on the array.
*/
void fill_fdlist(fd_list **fdp, char *filename, time_t filedate)
{
fd_list *tmp;
tmp = (fd_list *)malloc(sizeof(fd_list));
tmp->next = *fdp;
snprintf(tmp->fname, 65, "%s", filename);
tmp->fdate = filedate;
*fdp = tmp;
}
int compfdate(fd_list **, fd_list **);
/*
* Sort the array of files by filedate
*/
void sort_fdlist(fd_list **fdp)
{
fd_list *ta, **vector;
size_t n = 0, i;
if (*fdp == NULL) {
return;
}
for (ta = *fdp; ta; ta = ta->next)
n++;
vector = (fd_list **)malloc(n * sizeof(fd_list *));
i = 0;
for (ta = *fdp; ta; ta = ta->next) {
vector[i++] = ta;
}
qsort(vector, n, sizeof(fd_list*), (int(*)(const void*, const void*))compfdate);
(*fdp) = vector[0];
i = 1;
for (ta = *fdp; ta; ta = ta->next) {
if (i < n)
ta->next = vector[i++];
else
ta->next = NULL;
}
free(vector);
return;
}
int compfdate(fd_list **fdp1, fd_list **fdp2)
{
return ((*fdp1)->fdate - (*fdp2)->fdate);
}
/*
* Return the name of the oldest file in the array
*/
char *pull_fdlist(fd_list **fdp)
{
static char buf[65];
fd_list *ta;
if (*fdp == NULL)
return NULL;
ta = *fdp;
memset(&buf, 0, sizeof(buf));
snprintf(buf, 65, "%s", ta->fname);
if (ta->next != NULL)
*fdp = ta->next;
else
*fdp = NULL;
free(ta);
return buf;
}
int makelist(char *base, unsigned short zo, unsigned short ne, unsigned short no)
{
int rc = 0, files = 0;
struct dirent *de;
DIR *dp;
char *p = NULL, *q;
struct _nlfil fdx;
fd_list *fdl = NULL;
if (!strlen(base)) {
WriteError("Error, no nodelist defined for %d:%d/%d", zo, ne, no);
return 0;
}
if ((dp = opendir(CFG.nodelists)) == NULL) {
WriteError("$Can't open dir %s", CFG.nodelists);
rc = MBERR_GENERAL;
} else {
while ((de = readdir(dp))) {
if (strncmp(de->d_name, base, strlen(base)) == 0) {
/*
* Extension must be at least 2 digits
*/
q = (de->d_name) + strlen(base);
if ((*q == '.') && (strlen(q) > 2) && (strspn(q+1,"0123456789") == (strlen(q)-1))) {
/*
* Add matched filenames to the array
*/
fill_fdlist(&fdl, de->d_name, file_time(fullpath(de->d_name)));
files++;
}
}
}
closedir(dp);
if (files == 0) {
Syslog('+', "No nodelist found for %s", base);
return MBERR_GENERAL;
}
/*
* Sort found nodelists by age and kill all but the newest 4.
*/
sort_fdlist(&fdl);
while (files) {
p = pull_fdlist(&fdl);
if (files > 4) {
Syslog('+', "Remove old \"%s\"", p);
unlink(fullpath(p));
}
files--;
}
tidy_fdlist(&fdl);
memset(&fdx, 0, sizeof(fdx));
snprintf(fdx.filename, 13, "%s", p);
snprintf(fdx.domain, 13, "%s", fidonet.domain);
fdx.number = filenr;
fwrite(&fdx, sizeof(fdx), 1, ffp);
rc = compile(p, zo, ne, no);
filenr++;
}
return rc;
}
int nodebld(void)
{
int rc = 0, i;
char *im, *fm, *um, *old, *new;
struct _nlfil fdx;
FILE *fp;
nl_list *tmp;
nl_user *tmu;
memset(&fdx, 0, sizeof(fdx));
im = xstrcpy(fullpath((char *)"temp.index"));
fm = xstrcpy(fullpath((char *)"temp.files"));
um = xstrcpy(fullpath((char *)"temp.users"));
if ((ifp = fopen(im, "w+")) == NULL) {
WriteError("$Can't create %s",MBSE_SS(im));
return MBERR_GENERAL;
}
if ((ufp = fopen(um, "w+")) == NULL) {
WriteError("$Can't create %s", MBSE_SS(um));
fclose(ifp);
unlink(im);
return MBERR_GENERAL;
}
if ((ffp = fopen(fm, "w+")) == NULL) {
WriteError("$Can't create %s", MBSE_SS(fm));
fclose(ifp);
unlink(im);
fclose(ufp);
unlink(um);
return MBERR_GENERAL;
}
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("\n");
}
if ((fp = fopen(fidonet_fil, "r")) == 0)
rc = MBERR_GENERAL;
else {
fread(&fidonethdr, sizeof(fidonethdr), 1, fp);
while (fread(&fidonet, fidonethdr.recsize, 1, fp) == 1) {
if (fidonet.available) {
rc = makelist(fidonet.nodelist, 0, 0, 0);
if (rc)
break;
for (i = 0; i < 6; i++) {
if (fidonet.seclist[i].zone) {
rc = makelist(fidonet.seclist[i].nodelist, fidonet.seclist[i].zone,
fidonet.seclist[i].net, fidonet.seclist[i].node);
if (rc)
break;
}
}
if (rc)
break;
}
}
fclose(fp);
}
fclose(ffp);
if (rc == 0) {
IsDoing("Sorting nodes");
sort_nllist(&nll);
IsDoing("Sorting users");
sort_nluser(&nlu);
IsDoing("Writing files");
for (tmp = nll; tmp; tmp = tmp->next)
fwrite(&tmp->idx, sizeof(struct _nlidx), 1, ifp);
fclose(ifp);
for (tmu = nlu; tmu; tmu = tmu->next)
fwrite(&tmu->udx, sizeof(struct _nlusr), 1, ufp);
fclose(ufp);
Syslog('+', "Compiled %d entries", total);
/*
* Rename existing files to old.*, they stay on disk in
* case they are open by some program. The temp.* files
* are then renamed to node.*
*/
old = xstrcpy(fullpath((char *)"old.index"));
new = xstrcpy(fullpath((char *)"node.index"));
unlink(old);
rename(new, old);
rename(im, new);
free(old);
free(new);
old = xstrcpy(fullpath((char *)"old.users"));
new = xstrcpy(fullpath((char *)"node.users"));
unlink(old);
rename(new, old);
rename(um, new);
free(old);
free(new);
old = xstrcpy(fullpath((char *)"old.files"));
new = xstrcpy(fullpath((char *)"node.files"));
unlink(old);
rename(new, old);
rename(fm, new);
free(old);
free(new);
} else {
fclose(ifp);
Syslog('+', "Compile failed, rc=%d", rc);
unlink(im);
unlink(fm);
unlink(um);
}
free(im);
free(fm);
free(um);
tidy_nllist(&nll);
tidy_nluser(&nlu);
return rc;
}

35
mbfido/mbindex.h Normal file
View File

@@ -0,0 +1,35 @@
#ifndef _MBINDEX_H
#define _MBINDEX_H
/* $Id: mbindex.h,v 1.4 2004/07/10 15:03:49 mbse Exp $ */
typedef struct _fd_list {
struct _fd_list *next;
char fname[65];
time_t fdate;
} fd_list;
int lockindex(void);
void ulockindex(void);
void Help(void);
void ProgName(void);
void die(int);
char *fullpath(char *);
int compile(char *, unsigned short, unsigned short, unsigned short);
void tidy_fdlist(fd_list **);
void fill_fdlist(fd_list **, char *, time_t);
void sort_fdlist(fd_list **);
char *pull_fdlist(fd_list **);
int makelist(char *, unsigned short, unsigned short, unsigned short);
void tidy_nllist(nl_list **);
int in_nllist(struct _nlidx, nl_list **, int);
void fill_nllist(struct _nlidx, nl_list **);
void tidy_nluser(nl_user **);
void fill_nluser(struct _nlusr, nl_user **);
int comp_user(nl_user **, nl_user **);
int comp_node(nl_list **, nl_list **);
int nodebld(void);
#endif

571
mbfido/mbmsg.c Normal file
View File

@@ -0,0 +1,571 @@
/*****************************************************************************
*
* $Id: mbmsg.c,v 1.34 2007/09/02 11:17:32 mbse Exp $
* Purpose ...............: Message Base Maintenance
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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/mbsedb.h"
#include "post.h"
#include "mbmsg.h"
int do_pack = FALSE; /* Pack flag */
int do_kill = FALSE; /* Kill flag (age and maxmsgs) */
int do_link = FALSE; /* Link messages */
int do_post = FALSE; /* Post a Message */
extern int do_quiet; /* Quiet flag */
extern int show_log; /* Show loglines */
int do_area = 0; /* Do only one area */
time_t t_start; /* Start time */
time_t t_end; /* End time */
int are_tot = 0; /* Total areas */
int are_proc = 0; /* Areas processed */
int msg_tot = 0; /* Total messages */
int msg_del = 0; /* Deleted messages */
int msg_link = 0; /* Linked messages */
int processed = FALSE; /* Did process something */
int oldmask;
/*
* Header, only if not quiet
*/
void ProgName()
{
if (do_quiet)
return;
mbse_colour(WHITE, BLACK);
printf("\nMBMSG: MBSE BBS %s - Message Base Maintenance Utility\n", VERSION);
mbse_colour(YELLOW, BLACK);
printf(" %s\n", COPYRIGHT);
mbse_colour(LIGHTGRAY, BLACK);
}
int main(int argc, char **argv)
{
int i;
char *cmd, *too = NULL, *subj = NULL, *mfile = NULL, *flavor = NULL;
struct passwd *pw;
int tarea = 0;
InitConfig();
mbse_TermInit(1, 80, 25);
oldmask = umask(007);
t_start = time(NULL);
/*
* Catch all signals we can, and ignore or catch them
*/
for (i = 0; i < NSIG; i++) {
if ((i == SIGHUP) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM) || (i == SIGIOT))
signal(i, (void (*))die);
else if ((i != SIGKILL) && (i != SIGSTOP))
signal(i, SIG_IGN);
}
if (argc < 2)
Help();
cmd = xstrcpy((char *)"Cmd:");
for (i = 1; i < argc; i++) {
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if (strncasecmp(argv[i], "l", 1) == 0)
do_link = TRUE;
if (strncasecmp(argv[i], "k", 1) == 0)
do_kill = TRUE;
if (strncasecmp(argv[i], "pa", 2) == 0)
do_pack = TRUE;
if (strncasecmp(argv[i], "po", 2) == 0) {
if (((argc - i) < 6) || ((argc - i) > 7))
Help();
do_post = TRUE;
too = argv[++i];
cmd = xstrcat(cmd, (char *)" \"");
cmd = xstrcat(cmd, too);
tarea = atoi(argv[++i]);
cmd = xstrcat(cmd, (char *)"\" ");
cmd = xstrcat(cmd, argv[i]);
subj = argv[++i];
cmd = xstrcat(cmd, (char *)" \"");
cmd = xstrcat(cmd, subj);
mfile = argv[++i];
cmd = xstrcat(cmd, (char *)"\" ");
cmd = xstrcat(cmd, mfile);
flavor = argv[++i];
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, flavor);
}
if (strncasecmp(argv[i], "-a", 2) == 0) {
i++;
do_area = atoi(argv[i]);
}
if (strncasecmp(argv[i], "-q", 2) == 0)
do_quiet = TRUE;
}
if (!(do_link || do_kill || do_pack || do_post))
Help();
ProgName();
pw = getpwuid(getuid());
InitClient(pw->pw_name, (char *)"mbmsg", CFG.location, CFG.logfile,
CFG.util_loglevel, CFG.error_log, CFG.mgrlog, CFG.debuglog);
Syslog(' ', " ");
Syslog(' ', "MBMSG v%s", VERSION);
Syslog(' ', cmd);
free(cmd);
if (!do_quiet) {
printf("\n");
mbse_colour(CYAN, BLACK);
}
if (do_link || do_kill || do_pack) {
memset(&MsgBase, 0, sizeof(MsgBase));
DoMsgBase();
}
if (do_post) {
if (Post(too, tarea, subj, mfile, flavor))
die(MBERR_GENERAL);
}
die(MBERR_OK);
return 0;
}
void Help()
{
do_quiet = FALSE;
ProgName();
mbse_colour(LIGHTCYAN, BLACK);
printf("\n Usage: mbmsg [command(s)] <options>\n\n");
mbse_colour(LIGHTBLUE, BLACK);
printf(" Commands are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" l link Link messages by subject\n");
printf(" k kill Kill messages (age & count)\n");
printf(" pa pack Pack deleted messages\n");
printf(" po post <to> <#> <subj> <file> <flavor> Post file in message area #\n\n");
mbse_colour(LIGHTBLUE, BLACK);
printf(" Options are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" -a -area <#> Process area <#> only\n");
printf(" -q -quiet Quiet mode\n");
printf("\n");
die(MBERR_COMMANDLINE);
}
void die(int onsig)
{
if (onsig && (onsig <= NSIG)) {
signal(onsig, SIG_IGN);
}
if (!do_quiet) {
printf("\r");
mbse_colour(CYAN, BLACK);
}
if (MsgBase.Locked)
Msg_UnLock();
if (MsgBase.Open)
Msg_Close();
if (onsig) {
if (onsig <= NSIG)
WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]);
else
WriteError("Terminated with error %d", onsig);
}
if (are_tot || are_proc || msg_link)
Syslog('+', "Areas [%6d] Processed [%6d] Linked [%6d]", are_tot, are_proc, msg_link);
if (msg_tot || msg_del)
Syslog('+', "Msgs [%6d] Deleted [%6d]", msg_tot, msg_del);
t_end = time(NULL);
Syslog(' ', "MBMSG finished in %s", t_elapsed(t_start, t_end));
umask(oldmask);
if (!do_quiet) {
mbse_colour(LIGHTGRAY, BLACK);
printf("\r \n");
}
ExitClient(onsig);
}
void DoMsgBase()
{
FILE *pAreas;
char *sAreas, *Name;
int arearec;
int Del = 0;
sAreas = calloc(PATH_MAX, sizeof(char));
Name = calloc(PATH_MAX, sizeof(char ));
IsDoing("Msg Maintenance");
if (do_area)
Syslog('+', "Processing message area %ld", do_area);
else
Syslog('+', "Processing all message areas");
if (do_kill) {
Syslog('-', " Total Max. Days/Killed Max. Nr/Killed Area name");
Syslog('-', "------ ------ ------ ------ ------ ----------------------------------");
}
snprintf(sAreas, PATH_MAX, "%s/etc/mareas.data", getenv("MBSE_ROOT"));
if(( pAreas = fopen (sAreas, "r")) == NULL) {
WriteError("$Can't open %s", sAreas);
die(MBERR_GENERAL);
}
fread(&msgshdr, sizeof(msgshdr), 1, pAreas);
if (do_area) {
if (fseek(pAreas, (msgshdr.recsize + msgshdr.syssize) * (do_area - 1), SEEK_CUR) == 0) {
fread(&msgs, msgshdr.recsize, 1, pAreas);
if (msgs.Active) {
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("\r%5d .. %-40s", do_area, msgs.Name);
fflush(stdout);
}
are_tot++;
mkdirs(msgs.Base, 0770);
if (do_kill)
KillArea(msgs.Base, msgs.Name, msgs.DaysOld, msgs.MaxMsgs, do_area);
if (do_pack || msg_del)
PackArea(msgs.Base, do_area);
if (do_link)
LinkArea(msgs.Base, do_area);
if (processed)
are_proc++;
}
}
} else {
arearec = 0;
while (fread(&msgs, msgshdr.recsize, 1, pAreas) == 1) {
fseek(pAreas, msgshdr.syssize, SEEK_CUR);
arearec++;
if (msgs.Active) {
if (enoughspace(CFG.freespace) == 0)
die(MBERR_DISK_FULL);
Nopper();
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("\r%5d .. %-40s", arearec, msgs.Name);
fflush(stdout);
}
are_tot++;
mkdirs(msgs.Base, 0770);
processed = FALSE;
if (do_kill)
KillArea(msgs.Base, msgs.Name, msgs.DaysOld, msgs.MaxMsgs, arearec);
if (do_pack || (Del != msg_del)) {
PackArea(msgs.Base, arearec);
}
Del = msg_del;
if (do_link)
LinkArea(msgs.Base, arearec);
if (processed)
are_proc++;
}
}
}
fclose(pAreas);
if (!do_area) {
snprintf(sAreas, PATH_MAX, "%s/etc/users.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen (sAreas, "r")) == NULL) {
WriteError("$Can't open %s", sAreas);
die(MBERR_GENERAL);
}
fread(&usrconfighdr, sizeof(usrconfighdr), 1, pAreas);
while (fread(&usrconfig, usrconfighdr.recsize, 1, pAreas) == 1) {
if (usrconfig.Email && strlen(usrconfig.Name)) {
Nopper();
snprintf(Name, PATH_MAX, "User %s email area: mailbox", usrconfig.Name);
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("\r .. %-40s", Name);
fflush(stdout);
}
snprintf(sAreas, PATH_MAX, "%s/%s/mailbox", CFG.bbs_usersdir, usrconfig.Name);
are_tot++;
processed = FALSE;
if (do_kill)
KillArea(sAreas, Name, 0, CFG.defmsgs, 0);
if (do_pack || (Del != msg_del)) {
PackArea(sAreas, 0);
}
Del = msg_del;
if (do_link)
LinkArea(sAreas, 0);
if (processed)
are_proc++;
snprintf(sAreas, PATH_MAX, "%s/%s/archive", CFG.bbs_usersdir, usrconfig.Name);
snprintf(Name, 80, "User %s email area: archive", usrconfig.Name);
are_tot++;
processed = FALSE;
if (do_kill)
KillArea(sAreas, Name, 0, CFG.defmsgs, 0);
if (do_pack || (Del != msg_del))
PackArea(sAreas, 0);
Del = msg_del;
if (do_link)
LinkArea(sAreas, 0);
if (processed)
are_proc++;
snprintf(sAreas, PATH_MAX, "%s/%s/trash", CFG.bbs_usersdir, usrconfig.Name);
snprintf(Name, 80, "User %s email area: trash", usrconfig.Name);
are_tot++;
processed = FALSE;
if (do_kill)
KillArea(sAreas, Name, CFG.defdays, CFG.defmsgs, 0);
if (do_pack || (Del != msg_del))
PackArea(sAreas, 0);
Del = msg_del;
if (do_link)
LinkArea(sAreas, 0);
if (processed)
are_proc++;
}
}
fclose(pAreas);
}
if (do_link)
RemoveSema((char *)"msglink");
free(sAreas);
free(Name);
die(MBERR_OK);
}
void LinkArea(char *Path, int Areanr)
{
int rc;
IsDoing("Linking %ld", Areanr);
rc = Msg_Link(Path, do_quiet, CFG.slow_util);
if (rc != -1) {
msg_link += rc;
processed = TRUE;
}
}
/*
* Kill messages according to age and max messages.
*/
void KillArea(char *Path, char *Name, int DaysOld, int MaxMsgs, int Areanr)
{
unsigned int Number, TotalMsgs = 0, Highest, *Active, Counter = 0;
int i, DelCount = 0, DelAge = 0, Done;
time_t Today, MsgDate;
IsDoing("Killing %ld", Areanr);
Today = time(NULL) / 86400L;
if (Msg_Open(Path)) {
if (!do_quiet) {
mbse_colour(LIGHTRED, BLACK);
printf(" (Killing)");
mbse_colour(LIGHTMAGENTA, BLACK);
fflush(stdout);
}
if (Msg_Lock(30L)) {
TotalMsgs = Msg_Number();
if (TotalMsgs) {
if ((Active = (unsigned int *)malloc((size_t)((TotalMsgs + 100L) * sizeof(unsigned int)))) != NULL) {
i = 0;
Number = Msg_Lowest();
do {
Active[i++] = Number;
} while (Msg_Next(&Number) == TRUE);
}
} else
Active = NULL;
Number = Msg_Lowest();
Highest = Msg_Highest();
do {
if (CFG.slow_util && do_quiet)
msleep(1);
if ((!do_quiet) && ((Counter % 10L) == 0)) {
printf("%6u / %6u\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", Counter, TotalMsgs);
fflush(stdout);
}
if ((Counter % 10L) == 0)
DoNop();
Counter++;
msg_tot++;
if (Msg_ReadHeader(Number) == TRUE) {
Done = FALSE;
if (DaysOld) {
/*
* GoldED doesn't fill the Msg.Arrived field, use the
* written date instead.
*/
if (Msg.Arrived == 0L)
MsgDate = Msg.Written / 86400L;
else
MsgDate = Msg.Arrived / 86400L;
if ((Today - MsgDate) > DaysOld) {
Msg_Delete(Number);
Done = TRUE;
DelAge++;
msg_del++;
if (Active != NULL) {
for (i = 0; i < TotalMsgs; i++) {
if (Active[i] == Number)
Active[i] = 0L;
}
}
}
}
if (Done == FALSE && (MaxMsgs) && Msg_Number() > MaxMsgs) {
Msg_Delete(Number);
DelCount++;
msg_del++;
if (Active != NULL) {
for (i = 0; i < TotalMsgs; i++) {
if (Active[i] == Number)
Active[i] = 0L;
}
}
}
}
} while (Msg_Next(&Number) == TRUE);
if (Active != NULL)
free(Active);
Msg_UnLock();
} else {
Syslog('+', "Can't lock msgbase %s", Path);
}
if (!do_quiet) {
printf(" \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
Msg_Close();
Syslog('-', "%6d %6d %6d %6d %6d %s", TotalMsgs, DaysOld, DelAge, MaxMsgs, DelCount, Name);
if (!do_quiet) {
printf("\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
} else
Syslog('+', "Failed to open %s", Path);
}
/*
* Pack message area if there are deleted messages.
*/
void PackArea(char *Path, int Areanr)
{
IsDoing("Packing %ld", Areanr);
if (Msg_Open(Path)) {
if (!do_quiet) {
mbse_colour(LIGHTRED, BLACK);
printf(" (Packing)");
fflush(stdout);
}
if (Msg_Lock(30L)) {
Msg_Pack();
Msg_UnLock();
} else
Syslog('+', "Can't lock %s", Path);
Msg_Close();
if (!do_quiet) {
printf("\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
}
if (CFG.slow_util && do_quiet)
msleep(1);
}

15
mbfido/mbmsg.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef _MBMSG_H
#define _MBMSG_H
/* $Id: mbmsg.h,v 1.4 2005/10/11 20:49:47 mbse Exp $ */
void ProgName(void);
void Help(void);
void die(int);
void DoMsgBase(void);
void PackArea(char *, int);
void LinkArea(char *, int);
void KillArea(char *, char *, int, int, int);
#endif

65
mbfido/mbseq.c Normal file
View File

@@ -0,0 +1,65 @@
/*****************************************************************************
*
* $Id: mbseq.c,v 1.9 2005/10/11 20:49:47 mbse Exp $
* Purpose ...............: give a hexadecimal sequence to stdout
*
*****************************************************************************
* Copyright (C) 1997-2005
*
* 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 "mbseq.h"
int main(int argc, char **argv)
{
struct passwd *pw;
unsigned int seq;
InitConfig();
pw = getpwuid(getuid());
InitClient(pw->pw_name, (char *)"mbseq", CFG.location, CFG.logfile,
CFG.util_loglevel, CFG.error_log, CFG.mgrlog, CFG.debuglog);
Syslog(' ', " ");
Syslog(' ', "MBSEQ v%s", VERSION);
seq = sequencer();
Syslog('+', "Sequence string %08lx", seq);
printf("%08x", seq);
fflush(stdout);
Syslog(' ', "MBSEQ finished");
ExitClient(0);
return 0;
}

6
mbfido/mbseq.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef _MBSEQ_H
#define _MBSEQ_H
#endif

1008
mbfido/mgrutil.c Normal file

File diff suppressed because it is too large Load Diff

40
mbfido/mgrutil.h Normal file
View File

@@ -0,0 +1,40 @@
/* $Id: mgrutil.h,v 1.10 2005/08/28 12:54:10 mbse Exp $ */
#ifndef _MGRUTIL_H
#define _MGRUTIL_H
#define LIST_LIST 0
#define LIST_NOTIFY 1
#define LIST_QUERY 2
#define LIST_UNLINK 3
/*
* Linked list for atea areas create
*/
typedef struct _AreaList {
struct _AreaList *next;
char Name[51];
int IsPresent;
int DoDelete;
} AreaList;
void MacroRead(FILE *, FILE *);
int MsgResult(const char *, FILE *, char);
void GetRpSubject(const char *, char*, size_t);
void WriteMailGroups(FILE *, faddr *);
void WriteFileGroups(FILE *, faddr *);
void CleanBuf(char *);
void ShiftBuf(char *, int);
void MgrPasswd(faddr *, char *, FILE *, int, int);
void MgrNotify(faddr *, char *, FILE *, int);
int UplinkRequest(faddr *, faddr *, int, char *);
int Areas(void);
#endif

583
mbfido/mkftnhdr.c Normal file
View File

@@ -0,0 +1,583 @@
/*****************************************************************************
*
* $Id: mkftnhdr.c,v 1.19 2008/11/26 22:28:31 mbse Exp $
* Purpose ...............: MBSE BBS Mail Gate
*
*****************************************************************************
* Copyright (C) 1997-2008
*
* 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"
char *replyaddr=NULL;
char *ftnmsgidstyle=NULL;
faddr *bestaka;
int ftnmsgid(char *msgid, char **s, unsigned int *n, char *areaname)
{
char *buf, *l, *r, *p;
unsigned int nid = 0L;
faddr *tmp;
static int ftnorigin = 0;
Syslog('m', "Make ftn msgid from \"%s\"", MBSE_SS(msgid));
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 = 0xffffffff;
if (nid == 0xffffffff) {
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", printable(l, 0));
*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,"%x",&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,"%x",&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,"%x",&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 = 0xffffffff;
if (nid == 0xffffffff)
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) {
Syslog('m', "Getting `to' address from \"%s\"", MBSE_SS(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);
}
} 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('+', "from: %s <%s>",freename,rfcfrom);
needreplyaddr = 1;
if ((tmsg->from=parsefaddr(rfcfrom)) == NULL) {
if (freename && rfcfrom)
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)) {
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 *)" ");
}
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) - (gmt_offset((time_t)0) * 60);
else if ((p = hdr((char *)"Date",msg)))
tmsg->date = parsedate(p, NULL) - (gmt_offset((time_t)0) * 60);
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;
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);
}
return tmsg;
}

Some files were not shown because too many files have changed in this diff Show More