1 /*
2  * %CopyrightBegin%
3  *
4  * Copyright Ericsson AB 1998-2020. All Rights Reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * %CopyrightEnd%
19  */
20 #ifndef EI_H
21 #define EI_H
22 
23 #define EI_HAVE_TIMEOUT 1	/* Flag to user code that we have them */
24 #define USE_EI_UNDOCUMENTED     /* Want declarations for undocumented */
25 
26 /************************************************************************/
27 /*          This file defines the complete interface to ei              */
28 /************************************************************************/
29 
30 /* -------------------------------------------------------------------- */
31 /*                   Include types needed below                         */
32 /* -------------------------------------------------------------------- */
33 
34 #if defined(__WIN32__)
35 #include <winsock2.h>
36 #include <windows.h>
37 #include <winbase.h>
38 typedef LONG_PTR ssize_t; /* Sigh... */
39 #else
40 #include <sys/types.h>          /* ssize_t */
41 #endif
42 
43 #include <stdio.h>		/* Need type FILE */
44 #include <errno.h>		/* Need EHOSTUNREACH, ENOMEM, ... */
45 
46 #if !(defined(__WIN32__) || defined(_WIN32))
47 # include <netdb.h>
48 #endif
49 
50 #ifdef __has_attribute
51 #if __has_attribute(deprecated)
52 #define EI_HAVE_DEPRECATED_ATTR__ 1
53 #else
54 #undef EI_HAVE_DEPRECATED_ATTR__
55 #endif
56 #endif
57 
58 #ifdef EI_NO_DEPR_WARN
59 #undef EI_HAVE_DEPRECATED_ATTR__
60 #endif
61 
62 #ifdef EI_HAVE_DEPRECATED_ATTR__
63 #define EI_DEPRECATED_ATTR_NAME deprecated
64 #define EI_DEPRECATED_ATTR __attribute__((EI_DEPRECATED_ATTR_NAME))
65 #else
66 #define EI_DEPRECATED_ATTR_NAME
67 #define EI_DEPRECATED_ATTR
68 #endif
69 
70 /* -------------------------------------------------------------------- */
71 /*                      Defines part of API                             */
72 /* -------------------------------------------------------------------- */
73 
74 /*
75  * Some error codes might be missing, so here's a backstop definitions
76  * of the ones we use with `erl_errno':
77  */
78 
79 #ifndef EMSGSIZE		/* Message too long */
80 #define EMSGSIZE        EIO
81 #endif
82 
83 #ifndef ETIMEDOUT		/* Connection timed out */
84 #define ETIMEDOUT       EIO
85 #endif
86 
87 #ifndef EHOSTUNREACH		/* No route to host */
88 #define EHOSTUNREACH    EIO
89 #endif
90 
91 /* FIXME just a few are documented, does it mean they can't be returned? */
92 
93 #define ERL_ERROR -1           /* Error of some kind */
94 #define ERL_NO_DAEMON -2       /* No contact with EPMD */
95 #define ERL_NO_PORT -3         /* No port received from EPMD */
96 #define ERL_CONNECT_FAIL -4    /* Connect to Erlang Node failed */
97 #define ERL_TIMEOUT -5         /* A timeout has expired */
98 #define ERL_NO_REMOTE -6       /* Cannot execute rsh */
99 
100 #define ERL_TICK 0
101 #define ERL_MSG 1
102 
103 #define ERL_NO_TIMEOUT -1
104 
105 /* these are the control message types */
106 #define ERL_LINK           1
107 #define ERL_SEND           2
108 #define ERL_EXIT           3
109 #define ERL_UNLINK         4
110 #define ERL_NODE_LINK      5
111 #define ERL_REG_SEND       6
112 #define ERL_GROUP_LEADER   7
113 #define ERL_EXIT2          8
114 #define ERL_PASS_THROUGH  'p'
115 
116 /* new ones for tracing, from Kenneth */
117 #define ERL_SEND_TT        12
118 #define ERL_EXIT_TT        13
119 #define ERL_REG_SEND_TT    16
120 #define ERL_EXIT2_TT       18
121 #define ERL_MONITOR_P      19
122 #define ERL_DEMONITOR_P    20
123 #define ERL_MONITOR_P_EXIT 21
124 
125 /* For ei_xrpc_to */
126 #define EI_RPC_FETCH_STDOUT 1
127 /* -------------------------------------------------------------------- */
128 /*           Defines used for ei_get_type_internal() output             */
129 /* -------------------------------------------------------------------- */
130 /*
131  * these are the term type indicators used in
132  * the external (distribution) format
133  */
134 
135 /* FIXME we don't want to export these..... */
136 
137 #define ERL_SMALL_INTEGER_EXT 'a'
138 #define ERL_INTEGER_EXT       'b'
139 #define ERL_FLOAT_EXT         'c'
140 #define NEW_FLOAT_EXT         'F'
141 #define ERL_ATOM_EXT          'd'
142 #define ERL_SMALL_ATOM_EXT    's'
143 #define ERL_ATOM_UTF8_EXT     'v'
144 #define ERL_SMALL_ATOM_UTF8_EXT 'w'
145 #define ERL_REFERENCE_EXT     'e'
146 #define ERL_NEW_REFERENCE_EXT 'r'
147 #define ERL_NEWER_REFERENCE_EXT 'Z'
148 #define ERL_PORT_EXT          'f'
149 #define ERL_NEW_PORT_EXT      'Y'
150 #define ERL_PID_EXT           'g'
151 #define ERL_NEW_PID_EXT       'X'
152 #define ERL_SMALL_TUPLE_EXT   'h'
153 #define ERL_LARGE_TUPLE_EXT   'i'
154 #define ERL_NIL_EXT           'j'
155 #define ERL_STRING_EXT        'k'
156 #define ERL_LIST_EXT          'l'
157 #define ERL_BINARY_EXT        'm'
158 #define ERL_BIT_BINARY_EXT    'M'
159 #define ERL_SMALL_BIG_EXT     'n'
160 #define ERL_LARGE_BIG_EXT     'o'
161 #define ERL_NEW_FUN_EXT	      'p'
162 #define ERL_MAP_EXT           't'
163 #define ERL_FUN_EXT	      'u'
164 #define ERL_EXPORT_EXT        'q'
165 #define ERL_V4_PORT_EXT       'x'
166 
167 
168 #define ERL_NEW_CACHE         'N' /* c nodes don't know these two */
169 #define ERL_CACHED_ATOM       'C'
170 
171 
172 /* -------------------------------------------------------------------- */
173 /*                     Define the erl_errno macro                       */
174 /* -------------------------------------------------------------------- */
175 
176 #ifdef __cplusplus
177 extern "C" {
178 #endif
179 
180 /*
181  * GCC's attributes are too useful to not use. Other compilers
182  * just lose opportunities to optimize and warn.
183  */
184 #if !defined(__GNUC__) || __GNUC__ < 2
185 # define __attribute__(foo) /* nothing */
186 #endif
187 
188 /*
189  * Define the 'erl_errno' facility. Unfortunately this lives on in
190  * the 'ei' interface as well.... :-(
191  */
192 
193 #if defined(_REENTRANT) || defined(__WIN32__)
194 
195 /* 'erl_errno' as a function return value */
196 volatile int* __erl_errno_place(void) __attribute__ ((__const__));
197 
198 #define erl_errno (*__erl_errno_place ())
199 
200 #else /* !_REENTRANT && !__WIN32__ */
201 
202 extern volatile int __erl_errno;
203 
204 #define erl_errno __erl_errno
205 
206 #endif /* !_REENTRANT && !__WIN32__ */
207 
208 
209 /* -------------------------------------------------------------------- */
210 /*                      Type definitions                                */
211 /* -------------------------------------------------------------------- */
212 
213 #ifdef __WIN32__
214 #define EI_LONGLONG __int64
215 #define EI_ULONGLONG unsigned __int64
216 #else
217 #define EI_LONGLONG long long
218 #define EI_ULONGLONG unsigned long long
219 #endif
220 
221 /*
222  * To avoid confusion about the MAXHOSTNAMELEN when compiling the
223  * library and when using the library we set a value that we use
224  */
225 
226 #define EI_MAX_COOKIE_SIZE 512
227 #define MAXATOMLEN (255 + 1)
228 #define MAXATOMLEN_UTF8 (255*4 + 1)
229 #define EI_MAXHOSTNAMELEN (MAXATOMLEN - 2)
230 #define EI_MAXALIVELEN (MAXATOMLEN - 2)
231 #define MAXNODELEN MAXATOMLEN
232 
233 typedef enum {
234     ERLANG_ASCII = 1,
235     ERLANG_LATIN1 = 2,
236     ERLANG_UTF8 = 4
237 }erlang_char_encoding;
238 
239 /* a pid */
240 typedef struct {
241   char node[MAXATOMLEN_UTF8];
242   unsigned int num;
243   unsigned int serial;
244   unsigned int creation;
245 } erlang_pid;
246 
247 /* a port */
248 typedef struct {
249   char node[MAXATOMLEN_UTF8];
250   EI_ULONGLONG id;
251   unsigned int creation;
252 } erlang_port;
253 
254 /* a ref */
255 typedef struct {
256   char node[MAXATOMLEN_UTF8];
257   int len;
258   unsigned int n[5];
259   unsigned int creation;
260 } erlang_ref;
261 
262 /* a trace token */
263 typedef struct {
264   long serial;
265   long prev;
266   erlang_pid from;
267   long label;
268   long flags;
269 } erlang_trace;
270 
271 /* a message */
272 typedef struct {
273   long msgtype;
274   erlang_pid from;
275   erlang_pid to;
276   char toname[MAXATOMLEN_UTF8];
277   char cookie[MAXATOMLEN_UTF8];
278   erlang_trace token;
279 } erlang_msg;
280 
281 /* a fun */
282 typedef struct {
283     long arity;
284     char module[MAXATOMLEN_UTF8];
285     enum { EI_FUN_CLOSURE, EI_FUN_EXPORT } type;
286     union {
287         struct {
288             char md5[16];
289             long index;
290             long old_index;
291             long uniq;
292             long n_free_vars;
293             erlang_pid pid;
294             long free_var_len;
295             char* free_vars;
296         } closure;
297         struct {
298             char* func;
299             int func_allocated;
300         } exprt;
301     } u;
302 } erlang_fun;
303 
304 /* a big */
305 typedef struct {
306     unsigned int arity;
307     int is_neg;
308     void *digits;
309 } erlang_big;
310 
311 typedef struct {
312     char ei_type;
313     int arity;
314     int size;
315     union {
316 	long i_val;
317 	double d_val;
318 	char atom_name[MAXATOMLEN_UTF8];
319 	erlang_pid pid;
320 	erlang_port port;
321 	erlang_ref ref;
322     } value;
323 } ei_term;
324 
325 /* XXX */
326 
327 typedef struct {
328   char ipadr[4];             /* stored in network byte order */
329   char nodename[MAXNODELEN+1];
330 } ErlConnect;
331 
332 #define EI_SCLBK_INF_TMO (~((unsigned) 0))
333 
334 #define EI_SCLBK_FLG_FULL_IMPL (1 << 0)
335 
336 /*
337  * HACK: AIX defines many socket functions like accept to be naccept, which
338  * pollutes the global namespace. Set up an ugly ifdef for consumers of this
339  * API here so they get a mangled name for AIX and the sane name elsewhere.
340  */
341 #ifdef _AIX
342 #define EI_ACCEPT_NAME accept_ei
343 #else
344 #define EI_ACCEPT_NAME accept
345 #endif
346 
347 typedef struct {
348     int flags;
349 
350     int (*socket)(void **ctx, void *setup_ctx);
351     int	(*close)(void *ctx);
352     int (*listen)(void *ctx, void *addr, int *len, int backlog);
353     int (*EI_ACCEPT_NAME)(void **ctx, void *addr, int *len, unsigned tmo);
354     int (*connect)(void *ctx, void *addr, int len, unsigned tmo);
355     int (*writev)(void *ctx, const void *iov, int iovcnt, ssize_t *len, unsigned tmo);
356     int (*write)(void *ctx, const char *buf, ssize_t *len, unsigned tmo);
357     int (*read)(void *ctx, char *buf, ssize_t *len, unsigned tmo);
358 
359     int (*handshake_packet_header_size)(void *ctx, int *sz);
360     int (*connect_handshake_complete)(void *ctx);
361     int (*accept_handshake_complete)(void *ctx);
362     int (*get_fd)(void *ctx, int *fd);
363 
364     /* end of version 1 */
365 
366 } ei_socket_callbacks;
367 
368 typedef struct ei_cnode_s {
369     char thishostname[EI_MAXHOSTNAMELEN+1];
370     char thisnodename[MAXNODELEN+1];
371     char thisalivename[EI_MAXALIVELEN+1];
372 /* Currently this_ipaddr isn't used */
373 /*    struct in_addr this_ipaddr; */
374     char ei_connect_cookie[EI_MAX_COOKIE_SIZE+1];
375     unsigned int creation;
376     erlang_pid self;
377     ei_socket_callbacks *cbs;
378     void *setup_context;
379     unsigned int pidsn;
380 } ei_cnode;
381 
382 typedef struct in_addr *Erl_IpAddr;
383 
384 
385 /* A dynamic version of ei XX */
386 
387 typedef struct ei_x_buff_TAG {
388     char* buff;
389     int buffsz;
390     int index;
391 } ei_x_buff;
392 
393 /* -------------------------------------------------------------------- */
394 /*    Function definitions (listed in same order as documentation)      */
395 /* -------------------------------------------------------------------- */
396 
397 /* Handle the connection */
398 
399 int ei_connect_init(ei_cnode* ec, const char* this_node_name,
400 		    const char *cookie, short creation);
401 int ei_connect_xinit (ei_cnode* ec, const char *thishostname,
402 		      const char *thisalivename, const char *thisnodename,
403 		      Erl_IpAddr thisipaddr, const char *cookie,
404 		      const short creation);
405 
406 int ei_connect_init_ussi(ei_cnode* ec, const char* this_node_name,
407                          const char *cookie, short creation,
408                          ei_socket_callbacks *cbs, int cbs_sz,
409                          void *setup_context);
410 int ei_connect_xinit_ussi(ei_cnode* ec, const char *thishostname,
411                           const char *thisalivename, const char *thisnodename,
412                           Erl_IpAddr thisipaddr, const char *cookie,
413                           const short creation, ei_socket_callbacks *cbs,
414                           int cbs_sz, void *setup_context);
415 
416 int ei_connect(ei_cnode* ec, char *nodename);
417 int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned ms);
418 int ei_connect_host_port(ei_cnode* ec, char *hostname, int port);
419 int ei_connect_host_port_tmo(ei_cnode* ec, char *hostname, int port, unsigned ms);
420 int ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename);
421 int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned ms);
422 int ei_xconnect_host_port(ei_cnode* ec, Erl_IpAddr adr, int port);
423 int ei_xconnect_host_port_tmo(ei_cnode* ec, Erl_IpAddr adr, int port, unsigned ms);
424 
425 int ei_receive(int fd, unsigned char *bufp, int bufsize);
426 int ei_receive_tmo(int fd, unsigned char *bufp, int bufsize, unsigned ms);
427 int ei_receive_msg(int fd, erlang_msg* msg, ei_x_buff* x);
428 int ei_receive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned ms);
429 int ei_xreceive_msg(int fd, erlang_msg* msg, ei_x_buff* x);
430 int ei_xreceive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned ms);
431 
432 int ei_send(int fd, erlang_pid* to, char* buf, int len);
433 int ei_send_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned ms);
434 int ei_reg_send(ei_cnode* ec, int fd, char *server_name, char* buf, int len);
435 int ei_reg_send_tmo(ei_cnode* ec, int fd, char *server_name, char* buf, int len, unsigned ms);
436 
437 int ei_rpc(ei_cnode* ec, int fd, char *mod, char *fun,
438 	   const char* inbuf, int inbuflen, ei_x_buff* x);
439 int ei_xrpc_to(ei_cnode* ec, int fd, char *mod, char *fun,
440                const char* buf, int len, int flags);
441 int ei_rpc_to(ei_cnode* ec, int fd, char *mod, char *fun,
442 	      const char* buf, int len);
443 int ei_rpc_from(ei_cnode* ec, int fd, int timeout, erlang_msg* msg,
444 		ei_x_buff* x);
445 
446 int ei_publish(ei_cnode* ec, int port);
447 int ei_publish_tmo(ei_cnode* ec, int port, unsigned ms);
448 int ei_listen(ei_cnode *ec, int *port, int backlog);
449 int ei_xlisten(ei_cnode *ec, Erl_IpAddr adr, int *port, int backlog);
450 int ei_accept(ei_cnode* ec, int lfd, ErlConnect *conp);
451 int ei_accept_tmo(ei_cnode* ec, int lfd, ErlConnect *conp, unsigned ms);
452 int ei_unpublish(ei_cnode* ec);
453 int ei_unpublish_tmo(const char *alive, unsigned ms);
454 
455 int ei_close_connection(int fd);
456 
457 const char *ei_thisnodename(const ei_cnode* ec);
458 const char *ei_thishostname(const ei_cnode* ec);
459 const char *ei_thisalivename(const ei_cnode* ec);
460 
461 erlang_pid *ei_self(ei_cnode* ec);
462 int ei_make_pid(ei_cnode *ec, erlang_pid *pid);
463 int ei_make_ref(ei_cnode *ec, erlang_ref *ref);
464 
465 /*
466  * settings
467  */
468 
469 void ei_set_compat_rel(unsigned rel);
470 void ei_set_tracelevel(int);
471 int ei_get_tracelevel(void);
472 
473 /*
474  * We have erl_gethost*() so we include ei versions as well.
475  */
476 
477 struct hostent *ei_gethostbyname(const char *name);
478 struct hostent *ei_gethostbyaddr(const char *addr, int len, int type);
479 struct hostent *ei_gethostbyname_r(const char *name,
480 				   struct hostent *hostp,
481 				   char *buffer,
482 				   int buflen,
483 				   int *h_errnop);
484 struct hostent *ei_gethostbyaddr_r(const char *addr,
485 				   int length,
486 				   int type,
487 				   struct hostent *hostp,
488 				   char *buffer,
489 				   int buflen,
490 				   int *h_errnop);
491 
492 
493 /* Encode/decode functions */
494 
495 int ei_encode_version(char *buf, int *index);
496 int ei_x_encode_version(ei_x_buff* x);
497 int ei_encode_long(char *buf, int *index, long p);
498 int ei_x_encode_long(ei_x_buff* x, long n);
499 int ei_encode_ulong(char *buf, int *index, unsigned long p);
500 int ei_x_encode_ulong(ei_x_buff* x, unsigned long n);
501 int ei_encode_double(char *buf, int *index, double p);
502 int ei_x_encode_double(ei_x_buff* x, double dbl);
503 int ei_encode_boolean(char *buf, int *index, int p);
504 int ei_x_encode_boolean(ei_x_buff* x, int p);
505 int ei_encode_char(char *buf, int *index, char p);
506 int ei_x_encode_char(ei_x_buff* x, char p);
507 int ei_encode_string(char *buf, int *index, const char *p);
508 int ei_encode_string_len(char *buf, int *index, const char *p, int len);
509 int ei_x_encode_string(ei_x_buff* x, const char* s);
510 int ei_x_encode_string_len(ei_x_buff* x, const char* s, int len);
511 int ei_encode_atom(char *buf, int *index, const char *p);
512 int ei_encode_atom_as(char *buf, int *index, const char *p,
513 		    erlang_char_encoding from, erlang_char_encoding to);
514 int ei_encode_atom_len(char *buf, int *index, const char *p, int len);
515 int ei_encode_atom_len_as(char *buf, int *index, const char *p, int len,
516 			erlang_char_encoding from, erlang_char_encoding to);
517 int ei_x_encode_atom(ei_x_buff* x, const char* s);
518 int ei_x_encode_atom_as(ei_x_buff* x, const char* s,
519 		      erlang_char_encoding from, erlang_char_encoding to);
520 int ei_x_encode_atom_len(ei_x_buff* x, const char* s, int len);
521 int ei_x_encode_atom_len_as(ei_x_buff* x, const char* s, int len,
522 			  erlang_char_encoding from, erlang_char_encoding to);
523 int ei_encode_binary(char *buf, int *index, const void *p, long len);
524 int ei_encode_bitstring(char *buf, int *index, const char *p, size_t bitoffs, size_t bits);
525 int ei_x_encode_binary(ei_x_buff* x, const void* s, int len);
526 int ei_x_encode_bitstring(ei_x_buff* x, const char* p, size_t bitoffs, size_t bits);
527 int ei_encode_pid(char *buf, int *index, const erlang_pid *p);
528 int ei_x_encode_pid(ei_x_buff* x, const erlang_pid* pid);
529 int ei_encode_fun(char* buf, int* index, const erlang_fun* p);
530 int ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun);
531 int ei_encode_port(char *buf, int *index, const erlang_port *p);
532 int ei_x_encode_port(ei_x_buff* x, const erlang_port *p);
533 int ei_encode_ref(char *buf, int *index, const erlang_ref *p);
534 int ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p);
535 int ei_encode_trace(char *buf, int *index, const erlang_trace *p);
536 int ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p);
537 int ei_encode_tuple_header(char *buf, int *index, int arity);
538 int ei_x_encode_tuple_header(ei_x_buff* x, long n);
539 int ei_encode_list_header(char *buf, int *index, int arity);
540 int ei_x_encode_list_header(ei_x_buff* x, long n);
541 #define ei_encode_empty_list(buf,i) ei_encode_list_header(buf,i,0)
542 int ei_x_encode_empty_list(ei_x_buff* x);
543 int ei_encode_map_header(char *buf, int *index, int arity);
544 int ei_x_encode_map_header(ei_x_buff* x, long n);
545 
546 /*
547  * ei_get_type() returns the type and "size" of the item at
548  * buf[index]. For strings and atoms, size is the number of characters
549  * not including the terminating 0. For binaries, size is the number
550  * of bytes. For lists and tuples, size is the arity of the
551  * object. For other types, size is 0. In all cases, index is left
552  * unchanged.
553  */
554 
555 int ei_get_type(const char *buf, const int *index, int *type, int *size);
556 
557 /* Step through buffer, decoding the given type into the buffer
558  * provided. On success, 0 is returned and index is updated to point
559  * to the start of the next item in the buffer. If the type of item at
560  * buf[index] is not the requested type, -1 is returned and index is
561  * not updated. The buffer provided by the caller must be sufficiently
562  * large to contain the decoded object.
563  */
564 int ei_decode_version(const char *buf, int *index, int *version);
565 int ei_decode_long(const char *buf, int *index, long *p);
566 int ei_decode_ulong(const char *buf, int *index, unsigned long *p);
567 int ei_decode_double(const char *buf, int *index, double *p);
568 int ei_decode_boolean(const char *buf, int *index, int *p);
569 int ei_decode_char(const char *buf, int *index, char *p);
570 int ei_decode_string(const char *buf, int *index, char *p);
571 int ei_decode_atom(const char *buf, int *index, char *p);
572 int ei_decode_atom_as(const char *buf, int *index, char *p, int destlen, erlang_char_encoding want, erlang_char_encoding* was, erlang_char_encoding* result);
573 int ei_decode_binary(const char *buf, int *index, void *p, long *len);
574 int ei_decode_bitstring(const char *buf, int *index, const char** pp,
575                         unsigned int* bitoffsp, size_t *nbitsp);
576 
577 int ei_decode_fun(const char* buf, int* index, erlang_fun* p);
578 void free_fun(erlang_fun* f);
579 int ei_decode_pid(const char *buf, int *index, erlang_pid *p);
580 int ei_decode_port(const char *buf, int *index, erlang_port *p);
581 int ei_decode_ref(const char *buf, int *index, erlang_ref *p);
582 int ei_decode_trace(const char *buf, int *index, erlang_trace *p);
583 int ei_decode_tuple_header(const char *buf, int *index, int *arity);
584 int ei_decode_list_header(const char *buf, int *index, int *arity);
585 int ei_decode_map_header(const char *buf, int *index, int *arity);
586 int ei_decode_iodata(const char *buf, int* index, int *szp, char *out_buf);
587 
588 /*
589  * ei_decode_ei_term() returns 1 if term is decoded, 0 if term is OK,
590  * but not decoded here and -1 if something is wrong.  ONLY changes
591  * index if term is decoded (return value 1)!
592  */
593 
594 int ei_decode_ei_term(const char* buf, int* index, ei_term* term);
595 
596 
597 /*
598  * ei_print_term to print out a binary coded term
599  */
600 
601 int ei_print_term(FILE *fp, const char* buf, int* index);
602 int ei_s_print_term(char** s, const char* buf, int* index);
603 
604 /*
605  * format to build binary format terms a bit like printf
606  */
607 
608 int ei_x_format(ei_x_buff* x, const char* fmt, ...);
609 int ei_x_format_wo_ver(ei_x_buff* x, const char *fmt, ...);
610 
611 int ei_x_new(ei_x_buff* x);
612 int ei_x_new_with_version(ei_x_buff* x);
613 int ei_x_free(ei_x_buff* x);
614 int ei_x_append(ei_x_buff* x, const ei_x_buff* x2);
615 int ei_x_append_buf(ei_x_buff* x, const char* buf, int len);
616 int ei_skip_term(const char* buf, int* index);
617 
618 int ei_cmp_refs(erlang_ref *a, erlang_ref *b);
619 int ei_cmp_pids(erlang_pid *a, erlang_pid *b);
620 int ei_cmp_ports(erlang_port *a, erlang_port *b);
621 
622 /* -------------------------------------------------------------------- */
623 /* Initialize erl_interface                                             */
624 /* -------------------------------------------------------------------- */
625 
626 int ei_init(void);
627 
628 /* -------------------------------------------------------------------- */
629 /*            The ei_global functions */
630 /* -------------------------------------------------------------------- */
631 char **ei_global_names(ei_cnode *ec, int fd, int *count);
632 int ei_global_whereis(ei_cnode *ec, int fd, const char *name, erlang_pid* pid, char *node);
633 int ei_global_register(int fd, const char *name, erlang_pid *self);
634 int ei_global_unregister(ei_cnode *ec, int fd, const char *name);
635 
636 /* -------------------------------------------------------------------- */
637 /*            Encoding/decoding bugnums to GNU MP format                */
638 /* -------------------------------------------------------------------- */
639 
640 /* If the user included <gmp.h> we supply some more functions */
641 
642 #if defined(__GNU_MP_VERSION) \
643 	&& __GNU_MP_VERSION == 4 && __GNU_MP_VERSION_MINOR >= 1
644 
645 int ei_decode_bignum(const char *buf, int *index, mpz_t obj);
646 int ei_encode_bignum(char *buf, int *index, mpz_t obj);
647 int ei_x_encode_bignum(ei_x_buff *x, mpz_t obj);
648 
649 #endif /* __GNU_MP_VERSION */
650 
651 /* -------------------------------------------------------------------- */
652 /*            Function definitions not documented FIXME                 */
653 /* -------------------------------------------------------------------- */
654 
655 /* FIXME replace this primitive type size code */
656 
657 int ei_decode_longlong(const char *buf, int *index, EI_LONGLONG *p);
658 int ei_decode_ulonglong(const char *buf, int *index, EI_ULONGLONG *p);
659 int ei_encode_longlong(char *buf, int *index, EI_LONGLONG p);
660 int ei_encode_ulonglong(char *buf, int *index, EI_ULONGLONG p);
661 int ei_x_encode_longlong(ei_x_buff* x, EI_LONGLONG n);
662 int ei_x_encode_ulonglong(ei_x_buff* x, EI_ULONGLONG n);
663 
664 #ifdef USE_EI_UNDOCUMENTED
665 
666 /*
667  * Decode a list of integers into an integer array (i.e. even if it is
668  * encoded as a string). count gets number of items in array.
669  * See "decode_intlist.c".
670  */
671 
672 int ei_decode_intlist(const char *buf, int *index, long *a, int *count);
673 
674 /*
675  * FIXME: used in IC, document?
676  * bufp = address of pointer to dynamically allocated buffer - may be reallocated by
677  * this function if it is too small for the message
678  * bufsz = in/out value: in=user buffer size, out=new buffer size
679  * msglen = nr bytes in received message
680  */
681 int ei_receive_encoded(int fd, char **bufp, int *bufsz, erlang_msg *to,
682 		       int *msglen);
683 int ei_receive_encoded_tmo(int fd, char **bufp, int *bufsz, erlang_msg *to,
684 			   int *msglen, unsigned ms);
685 int ei_send_encoded(int fd, const erlang_pid *to, char *msg, int msglen);
686 int ei_send_encoded_tmo(int fd, const erlang_pid *to, char *msg, int msglen,
687 			unsigned ms);
688 int ei_send_reg_encoded(int fd, const erlang_pid *from, const char *to,
689 			char *msg, int msglen);
690 int ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to,
691 			    char *msg, int msglen, unsigned ms);
692 
693 /*
694  * Bacward compatibility with old undocumented but used interface...
695  * FIXME use wrapper function instead?!
696  */
697 #define ei_send_encoded_timeout(Fd,To,Msg,MsgLen,Ms) \
698     ei_send_encoded_tmo((Fd),(To),(Msg),(MsgLen),(Ms))
699 #define ei_send_reg_encoded_timeout(Fd,From,To,Msg,MsgLen,Ms) \
700     ei_send_reg_encoded_tmo((Fd),(From),(To),(Msg),(MsgLen),(Ms))
701 
702 
703 /* FIXME: is this really the best way to handle bignums? */
704 int ei_encode_big(char *buf, int *index, erlang_big* big);
705 int ei_x_encode_big(ei_x_buff* x, erlang_big* big);
706 int ei_decode_big(const char *buf, int *index, erlang_big* p);
707 int ei_big_comp(erlang_big *x, erlang_big *y);
708 int ei_big_to_double(erlang_big *b, double *resp);
709 int ei_small_to_big(int s, erlang_big *b);
710 erlang_big *ei_alloc_big(unsigned int arity);
711 void ei_free_big(erlang_big *b);
712 
713 #endif /* USE_EI_UNDOCUMENTED */
714 
715 #ifdef __cplusplus
716 }
717 #endif
718 
719 #endif /* EI_H */
720