Skip to content
Snippets Groups Projects
Commit 46a01292 authored by deuce's avatar deuce
Browse files

Initial support for telnet and RAW connections.

conn.c is horrible and should just be a struct.
parent be0c2080
No related branches found
No related tags found
No related merge requests found
......@@ -6,9 +6,11 @@ ifeq ($(os),sunos) # Solaris
CFLAGS += -DNEED_CFMAKERAW
endif
CFLAGS += $(UIFC-MT_CFLAGS) $(CIOLIB-MT_CFLAGS) $(XPDEV-MT_CFLAGS)
CFLAGS += $(UIFC-MT_CFLAGS) $(CIOLIB-MT_CFLAGS) $(XPDEV-MT_CFLAGS) -I../sbbs3
LDFLAGS += $(UIFC-MT_LDFLAGS) $(CIOLIB-MT_LDFLAGS) $(XPDEV-MT_LDFLAGS)
vpath %.c ../sbbs3
$(SYNCTERM): $(EXEODIR) $(OBJS) $(BUILD_DEPENDS)
@echo Linking $@
${QUIET}$(CC) $(LDFLAGS) $(MT_LDFLAGS) $(OBJS) -o $@ $(UIFC-MT_LIBS) $(CIOLIB-MT_LIBS) $(XPDEV-MT_LIBS)
SRC_ROOT = ..
!include ${SRC_ROOT}\build\Common.bmake
CFLAGS = $(CFLAGS) $(UIFC-MT_CFLAGS) $(CIOLIB-MT_CFLAGS) $(XPDEV-MT_CFLAGS)
CFLAGS = $(CFLAGS) $(UIFC-MT_CFLAGS) $(CIOLIB-MT_CFLAGS) $(XPDEV-MT_CFLAGS) -I../sbbs3
LDFLAGS = $(LDFLAGS) $(UIFC-MT_LDFLAGS) $(CIOLIB-MT_LDFLAGS) $(XPDEV-MT_LDFLAGS)
.path.c = .;../sbbs3
$(SYNCTERM): $(OBJS)
@echo Linking $@
${QUIET}$(CC) $(LDFLAGS) $(MT_LDFLAGS) -e$@ $(OBJS) $(UIFC-MT_LIBS) $(CIOLIB-MT_LIBS) $(XPDEV-MT_LIBS)
......@@ -7,6 +7,7 @@
#include "bbslist.h"
#include "uifcinit.h"
#include "conn.h"
enum {
USER_BBSLIST
......@@ -40,6 +41,7 @@ void read_list(char *listpath, struct bbslist **list, int *i, int type)
FILE *listfile;
char *bbsname;
str_list_t bbses;
BOOL dumb;
if((listfile=fopen(listpath,"r"))!=NULL) {
bbses=iniReadSectionList(listfile,NULL);
......@@ -54,7 +56,10 @@ void read_list(char *listpath, struct bbslist **list, int *i, int type)
list[*i]->calls=iniReadInteger(listfile,bbsname,"TotalCalls",0);
iniReadString(listfile,bbsname,"UserName","",list[*i]->user);
iniReadString(listfile,bbsname,"Password","",list[*i]->password);
list[*i]->dumb=iniReadBool(listfile,bbsname,"BeDumb",0);
list[*i]->conn_type=iniReadInteger(listfile,bbsname,"ConnectionType",CONN_TYPE_RLOGIN);
dumb=iniReadBool(listfile,bbsname,"BeDumb",0);
if(dumb)
list[*i]->conn_type=CONN_TYPE_RAW;
list[*i]->reversed=iniReadBool(listfile,bbsname,"Reversed",0);
list[*i]->type=type;
list[*i]->id=*i;
......@@ -84,9 +89,7 @@ int edit_list(struct bbslist *item,char *listpath)
if(item->type==SYSTEM_BBSLIST) {
uifc.helpbuf= "`Cannot edit system BBS list`\n\n"
"SyncTERM supports system-wide and per-user lists. You may only edit entries"
"in your own personal list.\n"
"\n"
"The Be Dumb option can be used to connect to BBSs which support 'dumb' telnet";
"in your own personal list.\n";
uifc.msg("Cannot edit system BBS list");
return(0);
}
......@@ -99,11 +102,11 @@ int edit_list(struct bbslist *item,char *listpath)
return(0);
for(;;) {
sprintf(opt[0],"BBS Name: %s",item->name);
sprintf(opt[1],"RLogin Address: %s",item->addr);
sprintf(opt[2],"RLogin Port: %hu",item->port);
sprintf(opt[1],"Address: %s",item->addr);
sprintf(opt[2],"Port: %hu",item->port);
sprintf(opt[3],"Username: %s",item->user);
sprintf(opt[4],"Password");
sprintf(opt[5],"Be Dumb: %s",item->dumb?"Yes":"No");
sprintf(opt[5],"Connection: %s",conn_types[item->conn_type]);
sprintf(opt[6],"Reversed: %s",item->reversed?"Yes":"No");
uifc.changes=0;
......@@ -125,23 +128,19 @@ int edit_list(struct bbslist *item,char *listpath)
iniRenameSection(&inifile,tmp,item->name);
break;
case 1:
uifc.helpbuf= "`RLogin address`\n\n"
uifc.helpbuf= "`Address`\n\n"
"Enter the domain name of the system to connect to ie:\n"
"nix.synchro.net";
uifc.input(WIN_MID|WIN_SAV,0,0,"RLogin Address",item->addr,LIST_ADDR_MAX,K_EDIT);
uifc.input(WIN_MID|WIN_SAV,0,0,"Address",item->addr,LIST_ADDR_MAX,K_EDIT);
iniSetString(&inifile,item->name,"Address",item->addr,NULL);
break;
case 2:
i=item->port;
sprintf(str,"%hu",item->port?item->port:513);
uifc.helpbuf= "`RLogin port`\n\n"
"Enter the port which RLogin is listening to on the remote system\n\n"
"~ NOTE:~\n"
"Connecting to telnet ports currently appears to work... however, if an\n"
"ASCII 255 char is sent by either end, it will be handled incorreclty by\n"
"the remote system. Further, if the remote system follows the RFC, some\n"
"Terminal weirdness should be expected. This program DOES NOT do telnet.";
uifc.input(WIN_MID|WIN_SAV,0,0,"RLogin Port",str,5,K_EDIT|K_NUMBER);
uifc.helpbuf= "`Port`\n\n"
"Enter the port which the BBS is listening to on the remote system\n"
"Telnet is generally port 23 and RLogin is generally 513\n";
uifc.input(WIN_MID|WIN_SAV,0,0,"Port",str,5,K_EDIT|K_NUMBER);
j=atoi(str);
if(j<1 || j>65535)
j=513;
......@@ -165,9 +164,11 @@ int edit_list(struct bbslist *item,char *listpath)
iniSetString(&inifile,item->name,"Password",item->password,NULL);
break;
case 5:
item->dumb=!item->dumb;
item->conn_type++;
if(item->conn_type==CONN_TYPE_TERMINATOR)
item->conn_type=CONN_TYPE_RLOGIN;
changed=1;
iniSetBool(&inifile,item->name,"BeDumb",item->dumb,NULL);
iniSetInteger(&inifile,item->name,"ConnectionType",item->conn_type,NULL);
break;
case 6:
item->reversed=!item->reversed;
......@@ -203,7 +204,7 @@ void add_bbs(char *listpath, struct bbslist *bbs)
iniSetInteger(&inifile,bbs->name,"TotalCalls",bbs->calls,NULL);
iniSetString(&inifile,bbs->name,"UserName",bbs->user,NULL);
iniSetString(&inifile,bbs->name,"Password",bbs->password,NULL);
iniSetBool(&inifile,bbs->name,"BeDumb",bbs->dumb,NULL);
iniSetInteger(&inifile,bbs->name,"ConnectionType",bbs->conn_type,NULL);
iniSetBool(&inifile,bbs->name,"Reversed",bbs->reversed,NULL);
if((listfile=fopen(listpath,"w"))!=NULL) {
iniWriteFile(listfile,inifile);
......@@ -314,10 +315,10 @@ struct bbslist *show_bbslist(int mode, char *path)
uifc.input(WIN_MID|WIN_SAV,0,0,"BBS Name",list[listcount-1]->name,LIST_NAME_MAX,K_EDIT);
if(uifc.changes) {
uifc.changes=0;
uifc.helpbuf= "`RLogin address`\n\n"
uifc.helpbuf= "`Address`\n\n"
"Enter the domain name of the system to connect to ie:\n"
"nix.synchro.net";
uifc.input(WIN_MID|WIN_SAV,0,0,"RLogin Address",list[listcount-1]->addr,LIST_ADDR_MAX,K_EDIT);
uifc.input(WIN_MID|WIN_SAV,0,0,"Address",list[listcount-1]->addr,LIST_ADDR_MAX,K_EDIT);
}
if(!uifc.changes) {
free(list[listcount-1]);
......@@ -328,27 +329,26 @@ struct bbslist *show_bbslist(int mode, char *path)
while(!list[listcount-1]->port) {
list[listcount-1]->port=513;
sprintf(str,"%hu",list[listcount-1]->port);
uifc.helpbuf= "`RLogin port`\n\n"
"Enter the port which RLogin is listening to on the remote system\n\n"
"~ NOTE:~\n"
"Connecting to telnet ports currently appears to work... however, if an\n"
"ASCII 255 char is sent by either end, it will be handled incorreclty by\n"
"the remote system. Further, if the remote system follows the RFC, some\n"
"Terminal weirdness should be expected. This program DOES NOT do telnet.";
uifc.input(WIN_MID|WIN_SAV,0,0,"RLogin Port",str,5,K_EDIT|K_NUMBER);
uifc.helpbuf= "`Port`\n\n"
"Enter the port which the BBS is listening to on the remote system\n"
"Telnet is generally port 23 and RLogin is generally 513\n";
uifc.input(WIN_MID|WIN_SAV,0,0,"Port",str,5,K_EDIT|K_NUMBER);
j=atoi(str);
if(j<1 || j>65535)
j=0;
list[listcount-1]->port=j;
}
if(list[listcount-1]->port != 513) {
uifc.helpbuf= "`Be Dumb`\n\n"
"Select this option if attempting to connect to a dumb telnet BBS";
list[listcount-1]->dumb=0;
uifc.list(WIN_MID|WIN_SAV,0,0,0,&list[listcount-1]->dumb,NULL,"Be Dumb",YesNo);
list[listcount-1]->dumb=!list[listcount-1]->dumb;
uifc.helpbuf= "`Connection Type`\n\n"
"Select the type of connection you wish to make:\n"
"~ RLogin:~ Auto-login with RLogin protocol\n"
"~ Telnet:~ Use more common Telnet protocol (experimental)\n"
"~ Raw: ~ Make a raw socket connection (experimental)\n";
list[listcount-1]->conn_type=CONN_TYPE_RLOGIN;
uifc.list(WIN_MID|WIN_SAV,0,0,0,&list[listcount-1]->conn_type,NULL,"Connection Type",&conn_types[1]);
list[listcount-1]->conn_type++;
}
if(!list[listcount-1]->dumb) {
if(list[listcount-1]->conn_type==CONN_TYPE_RLOGIN) {
uifc.helpbuf= "`Username`\n\n"
"Enter the username to attempt auto-login to the remote with.";
uifc.input(WIN_MID|WIN_SAV,0,0,"User Name",list[listcount-1]->user,MAX_USER_LEN,K_EDIT);
......
......@@ -23,8 +23,8 @@ struct bbslist {
char user[MAX_USER_LEN+1];
char password[MAX_PASSWD_LEN+1];
int type;
int conn_type;
int id;
int dumb;
int reversed;
};
......
#include "sockwrap.h"
#include "rlogin.h"
#include "telnet_io.h"
#include "raw_io.h"
#include "conn.h"
static int con_type=CONN_TYPE_UNKNOWN;
SOCKET conn_socket=INVALID_SOCKET;
char *conn_types[]={"Unknown","RLogin","Telnet","Raw",""};
int conn_recv(char *buffer, size_t buflen)
{
int retval=-1;
switch(con_type) {
case CONN_TYPE_RLOGIN:
retval=rlogin_recv(buffer, buflen);
break;
case CONN_TYPE_TELNET:
retval=telnet_recv(buffer, buflen);
break;
case CONN_TYPE_RAW:
retval=raw_recv(buffer, buflen);
break;
}
return(retval);
}
int conn_send(char *buffer, size_t buflen, unsigned int timeout)
{
int retval=-1;
switch(con_type) {
case CONN_TYPE_RLOGIN:
retval=rlogin_send(buffer, buflen, timeout);
break;
case CONN_TYPE_TELNET:
retval=telnet_send(buffer, buflen, timeout);
break;
case CONN_TYPE_RAW:
retval=raw_send(buffer, buflen, timeout);
break;
}
return(retval);
}
int conn_connect(char *addr, int port, char *ruser, char *passwd, int conn_type)
{
int retval=-1;
con_type=conn_type;
switch(con_type) {
case CONN_TYPE_RLOGIN:
retval=rlogin_connect(addr, port, ruser, passwd);
break;
case CONN_TYPE_TELNET:
retval=telnet_connect(addr, port, ruser, passwd);
break;
case CONN_TYPE_RAW:
retval=raw_connect(addr, port, ruser, passwd);
break;
}
return(retval);
}
int conn_close(void)
{
int retval=-1;
switch(con_type) {
case CONN_TYPE_RLOGIN:
retval=rlogin_close();
break;
case CONN_TYPE_TELNET:
retval=telnet_close();
break;
case CONN_TYPE_RAW:
retval=raw_close();
break;
}
con_type=CONN_TYPE_UNKNOWN;
return(retval);
}
#ifndef _CONN_H_
#define _CONN_H_
#include "sockwrap.h"
extern SOCKET conn_socket;
extern char *conn_types[];
enum {
CONN_TYPE_UNKNOWN
,CONN_TYPE_RLOGIN
,CONN_TYPE_TELNET
,CONN_TYPE_RAW
,CONN_TYPE_TERMINATOR
};
int conn_recv(char *buffer, size_t buflen);
int conn_send(char *buffer, size_t buflen, unsigned int timeout);
int conn_connect(char *addr, int port, char *ruser, char *passwd, int conn_type);
int conn_close(void);
void conn_settype(int type);
#endif
OBJS = \
$(MTOBJODIR)$(DIRSEP)bbslist$(OFILE) \
$(MTOBJODIR)$(DIRSEP)bbslist$(OFILE) \
$(MTOBJODIR)$(DIRSEP)uifcinit$(OFILE) \
$(MTOBJODIR)$(DIRSEP)conn$(OFILE) \
$(MTOBJODIR)$(DIRSEP)telnet$(OFILE) \
$(MTOBJODIR)$(DIRSEP)telnet_io$(OFILE) \
$(MTOBJODIR)$(DIRSEP)raw_io$(OFILE) \
$(MTOBJODIR)$(DIRSEP)rlogin$(OFILE) \
$(MTOBJODIR)$(DIRSEP)term$(OFILE) \
$(MTOBJODIR)$(DIRSEP)window$(OFILE) \
$(MTOBJODIR)$(DIRSEP)menu$(OFILE) \
$(MTOBJODIR)$(DIRSEP)syncterm$(OFILE)
$(MTOBJODIR)$(DIRSEP)syncterm$(OFILE)
#include <genwrap.h>
#include <sockwrap.h>
#include "uifcinit.h"
#include "bbslist.h"
#include "conn.h"
int raw_recv(char *buffer, size_t buflen)
{
int r;
int avail;
int rd;
if(!socket_check(conn_socket, NULL, NULL, 0))
return(-1);
if(!ioctlsocket(conn_socket,FIONREAD,(void *)&avail) && avail)
r=recv(conn_socket,buffer,avail<buflen?avail:buflen,0);
else
return(0);
if(r==-1 && (errno==EAGAIN || errno==EINTR || errno==0)) /* WTF? */
r=0;
return(r);
}
int raw_send(char *buffer, size_t buflen, unsigned int timeout)
{
int sent=0;
int ret;
int i;
while(sent<buflen) {
if(!socket_check(conn_socket, NULL, &i, timeout))
return(-1);
if(!i)
return(-1);
ret=send(conn_socket,buffer+sent,buflen-sent,0);
if(ret==-1) {
switch(errno) {
case EAGAIN:
case ENOBUFS:
SLEEP(1);
break;
default:
return(-1);
}
}
else
sent+=ret;
}
return(0);
}
int raw_connect(char *addr, int port, char *ruser, char *passwd)
{
HOSTENT *ent;
SOCKADDR_IN saddr;
char nil=0;
char *p;
unsigned int neta;
int i;
for(p=addr;*p;p++)
if(*p!='.' && !isdigit(*p))
break;
if(!(*p))
neta=inet_addr(addr);
else {
if((ent=gethostbyname(addr))==NULL) {
char str[LIST_ADDR_MAX+17];
sprintf(str,"Cannot resolve %s!",addr);
uifcmsg(str, "`Cannot Resolve Host`\n\n"
"The system is unable to resolve the hostname... double check the spelling.\n"
"If it's not an issue with your DNS settings, the issue is probobly\n"
"with the DNS settings of the system you are trying to contact.");
return(-1);
}
neta=*((unsigned int*)ent->h_addr_list[0]);
}
conn_socket=socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
if(conn_socket==INVALID_SOCKET) {
uifcmsg("Cannot create socket!", "`Unable to create socket`\n\n"
"Your system is either dangerously low on resources, or there"
"is a problem with your TCP/IP stack.");
return(-1);
}
memset(&saddr,0,sizeof(saddr));
saddr.sin_addr.s_addr = neta;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
if(connect(conn_socket, (struct sockaddr *)&saddr, sizeof(saddr))) {
char str[LIST_ADDR_MAX+20];
raw_close();
sprintf(str,"Cannot connect to %s!",addr);
uifcmsg(str, "`Unable to connect`\n\n"
"Cannot connect to the remost system... it is down or unreachable.");
return(-1);
}
return(0);
}
int raw_close(void)
{
return(closesocket(conn_socket));
}
#ifndef _RAW_IO_H_
#define _RAW_IO_H_
int raw_recv(char *buffer, size_t buflen);
int raw_send(char *buffer, size_t buflen, unsigned int timeout);
int raw_connect(char *addr, int port, char *ruser, char *passwd);
int raw_close(void);
#endif
......@@ -3,8 +3,7 @@
#include "uifcinit.h"
#include "bbslist.h"
static SOCKET rlogin_socket=INVALID_SOCKET;
#include "conn.h"
int rlogin_recv(char *buffer, size_t buflen)
{
......@@ -12,11 +11,11 @@ int rlogin_recv(char *buffer, size_t buflen)
int avail;
int rd;
if(!socket_check(rlogin_socket, NULL, NULL, 0))
if(!socket_check(conn_socket, NULL, NULL, 0))
return(-1);
if(!ioctlsocket(rlogin_socket,FIONREAD,(void *)&avail) && avail)
r=recv(rlogin_socket,buffer,avail<buflen?avail:buflen,0);
if(!ioctlsocket(conn_socket,FIONREAD,(void *)&avail) && avail)
r=recv(conn_socket,buffer,avail<buflen?avail:buflen,0);
else
return(0);
......@@ -32,11 +31,11 @@ int rlogin_send(char *buffer, size_t buflen, unsigned int timeout)
int i;
while(sent<buflen) {
if(!socket_check(rlogin_socket, NULL, &i, timeout))
if(!socket_check(conn_socket, NULL, &i, timeout))
return(-1);
if(!i)
return(-1);
ret=send(rlogin_socket,buffer+sent,buflen-sent,0);
ret=send(conn_socket,buffer+sent,buflen-sent,0);
if(ret==-1) {
switch(errno) {
case EAGAIN:
......@@ -53,7 +52,7 @@ int rlogin_send(char *buffer, size_t buflen, unsigned int timeout)
return(0);
}
int rlogin_connect(char *addr, int port, char *ruser, char *passwd, int bedumb)
int rlogin_connect(char *addr, int port, char *ruser, char *passwd)
{
HOSTENT *ent;
SOCKADDR_IN saddr;
......@@ -80,8 +79,8 @@ int rlogin_connect(char *addr, int port, char *ruser, char *passwd, int bedumb)
}
neta=*((unsigned int*)ent->h_addr_list[0]);
}
rlogin_socket=socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
if(rlogin_socket==INVALID_SOCKET) {
conn_socket=socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
if(conn_socket==INVALID_SOCKET) {
uifcmsg("Cannot create socket!", "`Unable to create socket`\n\n"
"Your system is either dangerously low on resources, or there"
"is a problem with your TCP/IP stack.");
......@@ -92,7 +91,7 @@ int rlogin_connect(char *addr, int port, char *ruser, char *passwd, int bedumb)
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
if(connect(rlogin_socket, (struct sockaddr *)&saddr, sizeof(saddr))) {
if(connect(conn_socket, (struct sockaddr *)&saddr, sizeof(saddr))) {
char str[LIST_ADDR_MAX+20];
rlogin_close();
......@@ -102,16 +101,15 @@ int rlogin_connect(char *addr, int port, char *ruser, char *passwd, int bedumb)
return(-1);
}
if(!bedumb) {
rlogin_send("",1,1000);
rlogin_send(passwd,strlen(passwd)+1,1000);
rlogin_send(ruser,strlen(ruser)+1,1000);
rlogin_send("ansi-bbs/9600",14,1000);
}
rlogin_send("",1,1000);
rlogin_send(passwd,strlen(passwd)+1,1000);
rlogin_send(ruser,strlen(ruser)+1,1000);
rlogin_send("ansi-bbs/9600",14,1000);
return(0);
}
int rlogin_close(void)
{
return(closesocket(rlogin_socket));
return(closesocket(conn_socket));
}
......@@ -7,7 +7,7 @@ extern SOCKET rlogin_socket;
int rlogin_recv(char *buffer, size_t buflen);
int rlogin_send(char *buffer, size_t buflen, unsigned int timeout);
int rlogin_connect(char *addr, int port, char *ruser, char *passwd, int dumb);
int rlogin_connect(char *addr, int port, char *ruser, char *passwd);
int rlogin_close(void);
#endif
......@@ -6,7 +6,7 @@
#include <dirwrap.h>
#include "bbslist.h"
#include "rlogin.h"
#include "conn.h"
#include "uifcinit.h"
#ifdef _WINSOCKAPI_
......@@ -58,7 +58,7 @@ int main(int argc, char **argv)
FULLPATH(path,drive,sizeof(path));
atexit(uifcbail);
while((bbs=show_bbslist(BBSLIST_SELECT,path))!=NULL) {
if(!rlogin_connect(bbs->addr,bbs->port,bbs->reversed?bbs->password:bbs->user,bbs->reversed?bbs->user:bbs->password,bbs->dumb)) {
if(!conn_connect(bbs->addr,bbs->port,bbs->reversed?bbs->password:bbs->user,bbs->reversed?bbs->user:bbs->password,bbs->conn_type)) {
/* ToDo: Update the entry with new lastconnected */
/* ToDo: Disallow duplicate entries */
str_list_t inifile;
......
#include <stdlib.h>
#include <string.h>
#include "genwrap.h"
#include "sockwrap.h"
#include "telnet.h"
#include "gen_defs.h"
#include "bbslist.h"
#include "conn.h"
#define TELNET_TERM_MAXLEN 40
uint telnet_cmdlen=0;
uchar telnet_cmd[64];
char terminal[TELNET_TERM_MAXLEN+1];
uint rows;
uint cols;
ulong telnet_mode;
uchar telnet_local_option[0x100];
uchar telnet_remote_option[0x100];
#define putcom(buf,len) send(conn_socket, buf, len, 0)
void send_telnet_cmd(uchar cmd, uchar opt);
static BYTE* telnet_interpret(BYTE* inbuf, int inlen, BYTE* outbuf, int *outlen)
{
BYTE* first_iac=NULL;
BYTE* first_cr=NULL;
int i;
if(inlen<1) {
*outlen=0;
return(inbuf); // no length? No interpretation
}
first_iac=(BYTE*)memchr(inbuf, TELNET_IAC, inlen);
if(!telnet_cmdlen && first_iac==NULL && first_cr==NULL) {
*outlen=inlen;
return(inbuf); // no interpretation needed
}
if(first_iac!=NULL || first_cr!=NULL) {
if(first_iac!=NULL && (first_cr==NULL || first_iac<first_cr))
*outlen=first_iac-inbuf;
else
*outlen=first_cr-inbuf;
memcpy(outbuf, inbuf, *outlen);
} else
*outlen=0;
for(i=*outlen;i<inlen;i++) {
if(inbuf[i]==TELNET_IAC && telnet_cmdlen==1) { /* escaped 255 */
telnet_cmdlen=0;
outbuf[*outlen++]=TELNET_IAC;
continue;
}
if(inbuf[i]==TELNET_IAC || telnet_cmdlen) {
uchar command = telnet_cmd[1];
uchar option = telnet_cmd[2];
if(telnet_cmdlen<sizeof(telnet_cmd))
telnet_cmd[telnet_cmdlen++]=inbuf[i];
if(telnet_cmdlen>=2 && command==TELNET_SB) {
if(inbuf[i]==TELNET_SE
&& telnet_cmd[telnet_cmdlen-2]==TELNET_IAC) {
/* sub-option terminated */
if(option==TELNET_TERM_TYPE
&& telnet_cmd[3]==TELNET_TERM_IS) {
sprintf(terminal,"%.*s",(int)telnet_cmdlen-6,telnet_cmd+4);
} else if(option==TELNET_TERM_SPEED
&& telnet_cmd[3]==TELNET_TERM_IS) {
char speed[128];
sprintf(speed,"%.*s",(int)telnet_cmdlen-6,telnet_cmd+4);
} else if(option==TELNET_NEGOTIATE_WINDOW_SIZE) {
long cols = (telnet_cmd[3]<<8) | telnet_cmd[4];
long rows = (telnet_cmd[5]<<8) | telnet_cmd[6];
if(rows) /* auto-detect rows */
rows=rows;
if(cols)
cols=cols;
}
telnet_cmdlen=0;
}
}
else if(telnet_cmdlen==2 && inbuf[i]<TELNET_WILL) {
telnet_cmdlen=0;
}
else if(telnet_cmdlen>=3) { /* telnet option negotiation */
if(command==TELNET_DO || command==TELNET_DONT) { /* local options */
if(telnet_local_option[option]!=command) {
telnet_local_option[option]=command;
send_telnet_cmd(telnet_opt_ack(command),option);
}
} else { /* WILL/WONT (remote options) */
if(telnet_remote_option[option]!=command) {
switch(option) {
case TELNET_BINARY_TX:
case TELNET_ECHO:
case TELNET_TERM_TYPE:
case TELNET_TERM_SPEED:
case TELNET_SUP_GA:
case TELNET_NEGOTIATE_WINDOW_SIZE:
telnet_remote_option[option]=command;
send_telnet_cmd(telnet_opt_ack(command),option);
break;
default: /* unsupported remote options */
if(command==TELNET_WILL) /* NAK */
send_telnet_cmd(telnet_opt_nak(command),option);
break;
}
}
if(command==TELNET_WILL && option==TELNET_TERM_TYPE) {
char buf[64];
sprintf(buf,"%c%c%c%c%c%c"
,TELNET_IAC,TELNET_SB
,TELNET_TERM_TYPE,TELNET_TERM_SEND
,TELNET_IAC,TELNET_SE);
putcom(buf,6);
}
else if(command==TELNET_WILL && option==TELNET_TERM_SPEED) {
char buf[64];
sprintf(buf,"%c%c%c%c%c%c"
,TELNET_IAC,TELNET_SB
,TELNET_TERM_SPEED,TELNET_TERM_SEND
,TELNET_IAC,TELNET_SE);
putcom(buf,6);
}
}
telnet_cmdlen=0;
}
} else
outbuf[*outlen++]=inbuf[i];
}
return(outbuf);
}
void send_telnet_cmd(uchar cmd, uchar opt)
{
char buf[16];
if(telnet_mode&TELNET_MODE_OFF)
return;
if(cmd<TELNET_WILL) {
sprintf(buf,"%c%c",TELNET_IAC,cmd);
putcom(buf,2);
} else {
sprintf(buf,"%c%c%c",TELNET_IAC,cmd,opt);
putcom(buf,3);
}
}
void request_telnet_opt(uchar cmd, uchar opt)
{
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 */
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 */
telnet_local_option[opt]=telnet_opt_ack(cmd);
}
send_telnet_cmd(cmd,opt);
}
int telnet_recv(char *buffer, size_t buflen)
{
int r;
int avail;
int rd;
BYTE *inbuf;
if(!socket_check(conn_socket, NULL, NULL, 0))
return(-1);
if((inbuf=(BYTE *)malloc(buflen))==NULL)
return(-1);
if(!ioctlsocket(conn_socket,FIONREAD,(void *)&avail) && avail)
r=recv(conn_socket,inbuf,avail<buflen?avail:buflen,0);
else {
free(inbuf);
return(0);
}
if(r==-1 && (errno==EAGAIN || errno==EINTR || errno==0)) /* WTF? */
r=0;
if(r) {
if(telnet_interpret(inbuf, r, buffer, &r)==inbuf)
memcpy(buffer, inbuf, r);
}
free(inbuf);
return(r);
}
BYTE* telnet_expand(BYTE* inbuf, size_t inlen, BYTE* outbuf, size_t *newlen)
{
BYTE* first_iac;
ulong i,outlen;
first_iac=(BYTE*)memchr(inbuf, TELNET_IAC, inlen);
if(first_iac==NULL) { /* Nothing to expand */
*newlen=inlen;
return(inbuf);
}
outlen=first_iac-inbuf;
memcpy(outbuf, inbuf, outlen);
for(i=outlen;i<inlen;i++) {
if(inbuf[i]==TELNET_IAC)
outbuf[outlen++]=TELNET_IAC;
outbuf[outlen++]=inbuf[i];
}
*newlen=outlen;
return(outbuf);
}
int telnet_send(char *buffer, size_t buflen, unsigned int timeout)
{
int sent=0;
int ret;
int i;
BYTE *outbuf;
BYTE *sendbuf;
if((outbuf=(BYTE *)malloc(buflen*2))==NULL)
return(-1);
sendbuf=telnet_expand(buffer, buflen, outbuf, &buflen);
while(sent<buflen) {
if(!socket_check(conn_socket, NULL, &i, timeout)) {
free(outbuf);
return(-1);
}
if(!i) {
free(outbuf);
return(-1);
}
ret=send(conn_socket,sendbuf+sent,buflen-sent,0);
if(ret==-1) {
switch(errno) {
case EAGAIN:
case ENOBUFS:
SLEEP(1);
break;
default:
free(outbuf);
return(-1);
}
}
else
sent+=ret;
}
free(outbuf);
return(0);
}
int telnet_close(void)
{
return(closesocket(conn_socket));
}
int telnet_connect(char *addr, int port, char *ruser, char *passwd)
{
HOSTENT *ent;
SOCKADDR_IN saddr;
char nil=0;
char *p;
unsigned int neta;
int i;
for(p=addr;*p;p++)
if(*p!='.' && !isdigit(*p))
break;
if(!(*p))
neta=inet_addr(addr);
else {
if((ent=gethostbyname(addr))==NULL) {
char str[LIST_ADDR_MAX+17];
sprintf(str,"Cannot resolve %s!",addr);
uifcmsg(str, "`Cannot Resolve Host`\n\n"
"The system is unable to resolve the hostname... double check the spelling.\n"
"If it's not an issue with your DNS settings, the issue is probobly\n"
"with the DNS settings of the system you are trying to contact.");
return(-1);
}
neta=*((unsigned int*)ent->h_addr_list[0]);
}
conn_socket=socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
if(conn_socket==INVALID_SOCKET) {
uifcmsg("Cannot create socket!", "`Unable to create socket`\n\n"
"Your system is either dangerously low on resources, or there"
"is a problem with your TCP/IP stack.");
return(-1);
}
memset(&saddr,0,sizeof(saddr));
saddr.sin_addr.s_addr = neta;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
if(connect(conn_socket, (struct sockaddr *)&saddr, sizeof(saddr))) {
char str[LIST_ADDR_MAX+20];
telnet_close();
sprintf(str,"Cannot connect to %s!",addr);
uifcmsg(str, "`Unable to connect`\n\n"
"Cannot connect to the remost system... it is down or unreachable.");
return(-1);
}
return(0);
}
#ifndef _TELNET_IO_H_
#define _TELNET_IO_H_
int telnet_recv(char *buffer, size_t buflen);
int telnet_send(char *buffer, size_t buflen, unsigned int timeout);
int telnet_close(void);
int telnet_connect(char *addr, int port, char *ruser, char *passwd);
#endif
......@@ -4,7 +4,7 @@
#include <mouse.h>
#include <keys.h>
#include "rlogin.h"
#include "conn.h"
#include "term.h"
#include "uifcinit.h"
#include "menu.h"
......@@ -32,19 +32,19 @@ void doterm(void)
/* Main input loop */
for(;;) {
/* Get remote input */
i=rlogin_recv(buf,sizeof(buf));
i=conn_recv(buf,sizeof(buf));
switch(i) {
case -1:
free(scrollback);
cterm_end();
rlogin_close();
conn_close();
uifcmsg("Disconnected","`Disconnected`\n\nRemote host dropped connection");
return;
case 0:
break;
default:
cterm_write(buf,i,prn,sizeof(prn));
rlogin_send(prn,strlen(prn),0);
conn_send(prn,strlen(prn),0);
break;
}
......@@ -62,37 +62,37 @@ void doterm(void)
break;
case CIO_KEY_LEFT:
rlogin_send("\033[D",3,0);
conn_send("\033[D",3,0);
break;
case CIO_KEY_RIGHT:
rlogin_send("\033[C",3,0);
conn_send("\033[C",3,0);
break;
case CIO_KEY_UP:
rlogin_send("\033[A",3,0);
conn_send("\033[A",3,0);
break;
case CIO_KEY_DOWN:
rlogin_send("\033[B",3,0);
conn_send("\033[B",3,0);
break;
case CIO_KEY_HOME:
rlogin_send("\033[H",3,0);
conn_send("\033[H",3,0);
break;
case CIO_KEY_END:
#ifdef CIO_KEY_SELECT
case CIO_KEY_SELECT: /* Some terminfo/termcap entries use KEY_SELECT as the END key! */
#endif
rlogin_send("\033[K",3,0);
conn_send("\033[K",3,0);
break;
case CIO_KEY_F(1):
rlogin_send("\033OP",3,0);
conn_send("\033OP",3,0);
break;
case CIO_KEY_F(2):
rlogin_send("\033OQ",3,0);
conn_send("\033OQ",3,0);
break;
case CIO_KEY_F(3):
rlogin_send("\033Ow",3,0);
conn_send("\033Ow",3,0);
break;
case CIO_KEY_F(4):
rlogin_send("\033Ox",3,0);
conn_send("\033Ox",3,0);
break;
case 0x1f00: /* ALT-S */
viewscroll();
......@@ -102,7 +102,7 @@ void doterm(void)
case 17: /* CTRL-Q */
cterm_end();
free(scrollback);
rlogin_close();
conn_close();
return;
case 19: /* CTRL-S */
i=wherex();
......@@ -111,7 +111,7 @@ void doterm(void)
case -1:
cterm_end();
free(scrollback);
rlogin_close();
conn_close();
return;
}
gotoxy(i,j);
......@@ -122,7 +122,7 @@ void doterm(void)
default:
if(key<256) {
ch[0]=key;
rlogin_send(ch,1,0);
conn_send(ch,1,0);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment