/*
**  Flash.c 1.00 (29.08.97)
**
**  Because this program has NO STARTUP MODULE, it is CLI ONLY !!! 
**
**  See SAS/C Development System User's Guide, Volume 1, page 160,
**  'Writing applications without a Startup Module'.
**
**  Use of the Quit: label is no residue of BASIC programming, but
**  greatly  improves source readability. It's also very easy when
**  necessary to break in case of errors.
*/


#include <dos.h>
#include <dos/dostags.h>
#include <dos/rdargs.h>
#include <exec/memory.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/utility.h>
#include <stdio.h>
#include <string.h>


#define  BUFSIZE  500000


UBYTE *Version = { "$VER: Flash 1.00 (23.09.97)" };


__saveds void Flash( void )
{
  BOOL del = FALSE;
  BPTR ifp = 0, ofp = 0, lock = 0;
  char file[ FMSIZE ], *inbuf = 0;
  char register *p, *s, *tmp;
  LONG oldpos, vec[ 3 ] = { 0, 0, 0 };
  struct ExecBase *SysBase = ( * ( ( struct ExecBase ** ) 4 ));
  struct RDArgs *rda = 0;
  UBYTE f, pos;                                //  f is used with file[]. 
  ULONG register x;
  UWORD seclen;


  if (! ( DOSBase = ( struct DosLibrary * )
                                       OpenLibrary( "dos.library", 37L )) )
    goto Quit;
  
  
  if (! ( rda = 
        ReadArgs( "Index/A,OutDir/A,Delete/S", vec, 0L )) != 0L )
    {
      Printf( "INDEX/A,OUTDIR/A,DELETE/S\n" );
      
      goto Quit;                                   //  Missing arguments. 
    }
  
  
  if (! ( ifp = Open( ( STRPTR ) vec[ 0 ], MODE_OLDFILE )) )
    {
      Printf( "\"%s\" not found\n", vec[ 0 ] );
      
      goto Quit;                                //  Index file not found. 
    }
      
      
  if (! ( lock = Lock( ( STRPTR ) vec[ 1 ], ACCESS_READ )) )
    {
      Printf( "Cannot find output dir \"%s\"\n", vec[ 1 ] );
      
      goto Quit;                                //  Output dir not found. 
    }
  
  
  del = vec[ 2 ] != NULL ? TRUE : FALSE;        //  Delete Index file ??? 
  
  
  for ( f = 0, p = ( char * ) vec[ 1 ]; ( file[ f ] = *p++ ) != NULL; ++f )
    ;
  
  if ( file[ f - 1 ] != ':' && file[ f - 1 ] != '/' )
    {
      file[ f++ ] = '/';                         //  Copy outdir to file. 
      
      file[ f ] = '\0';
    }
  
  
  if (! ( inbuf = ( UBYTE * ) AllocVec( BUFSIZE, MEMF_ANY | MEMF_CLEAR )) )
    goto Quit;
  
  
  Read( ifp, inbuf, BUFSIZE - 150 );        //  If p == NULL, refill buf. 
  
  
  if ( inbuf[ BUFSIZE - 150 - 1 ] != '\n' )       //  Fill up buffer with 
    {                                             //  complete line.      
      oldpos = Seek( ifp, 0, OFFSET_CURRENT );
      
      FGets( ifp, &inbuf[ BUFSIZE - 150 ], 150 );   
      
      for ( x = 0; inbuf[ BUFSIZE - 150 + x++ ] != '\n'; )
        ;
      
      Seek( ifp, oldpos + x, OFFSET_BEGINNING );
    }
  
  
  p = inbuf;
  
  while ( *p == '|' )                           //  Skip comment lines.   
    while ( *p++ != '\n' )
      ;                          //  p now points to beginning of output. 
  
  
  for ( pos = 0, tmp = p; *tmp != ' '; ++pos, ++tmp )
    ;
                                      //  Find section, e.g. biz/dbase.   
  for ( ; *tmp == ' '; ++pos, ++tmp ) //  pos = offset from p to section. 
    ;
  
  
  x = pos;                     //  No need to start at beginning of line. 
  
  s = p + pos;
  
  
  for ( tmp = s, seclen = 0; *tmp != '/'; ++tmp, ++seclen )
    ;
                           // ^-- seclen = lenght of e.g. biz/dbase.      
  
  tmp = p + pos;           //  tmp now points to very first section name. 
  
  
  while ( *p != NULL )
    {
      while ( *s != NULL )
        {
          while ( ++x && *s++ != '\n' )    //  Find end of line, increase 
            ;                              //  x equally with s.          
          
          
          if ( strncmp( tmp, s + pos, seclen ) != NULL ) 
            {
              file[ f ] = '\0';
              
              strncat( file, tmp, seclen );
              
              
              if ( ofp = Open( file, MODE_OLDFILE ))          //  Append. 
                Seek( ofp, 0, OFFSET_END );
              else if (! ( ofp = Open( file, MODE_NEWFILE )) )
                goto Quit;
              
              
              Write( ofp, p, x );
              
              Close( ofp );
              
              ofp = NULL;
              
              
              p = s;             //  p points to beginning of new output. 
              
              s += pos;
              
              
              for ( tmp = s, seclen = 0; *tmp != '/'; ++tmp, ++seclen )
                ;
                
              
              tmp = s;                       //  Set new strncmp() value. 
              
              x = pos;                       //  Reset x.                 
            }
          else
            {
              x += pos;                 //  Skip to beginning of section. 
              
              s += pos;
            }
        }
      
      
      setmem( inbuf, BUFSIZE, 0 );
      
      Read( ifp, inbuf, BUFSIZE - 150 );
      
      
      if ( inbuf[ BUFSIZE - 150 - 1 ] != '\n' )   //  Fill up buffer with 
        {                                         //  complete line.      
          oldpos = Seek( ifp, 0, OFFSET_CURRENT );
          
          FGets( ifp, &inbuf[ BUFSIZE - 150 ], 150 );   
          
          for ( x = 0; inbuf[ BUFSIZE - 150 + x++ ] != '\n'; )
            ;
          
          Seek( ifp, oldpos + x, OFFSET_BEGINNING );
        }
      
      
      p = inbuf;
  
  
      for ( pos = 0, tmp = p; *tmp != ' '; ++pos, ++tmp )
        ;
                                          //  Find section eg. biz/dbase, 
      for ( ; *tmp == ' '; ++pos, ++tmp ) //  pos = offset from p to sec. 
        ;
      
      
      x = pos;                 //  No need to start at beginning of line. 
      
      s = tmp;
      
      
      for ( seclen = 0; *tmp != '/'; ++tmp, ++seclen )
        ;
                           // ^-- seclen = lenght of e.g. biz/dbase.      
      
      tmp = s;             //  tmp now points to very first section name. 
    }
  
  
  Quit:
  
    if ( ofp )
      Close( ofp );
    
    if ( inbuf )
      FreeVec( inbuf );
    
    if ( lock )
      UnLock( lock );
    
    if ( ifp )
      Close( ifp );
    
    if ( del )
      DeleteFile( ( STRPTR ) vec[ 0 ] );
    
    if ( rda )
      FreeArgs( rda );
    
    CloseLibrary( ( struct Library * ) DOSBase );
}
