Start binkp PLZ option
This commit is contained in:
parent
acab7aa5e8
commit
839e61c60b
165
mbcico/binkp.c
165
mbcico/binkp.c
@ -131,7 +131,8 @@ struct binkprec {
|
|||||||
int Major; /* Major protocol version */
|
int Major; /* Major protocol version */
|
||||||
int Minor; /* Minor protocol version */
|
int Minor; /* Minor protocol version */
|
||||||
unsigned char *MD_Challenge; /* Received challenge data */
|
unsigned char *MD_Challenge; /* Received challenge data */
|
||||||
|
int PLZflag; /* Zlib packet compression */
|
||||||
|
|
||||||
/* Receiver buffer */
|
/* Receiver buffer */
|
||||||
char *rxbuf; /* Receiver buffer */
|
char *rxbuf; /* Receiver buffer */
|
||||||
int GotFrame; /* Frame complete flag */
|
int GotFrame; /* Frame complete flag */
|
||||||
@ -181,7 +182,7 @@ int binkp_send_command(int, ...); /* Send command frame */
|
|||||||
void binkp_settimer(int); /* Set timeout timer */
|
void binkp_settimer(int); /* Set timeout timer */
|
||||||
int binkp_expired(void); /* Timer expired? */
|
int binkp_expired(void); /* Timer expired? */
|
||||||
int binkp_banner(void); /* Send system banner */
|
int binkp_banner(void); /* Send system banner */
|
||||||
int binkp_recv_command(char *, int *, int *); /* Receive command frame */
|
int binkp_recv_command(char *, unsigned long *, int *); /* Receive command frame */
|
||||||
void parse_m_nul(char *); /* Parse M_NUL message */
|
void parse_m_nul(char *); /* Parse M_NUL message */
|
||||||
int binkp_poll_frame(void); /* Poll for a frame */
|
int binkp_poll_frame(void); /* Poll for a frame */
|
||||||
void binkp_add_message(char *frame); /* Add cmd frame to queue */
|
void binkp_add_message(char *frame); /* Add cmd frame to queue */
|
||||||
@ -230,6 +231,11 @@ int binkp(int role)
|
|||||||
bp.local_EOB = FALSE;
|
bp.local_EOB = FALSE;
|
||||||
bp.remote_EOB = FALSE;
|
bp.remote_EOB = FALSE;
|
||||||
bp.msgs_on_queue = 0;
|
bp.msgs_on_queue = 0;
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
bp.PLZflag = WeCan;
|
||||||
|
#else
|
||||||
|
bp.PLZflag = No;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (role == 1) {
|
if (role == 1) {
|
||||||
if (orgbinkp()) {
|
if (orgbinkp()) {
|
||||||
@ -304,11 +310,12 @@ SM_NAMES
|
|||||||
(char *)"WaitOk",
|
(char *)"WaitOk",
|
||||||
(char *)"Opts"
|
(char *)"Opts"
|
||||||
SM_EDECL
|
SM_EDECL
|
||||||
faddr *primary;
|
faddr *primary;
|
||||||
char *p, *q, *pwd;
|
char *p, *q, *pwd;
|
||||||
int i, rc = 0, bufl, cmd, dupe, SendPass = FALSE, akas = 0;
|
int i, rc = 0, cmd, dupe, SendPass = FALSE, akas = 0;
|
||||||
fa_list **tmp, *tmpa;
|
unsigned long bufl;
|
||||||
faddr *fa, ra;
|
fa_list **tmp, *tmpa;
|
||||||
|
faddr *fa, ra;
|
||||||
|
|
||||||
SM_START(ConnInit)
|
SM_START(ConnInit)
|
||||||
|
|
||||||
@ -323,10 +330,18 @@ SM_STATE(WaitConn)
|
|||||||
IsDoing("Connect binkp %s", ascfnode(remote->addr, 0xf));
|
IsDoing("Connect binkp %s", ascfnode(remote->addr, 0xf));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build options we want (Add PLZ etc).
|
* Build options we want
|
||||||
*/
|
*/
|
||||||
p = xstrcpy((char *)"OPT");
|
p = xstrcpy((char *)"OPT");
|
||||||
|
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
if (bp.PLZflag == WeCan) {
|
||||||
|
p = xstrcat(p, (char *)" PLZ");
|
||||||
|
bp.PLZflag = WeWant;
|
||||||
|
Syslog('b', "PLZflag WeCan => WeWant");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (strcmp(p, (char *)"OPT"))
|
if (strcmp(p, (char *)"OPT"))
|
||||||
rc = binkp_send_command(MM_NUL, p);
|
rc = binkp_send_command(MM_NUL, p);
|
||||||
free(p);
|
free(p);
|
||||||
@ -576,6 +591,7 @@ SM_RETURN
|
|||||||
|
|
||||||
SM_DECL(ansbinkp, (char *)"ansbinkp")
|
SM_DECL(ansbinkp, (char *)"ansbinkp")
|
||||||
SM_STATES
|
SM_STATES
|
||||||
|
ConnInit,
|
||||||
WaitConn,
|
WaitConn,
|
||||||
WaitAddr,
|
WaitAddr,
|
||||||
IsPasswd,
|
IsPasswd,
|
||||||
@ -583,6 +599,7 @@ SM_STATES
|
|||||||
PwdAck,
|
PwdAck,
|
||||||
Opts
|
Opts
|
||||||
SM_NAMES
|
SM_NAMES
|
||||||
|
(char *)"ConnInit",
|
||||||
(char *)"WaitConn",
|
(char *)"WaitConn",
|
||||||
(char *)"WaitAddr",
|
(char *)"WaitAddr",
|
||||||
(char *)"IsPasswd",
|
(char *)"IsPasswd",
|
||||||
@ -590,12 +607,17 @@ SM_NAMES
|
|||||||
(char *)"PwdAck",
|
(char *)"PwdAck",
|
||||||
(char *)"Opts"
|
(char *)"Opts"
|
||||||
SM_EDECL
|
SM_EDECL
|
||||||
char *p, *q, *pw;
|
char *p, *q, *pw;
|
||||||
int i, rc, bufl, cmd, dupe, we_have_pwd = FALSE, akas = 0;
|
int i, rc, cmd, dupe, we_have_pwd = FALSE, akas = 0;
|
||||||
fa_list **tmp, *tmpa;
|
unsigned long bufl;
|
||||||
faddr *fa;
|
fa_list **tmp, *tmpa;
|
||||||
|
faddr *fa;
|
||||||
|
|
||||||
SM_START(WaitConn)
|
SM_START(ConnInit)
|
||||||
|
|
||||||
|
SM_STATE(ConnInit)
|
||||||
|
|
||||||
|
SM_PROCEED(WaitConn)
|
||||||
|
|
||||||
SM_STATE(WaitConn)
|
SM_STATE(WaitConn)
|
||||||
|
|
||||||
@ -613,7 +635,14 @@ SM_STATE(WaitConn)
|
|||||||
*/
|
*/
|
||||||
char s[MD5_DIGEST_LEN*2+15]; /* max. length of opt string */
|
char s[MD5_DIGEST_LEN*2+15]; /* max. length of opt string */
|
||||||
strcpy(s, "OPT ");
|
strcpy(s, "OPT ");
|
||||||
MD_toString(s+4, bp.MD_Challenge[0], bp.MD_Challenge+1);
|
#ifdef HAVE_ZLIB_H
|
||||||
|
if (bp.PLZflag == WeCan) {
|
||||||
|
strcpy(s + strlen(s), "PLZ ");
|
||||||
|
bp.PLZflag = WeWant;
|
||||||
|
Syslog('b', "PLZflag WeCan => WeWant");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
MD_toString(s + strlen(s), bp.MD_Challenge[0], bp.MD_Challenge+1);
|
||||||
bp.CRAMflag = TRUE;
|
bp.CRAMflag = TRUE;
|
||||||
if ((rc = binkp_send_command(MM_NUL, "%s", s))) {
|
if ((rc = binkp_send_command(MM_NUL, "%s", s))) {
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
@ -1639,9 +1668,13 @@ int binkp_banner(void)
|
|||||||
/*
|
/*
|
||||||
* Receive command frame
|
* Receive command frame
|
||||||
*/
|
*/
|
||||||
int binkp_recv_command(char *buf, int *len, int *cmd)
|
int binkp_recv_command(char *buf, unsigned long *len, int *cmd)
|
||||||
{
|
{
|
||||||
int b0, b1;
|
int b0, b1;
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
int rc, zlen, plz = FALSE;
|
||||||
|
char *zbuf;
|
||||||
|
#endif
|
||||||
|
|
||||||
*len = *cmd = 0;
|
*len = *cmd = 0;
|
||||||
|
|
||||||
@ -1651,15 +1684,52 @@ int binkp_recv_command(char *buf, int *len, int *cmd)
|
|||||||
if (b0 & 0x80)
|
if (b0 & 0x80)
|
||||||
*cmd = 1;
|
*cmd = 1;
|
||||||
|
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
/*
|
||||||
|
* During session setup even if we are not yet in PLZ mode,
|
||||||
|
* we already accept zlib compressed packets. This assumes
|
||||||
|
* that there are no command messages longer then 16Kb.
|
||||||
|
*/
|
||||||
|
if ((b0 & 0x40) && (bp.PLZflag != No)) {
|
||||||
|
Syslog('b', "Binkp: binkp_recv_command() compressed block");
|
||||||
|
plz = TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
b1 = GETCHAR(BINKP_TIMEOUT / 2);
|
b1 = GETCHAR(BINKP_TIMEOUT / 2);
|
||||||
if (tty_status)
|
if (tty_status)
|
||||||
goto to;
|
goto to;
|
||||||
|
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
if (plz) {
|
||||||
|
*len = (b0 & 0x3f) << 8;
|
||||||
|
|
||||||
|
zbuf = calloc(*len +1, sizeof(char));
|
||||||
|
GET(zbuf, *len, BINKP_TIMEOUT / 2);
|
||||||
|
zlen = *len;
|
||||||
|
rc = uncompress(buf, len, zbuf, zlen);
|
||||||
|
free(zbuf);
|
||||||
|
|
||||||
|
if (rc == Z_OK) {
|
||||||
|
Syslog('b', "Binkp: uncompress size %d => %d", zlen, len);
|
||||||
|
} else {
|
||||||
|
Syslog('b', "Binkp: uncompress error %d", rc);
|
||||||
|
tty_status = STAT_UNCOMP;
|
||||||
|
}
|
||||||
|
buf[*len] = '\0';
|
||||||
|
} else {
|
||||||
|
*len = (b0 & 0x7f) << 8;
|
||||||
|
*len += b1;
|
||||||
|
GET(buf, *len, BINKP_TIMEOUT / 2);
|
||||||
|
buf[*len] = '\0';
|
||||||
|
}
|
||||||
|
#else
|
||||||
*len = (b0 & 0x7f) << 8;
|
*len = (b0 & 0x7f) << 8;
|
||||||
*len += b1;
|
*len += b1;
|
||||||
|
|
||||||
GET(buf, *len, BINKP_TIMEOUT / 2);
|
GET(buf, *len, BINKP_TIMEOUT / 2);
|
||||||
buf[*len] = '\0';
|
buf[*len] = '\0';
|
||||||
|
#endif
|
||||||
if (tty_status)
|
if (tty_status)
|
||||||
goto to;
|
goto to;
|
||||||
|
|
||||||
@ -1713,15 +1783,39 @@ void parse_m_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 *)"CRAM-MD5-") != NULL) { /* No SHA-1 support */
|
p = msg;
|
||||||
if (CFG.NoMD5) {
|
q = strtok(p, " \n\r\0");
|
||||||
Syslog('+', "Binkp: Remote supports MD5, but it's turned off here");
|
while ((q = strtok(NULL, " \r\n\0"))) {
|
||||||
|
Syslog('b', "Binkp: parsing opt \"%s\"", printable(q, 0));
|
||||||
|
if (strncmp(q, (char *)"CRAM-MD5-", 9) == 0) { /* No SHA-1 support */
|
||||||
|
if (CFG.NoMD5) {
|
||||||
|
Syslog('+', "Binkp: Remote supports MD5, but it's turned off here");
|
||||||
|
} else {
|
||||||
|
if (bp.MD_Challenge)
|
||||||
|
free(bp.MD_Challenge);
|
||||||
|
bp.MD_Challenge = MD_getChallenge(q, NULL);
|
||||||
|
}
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
} else if (strncmp(q, (char *)"PLZ", 3) == 0) {
|
||||||
|
Syslog('b', "Binkp: got PLZ, current state %s", opstate[bp.PLZflag]);
|
||||||
|
if (bp.PLZflag == WeCan) {
|
||||||
|
bp.PLZflag = TheyWant;
|
||||||
|
Syslog('b', "PLZflag WeCan => TheyWant");
|
||||||
|
binkp_send_command(MM_NUL,"OPT PLZ");
|
||||||
|
Syslog('b', "PLZflag TheyWant => Active");
|
||||||
|
bp.PLZflag = Active;
|
||||||
|
} else if (bp.PLZflag == WeWant) {
|
||||||
|
bp.PLZflag = Active;
|
||||||
|
Syslog('b', "PLZflag WeWant => Active");
|
||||||
|
} else {
|
||||||
|
Syslog('b', "PLZflag is %s and received PLZ option", opstate[bp.PLZflag]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (bp.MD_Challenge)
|
Syslog('b', "Binkp: opt not supported");
|
||||||
free(bp.MD_Challenge);
|
|
||||||
bp.MD_Challenge = MD_getChallenge(msg, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Syslog('+', "Binkp: M_NUL \"%s\"", msg);
|
Syslog('+', "Binkp: M_NUL \"%s\"", msg);
|
||||||
}
|
}
|
||||||
@ -1739,6 +1833,11 @@ void parse_m_nul(char *msg)
|
|||||||
int binkp_poll_frame(void)
|
int binkp_poll_frame(void)
|
||||||
{
|
{
|
||||||
int c, rc = 0, bcmd;
|
int c, rc = 0, bcmd;
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
int plz = FALSE;
|
||||||
|
unsigned long zlen;
|
||||||
|
char *zbuf;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (bp.GotFrame) {
|
if (bp.GotFrame) {
|
||||||
@ -1769,11 +1868,31 @@ int binkp_poll_frame(void)
|
|||||||
default:bp.rxbuf[bp.rxlen-2] = c;
|
default:bp.rxbuf[bp.rxlen-2] = c;
|
||||||
}
|
}
|
||||||
if (bp.rxlen == 1) {
|
if (bp.rxlen == 1) {
|
||||||
bp.cmd = bp.header & 0x8000;
|
bp.cmd = bp.header & BINKP_CONTROL_BLOCK;
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
if (bp.PLZflag == Active) {
|
||||||
|
bp.blklen = bp.header & 0x3fff;
|
||||||
|
plz = bp.header & BINKP_PLZ_BLOCK;
|
||||||
|
} else {
|
||||||
|
bp.blklen = bp.header & 0x7fff;
|
||||||
|
}
|
||||||
|
#else
|
||||||
bp.blklen = bp.header & 0x7fff;
|
bp.blklen = bp.header & 0x7fff;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if ((bp.rxlen == (bp.blklen + 1) && (bp.rxlen >= 1))) {
|
if ((bp.rxlen == (bp.blklen + 1) && (bp.rxlen >= 1))) {
|
||||||
bp.GotFrame = TRUE;
|
bp.GotFrame = TRUE;
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
if (plz) {
|
||||||
|
Syslog('b', "Binkp: rcvd compressed block %d bytes", bp.rxlen -1);
|
||||||
|
zbuf = calloc(bp.rxlen, sizeof(char));
|
||||||
|
strncpy(zbuf, bp.rxbuf, bp.rxlen -1);
|
||||||
|
rc = uncompress(bp.rxbuf, &zlen, zbuf, bp.rxlen -1);
|
||||||
|
free(zbuf);
|
||||||
|
Syslog('b', "Binkp: uncompress rc=%d %d => %d", rc, bp.rxlen -1, zlen);
|
||||||
|
bp.rxlen = zlen +1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
bp.rxbuf[bp.rxlen-1] = '\0';
|
bp.rxbuf[bp.rxlen-1] = '\0';
|
||||||
if (bp.cmd) {
|
if (bp.cmd) {
|
||||||
bp.messages++;
|
bp.messages++;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef _BINKPNEW_H
|
#ifndef _BINKP_H
|
||||||
#define _BINKPNEW_H
|
#define _BINKP_H
|
||||||
|
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
@ -9,13 +9,24 @@
|
|||||||
binkp's frames:
|
binkp's frames:
|
||||||
|
|
||||||
+---------------------- 0=data block, 1=message(command)
|
+---------------------- 0=data block, 1=message(command)
|
||||||
| +---- data block size / msg's argument size
|
| +----- data block size / msg's argument size
|
||||||
| |
|
| |
|
||||||
7 6543210 76543210
|
7 6543210 76543210
|
||||||
+-+-------+--------+--- ... ---+
|
+-+-------+--------+--- ... ---+
|
||||||
| | HI LO | | -- data block / msg's argument
|
| | HI LO | | -- data block / msg's argument
|
||||||
+-+-------+--------+--- ... ---+
|
+-+-------+--------+--- ... ---+
|
||||||
|
|
||||||
|
binkp's frames in PLZ mode:
|
||||||
|
|
||||||
|
+---------------------- 0=data block, 1=message(command)
|
||||||
|
| +-------------------- 0=standard block, 1=zlib compressed block
|
||||||
|
| | +---- data block size / msg's argument size
|
||||||
|
| | |
|
||||||
|
7 6 543210 76543210
|
||||||
|
+-+-+------+--------+--- ... ---+
|
||||||
|
| | | HI LO | | -- data block / msg's argument
|
||||||
|
+-+-+------+--------+--- ... ---+
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -46,6 +57,7 @@
|
|||||||
|
|
||||||
#define BINKP_DATA_BLOCK 0x0000
|
#define BINKP_DATA_BLOCK 0x0000
|
||||||
#define BINKP_CONTROL_BLOCK 0x8000
|
#define BINKP_CONTROL_BLOCK 0x8000
|
||||||
|
#define BINKP_PLZ_BLOCK 0x4000
|
||||||
|
|
||||||
|
|
||||||
typedef struct _binkp_frame {
|
typedef struct _binkp_frame {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* Purpose ...............: Fidonet mailer
|
* Purpose ...............: Fidonet mailer
|
||||||
*
|
*
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
* Copyright (C) 1997-2003
|
* Copyright (C) 1997-2004
|
||||||
*
|
*
|
||||||
* Michiel Broek FIDO: 2:280/2802
|
* Michiel Broek FIDO: 2:280/2802
|
||||||
* Beekmansbos 10
|
* Beekmansbos 10
|
||||||
@ -62,7 +62,8 @@ char *ttystat[]= {(char *)"Ok",
|
|||||||
(char *)"TimeOut",
|
(char *)"TimeOut",
|
||||||
(char *)"EOF",
|
(char *)"EOF",
|
||||||
(char *)"Hangup",
|
(char *)"Hangup",
|
||||||
(char *)"Empty"};
|
(char *)"Empty",
|
||||||
|
(char *)"UnCompress"};
|
||||||
|
|
||||||
int tty_resettimer(int tno);
|
int tty_resettimer(int tno);
|
||||||
void tty_resettimers(void);
|
void tty_resettimers(void);
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#define STAT_EOFILE 3
|
#define STAT_EOFILE 3
|
||||||
#define STAT_HANGUP 4
|
#define STAT_HANGUP 4
|
||||||
#define STAT_EMPTY 5
|
#define STAT_EMPTY 5
|
||||||
|
#define STAT_UNCOMP 6
|
||||||
|
|
||||||
#define SUCCESS (STATUS == 0)
|
#define SUCCESS (STATUS == 0)
|
||||||
#define TERROR (-STAT_ERROR)
|
#define TERROR (-STAT_ERROR)
|
||||||
|
Reference in New Issue
Block a user