Annotation of sbbs/sbbs3/execnet.cpp, revision 1.1

1.1     ! root        1: /* execnet.cpp */
        !             2: 
        !             3: /* Synchronet command shell/module TCP/IP Network functions */
        !             4: 
        !             5: /* $Id: execnet.cpp,v 1.22 2003/10/24 21:46:55 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 2003 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 "cmdshell.h"
        !            40: 
        !            41: #define TIMEOUT_SOCK_READLINE  30      /* seconds */
        !            42: #define TIMEOUT_SOCK_LISTEN            30      /* seconds */
        !            43: #define TIMEOUT_FTP_RESPONSE   300     /* seconds */
        !            44: 
        !            45: int sbbs_t::exec_net(csi_t* csi)
        !            46: {
        !            47:        char    str[512],rsp[512],buf[1025],ch,*p,**pp,**pp1,**pp2;
        !            48:        ushort  w;
        !            49:        uint    i;
        !            50:        BOOL    rd;
        !            51:        long    *lp,*lp1,*lp2;
        !            52:        time_t  start;
        !            53: 
        !            54:        switch(*(csi->ip++)) {  /* sub-op-code stored as next byte */
        !            55:                case CS_SOCKET_OPEN:
        !            56:                        lp=getintvar(csi,*(long *)csi->ip);
        !            57:                        csi->ip+=4;
        !            58:                        csi->logic=LOGIC_FALSE;
        !            59:                        csi->socket_error=0;
        !            60:                        if(csi->sockets>=MAX_SOCKETS)
        !            61:                                return(0);
        !            62:                        if(lp!=NULL) {
        !            63: 
        !            64:                                SOCKET sock=open_socket(SOCK_STREAM);
        !            65:                                if(sock!=INVALID_SOCKET) {
        !            66: 
        !            67:                                        SOCKADDR_IN     addr;
        !            68: 
        !            69:                                        memset(&addr,0,sizeof(addr));
        !            70:                                        addr.sin_addr.s_addr = htonl(startup->telnet_interface);
        !            71:                                        addr.sin_family = AF_INET;
        !            72: 
        !            73:                                        if((i=bind(sock, (struct sockaddr *) &addr, sizeof (addr)))!=0) {
        !            74:                                                csi->socket_error=ERROR_VALUE;
        !            75:                                                close_socket(sock);
        !            76:                                                return(0);
        !            77:                                        }
        !            78: 
        !            79:                                        *lp=sock;
        !            80: 
        !            81:                                        for(i=0;i<csi->sockets;i++)
        !            82:                                                if(!csi->socket[i])
        !            83:                                                        break;
        !            84:                                        csi->socket[i]=*lp;
        !            85:                                        if(i==csi->sockets)
        !            86:                                                csi->sockets++;
        !            87:                                        csi->logic=LOGIC_TRUE; 
        !            88:                                } 
        !            89:                        }
        !            90:                        return(0);
        !            91:                case CS_SOCKET_CLOSE:
        !            92:                        lp=getintvar(csi,*(long *)csi->ip);
        !            93:                        csi->ip+=4;
        !            94:                        csi->logic=LOGIC_FALSE;
        !            95:                        csi->socket_error=0;
        !            96:                        if(lp && *lp) {
        !            97:                                csi->logic=close_socket((SOCKET)*lp);
        !            98:                                csi->socket_error=ERROR_VALUE;
        !            99:                                for(i=0;i<csi->sockets;i++)
        !           100:                                        if(csi->socket[i]==*lp)
        !           101:                                                csi->socket[i]=0; 
        !           102:                                *lp=0;
        !           103:                        }
        !           104:                        return(0);
        !           105:                case CS_SOCKET_CHECK:
        !           106:                        lp=getintvar(csi,*(long *)csi->ip);
        !           107:                        csi->ip+=4;
        !           108:                        csi->logic=LOGIC_FALSE;
        !           109:                        csi->socket_error=0;
        !           110: 
        !           111:                        if(lp==NULL || *lp==INVALID_SOCKET) 
        !           112:                                return(0);
        !           113: 
        !           114:                        if(socket_check(*lp,NULL,NULL,0)==TRUE)
        !           115:                                csi->logic=LOGIC_TRUE;
        !           116:                        else
        !           117:                                csi->socket_error=ERROR_VALUE;
        !           118:                                
        !           119:                        return(0);
        !           120:                case CS_SOCKET_CONNECT:
        !           121:                        lp=getintvar(csi,*(long *)csi->ip);             /* socket */
        !           122:                        csi->ip+=4;
        !           123: 
        !           124:                        pp=getstrvar(csi,*(long *)csi->ip);             /* address */
        !           125:                        csi->ip+=4;
        !           126: 
        !           127:                        w=*(ushort *)csi->ip;                                   /* port */
        !           128:                        csi->ip+=2;
        !           129: 
        !           130:                        csi->logic=LOGIC_FALSE;
        !           131:                        csi->socket_error=0;
        !           132: 
        !           133:                        if(!lp || !*lp || !pp || !*pp || !w)
        !           134:                                return(0);
        !           135: 
        !           136:                        ulong ip_addr;
        !           137: 
        !           138:                        if((ip_addr=resolve_ip(*pp))==INADDR_NONE)
        !           139:                                return(0);
        !           140: 
        !           141:                        SOCKADDR_IN     addr;
        !           142: 
        !           143:                        memset(&addr,0,sizeof(addr));
        !           144:                        addr.sin_addr.s_addr = ip_addr;
        !           145:                        addr.sin_family = AF_INET;
        !           146:                        addr.sin_port   = htons(w);
        !           147: 
        !           148:                        if((i=connect(*lp, (struct sockaddr *)&addr, sizeof(addr)))!=0) {
        !           149:                                csi->socket_error=ERROR_VALUE;
        !           150:                                return(0);
        !           151:                        }
        !           152:                        csi->logic=LOGIC_TRUE;
        !           153:                        return(0);
        !           154:                case CS_SOCKET_ACCEPT:
        !           155:                        lp1=getintvar(csi,*(long *)csi->ip);            /* socket */
        !           156:                        csi->ip+=4;
        !           157:                        csi->socket_error=0;
        !           158:                        /* TODO */
        !           159:                        return(0);
        !           160:                case CS_SOCKET_NREAD:
        !           161:                        lp1=getintvar(csi,*(long *)csi->ip);            /* socket */
        !           162:                        csi->ip+=4;
        !           163:                        lp2=getintvar(csi,*(long *)csi->ip);            /* var */
        !           164:                        csi->ip+=4;
        !           165: 
        !           166:                        csi->logic=LOGIC_FALSE;
        !           167:                        csi->socket_error=0;
        !           168: 
        !           169:                        if(!lp1 || !lp2)
        !           170:                                return(0);
        !           171: 
        !           172:                        if(ioctlsocket(*lp1, FIONREAD, (ulong*)lp2)==0) 
        !           173:                                csi->logic=LOGIC_TRUE;
        !           174:                        else
        !           175:                                csi->socket_error=ERROR_VALUE;
        !           176:                        return(0);
        !           177:                case CS_SOCKET_PEEK:
        !           178:                case CS_SOCKET_READ:
        !           179:                        lp=getintvar(csi,*(long *)csi->ip);                     /* socket */
        !           180:                        csi->ip+=4;
        !           181:                        pp=getstrvar(csi,*(long *)csi->ip);                     /* buffer */
        !           182:                        csi->ip+=4;
        !           183:                        w=*(ushort *)csi->ip;                                           /* length */
        !           184:                        csi->ip+=2;                                     
        !           185: 
        !           186:                        csi->logic=LOGIC_FALSE;
        !           187:                        csi->socket_error=0;
        !           188: 
        !           189:                        if(!lp || !pp)
        !           190:                                return(0);
        !           191: 
        !           192:                        if(w<1 || w>sizeof(buf)-1)
        !           193:                                w=sizeof(buf)-1;
        !           194: 
        !           195:                        if((i=recv(*lp,buf,w
        !           196:                                ,*(csi->ip-13)==CS_SOCKET_PEEK ? MSG_PEEK : 0))>0) {
        !           197:                                csi->logic=LOGIC_TRUE;
        !           198:                                buf[i]=0;
        !           199:                                if(csi->etx) {
        !           200:                                        p=strchr(buf,csi->etx);
        !           201:                                        if(p) *p=0; 
        !           202:                                }
        !           203:                                *pp=copystrvar(csi,*pp,buf); 
        !           204:                        } else
        !           205:                                csi->socket_error=ERROR_VALUE;
        !           206:                        return(0);
        !           207:                case CS_SOCKET_READLINE:
        !           208:                        lp=getintvar(csi,*(long *)csi->ip);                     /* socket */
        !           209:                        csi->ip+=4;
        !           210:                        pp=getstrvar(csi,*(long *)csi->ip);                     /* buffer */
        !           211:                        csi->ip+=4;
        !           212:                        w=*(ushort *)csi->ip;                                           /* length */
        !           213:                        csi->ip+=2;                                     
        !           214: 
        !           215:                        csi->logic=LOGIC_FALSE;
        !           216:                        csi->socket_error=0;
        !           217: 
        !           218:                        if(!lp || !pp)
        !           219:                                return(0);
        !           220: 
        !           221:                        if(w<1 || w>sizeof(buf)-1)
        !           222:                                w=sizeof(buf)-1;
        !           223: 
        !           224:                        start=time(NULL);
        !           225:                        for(i=0;i<w;) {
        !           226: 
        !           227:                                if(!online)
        !           228:                                        return(1);
        !           229: 
        !           230:                                if(!socket_check(*lp,&rd,NULL,1000))
        !           231:                                        return(0);
        !           232: 
        !           233:                                if(!rd) {
        !           234:                                        if(time(NULL)-start>TIMEOUT_SOCK_READLINE) {
        !           235:                                                lprintf(LOG_WARNING,"!socket_readline: timeout (%d) exceeded"
        !           236:                                                        ,TIMEOUT_SOCK_READLINE);
        !           237:                                                return(0);
        !           238:                                        }
        !           239:                                        continue;
        !           240:                                }
        !           241: 
        !           242:                                if(recv(*lp, &ch, 1, 0)!=1) {
        !           243:                                        csi->socket_error=ERROR_VALUE;
        !           244:                                        return(0);
        !           245:                                }
        !           246: 
        !           247:                                if(ch=='\n' && i>=1) 
        !           248:                                        break;
        !           249: 
        !           250:                                buf[i++]=ch;
        !           251:                        }
        !           252:                        if(i>0 && buf[i-1]=='\r')
        !           253:                                buf[i-1]=0;
        !           254:                        else
        !           255:                                buf[i]=0;
        !           256: 
        !           257:                        if(csi->etx) {
        !           258:                                p=strchr(buf,csi->etx);
        !           259:                                if(p) *p=0; 
        !           260:                        }
        !           261:                        *pp=copystrvar(csi,*pp,buf); 
        !           262:                        csi->logic=LOGIC_TRUE;
        !           263:                        return(0);
        !           264:                case CS_SOCKET_WRITE:   
        !           265:                        lp=getintvar(csi,*(long *)csi->ip);                     /* socket */
        !           266:                        csi->ip+=4;
        !           267:                        pp=getstrvar(csi,*(long *)csi->ip);                     /* buffer */
        !           268:                        csi->ip+=4;
        !           269: 
        !           270:                        csi->logic=LOGIC_FALSE;
        !           271:                        csi->socket_error=0;
        !           272: 
        !           273:                        if(!lp || !pp || !(*pp))
        !           274:                                return(0);
        !           275: 
        !           276:                        if(sendsocket(*lp,*pp,strlen(*pp))>0)
        !           277:                                csi->logic=LOGIC_TRUE;
        !           278:                        else
        !           279:                                csi->socket_error=ERROR_VALUE;
        !           280:                        return(0);
        !           281: 
        !           282:                /* FTP Functions */
        !           283:                case CS_FTP_LOGIN:
        !           284:                        lp=getintvar(csi,*(long *)csi->ip);                     /* socket */
        !           285:                        csi->ip+=4;
        !           286:                        pp1=getstrvar(csi,*(long *)csi->ip);            /* username */
        !           287:                        csi->ip+=4;
        !           288:                        pp2=getstrvar(csi,*(long *)csi->ip);            /* password */
        !           289:                        csi->ip+=4;
        !           290: 
        !           291:                        csi->logic=LOGIC_FALSE;
        !           292:                        csi->socket_error=0;
        !           293: 
        !           294:                        if(!lp || !pp1 || !pp2)
        !           295:                                return(0);
        !           296: 
        !           297:                        if(!ftp_cmd(csi,*lp,NULL,rsp))
        !           298:                                return(0);
        !           299: 
        !           300:                        if(atoi(rsp)!=220)
        !           301:                                return(0);
        !           302: 
        !           303:                        sprintf(str,"USER %s",*pp1);
        !           304: 
        !           305:                        if(!ftp_cmd(csi,*lp,str,rsp))
        !           306:                                return(0);
        !           307:                        
        !           308:                        if(atoi(rsp)==331) { /* Password needed */
        !           309:                                sprintf(str,"PASS %s",*pp2);
        !           310:                                if(!ftp_cmd(csi,*lp,str,rsp))
        !           311:                                        return(0);
        !           312:                        }
        !           313: 
        !           314:                        if(atoi(rsp)==230)      /* Login successful */
        !           315:                                csi->logic=LOGIC_TRUE;
        !           316:                        return(0);
        !           317: 
        !           318:                case CS_FTP_LOGOUT:
        !           319:                        lp=getintvar(csi,*(long *)csi->ip);                     /* socket */
        !           320:                        csi->ip+=4;
        !           321:                        csi->logic=LOGIC_FALSE;
        !           322:                        csi->socket_error=0;
        !           323: 
        !           324:                        if(!lp)
        !           325:                                return(0);
        !           326: 
        !           327:                        if(!ftp_cmd(csi,*lp,"QUIT",rsp))
        !           328:                                return(0);
        !           329: 
        !           330:                        if(atoi(rsp)==221)      /* Logout successful */
        !           331:                                csi->logic=LOGIC_TRUE;
        !           332:                        return(0);
        !           333: 
        !           334:                case CS_FTP_PWD:
        !           335:                        lp=getintvar(csi,*(long *)csi->ip);                     /* socket */
        !           336:                        csi->ip+=4;
        !           337:                        csi->logic=LOGIC_FALSE;
        !           338:                        csi->socket_error=0;
        !           339:                        if(!lp)
        !           340:                                return(0);
        !           341: 
        !           342:                        if(!ftp_cmd(csi,*lp,"PWD",rsp))
        !           343:                                return(0);
        !           344: 
        !           345:                        if(atoi(rsp)==257)      /* pathname */
        !           346:                                csi->logic=LOGIC_TRUE;
        !           347:                        return(0);
        !           348: 
        !           349:                case CS_FTP_CWD:
        !           350:                        lp=getintvar(csi,*(long *)csi->ip);                     /* socket */
        !           351:                        csi->ip+=4;
        !           352:                        pp=getstrvar(csi,*(long *)csi->ip);                     /* path */
        !           353:                        csi->ip+=4;
        !           354: 
        !           355:                        csi->logic=LOGIC_FALSE;
        !           356:                        csi->socket_error=0;
        !           357:                        if(!lp || !pp)
        !           358:                                return(0);
        !           359:                        
        !           360:                        sprintf(str,"CWD %s",*pp);
        !           361:                        if(!ftp_cmd(csi,*lp,str,rsp))
        !           362:                                return(0);
        !           363: 
        !           364:                        if(atoi(rsp)==250)
        !           365:                                csi->logic=LOGIC_TRUE;
        !           366: 
        !           367:                        return(0);
        !           368: 
        !           369:                case CS_FTP_DIR:
        !           370:                        lp=getintvar(csi,*(long *)csi->ip);                     /* socket */
        !           371:                        csi->ip+=4;
        !           372:                        pp=getstrvar(csi,*(long *)csi->ip);                     /* path */
        !           373:                        csi->ip+=4;
        !           374: 
        !           375:                        csi->logic=LOGIC_FALSE;
        !           376:                        csi->socket_error=0;
        !           377: 
        !           378:                        if(!lp || !pp)
        !           379:                                return(0);
        !           380: 
        !           381:                        if(ftp_get(csi,*lp,*pp,NULL /* unused */, true /* DIR */)==true)
        !           382:                                csi->logic=LOGIC_TRUE;
        !           383: 
        !           384:                        return(0);
        !           385: 
        !           386:                case CS_FTP_DELETE:
        !           387:                        lp=getintvar(csi,*(long *)csi->ip);                     /* socket */
        !           388:                        csi->ip+=4;
        !           389:                        pp=getstrvar(csi,*(long *)csi->ip);                     /* path */
        !           390:                        csi->ip+=4;
        !           391: 
        !           392:                        csi->logic=LOGIC_FALSE;
        !           393:                        csi->socket_error=0;
        !           394:                        if(!lp || !pp)
        !           395:                                return(0);
        !           396:                        
        !           397:                        sprintf(str,"DELE %s",*pp);
        !           398:                        if(!ftp_cmd(csi,*lp,str,rsp))
        !           399:                                return(0);
        !           400: 
        !           401:                        if(atoi(rsp)==250)
        !           402:                                csi->logic=LOGIC_TRUE;
        !           403: 
        !           404:                        return(0);
        !           405: 
        !           406: 
        !           407:                case CS_FTP_GET:
        !           408:                        lp=getintvar(csi,*(long *)csi->ip);                     /* socket */
        !           409:                        csi->ip+=4;
        !           410:                        pp1=getstrvar(csi,*(long *)csi->ip);            /* src path */
        !           411:                        csi->ip+=4;
        !           412:                        pp2=getstrvar(csi,*(long *)csi->ip);            /* dest path */
        !           413:                        csi->ip+=4;
        !           414: 
        !           415:                        csi->logic=LOGIC_FALSE;
        !           416:                        csi->socket_error=0;
        !           417: 
        !           418:                        if(!lp || !pp1 || !pp2)
        !           419:                                return(0);
        !           420: 
        !           421:                        if(ftp_get(csi,*lp,*pp1,*pp2)==true)
        !           422:                                csi->logic=LOGIC_TRUE;
        !           423:                        
        !           424:                        return(0);
        !           425: 
        !           426:                case CS_FTP_PUT:
        !           427:                        lp=getintvar(csi,*(long *)csi->ip);                     /* socket */
        !           428:                        csi->ip+=4;
        !           429:                        pp1=getstrvar(csi,*(long *)csi->ip);            /* src path */
        !           430:                        csi->ip+=4;
        !           431:                        pp2=getstrvar(csi,*(long *)csi->ip);            /* dest path */
        !           432:                        csi->ip+=4;
        !           433: 
        !           434:                        csi->logic=LOGIC_FALSE;
        !           435:                        csi->socket_error=0;
        !           436: 
        !           437:                        if(!lp || !pp1 || !pp2)
        !           438:                                return(0);
        !           439: 
        !           440:                        if(ftp_put(csi,*lp,*pp1,*pp2)==true)
        !           441:                                csi->logic=LOGIC_TRUE;
        !           442:                        
        !           443:                        return(0);
        !           444: 
        !           445: 
        !           446:                default:
        !           447:                        errormsg(WHERE,ERR_CHK,"net sub-instruction",*(csi->ip-1));
        !           448:                        return(0)        !           449:        }
        !           450: }
        !           451: 
        !           452: /* FTP Command/Response function */
        !           453: bool sbbs_t::ftp_cmd(csi_t* csi, SOCKET sock, char* cmdsrc, char* rsp)
        !           454: {
        !           455:        char    cmd[512];
        !           456:        int             len;
        !           457:        BOOL    data_avail;
        !           458:        time_t  start;
        !           459: 
        !           460:        if(cmdsrc!=NULL) {
        !           461:                sprintf(cmd,"%s\r\n",cmdsrc);
        !           462: 
        !           463:                if(csi->ftp_mode&CS_FTP_ECHO_CMD)
        !           464:                        bputs(cmd);
        !           465: 
        !           466:                len=strlen(cmd);
        !           467:                if(sendsocket(sock,cmd,len)!=len) {
        !           468:                        csi->socket_error=ERROR_VALUE;
        !           469:                        return(FALSE);
        !           470:                }
        !           471:        }
        !           472: 
        !           473:        if(rsp!=NULL) {
        !           474: 
        !           475:                int             rd;
        !           476:                char    ch;
        !           477: 
        !           478:                while(1) {
        !           479:                        rd=0;
        !           480: 
        !           481:                        start=time(NULL);
        !           482:                        while(rd<500) {
        !           483: 
        !           484:                                if(!online)
        !           485:                                        return(FALSE);
        !           486: 
        !           487:                                if(!socket_check(sock,&data_avail,NULL,1000))
        !           488:                                        return(FALSE);
        !           489: 
        !           490:                                if(!data_avail) {
        !           491:                                        if(time(NULL)-start>TIMEOUT_FTP_RESPONSE) {
        !           492:                                                lprintf(LOG_WARNING,"!ftp_cmd: TIMEOUT_FTP_RESPONSE (%d) exceeded"
        !           493:                                                        ,TIMEOUT_FTP_RESPONSE);
        !           494:                                                return(FALSE);
        !           495:                                        }
        !           496:                                        continue;
        !           497:                                }
        !           498: 
        !           499:                                if(recv(sock, &ch, 1, 0)!=1) {
        !           500:                                        csi->socket_error=ERROR_VALUE;
        !           501:                                        return(FALSE);
        !           502:                                }
        !           503: 
        !           504:                                if(ch=='\n' && rd>=1) 
        !           505:                                        break;
        !           506: 
        !           507:                                rsp[rd++]=ch;
        !           508:                        }
        !           509:                        rsp[rd-1]=0;
        !           510:                        if(csi->ftp_mode&CS_FTP_ECHO_RSP)
        !           511:                                bprintf("%s\r\n",rsp);
        !           512:                        if(rsp[0]!=' ' && rsp[3]!='-')
        !           513:                                break;
        !           514:                }
        !           515:        }               
        !           516: 
        !           517:        return(TRUE);
        !           518: }
        !           519: 
        !           520: SOCKET sbbs_t::ftp_data_sock(csi_t* csi, SOCKET ctrl_sock, SOCKADDR_IN* addr)
        !           521: {
        !           522:        char            cmd[512];
        !           523:        char            rsp[512];
        !           524:        char*           p;
        !           525:        socklen_t       addr_len;
        !           526:        SOCKET          data_sock;
        !           527:        int                     ip_b[4];
        !           528:        int                     port_b[2];
        !           529:        union {
        !           530:                DWORD   dw;
        !           531:                BYTE    b[sizeof(DWORD)];
        !           532:        } ip_addr;
        !           533:        union {
        !           534:                WORD    w;
        !           535:                BYTE    b[sizeof(WORD)];
        !           536:        } port;
        !           537: 
        !           538:        if(csi->ftp_mode&CS_FTP_ASCII)
        !           539:                strcpy(cmd,"TYPE A");
        !           540:        else    /* BINARY */
        !           541:                strcpy(cmd,"TYPE I");
        !           542:        if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
        !           543:                || atoi(rsp)!=200) {
        !           544:                return(INVALID_SOCKET);
        !           545:        }
        !           546: 
        !           547:        if((data_sock=open_socket(SOCK_STREAM))==INVALID_SOCKET) {
        !           548:                csi->socket_error=ERROR_VALUE;
        !           549:                return(INVALID_SOCKET);
        !           550:        }
        !           551: 
        !           552:        memset(addr,0,sizeof(SOCKADDR_IN));
        !           553:        addr->sin_addr.s_addr = htonl(startup->telnet_interface);
        !           554:        addr->sin_family = AF_INET;
        !           555: 
        !           556:        if(bind(data_sock, (struct sockaddr *)addr,sizeof(SOCKADDR_IN))!= 0) {
        !           557:                csi->socket_error=ERROR_VALUE;
        !           558:                close_socket(data_sock);
        !           559:                return(INVALID_SOCKET);
        !           560:        }
        !           561:        
        !           562:        if(csi->ftp_mode&CS_FTP_PASV) {
        !           563: 
        !           564:                if(!ftp_cmd(csi,ctrl_sock,"PASV",rsp) 
        !           565:                        || atoi(rsp)!=227 /* PASV response */) {
        !           566:                        bprintf("ftp: failure, line %d",__LINE__);
        !           567:                        close_socket(data_sock);
        !           568:                        return(INVALID_SOCKET);
        !           569:                }
        !           570: 
        !           571:                p=strchr(rsp,'(');
        !           572:                if(p==NULL) {
        !           573:                        bprintf("ftp: failure, line %d",__LINE__);
        !           574:                        close_socket(data_sock);
        !           575:                        return(INVALID_SOCKET);
        !           576:                }
        !           577:                p++;
        !           578:                if(sscanf(p,"%u,%u,%u,%u,%u,%u"
        !           579:                        ,&ip_b[0],&ip_b[1],&ip_b[2],&ip_b[3]
        !           580:                        ,&port_b[0],&port_b[1])!=6) {
        !           581:                        bprintf("ftp: failure, line %d",__LINE__);
        !           582:                        close_socket(data_sock);
        !           583:                        return(INVALID_SOCKET);
        !           584:                }
        !           585: 
        !           586:                ip_addr.b[0]=ip_b[0];   ip_addr.b[1]=ip_b[1];
        !           587:                ip_addr.b[2]=ip_b[2];   ip_addr.b[3]=ip_b[3];
        !           588:                port.b[0]=port_b[0];    port.b[1]=port_b[1];
        !           589: 
        !           590:                addr->sin_addr.s_addr=ip_addr.dw;
        !           591:                addr->sin_port=port.w;
        !           592: 
        !           593:        } else {        /* Normal (Active) FTP */
        !           594: 
        !           595:                addr_len=sizeof(SOCKADDR_IN);
        !           596:                if(getsockname(data_sock, (struct sockaddr *)addr,&addr_len)!=0) {
        !           597:                        csi->socket_error=ERROR_VALUE;
        !           598:                        close_socket(data_sock);
        !           599:                        return(INVALID_SOCKET);
        !           600:                } 
        !           601: 
        !           602:                SOCKADDR_IN ctrl_addr;
        !           603:                addr_len=sizeof(ctrl_addr);
        !           604:                if(getsockname(ctrl_sock, (struct sockaddr *)&ctrl_addr,&addr_len)!=0) {
        !           605:                        csi->socket_error=ERROR_VALUE;
        !           606:                        close_socket(data_sock);
        !           607:                        return(INVALID_SOCKET);
        !           608:                } 
        !           609: 
        !           610:                if(listen(data_sock, 1)!= 0) {
        !           611:                        csi->socket_error=ERROR_VALUE;
        !           612:                        close_socket(data_sock);
        !           613:                        return(INVALID_SOCKET);
        !           614:                }
        !           615: 
        !           616:                ip_addr.dw=ntohl(ctrl_addr.sin_addr.s_addr);
        !           617:                port.w=ntohs(addr->sin_port);
        !           618:                sprintf(cmd,"PORT %u,%u,%u,%u,%u,%u"
        !           619:                        ,ip_addr.b[3]
        !           620:                        ,ip_addr.b[2]
        !           621:                        ,ip_addr.b[1]
        !           622:                        ,ip_addr.b[0]
        !           623:                        ,port.b[1]
        !           624:                        ,port.b[0]
        !           625:                        );
        !           626: 
        !           627:                if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
        !           628:                        || atoi(rsp)!=200 /* PORT response */) {
        !           629:                        close_socket(data_sock);
        !           630:                        return(INVALID_SOCKET);
        !           631:                }
        !           632: 
        !           633:        }
        !           634: 
        !           635:        return(data_sock);
        !           636: }
        !           637: 
        !           638: bool sbbs_t::ftp_get(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest, bool dir)
        !           639: {
        !           640:        char            cmd[512];
        !           641:        char            rsp[512];
        !           642:        char            buf[4097];
        !           643:        int                     rd;
        !           644:        int                     result;
        !           645:        BOOL            data_avail;
        !           646:        ulong           total=0;
        !           647:        SOCKET          data_sock;
        !           648:        SOCKADDR_IN     addr;
        !           649:        socklen_t       addr_len;
        !           650:        FILE*           fp=NULL;
        !           651:        struct timeval  tv;
        !           652:        fd_set                  socket_set;
        !           653: 
        !           654:        if((data_sock=ftp_data_sock(csi, ctrl_sock, &addr))==INVALID_SOCKET)
        !           655:                return(false);
        !           656: 
        !           657:        if(csi->ftp_mode&CS_FTP_PASV) {
        !           658: 
        !           659: #if 0  // Debug
        !           660:                bprintf("Connecting to %s:%hd\r\n"
        !           661:                        ,inet_ntoa(addr.sin_addr)
        !           662:                        ,ntohs(addr.sin_port));
        !           663: #endif
        !           664: 
        !           665:                if(connect(data_sock,(struct sockaddr *)&addr,sizeof(addr))!=0) {
        !           666:                        csi->socket_error=ERROR_VALUE;
        !           667:                        close_socket(data_sock);
        !           668:                        return(false);
        !           669:                }
        !           670:        }
        !           671: 
        !           672:        if(dir)
        !           673:                sprintf(cmd,"LIST %s",src);
        !           674:        else
        !           675:                sprintf(cmd,"RETR %s",src);
        !           676: 
        !           677:        if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
        !           678:                || atoi(rsp)!=150 /* Open data connection */) {
        !           679:                close_socket(data_sock);
        !           680:                return(false);
        !           681:        }
        !           682: 
        !           683:        if(!(csi->ftp_mode&CS_FTP_PASV)) {      /* Normal (Active) FTP */
        !           684: 
        !           685:                /* Setup for select() */
        !           686:                tv.tv_sec=TIMEOUT_SOCK_LISTEN;
        !           687:                tv.tv_usec=0;
        !           688: 
        !           689:                FD_ZERO(&socket_set);
        !           690:                FD_SET(data_sock,&socket_set);
        !           691: 
        !           692:                result=select(data_sock+1,&socket_set,NULL,NULL,&tv);
        !           693:                if(result<1) {
        !           694:                        csi->socket_error=ERROR_VALUE;
        !           695:                        closesocket(data_sock);
        !           696:                        return(false);
        !           697:                }
        !           698: 
        !           699:                SOCKET accept_sock;
        !           700: 
        !           701:                addr_len=sizeof(addr);
        !           702:                if((accept_sock=accept_socket(data_sock,(struct sockaddr*)&addr,&addr_len))
        !           703:                        ==INVALID_SOCKET) {
        !           704:                        csi->socket_error=ERROR_VALUE;
        !           705:                        closesocket(data_sock);
        !           706:                        return(false);
        !           707:                }
        !           708: 
        !           709:                close_socket(data_sock);
        !           710:                data_sock=accept_sock;
        !           711:        }
        !           712: 
        !           713:        if(!dir)
        !           714:                if((fp=fopen(dest,"wb"))==NULL) {
        !           715:                        close_socket(data_sock);
        !           716:                        return(false);
        !           717:                }
        !           718: 
        !           719:        while(online) {
        !           720: 
        !           721:                if(!socket_check(ctrl_sock,NULL,NULL,0))
        !           722:                        break; /* Control connection lost */
        !           723: 
        !           724:                if(!socket_check(data_sock,&data_avail,NULL,100))
        !           725:                        break; /* Data connection lost */
        !           726: 
        !           727:                if(!data_avail)
        !           728:                        continue;
        !           729:        
        !           730:                if((rd=recv(data_sock, buf, sizeof(buf)-1, 0))<1)
        !           731:                        break;
        !           732: 
        !           733:                if(dir) {
        !           734:                        buf[rd]=0;
        !           735:                        bputs(buf);
        !           736:                } else
        !           737:                        fwrite(buf,1,rd,fp);
        !           738: 
        !           739:                total+=rd;
        !           740:                
        !           741:                if(!dir && csi->ftp_mode&CS_FTP_HASH)
        !           742:                        outchar('#');
        !           743:        }
        !           744: 
        !           745:        if(!dir && csi->ftp_mode&CS_FTP_HASH) {
        !           746:                CRLF;
        !           747:        }
        !           748: 
        !           749:        if(fp!=NULL)
        !           750:                fclose(fp);
        !           751: 
        !           752:        close_socket(data_sock);
        !           753: 
        !           754:        if(!ftp_cmd(csi,ctrl_sock,NULL,rsp) 
        !           755:                || atoi(rsp)!=226 /* Download complete */)
        !           756:                return(false);
        !           757: 
        !           758:        bprintf("ftp: %lu bytes received.\r\n", total);
        !           759: 
        !           760:        return(true);
        !           761: }
        !           762: 
        !           763: bool sbbs_t::ftp_put(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest)
        !           764: {
        !           765:        char            cmd[512];
        !           766:        char            rsp[512];
        !           767:        char            path[MAX_PATH+1];
        !           768:        char            buf[4097];
        !           769:        int                     rd;
        !           770:        int                     result;
        !           771:        ulong           total=0;
        !           772:        SOCKET          data_sock;
        !           773:        SOCKADDR_IN     addr;
        !           774:        socklen_t       addr_len;
        !           775:        FILE*           fp=NULL;
        !           776:        bool            error=false;
        !           777:        struct timeval  tv;
        !           778:        fd_set                  socket_set;
        !           779: 
        !           780:        SAFECOPY(path,src);
        !           781: 
        !           782:        if(!fexistcase(path))
        !           783:                return(false);
        !           784: 
        !           785:        if((data_sock=ftp_data_sock(csi, ctrl_sock, &addr))==INVALID_SOCKET) {
        !           786:                bprintf("ftp: failure, line %d",__LINE__);
        !           787:                return(false);
        !           788:        }
        !           789: 
        !           790:        if(csi->ftp_mode&CS_FTP_PASV) {
        !           791: 
        !           792: #if 0  // Debug
        !           793:                bprintf("Connecting to %s:%hd\r\n"
        !           794:                        ,inet_ntoa(addr.sin_addr)
        !           795:                        ,ntohs(addr.sin_port));
        !           796: #endif
        !           797: 
        !           798:                if(connect(data_sock,(struct sockaddr *)&addr,sizeof(addr))!=0) {
        !           799:                        bprintf("ftp: failure, line %d",__LINE__);
        !           800:                        csi->socket_error=ERROR_VALUE;
        !           801:                        close_socket(data_sock);
        !           802:                        return(false);
        !           803:                }
        !           804:        }
        !           805: 
        !           806:        if((fp=fopen(path,"rb"))==NULL) {
        !           807:                bprintf("ftp: failure, line %d",__LINE__);
        !           808:                close_socket(data_sock);
        !           809:                return(false);
        !           810:        }
        !           811: 
        !           812:        sprintf(cmd,"STOR %s",dest);
        !           813: 
        !           814:        if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
        !           815:                || atoi(rsp)!=150 /* Open data connection */) {
        !           816:                bprintf("ftp: failure, line %d",__LINE__);
        !           817:                close_socket(data_sock);
        !           818:                return(false);
        !           819:        }
        !           820: 
        !           821:        if(!(csi->ftp_mode&CS_FTP_PASV)) {      /* Normal (Active) FTP */
        !           822: 
        !           823:                /* Setup for select() */
        !           824:                tv.tv_sec=TIMEOUT_SOCK_LISTEN;
        !           825:                tv.tv_usec=0;
        !           826: 
        !           827:                FD_ZERO(&socket_set);
        !           828:                FD_SET(data_sock,&socket_set);
        !           829: 
        !           830:                result=select(data_sock+1,&socket_set,NULL,NULL,&tv);
        !           831:                if(result<1) {
        !           832:                        csi->socket_error=ERROR_VALUE;
        !           833:                        closesocket(data_sock);
        !           834:                        return(false);
        !           835:                }
        !           836: 
        !           837:                SOCKET accept_sock;
        !           838: 
        !           839:                addr_len=sizeof(addr);
        !           840:                if((accept_sock=accept_socket(data_sock,(struct sockaddr*)&addr,&addr_len))
        !           841:                        ==INVALID_SOCKET) {
        !           842:                        csi->socket_error=ERROR_VALUE;
        !           843:                        closesocket(data_sock);
        !           844:                        return(false);
        !           845:                }
        !           846: 
        !           847:                close_socket(data_sock);
        !           848:                data_sock=accept_sock;
        !           849:        }
        !           850: 
        !           851:        while(online && !feof(fp)) {
        !           852: 
        !           853:                rd=fread(buf,sizeof(char),sizeof(buf),fp);
        !           854:                if(rd<1) /* EOF or READ error */
        !           855:                        break;
        !           856: 
        !           857:                if(!socket_check(ctrl_sock,NULL,NULL,0))
        !           858:                        break; /* Control connection lost */
        !           859: 
        !           860:                if(sendsocket(data_sock,buf,rd)<1) {
        !           861:                        error=true;
        !           862:                        break;
        !           863:                }
        !           864: 
        !           865:                total+=rd;
        !           866:                
        !           867:                if(csi->ftp_mode&CS_FTP_HASH)
        !           868:                        outchar('#');
        !           869:        }
        !           870: 
        !           871:        if(csi->ftp_mode&CS_FTP_HASH) {
        !           872:                CRLF;
        !           873:        }
        !           874: 
        !           875:        fclose(fp);
        !           876: 
        !           877:        close_socket(data_sock);
        !           878: 
        !           879:        if(!ftp_cmd(csi,ctrl_sock,NULL,rsp) 
        !           880:                || atoi(rsp)!=226 /* Upload complete */)
        !           881:                return(false);
        !           882: 
        !           883:        if(!error)
        !           884:                bprintf("ftp: %lu bytes sent.\r\n", total);
        !           885: 
        !           886:        return(!error);
        !           887: }

unix.superglobalmegacorp.com

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