Binkp receiver supports CRC
This commit is contained in:
parent
2af1d25bdf
commit
c01b504c27
@ -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
|
||||
|
113
mbcico/binkp.c
113
mbcico/binkp.c
@ -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, <ime);
|
||||
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);
|
||||
|
Reference in New Issue
Block a user