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

// Note, replace all occurences of the string DoorName with the name of your door!

/*
  DupeCheck
  =========

  The Dupecheckers job is to check for duplicate files in the specified
  conference's download paths and to check the file lists in that conference
  to see if there is a file with the same name already in a list.

  Duplicate files cannot be checked by the x-fer protocol if the files are
  to be placed in a conference other than the one the user is currently in
  when the x-fer was started.   Also, there is no dupelicate checking for local
  sysop uploads..


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

    2  file name

    3  conference number

    4  NOUSER - optional parameter

  Returns
  =======

    DUPLICATE - if a duplicate was found

  ToDo
  ====

    what you still have to do



*/

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

#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>

#include <HBBS/ANSI_Codes.h>
#include <HBBS/Defines.h>
#include <HBBS/Access.h>
#include <HBBS/types.h>
#include <HBBS/structures.h>

#include <HBBS/Hbbscommon_protos.h>
#ifdef __SASC
#include <HBBS/hbbscommon_pragmas_sas.h>
#else
#include <HBBS/hbbscommon_pragmas_stc.h>
#endif

#include <HBBS/Hbbsnode_protos.h>
#ifdef __SASC
#include <HBBS/Hbbsnode_pragmas_sas.h>
#else
#include <HBBS/Hbbsnode_pragmas_stc.h>
#endif

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

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


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

struct BBSGlobalData *BBSGlobal = NULL;
struct NodeData *N_ND           = NULL;
int    N_NodeNum                = -1;
char   outstr[1024];

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;

BOOL UserAround=TRUE;

/* **** 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);
}

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

V_BOOL CheckConf(V_BIGNUM ConfNum)
{
  V_BOOL FoundDupe = FALSE;
  struct ConfData *Conf;
  struct Node *node;

  Conf = (struct ConfData *)GetNode(BBSGlobal->ConfList,ConfNum-1);

  if (UserAround)
  {
    sprintf(outstr,ANSI_FG_CYAN"Checking Conference "ANSI_FG_YELLOW"\"%s\" "ANSI_FG_CYAN,Conf->node.ln_Name);
    DOOR_WriteText(outstr);
  }

  for (node=Conf->Download->lh_Head ; node->ln_Succ && !FoundDupe ; node=node->ln_Succ)
  {
    strcpy(outstr,node->ln_Name);
    strcat(outstr,gargv[2]);

    FoundDupe = PathOK(outstr);
    
    if (UserAround) DOOR_WriteText(".");
  }
  
  if (UserAround)
  {   
    if (FoundDupe)
    {
      DOOR_WriteText(ANSI_FG_WHITE" DUPLICATE FOUND!\r\n"); // *C* display information about the previously uploaded file
    }
    else
    {
      DOOR_WriteText(ANSI_FG_YELLOW" OK\r\n");
    }
  }
  return(FoundDupe);
}

void DoorMain( void )
{
  V_BIGNUM ConfNum;
  V_BOOL FoundDupe = FALSE;

  // Doors are still started even if the user has lost carrier so if you door prints anything
  // to the screen or displays any screens then you need to check to see if the user is still
  // online. to do this you must check N_ND->OnLineStatus (see below)

  // this might seem odd if you have programmed /X doors but doors in hbbs are really just
  // an extension of the main node program..

  // it is done like this so that you can write doors that continue to do stuff
  // without the user being around, for example, if a user hangs up during file checking
  // after an upload we wouldn't all those nice files just stitting in the playpen would we ?!

  // you can still use DOOR_SysopText() to display messages to the watch screen however...
  
  if (UserAround)
  {
    DOOR_WriteText("\r\n"ANSI_FG_BLUE"-="ANSI_FG_CYAN"[ "ANSI_FG_WHITE"Dupe Checker "ANSI_FG_CYAN"]"ANSI_FG_BLUE"=-\r\n\r\n");
  }
   
  if (iposition(N_ND->ActiveDoor->SystemOptions,"CHECKALLCONFS") >= 0 )
  { 
    if (UserAround) DOOR_WriteText(ANSI_FG_YELLOW "Checking all conferences!\r\n");
    for (ConfNum = 1 ; !FoundDupe && ConfNum<= BBSGlobal->Conferences ; ConfNum++)
    {
      FoundDupe = CheckConf(ConfNum);
    }
  }
  else
  {
    if (gargc>=4)
    {
      ConfNum=atoi(gargv[3]);
    
      if (ConfNum>=1 && ConfNum <=BBSGlobal->Conferences)
      {
        FoundDupe = CheckConf(ConfNum);
      }                    
    }
  }
 
  if (!FoundDupe)
  {
    if (UserAround) DOOR_WriteText(ANSI_RESET ANSI_FG_CYAN "No duplicates found in any of the download paths!\r\n");
  }

  // *C* check the file lists here...

  if (FoundDupe)
  {
    DOOR_Return("DUPLICATE");
  }

}

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

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

  if (stricmp("NOUSER",argv[argc-1])==0) UserAround=FALSE;

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

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