code:
/* $FreeBSD: release/9.0.0/lib/libusb/libusb20.h 225659 2011-09-19 08:52:06Z hselasky $ */
/*-
 * Copyright (c) 2008-2009 Hans Petter Selasky. All rights reserved.
 * Copyright (c) 2007-2008 Daniel Drake.  All rights reserved.
 * Copyright (c) 2001 Johannes Erdfelt.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _LIBUSB20_H_
#define	_LIBUSB20_H_

#include <sys/endian.h>
#include <sys/time.h>
#include <sys/types.h>

#include <stdint.h>
#include <string.h>
#include <time.h>

#ifdef __cplusplus
extern	"C" {
#endif
#if 0
};					/* style */

#endif

/** \ingroup misc
 * Error codes. Most libusb20 functions return 0 on success or one of
 * these codes on failure.
 */
enum libusb20_error {
	/** Success (no error) */
	LIBUSB20_SUCCESS = 0,

	/** Input/output error */
	LIBUSB20_ERROR_IO = -1,

	/** Invalid parameter */
	LIBUSB20_ERROR_INVALID_PARAM = -2,

	/** Access denied (insufficient permissions) */
	LIBUSB20_ERROR_ACCESS = -3,

	/** No such device (it may have been disconnected) */
	LIBUSB20_ERROR_NO_DEVICE = -4,

	/** Entity not found */
	LIBUSB20_ERROR_NOT_FOUND = -5,

	/** Resource busy */
	LIBUSB20_ERROR_BUSY = -6,

	/** Operation timed out */
	LIBUSB20_ERROR_TIMEOUT = -7,

	/** Overflow */
	LIBUSB20_ERROR_OVERFLOW = -8,

	/** Pipe error */
	LIBUSB20_ERROR_PIPE = -9,

	/** System call interrupted (perhaps due to signal) */
	LIBUSB20_ERROR_INTERRUPTED = -10,

	/** Insufficient memory */
	LIBUSB20_ERROR_NO_MEM = -11,

	/** Operation not supported or unimplemented on this platform */
	LIBUSB20_ERROR_NOT_SUPPORTED = -12,

	/** Other error */
	LIBUSB20_ERROR_OTHER = -99,
};

/** \ingroup asyncio
 * libusb20_tr_get_status() values */
enum libusb20_transfer_status {
	/** Transfer completed without error. Note that this does not
	 * indicate that the entire amount of requested data was
	 * transferred. */
	LIBUSB20_TRANSFER_COMPLETED,

	/** Callback code to start transfer */
	LIBUSB20_TRANSFER_START,

	/** Drain complete callback code */
	LIBUSB20_TRANSFER_DRAINED,

	/** Transfer failed */
	LIBUSB20_TRANSFER_ERROR,

	/** Transfer timed out */
	LIBUSB20_TRANSFER_TIMED_OUT,

	/** Transfer was cancelled */
	LIBUSB20_TRANSFER_CANCELLED,

	/** For bulk/interrupt endpoints: halt condition detected
	 * (endpoint stalled). For control endpoints: control request
	 * not supported. */
	LIBUSB20_TRANSFER_STALL,

	/** Device was disconnected */
	LIBUSB20_TRANSFER_NO_DEVICE,

	/** Device sent more data than requested */
	LIBUSB20_TRANSFER_OVERFLOW,
};

/** \ingroup asyncio
 * libusb20_tr_set_flags() values */
enum libusb20_transfer_flags {
	/** Report a short frame as error */
	LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK = 0x0001,

	/** Multiple short frames are not allowed */
	LIBUSB20_TRANSFER_MULTI_SHORT_NOT_OK = 0x0002,

	/** All transmitted frames are short terminated */
	LIBUSB20_TRANSFER_FORCE_SHORT = 0x0004,

	/** Will do a clear-stall before xfer */
	LIBUSB20_TRANSFER_DO_CLEAR_STALL = 0x0008,
};

/** \ingroup misc
 * libusb20_dev_get_mode() values
 */
enum libusb20_device_mode {
	LIBUSB20_MODE_HOST,		/* default */
	LIBUSB20_MODE_DEVICE,
};

/** \ingroup misc
 * libusb20_dev_get_speed() values
 */
enum {
	LIBUSB20_SPEED_UNKNOWN,		/* default */
	LIBUSB20_SPEED_LOW,
	LIBUSB20_SPEED_FULL,
	LIBUSB20_SPEED_HIGH,
	LIBUSB20_SPEED_VARIABLE,
	LIBUSB20_SPEED_SUPER,
};

/** \ingroup misc
 * libusb20_dev_set_power() values
 */
enum {
	LIBUSB20_POWER_OFF,
	LIBUSB20_POWER_ON,
	LIBUSB20_POWER_SAVE,
	LIBUSB20_POWER_SUSPEND,
	LIBUSB20_POWER_RESUME,
};

struct usb_device_info;
struct libusb20_transfer;
struct libusb20_backend;
struct libusb20_backend_methods;
struct libusb20_device;
struct libusb20_device_methods;
struct libusb20_config;
struct LIBUSB20_CONTROL_SETUP_DECODED;
struct LIBUSB20_DEVICE_DESC_DECODED;

typedef void (libusb20_tr_callback_t)(struct libusb20_transfer *xfer);

struct libusb20_quirk {
	uint16_t vid;			/* vendor ID */
	uint16_t pid;			/* product ID */
	uint16_t bcdDeviceLow;		/* low revision value, inclusive */
	uint16_t bcdDeviceHigh;		/* high revision value, inclusive */
	uint16_t reserved[2];		/* for the future */
	/* quirk name, UQ_XXX, including terminating zero */
	char	quirkname[64 - 12];
};

#define	LIBUSB20_MAX_FRAME_PRE_SCALE	(1U << 31)

/* USB transfer operations */
int	libusb20_tr_close(struct libusb20_transfer *xfer);
int	libusb20_tr_open(struct libusb20_transfer *xfer, uint32_t max_buf_size, uint32_t max_frame_count, uint8_t ep_no);
struct libusb20_transfer *libusb20_tr_get_pointer(struct libusb20_device *pdev, uint16_t tr_index);
uint16_t libusb20_tr_get_time_complete(struct libusb20_transfer *xfer);
uint32_t libusb20_tr_get_actual_frames(struct libusb20_transfer *xfer);
uint32_t libusb20_tr_get_actual_length(struct libusb20_transfer *xfer);
uint32_t libusb20_tr_get_max_frames(struct libusb20_transfer *xfer);
uint32_t libusb20_tr_get_max_packet_length(struct libusb20_transfer *xfer);
uint32_t libusb20_tr_get_max_total_length(struct libusb20_transfer *xfer);
uint8_t	libusb20_tr_get_status(struct libusb20_transfer *xfer);
uint8_t	libusb20_tr_pending(struct libusb20_transfer *xfer);
void	libusb20_tr_callback_wrapper(struct libusb20_transfer *xfer);
void	libusb20_tr_clear_stall_sync(struct libusb20_transfer *xfer);
void	libusb20_tr_drain(struct libusb20_transfer *xfer);
void	libusb20_tr_set_buffer(struct libusb20_transfer *xfer, void *buffer, uint16_t fr_index);
void	libusb20_tr_set_callback(struct libusb20_transfer *xfer, libusb20_tr_callback_t *cb);
void	libusb20_tr_set_flags(struct libusb20_transfer *xfer, uint8_t flags);
uint32_t libusb20_tr_get_length(struct libusb20_transfer *xfer, uint16_t fr_index);
void	libusb20_tr_set_length(struct libusb20_transfer *xfer, uint32_t length, uint16_t fr_index);
void	libusb20_tr_set_priv_sc0(struct libusb20_transfer *xfer, void *sc0);
void	libusb20_tr_set_priv_sc1(struct libusb20_transfer *xfer, void *sc1);
void	libusb20_tr_set_timeout(struct libusb20_transfer *xfer, uint32_t timeout);
void	libusb20_tr_set_total_frames(struct libusb20_transfer *xfer, uint32_t nFrames);
void	libusb20_tr_setup_bulk(struct libusb20_transfer *xfer, void *pbuf, uint32_t length, uint32_t timeout);
void	libusb20_tr_setup_control(struct libusb20_transfer *xfer, void *psetup, void *pbuf, uint32_t timeout);
void	libusb20_tr_setup_intr(struct libusb20_transfer *xfer, void *pbuf, uint32_t length, uint32_t timeout);
void	libusb20_tr_setup_isoc(struct libusb20_transfer *xfer, void *pbuf, uint32_t length, uint16_t fr_index);
uint8_t	libusb20_tr_bulk_intr_sync(struct libusb20_transfer *xfer, void *pbuf, uint32_t length, uint32_t *pactlen, uint32_t timeout);
void	libusb20_tr_start(struct libusb20_transfer *xfer);
void	libusb20_tr_stop(struct libusb20_transfer *xfer);
void	libusb20_tr_submit(struct libusb20_transfer *xfer);
void   *libusb20_tr_get_priv_sc0(struct libusb20_transfer *xfer);
void   *libusb20_tr_get_priv_sc1(struct libusb20_transfer *xfer);

/* USB device operations */

const char *libusb20_dev_get_backend_name(struct libusb20_device *pdev);
const char *libusb20_dev_get_desc(struct libusb20_device *pdev);
int	libusb20_dev_close(struct libusb20_device *pdev);
int	libusb20_dev_detach_kernel_driver(struct libusb20_device *pdev, uint8_t iface_index);
int	libusb20_dev_set_config_index(struct libusb20_device *pdev, uint8_t configIndex);
int	libusb20_dev_get_debug(struct libusb20_device *pdev);
int	libusb20_dev_get_fd(struct libusb20_device *pdev);
int	libusb20_dev_kernel_driver_active(struct libusb20_device *pdev, uint8_t iface_index);
int	libusb20_dev_open(struct libusb20_device *pdev, uint16_t transfer_max);
int	libusb20_dev_process(struct libusb20_device *pdev);
int	libusb20_dev_request_sync(struct libusb20_device *pdev, struct LIBUSB20_CONTROL_SETUP_DECODED *setup, void *data, uint16_t *pactlen, uint32_t timeout, uint8_t flags);
int	libusb20_dev_req_string_sync(struct libusb20_device *pdev, uint8_t index, uint16_t langid, void *ptr, uint16_t len);
int	libusb20_dev_req_string_simple_sync(struct libusb20_device *pdev, uint8_t index, void *ptr, uint16_t len);
int	libusb20_dev_reset(struct libusb20_device *pdev);
int	libusb20_dev_check_connected(struct libusb20_device *pdev);
int	libusb20_dev_set_power_mode(struct libusb20_device *pdev, uint8_t power_mode);
uint8_t	libusb20_dev_get_power_mode(struct libusb20_device *pdev);
int	libusb20_dev_set_alt_index(struct libusb20_device *pdev, uint8_t iface_index, uint8_t alt_index);
int	libusb20_dev_get_info(struct libusb20_device *pdev, struct usb_device_info *pinfo);
int	libusb20_dev_get_iface_desc(struct libusb20_device *pdev, uint8_t iface_index, char *buf, uint8_t len);

struct LIBUSB20_DEVICE_DESC_DECODED *libusb20_dev_get_device_desc(struct libusb20_device *pdev);
struct libusb20_config *libusb20_dev_alloc_config(struct libusb20_device *pdev, uint8_t config_index);
struct libusb20_device *libusb20_dev_alloc(void);
uint8_t	libusb20_dev_get_address(struct libusb20_device *pdev);
uint8_t	libusb20_dev_get_parent_address(struct libusb20_device *pdev);
uint8_t	libusb20_dev_get_parent_port(struct libusb20_device *pdev);
uint8_t	libusb20_dev_get_bus_number(struct libusb20_device *pdev);
uint8_t	libusb20_dev_get_mode(struct libusb20_device *pdev);
uint8_t	libusb20_dev_get_speed(struct libusb20_device *pdev);
uint8_t	libusb20_dev_get_config_index(struct libusb20_device *pdev);
void	libusb20_dev_free(struct libusb20_device *pdev);
void	libusb20_dev_set_debug(struct libusb20_device *pdev, int debug);
void	libusb20_dev_wait_process(struct libusb20_device *pdev, int timeout);

/* USB global operations */

int	libusb20_be_get_dev_quirk(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq);
int	libusb20_be_get_quirk_name(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq);
int	libusb20_be_add_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq);
int	libusb20_be_remove_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq);
int	libusb20_be_get_template(struct libusb20_backend *pbe, int *ptemp);
int	libusb20_be_set_template(struct libusb20_backend *pbe, int temp);

/* USB backend operations */

struct libusb20_backend *libusb20_be_alloc(const struct libusb20_backend_methods *methods);
struct libusb20_backend *libusb20_be_alloc_default(void);
struct libusb20_backend *libusb20_be_alloc_freebsd(void);
struct libusb20_backend *libusb20_be_alloc_linux(void);
struct libusb20_backend *libusb20_be_alloc_ugen20(void);
struct libusb20_device *libusb20_be_device_foreach(struct libusb20_backend *pbe, struct libusb20_device *pdev);
void	libusb20_be_dequeue_device(struct libusb20_backend *pbe, struct libusb20_device *pdev);
void	libusb20_be_enqueue_device(struct libusb20_backend *pbe, struct libusb20_device *pdev);
void	libusb20_be_free(struct libusb20_backend *pbe);

/* USB debugging */

const char *libusb20_strerror(int);
const char *libusb20_error_name(int);

#if 0
{					/* style */
#endif
#ifdef __cplusplus
}

#endif

#endif					/* _LIBUSB20_H_ */


code:
/* $FreeBSD: release/9.0.0/lib/libusb/libusb20_desc.h 185087 2008-11-19 08:56:35Z alfred $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 * Copyright (c) 2007-2008 Daniel Drake.  All rights reserved.
 * Copyright (c) 2001 Johannes Erdfelt.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * NOTE: This file contains the definition of some standard USB
 * structures. All structures which name ends by *DECODED use host byte
 * order.
 */

/*
 * NOTE: This file uses a lot of macros. If you want to see what the
 * macros become when they are expanded then run the following
 * commands from your shell:
 *
 * cpp libusb20_desc.h > temp.h
 * indent temp.h
 * less temp.h
 */

#ifndef _LIBUSB20_DESC_H_
#define	_LIBUSB20_DESC_H_

#ifdef __cplusplus
extern	"C" {
#endif
#if 0
};					/* style */

#endif
/* basic macros */

#define	LIBUSB20__NOT(...) __VA_ARGS__
#define	LIBUSB20_NOT(arg) LIBUSB20__NOT(LIBUSB20_YES arg(() LIBUSB20_NO))
#define	LIBUSB20_YES(...) __VA_ARGS__
#define	LIBUSB20_NO(...)
#define	LIBUSB20_END(...) __VA_ARGS__
#define	LIBUSB20_MAX(a,b) (((a) > (b)) ? (a) : (b))
#define	LIBUSB20_MIN(a,b) (((a) < (b)) ? (a) : (b))

#define	LIBUSB20_ADD_BYTES(ptr,off) \
  ((void *)(((const uint8_t *)(ptr)) + (off) - ((const uint8_t *)0)))

/* basic message elements */
enum {
	LIBUSB20_ME_INT8,
	LIBUSB20_ME_INT16,
	LIBUSB20_ME_INT32,
	LIBUSB20_ME_INT64,
	LIBUSB20_ME_STRUCT,
	LIBUSB20_ME_MAX,		/* used to indicate end */
};

/* basic message element modifiers */
enum {
	LIBUSB20_ME_IS_UNSIGNED = 0x00,
	LIBUSB20_ME_IS_SIGNED = 0x80,
	LIBUSB20_ME_MASK = 0x7F,
};

enum {
	LIBUSB20_ME_IS_RAW,		/* structure excludes length field
					 * (hardcoded value) */
	LIBUSB20_ME_IS_ENCODED,		/* structure includes length field */
	LIBUSB20_ME_IS_EMPTY,		/* no structure */
	LIBUSB20_ME_IS_DECODED,		/* structure is recursive */
};

/* basic helper structures and macros */

#define	LIBUSB20_ME_STRUCT_ALIGN sizeof(void *)

struct libusb20_me_struct {
	void   *ptr;			/* data pointer */
	uint16_t len;			/* defaults to zero */
	uint16_t type;			/* defaults to LIBUSB20_ME_IS_EMPTY */
} __aligned(LIBUSB20_ME_STRUCT_ALIGN);

struct libusb20_me_format {
	const uint8_t *format;		/* always set */
	const char *desc;		/* optionally set */
	const char *fields;		/* optionally set */
};

#define	LIBUSB20_ME_STRUCT(n, field, arg, ismeta)		\
  ismeta ( LIBUSB20_ME_STRUCT, 1, 0, )			\
  LIBUSB20_NOT(ismeta) ( struct libusb20_me_struct field; )

#define	LIBUSB20_ME_STRUCT_ARRAY(n, field, arg, ismeta)	\
  ismeta ( LIBUSB20_ME_STRUCT , (arg) & 0xFF,		\
	   ((arg) / 0x100) & 0xFF, )			\
  LIBUSB20_NOT(ismeta) ( struct libusb20_me_struct field [arg]; )

#define	LIBUSB20_ME_INTEGER(n, field, ismeta, un, u, bits, a, size)	\
  ismeta ( LIBUSB20_ME_INT##bits |					\
	   LIBUSB20_ME_IS_##un##SIGNED ,				\
	   (size) & 0xFF, ((size) / 0x100) & 0xFF, )		\
  LIBUSB20_NOT(ismeta) ( u##int##bits##_t				\
		    __aligned((bits) / 8) field a; )

#define	LIBUSB20_ME_UINT8_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 8, , 1)

#define	LIBUSB20_ME_UINT8_ARRAY_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 8, [arg], arg)

#define	LIBUSB20_ME_SINT8_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 8, , 1)

#define	LIBUSB20_ME_SINT8_ARRAY_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 8, [arg], arg)

#define	LIBUSB20_ME_UINT16_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 16, , 1)

#define	LIBUSB20_ME_UINT16_ARRAY_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 16, [arg], arg)

#define	LIBUSB20_ME_SINT16_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 16, , 1)

#define	LIBUSB20_ME_SINT16_ARRAY_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 16, [arg], arg)

#define	LIBUSB20_ME_UINT32_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 32, , 1)

#define	LIBUSB20_ME_UINT32_ARRAY_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 32, [arg], arg)

#define	LIBUSB20_ME_SINT32_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 32, , 1)

#define	LIBUSB20_ME_SINT32_ARRAY_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 32, [arg], arg)

#define	LIBUSB20_ME_UINT64_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 64, , 1)

#define	LIBUSB20_ME_UINT64_ARRAY_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta, UN, u, 64, [arg], arg)

#define	LIBUSB20_ME_SINT64_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 64, , 1)

#define	LIBUSB20_ME_SINT64_ARRAY_T(n, field, arg, ismeta) \
  LIBUSB20_ME_INTEGER(n, field, ismeta,,, 64, [arg], arg)

#define	LIBUSB20_MAKE_DECODED_FIELD(n, type, field, arg) \
  LIBUSB20_ME_##type (n, field, arg, LIBUSB20_NO)

#define	LIBUSB20_MAKE_STRUCT(name)			\
  extern const struct libusb20_me_format			\
	 name##_FORMAT[1];				\
  struct name##_DECODED {				\
    const struct libusb20_me_format *name##_FORMAT;	\
    name (LIBUSB20_MAKE_DECODED_FIELD,)			\
  }

#define	LIBUSB20_MAKE_STRUCT_FORMAT(name)		\
  const struct libusb20_me_format			\
    name##_FORMAT[1] = {{			\
      .format = LIBUSB20_MAKE_FORMAT(name),	\
      .desc = #name,				\
      .fields = NULL,				\
  }}

#define	LIBUSB20_MAKE_FORMAT_SUB(n, type, field, arg) \
  LIBUSB20_ME_##type (n, field, arg, LIBUSB20_YES)

#define	LIBUSB20_MAKE_FORMAT(what) (const uint8_t []) \
  { what (LIBUSB20_MAKE_FORMAT_SUB, ) LIBUSB20_ME_MAX, 0, 0 }

#define	LIBUSB20_INIT(what, ptr) do {		\
    memset(ptr, 0, sizeof(*(ptr)));		\
    (ptr)->what##_FORMAT = what##_FORMAT;	\
} while (0)

#define	LIBUSB20_DEVICE_DESC(m,n) \
  m(n, UINT8_T, bLength, ) \
  m(n, UINT8_T, bDescriptorType, ) \
  m(n, UINT16_T, bcdUSB, ) \
  m(n, UINT8_T, bDeviceClass, ) \
  m(n, UINT8_T, bDeviceSubClass, ) \
  m(n, UINT8_T, bDeviceProtocol, ) \
  m(n, UINT8_T, bMaxPacketSize0, ) \
  m(n, UINT16_T, idVendor, ) \
  m(n, UINT16_T, idProduct, ) \
  m(n, UINT16_T, bcdDevice, ) \
  m(n, UINT8_T, iManufacturer, ) \
  m(n, UINT8_T, iProduct, ) \
  m(n, UINT8_T, iSerialNumber, ) \
  m(n, UINT8_T, bNumConfigurations, ) \

LIBUSB20_MAKE_STRUCT(LIBUSB20_DEVICE_DESC);

#define	LIBUSB20_ENDPOINT_DESC(m,n) \
  m(n, UINT8_T,  bLength, ) \
  m(n, UINT8_T,  bDescriptorType, ) \
  m(n, UINT8_T,  bEndpointAddress, ) \
  m(n, UINT8_T,  bmAttributes, ) \
  m(n, UINT16_T, wMaxPacketSize, ) \
  m(n, UINT8_T,  bInterval, ) \
  m(n, UINT8_T,  bRefresh, ) \
  m(n, UINT8_T,  bSynchAddress, ) \

LIBUSB20_MAKE_STRUCT(LIBUSB20_ENDPOINT_DESC);

#define	LIBUSB20_INTERFACE_DESC(m,n) \
  m(n, UINT8_T,  bLength, ) \
  m(n, UINT8_T,  bDescriptorType, ) \
  m(n, UINT8_T,  bInterfaceNumber, ) \
  m(n, UINT8_T,  bAlternateSetting, ) \
  m(n, UINT8_T,  bNumEndpoints, ) \
  m(n, UINT8_T,  bInterfaceClass, ) \
  m(n, UINT8_T,  bInterfaceSubClass, ) \
  m(n, UINT8_T,  bInterfaceProtocol, ) \
  m(n, UINT8_T,  iInterface, ) \

LIBUSB20_MAKE_STRUCT(LIBUSB20_INTERFACE_DESC);

#define	LIBUSB20_CONFIG_DESC(m,n) \
  m(n, UINT8_T,  bLength, ) \
  m(n, UINT8_T,  bDescriptorType, ) \
  m(n, UINT16_T, wTotalLength, ) \
  m(n, UINT8_T,  bNumInterfaces, ) \
  m(n, UINT8_T,  bConfigurationValue, ) \
  m(n, UINT8_T,  iConfiguration, ) \
  m(n, UINT8_T,  bmAttributes, ) \
  m(n, UINT8_T,  bMaxPower, ) \

LIBUSB20_MAKE_STRUCT(LIBUSB20_CONFIG_DESC);

#define	LIBUSB20_CONTROL_SETUP(m,n) \
  m(n, UINT8_T,  bmRequestType, ) \
  m(n, UINT8_T,  bRequest, ) \
  m(n, UINT16_T, wValue, ) \
  m(n, UINT16_T, wIndex, ) \
  m(n, UINT16_T, wLength, ) \

LIBUSB20_MAKE_STRUCT(LIBUSB20_CONTROL_SETUP);

/* standard USB stuff */

/** \ingroup desc
 * Device and/or Interface Class codes */
enum libusb20_class_code {
	/** In the context of a \ref LIBUSB20_DEVICE_DESC "device
	 * descriptor", this bDeviceClass value indicates that each
	 * interface specifies its own class information and all
	 * interfaces operate independently.
	 */
	LIBUSB20_CLASS_PER_INTERFACE = 0,

	/** Audio class */
	LIBUSB20_CLASS_AUDIO = 1,

	/** Communications class */
	LIBUSB20_CLASS_COMM = 2,

	/** Human Interface Device class */
	LIBUSB20_CLASS_HID = 3,

	/** Printer dclass */
	LIBUSB20_CLASS_PRINTER = 7,

	/** Picture transfer protocol class */
	LIBUSB20_CLASS_PTP = 6,

	/** Mass storage class */
	LIBUSB20_CLASS_MASS_STORAGE = 8,

	/** Hub class */
	LIBUSB20_CLASS_HUB = 9,

	/** Data class */
	LIBUSB20_CLASS_DATA = 10,

	/** Class is vendor-specific */
	LIBUSB20_CLASS_VENDOR_SPEC = 0xff,
};

/** \ingroup desc
 * Descriptor types as defined by the USB specification. */
enum libusb20_descriptor_type {
	/** Device descriptor. See LIBUSB20_DEVICE_DESC. */
	LIBUSB20_DT_DEVICE = 0x01,

	/** Configuration descriptor. See LIBUSB20_CONFIG_DESC. */
	LIBUSB20_DT_CONFIG = 0x02,

	/** String descriptor */
	LIBUSB20_DT_STRING = 0x03,

	/** Interface descriptor. See LIBUSB20_INTERFACE_DESC. */
	LIBUSB20_DT_INTERFACE = 0x04,

	/** Endpoint descriptor. See LIBUSB20_ENDPOINT_DESC. */
	LIBUSB20_DT_ENDPOINT = 0x05,

	/** HID descriptor */
	LIBUSB20_DT_HID = 0x21,

	/** HID report descriptor */
	LIBUSB20_DT_REPORT = 0x22,

	/** Physical descriptor */
	LIBUSB20_DT_PHYSICAL = 0x23,

	/** Hub descriptor */
	LIBUSB20_DT_HUB = 0x29,
};

/* Descriptor sizes per descriptor type */
#define	LIBUSB20_DT_DEVICE_SIZE			18
#define	LIBUSB20_DT_CONFIG_SIZE			9
#define	LIBUSB20_DT_INTERFACE_SIZE		9
#define	LIBUSB20_DT_ENDPOINT_SIZE		7
#define	LIBUSB20_DT_ENDPOINT_AUDIO_SIZE		9	/* Audio extension */
#define	LIBUSB20_DT_HUB_NONVAR_SIZE		7

#define	LIBUSB20_ENDPOINT_ADDRESS_MASK	0x0f	/* in bEndpointAddress */
#define	LIBUSB20_ENDPOINT_DIR_MASK	0x80

/** \ingroup desc
 * Endpoint direction. Values for bit 7 of the
 * \ref LIBUSB20_ENDPOINT_DESC::bEndpointAddress "endpoint address" scheme.
 */
enum libusb20_endpoint_direction {
	/** In: device-to-host */
	LIBUSB20_ENDPOINT_IN = 0x80,

	/** Out: host-to-device */
	LIBUSB20_ENDPOINT_OUT = 0x00,
};

#define	LIBUSB20_TRANSFER_TYPE_MASK	0x03	/* in bmAttributes */

/** \ingroup desc
 * Endpoint transfer type. Values for bits 0:1 of the
 * \ref LIBUSB20_ENDPOINT_DESC::bmAttributes "endpoint attributes" field.
 */
enum libusb20_transfer_type {
	/** Control endpoint */
	LIBUSB20_TRANSFER_TYPE_CONTROL = 0,

	/** Isochronous endpoint */
	LIBUSB20_TRANSFER_TYPE_ISOCHRONOUS = 1,

	/** Bulk endpoint */
	LIBUSB20_TRANSFER_TYPE_BULK = 2,

	/** Interrupt endpoint */
	LIBUSB20_TRANSFER_TYPE_INTERRUPT = 3,
};

/** \ingroup misc
 * Standard requests, as defined in table 9-3 of the USB2 specifications */
enum libusb20_standard_request {
	/** Request status of the specific recipient */
	LIBUSB20_REQUEST_GET_STATUS = 0x00,

	/** Clear or disable a specific feature */
	LIBUSB20_REQUEST_CLEAR_FEATURE = 0x01,

	/* 0x02 is reserved */

	/** Set or enable a specific feature */
	LIBUSB20_REQUEST_SET_FEATURE = 0x03,

	/* 0x04 is reserved */

	/** Set device address for all future accesses */
	LIBUSB20_REQUEST_SET_ADDRESS = 0x05,

	/** Get the specified descriptor */
	LIBUSB20_REQUEST_GET_DESCRIPTOR = 0x06,

	/** Used to update existing descriptors or add new descriptors */
	LIBUSB20_REQUEST_SET_DESCRIPTOR = 0x07,

	/** Get the current device configuration value */
	LIBUSB20_REQUEST_GET_CONFIGURATION = 0x08,

	/** Set device configuration */
	LIBUSB20_REQUEST_SET_CONFIGURATION = 0x09,

	/** Return the selected alternate setting for the specified
	 * interface */
	LIBUSB20_REQUEST_GET_INTERFACE = 0x0A,

	/** Select an alternate interface for the specified interface */
	LIBUSB20_REQUEST_SET_INTERFACE = 0x0B,

	/** Set then report an endpoint's synchronization frame */
	LIBUSB20_REQUEST_SYNCH_FRAME = 0x0C,
};

/** \ingroup misc
 * Request type bits of the
 * \ref libusb20_control_setup::bmRequestType "bmRequestType" field in
 * control transfers. */
enum libusb20_request_type {
	/** Standard */
	LIBUSB20_REQUEST_TYPE_STANDARD = (0x00 << 5),

	/** Class */
	LIBUSB20_REQUEST_TYPE_CLASS = (0x01 << 5),

	/** Vendor */
	LIBUSB20_REQUEST_TYPE_VENDOR = (0x02 << 5),

	/** Reserved */
	LIBUSB20_REQUEST_TYPE_RESERVED = (0x03 << 5),
};

/** \ingroup misc
 * Recipient bits of the
 * \ref libusb20_control_setup::bmRequestType "bmRequestType" field in
 * control transfers. Values 4 through 31 are reserved. */
enum libusb20_request_recipient {
	/** Device */
	LIBUSB20_RECIPIENT_DEVICE = 0x00,

	/** Interface */
	LIBUSB20_RECIPIENT_INTERFACE = 0x01,

	/** Endpoint */
	LIBUSB20_RECIPIENT_ENDPOINT = 0x02,

	/** Other */
	LIBUSB20_RECIPIENT_OTHER = 0x03,
};

#define	LIBUSB20_ISO_SYNC_TYPE_MASK		0x0C

/** \ingroup desc
 * Synchronization type for isochronous endpoints. Values for bits 2:3
 * of the \ref LIBUSB20_ENDPOINT_DESC::bmAttributes "bmAttributes"
 * field in LIBUSB20_ENDPOINT_DESC.
 */
enum libusb20_iso_sync_type {
	/** No synchronization */
	LIBUSB20_ISO_SYNC_TYPE_NONE = 0,

	/** Asynchronous */
	LIBUSB20_ISO_SYNC_TYPE_ASYNC = 1,

	/** Adaptive */
	LIBUSB20_ISO_SYNC_TYPE_ADAPTIVE = 2,

	/** Synchronous */
	LIBUSB20_ISO_SYNC_TYPE_SYNC = 3,
};

#define	LIBUSB20_ISO_USAGE_TYPE_MASK 0x30

/** \ingroup desc
 * Usage type for isochronous endpoints. Values for bits 4:5 of the
 * \ref LIBUSB20_ENDPOINT_DESC::bmAttributes "bmAttributes" field in
 * LIBUSB20_ENDPOINT_DESC.
 */
enum libusb20_iso_usage_type {
	/** Data endpoint */
	LIBUSB20_ISO_USAGE_TYPE_DATA = 0,

	/** Feedback endpoint */
	LIBUSB20_ISO_USAGE_TYPE_FEEDBACK = 1,

	/** Implicit feedback Data endpoint */
	LIBUSB20_ISO_USAGE_TYPE_IMPLICIT = 2,
};

struct libusb20_endpoint {
	struct LIBUSB20_ENDPOINT_DESC_DECODED desc;
	struct libusb20_me_struct extra;
} __aligned(sizeof(void *));

struct libusb20_interface {
	struct LIBUSB20_INTERFACE_DESC_DECODED desc;
	struct libusb20_me_struct extra;
	struct libusb20_interface *altsetting;
	struct libusb20_endpoint *endpoints;
	uint8_t	num_altsetting;
	uint8_t	num_endpoints;
} __aligned(sizeof(void *));

struct libusb20_config {
	struct LIBUSB20_CONFIG_DESC_DECODED desc;
	struct libusb20_me_struct extra;
	struct libusb20_interface *interface;
	uint8_t	num_interface;
} __aligned(sizeof(void *));

uint8_t	libusb20_me_get_1(const struct libusb20_me_struct *ie, uint16_t offset);
uint16_t libusb20_me_get_2(const struct libusb20_me_struct *ie, uint16_t offset);
uint16_t libusb20_me_encode(void *ptr, uint16_t len, const void *pd);
uint16_t libusb20_me_decode(const void *ptr, uint16_t len, void *pd);
const uint8_t *libusb20_desc_foreach(const struct libusb20_me_struct *pdesc, const uint8_t *psubdesc);
struct libusb20_config *libusb20_parse_config_desc(const void *config_desc);

#if 0
{					/* style */
#endif
#ifdef __cplusplus
}

#endif

#endif					/* _LIBUSB20_DESC_H_ */

repo_name: veiledmerc/mira

license: mit


code:
/*
 * Copyright (c) 1996  Peter Wemm <peter@FreeBSD.org>.
 * All rights reserved.
 * Copyright (c) 2002 Networks Associates Technology, Inc.
 * All rights reserved.
 *
 * Portions of this software were developed for the FreeBSD Project by
 * ThinkSec AS and NAI Labs, the Security Research Division of Network
 * Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
 * ("CBOSS"), as part of the DARPA CHATS research program.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, is permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/lib/libutil/libutil.h 221807 2011-05-12 10:11:39Z stas $
 */

#ifndef _LIBUTIL_H_
#define	_LIBUTIL_H_

#include <sys/cdefs.h>
#include <sys/_types.h>
#include <sys/_stdint.h>

#ifndef _GID_T_DECLARED
typedef	__gid_t		gid_t;
#define	_GID_T_DECLARED
#endif

#ifndef _PID_T_DECLARED
typedef	__pid_t		pid_t;
#define	_PID_T_DECLARED
#endif

#ifndef _SIZE_T_DECLARED
typedef	__size_t	size_t;
#define	_SIZE_T_DECLARED
#endif

#ifndef _UID_T_DECLARED
typedef	__uid_t		uid_t;
#define	_UID_T_DECLARED
#endif

#define PROPERTY_MAX_NAME	64
#define PROPERTY_MAX_VALUE	512

/* for properties.c */
typedef struct _property {
	struct _property *next;
	char *name;
	char *value;
} *properties;

#ifdef _SYS_PARAM_H_
/* for pidfile.c */
struct pidfh {
	int	pf_fd;
	char	pf_path[MAXPATHLEN + 1];
	__dev_t	pf_dev;
	ino_t	pf_ino;
};
#endif

/* Avoid pulling in all the include files for no need */
struct termios;
struct winsize;
struct in_addr;
struct kinfo_file;
struct kinfo_proc;
struct kinfo_vmentry;

__BEGIN_DECLS
void	clean_environment(const char * const *_white,
	    const char * const *_more_white);
int	extattr_namespace_to_string(int _attrnamespace, char **_string);
int	extattr_string_to_namespace(const char *_string, int *_attrnamespace);
int	flopen(const char *_path, int _flags, ...);
void	hexdump(const void *ptr, int length, const char *hdr, int flags);
int	login_tty(int _fd);
void	trimdomain(char *_fullhost, int _hostsize);
int	openpty(int *_amaster, int *_aslave, char *_name,
		     struct termios *_termp, struct winsize *_winp);
int	forkpty(int *_amaster, char *_name,
		     struct termios *_termp, struct winsize *_winp);
int	humanize_number(char *_buf, size_t _len, int64_t _number,
	    const char *_suffix, int _scale, int _flags);
int	expand_number(const char *_buf, uint64_t *_num);
const char *uu_lockerr(int _uu_lockresult);
int	uu_lock(const char *_ttyname);
int	uu_unlock(const char *_ttyname);
int	uu_lock_txfr(const char *_ttyname, pid_t _pid);
int	_secure_path(const char *_path, uid_t _uid, gid_t _gid);
properties properties_read(int fd);
void	properties_free(properties list);
char	*property_find(properties list, const char *name);
char	*auth_getval(const char *name);
int	realhostname(char *host, size_t hsize, const struct in_addr *ip);
struct sockaddr;
int	realhostname_sa(char *host, size_t hsize, struct sockaddr *addr,
			     int addrlen);

int	kld_isloaded(const char *name);
int	kld_load(const char *name);
struct kinfo_file *
	kinfo_getfile(pid_t _pid, int *_cntp);
struct kinfo_vmentry *
	kinfo_getvmmap(pid_t _pid, int *_cntp);
struct kinfo_proc *
	kinfo_getallproc(int *_cntp);
struct kinfo_proc *
	kinfo_getproc(pid_t _pid);

#ifdef _STDIO_H_	/* avoid adding new includes */
char   *fparseln(FILE *, size_t *, size_t *, const char[3], int);
#endif

#ifdef _PWD_H_
int	pw_copy(int _ffd, int _tfd, const struct passwd *_pw, struct passwd *_old_pw);
struct passwd *pw_dup(const struct passwd *_pw);
int	pw_edit(int _notsetuid);
int	pw_equal(const struct passwd *_pw1, const struct passwd *_pw2);
void	pw_fini(void);
int	pw_init(const char *_dir, const char *_master);
char	*pw_make(const struct passwd *_pw);
int	pw_mkdb(const char *_user);
int	pw_lock(void);
struct passwd *pw_scan(const char *_line, int _flags);
const char *pw_tempname(void);
int	pw_tmp(int _mfd);
#endif

#ifdef _GRP_H_
int	gr_equal(const struct group *gr1, const struct group *gr2);
char	*gr_make(const struct group *gr);
struct group *gr_dup(const struct group *gr);
struct group *gr_scan(const char *line);
#endif

#ifdef _SYS_PARAM_H_
struct pidfh *pidfile_open(const char *path, mode_t mode, pid_t *pidptr);
int pidfile_write(struct pidfh *pfh);
int pidfile_close(struct pidfh *pfh);
int pidfile_remove(struct pidfh *pfh);
#endif

#ifdef _UFS_UFS_QUOTA_H_
struct quotafile;
struct fstab;
struct quotafile *quota_open(struct fstab *, int, int);
void quota_close(struct quotafile *);
int quota_on(struct quotafile *);
int quota_off(struct quotafile *);
const char *quota_fsname(const struct quotafile *);
const char *quota_qfname(const struct quotafile *);
int quota_maxid(struct quotafile *);
int quota_check_path(const struct quotafile *, const char *path);
int quota_read(struct quotafile *, struct dqblk *, int);
int quota_write_limits(struct quotafile *, struct dqblk *, int);
int quota_write_usage(struct quotafile *, struct dqblk *, int);
int quota_convert(struct quotafile *, int);
#endif

__END_DECLS

#define UU_LOCK_INUSE (1)
#define UU_LOCK_OK (0)
#define UU_LOCK_OPEN_ERR (-1)
#define UU_LOCK_READ_ERR (-2)
#define UU_LOCK_CREAT_ERR (-3)
#define UU_LOCK_WRITE_ERR (-4)
#define UU_LOCK_LINK_ERR (-5)
#define UU_LOCK_TRY_ERR (-6)
#define UU_LOCK_OWNER_ERR (-7)

/* return values from realhostname() */
#define HOSTNAME_FOUND		(0)
#define HOSTNAME_INCORRECTNAME	(1)
#define HOSTNAME_INVALIDADDR	(2)
#define HOSTNAME_INVALIDNAME	(3)

/* fparseln(3) */
#define	FPARSELN_UNESCESC	0x01
#define	FPARSELN_UNESCCONT	0x02
#define	FPARSELN_UNESCCOMM	0x04
#define	FPARSELN_UNESCREST	0x08
#define	FPARSELN_UNESCALL	0x0f

/* pw_scan() */
#define PWSCAN_MASTER		0x01
#define PWSCAN_WARN		0x02

/* humanize_number(3) */
#define HN_DECIMAL		0x01
#define HN_NOSPACE		0x02
#define HN_B			0x04
#define HN_DIVISOR_1000		0x08
#define HN_IEC_PREFIXES		0x10

/* maxscale = 0x07 */
#define HN_GETSCALE		0x10
#define HN_AUTOSCALE		0x20

/* hexdump(3) */
#define	HD_COLUMN_MASK		0xff
#define	HD_DELIM_MASK		0xff00
#define	HD_OMIT_COUNT		(1 << 16)
#define	HD_OMIT_HEX		(1 << 17)
#define	HD_OMIT_CHARS		(1 << 18)

#endif /* !_LIBUTIL_H_ */


code:
/*-
 * Copyright (c) 1988, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)limits.h	8.2 (Berkeley) 1/4/94
 * $FreeBSD: release/9.0.0/include/limits.h 219271 2011-03-04 19:28:27Z jilles $
 */

#ifndef _LIMITS_H_
#define	_LIMITS_H_

#include <sys/cdefs.h>

#if __POSIX_VISIBLE
#define	_POSIX_ARG_MAX		4096
#define	_POSIX_LINK_MAX		8
#define	_POSIX_MAX_CANON	255
#define	_POSIX_MAX_INPUT	255
#define	_POSIX_NAME_MAX		14
#define	_POSIX_PIPE_BUF		512
#define	_POSIX_SSIZE_MAX	32767
#define	_POSIX_STREAM_MAX	8

#if __POSIX_VISIBLE >= 200112
#define	_POSIX_CHILD_MAX	25
#define	_POSIX_NGROUPS_MAX	8
#define	_POSIX_OPEN_MAX		20
#define	_POSIX_PATH_MAX		256
#define	_POSIX_TZNAME_MAX	6
#else
#define	_POSIX_CHILD_MAX	6
#define	_POSIX_NGROUPS_MAX	0
#define	_POSIX_OPEN_MAX		16
#define	_POSIX_PATH_MAX		255
#define	_POSIX_TZNAME_MAX	3
#endif

#define	BC_BASE_MAX		   99	/* max ibase/obase values in bc(1) */
#define	BC_DIM_MAX		 2048	/* max array elements in bc(1) */
#define	BC_SCALE_MAX		   99	/* max scale value in bc(1) */
#define	BC_STRING_MAX		 1000	/* max const string length in bc(1) */
#define	COLL_WEIGHTS_MAX	    0	/* max weights for order keyword */
#define	EXPR_NEST_MAX		   32	/* max expressions nested in expr(1) */
#define	LINE_MAX		 2048	/* max bytes in an input line */
#define	RE_DUP_MAX		  255	/* max RE's in interval notation */

#define	_POSIX2_BC_BASE_MAX	99
#define	_POSIX2_BC_DIM_MAX	2048
#define	_POSIX2_BC_SCALE_MAX	99
#define	_POSIX2_BC_STRING_MAX	1000
#define	_POSIX2_EQUIV_CLASS_MAX	2
#define	_POSIX2_EXPR_NEST_MAX	32
#define	_POSIX2_LINE_MAX	2048
#define	_POSIX2_RE_DUP_MAX	255
#endif

#if __POSIX_VISIBLE >= 199309
#define	_POSIX_AIO_LISTIO_MAX	2
#define	_POSIX_AIO_MAX		1
#define	_POSIX_DELAYTIMER_MAX	32
#define	_POSIX_MQ_OPEN_MAX	8
#define	_POSIX_MQ_PRIO_MAX	32
#define	_POSIX_RTSIG_MAX	8
#define	_POSIX_SEM_NSEMS_MAX	256
#define	_POSIX_SEM_VALUE_MAX	32767
#define	_POSIX_SIGQUEUE_MAX	32
#define	_POSIX_TIMER_MAX	32

#define	_POSIX_CLOCKRES_MIN	20000000
#endif

#if __POSIX_VISIBLE >= 199506
#define	_POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
#define	_POSIX_THREAD_KEYS_MAX	128
#define	_POSIX_THREAD_THREADS_MAX 64
#endif

#if __POSIX_VISIBLE >= 200112
#define	_POSIX_HOST_NAME_MAX	255
#define	_POSIX_LOGIN_NAME_MAX	9
#define	_POSIX_SS_REPL_MAX	4
#define	_POSIX_SYMLINK_MAX	255
#define	_POSIX_SYMLOOP_MAX	8
#define	_POSIX_TRACE_EVENT_NAME_MAX 30
#define	_POSIX_TRACE_NAME_MAX	8
#define	_POSIX_TRACE_SYS_MAX	8
#define	_POSIX_TRACE_USER_EVENT_MAX 32
#define	_POSIX_TTY_NAME_MAX	9
#define	_POSIX2_CHARCLASS_NAME_MAX 14
#define	_POSIX2_COLL_WEIGHTS_MAX 2

#define	_POSIX_RE_DUP_MAX	_POSIX2_RE_DUP_MAX
#endif

#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809
#define	NL_ARGMAX		99	/* max # of position args for printf */
#define	NL_MSGMAX		32767
#define	NL_SETMAX		255
#define	NL_TEXTMAX		2048
#endif

#if __XSI_VISIBLE
#define	_XOPEN_IOV_MAX		16
#define	_XOPEN_NAME_MAX		255
#define	_XOPEN_PATH_MAX		1024
#define	PASS_MAX		128	/* _PASSWORD_LEN from <pwd.h> */

#define	NL_LANGMAX		31	/* max LANG name length */
#define	NL_NMAX			1
#endif

#define	MB_LEN_MAX		6	/* 31-bit UTF-8 */

#include <sys/limits.h>

#if __POSIX_VISIBLE
#include <sys/syslimits.h>
#endif

#endif /* !_LIMITS_H_ */


code:
/*
 * Copyright (c) 1993 Paul Kranenburg
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Paul Kranenburg.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/include/link.h 103436 2002-09-17 01:49:00Z peter $
 */

#include <sys/link_elf.h>


code:
/*-
 * Copyright (c) 1999 John D. Polstra
 * Copyright (c) 1999,2001 Peter Wemm <peter@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/linker_set.h 215701 2010-11-22 19:32:54Z dim $
 */

#ifndef _SYS_LINKER_SET_H_
#define _SYS_LINKER_SET_H_

#ifndef _SYS_CDEFS_H_
#error this file needs sys/cdefs.h as a prerequisite
#endif

/*
 * The following macros are used to declare global sets of objects, which
 * are collected by the linker into a `linker_set' as defined below.
 * For ELF, this is done by constructing a separate segment for each set.
 */

/*
 * Private macros, not to be used outside this header file.
 */
#ifdef __GNUCLIKE___SECTION
#define __MAKE_SET(set, sym)						\
	__GLOBL(__CONCAT(__start_set_,set));				\
	__GLOBL(__CONCAT(__stop_set_,set));				\
	static void const * const __set_##set##_sym_##sym 		\
	__section("set_" #set) __used = &sym
#else /* !__GNUCLIKE___SECTION */
#ifndef lint
#error this file needs to be ported to your compiler
#endif /* lint */
#define __MAKE_SET(set, sym)	extern void const * const (__set_##set##_sym_##sym)
#endif /* __GNUCLIKE___SECTION */

/*
 * Public macros.
 */
#define TEXT_SET(set, sym)	__MAKE_SET(set, sym)
#define DATA_SET(set, sym)	__MAKE_SET(set, sym)
#define BSS_SET(set, sym)	__MAKE_SET(set, sym)
#define ABS_SET(set, sym)	__MAKE_SET(set, sym)
#define SET_ENTRY(set, sym)	__MAKE_SET(set, sym)

/*
 * Initialize before referring to a given linker set.
 */
#define SET_DECLARE(set, ptype)						\
	extern ptype *__CONCAT(__start_set_,set);			\
	extern ptype *__CONCAT(__stop_set_,set)

#define SET_BEGIN(set)							\
	(&__CONCAT(__start_set_,set))
#define SET_LIMIT(set)							\
	(&__CONCAT(__stop_set_,set))

/*
 * Iterate over all the elements of a set.
 *
 * Sets always contain addresses of things, and "pvar" points to words
 * containing those addresses.  Thus is must be declared as "type **pvar",
 * and the address of each set item is obtained inside the loop by "*pvar".
 */
#define SET_FOREACH(pvar, set)						\
	for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++)

#define SET_ITEM(set, i)						\
	((SET_BEGIN(set))[i])

/*
 * Provide a count of the items in a set.
 */
#define SET_COUNT(set)							\
	(SET_LIMIT(set) - SET_BEGIN(set))

#endif	/* _SYS_LINKER_SET_H_ */


code:
/*
 * Copyright (c) 1991, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)locale.h	8.1 (Berkeley) 6/2/93
 * $FreeBSD: release/9.0.0/include/locale.h 203964 2010-02-16 19:39:50Z imp $
 */

#ifndef _LOCALE_H_
#define _LOCALE_H_

#include <sys/_null.h>

struct lconv {
	char	*decimal_point;
	char	*thousands_sep;
	char	*grouping;
	char	*int_curr_symbol;
	char	*currency_symbol;
	char	*mon_decimal_point;
	char	*mon_thousands_sep;
	char	*mon_grouping;
	char	*positive_sign;
	char	*negative_sign;
	char	int_frac_digits;
	char	frac_digits;
	char	p_cs_precedes;
	char	p_sep_by_space;
	char	n_cs_precedes;
	char	n_sep_by_space;
	char	p_sign_posn;
	char	n_sign_posn;
	char	int_p_cs_precedes;
	char	int_n_cs_precedes;
	char	int_p_sep_by_space;
	char	int_n_sep_by_space;
	char	int_p_sign_posn;
	char	int_n_sign_posn;
};

#define	LC_ALL		0
#define	LC_COLLATE	1
#define	LC_CTYPE	2
#define	LC_MONETARY	3
#define	LC_NUMERIC	4
#define	LC_TIME		5
#define	LC_MESSAGES	6

#define	_LC_LAST	7		/* marks end */

#include <sys/cdefs.h>

__BEGIN_DECLS
struct lconv	*localeconv(void);
char		*setlocale(int, const char *);
__END_DECLS

#endif /* _LOCALE_H_ */


code:
/*-
 * Copyright (c) 1996 by
 * Sean Eric Fagan <sef@kithrup.com>
 * David Nugent <davidn@blaze.net.au>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, is permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice immediately at the beginning of the file, without modification,
 *    this list of conditions, and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. This work was done expressly for inclusion into FreeBSD.  Other use
 *    is permitted provided this notation is included.
 * 4. Absolutely no warranty of function or purpose is made by the authors.
 * 5. Modifications may be freely made to this file providing the above
 *    conditions are met.
 *
 * Low-level routines relating to the user capabilities database
 *
 *	Was login_cap.h,v 1.9 1997/05/07 20:00:01 eivind Exp
 * $FreeBSD: release/9.0.0/lib/libutil/login_cap.h 219304 2011-03-05 12:40:35Z trasz $
 */

#ifndef _LOGIN_CAP_H_
#define _LOGIN_CAP_H_

#define LOGIN_DEFCLASS		"default"
#define LOGIN_DEFROOTCLASS	"root"
#define LOGIN_MECLASS		"me"
#define LOGIN_DEFSTYLE		"passwd"
#define LOGIN_DEFSERVICE	"login"
#define LOGIN_DEFUMASK		022
#define LOGIN_DEFPRI		0
#define _PATH_LOGIN_CONF	"/etc/login.conf"
#define _FILE_LOGIN_CONF	".login_conf"
#define _PATH_AUTHPROG		"/usr/libexec/login_"

#define LOGIN_SETGROUP		0x0001		/* set group */
#define LOGIN_SETLOGIN		0x0002		/* set login (via setlogin) */
#define LOGIN_SETPATH		0x0004		/* set path */
#define LOGIN_SETPRIORITY	0x0008		/* set priority */
#define LOGIN_SETRESOURCES	0x0010		/* set resources (cputime, etc.) */
#define LOGIN_SETUMASK		0x0020		/* set umask, obviously */
#define LOGIN_SETUSER		0x0040		/* set user (via setuid) */
#define LOGIN_SETENV		0x0080		/* set user environment */
#define LOGIN_SETMAC		0x0100		/* set user default MAC label */
#define LOGIN_SETCPUMASK	0x0200		/* set user cpumask */
#define LOGIN_SETLOGINCLASS	0x0400		/* set login class in the kernel */
#define LOGIN_SETALL		0x07ff		/* set everything */

#define BI_AUTH		"authorize"		/* accepted authentication */
#define BI_REJECT	"reject"		/* rejected authentication */
#define BI_CHALLENG	"reject challenge"	/* reject with a challenge */
#define BI_SILENT	"reject silent"		/* reject silently */
#define BI_REMOVE	"remove"		/* remove file on error */
#define BI_ROOTOKAY	"authorize root"	/* root authenticated */
#define BI_SECURE	"authorize secure"	/* okay on non-secure line */
#define BI_SETENV	"setenv"		/* set environment variable */
#define BI_VALUE	"value"			/* set local variable */

#define AUTH_OKAY		0x01		/* user authenticated */
#define AUTH_ROOTOKAY		0x02		/* root login okay */
#define AUTH_SECURE		0x04		/* secure login */
#define AUTH_SILENT		0x08		/* silent rejection */
#define AUTH_CHALLENGE		0x10		/* a chellenge was given */

#define AUTH_ALLOW		(AUTH_OKAY | AUTH_ROOTOKAY | AUTH_SECURE)

typedef struct login_cap {
    char    *lc_class;
    char    *lc_cap;
    char    *lc_style;
} login_cap_t;

typedef struct login_time {
    u_short     lt_start;	/* Start time */
    u_short     lt_end;		/* End time */
#define LTM_NONE  0x00
#define LTM_SUN   0x01
#define LTM_MON   0x02
#define LTM_TUE   0x04
#define LTM_WED   0x08
#define LTM_THU   0x10
#define LTM_FRI   0x20
#define LTM_SAT   0x40
#define LTM_ANY   0x7F
#define LTM_WK    0x3E
#define LTM_WD    0x41
    u_char	 lt_dow;	/* Days of week */
} login_time_t;

#define LC_MAXTIMES 64

#include <sys/cdefs.h>
__BEGIN_DECLS
struct passwd;

void login_close(login_cap_t *);
login_cap_t *login_getclassbyname(const char *, const struct passwd *);
login_cap_t *login_getclass(const char *);
login_cap_t *login_getpwclass(const struct passwd *);
login_cap_t *login_getuserclass(const struct passwd *);

const char *login_getcapstr(login_cap_t *, const char *, const char *,
    const char *);
const char **login_getcaplist(login_cap_t *, const char *, const char *);
const char *login_getstyle(login_cap_t *, const char *, const char *);
rlim_t login_getcaptime(login_cap_t *, const char *, rlim_t, rlim_t);
rlim_t login_getcapnum(login_cap_t *, const char *, rlim_t, rlim_t);
rlim_t login_getcapsize(login_cap_t *, const char *, rlim_t, rlim_t);
const char *login_getpath(login_cap_t *, const char *, const char *);
int login_getcapbool(login_cap_t *, const char *, int);
const char *login_setcryptfmt(login_cap_t *, const char *, const char *);

int setclasscontext(const char *, unsigned int);
void setclasscpumask(login_cap_t *);
int setusercontext(login_cap_t *, const struct passwd *, uid_t, unsigned int);
void setclassresources(login_cap_t *);
void setclassenvironment(login_cap_t *, const struct passwd *, int);

/* Most of these functions are deprecated */
int auth_approve(login_cap_t *, const char *, const char *);
int auth_check(const char *, const char *, const char *, const char *, int *);
void auth_env(void);
char *auth_mkvalue(const char *);
int auth_response(const char *, const char *, const char *, const char *, int *,
    const char *, const char *);
void auth_rmfiles(void);
int auth_scan(int);
int auth_script(const char *, ...);
int auth_script_data(const char *, int, const char *, ...);
char *auth_valud(const char *);
int auth_setopt(const char *, const char *);
void auth_clropts(void);

void auth_checknologin(login_cap_t *);
int auth_cat(const char *);

int auth_ttyok(login_cap_t *, const char *);
int auth_hostok(login_cap_t *, const char *, char const *);
int auth_timeok(login_cap_t *, time_t);

struct tm;

login_time_t parse_lt(const char *);
int in_lt(const login_time_t *, time_t *);
int in_ltm(const login_time_t *, struct tm *, time_t *);
int in_ltms(const login_time_t *, struct tm *, time_t *);
int in_lts(const login_time_t *, time_t *);

/* helper functions */

int login_strinlist(const char **, char const *, int);
int login_str2inlist(const char **, const char *, const char *, int);
login_time_t * login_timelist(login_cap_t *, char const *, int *,
    login_time_t **);
int login_ttyok(login_cap_t *, const char *, const char *, const char *);
int login_hostok(login_cap_t *, const char *, const char *, const char *,
    const char *);

__END_DECLS

#endif /* _LOGIN_CAP_H_ */


code:
/*
 * Copyright (C) 2004-2008  Internet Systems Consortium, Inc. ("ISC")
 * Copyright (C) 2000, 2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $Id: context.h,v 1.23 2008-12-17 23:47:58 tbox Exp $ */

#ifndef LWRES_CONTEXT_H
#define LWRES_CONTEXT_H 1

/*! \file lwres/context.h */

#include <stddef.h>

#include <lwres/lang.h>
#include <lwres/int.h>
#include <lwres/result.h>

/*!
 * Used to set various options such as timeout, authentication, etc
 */
typedef struct lwres_context lwres_context_t;

LWRES_LANG_BEGINDECLS

typedef void *(*lwres_malloc_t)(void *arg, size_t length);
typedef void (*lwres_free_t)(void *arg, void *mem, size_t length);

/*
 * XXXMLG
 *
 * Make the server reload /etc/resolv.conf periodically.
 *
 * Make the server do sortlist/searchlist.
 *
 * Client side can disable the search/sortlist processing.
 *
 * Use an array of addresses/masks and searchlist for client-side, and
 * if added to the client disable the processing on the server.
 *
 * Share /etc/resolv.conf data between contexts.
 */

/*!
 * _SERVERMODE
 *	Don't allocate and connect a socket to the server, since the
 *	caller _is_ a server.
 *
 * _USEIPV4, _USEIPV6
 *	Use IPv4 and IPv6 transactions with remote servers, respectively.
 *	For backward compatibility, regard both flags as being set when both
 *	are cleared.
 */
#define LWRES_CONTEXT_SERVERMODE	0x00000001U
#define LWRES_CONTEXT_USEIPV4		0x00000002U
#define LWRES_CONTEXT_USEIPV6		0x00000004U

lwres_result_t
lwres_context_create(lwres_context_t **contextp, void *arg,
		     lwres_malloc_t malloc_function,
		     lwres_free_t free_function,
		     unsigned int flags);
/**<
 * Allocate a lwres context.  This is used in all lwres calls.
 *
 * Memory management can be replaced here by passing in two functions.
 * If one is non-NULL, they must both be non-NULL.  "arg" is passed to
 * these functions.
 *
 * Contexts are not thread safe.  Document at the top of the file.
 * XXXMLG
 *
 * If they are NULL, the standard malloc() and free() will be used.
 *
 *\pre	contextp != NULL && contextp == NULL.
 *
 *\return	Returns 0 on success, non-zero on failure.
 */

void
lwres_context_destroy(lwres_context_t **contextp);
/**<
 * Frees all memory associated with a lwres context.
 *
 *\pre	contextp != NULL && contextp == NULL.
 */

lwres_uint32_t
lwres_context_nextserial(lwres_context_t *ctx);
/**<
 * XXXMLG Document
 */

void
lwres_context_initserial(lwres_context_t *ctx, lwres_uint32_t serial);

void
lwres_context_freemem(lwres_context_t *ctx, void *mem, size_t len);

void *
lwres_context_allocmem(lwres_context_t *ctx, size_t len);

int
lwres_context_getsocket(lwres_context_t *ctx);

lwres_result_t
lwres_context_send(lwres_context_t *ctx,
		   void *sendbase, int sendlen);

lwres_result_t
lwres_context_recv(lwres_context_t *ctx,
		   void *recvbase, int recvlen,
		   int *recvd_len);

lwres_result_t
lwres_context_sendrecv(lwres_context_t *ctx,
		       void *sendbase, int sendlen,
		       void *recvbase, int recvlen,
		       int *recvd_len);

LWRES_LANG_ENDDECLS

#endif /* LWRES_CONTEXT_H */


code:
/*
 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
 * Copyright (C) 2000, 2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $Id: int.h,v 1.14 2007-06-19 23:47:23 tbox Exp $ */

#ifndef LWRES_INT_H
#define LWRES_INT_H 1

/*! \file lwres/int.h */

typedef char				lwres_int8_t;
typedef unsigned char			lwres_uint8_t;
typedef short				lwres_int16_t;
typedef unsigned short			lwres_uint16_t;
typedef int				lwres_int32_t;
typedef unsigned int			lwres_uint32_t;
typedef long long			lwres_int64_t;
typedef unsigned long long		lwres_uint64_t;

#endif /* LWRES_INT_H */


code:
/*
 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
 * Copyright (C) 2000, 2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $Id: ipv6.h,v 1.16 2007-06-19 23:47:23 tbox Exp $ */

#ifndef LWRES_IPV6_H
#define LWRES_IPV6_H 1

/*****
 ***** Module Info
 *****/

/*! \file lwres/ipv6.h
 * IPv6 definitions for systems which do not support IPv6.
 */

/***
 *** Imports.
 ***/

#include <lwres/int.h>
#include <lwres/platform.h>

/***
 *** Types.
 ***/

/*% in6_addr structure */
struct in6_addr {
        union {
		lwres_uint8_t	_S6_u8[16];
		lwres_uint16_t	_S6_u16[8];
		lwres_uint32_t	_S6_u32[4];
        } _S6_un;
};
/*@{*/
/*% IP v6 types */
#define s6_addr		_S6_un._S6_u8
#define s6_addr8	_S6_un._S6_u8
#define s6_addr16	_S6_un._S6_u16
#define s6_addr32	_S6_un._S6_u32
/*@}*/

#define IN6ADDR_ANY_INIT 	{{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
#define IN6ADDR_LOOPBACK_INIT 	{{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}

LIBLWRES_EXTERNAL_DATA extern const struct in6_addr in6addr_any;
LIBLWRES_EXTERNAL_DATA extern const struct in6_addr in6addr_loopback;

/*% used in getaddrinfo.c and getnameinfo.c */
struct sockaddr_in6 {
#ifdef LWRES_PLATFORM_HAVESALEN
	lwres_uint8_t		sin6_len;
	lwres_uint8_t		sin6_family;
#else
	lwres_uint16_t		sin6_family;
#endif
	lwres_uint16_t		sin6_port;
	lwres_uint32_t		sin6_flowinfo;
	struct in6_addr		sin6_addr;
	lwres_uint32_t		sin6_scope_id;
};

#ifdef LWRES_PLATFORM_HAVESALEN
#define SIN6_LEN 1
#endif

/*% in6_pktinfo structure */
struct in6_pktinfo {
	struct in6_addr ipi6_addr;    /*%< src/dst IPv6 address */
	unsigned int    ipi6_ifindex; /*%< send/recv interface index */
};

/*!
 * Unspecified IPv6 address
 */
#define IN6_IS_ADDR_UNSPECIFIED(a)      \
        (((a)->s6_addr32[0] == 0) &&    \
         ((a)->s6_addr32[1] == 0) &&    \
         ((a)->s6_addr32[2] == 0) &&    \
         ((a)->s6_addr32[3] == 0))

/*
 * Loopback
 */
#define IN6_IS_ADDR_LOOPBACK(a)         \
        (((a)->s6_addr32[0] == 0) &&    \
         ((a)->s6_addr32[1] == 0) &&    \
         ((a)->s6_addr32[2] == 0) &&    \
         ((a)->s6_addr32[3] == htonl(1)))

/*
 * IPv4 compatible
 */
#define IN6_IS_ADDR_V4COMPAT(a)         \
        (((a)->s6_addr32[0] == 0) &&    \
         ((a)->s6_addr32[1] == 0) &&    \
         ((a)->s6_addr32[2] == 0) &&    \
         ((a)->s6_addr32[3] != 0) &&    \
         ((a)->s6_addr32[3] != htonl(1)))

/*
 * Mapped
 */
#define IN6_IS_ADDR_V4MAPPED(a)               \
        (((a)->s6_addr32[0] == 0) &&          \
         ((a)->s6_addr32[1] == 0) &&          \
         ((a)->s6_addr32[2] == htonl(0x0000ffff)))

#endif /* LWRES_IPV6_H */


code:
/*
 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
 * Copyright (C) 2000, 2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $Id: lang.h,v 1.13 2007-06-19 23:47:23 tbox Exp $ */

#ifndef LWRES_LANG_H
#define LWRES_LANG_H 1

/*! \file lwres/lang.h */

#ifdef __cplusplus
#define LWRES_LANG_BEGINDECLS	extern "C" {
#define LWRES_LANG_ENDDECLS	}
#else
#define LWRES_LANG_BEGINDECLS
#define LWRES_LANG_ENDDECLS
#endif

#endif /* LWRES_LANG_H */


code:
/*
 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
 * Copyright (C) 1997-2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $Id: list.h,v 1.14 2007-06-19 23:47:23 tbox Exp $ */

#ifndef LWRES_LIST_H
#define LWRES_LIST_H 1

/*! \file lwres/list.h */

#define LWRES_LIST(type) struct { type *head, *tail; }
#define LWRES_LIST_INIT(list) \
	do { (list).head = NULL; (list).tail = NULL; } while (0)

#define LWRES_LINK(type) struct { type *prev, *next; }
#define LWRES_LINK_INIT(elt, link) \
	do { \
		(elt)->link.prev = (void *)(-1); \
		(elt)->link.next = (void *)(-1); \
	} while (0)
#define LWRES_LINK_LINKED(elt, link) \
	((void *)((elt)->link.prev) != (void *)(-1))

#define LWRES_LIST_HEAD(list) ((list).head)
#define LWRES_LIST_TAIL(list) ((list).tail)
#define LWRES_LIST_EMPTY(list) LWRES_TF((list).head == NULL)

#define LWRES_LIST_PREPEND(list, elt, link) \
	do { \
		if ((list).head != NULL) \
			(list).head->link.prev = (elt); \
		else \
			(list).tail = (elt); \
		(elt)->link.prev = NULL; \
		(elt)->link.next = (list).head; \
		(list).head = (elt); \
	} while (0)

#define LWRES_LIST_APPEND(list, elt, link) \
	do { \
		if ((list).tail != NULL) \
			(list).tail->link.next = (elt); \
		else \
			(list).head = (elt); \
		(elt)->link.prev = (list).tail; \
		(elt)->link.next = NULL; \
		(list).tail = (elt); \
	} while (0)

#define LWRES_LIST_UNLINK(list, elt, link) \
	do { \
		if ((elt)->link.next != NULL) \
			(elt)->link.next->link.prev = (elt)->link.prev; \
		else \
			(list).tail = (elt)->link.prev; \
		if ((elt)->link.prev != NULL) \
			(elt)->link.prev->link.next = (elt)->link.next; \
		else \
			(list).head = (elt)->link.next; \
		(elt)->link.prev = (void *)(-1); \
		(elt)->link.next = (void *)(-1); \
	} while (0)

#define LWRES_LIST_PREV(elt, link) ((elt)->link.prev)
#define LWRES_LIST_NEXT(elt, link) ((elt)->link.next)

#define LWRES_LIST_INSERTBEFORE(list, before, elt, link) \
	do { \
		if ((before)->link.prev == NULL) \
			LWRES_LIST_PREPEND(list, elt, link); \
		else { \
			(elt)->link.prev = (before)->link.prev; \
			(before)->link.prev = (elt); \
			(elt)->link.prev->link.next = (elt); \
			(elt)->link.next = (before); \
		} \
	} while (0)

#define LWRES_LIST_INSERTAFTER(list, after, elt, link) \
	do { \
		if ((after)->link.next == NULL) \
			LWRES_LIST_APPEND(list, elt, link); \
		else { \
			(elt)->link.next = (after)->link.next; \
			(after)->link.next = (elt); \
			(elt)->link.next->link.prev = (elt); \
			(elt)->link.prev = (after); \
		} \
	} while (0)

#define LWRES_LIST_APPENDLIST(list1, list2, link) \
	do { \
		if (LWRES_LIST_EMPTY(list1)) \
			(list1) = (list2); \
		else if (!LWRES_LIST_EMPTY(list2)) { \
			(list1).tail->link.next = (list2).head; \
			(list2).head->link.prev = (list1).tail; \
			(list1).tail = (list2).tail; \
		} \
		(list2).head = NULL; \
		(list2).tail = NULL; \
	} while (0)

#define LWRES_LIST_ENQUEUE(list, elt, link) LWRES_LIST_APPEND(list, elt, link)
#define LWRES_LIST_DEQUEUE(list, elt, link) LWRES_LIST_UNLINK(list, elt, link)

#endif /* LWRES_LIST_H */


code:
/*
 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
 * Copyright (C) 2000, 2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $Id: lwbuffer.h,v 1.22 2007-06-19 23:47:23 tbox Exp $ */

/*! \file lwres/lwbuffer.h
 *
 * A buffer is a region of memory, together with a set of related subregions.
 * Buffers are used for parsing and I/O operations.
 *
 * The 'used region' and the 'available' region are disjoint, and their
 * union is the buffer's region.  The used region extends from the beginning
 * of the buffer region to the last used byte.  The available region
 * extends from one byte greater than the last used byte to the end of the
 * buffer's region.  The size of the used region can be changed using various
 * buffer commands.  Initially, the used region is empty.
 *
 * The used region is further subdivided into two disjoint regions: the
 * 'consumed region' and the 'remaining region'.  The union of these two
 * regions is the used region.  The consumed region extends from the beginning
 * of the used region to the byte before the 'current' offset (if any).  The
 * 'remaining' region the current pointer to the end of the used
 * region.  The size of the consumed region can be changed using various
 * buffer commands.  Initially, the consumed region is empty.
 *
 * The 'active region' is an (optional) subregion of the remaining region.
 * It extends from the current offset to an offset in the remaining region
 * that is selected with lwres_buffer_setactive().  Initially, the active
 * region is empty.  If the current offset advances beyond the chosen offset,
 * the active region will also be empty.
 *
 * \verbatim
 *  /----- used region -----\/-- available --\
 *  +----------------------------------------+
 *  | consumed  | remaining |                |
 *  +----------------------------------------+
 *  a           b     c     d                e
 *
 * a == base of buffer.
 * b == current pointer.  Can be anywhere between a and d.
 * c == active pointer.  Meaningful between b and d.
 * d == used pointer.
 * e == length of buffer.
 *
 * a-e == entire (length) of buffer.
 * a-d == used region.
 * a-b == consumed region.
 * b-d == remaining region.
 * b-c == optional active region.
 * \endverbatim
 *
 * The following invariants are maintained by all routines:
 *
 *\verbatim
 *	length > 0
 *
 *	base is a valid pointer to length bytes of memory
 *
 *	0 <= used <= length
 *
 *	0 <= current <= used
 *
 *	0 <= active <= used
 *	(although active < current implies empty active region)
 *\endverbatim
 *
 * \li MP:
 *	Buffers have no synchronization.  Clients must ensure exclusive
 *	access.
 *
 * \li Reliability:
 *	No anticipated impact.
 *
 * \li Resources:
 *	Memory: 1 pointer + 6 unsigned integers per buffer.
 *
 * \li Security:
 *	No anticipated impact.
 *
 * \li Standards:
 *	None.
 */

#ifndef LWRES_LWBUFFER_H
#define LWRES_LWBUFFER_H 1

/***
 *** Imports
 ***/

#include <lwres/lang.h>
#include <lwres/int.h>

LWRES_LANG_BEGINDECLS

/***
 *** Magic numbers
 ***/
#define LWRES_BUFFER_MAGIC		0x4275663fU	/* Buf?. */

#define LWRES_BUFFER_VALID(b)		((b) != NULL && \
					 (b)->magic == LWRES_BUFFER_MAGIC)

/*!
 * The following macros MUST be used only on valid buffers.  It is the
 * caller's responsibility to ensure this by using the LWRES_BUFFER_VALID
 * check above, or by calling another lwres_buffer_*() function (rather than
 * another macro.)
 */

/*!
 * Get the length of the used region of buffer "b"
 */
#define LWRES_BUFFER_USEDCOUNT(b)	((b)->used)

/*!
 * Get the length of the available region of buffer "b"
 */
#define LWRES_BUFFER_AVAILABLECOUNT(b)	((b)->length - (b)->used)

#define LWRES_BUFFER_REMAINING(b)	((b)->used - (b)->current)

/*!
 * Note that the buffer structure is public.  This is principally so buffer
 * operations can be implemented using macros.  Applications are strongly
 * discouraged from directly manipulating the structure.
 */

typedef struct lwres_buffer lwres_buffer_t;
/*!
 * Buffer data structure
 */
struct lwres_buffer {
	unsigned int		magic;
	unsigned char 	       *base;
	/* The following integers are byte offsets from 'base'. */
	unsigned int		length;
	unsigned int		used;
	unsigned int 		current;
	unsigned int 		active;
};

/***
 *** Functions
 ***/

void
lwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length);
/**<
 * Make 'b' refer to the 'length'-byte region starting at base.
 *
 * Requires:
 *
 *	'length' > 0
 *
 *	'base' is a pointer to a sequence of 'length' bytes.
 *
 */

void
lwres_buffer_invalidate(lwres_buffer_t *b);
/**<
 * Make 'b' an invalid buffer.
 *
 * Requires:
 *	'b' is a valid buffer.
 *
 * Ensures:
 *	If assertion checking is enabled, future attempts to use 'b' without
 *	calling lwres_buffer_init() on it will cause an assertion failure.
 */

void
lwres_buffer_add(lwres_buffer_t *b, unsigned int n);
/**<
 * Increase the 'used' region of 'b' by 'n' bytes.
 *
 * Requires:
 *
 *	'b' is a valid buffer
 *
 *	used + n <= length
 *
 */

void
lwres_buffer_subtract(lwres_buffer_t *b, unsigned int n);
/**<
 * Decrease the 'used' region of 'b' by 'n' bytes.
 *
 * Requires:
 *
 *	'b' is a valid buffer
 *
 *	used >= n
 *
 */

void
lwres_buffer_clear(lwres_buffer_t *b);
/**<
 * Make the used region empty.
 *
 * Requires:
 *
 *	'b' is a valid buffer
 *
 * Ensures:
 *
 *	used = 0
 *
 */

void
lwres_buffer_first(lwres_buffer_t *b);
/**<
 * Make the consumed region empty.
 *
 * Requires:
 *
 *	'b' is a valid buffer
 *
 * Ensures:
 *
 *	current == 0
 *
 */

void
lwres_buffer_forward(lwres_buffer_t *b, unsigned int n);
/**<
 * Increase the 'consumed' region of 'b' by 'n' bytes.
 *
 * Requires:
 *
 *	'b' is a valid buffer
 *
 *	current + n <= used
 *
 */

void
lwres_buffer_back(lwres_buffer_t *b, unsigned int n);
/**<
 * Decrease the 'consumed' region of 'b' by 'n' bytes.
 *
 * Requires:
 *
 *	'b' is a valid buffer
 *
 *	n <= current
 *
 */

lwres_uint8_t
lwres_buffer_getuint8(lwres_buffer_t *b);
/**<
 * Read an unsigned 8-bit integer from 'b' and return it.
 *
 * Requires:
 *
 *	'b' is a valid buffer.
 *
 *	The length of the available region of 'b' is at least 1.
 *
 * Ensures:
 *
 *	The current pointer in 'b' is advanced by 1.
 *
 * Returns:
 *
 *	A 8-bit unsigned integer.
 */

void
lwres_buffer_putuint8(lwres_buffer_t *b, lwres_uint8_t val);
/**<
 * Store an unsigned 8-bit integer from 'val' into 'b'.
 *
 * Requires:
 *	'b' is a valid buffer.
 *
 *	The length of the unused region of 'b' is at least 1.
 *
 * Ensures:
 *	The used pointer in 'b' is advanced by 1.
 */

lwres_uint16_t
lwres_buffer_getuint16(lwres_buffer_t *b);
/**<
 * Read an unsigned 16-bit integer in network byte order from 'b', convert
 * it to host byte order, and return it.
 *
 * Requires:
 *
 *	'b' is a valid buffer.
 *
 *	The length of the available region of 'b' is at least 2.
 *
 * Ensures:
 *
 *	The current pointer in 'b' is advanced by 2.
 *
 * Returns:
 *
 *	A 16-bit unsigned integer.
 */

void
lwres_buffer_putuint16(lwres_buffer_t *b, lwres_uint16_t val);
/**<
 * Store an unsigned 16-bit integer in host byte order from 'val'
 * into 'b' in network byte order.
 *
 * Requires:
 *	'b' is a valid buffer.
 *
 *	The length of the unused region of 'b' is at least 2.
 *
 * Ensures:
 *	The used pointer in 'b' is advanced by 2.
 */

lwres_uint32_t
lwres_buffer_getuint32(lwres_buffer_t *b);
/**<
 * Read an unsigned 32-bit integer in network byte order from 'b', convert
 * it to host byte order, and return it.
 *
 * Requires:
 *
 *	'b' is a valid buffer.
 *
 *	The length of the available region of 'b' is at least 2.
 *
 * Ensures:
 *
 *	The current pointer in 'b' is advanced by 2.
 *
 * Returns:
 *
 *	A 32-bit unsigned integer.
 */

void
lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val);
/**<
 * Store an unsigned 32-bit integer in host byte order from 'val'
 * into 'b' in network byte order.
 *
 * Requires:
 *	'b' is a valid buffer.
 *
 *	The length of the unused region of 'b' is at least 4.
 *
 * Ensures:
 *	The used pointer in 'b' is advanced by 4.
 */

void
lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base,
		    unsigned int length);
/**<
 * Copy 'length' bytes of memory at 'base' into 'b'.
 *
 * Requires:
 *	'b' is a valid buffer.
 *
 *	'base' points to 'length' bytes of valid memory.
 *
 */

void
lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base,
		    unsigned int length);
/**<
 * Copy 'length' bytes of memory from 'b' into 'base'.
 *
 * Requires:
 *	'b' is a valid buffer.
 *
 *	'base' points to at least 'length' bytes of valid memory.
 *
 *	'b' have at least 'length' bytes remaining.
 */

LWRES_LANG_ENDDECLS

#endif /* LWRES_LWBUFFER_H */


code:
/*
 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
 * Copyright (C) 1999-2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $Id: lwpacket.h,v 1.24 2007-06-19 23:47:23 tbox Exp $ */

#ifndef LWRES_LWPACKET_H
#define LWRES_LWPACKET_H 1

#include <lwres/lang.h>
#include <lwres/lwbuffer.h>
#include <lwres/result.h>

/*% lwres_lwpacket_t */
typedef struct lwres_lwpacket lwres_lwpacket_t;

/*% lwres_lwpacket structure */
struct lwres_lwpacket {
	/*! The overall packet length, including the
	 *  entire packet header.
	 *  This field is filled in by the
	 *  \link lwres_gabn.c lwres_gabn_*()\endlink
	 *  and \link lwres_gnba.c lwres_gnba_*()\endlink calls.
	 */
	lwres_uint32_t		length;
	/*! Specifies the header format.  Currently,
	 *  there is only one format, #LWRES_LWPACKETVERSION_0.
	 *  This field is filled in by the
	 *  \link lwres_gabn.c lwres_gabn_*()\endlink
	 *  and \link lwres_gnba.c lwres_gnba_*()\endlink calls.
         */
	lwres_uint16_t		version;
 	/*! Specifies library-defined flags for this packet, such as
	 *  whether the packet is a request or a reply.  None of
	 *  these are definable by the caller, but library-defined values
	 *  can be set by the caller.  For example, one bit in this field
	 *  indicates if the packet is a request or a response.
	 *  This field is filled in by
	 *  the application wits the exception of the
	 *  #LWRES_LWPACKETFLAG_RESPONSE bit, which is set by the library
	 *  in the
	 *  \link lwres_gabn.c lwres_gabn_*()\endlink
	 *  and \link lwres_gnba.c lwres_gnba_*()\endlink calls.
         */
	lwres_uint16_t		pktflags;
 	/*! Set by the requestor and is returned in all replies.
	 *  If two packets from the same source have the same serial
	 *  number and are from the same source, they are assumed to
	 *  be duplicates and the latter ones may be dropped.
	 *  (The library does not do this by default on replies, but
 	 * does so on requests.)
         */
	lwres_uint32_t		serial;
 	/*! Opcodes between 0x04000000 and 0xffffffff
 	 *  are application defined.  Opcodes between
	 *  0x00000000 and 0x03ffffff are
 	 * reserved for library use.
	 *  This field is filled in by the
	 *  \link lwres_gabn.c lwres_gabn_*()\endlink
	 *  and \link lwres_gnba.c lwres_gnba_*()\endlink calls.
	 */
	lwres_uint32_t		opcode;
 	/*! Only valid for results.
	 *  Results between 0x04000000 and 0xffffffff are application
	 *  defined.
 	 * Results between 0x00000000 and 0x03ffffff are reserved for
	 * library use.
 	 * (This is the same reserved range defined in <isc/resultclass.h>,
	 * so it
 	 * would be trivial to map ISC_R_* result codes into packet result
	 * codes when appropriate.)
	 *  This field is filled in by the
	 *  \link lwres_gabn.c lwres_gabn_*()\endlink
	 *  and \link lwres_gnba.c lwres_gnba_*()\endlink calls.
	 */
	lwres_uint32_t		result;
 	/*! Set to the maximum buffer size that the receiver can
 	 *  handle on requests, and the size of the buffer needed to
	 *  satisfy a request
 	 *  when the buffer is too large for replies.
	 *  This field is supplied by the application.
	 */
	lwres_uint32_t		recvlength;
 	/*! The packet level auth type used.
 	 *  Authtypes between 0x1000 and 0xffff are application defined.
	 *  Authtypes
 	 *  between 0x0000 and 0x0fff are reserved for library use.
	 *  This is currently
 	 *  unused and MUST be set to zero.
	 */
	lwres_uint16_t		authtype;
 	/*! The length of the authentication data.
	 *  See the specific
 	 * authtypes for more information on what is contained
	 * in this field.  This is currently unused, and
	 * MUST be set to zero.
	 */
	lwres_uint16_t		authlength;
};

#define LWRES_LWPACKET_LENGTH		(4 * 5 + 2 * 4) /*%< Overall length. */

#define LWRES_LWPACKETFLAG_RESPONSE	0x0001U	/*%< If set, pkt is a response. */

#define LWRES_LWPACKETVERSION_0		0	/*%< Header format. */

/*! \file lwres/lwpacket.h
 *
 *
 * The remainder of the packet consists of two regions, one described by
 * "authlen" and one of "length - authlen - sizeof(lwres_lwpacket_t)".
 *
 * That is:
 *
 * \code
 *	pkt header
 *	authlen bytes of auth information
 *	data bytes
 * \endcode
 *
 * Currently defined opcodes:
 *
 *\li	#LWRES_OPCODE_NOOP.  Success is always returned, with the packet contents echoed.
 *
 *\li	#LWRES_OPCODE_GETADDRSBYNAME.  Return all known addresses for a given name.
 *		This may return NIS or /etc/hosts info as well as DNS
 *		information.  Flags will be provided to indicate ip4/ip6
 *		addresses are desired.
 *
 *\li	#LWRES_OPCODE_GETNAMEBYADDR.	Return the hostname for the given address.  Once
 *		again, it will return data from multiple sources.
 */

LWRES_LANG_BEGINDECLS

/* XXXMLG document */
lwres_result_t
lwres_lwpacket_renderheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt);

lwres_result_t
lwres_lwpacket_parseheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt);

LWRES_LANG_ENDDECLS

#endif /* LWRES_LWPACKET_H */


code:
/*
 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
 * Copyright (C) 2000, 2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* $Id: lwres.h,v 1.57 2007-06-19 23:47:23 tbox Exp $ */

#ifndef LWRES_LWRES_H
#define LWRES_LWRES_H 1

#include <stdio.h>

#include <lwres/context.h>
#include <lwres/lang.h>
#include <lwres/list.h>
#include <lwres/lwpacket.h>
#include <lwres/platform.h>

/*! \file lwres/lwres.h */

/*!
 * Design notes:
 *
 * Each opcode has two structures and three functions which operate on each
 * structure.  For example, using the "no operation/ping" opcode as an
 * example:
 *
 *

lwres_nooprequest_t:
 *
 *		lwres_nooprequest_render() takes a lwres_nooprequest_t and
 *		and renders it into wire format, storing the allocated
 *		buffer information in a passed-in buffer.  When this buffer
 *		is no longer needed, it must be freed by
 *		lwres_context_freemem().  All other memory used by the
 *		caller must be freed manually, including the
 *		lwres_nooprequest_t passed in.

 *
 *		lwres_nooprequest_parse() takes a wire format message and
 *		breaks it out into a lwres_nooprequest_t.  The structure
 *		must be freed via lwres_nooprequest_free() when it is no longer
 *		needed.

 *
 *		lwres_nooprequest_free() releases into the lwres_context_t
 *		any space allocated during parsing.

 *
 *
lwres_noopresponse_t:
 *
 *		The functions used are similar to the three used for
 *		requests, just with different names.

 *
 * Typically, the client will use request_render, response_parse, and
 * response_free, while the daemon will use request_parse, response_render,
 * and request_free.
 *
 * The basic flow of a typical client is:
 *
 *	\li fill in a request_t, and call the render function.
 *
 *	\li Transmit the buffer returned to the daemon.
 *
 *	\li Wait for a response.
 *
 *	\li When a response is received, parse it into a response_t.
 *
 *	\li free the request buffer using lwres_context_freemem().
 *
 *	\li free the response structure and its associated buffer using
 *	response_free().
 */

#define LWRES_UDP_PORT		921	/*%< UDP Port Number */
#define LWRES_RECVLENGTH	16384 /*%< Maximum Packet Length */
#define LWRES_ADDR_MAXLEN	16	/*%< changing this breaks ABI */
#define LWRES_RESOLV_CONF	"/etc/resolv.conf" /*%< Location of resolv.conf */

/*% DNSSEC is not required (input).  Only relevant to rrset queries. */
#define LWRES_FLAG_TRUSTNOTREQUIRED	0x00000001U
/*% The data was crypto-verified with DNSSEC (output). */
#define LWRES_FLAG_SECUREDATA		0x00000002U

/*% no-op */
#define LWRES_OPCODE_NOOP		0x00000000U

/*% lwres_nooprequest_t */
typedef struct {
	/* public */
	lwres_uint16_t			datalength;
	unsigned char		       *data;
} lwres_nooprequest_t;

/*% lwres_noopresponse_t */
typedef struct {
	/* public */
	lwres_uint16_t			datalength;
	unsigned char		       *data;
} lwres_noopresponse_t;

/*% get addresses by name */
#define LWRES_OPCODE_GETADDRSBYNAME	0x00010001U

/*% lwres_addr_t */
typedef struct lwres_addr lwres_addr_t;

/*% LWRES_LIST */
typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;

/*% lwres_addr */
struct lwres_addr {
	lwres_uint32_t			family;
	lwres_uint16_t			length;
	unsigned char			address[LWRES_ADDR_MAXLEN];
	LWRES_LINK(lwres_addr_t)	link;
};

/*% lwres_gabnrequest_t */
typedef struct {
	/* public */
	lwres_uint32_t			flags;
	lwres_uint32_t			addrtypes;
	lwres_uint16_t			namelen;
	char			       *name;
} lwres_gabnrequest_t;

/*% lwres_gabnresponse_t */
typedef struct {
	/* public */
	lwres_uint32_t			flags;
	lwres_uint16_t			naliases;
	lwres_uint16_t			naddrs;
	char			       *realname;
	char			      **aliases;
	lwres_uint16_t			realnamelen;
	lwres_uint16_t		       *aliaslen;
	lwres_addrlist_t		addrs;
	/*! if base != NULL, it will be freed when this structure is freed. */
	void			       *base;
	size_t				baselen;
} lwres_gabnresponse_t;

/*% get name by address */
#define LWRES_OPCODE_GETNAMEBYADDR	0x00010002U

/*% lwres_gnbarequest_t */
typedef struct {
	/* public */
	lwres_uint32_t			flags;
	lwres_addr_t			addr;
} lwres_gnbarequest_t;

/*% lwres_gnbaresponse_t */
typedef struct {
	/* public */
	lwres_uint32_t			flags;
	lwres_uint16_t			naliases;
	char			       *realname;
	char			      **aliases;
	lwres_uint16_t			realnamelen;
	lwres_uint16_t		       *aliaslen;
	/*! if base != NULL, it will be freed when this structure is freed. */
	void			       *base;
	size_t				baselen;
} lwres_gnbaresponse_t;

/*% get rdata by name */
#define LWRES_OPCODE_GETRDATABYNAME	0x00010003U

/*% lwres_grbnrequest_t */
typedef struct {
	/* public */
	lwres_uint32_t			flags;
	lwres_uint16_t			rdclass;
	lwres_uint16_t			rdtype;
	lwres_uint16_t			namelen;
	char			       *name;
} lwres_grbnrequest_t;

/*% lwres_grbnresponse_t */
typedef struct {
	/* public */
	lwres_uint32_t			flags;
	lwres_uint16_t			rdclass;
	lwres_uint16_t			rdtype;
	lwres_uint32_t			ttl;
	lwres_uint16_t			nrdatas;
	lwres_uint16_t			nsigs;
	char			       *realname;
	lwres_uint16_t			realnamelen;
	unsigned char		      **rdatas;
	lwres_uint16_t		       *rdatalen;
	unsigned char		      **sigs;
	lwres_uint16_t		       *siglen;
	/*% if base != NULL, it will be freed when this structure is freed. */
	void			       *base;
	size_t				baselen;
} lwres_grbnresponse_t;

/*% Used by lwres_getrrsetbyname() */
#define LWRDATA_VALIDATED	0x00000001

/*!
 * resolv.conf data
 */

#define LWRES_CONFMAXNAMESERVERS 3	/*%< max 3 "nameserver" entries */
#define LWRES_CONFMAXLWSERVERS 1	/*%< max 1 "lwserver" entry */
#define LWRES_CONFMAXSEARCH 8		/*%< max 8 domains in "search" entry */
#define LWRES_CONFMAXLINELEN 256	/*%< max size of a line */
#define LWRES_CONFMAXSORTLIST 10	/*%< max 10 */

/*% lwres_conf_t */
typedef struct {
	lwres_context_t *lwctx;
	lwres_addr_t    nameservers[LWRES_CONFMAXNAMESERVERS];
	lwres_uint8_t	nsnext;		/*%< index for next free slot */

	lwres_addr_t	lwservers[LWRES_CONFMAXLWSERVERS];
	lwres_uint8_t	lwnext;		/*%< index for next free slot */

	char	       *domainname;

	char 	       *search[LWRES_CONFMAXSEARCH];
	lwres_uint8_t	searchnxt;	/*%< index for next free slot */

	struct {
		lwres_addr_t addr;
		/*% mask has a non-zero 'family' and 'length' if set */
		lwres_addr_t mask;
	} sortlist[LWRES_CONFMAXSORTLIST];
	lwres_uint8_t	sortlistnxt;

	lwres_uint8_t	resdebug;      /*%< non-zero if 'options debug' set */
	lwres_uint8_t	ndots;	       /*%< set to n in 'options ndots:n' */
	lwres_uint8_t	no_tld_query;  /*%< non-zero if 'options no_tld_query' */
} lwres_conf_t;

#define LWRES_ADDRTYPE_V4		0x00000001U	/*%< ipv4 */
#define LWRES_ADDRTYPE_V6		0x00000002U	/*%< ipv6 */

#define LWRES_MAX_ALIASES		16		/*%< max # of aliases */
#define LWRES_MAX_ADDRS			64		/*%< max # of addrs */

LWRES_LANG_BEGINDECLS

/*% This is in host byte order. */
LIBLWRES_EXTERNAL_DATA extern lwres_uint16_t lwres_udp_port;

LIBLWRES_EXTERNAL_DATA extern const char *lwres_resolv_conf;

lwres_result_t
lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req,
			 lwres_lwpacket_t *pkt, lwres_buffer_t *b);

lwres_result_t
lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
			  lwres_lwpacket_t *pkt, lwres_buffer_t *b);

lwres_result_t
lwres_gabnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
			lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp);

lwres_result_t
lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
			 lwres_lwpacket_t *pkt,
			 lwres_gabnresponse_t **structp);

void
lwres_gabnrequest_free(lwres_context_t *ctx, lwres_gabnrequest_t **structp);
/**<
 * Frees any dynamically allocated memory for this structure.
 *
 * Requires:
 *
 *	ctx != NULL, and be a context returned via lwres_context_create().
 *
 *	structp != NULL && *structp != NULL.
 *
 * Ensures:
 *
 *	*structp == NULL.
 *
 *	All memory allocated by this structure will be returned to the
 *	system via the context's free function.
 */

void
lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp);
/**<
 * Frees any dynamically allocated memory for this structure.
 *
 * Requires:
 *
 *	ctx != NULL, and be a context returned via lwres_context_create().
 *
 *	structp != NULL && *structp != NULL.
 *
 * Ensures:
 *
 *	*structp == NULL.
 *
 *	All memory allocated by this structure will be returned to the
 *	system via the context's free function.
 */

lwres_result_t
lwres_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_t *req,
			 lwres_lwpacket_t *pkt, lwres_buffer_t *b);

lwres_result_t
lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req,
			  lwres_lwpacket_t *pkt, lwres_buffer_t *b);

lwres_result_t
lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
			lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp);

lwres_result_t
lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
			 lwres_lwpacket_t *pkt,
			 lwres_gnbaresponse_t **structp);

void
lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp);
/**<
 * Frees any dynamically allocated memory for this structure.
 *
 * Requires:
 *
 *	ctx != NULL, and be a context returned via lwres_context_create().
 *
 *	structp != NULL && *structp != NULL.
 *
 * Ensures:
 *
 *	*structp == NULL.
 *
 *	All memory allocated by this structure will be returned to the
 *	system via the context's free function.
 */

void
lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp);
/**<
 * Frees any dynamically allocated memory for this structure.
 *
 * Requires:
 *
 *	ctx != NULL, and be a context returned via lwres_context_create().
 *
 *	structp != NULL && *structp != NULL.
 *
 * Ensures:
 *
 *	*structp == NULL.
 *
 *	All memory allocated by this structure will be returned to the
 *	system via the context's free function.
 */

lwres_result_t
lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req,
			 lwres_lwpacket_t *pkt, lwres_buffer_t *b);

lwres_result_t
lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req,
			  lwres_lwpacket_t *pkt, lwres_buffer_t *b);

lwres_result_t
lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
			lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp);

lwres_result_t
lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
			 lwres_lwpacket_t *pkt,
			 lwres_grbnresponse_t **structp);

void
lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp);
/**<
 * Frees any dynamically allocated memory for this structure.
 *
 * Requires:
 *
 *	ctx != NULL, and be a context returned via lwres_context_create().
 *
 *	structp != NULL && *structp != NULL.
 *
 * Ensures:
 *
 *	*structp == NULL.
 *
 *	All memory allocated by this structure will be returned to the
 *	system via the context's free function.
 */

void
lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp);
/**<
 * Frees any dynamically allocated memory for this structure.
 *
 * Requires:
 *
 *	ctx != NULL, and be a context returned via lwres_context_create().
 *
 *	structp != NULL && *structp != NULL.
 *
 * Ensures:
 *
 *	*structp == NULL.
 *
 *	All memory allocated by this structure will be returned to the
 *	system via the context's free function.
 */

lwres_result_t
lwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req,
			 lwres_lwpacket_t *pkt, lwres_buffer_t *b);
/**<
 * Allocate space and render into wire format a noop request packet.
 *
 * Requires:
 *
 *	ctx != NULL, and be a context returned via lwres_context_create().
 *
 *	b != NULL, and points to a lwres_buffer_t.  The contents of the
 *	buffer structure will be initialized to contain the wire-format
 *	noop request packet.
 *
 *	Caller needs to fill in parts of "pkt" before calling:
 *		serial, maxrecv, result.
 *
 * Returns:
 *
 *	Returns 0 on success, non-zero on failure.
 *
 *	On successful return, *b will contain data about the wire-format
 *	packet.  It can be transmitted in any way, including lwres_sendblock().
 */

lwres_result_t
lwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req,
			  lwres_lwpacket_t *pkt, lwres_buffer_t *b);

lwres_result_t
lwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
			lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp);
/**<
 * Parse a noop request.  Note that to get here, the lwpacket must have
 * already been parsed and removed by the caller, otherwise it would be
 * pretty hard for it to know this is the right function to call.
 *
 * The function verifies bits of the header, but does not modify it.
 */

lwres_result_t
lwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
			 lwres_lwpacket_t *pkt,
			 lwres_noopresponse_t **structp);

void
lwres_nooprequest_free(lwres_context_t *ctx, lwres_nooprequest_t **structp);

void
lwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp);

/**<
 * Frees any dynamically allocated memory for this structure.
 *
 * Requires:
 *
 *	ctx != NULL, and be a context returned via lwres_context_create().
 *
 *	structp != NULL && *structp != NULL.
 *
 * Ensures:
 *
 *	*structp == NULL.
 *
 *	All memory allocated by this structure will be returned to the
 *	system via the context's free function.
 */

lwres_result_t
lwres_conf_parse(lwres_context_t *ctx, const char *filename);
/**<
 * parses a resolv.conf-format file and stores the results in the structure
 * pointed to by *ctx.
 *
 * Requires:
 *	ctx != NULL
 *	filename != NULL && strlen(filename) > 0
 *
 * Returns:
 *	LWRES_R_SUCCESS on a successful parse.
 *	Anything else on error, although the structure may be partially filled
 *	in.
 */

lwres_result_t
lwres_conf_print(lwres_context_t *ctx, FILE *fp);
/**<
 * Prints a resolv.conf-format of confdata output to fp.
 *
 * Requires:
 *	ctx != NULL
 */

void
lwres_conf_init(lwres_context_t *ctx);
/**<
 * sets all internal fields to a default state. Used to initialize a new
 * lwres_conf_t structure (not reset a used on).
 *
 * Requires:
 *	ctx != NULL
 */

void
lwres_conf_clear(lwres_context_t *ctx);
/**<
 * frees all internally allocated memory in confdata. Uses the memory
 * routines supplied by ctx.
 *
 * Requires:
 *	ctx != NULL
 */

lwres_conf_t *
lwres_conf_get(lwres_context_t *ctx);
/**<
 * Be extremely cautions in modifying the contents of this structure; it
 * needs an API to return the various bits of data, walk lists, etc.
 *
 * Requires:
 *	ctx != NULL
 */

/*
 * Helper functions
 */

lwres_result_t
lwres_data_parse(lwres_buffer_t *b, unsigned char **p, lwres_uint16_t *len);

lwres_result_t
lwres_string_parse(lwres_buffer_t *b, char **c, lwres_uint16_t *len);

lwres_result_t
lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr);

lwres_result_t
lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
		     lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp);

lwres_result_t
lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype,
		    lwres_uint16_t addrlen, const unsigned char *addr,
		    lwres_gnbaresponse_t **structp);

lwres_result_t
lwres_getrdatabyname(lwres_context_t *ctx, const char *name,
		     lwres_uint16_t rdclass, lwres_uint16_t rdtype,
		     lwres_uint32_t flags, lwres_grbnresponse_t **structp);

LWRES_LANG_ENDDECLS

#endif /* LWRES_LWRES_H */