Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commit 1223da7d authored by rswindell's avatar rswindell

request_telnet_opt() can now (optionally) block with timeout for the ack.

telnet_gate() now enables the telnet command pass-through after negotiating
necessary options. This doesn't quite fix the problem reported with telgating
to nethack.alt.org, but it's a step in the right direction.
parent 1fa11167
......@@ -1311,13 +1311,16 @@ static BYTE* telnet_interpret(sbbs_t* sbbs, BYTE* inbuf, int inlen,
if(!(sbbs->telnet_mode&TELNET_MODE_GATE)) {
if(command==TELNET_DO || command==TELNET_DONT) { /* local options */
if(sbbs->telnet_local_option[option]!=command) {
if(sbbs->telnet_local_option[option]==command)
SetEvent(sbbs->telnet_ack_event);
else {
sbbs->telnet_local_option[option]=command;
sbbs->send_telnet_cmd(telnet_opt_ack(command),option);
}
} else { /* WILL/WONT (remote options) */
if(sbbs->telnet_remote_option[option]!=command) {
if(sbbs->telnet_remote_option[option]==command)
SetEvent(sbbs->telnet_ack_event);
else {
switch(option) {
case TELNET_BINARY_TX:
case TELNET_ECHO:
......@@ -1413,18 +1416,23 @@ void sbbs_t::send_telnet_cmd(uchar cmd, uchar opt)
}
}
void sbbs_t::request_telnet_opt(uchar cmd, uchar opt)
bool sbbs_t::request_telnet_opt(uchar cmd, uchar opt, unsigned waitforack)
{
if(cmd==TELNET_DO || cmd==TELNET_DONT) { /* remote option */
if(telnet_remote_option[opt]==telnet_opt_ack(cmd))
return; /* already set in this mode, do nothing */
return true; /* already set in this mode, do nothing */
telnet_remote_option[opt]=telnet_opt_ack(cmd);
} else { /* local option */
if(telnet_local_option[opt]==telnet_opt_ack(cmd))
return; /* already set in this mode, do nothing */
return true; /* already set in this mode, do nothing */
telnet_local_option[opt]=telnet_opt_ack(cmd);
}
if(waitforack)
ResetEvent(telnet_ack_event);
send_telnet_cmd(cmd,opt);
if(waitforack)
return WaitForEvent(telnet_ack_event, waitforack)==WAIT_OBJECT_0;
return true;
}
void input_thread(void *arg)
......@@ -2880,6 +2888,7 @@ sbbs_t::sbbs_t(ushort node_num, DWORD addr, const char* name, SOCKET sd,
telnet_cmdlen=0;
telnet_mode=0;
telnet_last_rxch=0;
telnet_ack_event=CreateEvent(NULL, /* Manual Reset: */FALSE,/* InitialState */FALSE,NULL);
sys_status=lncntr=tos=criterrs=slcnt=0L;
column=0;
......@@ -3267,6 +3276,9 @@ sbbs_t::~sbbs_t()
if(!output_thread_running)
RingBufDispose(&outbuf);
if(telnet_ack_event!=NULL)
CloseEvent(telnet_ack_event);
/* Close all open files */
if(nodefile!=-1) {
close(nodefile);
......
......@@ -135,6 +135,7 @@ extern int thread_suid_broken; /* NPTL is no longer broken */
#include "filewrap.h"
#include "datewrap.h"
#include "sockwrap.h"
#include "eventwrap.h"
#include "link_list.h"
#include "msg_queue.h"
#include "xpdatetime.h"
......@@ -209,7 +210,7 @@ public:
uchar telnet_local_option[0x100];
uchar telnet_remote_option[0x100];
void send_telnet_cmd(uchar cmd, uchar opt);
void request_telnet_opt(uchar cmd, uchar opt);
bool request_telnet_opt(uchar cmd, uchar opt, unsigned waitforack=0);
uchar telnet_cmd[64];
uint telnet_cmdlen;
......@@ -217,6 +218,7 @@ public:
uchar telnet_last_rxch;
char telnet_location[128];
char terminal[TELNET_TERM_MAXLEN+1];
xpevent_t telnet_ack_event;
time_t event_time; // Time of next exclusive event
char* event_code; // Internal code of next exclusive event
......
......@@ -8,7 +8,7 @@
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2009 Rob Swindell - http://www.synchro.net/copyright.html *
* Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
......@@ -115,9 +115,6 @@ void sbbs_t::telnet_gate(char* destaddr, ulong mode)
,mode&TG_RLOGIN ? "RLogin" : "Telnet"
,destaddr,port,remote_socket);
if(mode&(TG_PASSTHRU|TG_RLOGIN))
telnet_mode|=TELNET_MODE_GATE; // Pass-through telnet commands
if(!(mode&TG_CTRLKEYS))
console|=CON_RAW_IN;
......@@ -136,10 +133,13 @@ void sbbs_t::telnet_gate(char* destaddr, ulong mode)
/* This is required for gating to Unix telnetd */
if(mode&TG_NOTERMTYPE)
request_telnet_opt(TELNET_DONT,TELNET_TERM_TYPE); // Re-negotiation of terminal type
request_telnet_opt(TELNET_DONT,TELNET_TERM_TYPE, 3000); // Re-negotiation of terminal type
/* Text/NVT mode by default */
request_telnet_opt(TELNET_DONT,TELNET_BINARY_TX);
request_telnet_opt(TELNET_DONT,TELNET_BINARY_TX, 3000);
if(mode&(TG_PASSTHRU|TG_RLOGIN))
telnet_mode|=TELNET_MODE_GATE; // Pass-through telnet commands
while(online) {
if(!(mode&TG_NOCHKTIME))
......@@ -250,7 +250,7 @@ void sbbs_t::telnet_gate(char* destaddr, ulong mode)
p=dump;
for(int i=0;i<rd;i++)
p+=sprintf(p,"%u ",buf[i]);
lprintf(LOG_DEBUG,"Node %d Telnet cmd from remote: %s", cfg.node_num, dump);
lprintf(LOG_DEBUG,"Node %d Telnet cmd from server: %s", cfg.node_num, dump);
}
#endif
RingBufWrite(&outbuf,buf,rd);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment