/*      Get and Resume Elite EDition source code


Get and Resume Elite EDition (GREED)
Copyright (C) 1999  Anoakie Turner

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.

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"

bool NumericHost(char *host);


bool Connect(URLp URL)
/*************************************
**	bool Connect (URLp)
**
** Pre:  URL MUST be parsed before a connection can take place!
** Post: Client connected to target server
*************************************/
{	struct in_addr Oaddress;

	/* If there is a proxy set, then use the proxy's info */
	if (PROXY[0] != '\0')
	{	if (NumericHost(PROXY))
		{
				#ifdef SUNOS
			if ((URL->host = inet_addr(PROXY)) == (in_addr_t)-1)
				#else
			if (!inet_aton(PROXY, &Oaddress))
				#endif
			{	printf("ERROR:  Incorrect proxy address!\n");
				URL->retry = 0;
				return (0);
			}
			else
				URL->host = gethostbyaddr((char *) &Oaddress, sizeof (struct in_addr), AF_INET);
		} else
			URL->host = gethostbyname(PROXY);
		address.sin_port = htons((unsigned)atoi(PROXYPORT));
	} else
	{	address.sin_port = htons(URL->port);
		if (NumericHost(URL->server))
		{
				#ifdef SUNOS
			if ((URL->host = inet_addr(URL->server)) == (in_addr_t)-1)
				#else
			if (!inet_aton(URL->server, &Oaddress))
				#endif
			{	printf("ERROR: numeric address incorrect!");
				URL->retry = 0;
				return (0);
			}
			else
				URL->host = gethostbyaddr((char *) &Oaddress, sizeof (struct in_addr), AF_INET);
		} else
			URL->host = gethostbyname(URL->server);
	}

	if (URL->host == NULL)
	{	if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
			fprintf(out, "%d:mb:Error#Error resolving hostname.\n",
				URL->pid);
#else
			printf("Error resolving %s!\n", URL->server);
#endif
		URL->retry = 0;
		return(0);
	}

	if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
		fprintf(out, "%d:lb:Connecting to %s:%d\n", URL->pid, URL->server,
			URL->port);
#else
		printf("[ CONNECTING TO\t: %s:%d ]\n", URL->server, URL->port);
#endif
	URL->sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (URL->sockfd == -1)
	{	if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
			fprintf(out, "%d:mb:Error#Error opening socket.\n",
				URL->pid);
#else
			printf("Error opening socket!\n");
#endif
		URL->retry = 0;
		return(0);
	}

	address.sin_family = AF_INET;
	memcpy(&address.sin_addr, URL->host->h_addr, URL->host->h_length);

	if(connect(URL->sockfd, (struct sockaddr *)&address, sizeof(address)) < 0)
	{	if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
			fprintf(out, "%d:mb:Error#Error connecting to server.\n",
				URL->pid);
#else
			printf("Error connecting to server!\n");
#endif
		URL->retry = 0;
		return(0);
	} else
	{	if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
			fprintf(out, "%d:lb:Connection established...\n",
				URL->pid);
#else
			printf ("** CONNECTION SUCCESSFULLY ESTABLISHED **\n");
#endif
		if (URL->protocol == HTTP)
			SendHTTPConnectData(URL);
		else
			SendFTPConnectData(URL);
	}
	return (1);
}


void SendFTPConnectData (URLp URL)
/*************************************
**	bool SendFTPConnectData (URLp)
**
** Pre:  URL MUST be parsed, and you must be connected to target server!
** Post: FTP Header sent to target server
*************************************/
{	char *temp;
	int i;
	int log = 1;
	i = 0;

	if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
		fprintf(out, "%d:lb:Sending connection data\n",
				URL->pid);
#else
		printf ("[ SENDING CONNECTION DATA\t: ");
#endif

	if (log)
	{	write(URL->sockfd, "USER ", 5);
		write(URL->sockfd, URL->user, strlen(URL->user));
		write(URL->sockfd, "\r\n", 2);
	fflush(NULL);
		usleep(FTP_WAIT_TIME);
		if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
			fprintf(out, "%d:lb:USER\n", URL->pid);
#else
			printf ("USER/");
#endif
		write(URL->sockfd, "PASS ", 5);
		write(URL->sockfd, URL->pass, strlen(URL->pass));
		write(URL->sockfd, "\r\n", 2);
	fflush(NULL);
		usleep(FTP_WAIT_TIME);
		if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
			fprintf(out, "%d:lb:PASS\n", URL->pid);
#else
			printf ("PASS/");
#endif
	}
	write(URL->sockfd, "PASV\r\n", 6);
fflush(NULL);
	usleep(FTP_WAIT_TIME);
	if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
		fprintf(out, "%d:lb:PASV\n", URL->pid);
#else
		printf ("PASV/");
#endif
	write(URL->sockfd, "REST 0\r\n", 8);
fflush(NULL);
	usleep(FTP_WAIT_TIME);
	if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
		fprintf(out, "%d:lb:REST\n", URL->pid);
#else
		printf ("REST/");
#endif
	write(URL->sockfd, "NOOP\r\n", 6);
fflush(NULL);
	usleep(FTP_WAIT_TIME);
	if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
		fprintf(out, "%d:lb:NOOP\n", URL->pid);
#else
		printf ("NOOP/");
#endif
	write(URL->sockfd, "LIST -L ", 8);
/*	write(URL->sockfd, "LIST -A ", 8);
	write(URL->sockfd, "LIST ", 5); */
	if (strstr(URL->user, "anonymous") == NULL)
		write(URL->sockfd, "~", 1);
	if (strchr(URL->file, ' ') == NULL)
		write(URL->sockfd, URL->file, strlen(URL->file));
	else
	{	temp = malloc(strlen(URL->file) + 1);
		strcpy(temp, URL->file);
		for (i = 0; i < strlen(temp); i++)
			if (temp[i] == ' ')
				temp[i] = '?';
		write(URL->sockfd, temp, strlen(temp));
	}
	write(URL->sockfd, "\r\n", 2);
fflush(NULL);
	usleep(FTP_WAIT_TIME);
	if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
		fprintf(out, "%d:lb:LIST\n", URL->pid);
#else
		printf ("LIST ]\n");
#endif
	URL->resume = 1;
}


void SendHTTPConnectData (URLp URL)
/*************************************
**	bool SendHTTPConnectData (URLp)
**
** Pre:  URL MUST be parsed, and you must be connected to target server!
** Post: HTTP Header sent to target server
*************************************/
{	if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
		fprintf(out, "%d:lb:Sending HTTP header info\n", URL->pid);
#else
		printf ("[ SENDING HTTP HEADER INFORMATION ]\n\n");
#endif

	write(URL->sockfd, "GET ", 4);
	if (PROXY[0] != '\0')
		write(URL->sockfd, URL->name, strlen(URL->name));
	else
		write(URL->sockfd, URL->file, strlen(URL->file));
	write(URL->sockfd, " HTTP/1.1\r\nHost: ", 17);
	write(URL->sockfd, URL->server, strlen(URL->server));
	write(URL->sockfd, ":", 1);
	write(URL->sockfd, URL->cport, strlen(URL->cport));
	if(REFERRER || REF[0] != '\0')
	{	write(URL->sockfd, "\r\nReferer: ", 11);
		if(REFERRER)
			write(URL->sockfd, URL->name, strlen(URL->name));
		else
			write(URL->sockfd, REF, strlen(REF));
	}
	write(URL->sockfd, "\r\nUser-Agent: ", 14);
	write(URL->sockfd, "Mozilla/", 8);
	write(URL->sockfd, CURRENT_VERSION, strlen(CURRENT_VERSION));
	write(URL->sockfd, "\r\nAccept: *.*, */*\r\n", 20);
	if (strstr(URL->name, "anonymous") == NULL)
	{	write(URL->sockfd, "Authorization: Basic ", 21);
		write(URL->sockfd, URL->user, strlen(URL->user));
	}
	write(URL->sockfd, "\r\nRange: bytes=", 15);
}

bool NumericHost(char *host)
{	int i = 0;
	for(; i < strlen(host); i++)
		if(!isdigit(host[i]) || host[i] != '.')
			return (0);
	return (1);
}
