/*

     [DSKEL-MSg v1.0] MS [Generic]           By The Skeleton [08-01-92]
     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
     | NODE | LOGON | HANDLE                    | ACTiViTY            |
     |======|=======|===========================|=====================|
     |   1  | 17:45 | The Skeleton              | Downloading         |
     |------|-------|---------------------------|---------------------|
     |   2  | --:-- | Awaiting a call           | Idle                |
     |------|-------|---------------------------|---------------------|
     |   3  | --:-- | Awaiting a call           | Idle                |
     |----------------------------------------------------------------|
     | Select node number you want to chat with.                      |
     `----------------------------------------------------------------'
      [Return = Quit] Select:

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

#include <proto/all.h>
#include <stdio.h>
#include <stdarg.h>

#include <string.h>
#include <time.h>
#include <tempest/headers.h>
#include <tempest/defines.h>

//********************************
//*****  Structures/Defines  *****
//********************************

 struct MyMessage
  {
   struct Message Msg; // for Exec message routines
   ULONG  Command;     // Command to be executed.

   char   *text1,
          *text2,
          *text3;
   int    Value1,
          Value2;
   ULONG  LongValue;
   LONGBITS Flags;
   int    carrier;
   struct User       *User;
   struct SystemData *SystemData;
   struct NodeData   *NodeData;
   struct Today      *Today;
  };

struct MyMessage send;

struct User *User;
struct SystemData *SystemData;
struct NodeData *NodeData;
struct Today *Today;
struct MsgPort *MyPort = NULL;
struct MyMessage *msg;
struct node_info nody;

int  DoorStart(TEXT *);
int  DOORIO(WORD);
VOID CloseStuff(VOID);

VOID Activity(BYTE,TEXT *);
int  CTRLC(VOID);
VOID Editor(TEXT *savename,TEXT *loadname,int maxlength);
VOID input(TEXT *,int);
VOID pl(TEXT *,...);
VOID WriteFile(TEXT *,TEXT *);
VOID GetStr(TEXT *s,int opt);


VOID core(ULONG);
VOID sendtext(BYTE);
VOID ListNodes(VOID);
int Loadnody(int node);
char *Myctime(long *);

//*******************************
//*****  Global Variables  ******
//*******************************

int  NODE,R_NODE,NODES;
int  Result,Error;
char nodename[255];
struct MsgPort *TempestPort;

char inputstring[300],ins[60];

char argtext[200];


UWORD RSlot;

//******************
//*****  Main  *****
//******************

int main(int argc,char *argv[])
{
 BYTE done=0;
 int stat,x;
 int Node=-1;
 if(!DoorStart(argv[1])) { PutStr("TempesT Door\n"); exit(0); }

 if(!(User->NFlags1 & NF1_InternodeMsgSend))
  {
   pl("\r\n[31mAccess Denied![0m\r\n");
   CloseStuff();
  }
 GetStr(inputstring,1);
 strcpy(argtext,"");
 for(stat=0;stat<strlen(inputstring);stat++)
  {
   if((inputstring[stat]>='0')&&(inputstring[stat]<='9')&&(done==0))
    {
     for(x=0;x<4;x++)
      {
       if((inputstring[stat]>='0')&&(inputstring[stat]<='9'))
        {
         ins[x]=inputstring[stat];
         stat++;
        }
       else break;
      }
     ins[x]=NULL;
     Node=atoi(ins);
     done=1;
    }
   if((inputstring[stat]==' ')&&(done==1))
    {
     strcpy(argtext,&inputstring[stat+1]);
     strcat(argtext,"\n");
     break;
    }
  }
 SetTaskPri(FindTask(0),SystemData->DoorsPriority);

 Activity(31,"");

 NODE = atoi(argv[1]);
 stat=Loadnody(NODE);
 if(stat==0)
  {
   pl("NodeInfo File Not Found!\r\n");
   CloseStuff();
  }
 NODES = nody.SystemDataInfo->NumberOfLines;
 core(Node);
 CloseStuff();
}
//******************
//*****  Core  *****
//******************

VOID core(ULONG Node)
{
 char string[60];
 register int x;
 int stat;

 pl("\r\n[44;37mInternode Msg Sender Module v3.60[0m\r\n");

 while(1)
  {
   REDO:
   if(Node==-1)
    {
     pl("\r\n[34m([35mRETURN[34m) [36mto Quit, [34m([35mWHO[34m) [36mis online\r\n");
     pl("[36mSelect Node Number to send msg to, [34m([35mA[34m) [36mfor all nodes[0m: ");
     input(string,3);
     if(string[0]==NULL) break;
     string[0]=toupper(string[0]);
     if((string[0]=='N')||(string[0]=='Q')) break;
     R_NODE = 0;
     if((string[0]=='?')||(string[0]=='L')||(string[0]=='W'))
      {
       ListNodes();
       goto REDO;
      }
     if(string[0]=='A')
      {
       stat=0;
       for(x=0;x<NODES+1;x++) if((nody.UserInfo->Name[0]!=NULL)&&(x!=NODE)) stat++;
       if(stat>0)
        {
         sprintf(string,"node:work_ed-A",NODE);
         Editor(string,"",10);
         for(x=0;x<NODES+1;x++)
          {
           if(x != NODE)
            {
             stat=Loadnody(x);
             if((nody.UserInfo->Name[0]!=NULL)&&(stat!=0)&&(!(nody.UserInfo->UserBitsB & B2_LP_AutoMute)))
              {
               R_NODE = x;
               RSlot=nody.UserInfo->Slot_Number;
               if(access(string,0)==0)
                {
                 sendtext(1);
                 nody.GLOB->OLM=1;
                }
              }
            }
          }
         DeleteFile(string);
        }
       else pl("\r\n[33mNobody online to send a msg to!\r\n\r\n");
      }
     x = atoi(string);
    }
   else
    {
     x=Node;
     Node=-1;
    }
   if(x==NODE) goto REDO;
   stat=Loadnody(x);
   if((nody.UserInfo->Name[0]!=NULL)&&(stat!=0))
    {
     if(nody.UserInfo->NFlags1 & NF1_RecieveNodeMsgs)
      {
       if(!(nody.GLOB->mute))
        {
         RSlot=nody.UserInfo->Slot_Number;
         R_NODE = x;
         sprintf(string,"node:work_ed-%d",NODE);
         if(argtext[0]==NULL)
          {
           Editor(string,"",10);
          }
         else
          {
           WriteFile(string,argtext);
           argtext[0]=NULL;
          }
         if(access(string,0)==0)
          {
           pl("\r\n[35mSending Msg![0m\r\n");
           sendtext(0);
           nody.GLOB->OLM=1;
          }
        }
       else pl("\r\n[31mUser is in mute mode, not allowing internode messages!\r\n\r\n");
      }
     else pl("\r\n[31mSorry, that user is not allowed to receive internode msgs!\r\n\r\n");
    }
   else pl("\r\n[31mNobody on that node!\r\n");
  }
}

//************************
//*****  Load Nody  ******
//************************

int Loadnody(int node)
{
 char string[50];
 register int y;
 int file;
 sprintf(string,"Node:NodeInfo_%d",node);
 for(y=1;y<3;y++)
  {
   file=Open(string,MODE_OLDFILE);
   if(file!=0)
    {
     Read(file,(char *)&nody,sizeof(struct node_info));
     Close(file);
     return(1);
    }
  }
 return(0);
}

//*************************
//*****  List Nodes  ******
//*************************

VOID ListNodes(VOID)
{
 char string[200],string2[20];
 char Handle[40],Activity[30],Time[15];
 int stat;
 register int i;

 if(!(User->NFlags1 & NF1_ViewNodeLists)) return;


 if(User->AnsiType<=1)
  {
   pl("[34m.----------------------------------------------------------------.[0m\r\n");
   pl("[34m| [33mNoDE [34m| [33mLoGoN [34m| [33mHANDLE                    [34m| [33mACTiViTY            [34m|\r\n");
  }
 else
  {
   pl("[34mÉÍÍÍÍÍÍËÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»[0m\r\n");
   pl("[34mº [33mNoDE [34mº [33mLoGoN [34mº [33mHANDLE                    [34mº [33mACTiViTY            [34mº\r\n");
  }

 i=0;
 do
  {
   if(CTRLC())
    {
     pl("[31mAborting Who Display![0m\r\n");
     return;
    }
   stat=Loadnody(i);
   if(stat==0) goto EXIT;
   if(nody.GLOB->AN!=62)
    {
     if((nody.GLOB->hide==1)&&(nody.UserInfo->Slot_Number==1)&&(!(User->SFlags1 & SF1_SysopWho))) goto EXIT;
     strcpy(Handle,nody.UserInfo->Name);
     if((nody.GLOB->hide==1)&&(!(User->SFlags1 & SF1_SysopWho)))
         strcpy(Handle,"(Hidden from display)");
     if(nody.UserInfo->Name[0]==NULL)
         strcpy(Handle," ");

     sprintf(string,"%s",Myctime(&nody.UserInfo->Time_Last_Connect));
     strmid(string,Time,12,5);
     strcpy(Activity,nody.GLOB->activity);

     //***************************
     //*****  Final Output  ******
     //***************************
     sprintf(string2,"%2d",i);
     if(User->AnsiType<=1)
      {
       pl("|------|-------|---------------------------|---------------------|\r\n");
       sprintf(string,"|  [36m%2s  [34m| [31m%5s [34m| [36m%-25.25s [34m| [35m%-19s [34m|\r\n",
               string2,Time,Handle,Activity);
      }
     else
      {
       pl("ºÍÍÍÍÍÍºÍÍÍÍÍÍÍºÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍºÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍº\r\n");
       sprintf(string,"º  [36m%2s  [34mº [31m%5s [34mº [36m%-25.25s [34mº [35m%-19s [34mº\r\n",
               string2,Time,Handle,Activity);
      }
     pl(string);
    }
   EXIT:
   i++;
  }
 while(i<NODES);
 if(User->AnsiType<=1)
      pl("`----------------------------------------------------------------'\r\n");
 else pl("ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼\r\n");
}

//***********************
//*****  Send Text  *****
//***********************

VOID sendtext(TYPE) // 0 = single, 1 = All
BYTE TYPE;
{
 FILE *in,*out;
 char string[300],shit[100];
 char begin[60],middle[60],end[60],send[60];

 if(nody.UserInfo->Slot_Number==RSlot)
      sprintf(send,"node:MsgToNode-%d",R_NODE);
 else strcpy(send,"node:MstToNode");

 sprintf(begin,"node:work1-%d",NODE);
 if(TYPE) sprintf(middle,"node:work_ed-A",NODE);
 else     sprintf(middle,"node:work_ed-%d",NODE);
 sprintf(end,"node:work2-%d",NODE);
 strcpy(shit,"-------------------------------------------------------------------------------\n");

 sprintf(string,"\r\n\r\n[37mInternode Message[0m Sent by [35m%s[0m on Node #%d\n%s",User->Name,NODE,shit);
 WriteFile(begin,string);

 sprintf(string,"%s[0m* END OF MSG *\n",shit);
 WriteFile(end,string);

 sprintf(string,"Join >nil: %s %s %s as %s",begin,middle,end,send);
 Execute(string,0L,0L);

 if(nody.UserInfo->Slot_Number!=RSlot)
  {
   in=fopen(send,"r");
   if(in!=NULL)
    {
     sprintf(string,"%sOLM/OLM-%d",SystemData->AccountInfoPath,RSlot);
     out=fopen(string,"a");
     if(out==NULL) out=fopen(string,"w");
     if(out!=NULL)
      {
       while(fgets(string,150,in)!=NULL)
        {
         fprintf(out,string);
        }
       fclose(out);
      }
     fclose(in);
    }
   DeleteFile(send);
  }
 DeleteFile(begin);
 if(!TYPE) DeleteFile(middle);
 DeleteFile(end);
}

//===========================* Beginning of Module *===========================
char *Myctime(long *secs)
{
 struct tm *tm;
 tm=gmtime(secs);
 return(asctime(tm));
}

//************************
//*****  Door Start  ***** // MUST BE INCLUDED IN ALL DOORS!
//************************
int DoorStart(TEXT *node)
{
 char string[60];
 send.carrier=0;
 sprintf(string,"%s:TEMPEST_DOOR",node);
 TempestPort=FindPort(string);
 if(TempestPort==NULL) return(int)FALSE;
 MyPort=CreateMsgPort();
 if(MyPort==NULL) return(int)FALSE;
 DOORIO(0);
 User=*&send.User;
 SystemData=*&send.SystemData;
 NodeData=*&send.NodeData;
 Today=*&send.Today;
 return(int)TRUE;
}
//********************
//*****  DoorIO  ***** // MUST BE INCLUDED IN ALL DOORS!
//********************
int DOORIO(WORD Command)
{
 if(send.carrier) return(0);
 send.Command=Command;
 send.Msg.mn_Node.ln_Type = NT_MESSAGE;
 send.Msg.mn_Length = sizeof(send);
 send.Msg.mn_ReplyPort = MyPort;
 send.carrier=0;
 PutMsg((struct MsgPort *)TempestPort,(struct Message *)&send);
 Wait(1 << MyPort->mp_SigBit);
 GetMsg(MyPort);
 if((send.carrier)&&(send.Command!=999)) CloseStuff();
 return(1);
}
//*************************
//*****  Close Stuff  ***** // MUST BE INCLUDED IN ALL DOORS!
//*************************
VOID CloseStuff(VOID)
{
 DOORIO(999);
 while(msg=(struct MyMessage *)GetMsg(MyPort)) ReplyMsg((struct Message *)msg);
 if(MyPort) DeleteMsgPort(MyPort);
 exit(0);
}
//**********************
//*****  Activity  ***** // Command 44
//**********************
VOID Activity(BYTE act,TEXT *s)
{
 send.Value1=act;
 send.text1=s;
 DOORIO(44);
}
//*************************
//*****  CTRLC CHECK  ***** // Command 10
//*************************
int CTRLC(VOID)
{
 DOORIO(10);
 return(send.Value1);
}
//********************
//*****  Editor  ***** // Command 73
//********************
VOID Editor(TEXT *savename,TEXT *loadname,int maxlength)
{
 send.Value1=maxlength;
 send.text1=savename;
 send.text2=loadname;
 DOORIO(73);
}
//*******************
//*****  Input  ***** // Command 20
//*******************
VOID input(TEXT *mstring,int len)
{
 send.Value1=len;
 send.text1 =mstring;
 DOORIO(20);
}
VOID pl(TEXT *fmt,...)
{
 va_list args;
 char s[255];
 va_start(args,fmt);
 vsprintf(s,fmt,args);
 va_end(args);
 send.text1=&s[0];
 DOORIO(1);
}
//************************
//*****  Write File  ***** // Command 69
//************************
VOID WriteFile(TEXT *ostring,TEXT *mstring)
{
 send.text1=ostring;
 send.text2=mstring;
 DOORIO(69);
}
//*********************************
//*****  GetStr (Get String)  ***** // Command 33
//*********************************
VOID GetStr(TEXT *s,int opt)
{
 send.Value1=opt;
 strcpy(s,"");
 send.text1=s;
 DOORIO(33);
}
