Fixed binkd file resync
This commit is contained in:
parent
f452c3635e
commit
7a9aaad934
@ -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
|
||||||
|
@ -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.DidSendGET) {
|
||||||
if (bp.CRCflag == Active) {
|
if (bp.CRCflag == Active) {
|
||||||
binkp_send_control(MM_GET, "%s %ld %ld %ld %lx", bp.rname, &bp.rsize, &bp.rtime, &bp.roffs, &bp.rcrc);
|
binkp_send_control(MM_GET, "%s %ld %ld %ld %lx", bp.rname, bp.rsize, bp.rtime, off, bp.rcrc);
|
||||||
} else {
|
} else {
|
||||||
binkp_send_control(MM_GET, "%s %ld %ld %ld", bp.rname, &bp.rsize, &bp.rtime, &bp.roffs);
|
binkp_send_control(MM_GET, "%s %ld %ld %ld", bp.rname, bp.rsize, bp.rtime, off);
|
||||||
}
|
}
|
||||||
return 0;
|
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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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,10 +1563,16 @@ int binkp_batch(file_list *to_send)
|
|||||||
transferred = TRUE;
|
transferred = TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
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]);
|
Syslog('+', "Binkp: unexpected DATA frame %d", rxbuf[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
GotFrame = FALSE;
|
GotFrame = FALSE;
|
||||||
rxlen = 0;
|
rxlen = 0;
|
||||||
header = 0;
|
header = 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
|
||||||
|
@ -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) {
|
||||||
|
case 0: /* Success */
|
||||||
|
opentype = (char *)"a+";
|
||||||
*resofs = st.st_size;
|
*resofs = st.st_size;
|
||||||
Syslog('s', "resync == 0");
|
Syslog('+', "Resyncing at offset %lu of \"%s\"", (unsigned long)st.st_size, infpath);
|
||||||
} else {
|
break;
|
||||||
Syslog('s', "resync != 0");
|
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);
|
||||||
|
Reference in New Issue
Block a user