/* **** 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: DoorName "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 *********************************************************** */

void DoorMain( void )
{
  struct ConfData *Conf;
  struct Node *node;
  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 (gargc>=4)
  {
    ConfNum=atoi(gargv[3]);

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

      if (UserAround)
      {
        sprintf(outstr,"Checking the \"%s\" conference for duplicates\r\n",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 (FoundDupe)
      {
        if (UserAround) DOOR_WriteText(ANSI_RESET ANSI_FG_RED ANSI_BOLD "Found a duplicate in a download path!\r\n");
      }
      else
      {
        if (UserAround) DOOR_WriteText(ANSI_RESET ANSI_FG_GREEN "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 ******************************************************** */
