#include "resman.h"

struct  List       *RMGetResReport(void);
void                RMFreeResReport(struct List *);
BOOL                RMLockResource(struct MiscNode *,struct MiscLock *,struct RMMessage *);
struct MiscLock    *RMFreeResource(struct MiscNode *mn, struct RMMessage *msg);
BOOL                CheckResource(struct MiscNode *,struct RMMessage *);


struct List *RMGetResReport(void)

{struct List       *lst;
 struct ResRepNode *rrn;
 struct Node       *nd;
 struct PortNode   *pn;
 struct MiscNode   *mn;

 lst = (struct List *)malloc(sizeof(struct List));

   InitList(lst);

   nd=ResourceList.lh_Head;

   while(nd->ln_Succ)
   {
      rrn=(struct ResRepNode *)malloc(sizeof(struct ResRepNode));

      rrn->node.ln_Type=nd->ln_Type;
      rrn->node.ln_Name=(char *)malloc(strlen(nd->ln_Name)+1);
      strcpy(rrn->node.ln_Name,nd->ln_Name);

      mn=(struct MiscNode *)nd;
      rrn->users=mn->users;

      rrn->activelocks=(struct List *)GetLockReport(&(mn->activelocks));
      rrn->pendinglocks=(struct List *)GetLockReport(&(mn->locklist));

      rrn->bgcommand=NULL;
      rrn->language=NULL;
      rrn->menu=NULL;

      if(nd->ln_Type==NODE_PORT)
      {
         pn=(struct PortNode *)nd;

         if(pn->bgcommand)
         {
            rrn->bgcommand=(char *)malloc(strlen(pn->bgcommand)+1);
            strcpy(rrn->bgcommand,pn->bgcommand);
         }

         if(pn->ln)
         {
            rrn->language=(char *)malloc(strlen(pn->ln->ls.name)+1);
            strcpy(rrn->language,pn->ln->ls.name);
         }

         if(pn->menu)
         {
            rrn->menu=(char *)malloc(strlen(pn->menu->mn.node.ln_Name)+1);
            strcpy(rrn->menu,pn->menu->mn.node.ln_Name);
         }
      }

      AddTail(lst,(struct Node *)rrn);

      nd=nd->ln_Succ;
   }

   return(lst);
}


void RMFreeResReport(struct List *lst)
{
   struct ResRepNode *rrn;

   while(rrn=(struct ResRepNode *)RemHead(lst))
   {
      free(rrn->node.ln_Name);

      if(rrn->activelocks) FreeLockReport(rrn->activelocks);
      if(rrn->pendinglocks) FreeLockReport(rrn->pendinglocks);
      if(rrn->bgcommand) free(rrn->bgcommand);
      if(rrn->language) free(rrn->language);
      if(rrn->menu) free(rrn->menu);

      free(rrn);
   }

   free(lst);
}


BOOL RMLockResource(struct MiscNode *mn, struct MiscLock *ml, struct RMMessage *msg)

{ml->node.ln_Name = malloc(strlen(msg->passwd) + strlen(msg->reason) + 2);
 ml->reason       = stpcpy(ml->node.ln_Name, msg->passwd);
                    strcpy(++ml->reason,     msg->reason);

 ml->node.ln_Type = mn->node.ln_Type;
 ml->node.ln_Pri  = msg->priority;
 ml->type         = msg->flags;
 ml->rm           = msg;

 if ((Empty(&(mn->activelocks))||!((mn->type|msg->flags)&WRITELOCK))&&((msg->flags&QUICKLOCK) || !mn->users))
    {AddTail(&(mn->activelocks),(struct Node *)ml);
     mn->type |= ml->type;
     return(TRUE);
    }

 Enqueue(&(mn->locklist), (struct Node *)ml);
 return(FALSE);
}


struct MiscLock *RMFreeResource(struct MiscNode *mn,struct RMMessage *msg)

{struct MiscLock *ml;

 if (!(ml = (struct MiscLock *)IFindName(&(mn->activelocks),msg->passwd)))
     return(NULL);

 Remove((struct Node *)ml);

 if (Empty(&(mn->activelocks)))
    {mn->type = 0;
     HandlePending(mn);
    }

 free(ml->node.ln_Name);
 return(ml);
}


BOOL CheckResource(struct MiscNode *mn, struct RMMessage *msg)

{if ((Empty(&(mn->activelocks)) || !((mn->type|msg->flags)&WRITELOCK))&&((msg->flags&QUICKLOCK) || !mn->users))
      return(TRUE);

 return(FALSE);
}
