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

1.1     ! root        1: /* telgate.cpp */
        !             2: 
        !             3: /* Synchronet telnet gateway routines */
        !             4: 
        !             5: /* $Id: telgate.cpp,v 1.28 2005/10/13 06:49:14 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 2005 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: 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: 
        !           113:        lprintf(LOG_INFO,"Node %d %s gate to %s port %d on socket %d"
        !           114:                ,cfg.node_num
        !           115:                ,mode&TG_RLOGIN ? "RLogin" : "Telnet"
        !           116:                ,destaddr,port,remote_socket);
        !           117: 
        !           118:        if(mode&(TG_PASSTHRU|TG_RLOGIN))
        !           119:                telnet_mode|=TELNET_MODE_GATE;  // Pass-through telnet commands
        !           120: 
        !           121:        if(!(mode&TG_CTRLKEYS))
        !           122:                console|=CON_RAW_IN;
        !           123: 
        !           124:        if(mode&TG_RLOGIN) {
        !           125:                p=(char*)buf;
        !           126:                *(p++)=0;
        !           127:                p+=sprintf(p,"%s",useron.alias);
        !           128:                p++;    // Add NULL
        !           129:                p+=sprintf(p,"%s",useron.name);
        !           130:                p++;    // Add NULL
        !           131:                p+=sprintf(p,"%s/57600",terminal);
        !           132:                p++;    // Add NULL
        !           133:                l=p-(char*)buf;
        !           134:                sendsocket(remote_socket,(char*)buf,l);
        !           135:        }
        !           136: 
        !           137:        /* This is required for gating to Unix telnetd */
        !           138:        if(mode&TG_NOTERMTYPE)
        !           139:                request_telnet_opt(TELNET_DONT,TELNET_TERM_TYPE);       // Re-negotiation of terminal type
        !           140: 
        !           141:        /* Text/NVT mode by default */
        !           142:        request_telnet_opt(TELNET_DONT,TELNET_BINARY_TX);
        !           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]);
        !           253:                        lprintf(LOG_DEBUG,"Node %d Telnet cmd from remote: %s", cfg.node_num, dump);
        !           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.