Rewrote binkp inbound handling and error recovery

This commit is contained in:
Michiel Broek
2005-09-12 13:47:09 +00:00
parent a25c4267df
commit c1dc37321d
15 changed files with 320 additions and 82 deletions

View File

@@ -9,8 +9,8 @@ SRCS = zmmisc.c zmrle.c zmrecv.c zmsend.c binkp.c md5b.c \
answer.c chat.c dial.c dietifna.c emsidat.c filelist.c \
openfile.c openport.c opentcp.c rdoptions.c yoohoo.c \
recvbark.c respfreq.c sendbark.c tcp.c tcpproto.c wazoo.c \
filetime.c ftsc.c atoul.c portsel.c telnet.c \
ttyio.c lutil.c scanout.c emsi.c ulock.c \
filetime.c ftsc.c atoul.c portsel.c telnet.c bopenfile.c \
ttyio.c lutil.c scanout.c emsi.c ulock.c dirlock.c \
callstat.c session.c call.c mbcico.c \
outstat.c nlinfo.c mbout.c
HDRS = zmodem.h binkp.h config.h statetbl.h md5b.h \
@@ -18,8 +18,8 @@ HDRS = zmodem.h binkp.h config.h statetbl.h md5b.h \
answer.h chat.h dial.h dietifna.h emsidat.h filelist.h \
openfile.h openport.h opentcp.h rdoptions.h yoohoo.h \
recvbark.h respfreq.h sendbark.h tcp.h tcpproto.h wazoo.h \
filetime.h ftsc.h atoul.h portsel.h telnet.h \
ttyio.h lutil.h scanout.h emsi.h ulock.h \
filetime.h ftsc.h atoul.h portsel.h telnet.h bopenfile.h \
ttyio.h lutil.h scanout.h emsi.h ulock.h dirlock.h \
callstat.h session.h call.h mbcico.h \
outstat.h nlinfo.h
MBCICO_OBJS = zmmisc.o zmrle.o zmrecv.o zmsend.o binkp.o md5b.o \
@@ -27,8 +27,8 @@ MBCICO_OBJS = zmmisc.o zmrle.o zmrecv.o zmsend.o binkp.o md5b.o \
answer.o chat.o dial.o dietifna.o emsidat.o filelist.o \
openfile.o openport.o opentcp.o rdoptions.o yoohoo.o \
recvbark.o respfreq.o sendbark.o tcp.o tcpproto.o wazoo.o \
filetime.o ftsc.o atoul.o portsel.o telnet.o \
ttyio.o lutil.o scanout.o emsi.o ulock.o \
filetime.o ftsc.o atoul.o portsel.o telnet.o bopenfile.o \
ttyio.o lutil.o scanout.o emsi.o ulock.o dirlock.o \
callstat.o session.o call.o mbcico.o
MBOUT_OBJS = outstat.o nlinfo.o mbout.o scanout.o callstat.o
SLIBS = ../lib/libmbse.a ../lib/libmsgbase.a ../lib/libdbase.a ../lib/libnodelist.a
@@ -90,14 +90,14 @@ zmmisc.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h ttyio.h session.h zmode
zmrle.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h ttyio.h session.h zmodem.h
zmrecv.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h lutil.h ttyio.h session.h zmodem.h config.h emsi.h openfile.h filelist.h openport.h
zmsend.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h ttyio.h session.h zmodem.h lutil.h emsi.h filelist.h
binkp.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/nodelist.h ../lib/mbsedb.h ttyio.h session.h statetbl.h config.h emsi.h openfile.h respfreq.h filelist.h opentcp.h rdoptions.h lutil.h binkp.h config.h md5b.h inbound.h callstat.h
binkp.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/nodelist.h ../lib/mbsedb.h ttyio.h session.h statetbl.h config.h emsi.h bopenfile.h respfreq.h filelist.h opentcp.h rdoptions.h lutil.h binkp.h config.h md5b.h inbound.h callstat.h mbcico.h
md5b.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h lutil.h md5b.h
xmsend.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h session.h ttyio.h statetbl.h xmsend.h m7send.h filelist.h filetime.h
xmrecv.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h session.h ttyio.h statetbl.h config.h lutil.h openfile.h m7recv.h xmrecv.h filelist.h filetime.h
m7recv.o: ../config.h ../lib/mbselib.h statetbl.h ttyio.h m7recv.h
m7send.o: ../config.h ../lib/mbselib.h statetbl.h ttyio.h m7send.h
hydra.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h session.h filelist.h filetime.h ttyio.h statetbl.h config.h emsi.h openfile.h lutil.h respfreq.h mbcico.h hydra.h
inbound.o: ../config.h ../lib/mbselib.h inbound.h
inbound.o: ../config.h ../lib/mbselib.h dirlock.h inbound.h
answer.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/nodelist.h ../lib/mbsedb.h lutil.h session.h config.h answer.h openport.h portsel.h dial.h rdoptions.h mbcico.h
chat.o: ../config.h ../lib/mbselib.h config.h chat.h ttyio.h
dial.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/nodelist.h ../lib/mbsedb.h config.h chat.h ttyio.h session.h dial.h
@@ -120,15 +120,17 @@ ftsc.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h session.h ttyio.h statetb
atoul.o: ../config.h ../lib/mbselib.h atoul.h
portsel.o: ../config.h ../lib/mbselib.h portsel.h
telnet.o: ../config.h ../lib/mbselib.h telnet.h
bopenfile.o: ../config.h ../lib/mbselib.h config.h lutil.h bopenfile.h
ttyio.o: ../config.h ../lib/mbselib.h ttyio.h lutil.h
lutil.o: ../config.h ../lib/mbselib.h lutil.h
scanout.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/mbsedb.h config.h scanout.h lutil.h
emsi.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/nodelist.h ../lib/mbsedb.h ttyio.h session.h statetbl.h config.h emsi.h emsidat.h hydra.h rdoptions.h tcp.h wazoo.h inbound.h callstat.h
ulock.o: ../config.h ../lib/mbselib.h
dirlock.o: ../config.h ../lib/mbselib.h dirlock.h
callstat.o: ../config.h ../lib/mbselib.h callstat.h
session.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h ttyio.h statetbl.h emsi.h ftsc.h session.h yoohoo.h mbcico.h binkp.h callstat.h inbound.h opentcp.h telnet.h
call.o: ../config.h ../lib/mbselib.h ../lib/users.h ../lib/nodelist.h ../lib/mbsedb.h session.h callstat.h call.h config.h dial.h lutil.h portsel.h openport.h opentcp.h rdoptions.h inbound.h
mbcico.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h ../lib/users.h ../lib/mbsedb.h config.h answer.h call.h lutil.h mbcico.h session.h
mbcico.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h ../lib/users.h ../lib/mbsedb.h config.h answer.h call.h lutil.h mbcico.h session.h binkp.h
outstat.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h ../lib/users.h ../lib/mbsedb.h scanout.h callstat.h outstat.h
nlinfo.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h nlinfo.h
mbout.o: ../config.h ../lib/mbselib.h ../lib/nodelist.h ../lib/users.h ../lib/mbsedb.h outstat.h nlinfo.h

View File

@@ -39,7 +39,7 @@
#include "statetbl.h"
#include "config.h"
#include "emsi.h"
#include "openfile.h"
#include "bopenfile.h"
#include "respfreq.h"
#include "filelist.h"
#include "opentcp.h"
@@ -50,6 +50,7 @@
#include "md5b.h"
#include "inbound.h"
#include "callstat.h"
#include "mbcico.h"
/*
@@ -74,6 +75,9 @@ extern pid_t mypid;
extern struct sockaddr_in peeraddr;
extern int most_debug;
extern int laststat;
extern int crashme;
int gotblock = 0;
extern unsigned long sentbytes;
@@ -171,7 +175,6 @@ struct binkprec {
#endif
struct timezone tz; /* Timezone */
int DidSendGET; /* Receiver send GET status */
char *txbuf; /* Transmitter buffer */
int txlen; /* Transmitter file length */
@@ -246,7 +249,6 @@ void parse_m_nul(char *); /* Parse M_NUL message */
int binkp_poll_frame(void); /* Poll for a frame */
void binkp_add_message(char *frame); /* Add cmd frame to queue */
int binkp_process_messages(void); /* Process the queue */
int binkp_resync(off_t); /* File resync */
char *unix2binkp(char *); /* Binkp -> Unix escape */
char *binkp2unix(char *); /* Unix -> Binkp escape */
void fill_binkp_list(binkp_list **, file_list *, off_t); /* Build pending files */
@@ -281,7 +283,6 @@ int binkp(int role)
bp.rname = calloc(512, sizeof(char));
bp.ropts = calloc(512, sizeof(char));
bp.rxfp = NULL;
bp.DidSendGET = FALSE;
bp.local_EOB = FALSE;
bp.remote_EOB = FALSE;
bp.msgs_on_queue = 0;
@@ -317,7 +318,6 @@ int binkp(int role)
#endif
#endif
bp.buggyIrex = FALSE;
laststat = 0;
bp.NRwe = No;
bp.NRthey = No;
bp.NDwe = No;
@@ -653,7 +653,6 @@ SM_STATE(WaitOk)
SM_STATE(Opts)
Syslog('b', "Binkp: last session was %d", laststat);
IsDoing("Binkp to %s", ascfnode(remote->addr, 0xf));
binkp_set_comp_state();
SM_SUCCESS;
@@ -924,7 +923,7 @@ SM_STATE(PwdAck)
}
free(pw);
Syslog('+', "Binkp: %s%sprotected session", bp.CRAMflag ? "MD5 ":"", bp.Secure ? "":"un");
inbound_open(remote->addr, bp.Secure);
inbound_open(remote->addr, bp.Secure, TRUE);
binkp_send_command(MM_OK, "%ssecure", bp.Secure ? "":"non-");
SM_PROCEED(Opts)
@@ -952,7 +951,6 @@ SM_STATE(Opts)
binkp_send_comp_opts();
binkp_set_comp_state();
Syslog('b', "Binkp: last session status %d", laststat);
SM_SUCCESS;
@@ -982,6 +980,7 @@ int file_transfer(void)
bp.TxState = TxGNF;
bp.FtState = Switch;
bp.messages = 0;
Syslog('b', "Binkp: last session was %d", laststat);
break;
case Switch: if ((bp.RxState == RxDone) && (bp.TxState == TxDone)) {
@@ -1184,21 +1183,24 @@ TrType binkp_receiver(void)
#endif
(void)binkp2unix(bp.rname);
rxbytes = bp.rxbytes;
bp.rxfp = openfile(binkp2unix(bp.rname), bp.rtime, bp.rsize, &rxbytes, binkp_resync);
/*
* Open file if M_FILE frame has offset 0
* Else the file is already open.
*/
if (bp.roffs && (bp.roffs == rxbytes)) {
Syslog('b', "Binkp: offset == rxbytes, don't open file again");
if (fseek(bp.rxfp, bp.roffs, SEEK_SET) == 0)
Syslog('b', "Binkp: file position set to %ld", bp.roffs);
else
WriteError("$Binkp: can't fseek to %ld", bp.roffs);
} else {
bp.rxfp = bopenfile(binkp2unix(bp.rname), bp.rtime, bp.rsize, &rxbytes);
}
bp.rxbytes = rxbytes;
bp.rxcompressed = 0;
if (bp.DidSendGET) {
Syslog('b', "Binkp: DidSendGET is set");
/*
* The file was partly received, via the openfile the resync function
* has send a GET command to start this file with a offset. This means
* we will get a new FILE command to open this file with a offset.
*/
bp.RxState = RxWaitF;
return Ok;
}
gettimeofday(&rxtvstart, &bp.tz);
bp.rxpos = bp.roffs;
@@ -1215,7 +1217,7 @@ TrType binkp_receiver(void)
if ((bp.rsize / (sfs.f_bsize + 1)) >= sfs.f_bfree) {
Syslog('!', "Binkp: only %lu blocks free (need %lu) in %s for this file", sfs.f_bfree,
(unsigned long)(bp.rsize / (sfs.f_bsize + 1)), tempinbound);
closefile();
bclosefile(FALSE);
bp.rxfp = NULL; /* Force SKIP command */
}
}
@@ -1233,6 +1235,14 @@ TrType binkp_receiver(void)
return Failure;
else
return Ok;
} else if ((bp.rxbytes < bp.rsize) && (bp.roffs == 0) && bp.rxbytes) {
Syslog('+', "Binkp: partial file present, resync");
rc = binkp_send_command(MM_GET, "%s %ld %ld %ld", bp.rname, bp.rsize, bp.rtime, bp.rxbytes);
bp.RxState = RxWaitF;
if (rc)
return Failure;
else
return Ok;
} else if (!bp.rxfp) {
/*
* Some error, request to skip it
@@ -1245,7 +1255,7 @@ TrType binkp_receiver(void)
else
return Ok;
} else {
Syslog('b', "rsize=%d, rxbytes=%d, roffs=%d", bp.rsize, bp.rxbytes, bp.roffs);
Syslog('b', "Binkp: rsize=%d, rxbytes=%d, roffs=%d, goto RxReceD", bp.rsize, bp.rxbytes, bp.roffs);
bp.RxState = RxReceD;
return Ok;
}
@@ -1278,7 +1288,7 @@ TrType binkp_receiver(void)
return Ok;
} else if (bcmd == MM_FILE) {
Syslog('+', "Binkp: partial received file, saving");
closefile();
bclosefile(FALSE);
bp.rxfp = NULL;
bp.RxState = RxAccF;
return Continue;
@@ -1371,7 +1381,7 @@ TrType binkp_receiver(void)
if (bp.rxpos == bp.rsize) {
rc = binkp_send_command(MM_GOT, "%s %ld %ld", bp.rname, bp.rsize, bp.rtime);
closefile();
bclosefile(TRUE);
bp.rxpos = bp.rxpos - bp.rxbytes;
gettimeofday(&rxtvend, &bp.tz);
#if defined(HAVE_ZLIB_H) || defined(HAVE_BZLIB_H)
@@ -2383,6 +2393,11 @@ int binkp_poll_frame(void)
}
} else {
Syslog('b', "Binkp: rcvd data (%d)", bp.rxlen -1);
gotblock++;
if (crashme && (gotblock > 10)) {
Syslog('b', "Binkp: will crash now");
die(SIGHUP);
}
}
binkp_settimer(BINKP_TIMEOUT);
Nopper();
@@ -2648,26 +2663,6 @@ int binkp_pendingfiles(void)
/*
* This function is called two times if a partial file exists from openfile.
* 1. A partial file is detected, send a GET to the remote, set DidSendGET flag.
* 2. DidSendGET is set, return 0 and let openfile open the file in append mode.
*/
int binkp_resync(off_t off)
{
Syslog('b', "Binkp: resync(%d) DidSendGET=%s", off, bp.DidSendGET ?"TRUE":"FALSE");
if (!bp.DidSendGET) {
binkp_send_command(MM_GET, "%s %ld %ld %ld", bp.rname, bp.rsize, bp.rtime, off);
bp.DidSendGET = TRUE;
Syslog('+', "Binkp: already %lu bytes received, requested restart with offset", (unsigned long)off);
return -1; /* Signal openfile not to open the file */
}
bp.DidSendGET = FALSE;
return 0; /* Signal openfile to open the file in append mode */
}
/*
* Translate string to binkp escaped string, unsafe characters are escaped.
*/
@@ -3142,3 +3137,21 @@ int decompress_abort(int type, void *data)
#endif
/*
* Abort, called from die in case there were errors.
* This will reconstruct file data that is still in
* compressed state in memory so that resync works.
*/
void binkp_abort(void)
{
Syslog('b', "Binkp: abort");
#ifdef USE_EXPERIMENT
if ((bp.rmode != CompNone) && z_idata)
decompress_abort(bp.rmode, z_idata);
if ((bp.tmode != CompNone) && z_odata)
compress_abort(bp.tmode, z_odata);
#endif
}

View File

@@ -96,6 +96,7 @@ typedef struct _the_queue {
int binkp(int);
int binkp(int);
void binkp_abort(void);
#endif

View File

@@ -163,7 +163,7 @@ int bclosefile(int success)
* Remove state file.
*/
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX, "%s.state", infpath, basename(infpath));
snprintf(temp, PATH_MAX, "%s.state", infpath);
if (unlink(temp))
WriteError("$Binkp: can't unlink %s", temp);
else

9
mbcico/bopenfile.h Normal file
View File

@@ -0,0 +1,9 @@
/* $Id$ */
#ifndef _BOPENFILE_H
#define _BOPENFILE_H
FILE *bopenfile(char *, time_t, off_t, off_t *);
int bclosefile(int);
#endif

View File

@@ -207,7 +207,7 @@ int call(faddr *addr)
Syslog('?', "Warning: calling non-CM system outside ZMH");
}
inbound_open(addr, TRUE); /* master sessions are secure */
inbound_open(addr, TRUE, (tcp_mode == TCPMODE_IBN)); /* master sessions are secure */
/*
* Call when:

149
mbcico/dirlock.c Normal file
View File

@@ -0,0 +1,149 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: Lock a directory
*
*****************************************************************************
* 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 "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('+', "Already locked by, 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);
}

9
mbcico/dirlock.h Normal file
View File

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

View File

@@ -175,7 +175,7 @@ int rx_emsi(char *data)
Syslog('?', "Unexpected remote password \"%s\"", MBSE_SS(emsi_local_password));
}
inbound_open(remote->addr, protect);
inbound_open(remote->addr, protect, FALSE);
Syslog('i', "local lcodes 0x%04x, protos 0x%04x, opts 0x%04x", emsi_local_lcodes,emsi_local_protos,emsi_local_opts);
if ((rc=txemsi()))

View File

@@ -461,10 +461,10 @@ SM_STATE(scan_packet)
if (ghc == 0) {
Syslog('+', "Password correct, protected FTS-0001 session");
inbound_open(remote->addr, TRUE);
inbound_open(remote->addr, TRUE, FALSE);
} else {
Syslog('+', "Unsecure FTS-0001 session");
inbound_open(remote->addr, FALSE);
inbound_open(remote->addr, FALSE, FALSE);
}
/*
* Move the packet to the temp inbound so the we can later

View File

@@ -1,7 +1,6 @@
/*****************************************************************************
*
* $Id$
* File ..................: mbcico/inbound.c
* Purpose ...............: Fidonet mailer, inbound functions
*
*****************************************************************************
@@ -31,28 +30,27 @@
#include "../config.h"
#include "../lib/mbselib.h"
#include "dirlock.h"
#include "inbound.h"
extern char *inbound;
extern char *tempinbound;
extern int gotfiles;
extern int laststat;
/*
* Open the inbound directory, set the temp inbound for the node
* so that this is true multiline safe. All files received from
* the node during the session are stored here.
* For binkp we add one extra directory to queue incoming files.
*/
int inbound_open(faddr *addr, int protected)
int inbound_open(faddr *addr, int protected, int binkp_mode)
{
char *temp;
DIR *dp;
if (inbound)
free(inbound);
inbound = NULL;
@@ -63,8 +61,22 @@ int inbound_open(faddr *addr, int protected)
temp = calloc(PATH_MAX, sizeof(char));
snprintf(temp, PATH_MAX -1, "%s/tmp.%d.%d.%d.%d", inbound, addr->zone, addr->net, addr->node, addr->point);
/*
* Check if this directory already exist, it should not unless the previous
* session with this node failed for some reason.
*/
if ((dp = opendir(temp))) {
Syslog('s', "Binkp: dir %s already exists, previous session failed", temp);
laststat++;
closedir(dp);
}
tempinbound = xstrcpy(temp);
snprintf(temp, PATH_MAX -1, "%s/foobar", tempinbound);
if (binkp_mode)
snprintf(temp, PATH_MAX, "%s/tmp/foobar", tempinbound);
else
snprintf(temp, PATH_MAX, "%s/foobar", tempinbound);
mkdirs(temp, 0700);
free(temp);
@@ -86,7 +98,7 @@ int inbound_close(int success)
struct dirent *de;
char *source, *dest;
struct stat stb;
int rc;
int i, rc;
Syslog('s', "Closing temp inbound after a %s session", success?"good":"failed");
if (! success) {
@@ -100,6 +112,24 @@ int inbound_close(int success)
return 0;
}
/*
* Try to lock the inbound so we can safely move the files
* to the inbound.
*/
i = 30;
while (TRUE) {
if (lockdir(inbound))
break;
i--;
if (! i) {
WriteError("Can't lock %s", inbound);
return 1;
}
sleep(20);
Nopper();
}
Syslog('s', "inbound_close(): %s locked", inbound);
if ((dp = opendir(tempinbound)) == NULL) {
WriteError("$Can't open %s", tempinbound);
return 1;
@@ -109,8 +139,8 @@ int inbound_close(int success)
dest = calloc(PATH_MAX, sizeof(char));
while ((de = readdir(dp))) {
snprintf(source, PATH_MAX -1, "%s/%s", tempinbound, de->d_name);
snprintf(dest, PATH_MAX -1, "%s/%s", inbound, de->d_name);
snprintf(source, PATH_MAX, "%s/%s", tempinbound, de->d_name);
snprintf(dest, PATH_MAX, "%s/%s", inbound, de->d_name);
if ((lstat(source, &stb) == 0) && (S_ISREG(stb.st_mode))) {
if (file_exist(dest, F_OK) == 0) {
Syslog('!', "Cannot move %s to %s, file exists", de->d_name, inbound);
@@ -126,19 +156,35 @@ int inbound_close(int success)
}
closedir(dp);
free(source);
free(dest);
ulockdir(inbound);
Syslog('s', "inbound_close(): %s unlocked", inbound);
/*
* Try to remove binkp tmp queue. Only log if not empty, else
* don't log anything, this directory doesn't exist for normal
* sessions.
*/
snprintf(source, PATH_MAX, "%s/tmp", tempinbound);
if ((rc = rmdir(source))) {
if (errno == ENOTEMPTY) {
Syslog('+', "Keep binkp temp incoming directory, partial file");
}
} else {
Syslog('s', "inbound_close(): removed %s", source);
}
/*
* Try to clean the temp inbound, if it fails log this, maybe the
* next time it will work.
*/
if ((rc = rmdir(tempinbound))) {
WriteError("Can't remove %s: %s", tempinbound, strerror(rc));
WriteError("$Can't remove %s", tempinbound);
} else {
Syslog('s', "inbound_close(): removed %s", tempinbound);
}
free(source);
free(dest);
free(tempinbound);
tempinbound = NULL;

View File

@@ -1,11 +1,10 @@
/*****************************************************************************
*
* $Id$
* File ..................: mbcico/inbound.h
* Purpose ...............: Fidonet mailer, inbound functions
*
*****************************************************************************
* Copyright (C) 1997-2003
* Copyright (C) 1997-2005
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
@@ -33,8 +32,8 @@
#define _INBOUND_H
int inbound_open(faddr *, int); /* Open temp inbound */
int inbound_close(int); /* Close temp inbound */
long inbound_space(void); /* Get free inbound space */
int inbound_open(faddr *, int, int); /* Open temp inbound */
int inbound_close(int); /* Close temp inbound */
long inbound_space(void); /* Get free inbound space */
#endif

View File

@@ -39,6 +39,8 @@
#include "lutil.h"
#include "mbcico.h"
#include "session.h"
#include "binkp.h"
#define IEMSI 1
@@ -59,6 +61,7 @@ unsigned long rcvdbytes = 0;
int tcp_mode = TCPMODE_NONE;
int Loaded = FALSE;
int telnet = FALSE;
int crashme = FALSE;
extern char *myname;
@@ -116,6 +119,7 @@ void die(int onsig)
WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]);
else
Syslog('+', "Terminated with error %d", onsig);
binkp_abort();
}
if (sentbytes || rcvdbytes) {
@@ -232,7 +236,7 @@ int main(int argc, char *argv[])
setmyname(argv[0]);
while ((c = getopt(argc,argv,"r:n:l:t:a:I:h")) != -1) {
while ((c = getopt(argc,argv,"r:n:l:t:a:ch")) != -1) {
switch (c) {
case 'r': WriteError("commandline option -r is obsolete");
break;
@@ -265,6 +269,10 @@ int main(int argc, char *argv[])
case 'n': forcedphone = optarg;
break;
case 'c': crashme = TRUE;
Syslog('+', "crashme is set");
break;
default: usage();
die(MBERR_COMMANDLINE);
}

View File

@@ -196,7 +196,7 @@ int rx_yoohoo(void)
} else
Syslog('s', "No YooHoo password check");
inbound_open(remote->addr, protect);
inbound_open(remote->addr, protect, FALSE);
fillhello(localcaps,pwd);