
/*

   This is the unfinished new version of a filelist to HBBS file list
   converter,  it is what I was working on when I stopped development
   of HydraBBS

   I was also experimenting with doing a PPC version of this utility..

   See the Usage() function for details...

   The goal was to make this converter work for any format of file
   list.  (ambitious, me ? :-)

   p.s.  this would have been cool if I finished it..

   Dominic Clifton
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <exec/exec.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <clib/exec_protos.h>

#include <dos/dos.h>
#include <libraries/dos.h>
#include <clib/dos_protos.h>

#include <HBBS/release.h>
char *versionstr="$VER: AX2HBBS "RELEASE_STR;

struct ColumnOffsets
{
  int co_Filename; /* these have to be int's for sscanf() */
  int co_Size;
  int co_Date;
  int co_Text;
};

struct ProgramData
{
  int YearPrefix;
  struct ColumnOffsets CO;
  char *infilename;
  char *outfilename;
  int MaxLineLength;
};


/*
 * set the defaults
 */

struct ProgramData PD={19,{1,15,24,34},NULL,NULL,1024};


void Usage( void )
{
  puts("Usage: AX2HBBS <infile> <outfile> [yearprefix] [column adjustments[,...]]\n"
       "Where column adjustments are specified thus:\n"
       "<column identifier><character offset (from 1)>"
       "Here's a list of column identifiers\n"
       "F = Filename, S = Size, D = Date, T = Desciption text\n"
       "e.g AX uses the following: F1,S15,D24,T34\n"
       "So a full example command line might be:\n"
       "\n"
       "AX2HBBS DIR1 ram:Files_1.TXT 19 F1,S15,D24,T34\n");
}

void DisplayColumnOffsets( struct ColumnOffsets *CO)
{
  printf(" Filename : %d\n"
         " Size     : %d\n"
         " Date     : %d\n"
         " Text     : %d\n",CO->co_Filename, CO->co_Size, CO->co_Date, CO->co_Text);
}


void ProcessColumnOffsetParam( char *param, struct ColumnOffsets *CO)
{

  /*
   * the long way
   * (more flexible, as offsets can be specified in any order)
   */

  /*

  int pos = 0;

  while (param[pos])
  {
    switch(param[pos++])
    {
      case 'F':
        sscanf(param+pos,"%d",&CO->co_Filename);
        break;
      case 'S':
        sscanf(param+pos,"%d",&CO->co_Size);
        break;
      case 'D':
        sscanf(param+pos,"%d",&CO->co_Date);
        break;
      case 'T':
        sscanf(param+pos,"%d",&CO->co_Text);
        break;
    }

  };

  */

  /*
   * the short way
   * (less flexible, paramaters must be specified in this order)
   */

  sscanf(param,"F%d,S%d,D%d,T%d",&CO->co_Filename, &CO->co_Size, &CO->co_Date, &CO->co_Text);

}

void ProcessFile( void )
{
  BPTR inFH=(BPTR)NULL,outFH=(BPTR)NULL;

  char *buffer;

  if (!(buffer = (char *) AllocVec(MEMF_PUBLIC,PD.MaxLineLength)))
  {
    puts("failed memory allocation");
    return;
  }

  if (!(inFH=Open(PD.infilename,MODE_OLDFILE)))
  {
    puts("Error opening inputfile");
  }
  else
  {

    if (!(outFH=Open(PD.outfilename,MODE_NEWFILE)))
    {
      puts("Error opening/creating outputfile");
    }
    else
    {

      /* quick mode: */

      struct FileInfoBlock *FIB;
      LONG nr;
      UBYTE *Data;
      ULONG Length;
      BOOL done,nearlydone,keepthis;
      LONG filepos=0,bufferpos,found=0;

      if (FIB=(struct FileInfoBlock *)AllocVec(sizeof(struct FileInfoBlock),MEMF_PUBLIC))
      {
        ExamineFH(inFH,FIB);
        Length=FIB->fib_Size;
        if (Data=AllocVec(Length,MEMF_PUBLIC))
        {
          if ((nr=Read(inFH,Data,Length))==Length)
          {

            do
            {
              keepthis=TRUE;
              bufferpos=0;
              done=FALSE;
              nearlydone=FALSE;
              do
              {
                if (Data[filepos]=='\r' || Data[filepos]=='\n')
                {
                  nearlydone=TRUE;
                  filepos++;
                }
                else
                {
                  if (nearlydone)
                  {
                    done=TRUE;
                  }
                  else
                  {
                    buffer[bufferpos++]=Data[filepos++];
                  }
                }
              } while (filepos<Length && !done && bufferpos< PD.MaxLineLength-2); // 1 for NULL and 1 more cos we still have to add the NULL
              buffer[bufferpos]=0;

              Write(outFH,buffer,bufferpos+1);

            } while (filepos<Length);

          }
          else
          {
            puts("error reading the file!");
          }

          FreeVec(Data);
        }
        FreeVec(FIB);
      }

      /*
       * files opened ok, so lets read the input file a bit..
       */

      /* slow mode:

      while (FGets(inFH,buffer,PD.MaxLineLength-1))
      {
        FPuts(outFH,buffer);
      };

      */

      Close(outFH);
    }


    Close(inFH);
  }

  FreeVec(buffer);
}

int main( int argc, char *argv[] )
{
  short nextparam=1;

/* debugging stuff

  printf("%d arg(s)\n",argc);
  DisplayColumnOffsets(&PD.CO);
*/

  /*
   * Process the parameters
   */

  if (argc < 3)
  {
    Usage( );
  }
  else
  {
    PD.infilename = argv[nextparam++];
    PD.outfilename = argv[nextparam++];

    if (nextparam < argc)
    {
      /*
       * if the first char of this next paramater is a number, then we're looking
       * at the date prefix
       */

      if (isdigit(argv[nextparam][0]))
      {
        sscanf(argv[nextparam++],"%d",&PD.YearPrefix);
      }

      if (nextparam < argc) /* more parameters to process ? */
      {
        ProcessColumnOffsetParam(argv[nextparam++], &PD.CO);
      }
    }

    /*
     * paramaters have been processed, now process the file
     */

    printf("Input file      : %s\n"
           "Output file     : %s\n"
           "Year prefix     : %d\n"
           "Column Offsets:\n",PD.infilename,PD.outfilename,PD.YearPrefix);

    DisplayColumnOffsets(&PD.CO);


    ProcessFile();

  }





  return(0);
}
