Algorithm 版 (精华区)
发信人: Lerry (想不开·撞树), 信区: Algorithm
标 题: parker.c
发信站: 哈工大紫丁香 (2002年06月09日21:27:16 星期天), 站内信件
/*
* NoseyParker, the search engine for FTP archives
* Copyright (C) 1993-96 by Jiri A. Randus
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* The author can be reached as follows:
* Internet: <Jiri.Randus@vslib.cz>
* Phone: ++42 48 5227374
* SnailMail: Jiri Randus
* KIN HF TU v Liberci
* Halkova 6
* 46117 Liberec
* Czech Republic
*/
#define PARKER_VERSION "3.75"
#include "parker.h"
char Line[MAX];
char *wordtbl[MAXWORDS];
int Words;
struct path {char *path, *file; };
struct path Lists[]={
"/","ls-lR.gz",
"/","ls-lR.Z",
"/","ls-lR",
"/pub/","ls-lR.gz",
"/pub/","ls-lR.Z",
"/pub/","ls-lR",
NULL, NULL
};
union InAddr {long addr; char bytes[SIZEOFINETADDR];} myaddr;
char resfile[MAX];
FILE *res;
char machine[MAX];
char TopDir[MAX];
FILE *CtlIn, *CtlOut;
struct sockaddr_in sa;
void Alarm(void)
{
printf("\007'%s' received ALARM !\n",machine);
unlink(resfile);
exit(101);
}
char *TempFile(char *dir, char *prfx)
{
static char fn[MAX];
sprintf(fn,"%s/%sXXXXXX",dir,prfx);
mktemp(fn);
return(fn);
}
int WaitPwd(char *d)
{
char *ptr;
while(1)
{
fgets(Line,MAX,CtlIn);
if(feof(CtlIn)) return(S_CLOSED);
#ifdef DEBUG
printf("%s",Line);
#endif
if(Line[3]=='-') continue;
if(!strncmp(Line,PWD,strlen(PWD)))
{
ptr=Line;
while(ptr++)
if(*ptr=='\"') break;
else if(*ptr==':') { ptr++; break;}
else if(!*ptr) return(S_ERROR);
strcpy(d,ptr+1);
if(ptr=strchr(d,'\"')) *ptr='\0';
else if(ptr=strchr(d,':')) *(++ptr)='\0';
return(S_OK);
}
else if(*Line==NEGATIVE) return(S_ERROR);
else if(*Line==PRENEGATIVE) return(S_ERROR);
}
}
int WaitSucc(void)
{
while(1)
{
fgets(Line,MAX,CtlIn);
if(feof(CtlIn)) return(S_CLOSED);
#ifdef DEBUG
printf("%s",Line);
#endif
if(Line[3]=='-') continue;
if(!strncmp(Line,SUCCESS,strlen(SUCCESS))) return(S_OK);
else if(*Line==PRENEGATIVE) return(S_ERROR);
else if(*Line==NEGATIVE) return(S_ERROR);
}
}
int WaitReply(void)
{
while(1)
{
fgets(Line,MAX,CtlIn);
if(feof(CtlIn)) return(S_CLOSED);
#ifdef DEBUG
printf("%s",Line);
#endif
if(Line[3]=='-') continue;
if(*Line==POSITIVE) return(S_OK);
if(*Line==PROCEED) return(S_OK);
else if(*Line==NEGATIVE) return(S_ERROR);
}
}
int WaitReply2(void)
{
while(1)
{
fgets(Line,MAX,CtlIn);
if(feof(CtlIn)) return(S_CLOSED);
#ifdef DEBUG
printf("%s",Line);
#endif
if(Line[3]=='-') continue;
if(*Line=='2') return(S_OK);
else if(*Line==PREPOSITIVE) return(S_PREOK);
else if(*Line==NEGATIVE) return(S_ERROR);
}
}
int WaitCon(char *m)
{
int h;
struct hostent *host;
if((h=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))<0) {
perror("socket");
return(S_ERROR);
}
sa.sin_family=AF_INET;
sa.sin_port=htons(FTPPORT);
if(!(host=gethostbyname(m))) {perror("gethostbyname");return(S_ERROR);}
memcpy(&sa.sin_addr.s_addr,host->h_addr,SIZEOFINETADDR);
if(connect(h,(struct sockaddr *)&sa, sizeof(sa))<0) {
perror("connect");
return(S_ERROR);
}
if(CtlIn) fclose(CtlIn);
if(CtlOut) fclose(CtlOut);
if(!(CtlIn=fdopen(h,"r"))) {perror("fdopen(CtlIn)");exit(102);}
if(!(CtlOut=fdopen(h,"w"))) {perror("fdopen(CtlOut)");exit(103);}
setbuf(CtlIn,NULL);
setbuf(CtlOut,NULL);
return(S_OK);
}
void ConvertBS(char *p)
{
while(*p)
{
if(*p=='\\') *p='/';
p++;
}
}
int Connect(char *p)
{
if(WaitCon(p)!=S_OK) return(S_ERROR);
if(WaitReply()!=S_OK) return(S_ERROR);
fprintf(CtlOut,"USER anonymous\r\n");
if(WaitReply()!=S_OK) return(S_ERROR);
fprintf(CtlOut,"PASS %s\r\n",EMAILINFO);
if(WaitReply()!=S_OK) return(S_ERROR);
fprintf(CtlOut,"PWD\r\n");
if(WaitPwd(TopDir)!=S_OK) return(S_ERROR);
ConvertBS(TopDir);
DEB("Logged in");
return(S_OK);
}
int IsMonth(char *p)
{
int i;
static char *m[]={"Jan","Feb","Mar","Apr","May","Jun","Jul",
"Aug","Sep","Oct","Nov","Dec",NULL};
for(i=0;i<12;i++) if(!strncasecmp(p,m[i],3)) return(S_OK);
return(S_ERROR);
}
char *DumpFile(char *path, FILE *f, int isdir)
{
if(Words==2) {
/* skip parent dir */
if(!strcmp(wordtbl[0],".") || !strcmp(wordtbl[0],"..")) return(NULL);
/* skip the `total' sum in the Unix listing */
if(!strcmp(wordtbl[0],"total")) return(NULL);
fprintf(f,"%s%s%s%s\n", path, (path[strlen(path)-1]=='/')?"":"/",
wordtbl[0], isdir?"/":"");
return(wordtbl[0]);
}
else {
/* skip parent dir */
if(!strcmp(wordtbl[Words-1],".") || !strcmp(wordtbl[Words-1],".."))
return(NULL);
fprintf(f,"%s%s%s%s", path, (path[strlen(path)-1]=='/')?"":"/",
wordtbl[Words-1], isdir?"/":"");
fprintf(f," %s %s_%s_%s\n",
wordtbl[Words-5],wordtbl[Words-4],wordtbl[Words-3],wordtbl[Words-2]);
return(wordtbl[Words-1]);
}
}
int QueryDir(char *f, char shortlong, char *fn)
{
struct sockaddr_in da;
int foo;
int hh;
int rc;
int i,s,ns;
short Port;
FILE *in, *out;
char *ptr;
da=sa;
if((hh=creat(f,MODE))==-1) return(S_ERROR);
da.sin_addr.s_addr=myaddr.addr;
da.sin_port = 0;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0)
{
perror("socket");
return(S_ERROR);
}
foo=sizeof(da);
while(bind(s, (struct sockaddr *) &da, foo)< 0)
{
perror("bind");
return(S_ERROR);
}
if (getsockname(s, (struct sockaddr *) &da, &foo) < 0)
{
perror("ftp: getsockname");
return(S_ERROR);
}
Port=ntohs(da.sin_port);
if (listen(s, 1) < 0)
{
perror("listen");
return(S_ERROR);
}
fprintf(CtlOut,"PORT %u,%u,%u,%u,%u,%u\r\n",
(unsigned char)myaddr.bytes[0],(unsigned char)myaddr.bytes[1],
(unsigned char)myaddr.bytes[2],(unsigned char)myaddr.bytes[3],
Port/256,Port-(unsigned int)(Port/256)*256);
if((rc=WaitReply())==S_OK) {
switch(shortlong) {
case 0: fprintf(CtlOut,"LIST\r\n");break;
case 1: fprintf(CtlOut,"LIST -lR\r\n");break;
case 2: fprintf(CtlOut,"TYPE I\r\n");
WaitReply();
fprintf(CtlOut,"RETR %s\r\n",fn);
break;
default: puts("Wrong kind of `shortlong' argument in QueryDir");
return(S_ERROR);
}
if(WaitReply2()!=S_PREOK) return(S_ERROR_INFIMA);
foo = sizeof da;
ns = accept(s, (struct sockaddr *) &da, &foo);
if (ns < 0)
{
perror("accept");
return(S_ERROR);
}
close(s);
if(shortlong==2) while(1) {
i=read(ns,Line,MAX);
if(!i) break;
alarm(TIMEOUT);
write(hh,Line,i);
}
else {
if(!(in=fdopen(ns,"r"))) {perror("fdopen in"); return(S_ERROR);}
if(!(out=fdopen(hh,"w"))) {perror("fdopen out"); return(S_ERROR);}
while(1)
{
fgets(Line,MAX,in);
if(feof(in)) break;
if((ptr=strchr(Line,CR))!=NULL) *ptr='\0';
if((ptr=strchr(Line,LF))!=NULL) *ptr='\0';
fprintf(out,"%s\n",Line);
alarm(TIMEOUT);
}
fclose(out);
fclose(in);
}
DEB("Done with fetching the directory");
close(ns);
close(hh);
rc=WaitSucc();
}
return(rc);
}
int IsDir(char *l)
{
if((Words==2) && !strcmp(wordtbl[1],"<DIR>")) return(S_OK);
if((Words==5) && !strncmp(wordtbl[1],"DIR ",4)) return(S_OK);
if((Words>=7) && (*l=='d')) return(S_OK);
return(S_ERROR);
}
int IsFile(char *l)
{
if((Words>=7) && (*l=='-')) return(S_OK);
if((Words==5) && !strncmp(wordtbl[1],"A ",2)) return(S_OK);
if((Words==2) && strcmp(wordtbl[1],"<DIR>")) return(S_OK);
return(S_ERROR);
}
int WordCount(char *l)
{
Words=0;
while(*l)
{
while(l && (*l==' ')) l++;
if(l && *l) {
if(Words<MAXWORDS) wordtbl[Words]=l;
Words++;
while(*l && (*l!=' ')) l++;
*l='\0';
l++;
}
}
if(Words<MAXWORDS) wordtbl[Words]=l;
return(Words);
}
int DoLookup(char *p)
{
char newdir[MAX];
char *ptr;
char tmpfn[MAX];
FILE *dirf;
int rc;
alarm(TIMEOUT);
fprintf(CtlOut,"CWD %s\r\n",p);
if(WaitReply()!=S_OK) return(S_ERROR);
if(feof(CtlIn)) {
DEB("Connection failed!");
exit(111);
}
fprintf(CtlOut,"PWD\r\n");
WaitPwd(newdir);
ConvertBS(newdir);
if(strcasecmp(newdir,p)) {
DEB("Dirs don't match");
fprintf(stderr,"--- new: %s, expected: %s\n",newdir,p);
return(S_ERROR);
}
strcpy(tmpfn,TempFile(WORKDIR,"Dir"));
rc=QueryDir(tmpfn,0,NULL);
if(rc!=S_ERROR_INFIMA) printf("%s:%s\n",machine,p);
else {
rc=S_OK;
printf("%s:%s - Major BBS Bug\n",machine,p);
}
if(!(dirf=fopen(tmpfn,"r"))) {unlink(tmpfn);return(S_ERROR);}
unlink(tmpfn);
while(rc==S_OK)
{
fgets(Line,MAX,dirf);
if(feof(dirf)) {rc=S_OK; break;}
if((ptr=strchr(Line,CR))!=NULL) *ptr='\0';
if((ptr=strchr(Line,LF))!=NULL) *ptr='\0';
WordCount(Line);
if(IsFile(Line)==S_OK) DumpFile(p,res,0);
else if(IsDir(Line)==S_OK) {
ptr=DumpFile(p,res,1);
if(ptr) {
strcpy(tmpfn,p);
if(tmpfn[strlen(tmpfn)-1]!='/') strcat(tmpfn,"/");
strcat(tmpfn,ptr);
}
else continue;
rc=DoLookup(tmpfn);
if(rc!=S_OK) {DEB("DoLookup returned an error"); rc=0;}
}
}
fclose(dirf);
return(rc);
}
void ConcStr(char *s, char *r)
{
char *ptr, str[2];
str[1]=0;
ptr=r;
while(*ptr)
{if(*ptr=='/') strcat(s,"\\"); str[0]=*ptr; strcat(s,str); ptr++;}
}
void DoAwk(char *root, char *infile, char *outfile)
{
char command[MAX];
sprintf(command,"%s 'BEGIN {print \"%s/\";}", NAWK, TopDir);
strcat(command," NF==1 { sub(\":\",\"/\",$1); ADRESAR=$1; };");
strcat(command," NF>=7 && $1 ~ /^-/ { print ROOT \"/\" ADRESAR $NF ");
strcat(command,"\" \" $(NF-4) \" \" $(NF-3) \"_\" $(NF-2) \"_\" $(NF-1);}"
);
strcat(command," NF>=7 && $1 ~ /^d/ && $NF !~ /^\\..*$/ ");
strcat(command,"{ print ROOT \"/\" ADRESAR $NF ");
strcat(command,"\"/ \" $(NF-4) \" \" $(NF-3) \"_\" $(NF-2) \"_\" $(NF-1);}
");
strcat(command,"' ROOT='");
strcat(command,root);
strcat(command,"' ADRESAR= ");
strcat(command,infile);
strcat(command," | sed -e 's/^.:\\//\\//' -e 's/\\\\/\\//g' -e 's/\\/\\//\
\//g' ");
strcat(command,"-e 's/\\/.\\//\\//g' -e 's/^");
ConcStr(command,root);
ConcStr(command,root);
strcat(command,"/");
ConcStr(command,root);
strcat(command,"/' | ");
strcat(command,SORTPATH);
strcat(command," -u | ");
strcat(command,GZIP);
strcat(command," > ");
strcat(command,outfile);
#ifdef DEBUG
printf("%s\n",command);
#endif
system(command);
DEB("Done DoAwk");
return;
}
int DoRec(char *p, char *fileres)
{
char newdir[MAX];
char tmpfn[MAX];
int lslRok;
int rc;
FILE *fh;
alarm(TIMEOUT);
fprintf(CtlOut,"CWD %s\r\n",p);
if(WaitReply()!=S_OK) return(S_ERROR);
if(feof(CtlIn)) {
DEB("Connection failed!");
exit(111);
}
fprintf(CtlOut,"PWD\r\n");
WaitPwd(newdir);
ConvertBS(newdir);
if(strcasecmp(newdir,p)) return(S_ERROR);
strcpy(tmpfn,TempFile(WORKDIR,"Dir2"));
rc=QueryDir(tmpfn,1,NULL);
alarm(0);
lslRok=0;
if(rc==S_OK) {
if((fh=fopen(tmpfn,"r"))!=NULL) {
while(1) {
fgets(Line,MAX,fh);
if(feof(fh)) break;
if(strlen(Line)<3) {lslRok=1; break;}
}
fclose(fh);
if(lslRok) {
printf("%s:%s Recursive LIST -lR\n",machine,p);
DoAwk(p,tmpfn,fileres);
rc=S_OK;
}
else {
printf("%s:%s I don't think this is a recursive list...\n",machine,p
);
unlink(tmpfn);
return(S_ERROR);
}
}
}
else {DEB("Giving up recursive listing");}
unlink(tmpfn);
DEB("Done with DoRec");
return(rc);
}
int DolslR(char *p, char *fileres)
{
char newdir[MAX];
int i;
char tmpfn[MAX];
int rc;
char command[MAX];
rc=0;
for(i=0;Lists[i].path;i++)
{
alarm(TIMEOUT);
fprintf(CtlOut,"CWD %s\r\n",Lists[i].path);
rc=WaitReply();
if(rc==S_CLOSED) {
DEB("Connection closed!!!");
exit(111);
}
else if(rc!=S_OK) continue;
fprintf(CtlOut,"PWD\r\n");
WaitPwd(newdir);
ConvertBS(newdir);
strcpy(tmpfn,TempFile(WORKDIR,"Dir3"));
rc=QueryDir(tmpfn,2,Lists[i].file);
if(rc!=S_OK) continue;
break;
}
alarm(0);
if(Lists[i].path) {
printf("%s:%s Fetched %s%s\n",machine,p,Lists[i].path,Lists[i].file);
if(toupper(Lists[i].file[strlen(Lists[i].file)-1])=='Z') {
DEB("Uncompressing");
strcpy(command,MV);
strcat(command," ");
strcat(command,tmpfn);
strcat(command," ");
strcat(command,tmpfn);
strcat(command,".gz");
system(command);
strcpy(command,GUNZIP);
strcat(command," ");
strcat(command,tmpfn);
system(command);
}
DoAwk(Lists[i].path,tmpfn,fileres);
}
else {DEB("Giving up remote ls-lR files...");}
unlink(tmpfn);
return(rc);
}
int Probe(char *p, char TypeOfFetch)
{
char host[MAX];
int rc;
struct hostent *hoste;
char command[MAX];
DEB("Probe");
gethostname(host,MAX);
if(!(hoste=gethostbyname(host))) {perror("Probe gethostbyname"); exit(106)
;}
memcpy(&myaddr.addr,hoste->h_addr,SIZEOFINETADDR);
unlink(resfile);
if(Connect(p)!=S_OK) {DEB("Couldn't connect");return(S_ERROR);}
if(TypeOfFetch=='r') {
rc=DoRec(TopDir,resfile);
alarm(0);
return(rc);
}
if(TypeOfFetch=='l') {
unlink(resfile);
res=fopen(resfile,"w");
fprintf(res,"%s\n",TopDir);
rc=DoLookup(TopDir);
fclose(res);
alarm(0);
sprintf(command,"%s %s",GZIP,resfile);
system(command);
sprintf(command,"%s %s.gz %s",MV,resfile,resfile);
system(command);
return(rc);
}
if(((rc=DolslR(TopDir,resfile))!=S_OK) && (rc=DoRec(TopDir,resfile))!=S_OK
)
{
DEB("Lookup");
unlink(resfile);
res=fopen(resfile,"w");
fprintf(res,"%s\n",TopDir);
rc=DoLookup(TopDir);
fclose(res);
sprintf(command,"%s %s",GZIP,resfile);
system(command);
sprintf(command,"%s %s.gz %s",MV,resfile,resfile);
system(command);
}
alarm(0);
DEB("Done with Probe");
return(rc);
}
void main(int n, char *p[])
{
int fh;
int child;
char command[MAX];
char *ptr;
int hostnum;
FILE *hosts;
char TypeOfFetch;
printf("NoseyParker %s, Gatherer V%s by Jiri A. Randus\n",VERSION,PARKER_V
ERSION);
if(n>3) {
printf("USAGE: parker\n");
printf(" parker [-r|-l] <machine>\n");
return;
}
nice(PARKER_NICE);
signal(SIGALRM,(void (*)(int))Alarm);
strcpy(resfile,TempFile(WORKDIR,"Res"));
hostnum=0;
TypeOfFetch=' ';
if(n>=2) {
if(*p[1]=='-') {
TypeOfFetch=p[1][1];
strcpy(machine,p[2]);
}
else strcpy(machine,p[1]);
if(Probe(machine,TypeOfFetch)==S_OK) {
if(!(fh=open(resfile,O_RDONLY)))
printf("Cannot open the machine file\n");
else {
if(lseek(fh,0L,SEEK_END)>0L) {
unlink(machine);
strcpy(command,MV);
strcat(command," ");
strcat(command,resfile);
strcat(command," ");
strcat(command,machine);
strcat(command,".gz");
system(command);
}
else {DEB("Bad seek - filelen=0");}
close(fh);
}
unlink(resfile);
}
}
else {
strcpy(Line,PARKER_HOME);
strcat(Line,HOSTLIST);
if(!(hosts=fopen(Line,"r"))) {
printf("No Hosts %s\n",Line);
return;
}
while(1)
{
fgets(Line,MAX,hosts);
if(feof(hosts)) break;
if((ptr=strchr(Line,CR))!=NULL) *ptr='\0';
if((ptr=strchr(Line,LF))!=NULL) *ptr='\0';
printf("Starting %s\n",Line);
while((child=fork())==-1) sleep(1);
if(!child) {
strcpy(resfile,TempFile(WORKDIR,"Res2"));
strcpy(machine,Line);
if(Probe(machine,TypeOfFetch)==S_OK) {
alarm(0);
fh=open(resfile,O_RDONLY);
if(lseek(fh,0L,SEEK_END)>0L) {
unlink(machine);
strcpy(command,MV);
strcat(command," ");
strcat(command,resfile);
strcat(command," ");
strcat(command,machine);
strcat(command,".gz");
system(command);
}
close(fh);
unlink(resfile);
}
fclose(hosts);
exit(0);
}
else {
hostnum++;
sleep(5);
if(hostnum>=MAXAGENTS) {wait(&child);hostnum--;}
}
}
fclose(hosts);
while(hostnum--) wait(&child);
}
}
--
当一个女孩儿觉得她不太容易了解那个男人的时候,她会爱他。
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 天外飞仙]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:211.542毫秒