|
|
1.1 ! root 1: /* telgate.cpp */ ! 2: ! 3: /* Synchronet telnet gateway routines */ ! 4: ! 5: /* $Id: telgate.cpp,v 1.6 2000/10/31 04:14:51 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include "sbbs.h" ! 39: #include "telnet.h" ! 40: ! 41: extern "C" { ! 42: int open_socket(int); ! 43: int close_socket(int); ! 44: } ! 45: ! 46: u_long resolve_ip(char *addr) ! 47: { ! 48: HOSTENT* host; ! 49: ! 50: if(isdigit(addr[0])) ! 51: return(inet_addr(addr)); ! 52: if ((host=gethostbyname(addr))==NULL) ! 53: return(0); ! 54: return(*((ulong*)host->h_addr_list[0])); ! 55: } ! 56: ! 57: void sbbs_t::telnet_gate(char* destaddr, ulong mode) ! 58: { ! 59: char* p; ! 60: char str[128]; ! 61: uchar buf[512]; ! 62: int i; ! 63: int rd; ! 64: ulong l; ! 65: bool gotline; ! 66: ushort port; ! 67: ulong ip_addr; ! 68: ulong save_console; ! 69: SOCKET remote_socket; ! 70: SOCKADDR_IN addr; ! 71: ! 72: if(mode&TG_RLOGIN) ! 73: port=513; ! 74: else ! 75: port=IPPORT_TELNET; ! 76: ! 77: p=strchr(destaddr,':'); ! 78: if(p!=NULL) { ! 79: *p=0; ! 80: port=atoi(p+1); ! 81: } ! 82: ! 83: ip_addr=resolve_ip(destaddr); ! 84: if(!ip_addr) { ! 85: lprintf("!Failed to resolve address: %s",destaddr); ! 86: bprintf("!Failed to resolve address: %s\n",destaddr); ! 87: return; ! 88: } ! 89: ! 90: if((remote_socket = open_socket(SOCK_STREAM)) == INVALID_SOCKET) { ! 91: errormsg(WHERE,ERR_OPEN,"socket",0); ! 92: return; ! 93: } ! 94: ! 95: memset(&addr,0,sizeof(addr)); ! 96: addr.sin_addr.s_addr = htonl(cfg.startup->telnet_interface); ! 97: addr.sin_family = AF_INET; ! 98: ! 99: if((i=bind(remote_socket, (struct sockaddr *) &addr, sizeof (addr)))!=0) { ! 100: close_socket(remote_socket); ! 101: lprintf("!ERROR %d (%d) binding to socket %d",i, ERROR_VALUE, socket); ! 102: bprintf("!ERROR %d (%d) binding to socket\n",i, ERROR_VALUE); ! 103: return; ! 104: } ! 105: ! 106: memset(&addr,0,sizeof(addr)); ! 107: addr.sin_addr.s_addr = ip_addr; ! 108: addr.sin_family = AF_INET; ! 109: addr.sin_port = htons(port); ! 110: ! 111: if((i=connect(remote_socket, (struct sockaddr *)&addr, sizeof(addr)))!=0) { ! 112: close_socket(remote_socket); ! 113: lprintf("!ERROR %d (%d) connecting to server: %s" ! 114: ,i,ERROR_VALUE, destaddr); ! 115: bprintf("!ERROR %d (%d) connecting to server: %s\n" ! 116: ,i,ERROR_VALUE, destaddr); ! 117: return; ! 118: } ! 119: ! 120: l=1; ! 121: ! 122: if((i = ioctlsocket(remote_socket, FIONBIO, &l))!=0) { ! 123: close_socket(remote_socket); ! 124: lprintf("!ERROR %d (%d) disabling socket blocking" ! 125: ,i, ERROR_VALUE); ! 126: return; ! 127: } ! 128: ! 129: lprintf("Node %d %s gate to %s port %d on socket %d" ! 130: ,cfg.node_num ! 131: ,mode&TG_RLOGIN ? "RLogin" : "Telnet" ! 132: ,destaddr,port,remote_socket); ! 133: ! 134: if(mode&(TG_PASSTHRU|TG_RLOGIN)) ! 135: telnet_mode|=TELNET_MODE_GATE; // Pass-through telnet commands ! 136: ! 137: if(!(mode&TG_CTRLKEYS)) ! 138: console|=CON_RAW_IN; ! 139: ! 140: if(mode&TG_RLOGIN) { ! 141: p=(char*)buf; ! 142: *(p++)=0; ! 143: strcpy(p,useron.alias); ! 144: p+=strlen(p)+1; ! 145: strcpy(p,useron.name); ! 146: p+=strlen(p)+1; ! 147: strcpy(p,"vt100/57600"); ! 148: p+=strlen(p)+1; ! 149: l=p-(char*)buf; ! 150: send(remote_socket,(char*)buf,l,0); ! 151: } ! 152: ! 153: while(online) { ! 154: gettimeleft(); ! 155: rd=RingBufRead(&inbuf,buf,sizeof(buf)); ! 156: if(rd) { ! 157: if(!(telnet_mode&TELNET_MODE_BIN_RX)) { ! 158: if(*buf==0x1d) { // ^] ! 159: save_console=console; ! 160: console&=~CON_RAW_IN; // Allow Ctrl-U/Ctrl-P ! 161: CRLF; ! 162: while(online) { ! 163: SYNC; ! 164: mnemonics("\1n\r\n\1h\1bTelnet Gate: \1y~D\1wisconnect, " ! 165: "\1y~E\1wcho toggle, \1y~L\1wist Users, \1y~P\1wrivate message, " ! 166: "\1y~Q\1wuit: "); ! 167: switch(getkeys("DELPQ",0)) { ! 168: case 'D': ! 169: closesocket(remote_socket); ! 170: break; ! 171: case 'E': ! 172: mode^=TG_ECHO; ! 173: bprintf(text[EchoIsNow] ! 174: ,mode&TG_ECHO ! 175: ? text[ON]:text[OFF]); ! 176: continue; ! 177: case 'L': ! 178: whos_online(true); ! 179: continue; ! 180: case 'P': ! 181: nodemsg(); ! 182: continue; ! 183: } ! 184: break; ! 185: } ! 186: attr(LIGHTGRAY); ! 187: console=save_console; ! 188: } ! 189: gotline=false; ! 190: if(mode&TG_LINEMODE && buf[0]!='\r') { ! 191: ungetkey(buf[0]); ! 192: l=K_CHAT; ! 193: if(!(mode&TG_ECHO)) ! 194: l|=K_NOECHO; ! 195: rd=getstr((char*)buf,sizeof(buf)-1,l); ! 196: if(!rd) ! 197: continue; ! 198: strcat((char*)buf,crlf); ! 199: rd+=2; ! 200: gotline=true; ! 201: } ! 202: if(mode&TG_CRLF && buf[rd-1]=='\r') ! 203: buf[rd++]='\n'; ! 204: if(!gotline && mode&TG_ECHO) { ! 205: RingBufWrite(&outbuf,buf,rd); ! 206: sem_post(&output_sem); ! 207: } ! 208: } ! 209: if((i=send(remote_socket,(char*)buf,rd,0))<0) { ! 210: lprintf("!TELGATE ERROR %d sending on socket %d",ERROR_VALUE,remote_socket); ! 211: break; ! 212: } ! 213: } ! 214: rd=recv(remote_socket,(char*)buf,sizeof(buf),0); ! 215: if(rd<0) { ! 216: if(ERROR_VALUE==EWOULDBLOCK) { ! 217: if(mode&TG_NODESYNC) { ! 218: SYNC; ! 219: } ! 220: mswait(1); ! 221: continue; ! 222: } ! 223: lprintf("!TELGATE ERROR %d receiving on socket %d",ERROR_VALUE,remote_socket); ! 224: break; ! 225: } ! 226: if(!rd) { ! 227: lprintf("Node %d Telnet gate disconnected",cfg.node_num); ! 228: break; ! 229: } ! 230: RingBufWrite(&outbuf,buf,rd); ! 231: sem_post(&output_sem); ! 232: } ! 233: console&=~CON_RAW_IN; ! 234: telnet_mode&=~TELNET_MODE_GATE; ! 235: ! 236: /* Disable Telnet Terminal Echo */ ! 237: sprintf(str,"%c%c%c",TELNET_IAC,TELNET_WILL,TELNET_ECHO); ! 238: putcom(str,3); ! 239: ! 240: close_socket(remote_socket); ! 241: ! 242: lprintf("Node %d Telnet gate to %s finished",cfg.node_num,destaddr); ! 243: } ! 244:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.