Annotation of sbbs/sbbs3/telgate.cpp, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.