rust: Implement TARGET_RUST_OS_INFO for *-*-freebsd*
[official-gcc.git] / libgm2 / libm2pim / sckt.cc
blobf0b3af0307bf932c59eb0279b7e3929711753111
1 /* sckt.c provide access to the socket layer.
3 Copyright (C) 2005-2022 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 This file is part of GNU Modula-2.
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
27 #include <config.h>
28 #include <m2rts.h>
30 #define EXPORT(FUNC) m2pim ## _sckt_ ## FUNC
31 #define M2EXPORT(FUNC) m2pim ## _M2_sckt_ ## FUNC
32 #define M2LIBNAME "m2pim"
34 #if defined(HAVE_SYS_TYPES_H)
35 #include <sys/types.h>
36 #endif
38 #if defined(HAVE_SYS_SOCKET_H)
39 #include <sys/socket.h>
40 #endif
42 #if defined(HAVE_NETINET_IN_H)
43 #include <netinet/in.h>
44 #endif
46 #if defined(HAVE_NETDB_H)
47 #include <netdb.h>
48 #endif
50 #if defined(HAVE_UNISTD_H)
51 #include <unistd.h>
52 #endif
54 #if defined(HAVE_SIGNAL_H)
55 #include <signal.h>
56 #endif
58 #if defined(HAVE_SYS_ERRNO_H)
59 #include <sys/errno.h>
60 #endif
62 #if defined(HAVE_ERRNO_H)
63 #include <errno.h>
64 #endif
66 #if defined(HAVE_MALLOC_H)
67 #include <malloc.h>
68 #endif
70 #if defined(HAVE_STRING_H)
71 #include <string.h>
72 #endif
74 #if defined(HAVE_STDLIB_H)
75 #include <stdlib.h>
76 #endif
78 #if defined(HAVE_STDIO_H)
79 #include <stdio.h>
80 #endif
82 #define PORTSTART 7000
83 #define NOOFTRIES 100
84 #define MAXHOSTNAME 256
86 #undef DEBUGGING
88 #if defined(HAVE_SYS_SOCKET_H)
90 #define ERROR(X) \
91 { \
92 printf ("%s:%d:%s\n", __FILE__, __LINE__, X); \
93 localExit (1); \
96 #define ASSERT(X) \
97 { \
98 if (!(X)) \
99 { \
100 printf ("%s:%d: assert(%s) failed\n", __FILE__, __LINE__, #X); \
101 exit (1); \
105 typedef struct
107 char hostname[MAXHOSTNAME];
108 struct hostent *hp;
109 struct sockaddr_in sa, isa;
110 int sockFd;
111 int portNo;
112 } tcpServerState;
115 localExit (int i)
117 exit (1);
120 /* tcpServerEstablishPort returns a tcpState containing the relevant
121 information about a socket declared to receive tcp connections.
122 This method attempts to use the port specified by the parameter. */
124 extern "C" tcpServerState *
125 EXPORT(tcpServerEstablishPort) (int portNo)
127 tcpServerState *s = (tcpServerState *)malloc (sizeof (tcpServerState));
128 int b, p, n;
130 if (s == NULL)
131 ERROR ("no more memory");
133 /* Remove SIGPIPE which is raised on the server if the client is killed. */
134 signal (SIGPIPE, SIG_IGN);
136 if (gethostname (s->hostname, MAXHOSTNAME) < 0)
137 ERROR ("cannot find our hostname");
139 s->hp = gethostbyname (s->hostname);
140 if (s->hp == NULL)
141 ERROR ("cannot get host name");
143 p = -1;
144 n = 0;
147 p++;
148 /* Open a TCP socket (an Internet stream socket). */
150 s->sockFd = socket (s->hp->h_addrtype, SOCK_STREAM, 0);
151 if (s->sockFd < 0)
152 ERROR ("socket");
154 memset ((void *)&s->sa, 0, sizeof (s->sa));
155 ASSERT ((s->hp->h_addrtype == AF_INET));
156 s->sa.sin_family = s->hp->h_addrtype;
157 s->sa.sin_addr.s_addr = htonl (INADDR_ANY);
158 s->sa.sin_port = htons (portNo + p);
160 b = bind (s->sockFd, (struct sockaddr *)&s->sa, sizeof (s->sa));
162 while ((b < 0) && (n < NOOFTRIES));
164 if (b < 0)
165 ERROR ("bind");
167 s->portNo = portNo + p;
168 #if defined(DEBUGGING)
169 printf ("the receiving host is: %s, the port is %d\n", s->hostname,
170 s->portNo);
171 #endif
172 listen (s->sockFd, 1);
173 return s;
176 /* tcpServerEstablish returns a tcpServerState containing the relevant
177 information about a socket declared to receive tcp connections. */
179 extern "C" tcpServerState *
180 EXPORT(tcpServerEstablish) (void)
182 return EXPORT(tcpServerEstablishPort) (PORTSTART);
185 /* tcpServerAccept returns a file descriptor once a client has connected and
186 been accepted. */
188 extern "C" int
189 EXPORT(tcpServerAccept) (tcpServerState *s)
191 socklen_t i = sizeof (s->isa);
192 int t;
194 #if defined(DEBUGGING)
195 printf ("before accept %d\n", s->sockFd);
196 #endif
197 t = accept (s->sockFd, (struct sockaddr *)&s->isa, &i);
198 return t;
201 /* tcpServerPortNo returns the portNo from structure, s. */
203 extern "C" int
204 EXPORT(tcpServerPortNo) (tcpServerState *s)
206 return s->portNo;
209 /* tcpServerSocketFd returns the sockFd from structure, s. */
211 extern "C" int
212 EXPORT(tcpServerSocketFd) (tcpServerState *s)
214 return s->sockFd;
217 /* getLocalIP returns the IP address of this machine. */
219 extern "C" unsigned int
220 EXPORT(getLocalIP) (tcpServerState *s)
222 char hostname[1024];
223 struct hostent *hp;
224 struct sockaddr_in sa;
225 unsigned int ip;
226 int ret = gethostname (hostname, sizeof (hostname));
228 if (ret == -1)
230 ERROR ("gethostname");
231 return 0;
234 hp = gethostbyname (hostname);
235 if (hp == NULL)
237 ERROR ("gethostbyname");
238 return 0;
241 if (sizeof (unsigned int) != sizeof (in_addr_t))
243 ERROR ("bad ip length");
244 return 0;
247 memset (&sa, 0, sizeof (struct sockaddr_in));
248 sa.sin_family = AF_INET;
249 sa.sin_port = htons (80);
250 if (hp->h_length == sizeof (unsigned int))
252 memcpy (&ip, hp->h_addr_list[0], hp->h_length);
253 return ip;
256 return 0;
259 /* tcpServerIP returns the IP address from structure s. */
261 extern "C" int
262 EXPORT(tcpServerIP) (tcpServerState *s)
264 return *((int *)s->hp->h_addr_list[0]);
267 /* tcpServerClientIP returns the IP address of the client who
268 has connected to server s. */
270 extern "C" unsigned int
271 EXPORT(tcpServerClientIP) (tcpServerState *s)
273 unsigned int ip;
275 ASSERT (s->isa.sin_family == AF_INET);
276 ASSERT (sizeof (ip) == 4);
277 memcpy (&ip, &s->isa.sin_addr, sizeof (ip));
278 return ip;
281 /* tcpServerClientPortNo returns the port number of the client who
282 has connected to server s. */
284 extern "C" unsigned int
285 EXPORT(tcpServerClientPortNo) (tcpServerState *s)
287 return s->isa.sin_port;
291 ****************************************************************
292 *** C L I E N T R O U T I N E S
293 ****************************************************************
296 typedef struct
298 char hostname[MAXHOSTNAME];
299 struct hostent *hp;
300 struct sockaddr_in sa;
301 int sockFd;
302 int portNo;
303 } tcpClientState;
305 /* tcpClientSocket returns a file descriptor (socket) which has
306 connected to, serverName:portNo. */
308 extern "C" tcpClientState *
309 EXPORT(tcpClientSocket) (char *serverName, int portNo)
311 tcpClientState *s = (tcpClientState *)malloc (sizeof (tcpClientState));
313 if (s == NULL)
314 ERROR ("no more memory");
316 /* Remove SIGPIPE which is raised on the server if the client is killed. */
317 signal (SIGPIPE, SIG_IGN);
319 s->hp = gethostbyname (serverName);
320 if (s->hp == NULL)
322 fprintf (stderr, "cannot find host: %s\n", serverName);
323 exit (1);
326 memset ((void *)&s->sa, 0, sizeof (s->sa));
327 s->sa.sin_family = AF_INET;
328 memcpy ((void *)&s->sa.sin_addr, (void *)s->hp->h_addr, s->hp->h_length);
329 s->portNo = portNo;
330 s->sa.sin_port = htons (portNo);
332 /* Open a TCP socket (an Internet stream socket). */
334 s->sockFd = socket (s->hp->h_addrtype, SOCK_STREAM, 0);
335 return s;
338 /* tcpClientSocketIP returns a file descriptor (socket) which has
339 connected to, ip:portNo. */
341 extern "C" tcpClientState *
342 EXPORT(tcpClientSocketIP) (unsigned int ip, int portNo)
344 tcpClientState *s = (tcpClientState *)malloc (sizeof (tcpClientState));
346 if (s == NULL)
347 ERROR ("no more memory");
349 /* Remove SIGPIPE which is raised on the server if the client is killed. */
350 signal (SIGPIPE, SIG_IGN);
352 memset ((void *)&s->sa, 0, sizeof (s->sa));
353 s->sa.sin_family = AF_INET;
354 memcpy ((void *)&s->sa.sin_addr, (void *)&ip, sizeof (ip));
355 s->portNo = portNo;
356 s->sa.sin_port = htons (portNo);
358 /* Open a TCP socket (an Internet stream socket). */
360 s->sockFd = socket (PF_INET, SOCK_STREAM, 0);
361 return s;
364 /* tcpClientConnect returns the file descriptor associated with s,
365 once a connect has been performed. */
367 extern "C" int
368 EXPORT(tcpClientConnect) (tcpClientState *s)
370 if (connect (s->sockFd, (struct sockaddr *)&s->sa, sizeof (s->sa)) < 0)
371 ERROR ("failed to connect to the TCP server");
373 return s->sockFd;
376 /* tcpClientPortNo returns the portNo from structure s. */
378 extern "C" int
379 EXPORT(tcpClientPortNo) (tcpClientState *s)
381 return s->portNo;
384 /* tcpClientSocketFd returns the sockFd from structure s. */
386 extern "C" int
387 EXPORT(tcpClientSocketFd) (tcpClientState *s)
389 return s->sockFd;
392 /* tcpClientIP returns the sockFd from structure s. */
394 extern "C" int
395 EXPORT(tcpClientIP) (tcpClientState *s)
397 #if defined(DEBUGGING)
398 printf ("client ip = %s\n", inet_ntoa (s->sa.sin_addr.s_addr));
399 #endif
400 return s->sa.sin_addr.s_addr;
402 #endif
404 /* GNU Modula-2 link fodder. */
406 extern "C" void
407 M2EXPORT(init) (int, char *[], char *[])
411 extern "C" void
412 M2EXPORT(finish) (int, char *[], char *[])
416 extern "C" void
417 M2EXPORT(dep) (void)
421 extern "C" void __attribute__((__constructor__))
422 M2EXPORT(ctor) (void)
424 m2pim_M2RTS_RegisterModule ("sckt", M2LIBNAME,
425 M2EXPORT(init), M2EXPORT(finish),
426 M2EXPORT(dep));