Annotation of sbbs/src/sbbs3/telgate.cpp, revision 1.1.1.2

1.1       root        1: /* telgate.cpp */
                      2: 
                      3: /* Synchronet telnet gateway routines */
                      4: 
1.1.1.2 ! root        5: /* $Id: telgate.cpp,v 1.30 2011/08/27 21:22:07 rswindell Exp $ */
1.1       root        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:  *                                                                                                                                                     *
1.1.1.2 ! root       11:  * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html         *
1.1       root       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: void sbbs_t::telnet_gate(char* destaddr, ulong mode)
                     42: {
                     43:        char*   p;
                     44:        uchar   buf[512];
                     45:        int             i;
                     46:        int             rd;
                     47:        uint    attempts;
                     48:        ulong   l;
                     49:        bool    gotline;
                     50:        ushort  port;
                     51:        ulong   ip_addr;
                     52:        ulong   save_console;
                     53:        SOCKET  remote_socket;
                     54:        SOCKADDR_IN     addr;
                     55: 
                     56:        if(mode&TG_RLOGIN)
                     57:                port=513;
                     58:        else
                     59:                port=IPPORT_TELNET;
                     60: 
                     61:        p=strchr(destaddr,':');
                     62:        if(p!=NULL) {
                     63:                *p=0;
                     64:                port=atoi(p+1);
                     65:        }
                     66: 
                     67:        ip_addr=resolve_ip(destaddr);
                     68:        if(ip_addr==INADDR_NONE) {
                     69:                lprintf(LOG_NOTICE,"!TELGATE Failed to resolve address: %s",destaddr);
                     70:                bprintf("!Failed to resolve address: %s\r\n",destaddr);
                     71:                return;
                     72:        }
                     73: 
                     74:     if((remote_socket = open_socket(SOCK_STREAM, client.protocol)) == INVALID_SOCKET) {
                     75:                errormsg(WHERE,ERR_OPEN,"socket",0);
                     76:                return;
                     77:        }
                     78: 
                     79:        memset(&addr,0,sizeof(addr));
                     80:        addr.sin_addr.s_addr = htonl(startup->telnet_interface);
                     81:        addr.sin_family = AF_INET;
                     82: 
                     83:        if((i=bind(remote_socket, (struct sockaddr *) &addr, sizeof (addr)))!=0) {
                     84:                lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) binding to socket %d",i, ERROR_VALUE, remote_socket);
                     85:                bprintf("!ERROR %d (%d) binding to socket\r\n",i, ERROR_VALUE);
                     86:                close_socket(remote_socket);
                     87:                return;
                     88:        }
                     89: 
                     90:        memset(&addr,0,sizeof(addr));
                     91:        addr.sin_addr.s_addr = ip_addr;
                     92:        addr.sin_family = AF_INET;
                     93:        addr.sin_port   = htons(port);
                     94: 
                     95:        if((i=connect(remote_socket, (struct sockaddr *)&addr, sizeof(addr)))!=0) {
                     96:                lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) connecting to server: %s"
                     97:                        ,i,ERROR_VALUE, destaddr);
                     98:                bprintf("!ERROR %d (%d) connecting to server: %s\r\n"
                     99:                        ,i,ERROR_VALUE, destaddr);
                    100:                close_socket(remote_socket);
                    101:                return;
                    102:        }
                    103: 
                    104:        l=1;
                    105: 
                    106:        if((i = ioctlsocket(remote_socket, FIONBIO, &l))!=0) {
                    107:                lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) disabling socket blocking"
                    108:                        ,i, ERROR_VALUE);
                    109:                close_socket(remote_socket);
                    110:                return;
                    111:        }
                    112: 
1.1.1.2 ! root      113:        lprintf(LOG_INFO,"Node %d %s gate to %s port %u on socket %d"
1.1       root      114:                ,cfg.node_num
                    115:                ,mode&TG_RLOGIN ? "RLogin" : "Telnet"
                    116:                ,destaddr,port,remote_socket);
                    117: 
                    118:        if(!(mode&TG_CTRLKEYS))
                    119:                console|=CON_RAW_IN;
                    120: 
                    121:        if(mode&TG_RLOGIN) {
                    122:                p=(char*)buf;
                    123:                *(p++)=0;
                    124:                p+=sprintf(p,"%s",useron.alias);
                    125:                p++;    // Add NULL
                    126:                p+=sprintf(p,"%s",useron.name);
                    127:                p++;    // Add NULL
                    128:                p+=sprintf(p,"%s/57600",terminal);
                    129:                p++;    // Add NULL
                    130:                l=p-(char*)buf;
                    131:                sendsocket(remote_socket,(char*)buf,l);
                    132:        }
                    133: 
                    134:        /* This is required for gating to Unix telnetd */
                    135:        if(mode&TG_NOTERMTYPE)
1.1.1.2 ! root      136:                request_telnet_opt(TELNET_DONT,TELNET_TERM_TYPE, 3000); // Re-negotiation of terminal type
1.1       root      137: 
                    138:        /* Text/NVT mode by default */
1.1.1.2 ! root      139:        request_telnet_opt(TELNET_DONT,TELNET_BINARY_TX, 3000);
        !           140: 
        !           141:        if(mode&(TG_PASSTHRU|TG_RLOGIN))
        !           142:                telnet_mode|=TELNET_MODE_GATE;  // Pass-through telnet commands
1.1       root      143: 
                    144:        while(online) {
                    145:                if(!(mode&TG_NOCHKTIME))
                    146:                        gettimeleft();
                    147:                rd=RingBufRead(&inbuf,buf,sizeof(buf));
                    148:                if(rd) {
                    149: #if 0
                    150:                        if(memchr(buf,TELNET_IAC,rd)) {
                    151:                                char dump[2048];
                    152:                                dump[0];
                    153:                                p=dump;
                    154:                                for(int i=0;i<rd;i++)
                    155:                                        p+=sprintf(p,"%u ",buf[i]);
                    156:                                lprintf(LOG_DEBUG,"Node %d Telnet cmd from client: %s", cfg.node_num, dump);
                    157:                        }
                    158: #endif
                    159:                        if(telnet_remote_option[TELNET_BINARY_TX]!=TELNET_WILL) {
                    160:                                if(*buf==0x1d) { // ^]
                    161:                                        save_console=console;
                    162:                                        console&=~CON_RAW_IN;   // Allow Ctrl-U/Ctrl-P
                    163:                                        CRLF;
                    164:                                        while(online) {
                    165:                                                SYNC;
                    166:                                                mnemonics("\1n\r\n\1h\1bTelnet Gate: \1y~D\1wisconnect, "
                    167:                                                        "\1y~E\1wcho toggle, \1y~L\1wist Users, \1y~P\1wrivate message, "
                    168:                                                        "\1y~Q\1wuit: ");
                    169:                                                switch(getkeys("DELPQ",0)) {
                    170:                                                        case 'D':
                    171:                                                                closesocket(remote_socket);
                    172:                                                                break;
                    173:                                                        case 'E':
                    174:                                                                mode^=TG_ECHO;
                    175:                                                                bprintf(text[EchoIsNow]
                    176:                                                                        ,mode&TG_ECHO
                    177:                                                                        ? text[ON]:text[OFF]);
                    178:                                                                continue;
                    179:                                                        case 'L':
                    180:                                                                whos_online(true);
                    181:                                                                continue;
                    182:                                                        case 'P':
                    183:                                                                nodemsg();
                    184:                                                                continue;
                    185:                                                }
                    186:                                                break;
                    187:                                        }
                    188:                                        attr(LIGHTGRAY);
                    189:                                        console=save_console;
                    190:                                }
                    191:                                else if(*buf<' ' && mode&TG_CTRLKEYS)
                    192:                                        handle_ctrlkey(*buf, K_NONE);
                    193:                                gotline=false;
                    194:                                if(mode&TG_LINEMODE && buf[0]!='\r') {
                    195:                                        ungetkey(buf[0]);
                    196:                                        l=K_CHAT;
                    197:                                        if(!(mode&TG_ECHO))
                    198:                                                l|=K_NOECHO;
                    199:                                        rd=getstr((char*)buf,sizeof(buf)-1,l);
                    200:                                        if(!rd)
                    201:                                                continue;
                    202:                                        strcat((char*)buf,crlf);
                    203:                                        rd+=2;
                    204:                                        gotline=true;
                    205:                                }
                    206:                                if(mode&TG_CRLF && buf[rd-1]=='\r')
                    207:                                        buf[rd++]='\n';
                    208:                                if(!gotline && mode&TG_ECHO) {
                    209:                                        RingBufWrite(&outbuf,buf,rd);
                    210:                                }
                    211:                        }
                    212:                        for(attempts=0;attempts<60 && online; attempts++) /* added retry loop here, Jan-20-2003 */
                    213:                        {
                    214:                                if((i=sendsocket(remote_socket,(char*)buf,rd))>=0)
                    215:                                        break;
                    216:                                if(ERROR_VALUE!=EWOULDBLOCK)
                    217:                                        break;
                    218:                                mswait(500);
                    219:                        } 
                    220:                        if(i<0) {
                    221:                                lprintf(LOG_NOTICE,"!TELGATE ERROR %d sending on socket %d",ERROR_VALUE,remote_socket);
                    222:                                break;
                    223:                        }
                    224:                }
                    225:                rd=recv(remote_socket,(char*)buf,sizeof(buf),0);
                    226:                if(rd<0) {
                    227:                        if(ERROR_VALUE==EWOULDBLOCK) {
                    228:                                if(mode&TG_NODESYNC) {
                    229:                                        SYNC;
                    230:                                } else {
                    231:                                        // Check if the node has been interrupted
                    232:                                        getnodedat(cfg.node_num,&thisnode,0);
                    233:                                        if(thisnode.misc&NODE_INTR)
                    234:                                                break;
                    235:                                }
                    236:                                YIELD();
                    237:                                continue;
                    238:                        }
                    239:                        lprintf(LOG_NOTICE,"!TELGATE ERROR %d receiving on socket %d",ERROR_VALUE,remote_socket);
                    240:                        break;
                    241:                }
                    242:                if(!rd) {
                    243:                        lprintf(LOG_INFO,"Node %d Telnet gate disconnected",cfg.node_num);
                    244:                        break;
                    245:                }
                    246: #if 0
                    247:                if(memchr(buf,TELNET_IAC,rd)) {
                    248:                        char dump[2048];
                    249:                        dump[0];
                    250:                        p=dump;
                    251:                        for(int i=0;i<rd;i++)
                    252:                                p+=sprintf(p,"%u ",buf[i]);
1.1.1.2 ! root      253:                        lprintf(LOG_DEBUG,"Node %d Telnet cmd from server: %s", cfg.node_num, dump);
1.1       root      254:                }
                    255: #endif
                    256:                RingBufWrite(&outbuf,buf,rd);
                    257:        }
                    258:        console&=~CON_RAW_IN;
                    259:        telnet_mode&=~TELNET_MODE_GATE;
                    260: 
                    261:        /* Disable Telnet Terminal Echo */
                    262:        request_telnet_opt(TELNET_WILL,TELNET_ECHO);
                    263: 
                    264:        close_socket(remote_socket);
                    265: 
                    266:        lprintf(LOG_INFO,"Node %d Telnet gate to %s finished",cfg.node_num,destaddr);
                    267: }
                    268: 

unix.superglobalmegacorp.com

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