📄 linuxdown.c
字号:
/*************************************************************************** * Copyright (C) 2005 by kongyang * * be_heack@hotmail.com * * Version 1.0 * * * * 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * * This program intends to help you download files using HTTP or FTP * * protocal, and you can use up to 20 threads to make your downloading * * faster. * * * * If you have better opinions about this program, please contact me. * * My msn is be_heack@hotmail.com, and mail the same. * * If you help me a lot, I will add your name to the developer list. * ***************************************************************************/#include <sys/types.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <stdlib.h>#include <stdio.h>#include <sys/errno.h>#include <stdarg.h>//#include <tidy.h>#include <pthread.h>#include <fcntl.h>#include <sys/time.h>#include <math.h>#define HTTP 0#define FTP 1static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;int hosttype;static int sizeget=0;int filelength=0;char filename[256];char localpath[256]="";char host[256],path[256];char user[32],pass[32];int port=80,portftp=21;int nthread=1;int downpart[30][2];//describe how much data has been downloaded of each threadint startthread=1;struct arg g[30];//every thread's datastruct timeval tpstart,tpend;struct arg{ int threadnumber; int a1; //range fromn a1 to a2 also lseed set to a1 int a2; int fd; int booldown;//indict whether a thread has begun int allowotherdown;//0 other thread cannot download this thread, 1 not};void ClearBuf(char *buf){ int i=0; for(i=0;i<=1023;i++){ *(buf+i)='\0'; }}void GetZero(char *buf){ int i=0,j=0; for(i=0;i<=1023;i++){ if(*(buf+i)=='\0'){ if(j==0){ j=i; continue; } if(i==(j+1))printf("%d %d ",i,j); j=i; } }}int GetInfo(char *arg,char *refer){ char head[256],referer[256],length1[32]; char headhost[256]; char port1[8],port2[8];//227 Entering Passive Mode (192,168,8,30,6,32) 6 is stored in port1, while 32 is stored in port2 char c_port[8]; int iport=0;//sign the first time to see : like www.xxx.com:8000/name this is the position of : char dataget[2048]=""; int i,i_sock,j,l,sockdata; int length=strlen(arg); if(!strncmp(arg,"http://",7))hosttype=HTTP; if(!strncmp(arg,"ftp://",6))hosttype=FTP; if(hosttype==HTTP){ for(i=0;i<=strlen(arg)-7;i++){ if(*(arg+7+i)==':')iport=i; if(*(arg+7+i)=='/'){ if(iport!=0){ snprintf(host,iport+1,"%s",arg+7); sprintf(path,"/%s",arg+7+i+1); snprintf(c_port,i-iport,"%s",arg+7+iport+1); port=atoi(c_port); } else{ snprintf(host,i+1,"%s",arg+7); sprintf(path,"/%s",arg+7+i+1); } break; } } for(i=length-1;i>=0;i--){ if(*(arg+i)=='/'){ sprintf(filename,"%s",arg+i+1); break; } } } if(hosttype==FTP){ if(strstr(arg,"@")==NULL){ for(i=0;i<=strlen(arg)-6;i++){ if(*(arg+6+i)==':'){ iport=i; continue; } if(*(arg+6+i)=='/'){ if(iport!=0){ snprintf(host,iport+1,"%s",arg+6); sprintf(path,"/%s",arg+6+i+1); snprintf(c_port,i-iport,"%s",arg+6+iport+1); portftp=atoi(c_port); } else{ snprintf(host,i+1,"%s",arg+6); sprintf(path,"/%s",arg+6+i+1); } break; } } for(i=length-1;i>=0;i--){ if(*(arg+i)=='/'){ sprintf(filename,"%s",arg+i+1); break; } } } else{ for(i=0;i<=strlen(arg)-6;i++){ if(*(arg+6+i)==':'){ iport=i; continue; } if(*(arg+6+i)=='@'){ if(iport!=0){ snprintf(user,iport+1,"%s",arg+6); snprintf(pass,i-iport,"%s",arg+6+iport+1); } else{ snprintf(user,i+1,"%s",arg+6); sprintf(pass,"%s",arg+6+i+1); } sprintf(arg,"ftp://%s",arg+8+strlen(user)+strlen(pass)); GetInfo(arg,refer); return 0; } } } } if(hosttype==HTTP){ i_sock=ConnectHttp(host,port); sprintf(head,"GET %s HTTP/1.1\r\nHost: %s:%d\r\nReferer: %s\r\n\r\n",path,host,port,refer); printf("head is %s",head); if(send(i_sock,head,strlen(head),0)!=strlen(head)){ printf("Error in sending HEAD\n"); exit(1); } recv(i_sock,dataget,512,0); write(1,dataget,strlen(dataget)); close(i_sock); if(strstr(dataget,"\nLocation")!=NULL){ for(i=0;*(strstr(dataget,"\nLocation")+11+i)!='\n';i++){} snprintf(arg,i,"%s\0",strstr(dataget,"\nLocation")+11); GetInfo(arg,refer); return 0; } if(strstr(dataget,"\nlocation")!=NULL){ for(i=0;*(strstr(dataget,"\nlocation")+11+i)!='\n';i++){} snprintf(arg,i,"%s\0",strstr(dataget,"\nlocation")+11); GetInfo(arg,refer); return 0; } if(strstr(dataget,"Content-Location")!=NULL){ for(i=0;*(strstr(dataget,"Content-Location")+18+i)!='\n';i++){} snprintf(filename,i,"%s\0",strstr(dataget,"Content-Location")+18); if(*(path+strlen(path)-1)=='/')sprintf(path,"%s%s",path,filename); } filelength=GetLength(dataget); } if(hosttype==FTP){ i_sock=ConnectHttp(host,portftp); //while(ReadEn(i_sock,2)>0){ j=recv(i_sock,dataget,1024,0); printf("bytesget is j = %d\n",j); write(1,dataget,j); //} ClearBuf(dataget); sleep(5); sprintf(head,"USER %s\r\n\r\n",user); if(send(i_sock,head,strlen(head),0)!=strlen(head)){ printf("Error in sending HEAD\n"); exit(1); } //while(ReadEn(i_sock,2)>0){ j=recv(i_sock,dataget,1024,0); write(1,dataget,strlen(dataget)); // } if(strstr(dataget,"230")==NULL){ ClearBuf(dataget); sprintf(head,"PASS %s\r\n\r\n",pass); if(send(i_sock,head,strlen(head),0)!=strlen(head)){ printf("Error in sending HEAD\n"); exit(1); } //while(ReadEn(i_sock,2)>0){ j=recv(i_sock,dataget,1024,0); write(1,dataget,j); //} ClearBuf(dataget); } sprintf(head,"SIZE %s\r\n\r\n",path); if(send(i_sock,head,strlen(head),0)!=strlen(head)){ printf("Error in sending HEAD\n"); exit(1); } printf("head SIZE is_%s\n",head); recv(i_sock,dataget,1024,0); write(1,dataget,strlen(dataget)); if(strstr(dataget,"213")!=NULL){ i=1; while(1){ if(*(strstr(dataget,"213")+i)=='\n')break; i++; } snprintf(length1,i-4,"%s",strstr(dataget,"213")+4); filelength=atoi(length1); if(filelength==0){ close(i_sock); sleep(1); GetInfo(arg,refer); return 0; } printf("\nFile length is %d\n",filelength); } /*else if(strstr(dataget,"Unknown command")!=NULL){ ClearBuf(dataget); printf("come heare 1"); sprintf(head,"LIST %s\r\n\r\n",path); if(send(i_sock,head,strlen(head),0)!=strlen(head)){ printf("Error in sending LIST\n"); exit(1); } printf("head is %s\n",head); j=recv(i_sock,dataget,512,0); write(1,dataget,j); if(strstr(dataget,filename)!=NULL){ printf("heiheiheihei"); j=0; for(i=0;i<=50;i++){ if(*(strstr(dataget,filename)-i)==' ')j++; if(j==4)l=i; if(j==5){ snprintf(length1,l-i-1,"%s",strstr(dataget,filename)-i+1); filelength=atoi(length1); printf("^^filelength is %d\n^^",filelength); if(filelength==0){ close(i_sock); sleep(1); GetInfo(arg,refer); return 0; } break; } } } }*/ else{ close(i_sock); sleep(1); GetInfo(arg,refer); return 0; } close(i_sock); } return 0;}int GetStartText(char *buf,int sizebuf){ int i; for(i=0;i<=sizebuf-1;i++){ if(buf[i]=='\n'&&!(buf[i+1]>='a'&&buf[i+1]<='z'||buf[i+1]>='A'&&buf[i+1]<='Z'))break; } return i+3;}int GetLength(char *buf){ int i=0,start=0,length=0,end=0; while(buf[start]!='\0'){ if(buf[start]=='L'){ if(!strncmp(buf+start,"Length:",7)){ start+=8; break; } } start++; } end=start; while(buf[end++]!='\n'){} buf[--end]='\0'; length=atoi(buf+start);//Content-Length: xxxxxx\n return length; //return 4512912;}int GetLengthFtp(char *buf){}int GetPortFtp(char *buf){}#define m_sock 10int ReadEn(int sock,int n);int ConnectHttp(char* host,int iport){ int sd; struct sockaddr_in pin; struct hostent *nlp_host; if((nlp_host=gethostbyname(host))==0){ printf("Error resolving local host\n"); return 0; } bzero(&pin,sizeof(pin)); pin.sin_family=AF_INET; pin.sin_addr.s_addr=((struct in_addr*)(nlp_host->h_addr))->s_addr; pin.sin_port=htons(iport); if((sd=socket(PF_INET,SOCK_STREAM,0))==-1){ printf("Error opening socket\n"); return 0; } if(connect(sd,(struct sockaddr*)&pin,sizeof(pin))==-1){ printf("Error connecting to socket\n"); return 0; } return sd; }int DownLoadHttp(struct arg *s_info){ char get[256]; char buf[1024]=""; char headhost[256]; char range[32];#define FALSE 0#define TRUE 1 //this function used to download assigned file from a1 bytes to a2 bytes from host, try 5 times int connected =FALSE; int i,j,starttext,boolprint=0; int sock,nextthread=0,boolbyte=0; long timeuse; int readen,bytesget=0; int inflen,index=0,offset=0; int bytesleft=(s_info->a2)-(s_info->a1)+1; struct timeval tv; if(s_info->booldown==1&&s_info->allowotherdown==1)return 0; if(s_info->threadnumber!=0){ while(g[(s_info->threadnumber)-1].booldown==0){ write(1,"$$$$$wate here$$$$\n",19); sleep(1); } } while(1){ printf("\nhost portftp is %s %d\n",host,port); if((sock=ConnectHttp(host,port))<=0)sleep(1); else{ write(1,"connected",10); connected=TRUE; break; } } if(connected){ sprintf(get,"GET %s HTTP/1.1\r\nRange: bytes=%d-\r\nHost: %s:%d\r\n\r\n",path,s_info->a1,host,port); if(send(sock,get,strlen(get),0)!=strlen(get)){ printf("Error in send GET\n"); close(sock); sleep(5); DownLoadHttp(s_info); return 0; } s_info->fd=open(filename,O_WRONLY|O_CREAT,0644); lseek(s_info->fd,s_info->a1,0); pthread_mutex_lock(&lock); s_info->booldown=1; pthread_mutex_unlock(&lock); ClearBuf(buf); while(bytesleft>0){ readen =ReadEn(sock,30); if(readen<1){ s_info->a1+=offset; printf("fails to open sockdata,thread %d restart at offset %d",s_info->threadnumber,offset); close(sock); sleep(2); pthread_mutex_lock(&lock); s_info->booldown=0; s_info->allowotherdown=0; pthread_mutex_unlock(&lock); DownLoadHttp(s_info); return 0; } boolprint++; if(boolprint==10)boolprint=0; if(bytesleft>=1024&&offset==0){ bytesget=recv(sock,buf,1024,MSG_WAITALL); starttext=GetStartText(buf,bytesget); write(s_info->fd,buf+starttext,1024-starttext); bytesleft+=starttext-bytesget; offset+=bytesget-starttext; sizeget+=bytesget-starttext; ClearBuf(buf); continue; } else if(bytesleft>=1024){ bytesget=recv(sock,buf,1024,0); if(bytesget==0)boolbyte++; if(bytesget<0||(bytesget==0&&boolbyte>=10)){ s_info->a1+=offset; printf("\n!!!!!buf size is %d thread %d try again at %d!!!!\n",strlen(buf),s_info->threadnumber,offset); close(sock); pthread_mutex_lock(&lock); s_info->booldown=0; s_info->allowotherdown=0; pthread_mutex_unlock(&lock); DownLoadHttp(s_info); return 0; } write(s_info->fd,buf,bytesget); offset+=bytesget; sizeget+=bytesget; bytesleft-=bytesget; ClearBuf(buf); } else{ if(offset==0){//used only if the thread size <1024 bytesget=recv(sock,buf,2048,MSG_WAITALL); starttext=GetStartText(buf,bytesget); if(bytesleft!=bytesget-starttext){ close(sock); sleep(2); pthread_mutex_lock(&lock); s_info->booldown=0; s_info->allowotherdown=0; pthread_mutex_unlock(&lock); DownLoadHttp(s_info); return 0; } write(s_info->fd,buf+starttext,strlen(buf)-starttext); offset+=bytesget-starttext; bytesleft-=bytesget-starttext; sizeget+=bytesget-starttext; } else{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -