#include "common.h"
#include "packet.h"

struct stufflist {
  SHORT count;
  PACKET *p;
};

packet_check(p, cshort, clong, cstr, cbin)
PACKET *p;
SHORT cshort, clong, cstr, cbin;
{
  if (p->cshort < cshort || p->clong < clong ||
      p->cstr < cstr || p->cbin < cbin) return -1;

  return 0;
}

/*ARGSUSED*/
_stuff_list_fn(indx, str, sl)
int indx;
char *str;
struct stufflist *sl;
{
  stuff_str(sl->p, str);
  (sl->count)++;
  return S_OK;
}

stuff_NAMELIST(p, list)
PACKET *p;
NAMELIST list;
{
  struct stufflist sl;
  sl.count = 0;
  sl.p = p;
  apply_namelist(list, _stuff_list_fn, &sl);    
  stuff_short(p, sl.count);
  return 0;
}

extract_NAMELIST(p, list, ishort, istr)
PACKET *p;
NAMELIST *list;
SHORT *ishort, *istr;
{
  SHORT cshort = (*ishort);
  SHORT cstr = (*istr);
  SHORT i, nstrs;

  if (packet_check(p, cshort+1, 0, 0, 0) == -1) {
    return -1;
  }
  
  nstrs =  p->shorts[cshort++];
  if (packet_check(p, 0, 0, cstr+nstrs, 0) == -1) {
    return -1;
  }

  create_namelist(list);
  for (i=0; i<nstrs; i++) {
    add_namelist(list, p->strs[cstr++], NULL);
  }

  (*ishort) = cshort;
  (*istr) = cstr;
  return 0;
}

stuff_ACCOUNT(p, acct)
PACKET *p;
ACCOUNT *acct;
{
  /* 
     NOTICE: This function and extract_ACCOUNT 
             must be updated if the ACCOUNT struct is changed!!!!

     Shorts: 1 (flags)
     Longs:  2 (perms, lastlogin)
     Strs:   10 (userid, passwd, username, fromhost, terminal,
                 realname, address, email, protocol, editor)
  */
  
  int rc = stuff_short(p, acct->flags)    |
           stuff_long(p, acct->perms)     |
           stuff_long(p, acct->lastlogin) |
           stuff_str(p, acct->userid)     |
           stuff_str(p, acct->passwd)     |
           stuff_str(p, acct->username)   |
           stuff_str(p, acct->fromhost)   |
           stuff_str(p, acct->terminal)   |
           stuff_str(p, acct->realname)   |
           stuff_str(p, acct->address)    |
           stuff_str(p, acct->email)      |
           stuff_str(p, acct->protocol)   |
           stuff_str(p, acct->editor);

  return rc;
}

extract_ACCOUNT(p, acct, ishort, ilong, istr)
PACKET *p;
ACCOUNT *acct;
SHORT *ishort, *ilong, *istr;
{
  /*
     NOTICE: This function AND stuff_ACCOUNT in the daemon
             must be updated if the ACCOUNT struct is changed!!!!

     Shorts: 1 (flags)
     Longs:  2 (perms, lastlogin)
     Strs:   10 (userid, passwd, username, fromhost, terminal,
                 realname, address, email, protocol, editor)
  */

  SHORT cshort = (*ishort);
  SHORT clong = (*ilong);
  SHORT cstr = (*istr);

  if (packet_check(p, cshort+1, clong+2, cstr+10, 0) == -1) {
    return -1;
  }

  acct->flags = p->shorts[cshort++];
  acct->perms = p->longs[clong++];
  acct->lastlogin = p->longs[clong++];
  strncpy(acct->userid, p->strs[cstr++], NAMELEN);
  strncpy(acct->passwd, p->strs[cstr++], PASSLEN);
  strncpy(acct->username, p->strs[cstr++], UNAMELEN);
  strncpy(acct->fromhost, p->strs[cstr++], HOSTLEN);
  strncpy(acct->terminal, p->strs[cstr++], TERMLEN);
  strncpy(acct->realname, p->strs[cstr++], RNAMELEN);
  strncpy(acct->address, p->strs[cstr++], ADDRLEN);
  strncpy(acct->email, p->strs[cstr++], MAILLEN);
  strncpy(acct->protocol, p->strs[cstr++], NAMELEN);
  strncpy(acct->editor, p->strs[cstr++], NAMELEN);

  (*ishort) = cshort;
  (*ilong) = clong;
  (*istr) = cstr;
  return 0;
}

stuff_BOARD(p, indx, brd)
PACKET *p;
int indx;
BOARD *brd;
{
  /* 
     NOTICE: This function AND extract_BOARD
             must be updated if the BOARD struct is changed!!!!

     Shorts: 1 (flags)
     Longs:  7 (indx, readmask, postmask, totalposts, newposts, 
                ownedposts, lastpost)
     Strs:   2 (name, description)
  */
  
  int rc = stuff_short(p, brd->flags)     |
           stuff_long(p, (LONG)indx)      |
           stuff_long(p, brd->readmask)   |
           stuff_long(p, brd->postmask)   |
           stuff_long(p, brd->totalposts) |
           stuff_long(p, brd->newposts)   |
           stuff_long(p, brd->ownedposts) |
           stuff_long(p, brd->lastpost)   |
           stuff_str(p, brd->name)        |
           stuff_str(p, brd->description);

  return rc;
}

extract_BOARD(p, indx, brd, ishort, ilong, istr)
PACKET *p;
int *indx;
BOARD *brd;
SHORT *ishort, *ilong, *istr;
{
  /*
     NOTICE: This function AND stuff_BOARD in the daemon
             must be updated if the BOARD struct is changed!!!!

     Shorts: 1 (flags)
     Longs:  7 (indx, readmask, postmask, totalposts, newposts,
                ownedposts, lastpost)
     Strs:   2 (name, description)
  */

  SHORT cshort = (*ishort);
  SHORT clong = (*ilong);
  SHORT cstr = (*istr);

  if (packet_check(p, cshort+1, clong+7, cstr+2, 0) == -1) {
    return -1;
  }

  brd->flags = p->shorts[cshort++];
  *indx = (int)(p->longs[clong++]);
  brd->readmask = p->longs[clong++];
  brd->postmask = p->longs[clong++];
  brd->totalposts = p->longs[clong++];
  brd->newposts = p->longs[clong++];
  brd->ownedposts = p->longs[clong++];
  brd->lastpost = p->longs[clong++];
  strncpy(brd->name, p->strs[cstr++], NAMELEN);
  strncpy(brd->description, p->strs[cstr++], TITLELEN);

  (*ishort) = cshort;
  (*ilong) = clong;
  (*istr) = cstr;
  return 0;
}



