Fixed binkd file resync

This commit is contained in:
Michiel Broek 2003-09-13 21:07:06 +00:00
parent f452c3635e
commit 7a9aaad934
3 changed files with 78 additions and 25 deletions

View File

@ -38,12 +38,11 @@ v0.37.7 09-Sep-2003
mbcico:
Fixed MB state error from the previous version.
Added more code to debug the broken transfer problem.
Add attempt to send a resync command, please test.
Rewrote another part of the binkp driver, initializing the
options.
If doesn't do Multiple Batch mode anymore against binkp/1.1
mailers.
File resync during receive finally works.
mbtask:
Added support for debug logfile. Dropped the debug switch for

View File

@ -94,6 +94,7 @@ static int ansbinkp(void);
static int binkp_batch(file_list *);
extern char *tempinbound;
extern char *ttystat[];
extern int Loaded;
extern pid_t mypid;
@ -133,6 +134,7 @@ struct binkprec {
int role; /* 1=orig, 0=answer */
int RxState; /* Receiver state */
int TxState; /* Transmitter state */
int DidSendGET; /* Did we send a GET command */
long rsize; /* Receiver filesize */
long roffs; /* Receiver offset */
char *rname; /* Receiver filename */
@ -168,6 +170,7 @@ void binkp_init(void)
bp.CRCflag = WeCan;
bp.Major = 1;
bp.Minor = 0;
bp.DidSendGET = FALSE;
}
@ -442,15 +445,26 @@ void binkp_send_control(int id,...)
/*
* 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 resync(off_t off)
{
Syslog('b', "Binkp: resync(%d)", off);
if (bp.CRCflag == Active) {
binkp_send_control(MM_GET, "%s %ld %ld %ld %lx", bp.rname, &bp.rsize, &bp.rtime, &bp.roffs, &bp.rcrc);
} else {
binkp_send_control(MM_GET, "%s %ld %ld %ld", bp.rname, &bp.rsize, &bp.rtime, &bp.roffs);
Syslog('b', "Binkp: resync(%d) DidSendGET=%s", off, bp.DidSendGET ?"TRUE":"FALSE");
if (!bp.DidSendGET) {
if (bp.CRCflag == Active) {
binkp_send_control(MM_GET, "%s %ld %ld %ld %lx", bp.rname, bp.rsize, bp.rtime, off, bp.rcrc);
} else {
binkp_send_control(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 */
}
return 0;
bp.DidSendGET = FALSE;
return 0; /* Signal openfile to open the file in append mode */
}
@ -858,11 +872,9 @@ SM_STATE(WaitOk)
SM_STATE(Opts)
/*
* Room to negotiate more protocol options.
* When we are binkp/1.1 and remote is 1.0 we should
* negotiate MB mode here.
* Try to initiate the MB option if the remote is binkp/1.0
*/
if (bp.MBflag == WeCan) {
if ((bp.MBflag == WeCan) && (bp.Major == 1) && (bp.Minor == 0)) {
bp.MBflag = WeWant;
Syslog('b', "MBflag WeCan => WeWant");
binkp_send_control(MM_NUL, "OPT MB");
@ -1190,6 +1202,7 @@ int binkp_batch(file_list *to_send)
struct timeval rxtvstart, rxtvend;
struct timeval txtvstart, txtvend;
struct timezone tz;
struct statfs sfs;
rxtvstart.tv_sec = rxtvstart.tv_usec = 0;
rxtvend.tv_sec = rxtvend.tv_usec = 0;
@ -1550,7 +1563,13 @@ int binkp_batch(file_list *to_send)
transferred = TRUE;
}
} else {
Syslog('+', "Binkp: unexpected DATA frame %d", rxbuf[0]);
if (!bp.DidSendGET) {
/*
* Do not log after a GET command, there will be data packets
* in the pipeline that must be ignored.
*/
Syslog('+', "Binkp: unexpected DATA frame %d", rxbuf[0]);
}
}
}
}
@ -1576,8 +1595,26 @@ int binkp_batch(file_list *to_send)
bp.rname, date(bp.rtime), bp.rsize, bp.roffs);
(void)binkp2unix(bp.rname);
rxfp = openfile(binkp2unix(bp.rname), bp.rtime, bp.rsize, &rxbytes, resync);
if (bp.DidSendGET) {
/*
* 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 = RxWaitFile;
break;
}
gettimeofday(&rxtvstart, &tz);
rxpos = 0;
rxpos = bp.roffs;
/*
* FIXME: if we have a rxpos, we are appending a partial received file.
* We now need to know the CRC of the already received part!
* Note, file is open in a+ mode, so we can read the already received
* part and calculate the crc. For now, don't use CRC32 mode.
*/
rxcrc = 0xffffffff;
rxerror = FALSE;
@ -1590,6 +1627,17 @@ int binkp_batch(file_list *to_send)
break;
}
if (statfs(tempinbound, &sfs) == 0) {
Syslog('b', "blocksize %lu free blocks %lu", sfs.f_bsize, sfs.f_bfree);
Syslog('b', "need %lu blocks", (unsigned long)(bp.rsize / (sfs.f_bsize + 1)));
if ((bp.rsize / (sfs.f_bsize + 1)) >= sfs.f_bfree) {
Syslog('!', "Only %lu blocks free (need %lu) in %s", sfs.f_bfree,
(unsigned long)(bp.rsize / (sfs.f_bsize + 1)), tempinbound);
closefile();
rxfp = NULL; /* Force SKIP command */
}
}
if (bp.rsize == rxbytes) {
/*
* We already got this file, send GOT so it will

View File

@ -61,12 +61,12 @@ extern char *tempinbound;
FILE *openfile(char *fname, time_t remtime, off_t remsize, off_t *resofs, int(*resync)(off_t))
{
char *opentype, *p, x, ctt[32], tmpfname[16];
int rc, ncount;
int rc, rsc, ncount;
struct stat st;
strcpy(ctt,date(remtime));
Syslog('s', "openfile(\"%s\",%s,%lu,...)", MBSE_SS(fname), MBSE_SS(ctt),(unsigned long)remsize);
Syslog('s', "openfile(\"%s\",%s,%lu,...)", MBSE_SS(fname), MBSE_SS(ctt), (unsigned long)remsize);
if ((fname == NULL) || (fname[0] == '\0')) {
sprintf(tmpfname,"%08lx.pkt",(unsigned long)sequencer());
@ -97,8 +97,7 @@ FILE *openfile(char *fname, time_t remtime, off_t remsize, off_t *resofs, int(*r
}
infpath = xstrcat(infpath, fname);
if (stat(infpath, &st) == 0) {
/* FIXME: temp normal logging now! */
Syslog('-', "remtine=%ld, st_time=%ld, remsize=%ld, st_size=%ld", remtime, st.st_mtime, remsize, st.st_size);
Syslog('s', "remtine=%ld, st_time=%ld, remsize=%ld, st_size=%ld", remtime, st.st_mtime, remsize, st.st_size);
if ((remtime == st.st_mtime) && (remsize == st.st_size)) {
Syslog('+', "File %s is already here", fname);
@ -158,13 +157,20 @@ FILE *openfile(char *fname, time_t remtime, off_t remsize, off_t *resofs, int(*r
*resofs = 0L;
opentype = (char *)"w";
if ((rc == 0) && (remsize != 0)) {
Syslog('+', "Resyncing at offset %lu of \"%s\"", (unsigned long)st.st_size, infpath);
if (resync(st.st_size) == 0) {
opentype = (char *)"a";
*resofs = st.st_size;
Syslog('s', "resync == 0");
} else {
Syslog('s', "resync != 0");
rsc = resync(st.st_size);
Syslog('s', "resync(%d) rsc=%d", (int)st.st_size, rsc);
switch (rsc) {
case 0: /* Success */
opentype = (char *)"a+";
*resofs = st.st_size;
Syslog('+', "Resyncing at offset %lu of \"%s\"", (unsigned long)st.st_size, infpath);
break;
case -1: /* Binkp did send a GET, return here and do not open file */
free(infpath);
infpath = NULL;
return NULL;
default: /* Error from xmrecv, do nothing */
break;
}
}
Syslog('s', "try fopen(\"%s\",\"%s\")", infpath, opentype);