
/*

   Mail_Reply.HBBS
   ===============

   Door for replying to mail.

*/

#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/types.h>
#include <HBBS/Access.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: Mail_Reply "RELEASE_STR;

#include "/Mail_Common.h"


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

struct BBSGlobalData *BBSGlobal=NULL;
struct NodeData *N_ND=NULL;
int N_NodeNum=-1;
char outstr[1024]; // temp string for displaying text..

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

int startparam;

LONG __stack=16384;

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

#include "/maillib.i"

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

/*
BOOL PostNewMail( struct MailData *NewMail,V_BIGNUM ConfNum, char *TxtFilename)
{
  // maildata must be filled in, if TxtFilename is NOT NULL then a text file will
  // be loaded from there into NewMail->Data,  confnum should be specified if you
  // are posting a conference message.


  BOOL retval=FALSE;
  V_BIGNUM loop;
  struct CfgFileData *CfgFile,*StatCfgFile;
  char maildir[1024]="";
  char mailcfg[1024];
  char paramstr[1024];
  V_BIGNUM LastMsg=0;
  struct Node *node;
  struct ConfData *Conf;


  if (NewMail)
  {
    switch (NewMail->Type)
    {
      case MSGT_SYSOP:
        strcpy(maildir,MAILDIR_SYSOP);
        break;
      case MSGT_PRIVATE:
        sprintf(maildir,MAILDIR_USER "%d/",NewMail->ToID);
        if (!PathOK(maildir)) CreatePath(maildir);
        break;
      case MSGT_PUBLIC:
        strcpy(maildir,MAILDIR_PUBLIC);
        break;
      case MSGT_CONFERENCE:
        Conf=(struct ConfData *)GetNode(BBSGlobal->ConfList,ConfNum-1);
        sprintf(maildir,"%sMail/",Conf->ConfPath);
        break;
    }
    if (maildir[0])
    {
      strcpy(mailcfg,maildir);
      strcat(mailcfg,MAILSTATFILE);

      if (!(StatCfgFile=HBBS_LoadConfig(mailcfg,LCFG_NONE)))
      {
        if (StatCfgFile=HBBS_CreateConfig(mailcfg))
        {
          HBBS_AddCfgItem(StatCfgFile,"FirstMessage","0");
          // the "lastmessage" item is removed anway, so we don't need to ad it here..

        }
      }
      if (StatCfgFile)
      {
        HBBS_GetSetting(StatCfgFile,(void *)&LastMsg,VTYPE_BIGNUM,"LastMessage",OPT_SINGLE);

        LastMsg++;

        // update the pointer to the last message

        HBBS_RemoveCfgItem(StatCfgFile,"LastMessage");
        sprintf(paramstr,"%d",LastMsg);
        HBBS_AddCfgItem(StatCfgFile,"LastMessage",paramstr);
        HBBS_SaveConfig(StatCfgFile);
        HBBS_FlushConfig(StatCfgFile);


        sprintf(mailcfg,"%sMessage_%d.CFG",maildir,LastMsg);

        if (TxtFilename)
        {
          NewMail->Data=HBBS_LoadFile(TxtFilename);
        }
        if (NewMail->Data)
        {
          // got some message data ?? (must have at least some...)
          if (CfgFile=HBBS_CreateConfig(mailcfg))
          {
            // build the configuration file

            sprintf(paramstr,"%d",NewMail->Type);
            HBBS_AddCfgItem(CfgFile,"Type",paramstr);
            HBBS_AddCfgItem(CfgFile,"From",NewMail->From);
            sprintf(paramstr,"%d",NewMail->FromID);
            HBBS_AddCfgItem(CfgFile,"FromID",paramstr);
            HBBS_AddCfgItem(CfgFile,"To",NewMail->To);
            sprintf(paramstr,"%d",NewMail->ToID);
            HBBS_AddCfgItem(CfgFile,"ToID",paramstr);
            HBBS_AddCfgItem(CfgFile,"Subject",NewMail->Subject);
            HBBS_AddCfgItem(CfgFile,"CreateDate",NewMail->CreateDate);
            HBBS_AddCfgItem(CfgFile,"ExpiryDate",NewMail->ExpiryDate);
            sprintf(paramstr,"%d",NewMail->Flags);
            HBBS_AddCfgItem(CfgFile,"Flags",paramstr);
            sprintf(paramstr,"%d",NewMail->AccessLevel);
            HBBS_AddCfgItem(CfgFile,"AccessLevel",paramstr);
            sprintf(paramstr,"%d",NewMail->UserAccessLevel);
            HBBS_AddCfgItem(CfgFile,"UserAccessLevel",paramstr);
            if (NewMail->AttachedFileList)
            {
              for (loop=1,node=NewMail->AttachedFileList->lh_Head;node->ln_Succ;node=node->ln_Succ,loop++)
              {
                sprintf(paramstr,"AttacedFile_%d",loop);
                HBBS_AddCfgItem(CfgFile,paramstr,node->ln_Name);
              }
            }

            // ok, now save it.

            if (HBBS_SaveConfig(CfgFile))
            {
              // if we saved it then save the data file too..

              sprintf(mailcfg,"%sMessage_%d.TXT",maildir,LastMsg);
              if (HBBS_SaveFile(mailcfg,NewMail->Data))
              {
                // and if that worked then all is ok!! whaay!
                retval=TRUE;
                N_ND->Actions[ACTN_WROTEMAIL]=ACTC_WROTEMAIL;

              }
            }
            HBBS_FlushConfig(CfgFile);

          }

        }
      }
    }
  }
  return(retval);
}
*/

void DoorMain( void )
{
  struct MailData *Msg=NULL;
  char maildir[1024];
  V_SMALLNUM MsgType;
  V_BIGNUM MsgNum,ConfNum,loop;

//  char tmpstr[1024];
  char tmpmailfile[1024];
//  V_BIGNUM tmpnum;
  BOOL DefaultPrivate;
  struct Node *ndata;
  int linenum,ToLine,FromLine;
  struct List *txtdata;

  if (stricmp(gargv[2],"REPLY")==0)
  {
    for (loop=3;loop<gargc;loop++)
    {
      strcat(outstr,gargv[loop]);
      if (loop<gargc-1) strcat(outstr," ");
    }
    // msgnum, type, confnum
    if (sscanf(outstr,"%d %d %d",&MsgNum,&MsgType,&ConfNum)==3)
    {
      if (GetMailPath(maildir,MsgType,ConfNum,N_ND->User->CallData->UserID))
      {
        if (Msg=GetMailMessage(maildir,MsgNum))
        {
                                                     // *C* let user specify who to reply a mail message to....
                                                     // but default with the person who it was from...
          // Swap round from and to data.

          Msg->ToID=Msg->FromID;
          Msg->FromID=N_ND->User->CallData->UserID;

          if (Msg->Type==MSGT_SYSOP)
          {
            // can't save mail as type sysop if the sysop is reply to
            // someone else :-)
            Msg->Type=MSGT_PRIVATE;
          }

          FreeAndSet(&Msg->To,Msg->From);
          FreeAndSet(&Msg->From,N_ND->User->CallData->Handle);

          DefaultPrivate=FALSE;
          // remove private flag if
          if (Msg->Flags & MSGF_PRIVATE)
          {
            Msg->Flags-=MSGF_PRIVATE;
            DefaultPrivate=TRUE;
          }
          if (DOOR_ContinuePrompt("Private ",(DefaultPrivate ? DEFAULT_YES : DEFAULT_NO)|DCP_ADDYN))
          {
            Msg->Flags+=MSGF_PRIVATE;
          }

          Msg->UserAccessLevel=N_ND->User->NormalData->Access;

          sprintf(tmpmailfile,"%sWork/TmpMail.TXT",N_ND->NodeLocation);
          DeleteFile(tmpmailfile);

          if (DOOR_ContinuePrompt("Quote Message ",DEFAULT_YES|DCP_ADDYN))
          {

            for (linenum=0,ndata=Msg->Data->lh_Head;ndata->ln_Succ;ndata=ndata->ln_Succ)
            {
              linenum++;  // do here rather in loop so that linenum is usable later..
              sprintf(outstr,"%3d %s\r\n",linenum,ndata->ln_Name);
              DOOR_WriteText(outstr);
            }

            FromLine=1;
            ToLine=linenum;
            DOOR_MenuPrompt("From: Line Number or [A]ll ",'A');
            strcpy(N_ND->CharsAllowed,"*1234567890aA");
            if (IN_TIMEOUT!=DOOR_GetLine(GL_EDIT|GL_DISPLAY|GL_USECHARS,'\0',3,10,NULL))
            {
              if (N_ND->OnlineStatus==OS_ONLINE)
              {
                if (N_ND->CurrentLine[0] && toupper(N_ND->CurrentLine[0])!='A' && N_ND->CurrentLine[0]!='*')
                {
                  if (sscanf(N_ND->CurrentLine,"%d",&FromLine)) // should never fail, but it doesn't hurt to check..
                  {
                    DOOR_MenuPrompt("To: Line Number or [A]ll ",'A');
                    if (IN_TIMEOUT!=DOOR_GetLine(GL_EDIT|GL_DISPLAY|GL_USECHARS,'\0',3,10,NULL))
                    {
                      if (N_ND->OnlineStatus==OS_ONLINE)
                      {
                        if (N_ND->CurrentLine[0] && toupper(N_ND->CurrentLine[0])!='A' && N_ND->CurrentLine[0]!='*')
                        {
                          sscanf(N_ND->CurrentLine,"%d",&ToLine);
                        }
                      }
                    }
                  }
                }
              }
            }


            if (txtdata=HBBS_CreateList())
            {

              for (linenum=FromLine;linenum<=ToLine;linenum++)
              {
                ndata=GetNode(Msg->Data,linenum-1);
                NewStrNode(ndata->ln_Name,txtdata);
              }

              sprintf(outstr,"*** From: %s, Prev Num: %ld, Date: %s ",Msg->To,MsgNum,Msg->CreateDate);  // making sure we get the right name here helps :-)))
              for (loop=strlen(outstr);loop<79;loop++) outstr[loop]='*';
              outstr[79]=0; // to leave 78 printable chars

              NewStrNode(outstr,txtdata); // add the divider
              NewStrNode("",txtdata);     // and a blank line..

              if (HBBS_SaveFile(tmpmailfile,txtdata) && N_ND->OnlineStatus==OS_ONLINE)
              {
                DOOR_WriteText("Messages Quoted!\r\n");
              }
              FreeStrList(txtdata);
            }
          }
          if (N_ND->OnlineStatus==OS_ONLINE)
          {

            HBBS_GetDate(Msg->CreateDate);
            strcpy(Msg->ExpiryDate,"DD-MMM-YYYY"); // *C* changeme

            FreeStrList(Msg->Data);
            Msg->Data = NULL; // This was the cause of a crash prior to V1.10
            
            strcpy(outstr,tmpmailfile);
            strcat(outstr," LOAD");

            DOOR_SystemDoor("EDITOR",outstr);

            if (N_ND->OnlineStatus==OS_ONLINE)
            {
              if (iposition("CANCEL",N_ND->DoorReturn)>=0)
              {
                DOOR_WriteText("Cancelled!\r\n");
              }
              else
              {
                sprintf(outstr,"Saving Message to %s ",Msg->To);
                DOOR_WriteText(outstr);

                Msg->AttachedFiles=0;
                FreeStrList(Msg->AttachedFileList);
                 
                                         // confnum or 0
                if (PostNewMail(Msg,ConfNum,tmpmailfile))
                {
                  N_ND->User->MsgsWritten++; //this call
                  N_ND->User->CallData->MessagesWritten++; //total
                  N_ND->User->NormalData->MessagesWritten++;
                  DOOR_Return("OK");
                }

                FreeMailMessage(Msg);
              }
              DOOR_WriteText("\r[K");
            }
          }
        }
      }
    }
  }
}

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("Replying Mail");

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