/* Device.c - Device support routines */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* |_o_o|\\ Copyright (c) 1987, 1988 The Software Distillery.  All Rights  */
/* |. o.| || Reserved.  This program may not be distributed without the    */
/* | .  | || permission of the authors:                            BBS:    */
/* | o  | ||   John Toebes     Doug Walker    Dave Baker                   */
/* |  . |//                                                                */
/* ======                                                                  */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "handler.h"

#define MYNAME "\7NETWORK"

typedef struct FileSysStartupMsg *FSSM;

int GetDevice (global, myfssmsg)
GLOBAL global;    
FSSM myfssmsg;
{
FSSM  fssmsg;
int   devnum;
char  *defaultdev = "serial.device";

BUGP("GetDevice entry")

   BUG(("devname:%s\n",global->n.devname));
   BUG(("Global->node = %08lx Global->node->dn_Startup = %08lx\n",
         global->node, BADDR(global->node->dn_Startup)));

   /* Did they give us any information in the device list ? */
   if( (fssmsg = (FSSM)BADDR(global->node->dn_Startup)) == NULL)
   {
BUGP("Null FSSM")
      /* Initialize the device information */
      global->unitnum = myfssmsg->fssm_Unit = devnum = 0;
      myfssmsg->fssm_Device          = (ULONG)defaultdev;
      myfssmsg->fssm_Flags           = 0;
      BUG(("GetDevice-fssm_Device:%s\n", myfssmsg->fssm_Device));
      BUG(("GetDevice-fssm_Unit:%ld\n",   myfssmsg->fssm_Unit)); 
      BUG(("GetDevice-fssm_Flags:%lx\n", myfssmsg->fssm_Flags));
   }
   else
   {
BUGP("Good FSSM")
      /* They gave us all the device information in the mountlist */
      if(fssmsg->fssm_Device != NULL)
         myfssmsg->fssm_Device  = (ULONG)BADDR(fssmsg->fssm_Device);
      else
         myfssmsg->fssm_Device = (ULONG)defaultdev;
      global->unitnum        =
      myfssmsg->fssm_Unit    = fssmsg->fssm_Unit;
      myfssmsg->fssm_Flags   = (ULONG)BADDR(fssmsg->fssm_Flags);
  
      BUG(("fssm:%lx\n", fssmsg));
      BUG(("fssm_Device:%s\n",    fssmsg->fssm_Device));
      BUG(("fssm_Unit:%ld\n",      fssmsg->fssm_Unit)); 
      BUG(("fssm_Flags:%lx\n",    fssmsg->fssm_Flags));
   }

BUGP("GetDevice exit")
   return(-1);
}



int InitDevice(global)
GLOBAL global;
{
   struct FileSysStartupMsg myfssmsg;
   int rc;

   BUGP("InitDevice: Enter")
   BUG(("InitDevice: Enter\n"));

   if (GetDevice(global,&myfssmsg) == NULL)
   {
      BUG(("GetDevice Failed \n"));
      return(0);
   }

   if(!(global->n.devport=CreatePort(NULL,0)))
   {
      BUG(("ERROR: Can't CreatePort\n"));
      return(0);
   }

   BUG(("fssm_Device:%s\n", myfssmsg.fssm_Device));
   BUG(("fssm_Unit:%ld\n",   myfssmsg.fssm_Unit)); 
   BUG(("fssm_Flags:%lx\n", myfssmsg.fssm_Flags));

   BUGP("Init NetNode")

   /* Initialize NetNode struct for ourselves - at root of netnodes */
   global->netchain.next = NULL;
   global->netchain.status = NODE_UP;
   MBSTR(MYNAME, global->netchain.name);
   global->netchain.id = 0;
   global->netchain.ioptr = NULL;
   global->netchain.RootLock.NetNode = &global->netchain;
   /* A NULL RDevice indicates this is a lock on the local root */
   global->netchain.RootLock.RDevice = NULL;
   global->netchain.RootLock.RPtr = NULL;

   global->numnodes = global->upnodes = 1;
#ifndef SMALLPACKET
   MBSTR(MYNAME, global->RP.handler);
   global->RP.handlerid = 0;  /* Fix this! */
#endif
   rc = InitRDevice(global);

   BUGP("InitDevice: Exit")

   return(rc);
}

struct NetNode *AddNode(global, name, ioptr)
GLOBAL global;
char *name;
APTR ioptr;
{
   struct NetNode *node;

BUGBSTR("AddNode: Adding ", name);
BUG(("ioptr is %lx\n", ioptr));

   /* First see if the node's name is unique */
   for(node=&global->netchain; node; node=node->next)
   {
      if(!stricmp(node->name, name))
      {
         if(node->status == NODE_UP) global->upnodes--;
         break;
      }
   }
   if(!node)
   {
      BUG(("AddNode: Node not in chain\n"));
      /* Node is new, add it */
      if(!(node=(struct NetNode *)DosAllocMem(global, 
                                       (long)sizeof(struct NetNode))))
      {
         BUG(("AddNode: Out of memory!\n"));
         return(NULL);
      }
      /* Chain the node into the list of network nodes */
      node->next = global->netchain.next;
      global->netchain.next = node;
      strcpy(node->name, name);
      node->devname[0] = '\0';
      node->id = 0;
      global->numnodes++;
      /* Set up dummy lock for lock templating */
      node->RootLock.NetNode = node;
      node->RootLock.RDevice = (RPTR)1L; /* For now - Obtain from remote */
      node->RootLock.RPtr = NULL; /* For always */
   }

   node->status = (ioptr ? NODE_UP
                         : (node->status == NODE_UP ? NODE_CRASHED
                                                    : NODE_DEAD));
   node->ioptr = ioptr;

   if(node->status == NODE_UP) global->upnodes++;

   return(node);
}

int TermDevice(global)
GLOBAL global;
{
   TermRDevice(global, 0);
   return(1);
}
