/* **** HBBS Door Code****************************************************** */

/*
  DoorName
  ========

    View by Ben Clifton (Teppic)

  Version
  =======

    0.01, release  0, 24/12/1995

  Options
  =======

    N_ND->ActiveDoor->SystemOptions
    -------------------------------



    Command Line Arguments
    ----------------------

  ToDo
  ====




*/

/* **** Includes *********************************************************** */

#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <dos/dostags.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>

#include <HBBS/ANSI_Codes.h>
#include <HBBS/Defines.h>
#include <HBBS/types.h>
#include <HBBS/structures.h>
#include <HBBS/hbbscommon_protos.h>
#include <HBBS/hbbscommon_pragmas.h>
#include <HBBS/Hbbsnode_protos.h>
#include <HBBS/Hbbsnode_pragmas.h>
#include <HBBS/release.h>
char *versionstr="$VER: View "RELEASE_STR;

/* **** Variables ********************************************************** */


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

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

long __stack=16*1024; // increse this in 4k incrments if you suffer from
                      // random/suprious crashings after or during the running
                      // of your door.

int    gargc;         // these are just copies of main()'s argc and argv..
char   **gargv;

ULONG CurrentFileNumber = 0;
ULONG LinesOutput = 0;

BOOL NonStop = FALSE, Lopt = FALSE, SysopFile=FALSE;

struct List *FileNames;

char tmpstr[BIG_STR];

/* **** Functions ********************************************************** */


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

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 FM_strFNcpy( char *in, char *out, int start, int num )
{
  int loop, i;

  for( i=0, loop = start; (loop < num+start) && (in[loop]); loop++, i++ ) out[i] = in[loop];
  out[i]=0;
}

void FM_RemoveCR( char *s )
{
  if( s[0] )
  {
    if( (s[strlen(s)-1] == '\n')|| (s[strlen(s)-1] == '\r' ) )
      s[strlen(s)-1] = 0;
    if( (s[strlen(s)-1] == '\n')|| (s[strlen(s)-1] == '\r' ) )
      s[strlen(s)-1] = 0;
  }
}

char *GetExtension( char *filename )
{
  char *extstart, *tmp = NULL;

  for( extstart = filename; (extstart[0] != '.')&&(extstart[0] != 0); extstart++ );
  if( extstart[0] != 0 )
  {
    extstart++;
    tmp = GetExtension( extstart );
    if( tmp[0] != 0 )
      return( tmp );
    else
      return( extstart );
  }
  else
  {
    return( NULL );
  }

}

/*
V_BOOL HBBS_FindConfFile(V_BIGNUM ConfNum,char *filename,char *fullname)
{
  // searches the download paths of the conf for the filename specified
  // and returns TRUE if the file is found.  The full path and filename
  // are then stored in fullname if fullname is not a null pointer

  V_BOOL retval=FALSE;
  struct ConfData *Conf;
  char tmpstr[1024];
  struct Node *node;


  // valid conf num ?
  if (ConfNum>=1 && ConfNum<=BBSGlobal->Conferences)
  {
    Conf=(struct ConfData *)GetNode(BBSGlobal->ConfList,ConfNum-1);

    // any download paths to search ??
    if (Conf->Download)
    {
      for (node=Conf->Download->lh_Head;!retval && node->ln_Succ;node=node->ln_Succ)
      {
        strcpy(tmpstr,node->ln_Name);
        strcat(tmpstr,filename);
        if (PathOK(tmpstr))
        {
          retval=TRUE;
          if (fullname)
          {
            strcpy(fullname,tmpstr);
          }
        }
      }
    }
  }
  return(retval);
}
*/

BOOL ScreenPausePrompt( BOOL ReachedEOF, char *filename )
{
  BOOL retval=FALSE;
  V_BOOL Help;

  if ((!NonStop) || (NonStop && ReachedEOF))
  {
    do
    {
      Help=FALSE;
      if( ReachedEOF )
      {
        strcpy(N_ND->CharsAllowed,"YyFf?Qq");
        DOOR_WriteText(ANSI_RESET "End-Of-File "ANSI_FG_YELLOW"["ANSI_FG_WHITE"Y/Q/F/?"ANSI_FG_YELLOW"]"ANSI_FG_WHITE " : ");
      }
      else
      {
        strcpy(N_ND->CharsAllowed,"YyNnCcAaLlFf?Qq");
        DOOR_WriteText(ANSI_RESET "More "ANSI_FG_YELLOW"["ANSI_FG_WHITE"Y/N/C/A/F/L/Q/?"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)
        {
          if (SysopFile)
          {
            strcpy(tmpstr,"C=0,N=");
            strcat(tmpstr,filename);
            DOOR_SystemDoor("Tag_File",tmpstr);
          }
          else
          {
            DOOR_UserDoor("A",filename);
          }
          Help=TRUE;

        }
        else
        if (stricmp("C",N_ND->CurrentLine)==0)
        {
          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;
        }
        else
        if (stricmp("L",N_ND->CurrentLine)==0)
        {
          NonStop=TRUE;
          Lopt=TRUE;
        }
        if (stricmp("?",N_ND->CurrentLine)==0)
        {
          DOOR_WriteText( ANSI_RESET ANSI_FG_YELLOW ANSI_BG_BLACK ANSI_UNDERLINE
                          "                                                                               \r\n" );
          DOOR_WriteText( ANSI_BG_RED
                          "          Teppic View V1.0  (C) 1995 Teppic/Ruby Knight Productions            " ANSI_RESET "\r\n\r\n" );
          DOOR_WriteText(ANSI_FG_WHITE
                         "          ?  -  This Help Page.\r\n"
                         "          C  -  Clear Screen And Continue.\r\n"
                         "          N/Q-  No More Please (QUIT).\r\n"
                         "          Y  -  Display next screen of files\r\n"
                         "          A  -  Display All of remaining files (same as /X's NS).\r\n"
                         "          F  -  Flag File.\r\n" ANSI_RESET );
          Help=TRUE;
        }
      }
    }
    while ((N_ND->OnlineStatus==OS_ONLINE) && (Help));
  }
  LinesOutput=0;

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

  return(retval);
}

void DisplayAMrTextFile( char *fullname )
{
  BPTR FL, FH;
  BOOL Done = FALSE;
  char buffer[BIG_STR];

  if( FL = Lock( fullname, SHARED_LOCK ))
  {
    if( FH = OpenFromLock( FL ) )
    {
      while( (N_ND->OnlineStatus==OS_ONLINE) && (!Done) )
      {
        if( FGets( FH, buffer, BIG_STR-1 ) )
        {
          FM_RemoveCR( buffer );
          LinesOutput++;
          DOOR_WriteText( buffer );
          DOOR_WriteText( "\r\n" );

          if( (1 + LinesOutput) > (N_ND->User->CallData->LinesPerScreen-2) )
          {
            Done = ScreenPausePrompt( FALSE, fullname );
          }
        }
        else
        {
          if( IoErr() )
            DOOR_WriteText( "Error : Can't read file\r\n" );
          else
            ScreenPausePrompt( TRUE, fullname );

          Done = TRUE;
        }
      }
    }
  }
}

#define ARCTYPE_LZX 0
#define ARCTYPE_ZIP 1

void DoArcListFile( char *filename, long archivetype )
{
  BPTR OFH;
  char fullname[BIG_STR], outfilename[BIG_STR], systemcall[BIG_STR];
  V_BIGNUM ConfNum;
  BOOL FileOK = FALSE, Done = FALSE;
  long n=0;

  ConfNum = N_ND->CurrentConf->ConfNum;

  if (ConfNum>0)
  {
    if (HBBS_FindConfFile(ConfNum,filename,fullname))
    {
      FileOK=TRUE;
    }
  }
  else
  {
    if (N_ND->User->CallData->Access>=250)
    {
      if (PathOK(filename))
      {
        FileOK=TRUE;
        SysopFile=TRUE;
        strcpy(fullname,filename);
      }
    }
  }

  if( FileOK )
  {
    while( !Done )
    {
      sprintf(outfilename,"%sWork/result%ld.txt",N_ND->NodeLocation, n);
      if( OFH = Open( outfilename, MODE_NEWFILE ))
      {
        switch( archivetype )
        {
          case ARCTYPE_LZX:
            sprintf( systemcall, "lzx l -X %s", fullname );
            break;
          case ARCTYPE_ZIP:
            sprintf( systemcall, "unzip -l %s", fullname );
            break;
        }

        SystemTags( systemcall, SYS_Input, NULL, SYS_Output, (ULONG)OFH, SYS_Asynch, FALSE, SYS_UserShell, TRUE, NP_Priority, 0L );

        Close( OFH );
        DisplayAMrTextFile( outfilename );
        DeleteFile( outfilename );
        Done = TRUE;
        if (N_ND->OnlineStatus==OS_ONLINE) DOOR_WriteText( "Done!\r\n" );
      }
      else
      {
        if( IoErr() != 202 )
        {
          Fault( IoErr(), NULL, tmpstr, BIG_STR );
          sprintf( tmpstr, "%s\r\n", tmpstr );
          DOOR_WriteText( tmpstr );
          Done = TRUE;
        }
        else
        {
          n++;
        }
      }
    }
  }
}

void DoTextFile( char *filename )
{
  char fullname[BIG_STR];
  V_BIGNUM ConfNum;
  BOOL FileOK = FALSE;

  ConfNum = N_ND->CurrentConf->ConfNum;

  if (ConfNum>0)
  {
    if (HBBS_FindConfFile(ConfNum,filename,fullname))
    {
      FileOK=TRUE;
    }
  }
  else
  {
    if (N_ND->User->CallData->Access>=250)
    {
      if (PathOK(filename))
      {
        FileOK=TRUE;
        SysopFile=TRUE;
        strcpy(fullname,filename);
      }
    }
  }

  if( FileOK )
  {
    DisplayAMrTextFile( fullname );
  }
  else
  {
    DOOR_WriteText("File Not Found!\r\n");
  }
}

void ProcessFile( char *filename )
{
  char *extstart;

  extstart = GetExtension( filename );

  if( extstart[0] != 0 )
  {
    if( stricmp( extstart, "TXT" )==0 )
    {
      DoTextFile( filename );
    }
    else
    if( stricmp( extstart, "NFO" )==0 )
    {
      DoTextFile( filename );
    }
    else
    if( stricmp( extstart, "LHA" )==0 )
    {
      DoArcListFile( filename, ARCTYPE_LZX );
    }
    else
    if( stricmp( extstart, "LZH" )==0 )
    {
      DoArcListFile( filename, ARCTYPE_LZX );
    }
    else
    if( stricmp( extstart, "LZX" )==0 )
    {
      DoArcListFile( filename, ARCTYPE_LZX );
    }
    else
    if( stricmp( extstart, "ZIP" )==0 )
    {
      DoArcListFile( filename, ARCTYPE_ZIP );
    }
    else
    {
      DOOR_WriteText( "Unknown file type\r\n" );
    }
  }
  else
  {
    DOOR_WriteText( "Unknown file type\r\n" );
  }
}

/* **** DoorMain *********************************************************** */

void DoorMain( void )
{
  char filename[BIG_STR];

//  if( N_ND->User->Acs.Data[ACS_ALLOWVIEW] == 'Y' )
  filename[0] = 0;

  if( TRUE )
  {
    DOOR_WriteText( ANSI_RESET ANSI_FG_YELLOW ANSI_BG_BLACK ANSI_UNDERLINE
                    "                                                                               \r\n" );
    DOOR_WriteText( ANSI_BG_RED
                    "          Teppic View V1.0  (C) 1995 Teppic/Ruby Knight Productions            " ANSI_RESET "\r\n\r\n" );

    if( gargc < 3 )
    {
      DOOR_WriteText( ANSI_FG_YELLOW "Please Enter Filename " ANSI_FG_BLUE ": " ANSI_FG_WHITE );
      DOOR_GetLine( GL_DISPLAY|GL_EDIT|GL_HISTORY, '\0', 0, 0, NULL );
      if( N_ND->OnlineStatus==OS_ONLINE )
      {
        strcpy( filename, N_ND->CurrentLine );
        RemoveSpaces( filename );
      }
    }
    else
    {
      switch( gargv[2][0] )
      {
        case '?':
          DOOR_WriteText( ANSI_FG_RED "Usage " ANSI_FG_BLUE ": " ANSI_FG_WHITE "[filename] [C]\r\n\r\n" ANSI_RESET );
          break;
        default:
          strcpy( filename, gargv[2] );
          RemoveSpaces( filename );
          break;
      }
    }

    if( gargc >= 4 )
    {
      switch( gargv[3][0] )
      {
        case 'c':
        case 'C':
          NonStop = TRUE;
          break;
      }
    }

    if( filename[0] != 0 ) ProcessFile( filename );
  }
  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("-->Teppic View<--");

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

/* **** End Of File ******************************************************** */
