diff --git a/src/syncterm/GNUmakefile b/src/syncterm/GNUmakefile
index cf4b542319a12fd2f6dce3b6bfe64bbad12f4d64..73d669963b34fd3626074d922ddcad96d7cd8126 100644
--- a/src/syncterm/GNUmakefile
+++ b/src/syncterm/GNUmakefile
@@ -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)
diff --git a/src/syncterm/Makefile b/src/syncterm/Makefile
index 4f38644c9191902f0d612450e65358cc9c2347ce..0cfb3f4cea35b97b6332a486cc3d9ba5401bdaf5 100644
--- a/src/syncterm/Makefile
+++ b/src/syncterm/Makefile
@@ -1,9 +1,11 @@
 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)
diff --git a/src/syncterm/bbslist.c b/src/syncterm/bbslist.c
index 72b8ab1ac5e75622eab4de4ccd38469035fa1c71..57bf1859b3198e81b2a2fcdc4be188f037948b5a 100644
--- a/src/syncterm/bbslist.c
+++ b/src/syncterm/bbslist.c
@@ -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);
diff --git a/src/syncterm/bbslist.h b/src/syncterm/bbslist.h
index 61e899864beaa85eb368faf3d7f5a98795a9a4cb..031ed1e0321a550ac3354e68a0a500788afe9d80 100644
--- a/src/syncterm/bbslist.h
+++ b/src/syncterm/bbslist.h
@@ -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;
 };
 
diff --git a/src/syncterm/conn.c b/src/syncterm/conn.c
new file mode 100644
index 0000000000000000000000000000000000000000..6b317362bc06c59ea27349dbc233734b678b9719
--- /dev/null
+++ b/src/syncterm/conn.c
@@ -0,0 +1,84 @@
+#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);
+}
diff --git a/src/syncterm/conn.h b/src/syncterm/conn.h
new file mode 100644
index 0000000000000000000000000000000000000000..54c1335d6fdc2971da199e10580791d94c25cbf2
--- /dev/null
+++ b/src/syncterm/conn.h
@@ -0,0 +1,23 @@
+#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
diff --git a/src/syncterm/objects.mk b/src/syncterm/objects.mk
index 0dd7c8f7a83de90e5b69b1cb63f98ab6714ed8d3..1cc877595649088a9fde2200e67a217d32b23dc7 100644
--- a/src/syncterm/objects.mk
+++ b/src/syncterm/objects.mk
@@ -1,8 +1,12 @@
 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)
diff --git a/src/syncterm/raw_io.c b/src/syncterm/raw_io.c
new file mode 100644
index 0000000000000000000000000000000000000000..48943aaaba47b1f7f702793db6207a8d2fb1a33c
--- /dev/null
+++ b/src/syncterm/raw_io.c
@@ -0,0 +1,110 @@
+#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));
+}
diff --git a/src/syncterm/raw_io.h b/src/syncterm/raw_io.h
new file mode 100644
index 0000000000000000000000000000000000000000..d351617dc76f25e590a5b2eb268f848d5c82acb2
--- /dev/null
+++ b/src/syncterm/raw_io.h
@@ -0,0 +1,9 @@
+#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
diff --git a/src/syncterm/rlogin.c b/src/syncterm/rlogin.c
index eaca53b8d97c92c3aaa751fdcd7240d4a7fb2971..3841d05573a2e12b6320339fa124554a1286c3e5 100644
--- a/src/syncterm/rlogin.c
+++ b/src/syncterm/rlogin.c
@@ -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));
 }
diff --git a/src/syncterm/rlogin.h b/src/syncterm/rlogin.h
index 3375654803b890e96a13f950cd6a0d4beef1af82..8f8d9940d38e3cfacae3137ff44fac2c9581dae3 100644
--- a/src/syncterm/rlogin.h
+++ b/src/syncterm/rlogin.h
@@ -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
diff --git a/src/syncterm/syncterm.c b/src/syncterm/syncterm.c
index bab8aa412073d614d17fbcc07638f4113d0042af..fe70785679ebe0d14621c908996ebddc46077f7f 100644
--- a/src/syncterm/syncterm.c
+++ b/src/syncterm/syncterm.c
@@ -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;
diff --git a/src/syncterm/telnet_io.c b/src/syncterm/telnet_io.c
new file mode 100644
index 0000000000000000000000000000000000000000..ff9cd8d752d3a8a0fbd62eb24dcc0039086c0ae5
--- /dev/null
+++ b/src/syncterm/telnet_io.c
@@ -0,0 +1,323 @@
+#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);
+}
diff --git a/src/syncterm/telnet_io.h b/src/syncterm/telnet_io.h
new file mode 100644
index 0000000000000000000000000000000000000000..068256abba86feb4cab8b4664fffd0e6ee447370
--- /dev/null
+++ b/src/syncterm/telnet_io.h
@@ -0,0 +1,9 @@
+#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
diff --git a/src/syncterm/term.c b/src/syncterm/term.c
index 9f5ac32f203cfa136c982407027d85cfcbc891e7..5c4ca1d4f380edbb94ecd06ad24e592120d494a7 100644
--- a/src/syncterm/term.c
+++ b/src/syncterm/term.c
@@ -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);
 					}
 					
 			}