1 /* cnode_s.c */
2 
3 #include <stdio.h>
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <netinet/in.h>
7 
8 #include "erl_interface.h"
9 #include "ei.h"
10 
11 #define BUFSIZE 1000
12 
main(int argc,char ** argv)13 int main(int argc, char **argv) {
14   int port;                                /* Listen port number */
15   int listen;                              /* Listen socket */
16   int fd;                                  /* fd to Erlang node */
17   ErlConnect conn;                         /* Connection data */
18 
19   int loop = 1;                            /* Loop flag */
20   int got;                                 /* Result of receive */
21   unsigned char buf[BUFSIZE];              /* Buffer for incoming message */
22   ErlMessage emsg;                         /* Incoming message */
23 
24   ETERM *fromp, *tuplep, *fnp, *argp, *resp;
25   int res;
26 
27   port = atoi(argv[1]);
28 
29   erl_init(NULL, 0);
30 
31   if (erl_connect_init(1, "secretcookie", 0) == -1)
32     erl_err_quit("erl_connect_init");
33 
34   /* Make a listen socket */
35   if ((listen = my_listen(port)) <= 0)
36     erl_err_quit("my_listen");
37 
38   if (erl_publish(port) == -1)
39     erl_err_quit("erl_publish");
40 
41   if ((fd = erl_accept(listen, &conn)) == ERL_ERROR)
42     erl_err_quit("erl_accept");
43   fprintf(stderr, "Connected to %s\n\r", conn.nodename);
44 
45   while (loop) {
46 
47     got = erl_receive_msg(fd, buf, BUFSIZE, &emsg);
48     if (got == ERL_TICK) {
49       /* ignore */
50     } else if (got == ERL_ERROR) {
51       loop = 0;
52     } else {
53 
54       if (emsg.type == ERL_REG_SEND) {
55 	fromp = erl_element(2, emsg.msg);
56 	tuplep = erl_element(3, emsg.msg);
57 	fnp = erl_element(1, tuplep);
58 	argp = erl_element(2, tuplep);
59 
60 	if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) {
61 	  res = foo(ERL_INT_VALUE(argp));
62 	} else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) {
63 	  res = bar(ERL_INT_VALUE(argp));
64 	}
65 
66 	resp = erl_format("{cnode, ~i}", res);
67 	erl_send(fd, fromp, resp);
68 
69 	erl_free_term(emsg.from); erl_free_term(emsg.msg);
70 	erl_free_term(fromp); erl_free_term(tuplep);
71 	erl_free_term(fnp); erl_free_term(argp);
72 	erl_free_term(resp);
73       }
74     }
75   } /* while */
76 }
77 
78 
my_listen(int port)79 int my_listen(int port) {
80   int listen_fd;
81   struct sockaddr_in addr;
82   int on = 1;
83 
84   if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
85     return (-1);
86 
87   setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
88 
89   memset((void*) &addr, 0, (size_t) sizeof(addr));
90   addr.sin_family = AF_INET;
91   addr.sin_port = htons(port);
92   addr.sin_addr.s_addr = htonl(INADDR_ANY);
93 
94   if (bind(listen_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
95     return (-1);
96 
97   listen(listen_fd, 5);
98   return listen_fd;
99 }
100