/*
  NewUserAnnouncer
  ================

    Displayed bulletins

  Version
  =======

    Source code last changed for release V1.03

  Docs
  ====

    Not written yet

  Notes
  =====

    Source code based on ExampleDoor code from HydraBBS V1.0
*/

/* **** 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 <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>
#include <HBBS/hbbscommon_pragmas_sas.h>

#include <HBBS/Hbbsnode_protos.h>
#include <HBBS/Hbbsnode_pragmas_sas.h>

#include <HBBS/release.h>
char *versionstr="$VER: NewUserAnnouncer "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. (16k default)

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

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


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

#define INITERR_NOERROR 0
#define INITERR_NOPARAMS 1
#define INITERR_NOHBBSCOMMON 2
#define INITERR_INITCOMMONFAILED 3
#define INITERR_NOHBBSNODE 4
#define INITERR_INITDOORFAILED 5

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

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

  switch(num)
  {
    case INITERR_NOERROR:
      exit(0);

    case INITERR_NOPARAMS:
      puts("Bad or no paramaters specified, check your config files\n"
           "(Don't try starting doors from the CLI!)");
      break;

    case INITERR_NOHBBSCOMMON:
      puts("Could not open HBBSCommon.library, check your assign's");
      break;

    case INITERR_INITCOMMONFAILED:
      puts("Could not initialise HBBSCommon.library functions\n"
           "Is HBBS Running ?");
      break;

    case INITERR_NOHBBSNODE:
      puts("Could not open HBBSNode.library, check your assign's");
      break;

    case INITERR_INITDOORFAILED:
      puts("The node specified is either not running or did not want to\n"
           "start this door now. (Don't run doors from the CLI!)");
      break;
  }
  exit(20);
}

static VOID Init(char *name)
{
  if(!(HBBSCommonBase = OpenLibrary("HBBSCommon.library",0)))
  {
    CleanUp(INITERR_NOHBBSCOMMON);
  }

  if (!(HBBS_InitCommon()))
  {
    CleanUp(INITERR_INITCOMMONFAILED);
  }

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

  if (!(HBBS_InitDoor(N_NodeNum,name)))
  {
    CleanUp(INITERR_INITDOORFAILED);
  }
  SetProgramName(name);
}

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

void DoorMain( void )
{
  BPTR FH;
  char message_text[4096]; // 4K.
  char filename[30];
  char mailadd_options[1024];
  struct CfgFileData *Cfg;

  char *ToAccounts;
  V_SMALLNUM AccessLevel = 50;
  V_BOOL MustRead=TRUE;

  if (N_ND->OnlineStatus==OS_ONLINE)
  {
    if (ToAccounts=DupStr("ALL"))
    {
      DOOR_WriteText("New user announcer, processing...");

      if (Cfg=HBBS_LoadConfig("Progdir:NewUserAnnouncer.CFG",LCFG_NONE))
      {
        HBBS_GetSetting(Cfg,(void *)&AccessLevel,VTYPE_SMALLNUM,"MailAccessLevel",OPT_SINGLE);
        HBBS_GetSetting(Cfg,(void *)&ToAccounts ,VTYPE_STRING  ,"To"             ,OPT_SINGLE);
        HBBS_GetSetting(Cfg,(void *)&MustRead   ,VTYPE_BOOL    ,"MustRead"       ,OPT_SINGLE);

        HBBS_FlushConfig(Cfg);
      }
      else
      {
        HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_INFO,"The new user announcer door could not find it's config, see it's docs!",TYPE_INFO);
      }

      sprintf(filename,"T:HBBS/NUA_%ld.TMP",N_ND->NodeNum);

      if (FH = Open(filename,MODE_NEWFILE))
      {
        sprintf(message_text,"\n"
                             ANSI_FG_WHITE"A new user, \""ANSI_FG_YELLOW"%s"ANSI_FG_WHITE"\" of \""ANSI_FG_YELLOW"%s"ANSI_FG_WHITE"\" has joined the BBS\n"
                             "\n"
                             "If you know this user, please reply to this mail message giving details\n",
                             N_ND->User->CallData->Handle,N_ND->User->CallData->Group);

        FPuts(FH,message_text);

        Close(FH);

        sprintf(mailadd_options,"%s TO %s FROM %s TYPE P %sACCESS %ld SUBJECT New User: \"%s\" of \"%s\"",
                                filename,
                                ToAccounts,
                                N_ND->NodeSettings.SysopAccount,
                                MustRead ? "FLAGS 4 " : "",
                                AccessLevel,
                                N_ND->User->CallData->Handle,
                                N_ND->User->CallData->Group);


        DOOR_SystemDoor("MAILADD",mailadd_options);

        DOOR_WriteText("Done\r\n");
      }
      else
      {
        DOOR_WriteText("Failed\r\n");
      }

      FreeVec(ToAccounts);

    }
  }
}

int main(int argc,char **argv)
{

  /* set these so that we can access the paramaters in the rest of the program */

  gargc=argc;
  gargv=argv;

  /* Check to see if we've got any paramaters */

  if (argc <= 1)
  {
    CleanUp(INITERR_NOPARAMS);
  }

  /* Get the node number from the paramaters */

  if (sscanf(argv[1],"%d",&N_NodeNum)==0)
  {
    CleanUp(INITERR_NOPARAMS);
  }

  /* Initialise and set the door/program name */

  Init("NewUserAnnouncer");

  /* if the init() didn't fail then we need to ask HBBS for the pointer to
     it's data structures */

  if (BBSGlobal=HBBS_GimmeBBS())
  {
    /* Then we need to get the node's data structures for the node this door is going to run on */

    if (N_ND=HBBS_NodeDataPtr(N_NodeNum))
    {

      /* Now that's done, you can put the rest of your code here, or in the DoorMain() function */

      DoorMain();
    }
  }

  /* Cleanup and close libraries */

  CleanUp(INITERR_NOERROR);
}

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