/*
 * Copyright (c) 2003-2011
 * Distributed Systems Software.  All rights reserved.
 * See the file LICENSE for redistribution information.
 *
 * $Id: dsslib.h 2528 2011-09-23 21:54:05Z brachman $
 */

#ifndef _DSSLIB_H_
#define _DSSLIB_H_

#include "dacs_config.h"

#include <sys/types.h>
#include <limits.h>
#include <string.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>

/* Define this to get strptime() on some platforms */
#ifndef __USE_XOPEN
#define __USE_XOPEN
#endif

#include <time.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

/* Do not include DACS's local.h */
#include "ds.h"
#include "misc.h"
#include "str.h"
#include "range.h"
#include "kwv.h"
#include "net.h"
#include "http.h"
#include "cgiparse.h"
#include "mime.h"
#include "mkargv.h"
#include "http.h"
#include "xml.h"

/* For now, just make these functions go away... */
#define log_err(B)			log_exec_err B
#define log_msg(B)			log_exec_msg B
#define log_test(B)			0
#define log_would_log(LEV)	0

typedef enum {
  LOG_TRACE_LEVEL    = 0,
  LOG_DEBUG_LEVEL    = 1,
  LOG_INFO_LEVEL     = 2,
  LOG_NOTICE_LEVEL   = 3,
  LOG_WARN_LEVEL     = 4,
  LOG_ERROR_LEVEL    = 5,
  LOG_CRITICAL_LEVEL = 6,
  LOG_ALERT_LEVEL    = 7,
  LOG_EMERG_LEVEL    = 8,
} Log_level;

#ifdef __cplusplus
extern "C" {
#endif

extern int log_exec_err(int level, char *fmt, ...);
extern int log_exec_msg(int level, char *fmt, ...);

#ifdef __cplusplus
}
#endif

#ifndef EAGAIN
#define EAGAIN  EWOULDBLOCK
#endif

#ifndef HAVE_IN_PORT_T
#ifdef HAVE_UINT16_T
/* See IEEE Std 1003.1, 2004 Edition. */
typedef uint16_t in_port_t;
#else
/* A guess. */
typedef unsigned short in_port_t;
#endif
#endif

enum {
  INIT_CGI_KWV = 10
};

static char * MAYBE_UNUSED
non_null(char *s)
{

  return((s != NULL) ? s : "");
}

static inline MAYBE_UNUSED void *
safe_inline_malloc(size_t size, const char *log_module_name)
{
  void *p;

  if ((p = malloc(size)) == NULL) {
	log_msg((LOG_ALERT_LEVEL, "malloc failed, exiting"));
	exit(1);
  }

  return(p);
}
#define safe_malloc(SIZE)		safe_inline_malloc(SIZE, log_module_name)

static inline MAYBE_UNUSED void
safe_free(void *ptr)
{
  free(ptr);
}

static inline MAYBE_UNUSED void *
safe_inline_calloc(size_t number, size_t size, const char *log_module_name)
{
  void *p;

  if ((p = calloc(number, size)) == NULL) {
	log_msg((LOG_ALERT_LEVEL, "calloc failed, exiting"));
	exit(1);
  }

  return(p);
}
#define safe_calloc(NUMBER, SIZE) \
		safe_inline_calloc(NUMBER, SIZE, log_module_name)

static inline MAYBE_UNUSED void *
safe_inline_realloc(void *ptr, size_t size, const char *log_module_name)
{
  void *p;

  if ((p = realloc(ptr, size)) == NULL) {
	log_msg((LOG_ALERT_LEVEL, "realloc failed, exiting"));
	exit(1);
  }
  return(p);
}
#define safe_realloc(PTR, SIZE)	\
	safe_inline_realloc(PTR, SIZE, log_module_name)

static inline MAYBE_UNUSED char *
safe_inline_strdup(const char *str, const char *log_module_name)
{
  size_t len;
  void *p;

  len = strlen(str) + 1;
  p = safe_malloc(len);
  memcpy(p, str, len);
  return((char *) p);
}
#define safe_strdup(STR)	safe_inline_strdup(STR, log_module_name)

#define malloc(X)		safe_malloc(X)
#define calloc(X, Y)	safe_calloc(X, Y)
#define free(X)			safe_free(X)
#define realloc(X, Y)	safe_realloc(X, Y)
#define reallocf(X, Y)	safe_realloc(X, Y)
#define strdup(X)		safe_strdup(X)

#define ALLOC(OBJ)			((OBJ *) malloc(sizeof(OBJ)))
#define ALLOC_N(OBJ, N)		((OBJ *) malloc(sizeof(OBJ) * (N)))

#define XMLNS_SEP_CHAR				'|'

#endif
