BBS水木清华站∶精华区

发信人: scaner (S.c.a.n.e.R), 信区: Linux 
标  题: ftpdatapipe.c----支持ftp的datapipe.c 
发信站: BBS 水木清华站 (Thu May 14 21:18:05 1998) 
 
ftp需要两个tcp连接,为此,我修改了一下datapipe.c 
使它能够支持ftp.主要的改动是增加了对port命令的处理, 
 
fp.c   
---Begin--- 
 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <sys/wait.h> 
#include <netinet/in.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <unistd.h> 
#include <netdb.h> 
#include <string.h> 
 
#ifdef STRERROR 
extern char *sys_errlist[]; 
extern int sys_nerr; 
char *undef = "Undefined error"; 
 
char *strerror(error) 
int error; 

  if (error > sys_nerr) 
        return undef; 
  return sys_errlist[error]; 

#endif 
 
 
int main(int argc,char *argv[]) 

        int lsock,csock,csock2,osock,osock2,sock; 
        FILE *cfile; 
        char buf[4096]; 
        struct sockaddr_in laddr,caddr,oaddr; 
        int caddrlen=sizeof(caddr); 
        int laddrlen=sizeof(laddr); 
        fd_set fdsr,fdse; 
        struct hostent *h; 
        int nbyt; 
        unsigned long a,localip,cip; 
        unsigned short oport,cport,lport; 
 
        unsigned c1,c2,c3,c4,c5,c6; 
        perror("+START"); 
        if(argc!=4) 
        { 
                fprintf(stderr,"Usage: %s localport remoteport remotehost\n",argv[0]); 
                return 3; 
        } 
         
        if (gethostname(buf,4096)==-1) 
        { 
                perror("gethostname"); 
                return 5; 
        } 
 
 
        if (!(h = gethostbyname(buf))) 
        { 
                perror("gethostbyname"); 
                return 7; 
        } 
 
        memcpy(&localip,h->h_addr,sizeof(localip)); 
        printf("Local Name: %s Local IP: %X\n",buf,localip); 
        a = inet_addr(argv[3]); 
        if (!(h = gethostbyname(argv[3])) && 
                !(h = gethostbyaddr(&a, 4, AF_INET))) { 
                        perror(argv[3]); 
                        return 4; 
                } 
         
        oport=atol(argv[2]); 
        laddr.sin_port= htons((unsigned short)(atol(argv[1]))); 
 
        if ((lsock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) 
        { 
                perror("socket"); 
                return 2; 
        } 
 
        laddr.sin_family = htons(AF_INET); 
        laddr.sin_addr.s_addr = htonl(0); 
        if (bind(lsock,&laddr,sizeof(laddr))) 
        { 
                perror("bind"); 
                return 2; 
        } 
 
        if (listen(lsock,1)) 
        { 
                perror("listen"); 
                return 2; 
        } 
 
        if ((nbyt = fork()) == -1) 
        { 
                perror("fork"); 
                return 2; 
        } 
 
        if (nbyt > 0) 
                return 0; 
 
        /*setsid();*/ 
 
        while((csock = accept(lsock,&caddr,&caddrlen)) != -1) 
        { 
                perror("+ACCEPT LSOCK"); 
                cfile = fdopen(csock,"r+"); 
                if ((nbyt = fork()) == -1) 
                { 
                        fprintf(cfile,"500 fork %s\n",strerror(errno)); 
                        shutdown(csock,2); 
                        fclose(cfile); 
                        continue; 
                } 
 
                if (nbyt == 0) 
                        goto gotsock; 
 
                fclose(cfile); 
                while (waitpid(-1,NULL,WNOHANG) > 0); 
                perror("+WAITPID OK"); 
        } 
         
        return 20; 
 
 gotsock: 
        perror("GOTSOCK!"); 
        osock2=csock2=-1; 
        if ((osock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) 
        { 
                fprintf(cfile,"500 socket %s\n",strerror(errno)); 
                goto quit1; 
        } 
 
        oaddr.sin_family = h->h_addrtype; 
        oaddr.sin_port=htons(oport); 
        memcpy(&oaddr.sin_addr,h->h_addr,h->h_length); 
        if (connect(osock,&oaddr,sizeof(oaddr))) 
        { 
                fprintf(cfile,"500 connect :%X:%u:%s\n", 
                        oaddr.sin_addr.s_addr,oport,strerror(errno)); 
                goto quit1; 
        } 
 
back: 
        while(1) 
        { 
                perror("+FD_ZERO"); 
                FD_ZERO(&fdse); 
                FD_ZERO(&fdsr); 
                FD_SET(csock,&fdse); 
                FD_SET(osock,&fdse); 
                FD_SET(csock,&fdsr); 
                FD_SET(osock,&fdsr); 
 
                if(csock2 != -1) 
                { 
                        perror("+SELECT CSOCK2"); 
                        FD_SET(csock2,&fdse); 
                        FD_SET(csock2,&fdsr); 
                } 
 
                if(osock2 != -1) 
                { 
                        perror("+SELECT OSOCK2"); 
                        FD_SET(osock2,&fdse); 
                        FD_SET(osock2,&fdsr); 
                } 
                perror("+SELECT START"); 
                 
                if (select(20,&fdsr,NULL,&fdse,NULL) == -1) 
                { 
                        fprintf(cfile,"500 select: %s\n",strerror(errno)); 
                        goto quit2; 
                } 
                perror("+SELECT END"); 
 
                if (FD_ISSET(osock,&fdsr) || FD_ISSET(osock,&fdse)) 
                { 
                        perror("+OSOCK READ"); 
                        if ((nbyt = read(osock,buf,4096)) <= 0) 
                                goto quit2; 
                        if (write(csock,buf,nbyt) <=0) 
                                goto quit2; 
                } 
 
                if (csock2 != -1 && (FD_ISSET(csock2,&fdsr) || FD_ISSET(csock2,&fdse))) 
                { 
                        perror("+CSOCK2 READ"); 
                        if ((nbyt = read(csock2,buf,4096)) <= 0) 
                                goto quit3; 
                        if (write(osock2,buf,nbyt) <= 0) 
                                goto quit3; 
                } 
 
                if (osock2 != -1 && (FD_ISSET(osock2,&fdsr) || FD_ISSET(osock2,&fdse))) 
                { 
                        perror("+OSOCK2 READ"); 
                        if (csock2 != -1) 
                        { 
                                if ((nbyt = read(osock2,buf,4096)) <= 0) 
                                        goto quit3; 
                                if (write(csock2,buf,nbyt) <= 0) 
                                        goto quit3; 
                        } 
                        else 
                        { 
                                perror("+OSOCK2 ACCEPT"); 
                                caddrlen=sizeof(caddr); 
                                if ((sock=accept(osock2,&caddr,&caddrlen)) == -1) 
                                        goto quit3; 
 
                                close(osock2); 
                                osock2=sock; 
                                 
                                caddr.sin_family=AF_INET; 
                                caddr.sin_addr.s_addr=cip; 
                                caddr.sin_port=cport; 
 
                                sprintf(buf,"+CSOCK ADDR: %X:%X",cip,cport); 
                                perror(buf); 
                                if ((csock2=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) 
                                        goto quit3; 
                                perror("+CSOCK2 CONNECT"); 
                                if (connect(csock2,&caddr,sizeof(caddr)) == -1) 
                                        goto quit3; 
                                perror("+CSOCK2 CS"); 
                        } 
                } 
                         
                if (FD_ISSET(csock,&fdsr) || FD_ISSET(csock,&fdse)) 
                { 
                        perror("+CSOCK READ"); 
                        if ((nbyt=read(csock,buf,4096)) <= 0) 
                                goto quit2; 
 
                        if (osock2 != -1 && csock2 != -1 ||  
                                strncasecmp(buf,"PORT",4)!=0) 
                        { 
                                if(write(osock,buf,nbyt) <= 0) 
                                        goto quit2; 
                        } 
                        else 
                        { 
                                perror("+CSOCK PORT"); 
                                buf[nbyt+1]='\0'; 
                                perror(buf); 
                                sscanf(buf+4,"%u,%u,%u,%u,%u,%u",&c1,&c2,&c3,&c4,&c5,&c6); 
                                cip=(c4<<24)+(c3<<16)+(c2<<8)+c1; 
                                cport=(c6<<8)+c5; 
 
                                sprintf(buf,"+IP:%X PORT:%X",cip,cport); 
                                perror(buf); 
 
                                if ((osock2=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) 
                                        goto quit3; 
                                laddr.sin_port=htons(0); 
                                laddr.sin_addr.s_addr=htonl(0); 
                                laddr.sin_family=htons(AF_INET); 
 
                                if (bind(osock2,&laddr,sizeof(laddr)) == -1) 
                                        goto quit3; 
 
                                if (listen(osock2,1) == -1) 
                                        goto quit3; 
 
                                a=localip; 
                                c1=a&0xff;a>>=8; 
                                c2=a&0xff;a>>=8; 
                                c3=a&0xff;a>>=8; 
                                c4=a; 
 
                                laddrlen=sizeof(laddr); 
                                if (getsockname(osock2,(struct sockaddr*)&laddr,&laddrlen) == -1) 
                                        goto quit2;      
 
                                a=lport=laddr.sin_port; 
                                c5=a&0xff;a>>=8; 
                                c6=a&0xff; 
                                 
                                sprintf(buf,"+PORT %X,%X",localip,ntohs(lport)); 
                                perror(buf); 
                                sprintf(buf,"PORT %u,%u,%u,%u,%u,%u\n",c1,c2,c3,c4,c5,c6); 
                                perror(buf); 
                                if (write(osock,buf,strlen(buf)) <= 0) 
                                        goto quit2; 
                        } 
                } 
                perror("+WHILE END"); 
        } 
quit3: 
        perror("+QUIT3"); 
        if (osock2 != -1) 
                close(osock2); 
        if (csock2 != -1) 
                close(csock2); 
 
        osock2=csock2=-1; 
        goto back; 
quit2: 
        perror("+QUIT2"); 
        if (osock2 != -1) 
                close(osock2); 
        if (csock2 != -1) 
                close(csock2); 
 
        shutdown(osock,2); 
        close(osock); 
quit1: 
        perror("+QUIT1"); 
        fflush(cfile); 
        shutdown(csock,2); 
quit0: 
        perror("+QUIT0"); 
        fclose(cfile); 
        return 0; 

 
-- 
凝神窗外的蓝天,绿叶随风摇弋。 
面对缤纷的世界,我到底在追求什么? 
 
         
         
 
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.119.79.72] 

BBS水木清华站∶精华区