diff --git a/src/sbbs3/execmisc.cpp b/src/sbbs3/execmisc.cpp
index 79a954607b373b3ac279b89fe8048108702c03ae..7a45d9005f1249ea858a56adbb9cbbe5a95f2e68 100644
--- a/src/sbbs3/execmisc.cpp
+++ b/src/sbbs3/execmisc.cpp
@@ -38,33 +38,9 @@
 #include "sbbs.h"
 #include "cmdshell.h"
 
-/* Return true if connected */
-bool socket_check(SOCKET sock)
-{
-	char	ch;
-	int		i;
-	fd_set	socket_set;
-	struct	timeval tv;
-
-	FD_ZERO(&socket_set);
-	FD_SET(sock,&socket_set);
-
-	tv.tv_sec=0;
-	tv.tv_usec=0;
-
-	i=select(sock+1,&socket_set,NULL,NULL,&tv);
-	if(i==SOCKET_ERROR)
-		return(false);
-
-	if(i==0 || recv(sock,&ch,1,MSG_PEEK)==1) 
-		return(true);
-
-	return(false);
-}
-
 int sbbs_t::exec_misc(csi_t* csi, char *path)
 {
-	char	str[512],tmp[512],rsp[512],buf[1025],ch,*p,**pp,**pp1,**pp2;
+	char	str[512],tmp[512],buf[1025],ch,op,*p,**pp,**pp1,**pp2;
 	ushort	w;
 	uint 	i,j;
 	long	l,*lp,*lp1,*lp2;
@@ -88,6 +64,8 @@ int sbbs_t::exec_misc(csi_t* csi, char *path)
 					csi->ip+=4;
 					return(0);
 				case VAR_PRINTF:
+				case VAR_PRINTF_LOCAL:
+					op=*(csi->ip-1);
 					strcpy(str,(char*)csi->ip);
 					while(*(csi->ip++));	/* Find NULL */
 					j=*(csi->ip++); 		/* total args */
@@ -103,7 +81,10 @@ int sbbs_t::exec_misc(csi_t* csi, char *path)
 							arglist[i]=*(char **)vp;
 						csi->ip+=4; }
 					vsprintf(tmp,str,(char*)arglist);
-					putmsg(cmdstr(tmp,path,csi->str,buf),P_SAVEATR|P_NOABORT);
+					if(op==VAR_PRINTF)
+						putmsg(cmdstr(tmp,path,csi->str,buf),P_SAVEATR|P_NOABORT);
+					else
+						lputs(cmdstr(tmp,path,csi->str,buf));
 					return(0);
 				case SHOW_VARS:
 					bprintf("shell     str=(%08lX) %s\r\n"
@@ -1441,302 +1422,7 @@ int sbbs_t::exec_misc(csi_t* csi, char *path)
 					return(0); }
 
 		case CS_NET_FUNCTION:
-			switch(*(csi->ip++)) {	/* sub-op-code stored as next byte */
-				case CS_SOCKET_OPEN:
-					lp=getintvar(csi,*(long *)csi->ip);
-					csi->ip+=4;
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-					if(csi->sockets>=MAX_SOCKETS)
-						return(0);
-					if(lp!=NULL) {
-
-						SOCKET sock=open_socket(SOCK_STREAM);
-						if(sock!=INVALID_SOCKET) {
-
-							SOCKADDR_IN	addr;
-
-							memset(&addr,0,sizeof(addr));
-							addr.sin_addr.s_addr = htonl(cfg.startup->telnet_interface);
-							addr.sin_family = AF_INET;
-
-							if((i=bind(sock, (struct sockaddr *) &addr, sizeof (addr)))!=0) {
-								csi->socket_error=ERROR_VALUE;
-								close_socket(sock);
-								return(0);
-							}
-
-							*lp=sock;
-
-							for(i=0;i<csi->sockets;i++)
-								if(!csi->socket[i])
-									break;
-							csi->socket[i]=*lp;
-							if(i==csi->sockets)
-								csi->sockets++;
-							csi->logic=LOGIC_TRUE; 
-						} 
-					}
-					return(0);
-				case CS_SOCKET_CLOSE:
-					lp=getintvar(csi,*(long *)csi->ip);
-					csi->ip+=4;
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-					if(lp && *lp) {
-						csi->logic=close_socket((SOCKET)*lp);
-						csi->socket_error=ERROR_VALUE;
-						for(i=0;i<csi->sockets;i++)
-							if(csi->socket[i]==*lp)
-								csi->socket[i]=0; 
-						*lp=0;
-					}
-					return(0);
-				case CS_SOCKET_CHECK:
-					lp=getintvar(csi,*(long *)csi->ip);
-					csi->ip+=4;
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-
-					if(lp==NULL || *lp==INVALID_SOCKET) 
-						return(0);
-
-					if(socket_check(*lp)==true)
-						csi->logic=LOGIC_TRUE;
-					else
-						csi->socket_error=ERROR_VALUE;
-						
-					return(0);
-				case CS_SOCKET_CONNECT:
-					lp=getintvar(csi,*(long *)csi->ip);		/* socket */
-					csi->ip+=4;
-
-					pp=getstrvar(csi,*(long *)csi->ip);		/* address */
-					csi->ip+=4;
-
-					w=*(ushort *)csi->ip;					/* port */
-					csi->ip+=2;
-
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-
-					if(!lp || !*lp || !pp || !*pp || !w)
-						return(0);
-
-					ulong ip_addr;
-
-					if((ip_addr=resolve_ip(*pp))==0)
-						return(0);
-
-					SOCKADDR_IN	addr;
-
-					memset(&addr,0,sizeof(addr));
-					addr.sin_addr.s_addr = ip_addr;
-					addr.sin_family = AF_INET;
-					addr.sin_port   = htons(w);
-
-					if((i=connect(*lp, (struct sockaddr *)&addr, sizeof(addr)))!=0) {
-						csi->socket_error=ERROR_VALUE;
-						return(0);
-					}
-					csi->logic=LOGIC_TRUE;
-					return(0);
-				case CS_SOCKET_ACCEPT:
-					lp1=getintvar(csi,*(long *)csi->ip);		/* socket */
-					csi->ip+=4;
-					csi->socket_error=0;
-					/* TODO */
-					return(0);
-				case CS_SOCKET_NREAD:
-					lp1=getintvar(csi,*(long *)csi->ip);		/* socket */
-					csi->ip+=4;
-					lp2=getintvar(csi,*(long *)csi->ip);		/* var */
-					csi->ip+=4;
-
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-
-					if(!lp1 || !lp2)
-						return(0);
-
-					if(ioctlsocket(*lp1, FIONREAD, (ulong*)lp2)==0) 
-						csi->logic=LOGIC_TRUE;
-					else
-						csi->socket_error=ERROR_VALUE;
-					return(0);
-				case CS_SOCKET_PEEK:
-				case CS_SOCKET_READ:
-					lp=getintvar(csi,*(long *)csi->ip);			/* socket */
-					csi->ip+=4;
-					pp=getstrvar(csi,*(long *)csi->ip);			/* buffer */
-					csi->ip+=4;
-					w=*(ushort *)csi->ip;						/* length */
-					csi->ip+=2;					
-
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-
-					if(!lp || !pp)
-						return(0);
-
-					if(w<1 || w>sizeof(buf)-1)
-						w=sizeof(buf)-1;
-
-					if((i=recv(*lp,buf,w
-						,*(csi->ip-13)==CS_SOCKET_PEEK ? MSG_PEEK : 0))>0) {
-						csi->logic=LOGIC_TRUE;
-						buf[i]=0;
-						if(csi->etx) {
-							p=strchr(buf,csi->etx);
-							if(p) *p=0; 
-						}
-						*pp=copystrvar(csi,*pp,buf); 
-					} else
-						csi->socket_error=ERROR_VALUE;
-					return(0);
-				case CS_SOCKET_WRITE:	
-					lp=getintvar(csi,*(long *)csi->ip);			/* socket */
-					csi->ip+=4;
-					pp=getstrvar(csi,*(long *)csi->ip);			/* buffer */
-					csi->ip+=4;
-
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-
-					if(!lp || !pp || !(*pp))
-						return(0);
-
-					if(send(*lp,*pp,strlen(*pp),0)>0)
-						csi->logic=LOGIC_TRUE;
-					else
-						csi->socket_error=ERROR_VALUE;
-					return(0);
-
-				case CS_FTP_LOGIN:
-					lp=getintvar(csi,*(long *)csi->ip);			/* socket */
-					csi->ip+=4;
-					pp1=getstrvar(csi,*(long *)csi->ip);		/* username */
-					csi->ip+=4;
-					pp2=getstrvar(csi,*(long *)csi->ip);		/* password */
-					csi->ip+=4;
-
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-
-					if(!lp || !pp1 || !pp2)
-						return(0);
-
-					if(!ftp_cmd(csi,*lp,NULL,rsp))
-						return(0);
-
-					if(atoi(rsp)!=220)
-						return(0);
-
-					sprintf(str,"USER %s",*pp1);
-
-					if(!ftp_cmd(csi,*lp,str,rsp))
-						return(0);
-					
-					if(atoi(rsp)==331) { /* Password needed */
-						sprintf(str,"PASS %s\r\n",*pp2);
-						if(!ftp_cmd(csi,*lp,str,rsp))
-							return(0);
-					}
-
-					if(atoi(rsp)==230)	/* Login successful */
-						csi->logic=LOGIC_TRUE;
-					return(0);
-
-				case CS_FTP_LOGOUT:
-					lp=getintvar(csi,*(long *)csi->ip);			/* socket */
-					csi->ip+=4;
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-
-					if(!lp)
-						return(0);
-
-					if(!ftp_cmd(csi,*lp,"QUIT",rsp))
-						return(0);
-
-					if(atoi(rsp)==221)	/* Logout successful */
-						csi->logic=LOGIC_TRUE;
-					return(0);
-
-				case CS_FTP_PWD:
-					lp=getintvar(csi,*(long *)csi->ip);			/* socket */
-					csi->ip+=4;
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-					if(!lp)
-						return(0);
-
-					if(!ftp_cmd(csi,*lp,"PWD",rsp))
-						return(0);
-
-					if(atoi(rsp)==257)	/* pathname */
-						csi->logic=LOGIC_TRUE;
-					return(0);
-
-				case CS_FTP_CWD:
-					lp=getintvar(csi,*(long *)csi->ip);			/* socket */
-					csi->ip+=4;
-					pp=getstrvar(csi,*(long *)csi->ip);			/* path */
-					csi->ip+=4;
-
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-					if(!lp || !pp)
-						return(0);
-					
-					sprintf(str,"CWD %s",*pp);
-					if(!ftp_cmd(csi,*lp,str,rsp))
-						return(0);
-
-					if(atoi(rsp)==250)
-						csi->logic=LOGIC_TRUE;
-
-					return(0);
-
-				case CS_FTP_DIR:
-					lp=getintvar(csi,*(long *)csi->ip);			/* socket */
-					csi->ip+=4;
-					pp=getstrvar(csi,*(long *)csi->ip);			/* path */
-					csi->ip+=4;
-
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-
-					if(!lp || !pp)
-						return(0);
-
-					if(ftp_get(csi,*lp,*pp,NULL /* unused */, true /* DIR */)==true)
-						csi->logic=LOGIC_TRUE;
-	
-					return(0);
-
-				case CS_FTP_GET:
-					lp=getintvar(csi,*(long *)csi->ip);			/* socket */
-					csi->ip+=4;
-					pp1=getstrvar(csi,*(long *)csi->ip);		/* src path */
-					csi->ip+=4;
-					pp2=getstrvar(csi,*(long *)csi->ip);		/* dest path */
-					csi->ip+=4;
-
-					csi->logic=LOGIC_FALSE;
-					csi->socket_error=0;
-
-					if(!lp || !pp1 || !pp2)
-						return(0);
-
-					if(ftp_get(csi,*lp,*pp1,*pp2)==true)
-						csi->logic=LOGIC_TRUE;
-					
-					return(0);
-
-				default:
-					errormsg(WHERE,ERR_CHK,"net sub-instruction",*(csi->ip-1));
-					return(0); }
+			return(exec_net(csi));
 
 		case CS_SWITCH:
 			lp=getintvar(csi,*(long *)csi->ip);
@@ -1856,258 +1542,3 @@ int sbbs_t::exec_misc(csi_t* csi, char *path)
 			return(0); }
 }
 
-/* FTP Command/Response function */
-bool sbbs_t::ftp_cmd(csi_t* csi, SOCKET sock, char* cmdsrc, char* rsp)
-{
-	char	cmd[512];
-	int		len;
-
-	if(cmdsrc!=NULL) {
-		sprintf(cmd,"%s\r\n",cmdsrc);
-
-		if(csi->ftp_mode&CS_FTP_ECHO_CMD)
-			bputs(cmd);
-
-		len=strlen(cmd);
-		if(send(sock,cmd,len,0)!=len) {
-			csi->socket_error=ERROR_VALUE;
-			return(FALSE);
-		}
-	}
-
-	if(rsp!=NULL) {
-
-		int		rd;
-		char	ch;
-
-		while(1) {
-			rd=0;
-
-			while(rd<500) {
-
-				if(!online)
-					return(FALSE);
-
-				if(recv(sock, &ch, 1, 0)!=1) {
-					csi->socket_error=ERROR_VALUE;
-					return(FALSE);
-				}
-
-				if(ch=='\n' && rd>=1) 
-					break;
-
-				rsp[rd++]=ch;
-			}
-			rsp[rd-1]=0;
-			if(csi->ftp_mode&CS_FTP_ECHO_RSP)
-				bprintf("%s\r\n",rsp);
-			if(rsp[0]!=' ' && rsp[3]!='-')
-				break;
-		}
-	}		
-
-	return(TRUE);
-}
-
-SOCKET sbbs_t::ftp_data_sock(csi_t* csi, SOCKET ctrl_sock, SOCKADDR_IN* addr)
-{
-	char	cmd[512];
-	char	rsp[512];
-	char*	p;
-	int		addr_len;
-	SOCKET	data_sock;
-	int		ip_b[4];
-	int		port_b[2];
-	union {
-		DWORD	dw;
-		BYTE	b[sizeof(DWORD)];
-	} ip_addr;
-	union {
-		WORD	w;
-		BYTE	b[sizeof(WORD)];
-	} port;
-
-	if((data_sock=open_socket(SOCK_STREAM))==INVALID_SOCKET) {
-		csi->socket_error=ERROR_VALUE;
-		return(INVALID_SOCKET);
-	}
-
-	memset(addr,0,sizeof(addr));
-	addr->sin_addr.s_addr = htonl(cfg.startup->telnet_interface);
-	addr->sin_family = AF_INET;
-
-	if(bind(data_sock, (struct sockaddr *)addr,sizeof(SOCKADDR_IN))!= 0) {
-		csi->socket_error=ERROR_VALUE;
-		close_socket(data_sock);
-		return(INVALID_SOCKET);
-	}
-	
-	if(csi->ftp_mode&CS_FTP_PASV) {
-
-		if(!ftp_cmd(csi,ctrl_sock,"PASV",rsp) 
-			|| atoi(rsp)!=227 /* PASV response */) {
-			close_socket(data_sock);
-			return(INVALID_SOCKET);
-		}
-
-		p=strchr(rsp,'(');
-		if(p==NULL) {
-			close_socket(data_sock);
-			return(INVALID_SOCKET);
-		}
-		p++;
-		if(sscanf(p,"%u,%u,%u,%u,%u,%u"
-			,&ip_b[0],&ip_b[1],&ip_b[2],&ip_b[3]
-			,&port_b[0],&port_b[1])!=6) {
-			close_socket(data_sock);
-			return(INVALID_SOCKET);
-		}
-
-		ip_addr.b[0]=ip_b[0];	ip_addr.b[1]=ip_b[1];
-		ip_addr.b[2]=ip_b[2];	ip_addr.b[3]=ip_b[3];
-		port.b[0]=port_b[0];	port.b[1]=port_b[1];
-
-		addr->sin_addr.s_addr=ip_addr.dw;
-		addr->sin_port=port.w;
-
-	} else {	/* Normal (Active) FTP */
-
-		addr_len=sizeof(SOCKADDR_IN);
-		if(getsockname(data_sock, (struct sockaddr *)addr,&addr_len)!=0) {
-			csi->socket_error=ERROR_VALUE;
-			close_socket(data_sock);
-			return(INVALID_SOCKET);
-		} 
-
-		if(listen(data_sock, 1)!= 0) {
-			csi->socket_error=ERROR_VALUE;
-			close_socket(data_sock);
-			return(INVALID_SOCKET);
-		}
-
-		ip_addr.dw=ntohl(addr->sin_addr.s_addr);
-		port.w=ntohs(addr->sin_port);
-		sprintf(cmd,"PORT %u,%u,%u,%u,%hu,%hu"
-			,ip_addr.b[3]
-			,ip_addr.b[2]
-			,ip_addr.b[1]
-			,ip_addr.b[0]
-			,port.b[1]
-			,port.b[0]
-			);
-
-		if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
-			|| atoi(rsp)!=200 /* PORT response */) {
-			close_socket(data_sock);
-			return(INVALID_SOCKET);
-		}
-
-	}
-
-	return(data_sock);
-}
-
-/* FTP Command/Response function */
-bool sbbs_t::ftp_get(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest, bool dir)
-{
-	char	cmd[512];
-	char	rsp[512];
-	char	buf[4097];
-	int		rd;
-	int		addr_len;
-	ulong	total=0;
-	SOCKET	data_sock;
-	SOCKADDR_IN	addr;
-	FILE*	fp=NULL;
-
-	if((data_sock=ftp_data_sock(csi, ctrl_sock, &addr))==INVALID_SOCKET)
-		return(false);
-
-	if(dir)
-		sprintf(cmd,"LIST %s",src);
-	else
-		sprintf(cmd,"RETR %s",src);
-
-	if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
-		|| atoi(rsp)!=150 /* Open data connection */) {
-		close_socket(data_sock);
-		return(false);
-	}
-
-	if(csi->ftp_mode&CS_FTP_PASV) {
-
-#if 0	// Debug
-		bprintf("Connecting to %s:%hd\r\n"
-			,inet_ntoa(addr.sin_addr)
-			,ntohs(addr.sin_port));
-#endif
-
-		if(connect(data_sock,(struct sockaddr *)&addr,sizeof(addr))!=0) {
-			csi->socket_error=ERROR_VALUE;
-			close_socket(data_sock);
-			return(false);
-		}
-
-	} else {	/* Normal (Active) FTP */
-
-		SOCKET accept_sock;
-
-		addr_len=sizeof(addr);
-		if((accept_sock=accept(data_sock,(struct sockaddr*)&addr,&addr_len))
-			==INVALID_SOCKET) {
-			csi->socket_error=ERROR_VALUE;
-			closesocket(data_sock);
-			return(false);
-		}
-
-		if(cfg.startup->socket_open!=NULL)
-			cfg.startup->socket_open(TRUE);
-
-		close_socket(data_sock);
-		data_sock=accept_sock;
-	}
-
-
-	if(!dir)
-		if((fp=fopen(dest,"wb"))==NULL) {
-			close_socket(data_sock);
-			return(false);
-		}
-
-	while(online) {
-
-		if(!socket_check(ctrl_sock))
-			break; /* Control connection lost */
-
-		if((rd=recv(data_sock, buf, sizeof(buf)-1, 0))<1)
-			break;
-
-		if(dir) {
-			buf[rd]=0;
-			bputs(buf);
-		} else
-			fwrite(buf,1,rd,fp);
-
-		total+=rd;
-		
-		if(!dir && csi->ftp_mode&CS_FTP_HASH)
-			outchar('#');
-	}
-
-	if(!dir && csi->ftp_mode&CS_FTP_HASH) {
-		CRLF;
-	}
-
-	if(fp!=NULL)
-		fclose(fp);
-
-	close_socket(data_sock);
-
-	if(!ftp_cmd(csi,ctrl_sock,NULL,rsp) 
-		|| atoi(rsp)!=226 /* Download complete */)
-		return(false);
-
-	bprintf("ftp: %lu bytes received.\r\n", total);
-
-	return(true);
-}