#include"tcpdl.h"

BOOL __saveds
dotcpline( int task )
{
int s;
struct sockaddr_in sa;
struct Library *SocketBase;
int errno;
struct hostent *hp;
LONG nbytes;
int i;   
LONG length;
char tempstring[PFNSIZE+512];
char tempstring1[128];
BPTR inputfile;
BPTR outputfile;
ULONG port;
ULONG temptime;
ULONG dummy;
struct namedata *urldata;
STRPTR buffererror;
ULONG totalhtmlbytes;
BOOL local_accepted=FALSE;
BOOL texthtml=FALSE;
BPTR headerfile;

   SetTaskPri( FindTask(0), 4 );
   
   mmpoint->point[task].timeout=20;
   mmpoint->point[task].at_work++;
   
   /*phrasestring( &mmpoint->point[task].surl, mmpoint->point[task].curldata->urlname );*/
   
   sprintf( mmpoint->point[task].surl.type, "%s", mmpoint->point[task].curldata->typename );
   sprintf( mmpoint->point[task].surl.host, "%s", mmpoint->point[task].curldata->hostname );
   sprintf( mmpoint->point[task].surl.pathfilename, "%s", mmpoint->point[task].curldata->pathname );
   
   port=mmpoint->point[task].curldata->port;
   if( port==0 )
      return( TRUE );
   
   sprintf( tempstring, "%s                                                                                                                                                                                                                                                                ", mmpoint->point[task].curldata->urlname );
   tempstring[44]=0;
   
   sprintf( mmpoint->point[task].information2, "%s", tempstring );
   
   if( tst( mmpoint->point[task].curldata, acceptflag_update)==FALSE )
   {
      sprintf( tempstring, "tcpdldir:data/%s", mmpoint->point[task].curldata->urlfilename );
      inputfile=Open( tempstring, MODE_OLDFILE );
      if( inputfile!=0 )
      {
         Close( inputfile );
         sprintf( mmpoint->point[task].information1, "%s", "Updating   " );
         updatetree( mmpoint->point[task].curldata, task );
         return( TRUE );
      }
   }
   
   sprintf( mmpoint->point[task].information1, "%s", "Connecting " );
   
   Forbid();
   CurrentTime( &temptime, &dummy);
   mmpoint->point[task].starttime=temptime;
   Permit();
   
   SocketBase = OpenLibrary( "bsdsocket.library", (2L) );
   if( SocketBase == NULL)
   {
      sprintf( mmpoint->point[task].information1, "%s", "ERROR      " );
      mmpoint->ctrlcflag=TRUE;
      return( TRUE );
   }
   
   SetErrnoPtr(&errno, sizeof errno);
   
   SetSignal( 0L, SIGBREAKF_CTRL_C ); /* Clear CTRL-C */
   
   mmpoint->point[task].at_work++;
   hp=gethostbyname( mmpoint->point[task].surl.host );
   if( hp==NULL )
   {
      CloseLibrary( SocketBase ) ;
      sprintf( mmpoint->point[task].information1, "%s", "ERROR      " );
      clr( mmpoint->point[task].curldata, flag_IsDL );
      mmpoint->point[task].curldata->numberfailed++;
      return( FALSE );
      
      /* Connection Refused */
   }
   
   bzero(&sa, sizeof(sa));
   bcopy(hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
   sa.sin_family = hp->h_addrtype;
   sa.sin_port = htons((u_short)port);
   
   s=socket(hp->h_addrtype,SOCK_STREAM,0);
   if( s < 0 )
   {
      CloseLibrary( SocketBase ) ;
      sprintf( mmpoint->point[task].information1, "%s", "ERROR      " );
      clr( mmpoint->point[task].curldata, flag_IsDL );
      mmpoint->point[task].curldata->numberfailed++;
      return( FALSE);
      /* Something bad has happened */
   }
   
   mmpoint->point[task].at_work++;
   if( connect(s,(struct sockaddr *) &sa,sizeof(sa)) < 0 )
   {
      CloseSocket(s);
      CloseLibrary( SocketBase ) ;
      clr( mmpoint->point[task].curldata, flag_IsDL );
      sprintf( mmpoint->point[task].information1, "%s", "ERROR      " );
      mmpoint->point[task].curldata->numberfailed++;
      
      /* Couldn't reach host */
      
      return( FALSE );
   }
   
   /* Got Connection */
   
   mmpoint->point[task].timeout=60;
   
   sprintf( mmpoint->point[task].information1, "%s", "Sending    " );
   length=0;
   sprintf( tempstring, "tcpdldir:%s", mmpoint->point[task].curldata->urlfilename );
   inputfile=Open( tempstring, MODE_OLDFILE );
   if( inputfile!=0 )
   {
      Close( inputfile );
      sprintf( tempstring, "tcpdldir:data/%s", mmpoint->point[task].curldata->urlfilename );
      inputfile=Open( tempstring, MODE_OLDFILE );
      if( inputfile!=0 )
      {
         while( TRUE )
         {
            buffererror = FGets( inputfile, tempstring, PFNSIZE );
            if( buffererror==0 )
               break;
            
            if( Strnicmp( tempstring, "date", 4 ) == 0 )
            {
               i=4;
               while( tempstring[i]!=0 )
               {
                  if( (tempstring[i]==10) |  (tempstring[i]==13) )
                  {
                     tempstring[i]=0;
                     break;
                  }
                  i++;
               }
               
               if( i<120 )
               {
                  i=4;
                  while( (tempstring[i]==32) |  (tempstring[i]==58) )
                     i++;
                  
                  sprintf( tempstring1, "%s", &tempstring[i] );
                  length = sprintf( tempstring, "GET /%s HTTP/1.0\15\12From: %s <%s>\15\12User-Agent: %s\15\12Accept: */*\15\12If-Modified-Since: %s\15\12\15\12\0", mmpoint->point[task].surl.pathfilename, mmpoint->realname, mmpoint->username, VERSIONSTRING, tempstring1 );
               }
               break;
            }
         }
         Close( inputfile );
      }
   }
   
   if( length==0 )
      length = sprintf( tempstring, "GET /%s HTTP/1.0\15\12From: %s <%s>\15\12User-Agent: %s\15\12Accept: */*\15\12\15\12\0", mmpoint->point[task].surl.pathfilename, mmpoint->realname, mmpoint->username, VERSIONSTRING );
   
   mmpoint->point[task].at_work++;
   send( s, tempstring, length, 0 );
   mmpoint->point[task].at_work++;
   
   Forbid();
   mmpoint->point[task].currentsizecps=length;
   Permit();
   
   recv( s, &mmpoint->point[task].buffer[i], 0, 0 );
   
   sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
   headerfile = Open( tempstring, MODE_NEWFILE );
   
   sprintf( mmpoint->point[task].information1, "%s", "Header     " );
   while( TRUE )
   {
      i=0;
      while( TRUE )
      {
         mmpoint->point[task].at_work++;
         
         nbytes = recv( s, &mmpoint->point[task].buffer[i], 1, 0 );
         
         Forbid();
         mmpoint->point[task].currentsizecps++;
         mmpoint->totalbytes++;
         Permit();
         
         if( (nbytes!=1) | (mmpoint->ctrlcflag==TRUE) )
         {
            Close( headerfile );
            sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
            DeleteFile( tempstring );
            CloseSocket(s);
            CloseLibrary( SocketBase ) ;
            sprintf( mmpoint->point[task].information1, "%s", "ERROR      " );
            clr( mmpoint->point[task].curldata, flag_IsDL );
            mmpoint->point[task].curldata->numberfailed++;
            return( FALSE );
         }
         
         if( mmpoint->point[task].buffer[i]==10 )
            break;
         
         i++;
      }
      
      mmpoint->point[task].buffer[i]=0;
      
      i=0;
      while( TRUE )
      {
         if( (mmpoint->point[task].buffer[i]==0) | (mmpoint->point[task].buffer[i]==10) | (mmpoint->point[task].buffer[i]==13) )
         {
            mmpoint->point[task].buffer[i]=0;
            break;
         }
         i++;
      }
      
      if( mmpoint->point[task].buffer[0]==0 )
         break;
      
      if( headerfile!=0 )
      {
         FPuts( headerfile, mmpoint->point[task].buffer );
         FPuts( headerfile, "\12" );
      }
      
      if( Strnicmp( mmpoint->point[task].buffer, "Content-length", 14 ) == 0 )
      {
         i=14;
         while( (mmpoint->point[task].buffer[i]==32) | (mmpoint->point[task].buffer[i]==58) )
            i++;
         mmpoint->point[task].finalsize=0;
         
         while( (mmpoint->point[task].buffer[i]>47) & (mmpoint->point[task].buffer[i]<58) )
         {
            mmpoint->point[task].finalsize=mmpoint->point[task].finalsize*10+mmpoint->point[task].buffer[i]-48;
            i++;
         }
      }
      
      if( Strnicmp( mmpoint->point[task].buffer, "Content-type", 12 ) == 0 )
      {
         i=12;
         while( (mmpoint->point[task].buffer[i]==32) | (mmpoint->point[task].buffer[i]==58) )
            i++;
         
         if( (Strnicmp( &mmpoint->point[task].buffer[i], "text/", 5 ) == 0 ) & ((mmpoint->point[task].curldata->acceptflag&acceptflag_text)!=0) )
            local_accepted=TRUE;
         
         if( Strnicmp( &mmpoint->point[task].buffer[i], "text/html", 9 ) == 0 )
         {
            texthtml=TRUE;
            local_accepted=TRUE;
         }
         
      }
      
      if( Strnicmp( mmpoint->point[task].buffer, "HTTP/1.0 200 ", 13 ) == 0 )
         set( mmpoint->point[task].curldata, flag_Is200 );
   }
   
   sprintf( mmpoint->point[task].newfilename, "tcpdldir:data/temp/%08d.data.new", mmpoint->point[task].curldata );
   
   if( tst( mmpoint->point[task].curldata, flag_IsIMG) )
      local_accepted=TRUE;
   
   if( (mmpoint->point[task].curldata->acceptflag&acceptflag_all)!=0 )
      local_accepted=TRUE;
   
   if( local_accepted==FALSE )
   {
      Close( headerfile );
      sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
      DeleteFile( tempstring );
      CloseSocket(s);
      CloseLibrary( SocketBase ) ;
      SetTaskPri( FindTask(0), 0 );
      sprintf( mmpoint->point[task].information1, "%s", "Updating   " );
      updatetree( mmpoint->point[task].curldata, task );
      SetTaskPri( FindTask(0), 4 );
      sprintf( mmpoint->point[task].information1, "%s", "OK         " );
      return( TRUE );
   }
   
   outputfile = Open( mmpoint->point[task].newfilename, MODE_NEWFILE );
   if( outputfile == 0 )
   {
      /* Error:Couldn't open outputfile */
      Close( headerfile );
      sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
      DeleteFile( tempstring );
      CloseSocket(s);
      CloseLibrary( SocketBase ) ;
      sprintf( mmpoint->point[task].information1, "%s", "ERROR      " );
      return( TRUE );
   }
   
   Forbid();
   CurrentTime( &temptime, &dummy);
   mmpoint->point[task].starttimecps=temptime;
   Permit();
   
   mmpoint->point[task].currentsize=0;
   sprintf( mmpoint->point[task].information1, "%s", "Receiving  " );
   while( TRUE )
   {
      mmpoint->point[task].at_work++;
      nbytes = recv( s, mmpoint->point[task].buffer, BUFSIZE-1, 0 );
      Forbid();
      mmpoint->totalbytes=mmpoint->totalbytes+nbytes;
      Permit();
      mmpoint->point[task].at_work++;
      
      if( nbytes==-1 )
      {
         /* Error */
         Close( headerfile );
         sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
         DeleteFile( tempstring );
         Close( outputfile );
         DeleteFile( mmpoint->point[task].newfilename );
         CloseSocket(s);
         CloseLibrary( SocketBase ) ;
         sprintf( mmpoint->point[task].information1, "%s", "ERROR      " );
         mmpoint->point[task].curldata->numberfailed++;
         return( FALSE );
      }
      
      if( nbytes==0 )
         break;
      
      mmpoint->point[task].currentsize=mmpoint->point[task].currentsize+nbytes;
      
      Forbid();
      mmpoint->point[task].currentsizecps=mmpoint->point[task].currentsizecps+nbytes;
      Permit();
      
      if( Write( outputfile, mmpoint->point[task].buffer, nbytes ) != nbytes )
      {
         /* Error */
         Close( headerfile );
         sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
         DeleteFile( tempstring );
         Close( outputfile );
         DeleteFile( mmpoint->point[task].newfilename );
         CloseSocket(s);
         CloseLibrary( SocketBase ) ;
         sprintf( mmpoint->point[task].information1, "%s", "DISKERROR  " );
         mmpoint->ctrlcflag=TRUE;
         return( TRUE );
      }
   }
   
   Close( outputfile );
   CloseSocket(s);
   CloseLibrary( SocketBase ) ;
   
   mmpoint->point[task].finalsize=-1;
   mmpoint->point[task].starttimecps=0;
   
   if( mmpoint->point[task].currentsize==0 )
   {
      /* No data; upto date */
      Close( headerfile );
      sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
      DeleteFile( tempstring );
      DeleteFile( mmpoint->point[task].newfilename );
      
      SetTaskPri( FindTask(0), 0 );
      sprintf( mmpoint->point[task].information1, "%s", "Updating   " );
      updatetree( mmpoint->point[task].curldata, task );
      sprintf( mmpoint->point[task].information1, "%s", "OK         " );
      SetTaskPri( FindTask(0), 4 );
      
      return( TRUE );
   }
   
   /* Data recived */
   
   if( texthtml==FALSE )
   {
      Close( headerfile );
      sprintf( tempstring, "tcpdldir:%s", mmpoint->point[task].curldata->urlfilename );
      DeleteFile( tempstring );
      
      createpath( tempstring );
      Rename( mmpoint->point[task].newfilename, tempstring );
      
      /*  */
      
      sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
      inputfile=Open( tempstring, MODE_OLDFILE );
      if( inputfile!=0 )
      {
         sprintf( tempstring, "tcpdldir:data/%s", mmpoint->point[task].curldata->urlfilename );
         createpath( tempstring );
         outputfile=Open( tempstring, MODE_NEWFILE );
         copyfileclose( task, inputfile, outputfile );
      }
      else
         DisplayBeep( NULL );
      
      sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
      DeleteFile( tempstring );
      
      sprintf( mmpoint->point[task].information1, "%s", "OK         " );
      return( TRUE );
   }
   else
   {
      while( TRUE )
      {
         Forbid();
         if( mmpoint->namedatainuse==FALSE )
         {
            mmpoint->namedatainuse=TRUE;
            Permit();
            break;
         }
         Permit();
         Delay(1);
      }
      
      urldata=mmpoint->firsturldata;
      while( urldata!=0 )
      {
         urldata->flag_data=urldata->flag_data&(~(1<<task));
         urldata=urldata->next;
      }
      
      Forbid();
      mmpoint->namedatainuse=FALSE;
      Permit();
      
      SetTaskPri( FindTask(0), 0 );
      
      while( TRUE )
      {
         totalhtmlbytes=0;
         for( i=0;i<NUMBERPROCESSES;i++)
         {
            if( mmpoint->point[i].taskinghtml )
               totalhtmlbytes=totalhtmlbytes+mmpoint->point[i].currentsize;
         }
         if( totalhtmlbytes>262144 )
         {
            sprintf( mmpoint->point[task].information1, "%s", "Wait. html " );
            Delay( 100 );
         }
         else
            break;
      }
      
      mmpoint->point[task].taskinghtml=TRUE;
      readhtmlfile( task, mmpoint->point[task].curldata );
      mmpoint->point[task].taskinghtml=FALSE;
      SetTaskPri( FindTask(0), 4 );
      
      sprintf( mmpoint->point[task].information1, "%s", "Copying    " );
      
      urldata=mmpoint->firsturldata;
      while( urldata!=0 )
      {
         if( tst( urldata, (1<<task) ) )
         {
            if( tst( urldata, flag_IsIMG ) )
               FPuts( headerfile, "tcpdl_img: " );
            else
               FPuts( headerfile, "tcpdl_href: " );
            
            FPuts( headerfile, urldata->urlname );
            FPuts( headerfile, "\12" );
         }
         urldata=urldata->next;
      }
      Close( headerfile );
      
      sprintf( tempstring, "t:%08d.data.new", mmpoint->point[task].curldata );
      inputfile=Open( tempstring, MODE_OLDFILE );
      if( inputfile!=0 )
      {
         sprintf( tempstring, "tcpdldir:%s", mmpoint->point[task].curldata->urlfilename );
         createpath( tempstring );
         outputfile=Open( tempstring, MODE_NEWFILE );
         
         if( (inputfile==0) | (outputfile==0) )
         {
            if( inputfile!=0 )
               Close( inputfile );
            if( outputfile!=0 )
               Close( inputfile );

            sprintf( tempstring, "tcpdldir:data/%s", mmpoint->point[task].curldata->urlfilename );
            DeleteFile( tempstring );
         }
         else
            copyfileclose( task, inputfile, outputfile );
      }
      else
      {
         DisplayBeep( NULL );
         sprintf( tempstring, "t:%08d.data.new", mmpoint->point[task].curldata );
         DeleteFile( tempstring );
         sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
         DeleteFile( tempstring );
         sprintf( mmpoint->point[task].information1, "%s", "ERROR      " );
         return( TRUE );
      }
      
      sprintf( tempstring, "t:%08d.data.new", mmpoint->point[task].curldata );
      DeleteFile( tempstring );
      
      
      /*  */
      
      if( tst( mmpoint->point[task].curldata, flag_Is200 ) )
      {
         sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
         inputfile=Open( tempstring, MODE_OLDFILE );
         if( inputfile!=0 )
         {
            sprintf( tempstring, "tcpdldir:data/%s", mmpoint->point[task].curldata->urlfilename );
            createpath( tempstring );
            outputfile=Open( tempstring, MODE_NEWFILE );
            
            if( (inputfile==0) | (outputfile==0) )
            {
               if( inputfile!=0 )
                  Close( inputfile );
               if( outputfile!=0 )
                  Close( inputfile );
               
               sprintf( tempstring, "tcpdldir:data/%s", mmpoint->point[task].curldata->urlfilename );
               DeleteFile( tempstring );
            }
            else
               copyfileclose( task, inputfile, outputfile );
         }
         else
            DisplayBeep( NULL );
      }
      else
      {
         sprintf( tempstring, "tcpdldir:data/%s", mmpoint->point[task].curldata->urlfilename );
         DeleteFile( tempstring );
      }
      
      sprintf( tempstring, "t:%08d.http.new", mmpoint->point[task].curldata );
      DeleteFile( tempstring );
      
      sprintf( mmpoint->point[task].information1, "%s", "OK         " );
      return( TRUE );
   }
   return( TRUE );
}

void __saveds
updatetree( struct namedata *urldata, int task )
{
char tempstring[PFNSIZE+512];
BPTR inputfile;
struct namedata *tempstorage;
STRPTR buffererror;
int i;
int length;

   sprintf( tempstring, "tcpdldir:data/%s", urldata->urlfilename );
   inputfile=Open( tempstring, MODE_OLDFILE );
   if( inputfile!=0 )
   {
      while( TRUE )
      {
         buffererror = FGets( inputfile, tempstring, PFNSIZE );
         if( buffererror==0 )
            break;
         
         if( Strnicmp( tempstring, "tcpdl_img", 9 ) == 0 )
         {
            for( i=9;tempstring[i]!=0; i++ )
            {
               if( (tempstring[i]==10) |  (tempstring[i]==13) )
               {
                  tempstring[i]=0;
                  break;
               }
            }
            
            i=9;
            while( (tempstring[i]==32) |  (tempstring[i]==58) )
               i++;
            
            tempstorage = getfilenumber( &tempstring[i] );
            
            if( tempstorage!=0 )
            {
               set( tempstorage, flag_IsIMG );
               tempstorage->acceptflag=tempstorage->acceptflag|mmpoint->point[task].curldata->acceptflag;
            }
         }
         else
         if( Strnicmp( tempstring, "tcpdl_href", 10 ) == 0 )
         {
            for( i=10; tempstring[i]!=0; i++ )
            {
               if( (tempstring[i]==10) |  (tempstring[i]==13) )
               {
                  tempstring[i]=0;
                  break;
               }
            }
            
            i=10;
            while( (tempstring[i]==32) |  (tempstring[i]==58) )
               i++;
            
            tempstorage = getfilenumber( &tempstring[i] );
            
            if( tempstorage!=0 )
            {
               Forbid();
               tempstorage->acceptflag=tempstorage->acceptflag|mmpoint->point[task].curldata->acceptflag;
               tempstorage->flag_maxdiffhost=mmpoint->point[task].curldata->flag_maxdiffhost;
               tempstorage->flag_maxdiffpath=mmpoint->point[task].curldata->flag_maxdiffpath;
               if( tempstorage->flag_maxdeep>0 )
                  tempstorage->flag_maxdeep--;
               if( mmpoint->point[task].curldata->flag_maxdeep>0 )
               {
                  if( tempstorage->flag_maxdeep<(mmpoint->point[task].curldata->flag_maxdeep-1) )
                     tempstorage->flag_maxdeep=mmpoint->point[task].curldata->flag_maxdeep-1;
               }
               
               if( Strnicmp( tempstorage->hostname, mmpoint->point[task].curldata->hostname, -1 )!=0 )
               {
                  if( tempstorage->flag_maxdeep>urldata->flag_maxdiffhost )
                     tempstorage->flag_maxdeep=urldata->flag_maxdiffhost;
               }
               
               length=mmpoint->point[task].curldata->pathname-PathPart( mmpoint->point[task].curldata->pathname);
               if( Strnicmp( tempstorage->pathname, mmpoint->point[task].curldata->pathname, length )!=0 )
               {
                  if( tempstorage->flag_maxdeep>urldata->flag_maxdiffpath )
                     tempstorage->flag_maxdeep=urldata->flag_maxdiffpath;
               }
               
               Permit();
               set( tempstorage, flag_IsHREF );
            }
         }
      }
      Close( inputfile );
   }
   
   return;
}
   
