aboutsummaryrefslogtreecommitdiffstats
path: root/lib/erl_interface/include/ei.h
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/erl_interface/include/ei.h
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/erl_interface/include/ei.h')
-rw-r--r--lib/erl_interface/include/ei.h785
1 files changed, 785 insertions, 0 deletions
diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h
new file mode 100644
index 0000000000..01272244e1
--- /dev/null
+++ b/lib/erl_interface/include/ei.h
@@ -0,0 +1,785 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1998-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+#ifndef EI_H
+#define EI_H
+
+#define EI_HAVE_TIMEOUT 1 /* Flag to user code that we have them */
+#define USE_EI_UNDOCUMENTED /* Want declarations for undocumented */
+
+/************************************************************************/
+/* This file defines the complete interface to ei */
+/************************************************************************/
+
+/* -------------------------------------------------------------------- */
+/* Include types needed below */
+/* -------------------------------------------------------------------- */
+
+#if defined(__WIN32__)
+#include <winsock2.h>
+#include <windows.h>
+#include <winbase.h>
+#endif
+
+#include <stdio.h> /* Need type FILE */
+#include <errno.h> /* Need EHOSTUNREACH, ENOMEM, ... */
+
+#if !defined(__WIN32__) && !defined(VXWORKS) || (defined(VXWORKS) && defined(HAVE_SENS))
+# include <netdb.h>
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/* Defines part of API */
+/* -------------------------------------------------------------------- */
+
+/*
+ * Some error codes might be missing, so here's a backstop definitions
+ * of the ones we use with `erl_errno':
+ */
+
+#ifndef EMSGSIZE /* Message too long */
+#define EMSGSIZE EIO
+#endif
+
+#ifndef ETIMEDOUT /* Connection timed out */
+#define ETIMEDOUT EIO
+#endif
+
+#ifndef EHOSTUNREACH /* No route to host */
+#define EHOSTUNREACH EIO
+#endif
+
+/* FIXME just a few are documented, does it mean they can't be returned? */
+
+#define ERL_ERROR -1 /* Error of some kind */
+#define ERL_NO_DAEMON -2 /* No contact with EPMD */
+#define ERL_NO_PORT -3 /* No port received from EPMD */
+#define ERL_CONNECT_FAIL -4 /* Connect to Erlang Node failed */
+#define ERL_TIMEOUT -5 /* A timeout has expired */
+#define ERL_NO_REMOTE -6 /* Cannot execute rsh */
+
+#define ERL_TICK 0
+#define ERL_MSG 1
+
+#define ERL_NO_TIMEOUT -1
+
+/* these are the control message types */
+#define ERL_LINK 1
+#define ERL_SEND 2
+#define ERL_EXIT 3
+#define ERL_UNLINK 4
+#define ERL_NODE_LINK 5
+#define ERL_REG_SEND 6
+#define ERL_GROUP_LEADER 7
+#define ERL_EXIT2 8
+#define ERL_PASS_THROUGH 'p'
+
+/* new ones for tracing, from Kenneth */
+#define ERL_SEND_TT 12
+#define ERL_EXIT_TT 13
+#define ERL_REG_SEND_TT 16
+#define ERL_EXIT2_TT 18
+
+
+/* -------------------------------------------------------------------- */
+/* Defines used for ei_get_type_internal() output */
+/* -------------------------------------------------------------------- */
+/*
+ * these are the term type indicators used in
+ * the external (distribution) format
+ */
+
+/* FIXME we don't want to export these..... */
+
+#define ERL_SMALL_INTEGER_EXT 'a'
+#define ERL_INTEGER_EXT 'b'
+#define ERL_FLOAT_EXT 'c'
+#define ERL_ATOM_EXT 'd'
+#define ERL_REFERENCE_EXT 'e'
+#define ERL_NEW_REFERENCE_EXT 'r'
+#define ERL_PORT_EXT 'f'
+#define ERL_PID_EXT 'g'
+#define ERL_SMALL_TUPLE_EXT 'h'
+#define ERL_LARGE_TUPLE_EXT 'i'
+#define ERL_NIL_EXT 'j'
+#define ERL_STRING_EXT 'k'
+#define ERL_LIST_EXT 'l'
+#define ERL_BINARY_EXT 'm'
+#define ERL_SMALL_BIG_EXT 'n'
+#define ERL_LARGE_BIG_EXT 'o'
+#define ERL_NEW_FUN_EXT 'p'
+#define ERL_FUN_EXT 'u'
+
+#define ERL_NEW_CACHE 'N' /* c nodes don't know these two */
+#define ERL_CACHED_ATOM 'C'
+
+
+/* -------------------------------------------------------------------- */
+/* Define the erl_errno macro */
+/* -------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * GCC's attributes are too useful to not use. Other compilers
+ * just lose opportunities to optimize and warn.
+ */
+#if !defined(__GNUC__) || __GNUC__ < 2
+# define __attribute__(foo) /* nothing */
+#endif
+
+/*
+ * Define the 'erl_errno' facility. Unfortunately this lives on in
+ * the 'ei' interface as well.... :-(
+ */
+
+#if defined(_REENTRANT) || defined(VXWORKS) || defined(__WIN32__)
+
+/* 'erl_errno' as a function return value */
+volatile int* __erl_errno_place(void) __attribute__ ((__const__));
+
+#define erl_errno (*__erl_errno_place ())
+
+#else /* !_REENTRANT && !VXWORKS && !__WIN32__ */
+
+extern volatile int __erl_errno;
+
+#define erl_errno __erl_errno
+
+#endif /* !_REENTRANT && !VXWORKS && !__WIN32__ */
+
+
+/* -------------------------------------------------------------------- */
+/* Type definitions */
+/* -------------------------------------------------------------------- */
+
+/*
+ * To avoid confusion about the MAXHOSTNAMELEN when compiling the
+ * library and when using the library we set a value that we use
+ */
+
+#define EI_MAXHOSTNAMELEN 64
+#define EI_MAXALIVELEN 63
+#define EI_MAX_COOKIE_SIZE 512
+#define MAXATOMLEN 255
+#define MAXNODELEN EI_MAXALIVELEN+1+EI_MAXHOSTNAMELEN
+
+/* a pid */
+typedef struct {
+ char node[MAXATOMLEN+1];
+ unsigned int num;
+ unsigned int serial;
+ unsigned int creation;
+} erlang_pid;
+
+/* a port */
+typedef struct {
+ char node[MAXATOMLEN+1];
+ unsigned int id;
+ unsigned int creation;
+} erlang_port;
+
+/* a ref */
+typedef struct {
+ char node[MAXATOMLEN+1];
+ int len;
+ unsigned int n[3];
+ unsigned int creation;
+} erlang_ref;
+
+/* a trace token */
+typedef struct {
+ long serial;
+ long prev;
+ erlang_pid from;
+ long label;
+ long flags;
+} erlang_trace;
+
+/* a message */
+typedef struct {
+ long msgtype;
+ erlang_pid from;
+ erlang_pid to;
+ char toname[MAXATOMLEN+1];
+ char cookie[MAXATOMLEN+1];
+ erlang_trace token;
+} erlang_msg;
+
+/* a fun */
+typedef struct {
+ long arity;
+ char module[MAXATOMLEN+1];
+ char md5[16];
+ long index;
+ long old_index;
+ long uniq;
+ long n_free_vars;
+ erlang_pid pid;
+ long free_var_len;
+ char* free_vars;
+} erlang_fun;
+
+/* a big */
+typedef struct {
+ unsigned int arity;
+ int is_neg;
+ void *digits;
+} erlang_big;
+
+typedef struct {
+ char ei_type;
+ int arity;
+ int size;
+ union {
+ long i_val;
+ double d_val;
+ char atom_name[MAXATOMLEN+1];
+ erlang_pid pid;
+ erlang_port port;
+ erlang_ref ref;
+ } value;
+} ei_term;
+
+/* XXX */
+
+typedef struct {
+ char ipadr[4]; /* stored in network byte order */
+ char nodename[MAXNODELEN+1];
+} ErlConnect;
+
+typedef struct ei_cnode_s {
+ char thishostname[EI_MAXHOSTNAMELEN+1];
+ char thisnodename[MAXNODELEN+1];
+ char thisalivename[EI_MAXALIVELEN+1];
+/* Currently this_ipaddr isn't used */
+/* struct in_addr this_ipaddr; */
+ char ei_connect_cookie[EI_MAX_COOKIE_SIZE+1];
+ short creation;
+ erlang_pid self;
+} ei_cnode;
+
+typedef struct in_addr *Erl_IpAddr;
+
+
+/* A dynamic version of ei XX */
+
+typedef struct ei_x_buff_TAG {
+ char* buff;
+ int buffsz;
+ int index;
+} ei_x_buff;
+
+
+/* -------------------------------------------------------------------- */
+/* Function definitions (listed in same order as documentation) */
+/* -------------------------------------------------------------------- */
+
+/* Handle the connection */
+
+int ei_connect_init(ei_cnode* ec, const char* this_node_name,
+ const char *cookie, short creation);
+int ei_connect_xinit (ei_cnode* ec, const char *thishostname,
+ const char *thisalivename, const char *thisnodename,
+ Erl_IpAddr thisipaddr, const char *cookie,
+ const short creation);
+
+int ei_connect(ei_cnode* ec, char *nodename);
+int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned ms);
+int ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename);
+int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned ms);
+
+int ei_receive(int fd, unsigned char *bufp, int bufsize);
+int ei_receive_tmo(int fd, unsigned char *bufp, int bufsize, unsigned ms);
+int ei_receive_msg(int fd, erlang_msg* msg, ei_x_buff* x);
+int ei_receive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned ms);
+int ei_xreceive_msg(int fd, erlang_msg* msg, ei_x_buff* x);
+int ei_xreceive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned ms);
+
+int ei_send(int fd, erlang_pid* to, char* buf, int len);
+int ei_send_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned ms);
+int ei_reg_send(ei_cnode* ec, int fd, char *server_name, char* buf, int len);
+int ei_reg_send_tmo(ei_cnode* ec, int fd, char *server_name, char* buf, int len, unsigned ms);
+
+int ei_rpc(ei_cnode* ec, int fd, char *mod, char *fun,
+ const char* inbuf, int inbuflen, ei_x_buff* x);
+int ei_rpc_to(ei_cnode* ec, int fd, char *mod, char *fun,
+ const char* buf, int len);
+int ei_rpc_from(ei_cnode* ec, int fd, int timeout, erlang_msg* msg,
+ ei_x_buff* x);
+
+int ei_publish(ei_cnode* ec, int port);
+int ei_publish_tmo(ei_cnode* ec, int port, unsigned ms);
+int ei_accept(ei_cnode* ec, int lfd, ErlConnect *conp);
+int ei_accept_tmo(ei_cnode* ec, int lfd, ErlConnect *conp, unsigned ms);
+int ei_unpublish(ei_cnode* ec);
+int ei_unpublish_tmo(const char *alive, unsigned ms);
+
+const char *ei_thisnodename(const ei_cnode* ec);
+const char *ei_thishostname(const ei_cnode* ec);
+const char *ei_thisalivename(const ei_cnode* ec);
+
+erlang_pid *ei_self(ei_cnode* ec);
+
+void ei_set_compat_rel(unsigned rel);
+
+/*
+ * We have erl_gethost*() so we include ei versions as well.
+ */
+
+#if defined(VXWORKS)
+
+extern int h_errno;
+
+/*
+ * We need these definitions - if the user has SENS then he gets them
+ * from netdb.h, otherwise we define them ourselves.
+ *
+ * If you are getting "multiple definition" errors here,
+ * make sure you have included <netdb.h> BEFORE "erl_interface.h"
+ * or define HAVE_SENS in your CFLAGS.
+ */
+
+#if !defined(HAVE_SENS) && !defined(HOST_NOT_FOUND) /* just in case */
+
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+#define h_addr h_addr_list[0] /* address, for backward compatiblity */
+ unsigned int unused; /* SENS defines this as ttl */
+};
+
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data record of requested type */
+#define NO_ADDRESS NO_DATA /* no address, look for MX record */
+
+#endif /* !HAVE_SENS && !HOST_NOT_FOUND */
+#endif /* VXWORKS */
+
+
+struct hostent *ei_gethostbyname(const char *name);
+struct hostent *ei_gethostbyaddr(const char *addr, int len, int type);
+struct hostent *ei_gethostbyname_r(const char *name,
+ struct hostent *hostp,
+ char *buffer,
+ int buflen,
+ int *h_errnop);
+struct hostent *ei_gethostbyaddr_r(const char *addr,
+ int length,
+ int type,
+ struct hostent *hostp,
+ char *buffer,
+ int buflen,
+ int *h_errnop);
+
+
+/* Encode/decode functions */
+
+int ei_encode_version(char *buf, int *index);
+int ei_x_encode_version(ei_x_buff* x);
+int ei_encode_long(char *buf, int *index, long p);
+int ei_x_encode_long(ei_x_buff* x, long n);
+int ei_encode_ulong(char *buf, int *index, unsigned long p);
+int ei_x_encode_ulong(ei_x_buff* x, unsigned long n);
+int ei_encode_double(char *buf, int *index, double p);
+int ei_x_encode_double(ei_x_buff* x, double dbl);
+int ei_encode_boolean(char *buf, int *index, int p);
+int ei_x_encode_boolean(ei_x_buff* x, int p);
+int ei_encode_char(char *buf, int *index, char p);
+int ei_x_encode_char(ei_x_buff* x, char p);
+int ei_encode_string(char *buf, int *index, const char *p);
+int ei_encode_string_len(char *buf, int *index, const char *p, int len);
+int ei_x_encode_string(ei_x_buff* x, const char* s);
+int ei_x_encode_string_len(ei_x_buff* x, const char* s, int len);
+int ei_encode_atom(char *buf, int *index, const char *p);
+int ei_encode_atom_len(char *buf, int *index, const char *p, int len);
+int ei_x_encode_atom(ei_x_buff* x, const char* s);
+int ei_x_encode_atom_len(ei_x_buff* x, const char* s, int len);
+int ei_encode_binary(char *buf, int *index, const void *p, long len);
+int ei_x_encode_binary(ei_x_buff* x, const void* s, int len);
+int ei_encode_pid(char *buf, int *index, const erlang_pid *p);
+int ei_x_encode_pid(ei_x_buff* x, const erlang_pid* pid);
+int ei_encode_fun(char* buf, int* index, const erlang_fun* p);
+int ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun);
+int ei_encode_port(char *buf, int *index, const erlang_port *p);
+int ei_x_encode_port(ei_x_buff* x, const erlang_port *p);
+int ei_encode_ref(char *buf, int *index, const erlang_ref *p);
+int ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p);
+int ei_encode_term(char *buf, int *index, void *t); /* ETERM* actually */
+int ei_x_encode_term(ei_x_buff* x, void* t);
+int ei_encode_trace(char *buf, int *index, const erlang_trace *p);
+int ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p);
+int ei_encode_tuple_header(char *buf, int *index, int arity);
+int ei_x_encode_tuple_header(ei_x_buff* x, long n);
+int ei_encode_list_header(char *buf, int *index, int arity);
+int ei_x_encode_list_header(ei_x_buff* x, long n);
+#define ei_encode_empty_list(buf,i) ei_encode_list_header(buf,i,0)
+int ei_x_encode_empty_list(ei_x_buff* x);
+
+/*
+ * ei_get_type() returns the type and "size" of the item at
+ * buf[index]. For strings and atoms, size is the number of characters
+ * not including the terminating 0. For binaries, size is the number
+ * of bytes. For lists and tuples, size is the arity of the
+ * object. For other types, size is 0. In all cases, index is left
+ * unchanged.
+ */
+
+int ei_get_type(const char *buf, const int *index, int *type, int *size);
+int ei_get_type_internal(const char *buf, const int *index, int *type,
+ int *size);
+
+/* Step through buffer, decoding the given type into the buffer
+ * provided. On success, 0 is returned and index is updated to point
+ * to the start of the next item in the buffer. If the type of item at
+ * buf[index] is not the requested type, -1 is returned and index is
+ * not updated. The buffer provided by the caller must be sufficiently
+ * large to contain the decoded object.
+ */
+int ei_decode_version(const char *buf, int *index, int *version);
+int ei_decode_long(const char *buf, int *index, long *p);
+int ei_decode_ulong(const char *buf, int *index, unsigned long *p);
+int ei_decode_double(const char *buf, int *index, double *p);
+int ei_decode_boolean(const char *buf, int *index, int *p);
+int ei_decode_char(const char *buf, int *index, char *p);
+int ei_decode_string(const char *buf, int *index, char *p);
+int ei_decode_atom(const char *buf, int *index, char *p);
+int ei_decode_binary(const char *buf, int *index, void *p, long *len);
+int ei_decode_fun(const char* buf, int* index, erlang_fun* p);
+void free_fun(erlang_fun* f);
+int ei_decode_pid(const char *buf, int *index, erlang_pid *p);
+int ei_decode_port(const char *buf, int *index, erlang_port *p);
+int ei_decode_ref(const char *buf, int *index, erlang_ref *p);
+int ei_decode_term(const char *buf, int *index, void *t); /* ETERM** actually */
+int ei_decode_trace(const char *buf, int *index, erlang_trace *p);
+int ei_decode_tuple_header(const char *buf, int *index, int *arity);
+int ei_decode_list_header(const char *buf, int *index, int *arity);
+
+/*
+ * ei_decode_ei_term() returns 1 if term is decoded, 0 if term is OK,
+ * but not decoded here and -1 if something is wrong. ONLY changes
+ * index if term is decoded (return value 1)!
+ */
+
+int ei_decode_ei_term(const char* buf, int* index, ei_term* term);
+
+
+/*
+ * ei_print_term to print out a binary coded term
+ */
+
+int ei_print_term(FILE *fp, const char* buf, int* index);
+int ei_s_print_term(char** s, const char* buf, int* index);
+
+/*
+ * format to build binary format terms a bit like printf
+ */
+
+int ei_x_format(ei_x_buff* x, const char* fmt, ...);
+int ei_x_format_wo_ver(ei_x_buff* x, const char *fmt, ...);
+
+int ei_x_new(ei_x_buff* x);
+int ei_x_new_with_version(ei_x_buff* x);
+int ei_x_free(ei_x_buff* x);
+int ei_x_append(ei_x_buff* x, const ei_x_buff* x2);
+int ei_x_append_buf(ei_x_buff* x, const char* buf, int len);
+int ei_skip_term(const char* buf, int* index);
+
+/***************************************************************************
+ *
+ * Hash types needed by registry types
+ *
+ ***************************************************************************/
+
+#define EI_SMALLKEY 32
+
+typedef struct bucket_s {
+ int rawhash;
+ const char *key;
+ char keybuf[EI_SMALLKEY];
+ const void *value;
+ struct bucket_s *next;
+} ei_bucket;
+
+/* users of the package declare variables as pointers to this. */
+typedef struct {
+ ei_bucket **tab;
+ int (*hash)(const char *); /* hash function for this table */
+ int size; /* size of table */
+ int nelem; /* nr elements */
+ int npos; /* nr occupied positions */
+ ei_bucket *freelist; /* reuseable freed buckets */
+} ei_hash;
+
+
+/***************************************************************************
+ *
+ * Registry defines, types, functions
+ *
+ ***************************************************************************/
+
+/* -------------------------------------------------------------------- */
+/* XXXXXXXXXXX */
+/* -------------------------------------------------------------------- */
+
+/* registry object attributes */
+#define EI_DIRTY 0x01 /* dirty bit (object value differs from backup) */
+#define EI_DELET 0x02 /* object is deleted */
+#define EI_INT 0x10 /* object is an integer */
+#define EI_FLT 0x20 /* object is a float */
+#define EI_STR 0x40 /* object is a string */
+#define EI_BIN 0x80 /* object is a binary, i.e. pointer to arbitrary type */
+
+
+/* -------------------------------------------------------------------- */
+/* XXXXXXXXXXX */
+/* -------------------------------------------------------------------- */
+
+typedef struct ei_reg_inode {
+ int attr;
+ int size;
+ union {
+ long i;
+ double f;
+ char *s;
+ void *p;
+ } val;
+ struct ei_reg_inode *next;
+} ei_reg_obj;
+
+typedef struct {
+ ei_reg_obj *freelist;
+ ei_hash *tab;
+} ei_reg;
+
+struct ei_reg_stat {
+ int attr; /* object attributes (see above) */
+ int size; /* size in bytes (for STR and BIN) 0 for others */
+};
+
+struct ei_reg_tabstat {
+ int size; /* size of table */
+ int nelem; /* number of stored elements */
+ int npos; /* number of occupied positions */
+ int collisions; /* number of positions with more than one element */
+};
+
+
+/* -------------------------------------------------------------------- */
+/* XXXXXXXXXXX */
+/* -------------------------------------------------------------------- */
+
+/* FIXME move comments to source */
+
+/* open / close registry. On open, a descriptor is returned that must
+ * be specified in all subsequent calls to registry functions. You can
+ * open as many registries as you like.
+ */
+ei_reg *ei_reg_open(int size);
+int ei_reg_resize(ei_reg *oldreg, int newsize);
+int ei_reg_close(ei_reg *reg);
+
+/* set values... these routines assign values to keys. If the key
+ * exists, the previous value is discarded and the new one replaces
+ * it.
+ *
+ * BIN objects require an additional argument indicating the size in
+ * bytes of the stored object. This will be used when the object is
+ * backed up, since it will need to be copied at that time. Remember
+ * also that pointers are process-space specific and it is not
+ * meaningful to back them up for later recall. If you are storing
+ * binary objects for backup, make sure that they are self-contained
+ * (without references to other objects).
+ *
+ * On success the function returns 0, otherwise a value
+ * indicating the reason for failure will be returned.
+ */
+int ei_reg_setival(ei_reg *reg, const char *key, long i);
+int ei_reg_setfval(ei_reg *reg, const char *key, double f);
+int ei_reg_setsval(ei_reg *reg, const char *key, const char *s);
+int ei_reg_setpval(ei_reg *reg, const char *key, const void *p, int size);
+
+/* general set function (specifiy type via flags)
+ * optional arguments are as for equivalent type-specific function,
+ * i.e.:
+ * ei_reg_setval(fd, path, EI_INT, int i);
+ * ei_reg_setval(fd, path, EI_FLT, float f);
+ * ei_reg_setval(fd, path, EI_STR, const char *s);
+ * ei_reg_setval(fd, path, EI_BIN, const void *p, int size);
+ */
+int ei_reg_setval(ei_reg *reg, const char *key, int flags, ...);
+
+/* get value of specific type object */
+/* warning: it may be difficult to detect errors when using these
+ * functions, since the error values are returned "in band"
+ */
+long ei_reg_getival(ei_reg *reg, const char *key);
+double ei_reg_getfval(ei_reg *reg, const char *key);
+const char *ei_reg_getsval(ei_reg *reg, const char *key);
+const void *ei_reg_getpval(ei_reg *reg, const char *key, int *size);
+
+/* get value of any type object (must specify)
+ * Retrieve a value from an object. The type of value expected and a
+ * pointer to a large enough buffer must be provided. flags must be
+ * set to the appropriate type (see type constants above) and the
+ * object type must match. If (flags == 0) the pointer is *assumed* to
+ * be of the correct type for the object. In any case, the actual
+ * object type is always returned on success.
+ *
+ * The argument following flags must be one of int*, double*, const
+ * char** and const void**.
+ *
+ * for BIN objects an int* is needed to return the size of the object, i.e.
+ * int ei_reg_getval(ei_reg *reg, const char *path, int flags, void **p, int *size);
+ */
+int ei_reg_getval(ei_reg *reg, const char *key, int flags, ...);
+
+/* mark the object as dirty. Normally this operation will not be
+ * necessary, as it is done automatically by all of the above 'set'
+ * functions. However, if you modify the contents of an object pointed
+ * to by a STR or BIN object, then the registry will not be aware of
+ * the change. As a result, the object may be missed on a subsequent
+ * backup operation. Use this function to set the dirty bit on the
+ * object.
+ */
+int ei_reg_markdirty(ei_reg *reg, const char *key);
+
+/* remove objects. The value, if any, is discarded. For STR and BIN
+ * objects, the object itself is removed using free(). */
+int ei_reg_delete(ei_reg *reg, const char *key);
+
+/* get information about an object */
+int ei_reg_stat(ei_reg *reg, const char *key, struct ei_reg_stat *obuf);
+
+/* get information about table */
+int ei_reg_tabstat(ei_reg *reg, struct ei_reg_tabstat *obuf);
+
+/* dump to / restore from backup */
+/* fd is open descriptor to Erlang, mntab is Mnesia table name */
+/* flags here: */
+#define EI_FORCE 0x1 /* dump all records (not just dirty ones) */
+#define EI_NOPURGE 0x2 /* don't purge deleted records */
+int ei_reg_dump(int fd, ei_reg *reg, const char *mntab, int flags);
+int ei_reg_restore(int fd, ei_reg *reg, const char *mntab);
+int ei_reg_purge(ei_reg *reg);
+
+
+/* -------------------------------------------------------------------- */
+/* Encoding/decoding bugnums to GNU MP format */
+/* -------------------------------------------------------------------- */
+
+/* If the user included <gmp.h> we supply some more functions */
+
+#if defined(__GNU_MP_VERSION) \
+ && __GNU_MP_VERSION == 4 && __GNU_MP_VERSION_MINOR >= 1
+
+int ei_decode_bignum(const char *buf, int *index, mpz_t obj);
+int ei_encode_bignum(char *buf, int *index, mpz_t obj);
+int ei_x_encode_bignum(ei_x_buff *x, mpz_t obj);
+
+#endif /* __GNU_MP_VERSION */
+
+/* -------------------------------------------------------------------- */
+/* Function definitions not documented FIXME */
+/* -------------------------------------------------------------------- */
+
+/* FIXME replace this primitive type size code */
+
+#ifdef __WIN32__
+#define EI_LONGLONG __int64
+#define EI_ULONGLONG unsigned __int64
+#else
+#ifndef VXWORKS
+#define EI_LONGLONG long long
+#define EI_ULONGLONG unsigned long long
+#endif
+#endif
+
+#ifndef VXWORKS
+int ei_decode_longlong(const char *buf, int *index, EI_LONGLONG *p);
+int ei_decode_ulonglong(const char *buf, int *index, EI_ULONGLONG *p);
+int ei_encode_longlong(char *buf, int *index, EI_LONGLONG p);
+int ei_encode_ulonglong(char *buf, int *index, EI_ULONGLONG p);
+int ei_x_encode_longlong(ei_x_buff* x, EI_LONGLONG n);
+int ei_x_encode_ulonglong(ei_x_buff* x, EI_ULONGLONG n);
+#endif
+
+#ifdef USE_EI_UNDOCUMENTED
+
+/*
+ * Decode a list of integers into an integer array (i.e. even if it is
+ * encoded as a string). count gets number of items in array.
+ * See "decode_intlist.c".
+ */
+
+int ei_decode_intlist(const char *buf, int *index, long *a, int *count);
+
+/*
+ * FIXME: used in IC, document?
+ * bufp = address of pointer to dynamically allocated buffer - may be reallocated by
+ * this function if it is too small for the message
+ * bufsz = in/out value: in=user buffer size, out=new buffer size
+ * msglen = nr bytes in received message
+ */
+int ei_receive_encoded(int fd, char **bufp, int *bufsz, erlang_msg *to,
+ int *msglen);
+int ei_receive_encoded_tmo(int fd, char **bufp, int *bufsz, erlang_msg *to,
+ int *msglen, unsigned ms);
+int ei_send_encoded(int fd, const erlang_pid *to, char *msg, int msglen);
+int ei_send_encoded_tmo(int fd, const erlang_pid *to, char *msg, int msglen,
+ unsigned ms);
+int ei_send_reg_encoded(int fd, const erlang_pid *from, const char *to,
+ char *msg, int msglen);
+int ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to,
+ char *msg, int msglen, unsigned ms);
+
+/*
+ * Bacward compatibility with old undocumented but used interface...
+ * FIXME use wrapper function instead?!
+ */
+#define ei_send_encoded_timeout(Fd,To,Msg,MsgLen,Ms) \
+ ei_send_encoded_tmo((Fd),(To),(Msg),(MsgLen),(Ms))
+#define ei_send_reg_encoded_timeout(Fd,From,To,Msg,MsgLen,Ms) \
+ ei_send_reg_encoded_tmo((Fd),(From),(To),(Msg),(MsgLen),(Ms))
+
+
+/* FIXME: is this really the best way to handle bignums? */
+int ei_encode_big(char *buf, int *index, erlang_big* big);
+int ei_x_encode_big(ei_x_buff* x, erlang_big* big);
+int ei_decode_big(const char *buf, int *index, erlang_big* p);
+int ei_big_comp(erlang_big *x, erlang_big *y);
+int ei_big_to_double(erlang_big *b, double *resp);
+int ei_small_to_big(int s, erlang_big *b);
+erlang_big *ei_alloc_big(unsigned int arity);
+void ei_free_big(erlang_big *b);
+
+#endif /* USE_EI_UNDOCUMENTED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EI_H */