Binkp receiver supports CRC

This commit is contained in:
Michiel Broek 2002-06-16 16:44:38 +00:00
parent 2af1d25bdf
commit c01b504c27
2 changed files with 814 additions and 761 deletions

View File

@ -4,6 +4,8 @@ $Id$
v0.35.01 05-Jun-2002
DO NOT USE THIS VERSION, IT WON'T WORK !!!!!!
general:
Added structures for netmail routing file.
Expanded nodes structures for FTP and Directory transfers.
@ -23,6 +25,8 @@ v0.35.01 05-Jun-2002
The binkd version string now includes the OS and CPU type.
If a transmitted file via binkp is skipped by the remote it
will stay in the queue for the next session.
The binkp receiver now supports the CRC option.
The binkp transmitter doesn't right now, sessions will fail!!!!!
mbfile:
Added -v commandline switch to supress virus checking for the

View File

@ -87,7 +87,7 @@ static int CRAMflag = FALSE;
static int CRCflag = FALSE;
unsigned long nethold, mailhold;
int transferred = FALSE;
int batchnr = 0;
int batchnr = 0, crc_errors = 0;
@ -371,8 +371,10 @@ void b_nul(char *msg)
CRYPTflag = TRUE;
if (strstr(msg, (char *)"CRAM-") != NULL)
CRAMflag = TRUE;
if (strstr(msg, (char *)"CRC") != NULL)
if (strstr(msg, (char *)"CRC") != NULL) {
CRCflag = TRUE;
Syslog('b', "Switching to CRC32 mode");
}
} else
Syslog('+', "M_NUL \"%s\"", msg);
}
@ -410,8 +412,7 @@ SM_STATE(waitconn)
Loaded = FALSE;
Syslog('+', "Start binkp session with %s", ascfnode(remote->addr, 0x1f));
b_banner(TRUE);
// binkp_send_control(MM_NUL,"OPT NR");
binkp_send_control(MM_NUL,"OPT MB");
binkp_send_control(MM_NUL,"OPT MB CRC");
/*
* Build a list of aka's to send, the primary aka first.
@ -520,10 +521,8 @@ SM_STATE(authremote)
rc = 0;
for (tmpa = remote; tmpa; tmpa = tmpa->next) {
if ((tmpa->addr->zone == ra.zone) &&
(tmpa->addr->net == ra.net) &&
(tmpa->addr->node == ra.node) &&
(tmpa->addr->point == ra.point)) {
if ((tmpa->addr->zone == ra.zone) && (tmpa->addr->net == ra.net) &&
(tmpa->addr->node == ra.node) && (tmpa->addr->point == ra.point)) {
rc = 1;
}
}
@ -654,8 +653,7 @@ SM_STATE(waitaddr)
}
for (tmpa = remote; tmpa; tmpa = tmpa->next) {
if (((nlent = getnlent(tmpa->addr))) &&
(nlent->pflag != NL_DUMMY)) {
if (((nlent = getnlent(tmpa->addr))) && (nlent->pflag != NL_DUMMY)) {
Syslog('+', "Remote is a listed system");
if (inbound)
free(inbound);
@ -670,6 +668,10 @@ SM_STATE(waitaddr)
Syslog('b', "Remote supports MB");
binkp_send_control(MM_NUL,"OPT MB");
}
if (CRCflag) {
Syslog('b', "Remote supports CRC32");
binkp_send_control(MM_NUL,"OPT CRC");
}
history.aka.zone = remote->addr->zone;
history.aka.net = remote->addr->net;
@ -712,6 +714,7 @@ SM_STATE(waitpwd)
}
SM_STATE(pwdack)
if ((strcmp(&rbuf[1], "-") == 0) && !Loaded) {
Syslog('+', "Node not in setup, unprotected BINKP session");
binkp_send_control(MM_OK, "");
@ -791,21 +794,16 @@ void debug_binkp_list(binkp_list **bll)
int binkp_batch(file_list *to_send)
{
int rc = 0, NotDone;
int rc = 0, NotDone, rxlen = 0, txlen = 0, rxerror = FALSE;
static char *txbuf, *rxbuf;
FILE *txfp = NULL;
FILE *rxfp = NULL;
int rxlen = 0, txlen = 0;
long txpos = 0, rxpos = 0;
long stxpos = 0;
int sverr, cmd = FALSE, GotFrame = FALSE;
int blklen = 0, c, Found = FALSE;
FILE *txfp = NULL, *rxfp = NULL;
long txpos = 0, rxpos = 0, stxpos = 0, written, rsize, roffs, lsize, gsize, goffset;
int sverr, cmd = FALSE, GotFrame = FALSE, blklen = 0, c, Found = FALSE;
unsigned short header = 0;
char *rname, *lname, *gname, *rcrc;
long rsize, roffs, lsize, gsize, goffset;
char *rname, *lname, *gname;
time_t rtime, ltime, gtime;
unsigned long rcrc = 0, tcrc = 0, rxcrc = 0;
off_t rxbytes;
long written;
binkp_list *bll = NULL, *tmp, *tmpg, *cursend = NULL;
file_list *tsl;
struct timeval rxtvstart, rxtvend;
@ -823,7 +821,6 @@ int binkp_batch(file_list *to_send)
txbuf = calloc(MAX_BLKSIZE + 3, sizeof(unsigned char));
rxbuf = calloc(MAX_BLKSIZE + 3, sizeof(unsigned char));
rname = calloc(512, sizeof(char));
rcrc = calloc(512, sizeof(char));
lname = calloc(512, sizeof(char));
gname = calloc(512, sizeof(char));
TfState = Switch;
@ -919,6 +916,12 @@ int binkp_batch(file_list *to_send)
txflock.l_start = 0L;
txflock.l_len = 0L;
if (CRCflag)
tcrc = file_crc(tmp->local, FALSE);
else
tcrc = 0;
Syslog('b', "File CRC is %lx", tcrc);
txfp = fopen(tmp->local, "r");
if (txfp == NULL) {
sverr = errno;
@ -941,9 +944,15 @@ int binkp_batch(file_list *to_send)
txpos = stxpos = tmp->offset;
Syslog('+', "Binkp: send \"%s\" as \"%s\"", MBSE_SS(tmp->local), MBSE_SS(tmp->remote));
if (CRCflag && tcrc) {
Syslog('+', "Binkp: size %lu bytes, dated %s, crc %lx", (unsigned long)tmp->size, date(tmp->date), tcrc +5);
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;
} else {
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),
(unsigned long)tmp->size, (long)tmp->date, (unsigned long)tmp->offset);
}
gettimeofday(&txtvstart, &tz);
tmp->state = Sending;
cursend = tmp;
@ -1003,8 +1012,7 @@ int binkp_batch(file_list *to_send)
stxpos = txpos - stxpos;
Syslog('+', "Binkp: OK %s", transfertime(txtvstart, txtvend, stxpos, TRUE));
} else {
Syslog('+', "Binkp: transmitter skipped file after %ld seconds",
txtvend.tv_sec - txtvstart.tv_sec);
Syslog('+', "Binkp: transmitter skipped file after %ld seconds", txtvend.tv_sec - txtvstart.tv_sec);
}
cursend->state = IsSent;
@ -1073,8 +1081,7 @@ int binkp_batch(file_list *to_send)
case MM_GOT: sscanf(rxbuf+1, "%s %ld %ld", lname, &lsize, &ltime);
Found = FALSE;
for (tmp = bll; tmp; tmp = tmp->next)
if ((strcmp(lname, tmp->remote) == 0) &&
(lsize == tmp->size) && (ltime == tmp->date)) {
if ((strcmp(lname, tmp->remote) == 0) && (lsize == tmp->size) && (ltime == tmp->date)) {
Syslog('+', "Binkp: remote GOT \"%s\"", tmp->remote);
tmp->state = Got;
Found = TRUE;
@ -1098,10 +1105,13 @@ int binkp_batch(file_list *to_send)
/*
* Check against buffer overflow
*/
if (CRCflag)
sscanf(rxbuf+1, "%s %ld %ld %ld %s", rname, &rsize, &rtime, &roffs, rcrc);
else
rcrc = 0;
if (CRCflag) {
sscanf(rxbuf+1, "%s %ld %ld %ld %lx", rname, &rsize, &rtime, &roffs, &rcrc);
} else {
sscanf(rxbuf+1, "%s %ld %ld %ld", rname, &rsize, &rtime, &roffs);
}
Syslog('b', "Expecting CRC %lx", rcrc);
} else {
Syslog('+', "Got corrupted FILE frame, size %d bytes", strlen(rxbuf));
}
@ -1116,17 +1126,41 @@ int binkp_batch(file_list *to_send)
if (blklen) {
if (RxState == RxReceData) {
written = fwrite(rxbuf, 1, blklen, rxfp);
if (CRCflag)
rxcrc = upd_crc32(rxbuf, rxcrc, blklen);
if (!written && blklen) {
Syslog('+', "Binkp: file write error");
RxState = RxDone;
}
rxpos += written;
if (rxpos == rsize) {
if (CRCflag && rcrc) {
rxcrc = rxcrc ^ 0xffffffff;
Syslog('b', "File received crc %lx, expected %lx", rxcrc, rcrc);
if (rcrc == rxcrc) {
binkp_send_control(MM_GOT, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
} else {
rxerror = TRUE;
crc_errors++;
if (crc_errors < 3) {
binkp_send_control(MM_SKIP, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
WriteError("File CRC error nr %d, sending SKIP frame", crc_errors);
} else {
WriteError("File CRC error nr %d, aborting session", crc_errors);
binkp_send_control(MM_ERR, "Too much CRC errors, aborting session");
RxState = RxDone;
}
}
} else {
/*
* ACK without CRC check
*/
binkp_send_control(MM_GOT, "%s %ld %ld", rname, rsize, rtime);
}
closefile(TRUE);
rxpos = rxpos - rxbytes;
gettimeofday(&rxtvend, &tz);
Syslog('+', "Binkp: OK %s", transfertime(rxtvstart, rxtvend, rxpos, FALSE));
Syslog('+', "Binkp: %s %s", rxerror?"ERROR":"OK", transfertime(rxtvstart, rxtvend, rxpos, FALSE));
rcvdbytes += rxpos;
RxState = RxWaitFile;
transferred = TRUE;
@ -1142,15 +1176,25 @@ int binkp_batch(file_list *to_send)
blklen = 0;
}
/*
* Receiver state machine
*/
switch (RxState) {
case RxWaitFile:
break;
case RxAcceptFile:
Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld", rname, date(rtime), rsize, roffs);
if (CRCflag)
Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld crc %lx",
rname, date(rtime), rsize, roffs, rcrc);
else
Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld",
rname, date(rtime), rsize, roffs);
rxfp = openfile(rname, rtime, rsize, &rxbytes, resync);
gettimeofday(&rxtvstart, &tz);
rxpos = 0;
rxcrc = 0xffffffff;
rxerror = FALSE;
if (!diskfree(CFG.freespace)) {
Syslog('+', "Binkp: low diskspace, sending BSY");
@ -1166,6 +1210,9 @@ int binkp_batch(file_list *to_send)
* be deleted at the remote.
*/
Syslog('+', "Binkp: already got %s, sending GOT", rname);
if (CRCflag &rcrc)
binkp_send_control(MM_GOT, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
else
binkp_send_control(MM_GOT, "%s %ld %ld", rname, rsize, rtime);
RxState = RxWaitFile;
rxfp = NULL;
@ -1174,6 +1221,9 @@ int binkp_batch(file_list *to_send)
* Some error, request to skip it
*/
Syslog('+', "Binkp: error file %s, sending SKIP", rname);
if (CRCflag && rcrc)
binkp_send_control(MM_SKIP, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
else
binkp_send_control(MM_SKIP, "%s %ld %ld", rname, rsize, rtime);
RxState = RxWaitFile;
} else {
@ -1223,7 +1273,6 @@ int binkp_batch(file_list *to_send)
free(txbuf);
free(rxbuf);
free(rname);
free(rcrc);
free(lname);
free(gname);
Syslog('+', "Binkp: batch %d completed rc=%d", batchnr, rc);