aboutsummaryrefslogtreecommitdiffstats
path: root/lib/erl_interface/include
diff options
context:
space:
mode:
Diffstat (limited to 'lib/erl_interface/include')
-rw-r--r--lib/erl_interface/include/ei.h785
-rw-r--r--lib/erl_interface/include/ei_connect.h26
-rw-r--r--lib/erl_interface/include/eicode.h26
-rw-r--r--lib/erl_interface/include/erl_interface.h449
4 files changed, 1286 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 */
diff --git a/lib/erl_interface/include/ei_connect.h b/lib/erl_interface/include/ei_connect.h
new file mode 100644
index 0000000000..02880e197c
--- /dev/null
+++ b/lib/erl_interface/include/ei_connect.h
@@ -0,0 +1,26 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2003-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_CONNECT_H
+#define EI_CONNECT_H
+
+/* Dummy for now.... */
+
+#include "ei.h"
+
+#endif /* EI_CONNECT_H */
diff --git a/lib/erl_interface/include/eicode.h b/lib/erl_interface/include/eicode.h
new file mode 100644
index 0000000000..c35489e890
--- /dev/null
+++ b/lib/erl_interface/include/eicode.h
@@ -0,0 +1,26 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2003-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 EICODE_H
+#define EICODE_H
+
+/* Dummy for now.... */
+
+#include "ei.h"
+
+#endif /* EICODE_H */
diff --git a/lib/erl_interface/include/erl_interface.h b/lib/erl_interface/include/erl_interface.h
new file mode 100644
index 0000000000..1c4a94700d
--- /dev/null
+++ b/lib/erl_interface/include/erl_interface.h
@@ -0,0 +1,449 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1996-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 _ERL_INTERFACE_H
+#define _ERL_INTERFACE_H
+
+/************************************************************************/
+/* This file defines the complete interface to erl_interface */
+/* Note: the 'ei' interface is the prefered C API. */
+/************************************************************************/
+
+/* FIXME only include if needed? */
+
+#include "ei.h" /* ei is the base */
+
+/* -------------------------------------------------------------------- */
+/* Public defines */
+/* -------------------------------------------------------------------- */
+
+#define ERL_COMPOUND (1 << 7)
+
+#define ERL_UNDEF 0
+#define ERL_INTEGER 1
+#define ERL_U_INTEGER 2 /* unsigned int */
+#define ERL_ATOM 3
+#define ERL_PID 4
+#define ERL_PORT 5
+#define ERL_REF 6
+#define ERL_CONS (7 | ERL_COMPOUND)
+#define ERL_LIST ERL_CONS
+#define ERL_NIL 8
+#define ERL_EMPTY_LIST ERL_NIL
+#define ERL_TUPLE (9 | ERL_COMPOUND)
+#define ERL_BINARY 10
+#define ERL_FLOAT 11
+#define ERL_VARIABLE (12 | ERL_COMPOUND) /* used in patterns */
+#define ERL_SMALL_BIG 13
+#define ERL_U_SMALL_BIG 14
+#define ERL_FUNCTION (15 | ERL_COMPOUND)
+#define ERL_BIG 16
+#define ERL_LONGLONG 17
+#define ERL_U_LONGLONG 18
+
+
+#define ERL_TYPE(x) (ERL_HEADER(x)->type)
+
+/* FIXME some macros left in erl_eterm.h should probably be documented */
+
+#define ERL_IS_INTEGER(x) (ERL_TYPE(x) == ERL_INTEGER)
+#define ERL_IS_UNSIGNED_INTEGER(x) (ERL_TYPE(x) == ERL_U_INTEGER)
+#define ERL_IS_LONGLONG(x) (ERL_TYPE(x) == ERL_LONGLONG)
+#define ERL_IS_UNSIGNED_LONGLONG(x) (ERL_TYPE(x) == ERL_U_LONGLONG)
+#define ERL_IS_FLOAT(x) (ERL_TYPE(x) == ERL_FLOAT)
+#define ERL_IS_ATOM(x) (ERL_TYPE(x) == ERL_ATOM)
+#define ERL_IS_PID(x) (ERL_TYPE(x) == ERL_PID)
+#define ERL_IS_PORT(x) (ERL_TYPE(x) == ERL_PORT)
+#define ERL_IS_REF(x) (ERL_TYPE(x) == ERL_REF)
+#define ERL_IS_TUPLE(x) (ERL_TYPE(x) == ERL_TUPLE)
+#define ERL_IS_BINARY(x) (ERL_TYPE(x) == ERL_BINARY)
+#define ERL_IS_NIL(x) (ERL_TYPE(x) == ERL_NIL)
+#define ERL_IS_EMPTY_LIST(x) ERL_IS_NIL(x)
+#define ERL_IS_CONS(x) (ERL_TYPE(x) == ERL_CONS)
+#define ERL_IS_LIST(x) (ERL_IS_CONS(x) || ERL_IS_EMPTY_LIST(x))
+
+/*
+ * Macros used for XXXX
+ */
+
+#define ERL_HEADER(x) ((Erl_Header *)x)
+#define ERL_COUNT(x) (ERL_HEADER(x)->count)
+
+/*
+ * Macros used for retrieving values from Erlang terms.
+ */
+
+#define ERL_INT_VALUE(x) ((x)->uval.ival.i)
+#define ERL_INT_UVALUE(x) ((x)->uval.uival.u)
+#define ERL_LL_VALUE(x) ((x)->uval.llval.i)
+#define ERL_LL_UVALUE(x) ((x)->uval.ullval.u)
+
+#define ERL_FLOAT_VALUE(x) ((x)->uval.fval.f)
+
+#define ERL_ATOM_PTR(x) ((x)->uval.aval.a)
+#define ERL_ATOM_SIZE(x) ((x)->uval.aval.len)
+
+#define ERL_PID_NODE(x) ((x)->uval.pidval.node)
+#define ERL_PID_NUMBER(x) ((x)->uval.pidval.number)
+#define ERL_PID_SERIAL(x) ((x)->uval.pidval.serial)
+#define ERL_PID_CREATION(x) ((x)->uval.pidval.creation)
+
+#define ERL_PORT_NODE(x) ((x)->uval.portval.node)
+#define ERL_PORT_NUMBER(x) ((x)->uval.portval.number)
+#define ERL_PORT_CREATION(x) ((x)->uval.portval.creation)
+
+#define ERL_REF_NODE(x) ((x)->uval.refval.node)
+#define ERL_REF_NUMBER(x) ((x)->uval.refval.n[0])
+#define ERL_REF_NUMBERS(x) ((x)->uval.refval.n)
+#define ERL_REF_LEN(x) ((x)->uval.refval.len)
+#define ERL_REF_CREATION(x) ((x)->uval.refval.creation)
+
+#define ERL_TUPLE_SIZE(x) ((x)->uval.tval.size)
+
+/* NOTE!!! This is 0-based!! (first item is number 0)
+ * Note too that element/2 (in Erlang) and
+ * erl_element() are both 1-based.
+ */
+#define ERL_TUPLE_ELEMS(x) ((x)->uval.tval.elems)
+#define ERL_TUPLE_ELEMENT(x, i) (ERL_TUPLE_ELEMS(x)[(i)])
+
+#define ERL_BIN_SIZE(x) ((x)->uval.bval.size)
+#define ERL_BIN_PTR(x) ((x)->uval.bval.b)
+
+#define ERL_CONS_HEAD(x) ((x)->uval.lval.head)
+#define ERL_CONS_TAIL(x) ((x)->uval.lval.tail)
+
+#define ERL_VAR_LEN(x) ((x)->uval.vval.len)
+#define ERL_VAR_NAME(x) ((x)->uval.vval.name)
+#define ERL_VAR_VALUE(x) ((x)->uval.vval.v)
+
+#define ERL_CLOSURE_SIZE(x) ((x)->uval.funcval.size)
+#define ERL_FUN_CREATOR(x) ((x)->uval.funcval.creator)
+#define ERL_FUN_MODULE(x) ((x)->uval.funcval.module)
+#define ERL_FUN_UNIQ(x) ((x)->uval.funcval.uniq)
+#define ERL_FUN_INDEX(x) ((x)->uval.funcval.index)
+#define ERL_FUN_ARITY(x) ((x)->uval.funcval.arity)
+#define ERL_FUN_NEW_INDEX(x) ((x)->uval.funcval.new_index)
+#define ERL_FUN_MD5(x) ((x)->uval.funcval.md5)
+#define ERL_CLOSURE(x) ((x)->uval.funcval.closure)
+#define ERL_CLOSURE_ELEMENT(x,i) (ERL_CLOSURE(x)[(i)])
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* -------------------------------------------------------------------- */
+/* Type definitions of Erlang terms in C */
+/* -------------------------------------------------------------------- */
+
+typedef struct {
+ unsigned int count:24; /* reference counter */
+ unsigned int type:8; /* type of Erlang term */
+} Erl_Header;
+
+typedef struct {
+ Erl_Header h;
+ int i;
+} Erl_Integer;
+
+typedef struct {
+ Erl_Header h;
+ unsigned int u;
+} Erl_Uinteger;
+
+typedef struct {
+ Erl_Header h;
+ long long i;
+} Erl_LLInteger;
+
+typedef struct {
+ Erl_Header h;
+ unsigned long long u;
+} Erl_ULLInteger;
+
+typedef struct {
+ Erl_Header h;
+ double f;
+} Erl_Float;
+
+typedef struct {
+ Erl_Header h;
+ int len;
+ char *a;
+} Erl_Atom;
+
+typedef struct {
+ Erl_Header h;
+ char * node;
+ unsigned int number;
+ unsigned int serial;
+ unsigned char creation;
+} Erl_Pid;
+
+typedef struct {
+ Erl_Header h;
+ char * node;
+ unsigned int number;
+ unsigned char creation;
+} Erl_Port;
+
+typedef struct {
+ Erl_Header h;
+ char * node;
+ int len;
+ unsigned int n[3];
+ unsigned char creation;
+} Erl_Ref;
+
+typedef struct {
+ Erl_Header h;
+ int arity;
+ int is_neg;
+ unsigned short *digits;
+} Erl_Big;
+
+struct _eterm; /* forward */
+
+typedef struct {
+ Erl_Header h;
+ struct _eterm *head;
+ struct _eterm *tail;
+} Erl_List;
+
+typedef struct {
+ Erl_Header h;
+} Erl_EmptyList;
+
+typedef struct {
+ Erl_Header h;
+ int size;
+ struct _eterm **elems;
+} Erl_Tuple;
+
+typedef struct {
+ Erl_Header h;
+ int size;
+ unsigned char *b;
+} Erl_Binary;
+
+/* Variables may only exist in patterns.
+ * Note: identical variable names in a pattern
+ * denotes the same value.
+ */
+typedef struct {
+ Erl_Header h;
+ int len;
+ char *name;
+ struct _eterm *v;
+} Erl_Variable;
+
+
+typedef struct {
+ Erl_Header h;
+ int size; /* size of closure */
+ int arity; /* arity for new (post R7) external funs */
+ unsigned char md5[16]; /* md5 for new funs */
+ int new_index; /* new funs */
+ struct _eterm* creator; /* pid */
+ struct _eterm* module; /* module */
+ struct _eterm* index;
+ struct _eterm* uniq;
+ struct _eterm** closure;
+} Erl_Function;
+
+typedef struct _eterm {
+ union {
+ Erl_Integer ival;
+ Erl_Uinteger uival;
+ Erl_LLInteger llval;
+ Erl_ULLInteger ullval;
+ Erl_Float fval;
+ Erl_Atom aval;
+ Erl_Pid pidval;
+ Erl_Port portval;
+ Erl_Ref refval;
+ Erl_List lval;
+ Erl_EmptyList nval;
+ Erl_Tuple tval;
+ Erl_Binary bval;
+ Erl_Variable vval;
+ Erl_Function funcval;
+ Erl_Big bigval;
+ } uval;
+} ETERM;
+
+
+#define MAXREGLEN 255 /* max length of registered (atom) name */
+
+typedef struct {
+ int type; /* one of the message type constants in eiext.h */
+ ETERM *msg; /* the actual message */
+ ETERM *from;
+ ETERM *to;
+ char to_name[MAXREGLEN+1];
+} ErlMessage;
+
+typedef unsigned char Erl_Heap;
+
+
+/* -------------------------------------------------------------------- */
+/* The functions */
+/* -------------------------------------------------------------------- */
+
+void erl_init(void *x, long y);
+void erl_set_compat_rel(unsigned);
+int erl_connect_init(int, char*,short);
+int erl_connect_xinit(char*,char*,char*,struct in_addr*,char*,short);
+int erl_connect(char*);
+int erl_xconnect(struct in_addr*,char *);
+int erl_close_connection(int);
+int erl_receive(int, unsigned char*, int);
+int erl_receive_msg(int, unsigned char*, int, ErlMessage*);
+int erl_xreceive_msg(int, unsigned char**, int*, ErlMessage*);
+int erl_send(int, ETERM*, ETERM*);
+int erl_reg_send(int, char*, ETERM*);
+ETERM *erl_rpc(int,char*,char*,ETERM*);
+int erl_rpc_to(int,char*,char*,ETERM*);
+int erl_rpc_from(int,int,ErlMessage*);
+
+/* erl_publish returns open descriptor on success, or -1 */
+int erl_publish(int port);
+int erl_accept(int,ErlConnect*);
+
+const char *erl_thiscookie(void);
+const char *erl_thisnodename(void);
+const char *erl_thishostname(void);
+const char *erl_thisalivename(void);
+short erl_thiscreation(void);
+
+/* returns 0 on success, -1 if node not known to epmd or epmd not reached */
+int erl_unpublish(const char *alive);
+
+/* Report generic error to stderr. */
+void erl_err_msg(const char * __template, ...)
+ __attribute__ ((__format__ (printf, 1, 2)));
+/* Report generic error to stderr and die. */
+void erl_err_quit(const char * __template, ...)
+ __attribute__ ((__format__ (printf, 1, 2), __noreturn__));
+/* Report system/libc error to stderr. */
+void erl_err_ret(const char * __template, ...)
+ __attribute__ ((__format__ (printf, 1, 2)));
+/* Report system/libc error to stderr and die. */
+void erl_err_sys(const char * __template, ...)
+ __attribute__ ((__format__ (printf, 1, 2), __noreturn__));
+
+ETERM *erl_cons(ETERM*,ETERM*);
+ETERM *erl_copy_term(const ETERM*);
+ETERM *erl_element(int,const ETERM*);
+
+ETERM *erl_hd(const ETERM*);
+ETERM* erl_iolist_to_binary(const ETERM* term);
+char* erl_iolist_to_string(const ETERM* term);
+int erl_iolist_length(const ETERM*);
+int erl_length(const ETERM*);
+ETERM *erl_mk_atom(const char*);
+ETERM *erl_mk_binary(const char*,int);
+ETERM *erl_mk_empty_list(void);
+ETERM *erl_mk_estring(const char*, int);
+ETERM *erl_mk_float(double);
+ETERM *erl_mk_int(int);
+ETERM *erl_mk_longlong(long long);
+ETERM *erl_mk_list(ETERM**,int);
+ETERM *erl_mk_pid(const char*,unsigned int,unsigned int,unsigned char);
+ETERM *erl_mk_port(const char*,unsigned int,unsigned char);
+ETERM *erl_mk_ref(const char*,unsigned int,unsigned char);
+ETERM *erl_mk_long_ref(const char*,unsigned int,unsigned int,
+ unsigned int,unsigned char);
+ETERM *erl_mk_string(const char*);
+ETERM *erl_mk_tuple(ETERM**,int);
+ETERM *erl_mk_uint(unsigned int);
+ETERM *erl_mk_ulonglong(unsigned long long);
+ETERM *erl_mk_var(const char*);
+int erl_print_term(FILE*,const ETERM*);
+/* int erl_sprint_term(char*,const ETERM*); */
+int erl_size(const ETERM*);
+ETERM *erl_tl(const ETERM*);
+ETERM *erl_var_content(const ETERM*, const char*);
+
+ETERM *erl_format(char*, ... );
+int erl_match(ETERM*, ETERM*);
+
+char **erl_global_names(int fd, int *count);
+int erl_global_register(int fd, const char *name, ETERM *pid);
+int erl_global_unregister(int fd, const char *name);
+ETERM *erl_global_whereis(int fd, const char *name, char *node);
+
+void erl_init_malloc(Erl_Heap*,long);
+ETERM *erl_alloc_eterm(unsigned char);
+void erl_eterm_release(void);
+void erl_eterm_statistics(unsigned long*,unsigned long*);
+void erl_free_array(ETERM**,int);
+void erl_free_term(ETERM*);
+void erl_free_compound(ETERM*);
+void *erl_malloc(long);
+void erl_free(void*);
+
+int erl_compare_ext(unsigned char*, unsigned char*);
+ETERM *erl_decode(unsigned char*);
+ETERM *erl_decode_buf(unsigned char**);
+int erl_encode(ETERM*,unsigned char*t);
+int erl_encode_buf(ETERM*,unsigned char**);
+int erl_ext_size(unsigned char*);
+unsigned char erl_ext_type(unsigned char*); /* Note: returned 'char' before R9C */
+unsigned char *erl_peek_ext(unsigned char*,int);
+int erl_term_len(ETERM*);
+
+
+/* -------------------------------------------------------------------- */
+/* Wrappers around ei functions */
+/* -------------------------------------------------------------------- */
+
+/*
+ * Undocumented before R9C, included for compatibility with old code
+ */
+
+struct hostent *erl_gethostbyname(const char *name);
+struct hostent *erl_gethostbyaddr(const char *addr, int len, int type);
+struct hostent *erl_gethostbyname_r(const char *name,
+ struct hostent *hostp,
+ char *buffer,
+ int buflen,
+ int *h_errnop);
+struct hostent *erl_gethostbyaddr_r(const char *addr,
+ int length,
+ int type,
+ struct hostent *hostp,
+ char *buffer,
+ int buflen,
+ int *h_errnop);
+
+/*
+ * Undocumented, included for compatibility with old code
+ */
+
+void erl_init_resolve(void);
+int erl_distversion(int fd);
+int erl_epmd_connect(struct in_addr *inaddr);
+int erl_epmd_port(struct in_addr *inaddr, const char *alive, int *dist);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif