/*      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"


struct timeval timeout;
unsigned long int eta;
unsigned long int tmp;
char unit;


void Download(URLp URL)
/*************************************
**	void Download(URLp URL)
**
**	Downloads up to 4k of data from URL->sockfd and writes it to URL->fp
**
** Pre:  Assigned(URL->sockfd) && Assigned(URL->lleft) && Assigned(URL->fp) && URL->done != 1
** Post: set URL->done = 1, if finished.
*************************************/
{	int bsize = 1;
	char *buff = malloc(ROLLBACK);
	float amtdl = 0.0;
	time_t t_diff;

	timeout.tv_sec = TIMEOUT_SEC;

	switch(select(FD_SETSIZE, &testfds, (fd_set *)0, (fd_set *)0, &timeout))
	{	case 0:
			if (OUTPUT_LEVEL > 1)
#ifdef USE_GTK
				fprintf(out, "%d:lb:timeout\n", URL->pid);
#else
				printf("]\ntimeout!\n");
#endif
			URL->done = 1;
			break;
		case -1:
#ifdef USE_GTK
			fprintf(out, "%d:mb:Big socket error or something!\n",
					URL->pid);
#else
			printf("Big socket error or something!\n");
#endif
/* Start new code (B5) +Honza Tomasek, bug fix+ */
			URL->done = (URL->lleft==0);
			URL->retry = !URL->done;
/* End new code */
/* Start replaced code
			URL->retry = 0;
			URL->done = 1;
   End replaced code */
			close(URL->sockfd);
			fclose(URL->fp);
			return;
			break;
		default:
			bsize = read(URL->sockfd, buff, sizeof(buff));
			URL->lleft = URL->lleft - bsize;
			if (bsize > 0)
				dlstat += bsize;

			if (STDOUT == 1)
			{	buff[bsize + 1] = '\0';
				printf("%s", buff);
			}
			else
				fwrite(buff, bsize, 1, URL->fp);

			if (dlstat > ROLLBACK - 1)
			{
#ifndef USE_GTK
				if (OUTPUT_LEVEL > 2 && STDOUT == 0)
					printf(".");
#endif
				dlstat -= ROLLBACK;

				fflush(NULL);
				dldots ++;

#ifndef USE_GTK
				if (dldots%50 == 0)
				{
#endif
					tmp = (dldots - URL->lsize/ROLLBACK) % 50;
					if (tmp == 0)
						tmp = 50;

					t_diff = time((time_t *)0) - start;
					if (!t_diff)
						t_diff = 1;

					amtdl = ((float)((ROLLBACK * tmp) / 1024)) / ((float)t_diff);


					tmp = dldots * ROLLBACK;
					eta = (unsigned int)((URL->ltotal - tmp)/(amtdl*1024));

					if (eta < 60 * 2)
						unit='s';
					else if (eta < 60*60*2)
					{	unit = 'm';
						eta = (int)(eta/60);
					}
					else
					{	unit='h';
						eta=(int)(eta/(60*60));
					}

					if (OUTPUT_LEVEL > 1)
#ifdef USE_GTK
					{	fprintf(out, "%d:lb:%ldkb downloaded$%.2f kb/s$ETA:%ld %c\n",
							URL->pid, tmp/1024, amtdl, eta, unit);
						fprintf(out, "%d:pb:%f\n", URL->pid,
							((float)tmp)/(float)URL->ltotal);
					}
#else
						printf("] %ldk @ %.2f k/s : %ld %c\n[.", tmp/1024,
							amtdl, eta, unit);
#endif
					start = time((time_t *)0);
#ifndef USE_GTK
				} else
				{	if (time((time_t *)0) == end && MINSPEED != 0)
						sleep((ROLLBACK/MINSPEED)/1024);
					else if (MINSPEED != 0
					 	 && (int)((ROLLBACK/1024)/(time((time_t *)0) - end) - MINSPEED) > 0)
							sleep((int)((ROLLBACK/1024)/(time((time_t *)0) - end) - MINSPEED));
				}
#endif
				end = time((time_t *)0);
			}
			break;
		}

	free(buff);


	if ((bsize < 1) || (URL->lleft < 1 && URL->resume))
	{	if (OUTPUT_LEVEL > 1)
		{	if (dldots%50 == 0)
#ifdef USE_GTK
			{	fprintf(out, "%d:lb:Checking completion status\n", URL->pid);
#else
			{	printf("]\n\n[ CHECKING COMPLETION STATUS ]\n");
#endif
			} else
			{
				t_diff = time((time_t *)0) - start;
				if (t_diff == 0) t_diff = 1;
#ifdef USE_GTK
				fprintf(out, "%d:lb:%ldkb dowloaded$%.2f kb/s$Checking Completion Status...\n",
					URL->pid, (ROLLBACK * dldots)/1024,
					((float)((ROLLBACK * (dldots%50)) / 1024)) /
					 ((float)t_diff));
#else
				printf("] %ldk @ %.2f k/s\n\nChecking Completion Status...\n",
					(ROLLBACK * dldots)/1024,
					((float)((ROLLBACK * (dldots%50)) / 1024)) /
					 ((float)t_diff));
#endif
			}
		}

#ifndef __riscos__
		if (OUTPUT_LEVEL > 0)
			perror(NULL);
#endif /* !__riscos__ */

		close(URL->sockfd);
		fclose(URL->fp);
		URL->done = 1;
		if((NOSIZE && !URL->retry) || (URL->lleft > 1 && !NOSIZE))
		{	URL->retry = 1;
			if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
				fprintf(out, "%d:lb:File not finished\n", URL->pid);
#else
				printf("** FILE NOT FINISHED **\n\n");
#endif
		}
		else
		{	URL->done = 1;
			URL->retry = 0;
			if (OUTPUT_LEVEL > 0)
#ifdef USE_GTK
				fprintf(out, "%d:lb:Done!\n", URL->pid);
#else
				printf("[ %s DONE! ]\n\n\n", URL->filename);
#endif
		}
	}
}
