Implement binkp/1.1 and Turn on FREQ at binkp.

master
Sergey Babitch 17 years ago
parent a148609494
commit fd35c10c4e

@ -49,4 +49,6 @@
+ Changed version for compliance with *BSD ports + Changed version for compliance with *BSD ports
+ Added possibility to run external program for each override and + Added possibility to run external program for each override and
hidden. See bforce.subst.sample for examples and hidden. See bforce.subst.sample for examples and
docs/readme.txt for details docs/readme.txt for details.
+ Implement binkp/1.1 (Multiple Batch Mode and Non-reliable Mode).
+ Turn on FREQ at binkp sessions.

@ -12,6 +12,9 @@
# #
# To use BinkP protocol, write: # To use BinkP protocol, write:
# Override 1:2/3 Ipaddr f3.n2.z1.fidonet.net Flags CM,BINKP # Override 1:2/3 Ipaddr f3.n2.z1.fidonet.net Flags CM,BINKP
# Override 1:2/4 Ipaddr f4.n2.z1.fidonet.net Flags CM,BINKP,NR
#
# NR - for binkp NR mode request (Not Reliable Links).
# #
# If you want never call to certain node, write: # If you want never call to certain node, write:
# Override 1:2/3 Phone Unpublished # Override 1:2/3 Phone Unpublished

@ -83,6 +83,9 @@ void binkp_process_NUL(s_binkp_sysinfo *remote_data, char *buffer)
&remote_data->majorver, &remote_data->majorver,
&remote_data->minorver); &remote_data->minorver);
} }
if ((remote_data->majorver * 100 +
remote_data->minorver)> 100)
remote_data->options |= BINKP_OPT_MB;
} }
else else
strnxcpy(remote_data->progname, buffer+4, sizeof(remote_data->progname)); strnxcpy(remote_data->progname, buffer+4, sizeof(remote_data->progname));
@ -210,12 +213,9 @@ int binkp_outgoing(s_binkp_sysinfo *local_data, s_binkp_sysinfo *remote_data)
break; break;
case BPMSG_NUL: case BPMSG_NUL:
if( binkp_state == BPO_WaitNUL || binkp_state == BPO_WaitADR ) binkp_process_NUL(remote_data, bpi.ibuf+1);
{ if( binkp_state == BPO_WaitNUL )
binkp_process_NUL(remote_data, bpi.ibuf+1); binkp_state = BPO_SendPWD;
if( binkp_state == BPO_WaitNUL )
binkp_state = BPO_SendPWD;
}
break; break;
case BPMSG_ADR: case BPMSG_ADR:
@ -347,14 +347,28 @@ int binkp_incoming(s_binkp_sysinfo *local_data, s_binkp_sysinfo *remote_data)
break; break;
case BPMSG_NUL: case BPMSG_NUL:
if( binkp_state == BPI_WaitADR ) binkp_process_NUL(remote_data, bpi.ibuf+1);
binkp_process_NUL(remote_data, bpi.ibuf+1);
break; break;
case BPMSG_ADR: case BPMSG_ADR:
if( binkp_state == BPI_WaitADR ) if( binkp_state == BPI_WaitADR )
{ {
int i;
char *szOpt = xstrcpy (" MB");
s_override ovr;
binkp_process_ADR(remote_data, bpi.ibuf+1); binkp_process_ADR(remote_data, bpi.ibuf+1);
for(i = 0; i < remote_data->anum; i++)
{
ovr.sFlags = "";
override_get (&ovr, remote_data->addrs[i].addr, 0);
if (!nodelist_checkflag (ovr.sFlags, "NR"))
{
szOpt = xstrcat (szOpt, " NR");
break;
}
}
binkp_queuemsg(&bpi,BPMSG_NUL,"OPT",szOpt);
free (szOpt);
binkp_state = BPI_WaitPWD; binkp_state = BPI_WaitPWD;
} }
break; break;
@ -387,17 +401,13 @@ Abort:
return rc; return rc;
} }
int binkp_transfer(s_protinfo *pi) int binkp_transfer(s_protinfo *pi) {
{
int i, n, rc = PRC_NOERROR; int i, n, rc = PRC_NOERROR;
bool recv_ready = FALSE; bool recv_ready = FALSE;
bool send_ready = FALSE; bool send_ready = FALSE;
bool sent_EOB = FALSE;
bool rcvd_EOB = FALSE; bool rcvd_EOB = FALSE;
bool send_file = FALSE;
bool recv_file = FALSE; bool recv_file = FALSE;
bool wait_got = FALSE;
bool nofiles = FALSE;
int recv_rc = 0; int recv_rc = 0;
int send_rc = 0; int send_rc = 0;
char *fname = NULL; char *fname = NULL;
@ -405,52 +415,71 @@ int binkp_transfer(s_protinfo *pi)
time_t ftime = 0; time_t ftime = 0;
size_t foffs = 0; size_t foffs = 0;
s_bpinfo bpi; s_bpinfo bpi;
s_binkp_sysinfo *remote;
binkp_init_bpinfo(&bpi); enum {
BPT_Start_Send_File,
while( !sent_EOB || !rcvd_EOB ) BPT_Wait_M_GET,
{ BPT_Send_File,
if( !send_file && !sent_EOB && bpi.opos == 0 && bpi.n_msgs == 0 ) BPT_Wait_M_GOT,
{ BPT_No_Files,
if( !p_tx_fopen(pi) ) BPT_EOB
{ } binkp_send_state = BPT_Start_Send_File;
send_file = TRUE; remote = (s_binkp_sysinfo *) state.handshake->remote_data;
binkp_queuemsgf(&bpi, BPMSG_FILE, "%s %ld %ld 0", binkp_init_bpinfo(&bpi);
pi->send->net_name, (long)pi->send->bytes_total, while (1) {
(long)pi->send->mod_time); if (binkp_send_state == BPT_Start_Send_File) {
} if (p_tx_fopen (pi)) {
else binkp_send_state = BPT_No_Files;
/* No more files */ } else {
nofiles = TRUE; char *name = pi->send->net_name;
} long total = (long) pi->send->bytes_total;
long time = (long) pi->send->mod_time;
if( send_file && bpi.opos == 0 && bpi.n_msgs == 0 ) if (remote->options & BINKP_OPT_NR) {
{ binkp_queuemsgf(&bpi,BPMSG_FILE,"%s %ld %ld -1",name,total,time);
if( (n = p_tx_readfile(bpi.obuf + BINKP_BLK_HDRSIZE, binkp_send_state = BPT_Wait_M_GET;
4096, pi)) < 0 ) } else {
{ binkp_queuemsgf(&bpi,BPMSG_FILE,"%s %ld %ld 0", name,total,time);
p_tx_fclose(pi); binkp_send_state = BPT_Send_File;
send_file = FALSE; }
} }
else }
{ if (binkp_send_state == BPT_Send_File) {
binkp_puthdr(bpi.obuf, (unsigned)(n & 0x7fff)); if (bpi.opos == 0 && bpi.n_msgs == 0) {
bpi.opos = n + BINKP_BLK_HDRSIZE; if((n = p_tx_readfile (bpi.obuf+BINKP_BLK_HDRSIZE,4096,pi))<0) {
pi->send->bytes_sent += n; p_tx_fclose (pi);
if( pi->send->eofseen ) binkp_send_state = BPT_Start_Send_File;
{ } else {
wait_got = TRUE; send_file = FALSE; binkp_puthdr (bpi.obuf, (unsigned) (n & 0x7fff));
pi->send->status = FSTAT_WAITACK; bpi.opos = n + BINKP_BLK_HDRSIZE;
} pi->send->bytes_sent += n;
} if (pi->send->eofseen) {
} pi->send->status = FSTAT_WAITACK;
if (remote->options & BINKP_OPT_NR)
if( nofiles && !wait_got && !sent_EOB ) binkp_send_state = BPT_Wait_M_GOT;
{ else binkp_send_state = BPT_Start_Send_File;
sent_EOB = TRUE; }
binkp_queuemsg(&bpi, BPMSG_EOB, NULL, NULL); }
} }
}
if (binkp_send_state == BPT_No_Files) {
for (i = 0; i < pi->n_sentfiles; i++) {
if (pi->sentfiles[i].status == FSTAT_WAITACK) break;
}
if (i == pi->n_sentfiles) {
binkp_queuemsg (&bpi, BPMSG_EOB, NULL, NULL);
binkp_send_state = BPT_EOB;
}
}
/* End of the current batch (start the next batch if need). */
if (binkp_send_state == BPT_EOB && rcvd_EOB) {
if (remote->options & BINKP_OPT_MB && bpi.msgs_in_batch > 2) {
bpi.msgs_in_batch = 0;
binkp_send_state = BPT_Start_Send_File;
rcvd_EOB = FALSE;
continue;
}
break;
}
recv_ready = send_ready = FALSE; recv_ready = send_ready = FALSE;
if( tty_select(&recv_ready, (bpi.opos || bpi.n_msgs) ? if( tty_select(&recv_ready, (bpi.opos || bpi.n_msgs) ?
&send_ready : NULL, bpi.timeout) < 0 ) &send_ready : NULL, bpi.timeout) < 0 )
@ -464,8 +493,8 @@ int binkp_transfer(s_protinfo *pi)
if( send_ready && (send_rc = binkp_send(&bpi)) < 0 ) if( send_ready && (send_rc = binkp_send(&bpi)) < 0 )
gotoexit(PRC_ERROR); gotoexit(PRC_ERROR);
switch(recv_rc) { switch(recv_rc) {
case BPMSG_NONE: case BPMSG_NONE:
break; break;
case BPMSG_DATA: /* Got new data block */ case BPMSG_DATA: /* Got new data block */
if( recv_file ) if( recv_file )
@ -533,26 +562,29 @@ int binkp_transfer(s_protinfo *pi)
break; break;
case BPMSG_FILE: case BPMSG_FILE:
if( recv_file )
{ p_rx_fclose(pi); recv_file = FALSE; }
if( binkp_parsfinfo(bpi.ibuf+1, &fname, if( binkp_parsfinfo(bpi.ibuf+1, &fname,
&fsize, &ftime, &foffs) ) &fsize, &ftime, &foffs) )
{ {
log ("BinkP error: M_FILE: %s", bpi.ibuf + 1);
binkp_queuemsg(&bpi, BPMSG_ERR, "FILE: ", "unparsable arguments"); binkp_queuemsg(&bpi, BPMSG_ERR, "FILE: ", "unparsable arguments");
goto FinishSession; goto FinishSession;
} }
if( pi->recv && !p_compfinfo(pi->recv, fname, fsize, ftime) if( pi->recv && !p_compfinfo(pi->recv, fname, fsize, ftime)
&& pi->recv->bytes_skipped == foffs ) && pi->recv->bytes_skipped == foffs && pi->recv->fp )
{ {
recv_file = TRUE; recv_file = TRUE;
break; break;
} }
if (recv_file) {
p_rx_fclose (pi);
recv_file = FALSE;
}
switch(p_rx_fopen(pi, fname, fsize, ftime, 0)) { switch(p_rx_fopen(pi, fname, fsize, ftime, 0)) {
case 0: case 0:
if( pi->recv->bytes_skipped == 0 ) if (pi->recv->bytes_skipped == foffs)
{ {
recv_file = TRUE; recv_file = TRUE;
break; break;
@ -588,58 +620,43 @@ int binkp_transfer(s_protinfo *pi)
rcvd_EOB = TRUE; rcvd_EOB = TRUE;
break; break;
case BPMSG_GOT: case BPMSG_GOT:
case BPMSG_SKIP: case BPMSG_SKIP:
if( binkp_parsfinfo(bpi.ibuf+1, &fname, &fsize, &ftime, NULL) == 0 ) if (binkp_parsfinfo (bpi.ibuf+1,&fname,&fsize,&ftime,NULL)) {
{ char *m = recv_rc == BPMSG_GOT ? "M_GOT" : "M_SKIP";
if( send_file && !p_compfinfo(pi->send, fname, fsize, ftime) ) binkp_queuemsgf (&bpi, BPMSG_ERR, "%s: %s", m, bpi.ibuf + 1);
{ log ("BinkP error: %s: %s", m, bpi.ibuf + 1);
/* We got GOT/SKIP for current file! */ binkp_send_state = BPT_No_Files;
if( recv_rc == BPMSG_GOT ) rc = PRC_ERROR;
pi->send->status = FSTAT_SKIPPED; break;
else }
pi->send->status = FSTAT_REFUSED; for(i = 0; i < pi->n_sentfiles; i++ ) {
p_tx_fclose(pi); if (!p_compfinfo (&pi->sentfiles[i], fname, fsize, ftime)) {
send_file = FALSE; s_finfo *tmp = pi->send;
break; pi->send = &pi->sentfiles[i];
} if (recv_rc == BPMSG_SKIP) {
pi->send->status = FSTAT_REFUSED;
wait_got = FALSE; } else {
if (pi->send->status == FSTAT_WAITACK) {
for( i = 0; i < pi->n_sentfiles; i++ ) pi->send->status = FSTAT_SUCCESS;
{ } else {
if( pi->sentfiles[i].status == FSTAT_WAITACK pi->send->status = FSTAT_SKIPPED;
&& !p_compfinfo(&pi->sentfiles[i], fname, fsize, ftime) ) }
{ }
s_finfo *tmp = pi->send; p_tx_fclose(pi);
pi->send = tmp;
pi->send = &pi->sentfiles[i]; break;
if( recv_rc == BPMSG_GOT ) }
pi->send->status = FSTAT_SUCCESS; }
else if (!strcmp (pi->send->net_name, fname)) {
pi->send->status = FSTAT_REFUSED; if (binkp_send_state == BPT_Send_File ||
p_tx_fclose(pi); binkp_send_state == BPT_Wait_M_GET ||
binkp_send_state == BPT_Wait_M_GOT) {
pi->send = tmp; binkp_send_state = BPT_Start_Send_File;
break; }
} }
else if( pi->sentfiles[i].status == FSTAT_WAITACK ) break;
wait_got = TRUE;
}
/*
* Check, maybe there are files still
* waiting for the GOT/SKIP acknwoledge
*/
while( i < pi->n_sentfiles && !wait_got )
{
if( pi->sentfiles[i].status == FSTAT_WAITACK )
wait_got = TRUE;
++i;
}
}
break;
case BPMSG_ERR: case BPMSG_ERR:
log("remote report error: \"%s\"", bpi.ibuf+1); log("remote report error: \"%s\"", bpi.ibuf+1);
gotoexit(PRC_ERROR); gotoexit(PRC_ERROR);
@ -653,13 +670,13 @@ int binkp_transfer(s_protinfo *pi)
case BPMSG_GET: case BPMSG_GET:
if( binkp_parsfinfo(bpi.ibuf+1, &fname, &fsize, &ftime, &foffs) == 0 ) if( binkp_parsfinfo(bpi.ibuf+1, &fname, &fsize, &ftime, &foffs) == 0 )
{ {
if( send_file && !p_compfinfo(pi->send, fname, fsize, ftime) ) if(!p_compfinfo(pi->send,fname,fsize,ftime))
{ {
if( fseek(pi->send->fp, foffs, SEEK_SET) == -1 ) if( fseek(pi->send->fp, foffs, SEEK_SET) == -1 )
{ {
log("cannot send file from requested offset %ld", (long)foffs); log("cannot send file from requested offset %ld", (long)foffs);
p_tx_fclose(pi); p_tx_fclose(pi);
send_file = FALSE; binkp_send_state = BPT_Start_Send_File;
} }
else else
{ {
@ -670,6 +687,7 @@ int binkp_transfer(s_protinfo *pi)
binkp_queuemsgf(&bpi, BPMSG_FILE, "%s %ld %ld %ld", binkp_queuemsgf(&bpi, BPMSG_FILE, "%s %ld %ld %ld",
pi->send->net_name, (long)pi->send->bytes_total, pi->send->net_name, (long)pi->send->bytes_total,
(long)pi->send->mod_time, (long)foffs); (long)pi->send->mod_time, (long)foffs);
binkp_send_state = BPT_Send_File;
} }
} }
} }

@ -117,6 +117,7 @@ int binkp_incoming2(s_handshake_protocol *THIS)
{ {
session_remote_lookup(remote_data->addrs, remote_data->anum); session_remote_lookup(remote_data->addrs, remote_data->anum);
session_remote_log_status(); session_remote_log_status();
binkp_log_options(remote_data);
} }
if( rc == HRC_OK ) if( rc == HRC_OK )
@ -128,6 +129,7 @@ int binkp_incoming2(s_handshake_protocol *THIS)
remote_data->anum); remote_data->anum);
session_set_send_options(); session_set_send_options();
session_set_inbound(); session_set_inbound();
session_set_freqs_status();
} }
return rc; return rc;
@ -145,6 +147,8 @@ int binkp_outgoing2(s_handshake_protocol *THIS)
remote_data = (s_binkp_sysinfo *)THIS->remote_data; remote_data = (s_binkp_sysinfo *)THIS->remote_data;
local_data = (s_binkp_sysinfo *)THIS->local_data; local_data = (s_binkp_sysinfo *)THIS->local_data;
session_set_freqs_status();
binkp_set_sysinfo(local_data, &state.node.addr, TRUE); binkp_set_sysinfo(local_data, &state.node.addr, TRUE);
@ -155,6 +159,7 @@ int binkp_outgoing2(s_handshake_protocol *THIS)
{ {
session_remote_lookup(remote_data->addrs, remote_data->anum); session_remote_lookup(remote_data->addrs, remote_data->anum);
session_remote_log_status(); session_remote_log_status();
binkp_log_options(remote_data);
} }
if( rc == HRC_OK ) if( rc == HRC_OK )

@ -177,6 +177,7 @@ void binkp_queuemsg(s_bpinfo *bpi, e_bpmsg msg, const char *s1, const char *s2)
(char*)bpi->msgqueue[bpi->n_msgs].data+3)); (char*)bpi->msgqueue[bpi->n_msgs].data+3));
++bpi->n_msgs; ++bpi->n_msgs;
++bpi->msgs_in_batch;
} }
/***************************************************************************** /*****************************************************************************
@ -220,20 +221,24 @@ void binkp_queuemsgf(s_bpinfo *bpi, e_bpmsg msg, const char *fmt, ...)
* Return value: * Return value:
* non-zero value on error, zero on success * non-zero value on error, zero on success
*/ */
int binkp_parsfinfo(char *s, char **fn, size_t *sz, time_t *tm, size_t *offs) int binkp_parsfinfo(char *str,char **fn,size_t *sz,time_t *tm,size_t *offs){
{
char *n; char *n;
char *p_fname = NULL; char *p_fname = NULL;
char *p_size = NULL; char *p_size = NULL;
char *p_time = NULL; char *p_time = NULL;
char *p_offs = NULL; char *p_offs = NULL;
static char *s = NULL;
/* Attention, offs may be NULL! */ /* Attention, offs may be NULL! */
ASSERT(s != NULL && fn != NULL && sz != NULL && tm != NULL); ASSERT(str != NULL && fn != NULL && sz != NULL && tm != NULL);
DEB((D_PROT, "binkp_parsemsg: want parse \"%s\"", s)); DEB((D_PROT, "binkp_parsemsg: want parse \"%s\"", s));
if (s) free (s);
s = xstrcpy (str);
p_fname = string_token(s, &n, NULL, 0); p_fname = string_token(s, &n, NULL, 0);
p_size = string_token(NULL, &n, NULL, 0); p_size = string_token(NULL, &n, NULL, 0);
p_time = string_token(NULL, &n, NULL, 0); p_time = string_token(NULL, &n, NULL, 0);
@ -241,7 +246,8 @@ int binkp_parsfinfo(char *s, char **fn, size_t *sz, time_t *tm, size_t *offs)
if( p_fname && p_size && p_time && (!offs || p_offs) ) if( p_fname && p_size && p_time && (!offs || p_offs) )
{ {
if( ISDEC(p_size) && ISDEC(p_time) && (!offs || ISDEC(p_offs)) ) if( ISDEC(p_size) && ISDEC(p_time) &&
(!offs || ISDEC(p_offs) || !strcmp (p_offs, "-1")) )
{ {
(*fn) = p_fname; (*fn) = p_fname;
(*sz) = atol(p_size); (*sz) = atol(p_size);
@ -454,6 +460,7 @@ int binkp_recv(s_bpinfo *bpi)
bpi->imsgtype = binkp_getmsgtype(bpi->ibuf[0]); bpi->imsgtype = binkp_getmsgtype(bpi->ibuf[0]);
DEB((D_PROT, "binkp_recv: got message #%d, %ld byte(s), \"%s\"", DEB((D_PROT, "binkp_recv: got message #%d, %ld byte(s), \"%s\"",
(int)bpi->imsgtype, bpi->isize, bpi->ibuf+1)); (int)bpi->imsgtype, bpi->isize, bpi->ibuf+1));
++bpi->msgs_in_batch;
if( bpi->imsgtype < 0 ) if( bpi->imsgtype < 0 )
{ {
bpi->isize = -1; bpi->isize = -1;
@ -528,6 +535,32 @@ void binkp_queue_sysinfo(s_bpinfo *bpi, s_binkp_sysinfo *binkp)
binkp_queuemsg(bpi, BPMSG_ADR, NULL, astr); binkp_queuemsg(bpi, BPMSG_ADR, NULL, astr);
free(astr); free(astr);
} }
if (state.caller)
{
char *szOpt = xstrcpy (" MB");
if (!nodelist_checkflag (state.node.flags, "NR"))
szOpt = xstrcat (szOpt, " NR");
if (!nodelist_checkflag (state.node.flags, "ND"))
szOpt = xstrcat (szOpt, " ND");
if (*szOpt)
binkp_queuemsg(bpi, BPMSG_NUL, "OPT", szOpt);
free (szOpt);
}
}
/*****************************************************************************
* Write options to the log
*
* Arguments:
* binkp structure with the system information
*
* Return value:
* None
*/
void binkp_log_options(s_binkp_sysinfo *remote)
{
if (remote->options & BINKP_OPT_MB) log ("We are in MB mode.");
if (remote->options & BINKP_OPT_NR) log ("We are in NR mode.");
} }
/***************************************************************************** /*****************************************************************************

@ -387,7 +387,16 @@ int p_tx_readfile(char *buffer, size_t buflen, s_protinfo *pi)
{ {
int n; int n;
struct stat st; struct stat st;
long ftell_pos = ftell(pi->send->fp); long ftell_pos;
/*
* Sanity check: read from closed file.
*/
if (pi->send->fp == NULL) {
log ("Error: Read from closed file \"%s\".", pi->send->fname);
return -1;
}
ftell_pos = ftell(pi->send->fp);
pi->send->eofseen = FALSE; /* clear EOF flag */ pi->send->eofseen = FALSE; /* clear EOF flag */

@ -26,7 +26,7 @@
#define BINKP_NAME "binkp" #define BINKP_NAME "binkp"
#define BINKP_MAJOR 1 #define BINKP_MAJOR 1
#define BINKP_MINOR 0 #define BINKP_MINOR 1
#define BINKP_PORT 24554 #define BINKP_PORT 24554
#define BINKP_TIMEOUT (5*60) #define BINKP_TIMEOUT (5*60)
#define BINKP_MIN_BLKSIZE 128 #define BINKP_MIN_BLKSIZE 128
@ -124,6 +124,7 @@ typedef struct {
int junkcount; int junkcount;
s_bpmsg *msgqueue; /* Outgoing messages queue */ s_bpmsg *msgqueue; /* Outgoing messages queue */
int n_msgs; /* Number of messages in queue */ int n_msgs; /* Number of messages in queue */
int msgs_in_batch; /* Number of messages in batch */
int timeout; int timeout;
} s_bpinfo; } s_bpinfo;
@ -149,6 +150,7 @@ int binkp_send(s_bpinfo *bpi);
int binkp_flush_queue(s_bpinfo *bpi, int timeout); int binkp_flush_queue(s_bpinfo *bpi, int timeout);
int binkp_recv(s_bpinfo *bpi); int binkp_recv(s_bpinfo *bpi);
void binkp_update_sysinfo(s_binkp_sysinfo *binkp); void binkp_update_sysinfo(s_binkp_sysinfo *binkp);
void binkp_log_options(s_binkp_sysinfo *remote);
void binkp_log_sysinfo(s_binkp_sysinfo *binkp); void binkp_log_sysinfo(s_binkp_sysinfo *binkp);
void binkp_queue_sysinfo(s_bpinfo *bpi, s_binkp_sysinfo *binkp); void binkp_queue_sysinfo(s_bpinfo *bpi, s_binkp_sysinfo *binkp);
void binkp_set_sysinfo(s_binkp_sysinfo *binkp, s_faddr *remote_addr, bool caller); void binkp_set_sysinfo(s_binkp_sysinfo *binkp, s_faddr *remote_addr, bool caller);

Loading…
Cancel
Save