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水木清华站∶精华区