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

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


#ifdef __SASC
int CXBRK(void) { return(0); }
int _CXBRK(void) { return(0); }
void chkabort(void) {}
#endif

#include <HBBS/ANSI_Codes.h>
#include <HBBS/Defines.h>
#include <HBBS/types.h>
#include <HBBS/structures.h>
#include <HBBS/Access.h>
#include <HBBS/hbbscommon_protos.h>
#include <HBBS/hbbscommon_pragmas.h>
#include <HBBS/Hbbsnode_protos.h>
#include <HBBS/Hbbsnode_pragmas.h>

struct Library *HBBSCommonBase=NULL;
struct Library *HBBSNodeBase=NULL;

struct BBSGlobalData *BBSGlobal=NULL;
struct NodeData *N_ND=NULL;
int N_NodeNum=-1;

char tmpstr[BIG_STR];
char outstr[BIG_STR];
V_SMALLNUM LinesOutput=0;
BOOL Quit=FALSE,NonStop=FALSE,NonStopCLS=FALSE;
V_BIGNUM CurrentFileNumber;

#define FLM_NONE     0
#define FLM_NEW      1
#define FLM_REVERSE  2
#define FLM_LIST     3

ULONG Mode=FLM_NONE;

int gargc;
char **gargv;

struct List *FileNames=NULL;
char versionstr[]="$VER: FileList.HBBS V1.0 (25.12.95)";

char monthstr[12][4]={"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"};
  LONG todaytime,fromtime;
  struct tm *todaytr,*fromtr;

#define BUFFERSIZE 1024  // *C* Increase to 32k



ULONG FH;
ULONG FL;
UBYTE Buffer[BUFFERSIZE];
ULONG BytesInBuffer;
ULONG BufferOffset;

#define DIR_FORWARDS TRUE
#define DIR_REVERSE FALSE

static VOID cleanup(ULONG num)
{
  if (HBBSNodeBase)
  {
    HBBS_CleanUpDoor();
    CloseLibrary (HBBSNodeBase);
  }

  if (HBBSCommonBase)
  {
    HBBS_CleanUpCommon();
    CloseLibrary (HBBSCommonBase);
  }

  if (num) printf("Door Error = %d\n",num);

  exit(0);
}

static VOID init(char *name)
{
  if(!(HBBSCommonBase = OpenLibrary("HBBSCommon.library",0)))
  {
    cleanup(1);
  }

  if (!(HBBS_InitCommon()))
  {
    cleanup(2);
  }

  if(!(HBBSNodeBase = OpenLibrary("HBBSNode.library",0)))
  {
    cleanup(3);
  }

  if (!(HBBS_InitDoor(N_NodeNum,name)))
  {
    cleanup(4);
  }
  SetProgramName(name);
}

void strpad(char *buffer, int requiredlen, UBYTE PadChar)
{
  int many;
  int loop;
  int clen=strlen(buffer);

  if (clen<requiredlen)
  {
    many=requiredlen-clen;
    for (loop=0;loop<=many;loop++) buffer[clen+loop]=PadChar;
    buffer[requiredlen]=0;
  }
}

void PrintLine( char *Buffer)
{
  // Depending on the it at the start of the buffer different things happen to the
  // output of the reset of the buffer..

  UBYTE buffer[82];
  strcpy(buffer,Buffer);

  if (buffer[1]==' ')
  {
    switch (buffer[0])
    {
      case 'F' :
        CurrentFileNumber++;
        DOOR_WriteText(ANSI_RESET ANSI_FG_BLUE);
        sprintf(tmpstr,"-- "ANSI_FG_YELLOW"["ANSI_FG_WHITE" %d "ANSI_FG_YELLOW"]"ANSI_FG_WHITE" - "ANSI_FG_YELLOW"["ANSI_FG_WHITE" %s "ANSI_FG_YELLOW"]"ANSI_FG_WHITE" - "ANSI_FG_YELLOW"["ANSI_FG_WHITE" Node %d "ANSI_FG_YELLOW"]"ANSI_FG_BLUE" ",CurrentFileNumber,BBSGlobal->BBSName,N_ND->NodeNum);
        strpad(tmpstr,79+60,'-'); // +60 for the ansi!
        strcat(tmpstr,"\r\n");
        DOOR_WriteText(tmpstr);

        // first part of line needs to be CYAN

        DOOR_WriteText(ANSI_FG_CYAN);
        strNcpy(tmpstr,&buffer[2],34);
        DOOR_WriteText(tmpstr);

        // last part of line needs to be WHITE

        DOOR_WriteText(ANSI_FG_WHITE);
        strfcpy(tmpstr,&buffer[2],34); // index at 0, so use 34 instead of 35 for the 34th char..
        DOOR_WriteText(tmpstr);
        DOOR_WriteText("\r\n");
        LinesOutput+=2;
        break;
      case 'I' :
        DOOR_WriteText(ANSI_FG_WHITE);
        DOOR_WriteText(&buffer[2]);
        DOOR_WriteText("\r\n");
        LinesOutput++;
        break;
      case 'X' :
        strpad(buffer,81,' '); // make sure it's 81 chars long.. 79 are printed..
        DOOR_WriteText(ANSI_BG_BLUE ANSI_FG_WHITE);
        DOOR_WriteText(&buffer[2]);
        DOOR_WriteText("\r\n");
        DOOR_WriteText(ANSI_RESET);
        LinesOutput++;
        break;
      case 'P' :
        DOOR_WriteText(ANSI_RESET);
        DOOR_WriteText(&buffer[2]);
        DOOR_WriteText("\r\n");
        DOOR_WriteText(ANSI_RESET);
        LinesOutput++;
        break;
      case 'T' :
        if (strlen(buffer)>=25)
        {
          strNcpy(tmpstr,&buffer[2],25);
          DOOR_WriteText(tmpstr);
          DOOR_WriteText(ANSI_FG_YELLOW);
          strNcpy(tmpstr,&buffer[27],8);
          DOOR_WriteText(tmpstr);
          DOOR_WriteText(ANSI_FG_WHITE);
          DOOR_WriteText(&buffer[35]);
          DOOR_WriteText("\r\n");
          LinesOutput++;
        }
        break;
      case 'N' :
        if (strlen(buffer)>=25)
        {
          strNcpy(tmpstr,&buffer[2],25);
          DOOR_WriteText(tmpstr);
          DOOR_WriteText(ANSI_FG_GREEN);
          strNcpy(tmpstr,&buffer[27],8);
          DOOR_WriteText(tmpstr);
          DOOR_WriteText(ANSI_FG_WHITE);
          DOOR_WriteText(&buffer[35]);
          DOOR_WriteText("\r\n");
          LinesOutput++;
        }
        break;
    }
  }
}

BOOL ScreenPausePrompt( BOOL ReachedEOF )
{
  BOOL retval=FALSE;
  V_BOOL Help;

  if ((!NonStop) || (NonStop && ReachedEOF))
  {
    do
    {
      Help=FALSE;

      if (ReachedEOF)
      {
        strcpy(N_ND->CharsAllowed,"YyNnQqFfRr? ");
        DOOR_MenuPrompt("End-Of-File [Y/N/F/R/?] : ",' ');
//        DOOR_WriteText(ANSI_RESET "End-Of-File "ANSI_FG_YELLOW"["ANSI_FG_WHITE"Y/N/F/R/?"ANSI_FG_YELLOW"]"ANSI_FG_WHITE " : ");
      }
      else
      {
        strcpy(N_ND->CharsAllowed,"LlYyNnCcAaFfRr?Qq ");
        DOOR_MenuPrompt("End-Of-File [Y/N/C/A/F/R/?] : ",' ');
//        DOOR_WriteText(ANSI_RESET "More "ANSI_FG_YELLOW"["ANSI_FG_WHITE"Y/N/C/A/F/R/?"ANSI_FG_YELLOW"]"ANSI_FG_WHITE " : ");
      }


      DOOR_GetLine(GL_EDIT|GL_DISPLAY|GL_USECHARS|GL_IMMEDIATE|GL_NORETURN,'\0',1,0,NULL);
      if (N_ND->OnlineStatus==OS_ONLINE)
      {
        DOOR_WriteText("\r[K"); // erase line
        if (stricmp("F",N_ND->CurrentLine)==0)
        {
          DOOR_WriteText(ANSI_FG_CYAN "Enter Filenames To Tag > "ANSI_FG_WHITE);
          DOOR_GetLine(GL_EDIT|GL_DISPLAY|GL_HISTORY|GL_NORETURN,'\0',0,0,NULL);
          if (N_ND->OnlineStatus==OS_ONLINE)
          {
            DOOR_WriteText("\r[K"); // erase line
            RemoveSpaces(N_ND->CurrentLine);
            if (N_ND->CurrentLine[0])
            {
              strcpy(tmpstr,N_ND->CurrentLine);
              DOOR_UserDoor("A",tmpstr);
              Help=TRUE;
            }
          }
        }
        else
        if (stricmp("R",N_ND->CurrentLine)==0)
        {
          DOOR_WriteText(ANSI_FG_CYAN"Enter FileNumbers To Tag > "ANSI_FG_WHITE);
          DOOR_GetLine(GL_EDIT|GL_DISPLAY|GL_HISTORY|GL_NORETURN,'\0',0,0,NULL);
          RemoveSpaces(N_ND->CurrentLine);
          if (N_ND->CurrentLine[0])
          {
            // this (horrible) code is nicked from ben's Zippy program
            // hence the horrible varialbe names and huge amount of them..

            LONG i,where;
            UBYTE filename[BIG_STR],rp[BIG_STR],*filenames;


            DOOR_WriteText("\r[K"); // erase line

            tmpstr[0]=0;

            for( i=0; i<strlen( N_ND->CurrentLine ); i++ )
            {
              if( N_ND->CurrentLine[i] == ',' )
              {
                rp[i] = ' ';
              }
              else
              {
                rp[i] = N_ND->CurrentLine[i];
              }
            }
            rp[i] = 0;


            filenames = rp;

            // but this bit is mine...

            while (filenames[0]) // any chars left ?
            {
              while ((filenames[0]==' ') && (filenames[0])) filenames++; //skip spaces..

              if (filenames[0])
              {
                if (((where=position(" ",filenames))>=0) )
                {
                  strNcpy(filename,filenames,where);
                  filenames+=where;
                }
                else
                {
                  strcpy(filename,filenames);
                  filenames+=strlen(filename);
                }

                // and this isn't mine..

                i = atol( filename );
                if (i>0 && i<=CurrentFileNumber)
                {
                  sprintf( tmpstr+strlen(tmpstr), "%s ", HBBS_ListName(FileNames, i-1) );
                }

              }
            }
            // but this is..
            if (tmpstr[0]) DOOR_UserDoor("A",tmpstr);
            Help=TRUE;
          }
        }
        else
        if (stricmp("C",N_ND->CurrentLine)==0)
        {
          DOOR_WriteText(ANSI_CLS);
        }
        else
        if (stricmp("L",N_ND->CurrentLine)==0)
        {
          NonStop=TRUE;
          NonStopCLS=TRUE;
          DOOR_WriteText(ANSI_CLS);
        }
        else
        if ((stricmp("N",N_ND->CurrentLine)==0) || (stricmp("Q",N_ND->CurrentLine)==0))
        {
          retval=TRUE;
        }
        else
        if (stricmp("A",N_ND->CurrentLine)==0)
        {
          NonStop=TRUE;
        }
        if (stricmp("?",N_ND->CurrentLine)==0)
        {
          DOOR_WriteText(ANSI_FG_WHITE
                         "Help\r\n~~~~\r\n\r\n"
                         "?    "ANSI_FG_CYAN"-"ANSI_FG_WHITE"  This Help Page\r\n"
                         "C    "ANSI_FG_CYAN"-"ANSI_FG_WHITE"  Clear Screen And Continue\r\n"
                         "N/Q  "ANSI_FG_CYAN"-"ANSI_FG_WHITE"  No More Please (QUIT)\r\n"
                         "A    "ANSI_FG_CYAN"-"ANSI_FG_WHITE"  Display All of remaining files (same as /X's NS)\r\n"
                         "L    "ANSI_FG_CYAN"-"ANSI_FG_WHITE"  Display All of remaining files with CLS's!\r\n"
                         "F    "ANSI_FG_CYAN"-"ANSI_FG_WHITE"  Flag File By NAME\r\n"
                         "R    "ANSI_FG_CYAN"-"ANSI_FG_WHITE"  Flag File By NUMBER\r\n");
          Help=TRUE;
        }
      }
    }
    while ((N_ND->OnlineStatus==OS_ONLINE) && (Help));
  }
  LinesOutput=0;

  if (N_ND->OnlineStatus==OS_ONLINE)
  {
    if (NonStopCLS && !ReachedEOF) DOOR_WriteText( ANSI_CLS );
  }
  else
  {
    retval=TRUE; // cancel!
  }


  return(retval);
}

void DisplayHelp( void )
{
  switch(Mode) // display different help depending on the mode!
  {
    case FLM_LIST:
      DOOR_WriteText("Supported options are:\r\n\r\n"
                     "CFG              - Configure Scanner!\r\n\r\n"
                     "T      [List]    - Scan Todays Files\r\n"
                     "S      [List]    - Scan since last call\r\n"
                     "<days> [List]    - Scan from <days> ago\r\n");
      break;
    case FLM_NEW:
      DOOR_WriteText("Supported options are:\r\n\r\n"
                     "CFG              - Configure Scanner!\r\n\r\n"
                     "T      [List]    - Scan Todays Files\r\n"
                     "S      [List]    - Scan since last call\r\n"
                     "<days> [List]    - Scan from <days> ago\r\n");
      break;
    case FLM_REVERSE:
      DOOR_WriteText("Supported options are:\r\n\r\n"
                     "CFG              - Configure Scanner!\r\n\r\n"
                     "[List]           - Reverse Scan Files\r\n");
      break;
  }
  if (N_ND->User.CallData.Access>=250)
  {
    DOOR_WriteText(  "H                - Reverse Scan HOLD list\r\n");
  }
}

void stripCR(UBYTE *String)
{
  ULONG Len;
  if (String && (Len=strlen(String)))
  {
    Len--; // Len now = character index..

    while (Len && (String[Len]=='\r' || String[Len]=='\n'))
    {
      String[Len--]=0;
    }
  }
}

void PrintFileInfo(struct List *FileInfo)
{
  struct Node *node;
  UBYTE tmpstr[20];
  if (FileInfo)
  {
    strftcpy( tmpstr,FileInfo->lh_Head->ln_Name,  2, 14 );
    NewStrNode( tmpstr, FileNames ); // *C* errorcheck!

    for (node=FileInfo->lh_Head;node->ln_Succ;node=node->ln_Succ)
    {
      PrintLine(node->ln_Name);
    }
  }
}

/*
BOOL FGetsR(BPTR FH,UBYTE *Buffer,LONG BufferLen)
{

  LONG nr,startpos,where,back,foundpos=0;
  BOOL retval=TRUE,sof=FALSE,error=FALSE;

  UBYTE *strptr=NULL;


  Buffer[0]=0;
  BufferLen--;

  where=Seek(FH,0,OFFSET_CURRENT);  // start of file already ?
  if (where<=0) //start of file or error
  {
    retval=FALSE;
  }
  else
  {
    startpos=where; // make a note of where we started from.
    do
    {
      back=255;
      if (where<255) back=where;

      if (back>BufferLen) back=BufferLen;

      if ((where=Seek(FH,0-back,OFFSET_CURRENT))!=-1)
      {
        where-=back;

        if (nr=Read(FH,Buffer,back))
        {
          Buffer[nr]=0;
          if (strptr=strrchr(Buffer,'\n'))
          {
            foundpos=where+(strptr-Buffer);
            if (Seek(FH,foundpos+1,OFFSET_BEGINNING)==-1)
            {
              error=TRUE;
            }
          }
          else
          {
            if (where==0)
            {
              if (Seek(FH,0,OFFSET_BEGINNING)==-1)
              {
                error=TRUE;
              }
              else
              {
                sof=TRUE;
                foundpos=1;
              }
            }
            else
            {

              if (Seek(FH,0-nr,OFFSET_CURRENT)!=-1)
              {
                where-=nr;
              }
              else
              {
                error=TRUE;
              }
            }

          }
        }
        else
        {
          error=TRUE;
        }

      }
    } while (strptr==NULL && !error && !sof);

    Buffer[0]=0;
    if (strptr || sof )
    {
      FGets(FH,Buffer,BufferLen);
      Seek(FH,foundpos ? foundpos-1 : 0,OFFSET_BEGINNING);
    }
  }

  return(retval);

}

BOOL FGetsR(BPTR FH,UBYTE *Buffer,LONG BufferLen)
{

  LONG nr,BufferPos=0;
  BOOL retval=TRUE,First=TRUE,Done=FALSE;
  char c;


  Buffer[0]=0;
  BufferLen--;

  if ((nr=Seek(FH,0,OFFSET_CURRENT))==0)  // start of file already ?
  {
    retval=FALSE;
  }
  else
  {
    do
    {
      if (Seek(FH,First ? -1 : -2 ,OFFSET_CURRENT)!=-1)
      {
        if (Read(FH,&c,1))
        {
          if (c=='\n')
          {
            Done=TRUE;
            Seek(FH,-1,OFFSET_CURRENT);
          }
          else
          {
            Buffer[BufferPos++]=c;
          }

        }
        else
        {
          Done=TRUE;
        }
        First=FALSE;
      }
      else
      {
        if (First)
        {
          retval=FALSE; // error, beginning of file or file error as seek() failed!
        }
        else
        {
          Seek(FH,-1,OFFSET_CURRENT);
                       // beginning of file..
        }
        Done=TRUE;
      }
    }
    while(BufferPos<BufferLen && !Done);

    Buffer[BufferPos]=0;

    if (BufferPos) strrev(Buffer); // reverse the string.
  }
  return(retval);

}
*/


struct List *GetFileInfoReverse( void )
{
  UBYTE Buffer[255];
  struct List *FileInfo=NULL;
  struct Node *node;

  BOOL Done=FALSE;

  if (FileInfo=HBBS_CreateList())
  {
    do
    {
      if (FGetsR(FH,Buffer,255))
      {
        stripCR(Buffer);
        switch(Buffer[0])
        {
          case 'F':
            Done=TRUE;
          case 'T':
          case 'N':
          case 'I':
          case 'U':
          case 'C':
          case 'X':
          case 'P':

            if (node=HBBS_CreateNode(Buffer,0))
            {
              AddHead(FileInfo,node); //note: addHEAD() rather than addTAIL()
            }
            else
            {
              Done=TRUE;
            }
            break;
        }
      }
      else
      {
        Done=TRUE;
      }
    } while (!Done);

    if (HBBS_NodesInList(FileInfo)==0)
    {
      FreeStrList(FileInfo);
      FileInfo=NULL;
    }
  }
  return(FileInfo);
}

struct List *GetFileInfo( void )
{
  UBYTE Buffer[255];
  struct List *FileInfo=NULL;

  BOOL Done=FALSE,KeepAdding=FALSE;

  if (FileInfo=HBBS_CreateList())
  {
    do
    {
      if (FGets(FH,Buffer,255))
      {
        stripCR(Buffer);
        switch(Buffer[0])
        {
          case 'F':
            KeepAdding=TRUE;
            // note: the lack of a "break" here!
          case 'T':
          case 'N':
          case 'I':
          case 'U':
          case 'C':
          case 'X':
          case 'P':
            if (KeepAdding)
            {
              if (NewStrNode(Buffer,FileInfo))
              {
                Done=TRUE;
              }
            }
            break;
          default:
            if (KeepAdding) Done=TRUE;
            break;
        }
      }
      else
      {
        Done=TRUE;
      }
    } while (!Done);


    if (HBBS_NodesInList(FileInfo)==0)
    {
      FreeStrList(FileInfo);
      FileInfo=NULL;
    }
  }
  return(FileInfo);
}


void FileListNotAvailable( UBYTE *filename )
{
  sprintf(outstr,"File List \"%s\", is not available\r\n",FilePart(filename));
  DOOR_WriteText(outstr);
}

BOOL ForwardList(UBYTE *filename)
{
  struct List *FileInfo=NULL;
  BOOL Done=FALSE,DisplayOK=FALSE;
  UBYTE datestr[LEN_DATESTR];
//  UBYTE copyoffile[BIG_STR];

  struct tm cptr={0,0,0,0,0,0,0,0,0};
  long cpt;

  if (FileNames=HBBS_CreateList())
  {
    CurrentFileNumber=0;
    if (AssignOK(filename))
    {
//      sprintf(copyoffile,"%sWork/FileList.TEMP",N_ND->NodeLocation);

//      if (HBBS_CopyFile(filename,copyoffile,0))
//      {
//        if (FL=Lock(copyoffile,ACCESS_READ))
        if (FL=Lock(filename,ACCESS_READ))
        {
          if (FH=OpenFromLock(FL))
          {
            LinesOutput=0;
            while ((!Done) && (FileInfo=GetFileInfo()))
            {
              if (HBBS_NodesInList(FileInfo))
              {
                if (!DisplayOK)
                {
                  strftcpy(datestr,FileInfo->lh_Head->ln_Name,24,34);
                  if (HBBS_DateStrToTM(datestr,&cptr))
                  {
                    cpt=mktime(&cptr);

                    if (cpt>=fromtime) DisplayOK=TRUE;
                  }
                }
                if ((1 + LinesOutput + HBBS_NodesInList(FileInfo)) > (N_ND->User.CallData.LinesPerScreen-1) )
                {
                  Done=ScreenPausePrompt(FALSE);
                }
                if (!Done && DisplayOK) PrintFileInfo(FileInfo);
              }
              FreeStrList(FileInfo);
            }
            if (LinesOutput && !Done)
            {
              Done=ScreenPausePrompt(TRUE);
            }
            Close(FH);
          }
          else
          {
            UnLock(FL);
          }
        } else FileListNotAvailable(filename);
//        DeleteFile(copyoffile);
//      } else DOOR_WriteText("Could not create a copy of the filelist!\r\n");
    } else FileListNotAvailable(filename);
    FreeStrList(FileNames);
  }
  return(Done);

}

BOOL ReverseList(UBYTE *filename)
{
  struct List *FileInfo=NULL;
  BOOL Done=FALSE,DisplayOK=FALSE;
  UBYTE datestr[LEN_DATESTR];

  struct tm cptr={0,0,0,0,0,0,0,0,0};
  long cpt;

  if (FileNames=HBBS_CreateList())
  {
    CurrentFileNumber=0;
    if (AssignOK(filename))
    {
      if (FL=Lock(filename,ACCESS_READ))
      {
        if (FH=OpenFromLock(FL))
        {
          if (Seek(FH,0,OFFSET_END)!=-1)
          {
            LinesOutput=0;
            while ((!Done) && (FileInfo=GetFileInfoReverse()))
            {
              if (HBBS_NodesInList(FileInfo))
              {
                if (!DisplayOK)
                {
                  strftcpy(datestr,FileInfo->lh_Head->ln_Name,24,34);
                  if (HBBS_DateStrToTM(datestr,&cptr))
                  {
                    cpt=mktime(&cptr);

                    if (cpt>=fromtime) DisplayOK=TRUE;
                  }
                }
                if ((1 + LinesOutput + HBBS_NodesInList(FileInfo)) > (N_ND->User.CallData.LinesPerScreen-1) )
                {
                  Done=ScreenPausePrompt(FALSE);
                }
                if (!Done && DisplayOK) PrintFileInfo(FileInfo);
              }
              FreeStrList(FileInfo);
            }
            if (LinesOutput && !Done)
            {
              Done=ScreenPausePrompt(TRUE);
            }
          }
          Close(FH);
        }
        else
        {
          UnLock(FL);
        }
      } else FileListNotAvailable(filename);
    } else FileListNotAvailable(filename);
    FreeStrList(FileNames);
  }
  return(Done);

}


BOOL DisplayList( ULONG listnum, UBYTE *datestr,UBYTE *filename)
{
  BOOL Cancel=TRUE;
  struct Node *node;
  if (filename)
  {
    switch(Mode)
    {
      case FLM_NEW:
        Cancel=ForwardList(filename);
        break;
      case FLM_REVERSE:
        Cancel=ReverseList(filename);
        break;
      case FLM_LIST:

        Cancel=ForwardList(filename);
        break;
    }
  }
  else
  {
    if ((listnum>0) && (listnum<=N_ND->CurrentConf->FileLists))
    {

      node=GetNode(N_ND->CurrentConf->FileList,listnum-1);

      sprintf(outstr,"Searching for files from %s in list %s\r\n",datestr,FilePart(node->ln_Name));
      DOOR_WriteText(outstr);

      switch(Mode)
      {
        case FLM_NEW:
          Cancel=ForwardList(node->ln_Name);
          break;
        case FLM_REVERSE:
          Cancel=ReverseList(node->ln_Name);
          break;
        case FLM_LIST:

          Cancel=ForwardList(node->ln_Name);
          break;
      }
    }
    else
    {
      DOOR_WriteText("Invalid file list number specified\r\n");
    }
  }
  return(Cancel);
}

void DoConfig( void )
{
  DOOR_WriteText("There are currently no configuration options for this door\r\n");
  DOOR_PausePrompt(NULL);
}

void DoorMain( void )
{
  ULONG loop;
  LONG daysago;
  char datestr[LEN_DATESTR];
  ULONG listnum,tmpnum;
  BOOL error=FALSE,ScanAll=FALSE,Cancel=FALSE,ScanHOLD=FALSE;
  ULONG nextparam=2;

  if (N_ND->User.Acs.Data[ACS_SCANFILES]=='Y')
  {
    N_ND->Actions[ACTN_FILESCAN]=ACTC_FILESCAN;

    if ((listnum=N_ND->CurrentConf->FileLists)>0)
    {
      time(&todaytime);
      todaytr=localtime(&todaytime);

      todaytr->tm_sec=0;
      todaytr->tm_min=0;
      todaytr->tm_hour=0;        // as we want the date check to compare
      todaytr->tm_wday=0;        // between 00:00am from one day to the next..
      todaytr->tm_yday=0;
      todaytr->tm_isdst=0;

      todaytime=mktime(todaytr);

      fromtime=todaytime;

      if (iposition("NEW",N_ND->ActiveDoor->SystemOptions)>=0)
      {
        Mode=FLM_NEW;
        if (gargc>=3 && Mode==FLM_NEW)
        {
          nextparam=3;
          switch(toupper(gargv[2][0]))
          {
            case '?':
              DisplayHelp();
              error=TRUE;
              break;
            case 'T':
              break;
            case 'S':
              fromtime=N_ND->User.CallData.LastCalledDate;
              break;
            default:

              // "-" is not allowed, "-<n>" and "<n>" are allowed

              if ( ((strlen(gargv[2])==1) && (isdigit(gargv[2][0]))) ||
                   ((strlen(gargv[2])>1 ) && ((gargv[2][0]=='-') || (isdigit(gargv[2][0])) )))
              {
                if (sscanf(gargv[2],"%ld",&daysago))
                {
                  daysago=abs(daysago); // -2 is the same as 2 :-)
                  fromtime-=(daysago*86400); // 60secs * 60mins * 24hours = 86400 = 1day
                }
              }
              else
              {
                nextparam=2;
              }
              break;

          }
        }

        fromtr=localtime(&fromtime);
      }


      if (iposition("REVERSE",N_ND->ActiveDoor->SystemOptions)>=0)
      {
        Mode=FLM_REVERSE;
        fromtr=localtime(&fromtime);
        HBBS_DateStrToTM("01-JAN-1970",fromtr);
        fromtime=mktime(fromtr);
      }

      if (iposition("LIST",N_ND->ActiveDoor->SystemOptions)>=0)
      {
        Mode=FLM_LIST;
        fromtr=localtime(&fromtime);
        HBBS_DateStrToTM("01-JAN-1970",fromtr);
        fromtime=mktime(fromtr);

      }

      fromtr->tm_sec=0;
      fromtr->tm_min=0;
      fromtr->tm_hour=0;        // as we want the date check to compare
      fromtr->tm_wday=0;        // between 00:00am from one day to the next..
      fromtr->tm_yday=0;
      fromtr->tm_isdst=0;

      fromtime=mktime(fromtr);

      if (Mode)
      {

        if (gargc>=nextparam+1)
        {
          // user specified a file list to read from ?
          // other than the default one ?

          if (sscanf(gargv[nextparam],"%ld",&tmpnum))
          {
            listnum=tmpnum;
          }
          else
          {
            // not a number of a file list, perhaps it's an option..
            // *C* do!
            switch(toupper(gargv[nextparam][0]))
            {
              case '?':
                DisplayHelp();
                error=TRUE;
                break;
              case 'A':
                ScanAll=TRUE;
                break;
              case 'H':
                if (N_ND->User.CallData.Access>=255)
                {
                  ScanHOLD=TRUE;
                }
                else
                {
                  DOOR_WriteText("Access Denied!\r\n");
                }
                break;
              case 'U':
                // Upload dir. listnum is already set to this..
                // so we ned to do anything!
                break;
              default:
                if (stricmp(gargv[nextparam],"CFG")==0)
                {
                  DoConfig();
                }
                else
                {
                  DOOR_WriteText("Invalid option specified!\r\n");
                }
                error=TRUE;
                break;
            }
          }
        }

        if (!error)
        {
          if (fromtr->tm_mday<0) fromtr->tm_mday=0; // can't be less than 01-JAN-1970

          fromtime=mktime(fromtr);
          HBBS_GetDateStr(datestr,fromtime);

          if (ScanAll)
          {
            for (loop=1;!Cancel && (loop<=N_ND->CurrentConf->FileLists);loop++)
            {
              Cancel = DisplayList(loop,datestr,NULL);
            }
          }
          else
          {
            if (ScanHOLD)
            {
              DisplayList(0,NULL,N_ND->CurrentConf->HoldFileList);
            }
            else
            {
              DisplayList(listnum,datestr,NULL);
            }
          }

          if (N_ND->OnlineStatus==OS_ONLINE)
          {
            DOOR_WriteText("Done!\r\n");
          }
        }
      }
      free(fromtr);
      free(todaytr);
    }
    else
    {
      DOOR_WriteText("No files in this conference\r\n");
    }
  }
  else
  {
    DOOR_WriteText("Access Denied :-)\r\n");
  }
}

int main(int argc,char *argv[])
{
  gargc=argc;
  gargv=argv;

  if (sscanf(argv[1],"%d",&N_NodeNum)==0)
  {
    printf("Invalid/No Paramaters for door!\n");
    exit (20);
  }
  init("FileLister");

  if (BBSGlobal=HBBS_GimmeBBS())
  {
    if (N_ND=HBBS_NodeDataPtr(N_NodeNum)) // this should not fail in normal circumstances..
    {
      DoorMain();
    }
  }
  cleanup(0);
}
