Binkp MB handshake options changed

This commit is contained in:
Michiel Broek 2003-09-12 20:38:00 +00:00
parent 55ea16e838
commit f452c3635e
2 changed files with 193 additions and 147 deletions

View File

@ -2,11 +2,10 @@ $Id$
WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!
Inbound file handling is changed, this version is under test and should NOT Inbound file handling is changed, this is safe to use now.
be used on production systems if you don't want to help debugging. Please run this version with debugging on, mbsetup 1.14.1 turn 5, 11
Handshake and EMSI is changed, please run this version with debugging on, and 18 on at least. Report any problems and include a piece of the
mbsetup 1.14.1 turn 5, 11 and 18 on at least. Report any problems and include (debug)logfile.
a piece of the (debug)logfile.
Before installing, make a copy of /opt/mbse/bin/mbcico so you can go back Before installing, make a copy of /opt/mbse/bin/mbcico so you can go back
if you experience any problems. if you experience any problems.
@ -41,6 +40,10 @@ v0.37.7 09-Sep-2003
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. Added more code to debug the broken transfer problem.
Add attempt to send a resync command, please test. 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.
mbtask: mbtask:
Added support for debug logfile. Dropped the debug switch for Added support for debug logfile. Dropped the debug switch for

View File

@ -75,6 +75,8 @@ static char *bstate[] = {
/* /*
* Local prototypes * Local prototypes
*/ */
void binkp_init(void);
void binkp_deinit(void);
char *unix2binkp(char *); char *unix2binkp(char *);
char *binkp2unix(char *); char *binkp2unix(char *);
int binkp_expired(void); int binkp_expired(void);
@ -89,7 +91,7 @@ void binkp_settimer(int);
int resync(off_t); int resync(off_t);
static int orgbinkp(void); static int orgbinkp(void);
static int ansbinkp(void); static int ansbinkp(void);
static int binkp_batch(file_list *, int); static int binkp_batch(file_list *);
extern char *ttystat[]; extern char *ttystat[];
@ -117,15 +119,9 @@ static char *txstate[] = { (char *)"TxGetNextFile", (char *)"TryRread", (char *)
static char *opstate[] = { (char *)"No", (char *)"WeCan", (char *)"WeWant", (char *)"TheyWant", (char *)"Active" }; static char *opstate[] = { (char *)"No", (char *)"WeCan", (char *)"WeWant", (char *)"TheyWant", (char *)"Active" };
static int RxState; /* Receiver state */
static int TxState; /* Transmitter state */
//static int TfState; //static int TfState;
static time_t Timer; static time_t Timer;
static int MBflag = No; /* MB option flag */
static int CRAMflag = FALSE; /* CRAM option flag */ static int CRAMflag = FALSE; /* CRAM option flag */
static int CRCflag = No; /* CRC option flag */
static int Major = 1; /* Remote major protocol version */
static int Minor = 0; /* Remote minor protocol version */
static int Secure = FALSE; /* Secure session */ static int Secure = FALSE; /* Secure session */
unsigned long nethold, mailhold; /* Trafic for the remote */ unsigned long nethold, mailhold; /* Trafic for the remote */
int transferred = FALSE; /* Anything transferred in batch */ int transferred = FALSE; /* Anything transferred in batch */
@ -133,12 +129,57 @@ int batchnr = 0, crc_errors = 0;
unsigned char *MD_challenge = NULL; /* Received CRAM challenge data */ unsigned char *MD_challenge = NULL; /* Received CRAM challenge data */
int ext_rand = 0; int ext_rand = 0;
struct binkprec {
int role; /* 1=orig, 0=answer */
int RxState; /* Receiver state */
int TxState; /* Transmitter state */
long rsize; /* Receiver filesize */ long rsize; /* Receiver filesize */
long roffs; /* Receiver offset */ long roffs; /* Receiver offset */
char *rname; /* Receiver filename */ char *rname; /* Receiver filename */
time_t rtime; /* Receiver filetime */ time_t rtime; /* Receiver filetime */
unsigned long rcrc; /* Receiver crc */ unsigned long rcrc; /* Receiver crc */
long lsize; /* Local filesize */
char *lname; /* Local filename */
time_t ltime; /* Local filetime */
unsigned long tcrc; /* Transmitter crc */
long gsize; /* GET filesize */
long goffset; /* GET offset */
char *gname; /* GET filename */
time_t gtime; /* GET filetime */
int MBflag; /* MB option flag */
int CRCflag; /* CRC option flag */
int Major; /* Remote major protocol version */
int Minor; /* Remote minor protocol version */
};
struct binkprec bp; /* Global structure */
void binkp_init(void)
{
bp.rname = calloc(512, sizeof(char));
bp.lname = calloc(512, sizeof(char));
bp.gname = calloc(512, sizeof(char));
bp.MBflag = WeCan;
if (CFG.NoCRC32)
bp.CRCflag = No;
else
bp.CRCflag = WeCan;
bp.Major = 1;
bp.Minor = 0;
}
void binkp_deinit(void)
{
if (bp.rname)
free(bp.rname);
if (bp.lname)
free(bp.lname);
if (bp.gname)
free(bp.gname);
}
int binkp(int role) int binkp(int role)
@ -148,11 +189,7 @@ int binkp(int role)
file_list *tosend = NULL, *request = NULL, *respond = NULL, *tmpfl; file_list *tosend = NULL, *request = NULL, *respond = NULL, *tmpfl;
char *nonhold_mail; char *nonhold_mail;
MBflag = WeCan; binkp_init();
if (CFG.NoCRC32)
CRCflag = No;
else
CRCflag = WeCan;
most_debug = TRUE; most_debug = TRUE;
if (role == 1) { if (role == 1) {
@ -167,6 +204,7 @@ int binkp(int role)
if (rc) { if (rc) {
Syslog('!', "Binkp: session failed"); Syslog('!', "Binkp: session failed");
binkp_deinit();
return rc; return rc;
} }
@ -197,11 +235,11 @@ int binkp(int role)
request = NULL; request = NULL;
} }
rc = binkp_batch(tosend, role); rc = binkp_batch(tosend);
tidy_filelist(tosend, (rc == 0)); tidy_filelist(tosend, (rc == 0));
tosend = NULL; tosend = NULL;
if ((rc == 0) && transferred && (MBflag == Active)) { if ((rc == 0) && transferred && (bp.MBflag == Active)) {
/* /*
* Running Multiple Batch, only if last batch actually * Running Multiple Batch, only if last batch actually
* did transfer some data. * did transfer some data.
@ -214,16 +252,16 @@ int binkp(int role)
tosend = create_filelist(eff_remote, nonhold_mail, 0); tosend = create_filelist(eff_remote, nonhold_mail, 0);
for (tmpfl = tosend; tmpfl->next; tmpfl = tmpfl->next); for (tmpfl = tosend; tmpfl->next; tmpfl = tmpfl->next);
tmpfl->next = respond; tmpfl->next = respond;
rc = binkp_batch(tosend, role); rc = binkp_batch(tosend);
tmpfl->next = NULL; tmpfl->next = NULL;
} }
Syslog('+', "Binkp: end transfer rc=%d", rc); Syslog('+', "Binkp: end transfer rc=%d", rc);
closetcp(); closetcp();
Syslog('b', "2nd batch or not, MB flag =%d", MBflag); Syslog('b', "2nd batch or not, MB flag is %s", opstate[bp.MBflag]);
if (MBflag != Active) { if (bp.MBflag != Active) {
/* /*
* In singe batch mode we process filerequests after the batch. * In singe batch mode we process filerequests after the batch.
* The results will be put on hold for the calling node. * The results will be put on hold for the calling node.
@ -245,6 +283,7 @@ int binkp(int role)
tidy_filelist(tosend, (rc == 0)); tidy_filelist(tosend, (rc == 0));
tidy_filelist(respond, 0); tidy_filelist(respond, 0);
binkp_deinit();
rc = abs(rc); rc = abs(rc);
return rc; return rc;
} }
@ -406,10 +445,10 @@ void binkp_send_control(int id,...)
int resync(off_t off) int resync(off_t off)
{ {
Syslog('b', "Binkp: resync(%d)", off); Syslog('b', "Binkp: resync(%d)", off);
if (CRCflag == Active) { if (bp.CRCflag == Active) {
binkp_send_control(MM_GET, "%s %ld %ld %ld %lx", rname, &rsize, &rtime, &roffs, &rcrc); binkp_send_control(MM_GET, "%s %ld %ld %ld %lx", bp.rname, &bp.rsize, &bp.rtime, &bp.roffs, &bp.rcrc);
} else { } else {
binkp_send_control(MM_GET, "%s %ld %ld %ld", rname, &rsize, &rtime, &roffs); binkp_send_control(MM_GET, "%s %ld %ld %ld", bp.rname, &bp.rsize, &bp.rtime, &bp.roffs);
} }
return 0; return 0;
} }
@ -509,9 +548,16 @@ void b_nul(char *msg)
else if (strncmp(msg, "VER ", 4) == 0) { else if (strncmp(msg, "VER ", 4) == 0) {
Syslog('+', "Uses : %s", msg+4); Syslog('+', "Uses : %s", msg+4);
if ((p = strstr(msg+4, PRTCLNAME "/")) && (q = strstr(p, "."))) { if ((p = strstr(msg+4, PRTCLNAME "/")) && (q = strstr(p, "."))) {
Major = atoi(p + 6); bp.Major = atoi(p + 6);
Minor = atoi(q + 1); bp.Minor = atoi(q + 1);
Syslog('b', "Remote protocol version %d.%d", Major, Minor); Syslog('b', "Remote protocol version %d.%d", bp.Major, bp.Minor);
/*
* Disable MB if protocol > 1.0 and MB was not yet active.
*/
if ((bp.MBflag != Active) && (((bp.Major * 10) + bp.Minor) > 10)) {
Syslog('b', "MBflag %s => No", opstate[bp.MBflag]);
bp.MBflag = No;
}
} }
} }
else if (strncmp(msg, "PHN ", 4) == 0) else if (strncmp(msg, "PHN ", 4) == 0)
@ -523,15 +569,18 @@ void b_nul(char *msg)
else if (strncmp(msg, "OPT ", 4) == 0) { else if (strncmp(msg, "OPT ", 4) == 0) {
Syslog('+', "Options : %s", msg+4); Syslog('+', "Options : %s", msg+4);
if (strstr(msg, (char *)"MB") != NULL) { if (strstr(msg, (char *)"MB") != NULL) {
Syslog('b', "Remote requests MB, current state = %d", MBflag); Syslog('b', "Remote requests MB, current state = %s", opstate[bp.MBflag]);
if (MBflag == WeCan) { /* Answering session and do binkp/1.0 */ if ((bp.MBflag == WeCan) && (bp.Major == 1) && (bp.Minor == 0)) { /* Answering session and do binkp/1.0 */
MBflag = TheyWant; bp.MBflag = TheyWant;
Syslog('b', "MBflag WeCan => TheyWant"); Syslog('b', "MBflag WeCan => TheyWant");
} else if (MBflag == WeWant) { /* Originating session and do binkp/1.0 */ binkp_send_control(MM_NUL,"OPT MB");
MBflag = Active; Syslog('b', "MBflag TheyWant => Active");
bp.MBflag = Active;
} else if ((bp.MBflag == WeWant) && (bp.Major == 1) && (bp.Minor == 0)) { /* Originating session and do binkp/1.0 */
bp.MBflag = Active;
Syslog('b', "MBflag WeWant => Active"); Syslog('b', "MBflag WeWant => Active");
} else { } else {
Syslog('b', "MBflag is %s and received MB option", opstate[MBflag]); Syslog('b', "MBflag is %s and received MB option", opstate[bp.MBflag]);
} }
} }
if (strstr(msg, (char *)"CRAM-MD5-") != NULL) { /* No SHA-1 support */ if (strstr(msg, (char *)"CRAM-MD5-") != NULL) { /* No SHA-1 support */
@ -544,14 +593,14 @@ void b_nul(char *msg)
} }
} }
if (strstr(msg, (char *)"CRC") != NULL) { if (strstr(msg, (char *)"CRC") != NULL) {
if (CRCflag == WeCan) { if (bp.CRCflag == WeCan) {
CRCflag = TheyWant; bp.CRCflag = TheyWant;
Syslog('b', "CRCflag WeCan => TheyWant"); Syslog('b', "CRCflag WeCan => TheyWant");
} else if (CRCflag == WeWant) { } else if (bp.CRCflag == WeWant) {
CRCflag = Active; bp.CRCflag = Active;
Syslog('b', "CRCflag WeWant => Active"); Syslog('b', "CRCflag WeWant => Active");
} else { } else {
Syslog('b', "CRCflag is %s and received CRC option", opstate[CRCflag]); Syslog('b', "CRCflag is %s and received CRC option", opstate[bp.CRCflag]);
} }
} }
} else } else
@ -605,14 +654,9 @@ SM_STATE(WaitConn)
* Build options we want * Build options we want
*/ */
p = xstrcpy((char *)"OPT"); p = xstrcpy((char *)"OPT");
if (MBflag == WeCan) { if ((noderecord(remote->addr)) && nodes.CRC32 && (bp.CRCflag == WeCan)) {
p = xstrcat(p, (char *)" MB");
MBflag = WeWant;
Syslog('b', "MBflag WeCan => WeWant");
}
if ((noderecord(remote->addr)) && nodes.CRC32 && (CRCflag == WeCan)) {
p = xstrcat(p, (char *)" CRC"); p = xstrcat(p, (char *)" CRC");
CRCflag = WeWant; bp.CRCflag = WeWant;
Syslog('b', "CRCflag WeCan => WeWant"); Syslog('b', "CRCflag WeCan => WeWant");
} }
if (strcmp(p, (char *)"OPT")) if (strcmp(p, (char *)"OPT"))
@ -818,6 +862,11 @@ SM_STATE(Opts)
* When we are binkp/1.1 and remote is 1.0 we should * When we are binkp/1.1 and remote is 1.0 we should
* negotiate MB mode here. * negotiate MB mode here.
*/ */
if (bp.MBflag == WeCan) {
bp.MBflag = WeWant;
Syslog('b', "MBflag WeCan => WeWant");
binkp_send_control(MM_NUL, "OPT MB");
}
SM_SUCCESS; SM_SUCCESS;
SM_END SM_END
@ -950,19 +999,19 @@ SM_STATE(WaitAddr)
if (nlent) if (nlent)
rdoptions(Loaded); rdoptions(Loaded);
if (MBflag == TheyWant) { // if (bp.MBflag == TheyWant) {
Syslog('b', "Binkp: remote supports MB"); // Syslog('b', "Binkp: remote supports MB");
binkp_send_control(MM_NUL,"OPT MB"); // binkp_send_control(MM_NUL,"OPT MB");
MBflag = Active; // bp.MBflag = Active;
} // }
if (CRCflag == TheyWant) { if (bp.CRCflag == TheyWant) {
if (Loaded && nodes.CRC32 && !CFG.NoCRC32) { if (Loaded && nodes.CRC32 && !CFG.NoCRC32) {
binkp_send_control(MM_NUL,"OPT CRC"); binkp_send_control(MM_NUL,"OPT CRC");
Syslog('+', "Binkp: using file transfers with CRC32 checking"); Syslog('+', "Binkp: using file transfers with CRC32 checking");
CRCflag = Active; bp.CRCflag = Active;
} else { } else {
Syslog('b', "Binkp: CRC32 support is diabled here"); Syslog('b', "Binkp: CRC32 support is diabled here");
CRCflag = No; bp.CRCflag = No;
} }
} }
@ -1126,17 +1175,15 @@ void debug_binkp_list(binkp_list **bll)
int binkp_batch(file_list *to_send, int role) int binkp_batch(file_list *to_send)
{ {
int rc = 0, NotDone, rxlen = 0, txlen = 0, rxerror = FALSE; int rc = 0, NotDone, rxlen = 0, txlen = 0, rxerror = FALSE;
static char *txbuf, *rxbuf; static char *txbuf, *rxbuf;
FILE *txfp = NULL, *rxfp = NULL; FILE *txfp = NULL, *rxfp = NULL;
long txpos = 0, rxpos = 0, stxpos = 0, written, lsize, gsize, goffset; long txpos = 0, rxpos = 0, stxpos = 0, written;
int sverr, cmd = FALSE, GotFrame = FALSE, blklen = 0, c, Found = FALSE; int sverr, cmd = FALSE, GotFrame = FALSE, blklen = 0, c, Found = FALSE;
unsigned short header = 0; unsigned short header = 0;
char *lname, *gname; unsigned long rxcrc = 0;
time_t ltime, gtime;
unsigned long tcrc = 0, rxcrc = 0;
off_t rxbytes; off_t rxbytes;
binkp_list *bll = NULL, *tmp, *tmpg, *cursend = NULL; binkp_list *bll = NULL, *tmp, *tmpg, *cursend = NULL;
file_list *tsl; file_list *tsl;
@ -1149,19 +1196,17 @@ int binkp_batch(file_list *to_send, int role)
txtvstart.tv_sec = txtvstart.tv_usec = 0; txtvstart.tv_sec = txtvstart.tv_usec = 0;
txtvend.tv_sec = txtvend.tv_usec = 0; txtvend.tv_sec = txtvend.tv_usec = 0;
tz.tz_minuteswest = tz.tz_dsttime = 0; tz.tz_minuteswest = tz.tz_dsttime = 0;
rcrc = 0; bp.rcrc = 0;
bp.tcrc = 0;
batchnr++; batchnr++;
Syslog('+', "Binkp: starting batch %d", batchnr); Syslog('+', "Binkp: starting batch %d", batchnr);
IsDoing("Binkp %s %s", (role == 1)?"out":"inb", ascfnode(remote->addr, 0xf)); IsDoing("Binkp %s %s", (bp.role == 1)?"out":"inb", ascfnode(remote->addr, 0xf));
txbuf = calloc(MAX_BLKSIZE + 3, sizeof(unsigned char)); txbuf = calloc(MAX_BLKSIZE + 3, sizeof(unsigned char));
rxbuf = calloc(MAX_BLKSIZE + 3, sizeof(unsigned char)); rxbuf = calloc(MAX_BLKSIZE + 3, sizeof(unsigned char));
rname = calloc(512, sizeof(char));
lname = calloc(512, sizeof(char));
gname = calloc(512, sizeof(char));
// TfState = Switch; // TfState = Switch;
RxState = RxWaitFile; bp.RxState = RxWaitFile;
TxState = TxGetNextFile; bp.TxState = TxGetNextFile;
binkp_settimer(BINKP_TIMEOUT); binkp_settimer(BINKP_TIMEOUT);
nethold = mailhold = 0L; nethold = mailhold = 0L;
transferred = FALSE; transferred = FALSE;
@ -1179,14 +1224,14 @@ int binkp_batch(file_list *to_send, int role)
Syslog('+', "Binkp: mail %ld, files %ld bytes", nethold, mailhold); Syslog('+', "Binkp: mail %ld, files %ld bytes", nethold, mailhold);
binkp_send_control(MM_NUL, "TRF %ld %ld", nethold, mailhold); binkp_send_control(MM_NUL, "TRF %ld %ld", nethold, mailhold);
while ((RxState != RxDone) || (TxState != TxDone)) { while ((bp.RxState != RxDone) || (bp.TxState != TxDone)) {
Nopper(); Nopper();
if (binkp_expired()) { if (binkp_expired()) {
Syslog('!', "Binkp: Transfer timeout"); Syslog('!', "Binkp: Transfer timeout");
Syslog('b', "Binkp: TxState=%s, RxState=%s, rxlen=%d", txstate[TxState], rxstate[RxState], rxlen); Syslog('b', "Binkp: TxState=%s, RxState=%s, rxlen=%d", txstate[bp.TxState], rxstate[bp.RxState], rxlen);
RxState = RxDone; bp.RxState = RxDone;
TxState = TxDone; bp.TxState = TxDone;
binkp_send_control(MM_ERR, "Transfer timeout"); binkp_send_control(MM_ERR, "Transfer timeout");
rc = MBERR_FTRANSFER; rc = MBERR_FTRANSFER;
break; break;
@ -1208,8 +1253,8 @@ int binkp_batch(file_list *to_send, int role)
break; break;
} }
Syslog('?', "Binkp: receiver status %s", ttystat[c]); Syslog('?', "Binkp: receiver status %s", ttystat[c]);
TxState = TxDone; bp.TxState = TxDone;
RxState = RxDone; bp.RxState = RxDone;
rc = (MBERR_TTYIO + (-c)); rc = (MBERR_TTYIO + (-c));
break; break;
} else { } else {
@ -1238,7 +1283,7 @@ int binkp_batch(file_list *to_send, int role)
/* /*
* Transmitter state machine * Transmitter state machine
*/ */
switch (TxState) { switch (bp.TxState) {
case TxGetNextFile: case TxGetNextFile:
for (tmp = bll; tmp; tmp = tmp->next) { for (tmp = bll; tmp; tmp = tmp->next) {
if (tmp->state == NoState) { if (tmp->state == NoState) {
@ -1252,10 +1297,10 @@ int binkp_batch(file_list *to_send, int role)
txflock.l_start = 0L; txflock.l_start = 0L;
txflock.l_len = 0L; txflock.l_len = 0L;
if (CRCflag == Active) if (bp.CRCflag == Active)
tcrc = file_crc(tmp->local, FALSE); bp.tcrc = file_crc(tmp->local, FALSE);
else else
tcrc = 0; bp.tcrc = 0;
txfp = fopen(tmp->local, "r"); txfp = fopen(tmp->local, "r");
if (txfp == NULL) { if (txfp == NULL) {
@ -1279,10 +1324,10 @@ int binkp_batch(file_list *to_send, int role)
txpos = stxpos = tmp->offset; txpos = stxpos = tmp->offset;
Syslog('+', "Binkp: send \"%s\" as \"%s\"", MBSE_SS(tmp->local), MBSE_SS(tmp->remote)); Syslog('+', "Binkp: send \"%s\" as \"%s\"", MBSE_SS(tmp->local), MBSE_SS(tmp->remote));
if ((CRCflag == Active) && tcrc) { if ((bp.CRCflag == Active) && bp.tcrc) {
Syslog('+', "Binkp: size %lu bytes, dated %s, crc %lx", (unsigned long)tmp->size, date(tmp->date), tcrc); Syslog('+', "Binkp: size %lu bytes, dated %s, crc %lx", (unsigned long)tmp->size, date(tmp->date), bp.tcrc);
binkp_send_control(MM_FILE, "%s %lu %ld %ld %lx", MBSE_SS(tmp->remote), binkp_send_control(MM_FILE, "%s %lu %ld %ld %lx", MBSE_SS(tmp->remote),
(unsigned long)tmp->size, (long)tmp->date, (unsigned long)tmp->offset, tcrc); (unsigned long)tmp->size, (long)tmp->date, (unsigned long)tmp->offset, bp.tcrc);
} else { } else {
Syslog('+', "Binkp: size %lu bytes, dated %s", (unsigned long)tmp->size, date(tmp->date)); Syslog('+', "Binkp: size %lu bytes, dated %s", (unsigned long)tmp->size, date(tmp->date));
binkp_send_control(MM_FILE, "%s %lu %ld %ld", MBSE_SS(tmp->remote), binkp_send_control(MM_FILE, "%s %lu %ld %ld", MBSE_SS(tmp->remote),
@ -1291,7 +1336,7 @@ int binkp_batch(file_list *to_send, int role)
gettimeofday(&txtvstart, &tz); gettimeofday(&txtvstart, &tz);
tmp->state = Sending; tmp->state = Sending;
cursend = tmp; cursend = tmp;
TxState = TxTryRead; bp.TxState = TxTryRead;
transferred = TRUE; transferred = TRUE;
break; break;
} /* if state == NoState */ } /* if state == NoState */
@ -1301,7 +1346,7 @@ int binkp_batch(file_list *to_send, int role)
/* /*
* No more files to send * No more files to send
*/ */
TxState = TxWaitLastAck; bp.TxState = TxWaitLastAck;
Syslog('b', "Binkp: transmitter to WaitLastAck"); Syslog('b', "Binkp: transmitter to WaitLastAck");
} }
break; break;
@ -1311,7 +1356,7 @@ int binkp_batch(file_list *to_send, int role)
* Check if there is room in the output buffer * Check if there is room in the output buffer
*/ */
if ((WAITPUTGET(-1) & 2) != 0) if ((WAITPUTGET(-1) & 2) != 0)
TxState = TxReadSend; bp.TxState = TxReadSend;
break; break;
case TxReadSend: case TxReadSend:
@ -1322,7 +1367,7 @@ int binkp_batch(file_list *to_send, int role)
if (ferror(txfp)) { if (ferror(txfp)) {
WriteError("$Binkp: error reading from file"); WriteError("$Binkp: error reading from file");
TxState = TxGetNextFile; bp.TxState = TxGetNextFile;
cursend->state = Skipped; cursend->state = Skipped;
debug_binkp_list(&bll); debug_binkp_list(&bll);
break; break;
@ -1351,7 +1396,7 @@ int binkp_batch(file_list *to_send, int role)
} }
cursend->state = IsSent; cursend->state = IsSent;
TxState = TxGetNextFile; bp.TxState = TxGetNextFile;
break; break;
} else { } else {
txpos += txlen; txpos += txlen;
@ -1359,7 +1404,7 @@ int binkp_batch(file_list *to_send, int role)
binkp_send_data(txbuf, txlen); binkp_send_data(txbuf, txlen);
} }
TxState = TxTryRead; bp.TxState = TxTryRead;
break; break;
case TxWaitLastAck: case TxWaitLastAck:
@ -1371,7 +1416,7 @@ int binkp_batch(file_list *to_send, int role)
break; break;
} }
if (tmp == NULL) { if (tmp == NULL) {
TxState = TxDone; bp.TxState = TxDone;
binkp_send_control(MM_EOB, ""); binkp_send_control(MM_EOB, "");
Syslog('b', "Binkp: sending EOB"); Syslog('b', "Binkp: sending EOB");
} }
@ -1388,14 +1433,14 @@ int binkp_batch(file_list *to_send, int role)
if (cmd) { if (cmd) {
switch (rxbuf[0]) { switch (rxbuf[0]) {
case MM_ERR: Syslog('+', "Binkp: got ERR: %s", rxbuf+1); case MM_ERR: Syslog('+', "Binkp: got ERR: %s", rxbuf+1);
RxState = RxDone; bp.RxState = RxDone;
TxState = TxDone; bp.TxState = TxDone;
rc = MBERR_FTRANSFER; rc = MBERR_FTRANSFER;
break; break;
case MM_BSY: Syslog('+', "Binkp: got BSY: %s", rxbuf+1); case MM_BSY: Syslog('+', "Binkp: got BSY: %s", rxbuf+1);
RxState = RxDone; bp.RxState = RxDone;
TxState = TxDone; bp.TxState = TxDone;
rc = MBERR_FTRANSFER; rc = MBERR_FTRANSFER;
break; break;
@ -1403,22 +1448,23 @@ int binkp_batch(file_list *to_send, int role)
break; break;
case MM_GET: Syslog('+', "Binkp: got GET: %s", rxbuf+1); case MM_GET: Syslog('+', "Binkp: got GET: %s", rxbuf+1);
sscanf(rxbuf+1, "%s %ld %ld %ld", gname, &gsize, &gtime, &goffset); sscanf(rxbuf+1, "%s %ld %ld %ld", bp.gname, &bp.gsize, &bp.gtime, &bp.goffset);
for (tmpg = bll; tmpg; tmpg = tmpg->next) { for (tmpg = bll; tmpg; tmpg = tmpg->next) {
if (strcasecmp(tmpg->remote, gname) == 0) { if (strcasecmp(tmpg->remote, bp.gname) == 0) {
tmpg->state = NoState; tmpg->state = NoState;
tmpg->offset = goffset; tmpg->offset = bp.goffset;
Syslog('+', "Remote wants %s again, offset %ld", gname, goffset); Syslog('+', "Remote wants %s again, offset %ld", bp.gname, bp.goffset);
TxState = TxGetNextFile; bp.TxState = TxGetNextFile;
} }
} }
break; break;
case MM_GOT: Syslog('+', "Binkp: got GOT: %s", rxbuf+1); case MM_GOT: Syslog('+', "Binkp: got GOT: %s", rxbuf+1);
sscanf(rxbuf+1, "%s %ld %ld", lname, &lsize, &ltime); sscanf(rxbuf+1, "%s %ld %ld", bp.lname, &bp.lsize, &bp.ltime);
Found = FALSE; Found = FALSE;
for (tmp = bll; tmp; tmp = tmp->next) for (tmp = bll; tmp; tmp = tmp->next)
if ((strcmp(lname, tmp->remote) == 0) && (lsize == tmp->size) && (ltime == tmp->date)) { if ((strcmp(bp.lname, tmp->remote) == 0) && (bp.lsize == tmp->size) &&
(bp.ltime == tmp->date)) {
Syslog('+', "Binkp: remote GOT \"%s\"", tmp->remote); Syslog('+', "Binkp: remote GOT \"%s\"", tmp->remote);
tmp->state = Got; tmp->state = Got;
Found = TRUE; Found = TRUE;
@ -1432,21 +1478,21 @@ int binkp_batch(file_list *to_send, int role)
break; break;
case MM_EOB: Syslog('+', "Binkp: got EOB"); case MM_EOB: Syslog('+', "Binkp: got EOB");
RxState = RxEndOfBatch; bp.RxState = RxEndOfBatch;
break; break;
case MM_FILE: Syslog('b', "Binkp: got FILE: %s", rxbuf+1); case MM_FILE: Syslog('b', "Binkp: got FILE: %s", rxbuf+1);
if ((RxState == RxWaitFile) || (RxState == RxEndOfBatch)) { if ((bp.RxState == RxWaitFile) || (bp.RxState == RxEndOfBatch)) {
RxState = RxAcceptFile; bp.RxState = RxAcceptFile;
if (strlen(rxbuf) < 512) { if (strlen(rxbuf) < 512) {
/* /*
* Check against buffer overflow * Check against buffer overflow
*/ */
rcrc = 0; bp.rcrc = 0;
if (CRCflag == Active) { if (bp.CRCflag == Active) {
sscanf(rxbuf+1, "%s %ld %ld %ld %lx", rname, &rsize, &rtime, &roffs, &rcrc); sscanf(rxbuf+1, "%s %ld %ld %ld %lx", bp.rname, &bp.rsize, &bp.rtime, &bp.roffs, &bp.rcrc);
} else { } else {
sscanf(rxbuf+1, "%s %ld %ld %ld", rname, &rsize, &rtime, &roffs); sscanf(rxbuf+1, "%s %ld %ld %ld", bp.rname, &bp.rsize, &bp.rtime, &bp.roffs);
} }
} else { } else {
Syslog('+', "Binkp: got corrupted FILE frame, size %d bytes", strlen(rxbuf)); Syslog('+', "Binkp: got corrupted FILE frame, size %d bytes", strlen(rxbuf));
@ -1460,31 +1506,31 @@ int binkp_batch(file_list *to_send, int role)
} }
} else { } else {
if (blklen) { if (blklen) {
if (RxState == RxReceData) { if (bp.RxState == RxReceData) {
written = fwrite(rxbuf, 1, blklen, rxfp); written = fwrite(rxbuf, 1, blklen, rxfp);
if (CRCflag == Active) if (bp.CRCflag == Active)
rxcrc = upd_crc32(rxbuf, rxcrc, blklen); rxcrc = upd_crc32(rxbuf, rxcrc, blklen);
if (!written && blklen) { if (!written && blklen) {
Syslog('+', "Binkp: file write error"); Syslog('+', "Binkp: file write error");
RxState = RxDone; bp.RxState = RxDone;
} }
rxpos += written; rxpos += written;
if (rxpos == rsize) { if (rxpos == bp.rsize) {
RxState = RxWaitFile; bp.RxState = RxWaitFile;
if ((CRCflag == Active) && rcrc) { if ((bp.CRCflag == Active) && bp.rcrc) {
rxcrc = rxcrc ^ 0xffffffff; rxcrc = rxcrc ^ 0xffffffff;
if (rcrc == rxcrc) { if (bp.rcrc == rxcrc) {
binkp_send_control(MM_GOT, "%s %ld %ld %lx", rname, rsize, rtime, rcrc); binkp_send_control(MM_GOT, "%s %ld %ld %lx", bp.rname, bp.rsize, bp.rtime, bp.rcrc);
closefile(); closefile();
} else { } else {
rxerror = TRUE; rxerror = TRUE;
crc_errors++; crc_errors++;
binkp_send_control(MM_SKIP, "%s %ld %ld %lx", rname, rsize, rtime, rcrc); binkp_send_control(MM_SKIP, "%s %ld %ld %lx", bp.rname, bp.rsize, bp.rtime, bp.rcrc);
Syslog('+', "Binkp: file CRC error nr %d, sending SKIP frame", crc_errors); Syslog('+', "Binkp: file CRC error nr %d, sending SKIP frame", crc_errors);
if (crc_errors >= 3) { if (crc_errors >= 3) {
WriteError("Binkp: file CRC error nr %d, aborting session", crc_errors); WriteError("Binkp: file CRC error nr %d, aborting session", crc_errors);
binkp_send_control(MM_ERR, "Too much CRC errors, aborting session"); binkp_send_control(MM_ERR, "Too much CRC errors, aborting session");
RxState = RxDone; bp.RxState = RxDone;
rc = MBERR_FTRANSFER; rc = MBERR_FTRANSFER;
} }
closefile(); closefile();
@ -1493,14 +1539,14 @@ int binkp_batch(file_list *to_send, int role)
/* /*
* ACK without CRC check * ACK without CRC check
*/ */
binkp_send_control(MM_GOT, "%s %ld %ld", rname, rsize, rtime); binkp_send_control(MM_GOT, "%s %ld %ld", bp.rname, bp.rsize, bp.rtime);
closefile(); closefile();
} }
rxpos = rxpos - rxbytes; rxpos = rxpos - rxbytes;
gettimeofday(&rxtvend, &tz); gettimeofday(&rxtvend, &tz);
Syslog('+', "Binkp: %s %s", rxerror?"ERROR":"OK", transfertime(rxtvstart, rxtvend, rxpos, FALSE)); Syslog('+', "Binkp: %s %s", rxerror?"ERROR":"OK", transfertime(rxtvstart, rxtvend, rxpos, FALSE));
rcvdbytes += rxpos; rcvdbytes += rxpos;
RxState = RxWaitFile; bp.RxState = RxWaitFile;
transferred = TRUE; transferred = TRUE;
} }
} else { } else {
@ -1517,19 +1563,19 @@ int binkp_batch(file_list *to_send, int role)
/* /*
* Receiver state machine * Receiver state machine
*/ */
switch (RxState) { switch (bp.RxState) {
case RxWaitFile: case RxWaitFile:
break; break;
case RxAcceptFile: case RxAcceptFile:
if (CRCflag == Active) if (bp.CRCflag == Active)
Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld crc %lx", Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld crc %lx",
rname, date(rtime), rsize, roffs, rcrc); bp.rname, date(bp.rtime), bp.rsize, bp.roffs, bp.rcrc);
else else
Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld", Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld",
rname, date(rtime), rsize, roffs); bp.rname, date(bp.rtime), bp.rsize, bp.roffs);
(void)binkp2unix(rname); (void)binkp2unix(bp.rname);
rxfp = openfile(binkp2unix(rname), rtime, rsize, &rxbytes, resync); rxfp = openfile(binkp2unix(bp.rname), bp.rtime, bp.rsize, &rxbytes, resync);
gettimeofday(&rxtvstart, &tz); gettimeofday(&rxtvstart, &tz);
rxpos = 0; rxpos = 0;
rxcrc = 0xffffffff; rxcrc = 0xffffffff;
@ -1538,37 +1584,37 @@ int binkp_batch(file_list *to_send, int role)
if (!diskfree(CFG.freespace)) { if (!diskfree(CFG.freespace)) {
Syslog('+', "Binkp: low diskspace, sending BSY"); Syslog('+', "Binkp: low diskspace, sending BSY");
binkp_send_control(MM_BSY, "Low diskspace, try again later"); binkp_send_control(MM_BSY, "Low diskspace, try again later");
RxState = RxDone; bp.RxState = RxDone;
TxState = TxDone; bp.TxState = TxDone;
rc = MBERR_FTRANSFER; rc = MBERR_FTRANSFER;
break; break;
} }
if (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
* be deleted at the remote. * be deleted at the remote.
*/ */
Syslog('+', "Binkp: already got %s, sending GOT", rname); Syslog('+', "Binkp: already got %s, sending GOT", bp.rname);
if ((CRCflag == Active) && rcrc) if ((bp.CRCflag == Active) && bp.rcrc)
binkp_send_control(MM_GOT, "%s %ld %ld %lx", rname, rsize, rtime, rcrc); binkp_send_control(MM_GOT, "%s %ld %ld %lx", bp.rname, bp.rsize, bp.rtime, bp.rcrc);
else else
binkp_send_control(MM_GOT, "%s %ld %ld", rname, rsize, rtime); binkp_send_control(MM_GOT, "%s %ld %ld", bp.rname, bp.rsize, bp.rtime);
RxState = RxWaitFile; bp.RxState = RxWaitFile;
rxfp = NULL; rxfp = NULL;
} else if (!rxfp) { } else if (!rxfp) {
/* /*
* Some error, request to skip it * Some error, request to skip it
*/ */
Syslog('+', "Binkp: error file %s, sending SKIP", rname); Syslog('+', "Binkp: error file %s, sending SKIP", bp.rname);
if ((CRCflag == Active) && rcrc) if ((bp.CRCflag == Active) && bp.rcrc)
binkp_send_control(MM_SKIP, "%s %ld %ld %lx", rname, rsize, rtime, rcrc); binkp_send_control(MM_SKIP, "%s %ld %ld %lx", bp.rname, bp.rsize, bp.rtime, bp.rcrc);
else else
binkp_send_control(MM_SKIP, "%s %ld %ld", rname, rsize, rtime); binkp_send_control(MM_SKIP, "%s %ld %ld", bp.rname, bp.rsize, bp.rtime);
RxState = RxWaitFile; bp.RxState = RxWaitFile;
} else { } else {
Syslog('b', "rsize=%d, rxbytes=%d, roffs=%d", rsize, rxbytes, roffs); Syslog('b', "rsize=%d, rxbytes=%d, roffs=%d", bp.rsize, rxbytes, bp.roffs);
RxState = RxReceData; bp.RxState = RxReceData;
} }
break; break;
@ -1576,8 +1622,8 @@ int binkp_batch(file_list *to_send, int role)
break; break;
case RxEndOfBatch: case RxEndOfBatch:
if (TxState == TxDone) if (bp.TxState == TxDone)
RxState = RxDone; bp.RxState = RxDone;
break; break;
case RxDone: case RxDone:
@ -1613,9 +1659,6 @@ int binkp_batch(file_list *to_send, int role)
free(txbuf); free(txbuf);
free(rxbuf); free(rxbuf);
free(rname);
free(lname);
free(gname);
/* /*
* If there was an error, try to close a possible incomplete file in * If there was an error, try to close a possible incomplete file in