Fixed binkd file resync
This commit is contained in:
parent
f452c3635e
commit
7a9aaad934
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user