1 /*
2 * %CopyrightBegin%
3 *
4 * Copyright Ericsson AB 1999-2016. 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 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <sys/types.h>
25 #include <string.h>
26 #ifdef __WIN32__
27 #include <winsock2.h>
28 #include <direct.h>
29 #include <windows.h>
30 #include <winbase.h>
31 #else /* not __WIN32__ */
32 #include <errno.h>
33 #include <unistd.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #include <netdb.h>
38 #endif
39 #include "rmod_random__s.h"
40
41 /* Used functions */
42 static int getport(int sockd);
43 static int getlisten(int port);
44 static int init(int *sd, int *portnr, int *epmd_fd);
45 void terminate(int *fd, int *sd, int *epmd_fd);
46 static void server_loop(int fd, int sd);
47
48 /* change these, or even better, make command-line args to program... */
49 #define COOKIE "flash"
50 #define SERVER "babbis"
51 #define NODENAMESZ 512
52 #define HOSTNAMESZ 256
53 #define INBUFSZ 1024
54 #define OUTBUFSZ 1024
55
56
main(int argc,char ** argv)57 int main(int argc, char **argv)
58 {
59 int sd;
60 int portnr;
61 int epmd_fd;
62
63 /* crate file descriptors */
64 if (init(&sd, &portnr, &epmd_fd) < 0)
65 return -1;
66
67 /* start server loop */
68 server_loop(sd,epmd_fd);
69
70 return 0;
71 }
72
73
74
server_loop(int sd,int epmd_fd)75 static void server_loop(int sd, int epmd_fd)
76 {
77 ErlConnect conn;
78 erlang_msg msg;
79 int status=1;
80 CORBA_Environment *env;
81
82 /* Create and init CORBA_Environment */
83 env = CORBA_Environment_alloc(INBUFSZ,OUTBUFSZ);
84
85 while (status >= 0) {
86
87 status = 1;
88
89 if ((env->_fd = erl_accept(sd,&conn)) < 0) {
90 /* error */
91 fprintf(stderr,"Accept failed: %s\n",strerror(errno));
92 }
93 else {
94 /* connection */
95 fprintf(stderr,"Accepted connection from %s\n",conn.nodename);
96
97 while (status >= 0) {
98
99 /* write message to buffer */
100 status = ei_receive_encoded(env->_fd, &env->_inbuf, &env->_inbufsz, &msg, &env->_iin);
101 switch(status) {
102 case ERL_SEND:
103 case ERL_REG_SEND :
104 /* do transaction with fd */
105 rmod_random__switch(NULL,env);
106
107 switch(env->_major) {
108 case CORBA_NO_EXCEPTION: /* Success */
109 break;
110 case CORBA_SYSTEM_EXCEPTION: /* System exception */
111 printf("Request failure, reason : %s\n",(char *) CORBA_exception_value(env));
112 CORBA_exception_free(env);
113 break;
114 default: /* Should not come here */
115 CORBA_exception_free(env);
116 break;
117 }
118
119 /* send outdata */
120 if (env->_iout > 0)
121 ei_send_encoded(env->_fd,&env->_caller,env->_outbuf,env->_iout);
122 break;
123
124 case ERL_TICK :
125 break;
126 default : /* < 0 */
127 printf("Connection terminated\n");
128 break;
129 }
130 }
131 }
132 status=0; /* restart */
133 }
134
135 /* close file descriptors */
136 terminate(&env->_fd, &sd, &epmd_fd);
137
138 /* Free env & buffers */
139 CORBA_free(env->_inbuf);
140 CORBA_free(env->_outbuf);
141 CORBA_free(env);
142 }
143
144
145
init(int * sd,int * portnr,int * epmd_fd)146 static int init(int *sd, int *portnr, int *epmd_fd)
147 {
148 char host[HOSTNAMESZ];
149 char servernode[NODENAMESZ];
150 struct hostent *h;
151 int error = 0;
152
153 #ifdef __WIN32__
154 WORD wVersionRequested;
155 WSADATA wsaData;
156
157 wVersionRequested = MAKEWORD(1, 1);
158 if ((error = WSAStartup(wVersionRequested, &wsaData))) {
159 fprintf(stderr,"Can't initialize windows sockets: %d",error);
160 }
161 #endif
162 /* get the host name */
163 error = gethostname(host,HOSTNAMESZ);
164 if (error) {
165 #ifdef __WIN32__
166 fprintf(stderr,"can't find own hostname (error = %ld) !\n",WSAGetLastError());
167 #else /* not __WIN32__ */
168 fprintf(stderr,"can't find own hostname !\n");
169 #endif
170 }
171 else {
172 /* identify host */
173 if (!(h = erl_gethostbyname(host)))
174 fprintf(stdout,"can't find own ip address\n");
175 else {
176
177 /* get a listen port. 0 means let system choose port number */
178 *sd = getlisten(0);
179
180 /* what port did we get? */
181 /* this call not necessary if we specified port in call to getlisten() */
182 *portnr = getport(*sd);
183
184 /* make the nodename server@host */
185 sprintf(servernode,"%s@%s",SERVER,host);
186
187 /* initiate */
188 erl_init(NULL,0);
189
190 /* host, alive, alive@host, addr, cookie, creation */
191 erl_connect_xinit(host,SERVER,servernode,(Erl_IpAddr)(h->h_addr_list[0]),COOKIE,0);
192
193 /* let epmd know we are here */
194 *epmd_fd = erl_publish(*portnr);
195
196 return 0;
197 }
198 }
199 return -1;
200 }
201
202
terminate(int * fd,int * sd,int * epmd_fd)203 void terminate(int *fd, int *sd, int *epmd_fd) {
204
205 close(*fd);
206
207 /* remove info from epnd */
208 close(*epmd_fd);
209
210 /* return socket */
211 close(*sd);
212
213 }
214
215
216
217 /* tells you what port you are using on given socket */
getport(int sockd)218 static int getport(int sockd)
219 {
220 struct sockaddr_in addr;
221 int namelen = sizeof(addr);
222 int i;
223
224 memset(&addr,0,sizeof(addr));
225
226 if ((i = getsockname(sockd,(struct sockaddr *)&addr,&namelen))<0)
227 return i;
228
229 return ntohs(addr.sin_port);
230 }
231
232
233
234 /* return a listen socket, bound to given port */
235 /* specify port = 0 to let system assign port */
getlisten(int port)236 static int getlisten(int port)
237 {
238 int sockd;
239 struct sockaddr_in inaddr;
240 int opt = 1;
241 int i;
242
243 /* get listen socket */
244 if ((sockd = socket(AF_INET,SOCK_STREAM,0)) < 0) return sockd;
245
246 if ((i=setsockopt(sockd,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)))<0)
247 return i;
248
249 /* bind to requested port */
250 memset(&inaddr,0,sizeof(inaddr));
251 inaddr.sin_family = AF_INET;
252 inaddr.sin_addr.s_addr = htonl(INADDR_ANY);
253 inaddr.sin_port = htons(port);
254
255 if ((i = bind(sockd,(struct sockaddr*) &inaddr, sizeof(inaddr))) < 0)
256 return i;
257
258 listen(sockd,5);
259
260 return sockd;
261 }
262
263