#include "resman.h"

struct  List        *GetLockReport(struct List *);
void                FreeLockReport(struct List *);
struct MiscLock     *RMFreeResource(struct MiscNode *,struct RMMessage *);
int                 HandlePending(struct MiscNode *);

struct List *GetLockReport(struct List *locklst)

{struct List        *lst;
 struct LockRepNode *lrn;
 struct Node        *nd;
 struct MiscLock    *ml;
 struct PortLock    *pl;

 if (Empty(locklst))  return(NULL);

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

 nd = locklst->lh_Head;
 while(nd->ln_Succ)
      {lrn = malloc(sizeof(struct LockRepNode) + strlen(nd->ln_Name) + 1);

       lrn->node.ln_Type = nd->ln_Type;
       lrn->node.ln_Pri  = nd->ln_Pri;
       lrn->node.ln_Name = (char *)lrn + sizeof(struct LockRepNode);
       strcpy(lrn->node.ln_Name, nd->ln_Name);

       ml = (struct MiscLock *)nd;
       lrn->type = ml->type;

       lrn->reason = NULL;
       if (ml->reason)
          {lrn->reason = malloc(strlen(ml->reason)+1);
           strcpy(lrn->reason, ml->reason);
          }

       lrn->breakcommand = NULL;
       if (nd->ln_Type==NODE_PORT)
          {pl = (struct PortLock *)nd;
           if (pl->breakcommand)
              {lrn->breakcommand = malloc(strlen(pl->breakcommand)+1);
          strcpy(lrn->breakcommand, pl->breakcommand);
              }
          }

       AddTail(lst, (struct Node *)lrn);
       nd = nd->ln_Succ;
      }

 return(lst);
}


void FreeLockReport(struct List *lst)

{struct LockRepNode *lrn;

 while(lrn=(struct LockRepNode *)RemHead(lst))
      {if (lrn->breakcommand)  free(lrn->breakcommand);
       if (lrn->reason)        free(lrn->reason);
       free(lrn);
      }

 free(lst);
}


int HandlePending(struct MiscNode *mn)

{struct RMMessage *rm;
 struct Node      *nd;
 struct Node      *nxtnd;
 struct MiscLock  *ml;
 int    count = 0;

 nd = mn->locklist.lh_Head;
 while(nd->ln_Succ)
      {ml    = (struct MiscLock *)nd;
       nxtnd =  nd->ln_Succ;

       if ((Empty(&(mn->activelocks)) || !((mn->type|ml->type)&WRITELOCK))&&((ml->type&QUICKLOCK) || !mn->users))
          {Remove(nd);

           AddTail(&(mn->activelocks),(struct Node *)ml);
           mn->type |= ml->type;
           rm        = ml->rm;
           rm->type  = RMNOERR;
           ReplyMsg((struct Message *)rm);
           count++;
          }

       if (ml->type&WRITELOCK)  break;
       nd = nxtnd;
      }

 return(count);
}
