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: mbcico:
Fixed MB state error from the previous version. 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 Rewrote another part of the binkp driver, initializing the
options. options.
If doesn't do Multiple Batch mode anymore against binkp/1.1 If doesn't do Multiple Batch mode anymore against binkp/1.1
mailers. mailers.
File resync during receive finally works.
mbtask: mbtask:
Added support for debug logfile. Dropped the debug switch for 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 *); static int binkp_batch(file_list *);
extern char *tempinbound;
extern char *ttystat[]; extern char *ttystat[];
extern int Loaded; extern int Loaded;
extern pid_t mypid; extern pid_t mypid;
@ -133,6 +134,7 @@ struct binkprec {
int role; /* 1=orig, 0=answer */ int role; /* 1=orig, 0=answer */
int RxState; /* Receiver state */ int RxState; /* Receiver state */
int TxState; /* Transmitter state */ int TxState; /* Transmitter state */
int DidSendGET; /* Did we send a GET command */
long rsize; /* Receiver filesize */ long rsize; /* Receiver filesize */
long roffs; /* Receiver offset */ long roffs; /* Receiver offset */
char *rname; /* Receiver filename */ char *rname; /* Receiver filename */
@ -168,6 +170,7 @@ void binkp_init(void)
bp.CRCflag = WeCan; bp.CRCflag = WeCan;
bp.Major = 1; bp.Major = 1;
bp.Minor = 0; 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) int resync(off_t off)
{ {
Syslog('b', "Binkp: resync(%d)", off); Syslog('b', "Binkp: resync(%d) DidSendGET=%s", off, bp.DidSendGET ?"TRUE":"FALSE");
if (bp.CRCflag == Active) { if (!bp.DidSendGET) {
binkp_send_control(MM_GET, "%s %ld %ld %ld %lx", bp.rname, &bp.rsize, &bp.rtime, &bp.roffs, &bp.rcrc); if (bp.CRCflag == Active) {
} else { binkp_send_control(MM_GET, "%s %ld %ld %ld %lx", bp.rname, bp.rsize, bp.rtime, off, bp.rcrc);
binkp_send_control(MM_GET, "%s %ld %ld %ld", bp.rname, &bp.rsize, &bp.rtime, &bp.roffs); } 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) SM_STATE(Opts)
/* /*
* Room to negotiate more protocol options. * Try to initiate the MB option if the remote is binkp/1.0
* When we are binkp/1.1 and remote is 1.0 we should
* negotiate MB mode here.
*/ */
if (bp.MBflag == WeCan) { if ((bp.MBflag == WeCan) && (bp.Major == 1) && (bp.Minor == 0)) {
bp.MBflag = WeWant; bp.MBflag = WeWant;
Syslog('b', "MBflag WeCan => WeWant"); Syslog('b', "MBflag WeCan => WeWant");
binkp_send_control(MM_NUL, "OPT MB"); binkp_send_control(MM_NUL, "OPT MB");
@ -1190,6 +1202,7 @@ int binkp_batch(file_list *to_send)
struct timeval rxtvstart, rxtvend; struct timeval rxtvstart, rxtvend;
struct timeval txtvstart, txtvend; struct timeval txtvstart, txtvend;
struct timezone tz; struct timezone tz;
struct statfs sfs;
rxtvstart.tv_sec = rxtvstart.tv_usec = 0; rxtvstart.tv_sec = rxtvstart.tv_usec = 0;
rxtvend.tv_sec = rxtvend.tv_usec = 0; rxtvend.tv_sec = rxtvend.tv_usec = 0;
@ -1550,7 +1563,13 @@ int binkp_batch(file_list *to_send)
transferred = TRUE; transferred = TRUE;
} }
} else { } 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); bp.rname, date(bp.rtime), bp.rsize, bp.roffs);
(void)binkp2unix(bp.rname); (void)binkp2unix(bp.rname);
rxfp = openfile(binkp2unix(bp.rname), bp.rtime, bp.rsize, &rxbytes, resync); 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); 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; rxcrc = 0xffffffff;
rxerror = FALSE; rxerror = FALSE;
@ -1590,6 +1627,17 @@ int binkp_batch(file_list *to_send)
break; 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) { if (bp.rsize == rxbytes) {
/* /*
* We already got this file, send GOT so it will * 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)) 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]; char *opentype, *p, x, ctt[32], tmpfname[16];
int rc, ncount; int rc, rsc, ncount;
struct stat st; struct stat st;
strcpy(ctt,date(remtime)); 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')) { if ((fname == NULL) || (fname[0] == '\0')) {
sprintf(tmpfname,"%08lx.pkt",(unsigned long)sequencer()); 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); infpath = xstrcat(infpath, fname);
if (stat(infpath, &st) == 0) { if (stat(infpath, &st) == 0) {
/* FIXME: temp normal logging now! */ Syslog('s', "remtine=%ld, st_time=%ld, remsize=%ld, st_size=%ld", remtime, st.st_mtime, remsize, st.st_size);
Syslog('-', "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)) { if ((remtime == st.st_mtime) && (remsize == st.st_size)) {
Syslog('+', "File %s is already here", fname); 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; *resofs = 0L;
opentype = (char *)"w"; opentype = (char *)"w";
if ((rc == 0) && (remsize != 0)) { if ((rc == 0) && (remsize != 0)) {
Syslog('+', "Resyncing at offset %lu of \"%s\"", (unsigned long)st.st_size, infpath); rsc = resync(st.st_size);
if (resync(st.st_size) == 0) { Syslog('s', "resync(%d) rsc=%d", (int)st.st_size, rsc);
opentype = (char *)"a"; switch (rsc) {
*resofs = st.st_size; case 0: /* Success */
Syslog('s', "resync == 0"); opentype = (char *)"a+";
} else { *resofs = st.st_size;
Syslog('s', "resync != 0"); 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); Syslog('s', "try fopen(\"%s\",\"%s\")", infpath, opentype);