/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* |_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                   */
/* |  . |//                                                                */
/* ======                                                                  */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Volume Manipulation */
/* ActCurentVol  ActRenameDisk ActDiskInfo ActInfo ActDiskChange*/

#include "handler.h"

static void GetInfo U_ARGS((GLOBAL, struct DosPacket *, struct InfoData *));

void ActCurentVol(global, pkt)
GLOBAL global;
struct DosPacket *pkt;              /* a pointer to the dos packet sent    */
{
   BUG(("ActCurentVol\n"));
   pkt->dp_Res1 = MKBADDR(global->volume);
}

void ActRenameDisk(global, pkt)
GLOBAL global;
struct DosPacket *pkt;              /* a pointer to the dos packet sent       */
{
   BUG(("ActRenameDisk\n"));

   DisMount(global);
   Mount(global, (char *)pkt->dp_Arg1);

   pkt->dp_Res1 = DOS_TRUE;
}

void GetInfo(global, pkt, info)
GLOBAL global;
struct DosPacket *pkt;
struct InfoData *info;
{
   BUG(("GetInfo\n"));

   if(global->volume == NULL)
   {
      info->id_DiskType = ID_NO_DISK_PRESENT;
      pkt->dp_Res1 = DOS_FALSE;
   }
   else
   {
      info->id_NumSoftErrors = global->n.ErrorCount;
      info->id_UnitNumber = global->unitnum;
      if(global->upnodes>1)
      {
         info->id_DiskState = ID_VALIDATED;
         info->id_DiskType  = ID_DOS_DISK;
      }
      else
      {
         info->id_DiskState = ID_VALIDATING;
         info->id_DiskType  = ID_NO_DISK_PRESENT;
      }
      info->id_NumBlocks = global->numnodes;
      info->id_NumBlocksUsed = global->upnodes;
      info->id_VolumeNode = MKBADDR(global->volume);
      info->id_InUse = 0;
      pkt->dp_Res1 = DOS_TRUE;
   }
   BUG(("GetInfo: Exit\n"));
}

void ActDiskInfo(global, pkt)
GLOBAL global;
struct DosPacket *pkt;
{
   BUG(("ActDiskInfo\n"));
   GetInfo(global, pkt, (struct InfoData *)pkt->dp_Arg1);
}

void ActInfo(global, pkt)
GLOBAL global;
struct DosPacket *pkt;              /* a pointer to the dos packet sent    */
{
   struct FileLock *flock;
   NETPTR nlock;

   BUG(("ActInfo\n"));

   flock = (struct FileLock *)pkt->dp_Arg1;

   if(flock == NULL || flock->fl_Volume != MKBADDR(global->volume) ||
      (nlock=(NETPTR)flock->fl_Key)->RPtr == NULL)
      GetInfo(global, pkt, (struct InfoData *)pkt->dp_Arg2);
   else
   {
      /* It is a remote lock - query the remote fs */
      global->RP.Type = pkt->dp_Type;
      global->RP.Arg1 = (LONG)nlock->RPtr;
      global->RP.DLen = 0;
   
      if(!RemotePacket(global, nlock))
         MQ(global->RP.Data, pkt->dp_Arg2, sizeof(struct InfoData));
   }
}

void ActNetKludge(global, pkt)
GLOBAL global;
struct DosPacket *pkt;
{
   struct NetNode *netnode;
   /* Arg1: BPTR to null-terminated BCPL string of name of network node */
   /* Arg2: BPTR to null-terminated string of name of device to use     */

   global->RP.Type = ACTION_NETWORK_KLUDGE;
   strcpy(global->RP.Data, (char *)pkt->dp_Arg2);
   global->RP.DLen = strlen((char *)pkt->dp_Arg2);
   if(!(netnode = FindNode(global, (char *)pkt->dp_Arg1+1)) &&
       global->netchain.next)
   {
      BUG(("ActNetKludge: Adding node %s len %d\n", 
         pkt->dp_Arg1+1, (int)*((unsigned char *)pkt->dp_Arg1)));

      if(netnode=AddNode(global, 
             (char *)pkt->dp_Arg1, global->netchain.next->ioptr))
         strcpy(netnode->devname, (char *)pkt->dp_Arg2);
   }
   else if(netnode->status != NODE_UP)
      ReSync(global, netnode->ioptr);

   if(!netnode || netnode->status != NODE_UP || !netnode->RootLock.RDevice)
   {
      BUG(("ActNetKludge: node %s netnode %08lx unavailable\n", 
         pkt->dp_Arg1, netnode));
      pkt->dp_Res1 = DOS_FALSE;
      pkt->dp_Res2 = ERROR_NODE_DOWN;
   }
   else 
      if(RemotePacket(global, &netnode->RootLock))
         netnode->status = NODE_CRASHED;
}

void ActDiskChange(global, pkt)
GLOBAL global;
struct DosPacket *pkt;
{
   BUG(("ActDiskChange\n"));
}
