#ifndef LIBATALK_CNID_PRIVATE_H
#define LIBATALK_CNID_PRIVATE_H 1

#include <string.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>

#include <db.h>

#include <atalk/adouble.h>
#include <atalk/cnid.h>

#define CNID_DB_MAGIC   0x434E4944U  /* CNID */
#define CNID_DATA_MAGIC 0x434E4945U  /* CNIE */

#define CNID_DEVINO_LEN          8
#define CNID_DID_LEN             4
#define CNID_HEADER_LEN          (CNID_DEVINO_LEN + CNID_DID_LEN)

#define CNID_START               3

#define CNIDFLAG_ROOTINFO_RO     (1 << 0)
#define CNIDFLAG_DB_RO           (1 << 1)

typedef struct CNID_private {
	u_int32_t magic;
	DB *db_cnid, *db_didname, *db_devino;
	DB_ENV dbenv;
	struct adouble rootinfo;
        int lockfd, flags;
} CNID_private;

/* on-disk data format (in network byte order where appropriate) --
 * name          size
 * dev           4
 * ino           4
 * did           4
 * name          strlen(name) + 1
 *
 * NOTE: this is not re-entrant.
 *
 */
static __inline__ char *make_cnid_data(const struct stat *st,
				       const cnid_t did, const char *name,
				       const int len)
{
  static char start[CNID_HEADER_LEN + MAXPATHLEN + 1], *buf;
  u_int32_t i;
  
  if (len > MAXPATHLEN)
    return NULL;

  buf = start;
  i = htonl(st->st_dev);
  memcpy(buf, &i, sizeof(i));
  buf += sizeof(i);
  i = htonl(st->st_ino);
  memcpy(buf, &i, sizeof(i));
  buf += sizeof(i);
  memcpy(buf, &did, sizeof(did)); /* did already in network byte order */
  buf += sizeof(did);
  memcpy(buf, name, len);
  *(buf + len) = '\0'; /* include a terminal null byte */

  return start;
}

#endif /* atalk/cnid/cnid_private.h */
