⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpheader.c

📁 linux下网络下载软件的源码
💻 C
字号:
/*      Get and Resume Elite EDition source codeGet and Resume Elite EDition (GREED)Copyright (C) 1999  Anoakie TurnerThis program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.For more information on the GPL, please go to:http://www.gnu.org/copyleft/gpl.html        Contact:  Anoakie Turner                  Anoakie.Turner@asu.edu                  13240 N. 94th Pl.                  Scottsdale, AZ 85260*/#include "main.h"void RecurseFTP(char*, char*, int);int ReadSock (int sockfd, char* buffer, char* stopstr)/***************************************	ReadSock(int, char*, char*)**** PRE:	 Assigned(sockfd, buffer, stopstr)** POST: reads data from socket(sockfd) until either the**	 stopstr is hit or sockfd reaches the EOF*************************************/{       int len = 1;        int result = 0;	struct timeval timeout; /* = { TIMEOUT_SEC, 0 }; .8+S patch */	timeout.tv_sec = TIMEOUT_SEC;	timeout.tv_usec = 0;        do        {	switch(select(FD_SETSIZE, &testfds, (fd_set *)0, (fd_set *)0, &timeout))		{	case 0:				if (OUTPUT_LEVEL > 1)					printf("\ntimeout!\n");				return (0);				break;			case -1:				printf("Big socket error or something!\n");				return (0);				break;			default:				result = read(sockfd, buffer + len - 1, sizeof(buffer) + len - 1);		                len += result;				buffer[len] = '\0';				break;		}		timeout.tv_sec = TIMEOUT_SEC;        } while (result > 0 && strstr(buffer, stopstr) == NULL);	if (OUTPUT_LEVEL > 8)        	printf("%s\n\n", buffer);	return(1);}int ReadPASVPort(char* buffer)/***************************************	ReadPASVPort(char*)**** PRE:  Assigned(buffer)** POST: Returns the first specified valid passive port in (buffer)*************************************/{	char *rbuffer = strstr(buffer, "Passive Mode (");	char lhost[6][4];	int i = 0, j = 0, k = 0;	/* If Passive Mode was not found in the buffer,		we have to assume the ftp server doesn't use		PASV mode, therefore it fails 		NOTE: Server could aso be busy! */	if (rbuffer == NULL)	{	if (OUTPUT_LEVEL > 0)			printf("PASV mode failed");		return(0);	} else	{	for (i = 14; (unsigned)i < strlen(rbuffer) && rbuffer[i] != ')'; i++)			if (rbuffer[i] == ',')			{	lhost[j][k] = '\0';				j++;				k = 0;			} else		lhost[j][k++] = rbuffer[i];		return (atoi(lhost[4])*256 + atoi(lhost[5]));	}}void GetFileListing (URLp URL){}bool ReadFTPListing (URLp URL)/***************************************	bool ReadFTPListing**** PRE:  URL has been Parse()'d and Connect()'ed** POST: Sets URL->sockfd up for reading and determines the files size.*************************************/{	int i = 0, j = 0, k = 0, listfd = 0, datafd = 0, noretry = 0;	unsigned int tempport = 0;	int whitespace = 0;	char *buffer;	struct sockaddr_in datastream, liststream;	URL->size = malloc(15);	NOSIZE = 0;	buffer = malloc(64000);	/* Reads from the FTP socket until 200 (ok) is reached	*/	i = ReadSock(URL->sockfd, buffer, "\n200");	/* If a 501 is found, then the FTP site DOESN'T support resuming */	if (strstr(buffer, "\n501"))		noretry = 1;	listfd = socket(AF_INET, SOCK_STREAM, 0);	tempport = ReadPASVPort(buffer);		/* If we can't find a valid port to connect to, or can't open		a socket to read the file listing, then an error occurs */	if (tempport == 0 || listfd == -1 || !i)	{	URL->retry = 1;		/* Server returns 530 if busy */		if (strstr(buffer, "\n530") != NULL || strstr(buffer, "\n421") != NULL)			if (OUTPUT_LEVEL > 0)				printf(" because server is busy");		else			URL->retry = 0;		write(URL->sockfd, "\r\nQUIT\r\n", 8);		close(URL->sockfd);		close(listfd);		if (OUTPUT_LEVEL > 0)			printf("!\n");			if (OUTPUT_LEVEL > 0 && listfd == -1)			printf("Error opening socket to FTP server for LIST!\n\n");			return(0);	}	liststream.sin_family = AF_INET;	liststream.sin_port = htons(tempport);	memcpy(&liststream.sin_addr, URL->host->h_addr, URL->host->h_length);        if (OUTPUT_LEVEL > 0)                printf ("[ CONNECTING TO PORT %d FOR FILE LISTING ]\n\n", tempport);  	/* Attempts to connect to socket for list of files */	if (connect(listfd, (struct sockaddr *)&liststream, sizeof(liststream)) == -1)	{	if (OUTPUT_LEVEL > 0)			printf("Error connecting to FTP socket for LIST!\n");		write(URL->sockfd, "\r\nQUIT\r\n", 8);		close(listfd);		return(0);	}	/* Reads the socket for the file listing */	if(!ReadSock(listfd, buffer, "\r\n\r\n"))	{	URL->retry = 1;		write(URL->sockfd, "\r\nQUIT\r\n", 8);		close(listfd);		return(0);	}			close(listfd);	if (strlen(buffer) < 7 || strstr(buffer, "No such file or directory") != NULL)		/* file not found */	{	if (OUTPUT_LEVEL > 0)			printf("Error:  No file or files found!\n");		write(URL->sockfd, "\r\nQUIT\r\n", 8);		close(listfd);		URL->retry = 0;		return(0);	}	if (buffer[0] != '-' && buffer[0] != 'd' && buffer[0] != 'l')		buffer = strchr(buffer, '\n') + 1;	if (((URL->filename == NULL || strstr(buffer, "\nd") || buffer[0] == 'd')		&& URL->recurse >= 0) || buffer[0] == 'l')	{	RecurseFTP (URL->name, buffer, URL->recurse);		URL->done = 1;		URL->retry = 0;		sleep(3);		return (0);	} else if ((strstr(buffer, "\nd") != NULL || buffer[0] == 'd') && URL->recurse < 0)	{	if (OUTPUT_LEVEL > 0)                        printf("Directory hit... Ignoring!\n");                 write(URL->sockfd, "\r\nQUIT\r\n", 8);                close(listfd);                URL->retry = 0;                return(0);        }	/* queues the variable 'j' to the start of the filesize */	/* Sample: "-rwx-wx--x 1 root wheel 1024 /etc/passwd" */	while ((unsigned)j < strlen(buffer) && whitespace < 4)	{	if (buffer[j] == ' ' && buffer[j + 1] != ' ')			whitespace ++;		j++;	}		k = j;	/* Calculates the size of the string being read in */	for (i = 0; (unsigned)j < strlen(buffer); j++)		if (buffer[j] == ' ' || (buffer[j] > ('0' - 1) && buffer[j] < ('9' + 1)))			i++;		else			j = strlen(buffer);		/* Allocates space for the string */	URL->total = malloc(i + 1);	j = k;	k = 0;	/* reads the first set of numbers it finds into the string URL->total */	for (i = 0; (unsigned)j < strlen(buffer); j++)		if (buffer[j] == ' ' || (buffer[j] > ('0' - 1) && buffer[j] < ('9' + 1)))		{	URL->total[i++] = buffer[j];			if (buffer[j] != ' ')				k = 1;		}		else			j = strlen(buffer);	URL->total[j - 4] = '\0';	URL->ltotal = atol(URL->total);	if (OUTPUT_LEVEL > 1)	{	printf("# File: %s\n",URL->filename);		if (!isdigit(URL->total[0]))			printf("# File size is unknown!\n");		else			printf("# File size: %ld kbytes (%ld bytes)\n", (long int)((URL->ltotal)/1024+.5), URL->ltotal);	}			usleep(FTP_WAIT_TIME);	if (!noretry)		write(URL->sockfd, "REST 0\r\n", 8);	usleep(FTP_WAIT_TIME);	write(URL->sockfd, "PASV\r\n", 6);	usleep(FTP_WAIT_TIME);	write(URL->sockfd, "NOOP\r\n", 6);	/* Note, it looks for a 200, which NOOP returns */	if(!ReadSock(URL->sockfd, buffer, "\n200"))	{	URL->retry = 1;		write(URL->sockfd, "\r\nQUIT\r\n", 8);		close(listfd);		return(0);	}	/* If a 350 is returned, then you cannot resume the file! */	if (strstr(buffer, "\n350") == NULL)		URL->retry = 0;	tempport = ReadPASVPort(buffer);	if (!tempport)	{	URL->retry = 1;		printf(" for file retrieval!\n");		write(URL->sockfd, "\r\nQUIT\r\n", 8);		close(URL->sockfd);		return (0);	}	/* Opens up the file for appending, seeks to the end of the file and 		determines teh files size from its current location */	if (strchr(URL->filename, ' ') != NULL)		for (i = 0; i < strlen(URL->filename); i++)     			if (URL->filename[i] == ' ')				URL->filename[i] = '_';	URL->fp = fopen (URL->filename, "a+b");	if (URL->fp == NULL)	{	printf("Error opening file!\n");		exit(69);	}	fseek (URL->fp,0,SEEK_END);	URL->lsize = ftell(URL->fp);	/* If the size is of the file (according to the FTP server)		is 0 bytes, or it doesn't return the file size,		the file is set to 2 gigs (doesn't effect transfer)		and the NOSIZE flag is set */	if (k == 0)	{	URL->ltotal = 2000000000;		NOSIZE = 1;	}	/* If the size of the file is greater than or equal to the size		the ftp server reports, then the file is already finished!		If URL->fp is NULL, then an error has occured when opening		the file */	if ((URL->lsize >= URL->ltotal && URL->ltotal != 0) || URL->fp == NULL)	{	if (OUTPUT_LEVEL > 0)			printf("Error... It seems this file has already been downloaded OR it's "				"currently in use!\n");		write(URL->sockfd, "\r\nQUIT\r\n", 8);		close(datafd);		URL->retry = 0;		return(0);	}	/* If the size of the file is smaller then the set ROLLBACK size,		then the file size is reset to 0, otherwise it rolls		the file size back ROLLBACK bytes */	if (URL->lsize < ROLLBACK || !URL->retry)		URL->lsize = 0;	else		URL->lsize -= ROLLBACK;	sprintf(URL->size, "%ld", URL->lsize);	if (OUTPUT_LEVEL > 1)		printf("# Found %ld kbytes : resuming from byte %ld.\n\n", URL->lsize/1024, URL->lsize);        if (OUTPUT_LEVEL > 0)                printf ("[ REQUESTING FILE TRANSFER ]\n");  	/* Tells the FTP server that you want to resume a file at		URL->size bytes */	usleep(FTP_WAIT_TIME);	write(URL->sockfd, "TYPE I\r\n", 8);	usleep(FTP_WAIT_TIME);	if (!noretry)	{	write(URL->sockfd, "REST ", 5);		write(URL->sockfd, URL->size, strlen(URL->size));		write(URL->sockfd, "\r\n", 2);	}	usleep(FTP_WAIT_TIME);	write(URL->sockfd, "RETR ", 5);	usleep(FTP_WAIT_TIME);	write(URL->sockfd, URL->file, strlen(URL->file));	usleep(FTP_WAIT_TIME);	write(URL->sockfd, "\r\n", 2);	usleep(FTP_WAIT_TIME);	/* Sets the dldots equal to the amount that is already downloaded */	dldots = URL->lsize / ROLLBACK;	datafd = socket(AF_INET, SOCK_STREAM, 0);	if (datafd == -1)	{	if (OUTPUT_LEVEL > 0)			printf("Error opening socket to FTP server for RETR!\n");		write(URL->sockfd, "\r\nABOR\r\nQUIT\r\n", 14);		close(datafd);		close(URL->sockfd);		URL->retry = 1;		return(0);	}	datastream.sin_family = AF_INET;	datastream.sin_port = htons(tempport);	memcpy(&datastream.sin_addr, URL->host->h_addr, URL->host->h_length);	if (connect(datafd, (struct sockaddr *)&datastream, sizeof(datastream)) == -1)	{	if (OUTPUT_LEVEL > 1)			printf("Error connecting to FTP socket for RETR!\n");		write(URL->sockfd, "\r\nABOR\r\nQUIT\r\n", 14);		close(datafd);		URL->retry = 1;		return(0);	}	if(!ReadSock(URL->sockfd, buffer, "\n150"))	{	URL->retry = 1;		write(URL->sockfd, "\r\nQUIT\r\n", 8);		close(listfd);		return(0);	}	write(URL->sockfd, "\r\nQUIT\r\n", 8);	listfd = URL->sockfd;	URL->sockfd = datafd;	close (listfd);	URL->lleft = URL->ltotal - URL->lsize;	if (OUTPUT_LEVEL > 0)	{	printf ("[ REQUEST FOR FILE %s SUCCESSFUL! ]\n", URL->filename);		printf ("[ CONNECTION ESTABLISHED, TRANSFERRING FILE ]\n\n\n");	}	if (OUTPUT_LEVEL > 1 && STDOUT == 0)		printf("[.");	/* Shrinks the file size for the rollback */	ftruncate(fileno(URL->fp), URL->lsize);	usleep(FTP_WAIT_TIME);	return (1);}void RecurseFTP (char* URLname, char *buff, int rec){	char *tname;	char *tfilename;	char *buffer;	char tempch;	int i, j, ahead;	char type;	buffer = buff;	if (strchr (buffer, '\r') == NULL)		tempch = '\n';	else		tempch = '\r';	while (buffer != NULL && buffer[0] != '\n' && strlen (buffer) > 7)	{	tname = malloc (4096);		tfilename = malloc (1024);		tname = strcpy(tname, URLname);		type = buffer[0];		i = 1; j = 0;		while ((unsigned)i < strlen(buffer) && j < 8)		{	if (buffer[i] == ' ' && buffer[i + 1] != ' ')				j ++;			i++;		}/*		for (i = 1; i < strlen(buffer) && buffer[i] != tempch; i++);		for (; i > 0 && buffer[i - 1] != ' '; i--);*/		j = 0;		while (buffer != NULL && buffer[i] != tempch)		{	tfilename[j] = buffer[i];			j++; i++;		}		tfilename[j] = '\0';		ahead = 0;		if (type == 'l')		{	if (strstr(tfilename, " -> ") != NULL)				ahead = strlen(tfilename) - strlen(strstr(tfilename, " -> ")) + 4;			*strrchr(tname, '/') = '\0';		}		tfilename += ahead;		if (tname[strlen(tname) - 1] != '/')			strcat(tname, "/");		strcat(tname, tfilename); 		if (buffer != NULL)		{   if (tfilename[strlen(tfilename) - 1] != '.' &&			(strstr(tfilename, "/.") == NULL || strlen(strstr(tfilename, "/.")) > 3))			switch (type)			{	case '-':					if (OUTPUT_LEVEL > 0) 						printf("+Added file: %s\n", tname);					InsertURL(tname, 0);					break;				case 'l':					if (rec >= 0)					{	if (OUTPUT_LEVEL > 0) 							printf("+Added");						InsertURL(tname, rec - 1);					} else						if (OUTPUT_LEVEL > 0) 							printf("-IGNORED");					if (OUTPUT_LEVEL > 0) 						printf(" link: %s\n", tname);					break;				case 'd':					if (rec > 0)					{	if (OUTPUT_LEVEL > 0) 							printf("+Added");						InsertURL(strcat(tname, "/"), rec - 1);					} else						if (OUTPUT_LEVEL > 0) 							printf("-IGNORED");					if (OUTPUT_LEVEL > 0) 						printf(" directory: %s\n", tname);					break;				default:					if (OUTPUT_LEVEL > 0) 						printf("Unrecognized file type for: %s\n", tname);					break;			}			buffer = strchr(buffer, '\n');			if (buffer != NULL)				buffer++;		}		tfilename -= ahead;		free (tfilename);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -