portability fixes for header inclusion etc.
[bpt/guile.git] / libguile / socket.c
CommitLineData
0f2d19dd
JB
1/* "socket.c" internet socket support for client/server in SCM
2 Copyright (C) 1994 Aubrey Jaffer.
3 Thanks to Hallvard.Tretteberg@si.sintef.no
4 who credits NCSA httpd software by Rob McCool 3/21/93.
5 Rewritten by Gary Houston to be a closer interface to the C
6 socket library.
7 */
8\f
9
10#include <stdio.h>
0f2d19dd 11#include "_scm.h"
95b88819
GH
12
13#ifdef HAVE_STRING_H
14#include <string.h>
15#endif
16
0f2d19dd
JB
17#include <sys/types.h>
18#include <sys/socket.h>
19#include <sys/un.h>
20#include <netinet/in.h>
21#include <netdb.h>
22#include <arpa/inet.h>
23
24\f
25
26#ifndef STDC_HEADERS
27int close P ((int fd));
28#endif /* STDC_HEADERS */
29
02b754d3 30SCM_PROC (s_sys_inet_aton, "inet-aton", 1, 0, 0, scm_sys_inet_aton);
0f2d19dd
JB
31#ifdef __STDC__
32SCM
33scm_sys_inet_aton (SCM address)
34#else
35SCM
36scm_sys_inet_aton (address)
37 SCM address;
38#endif
39{
40 struct in_addr soka;
2e18892a 41
0f2d19dd
JB
42 SCM_ASSERT (SCM_NIMP (address) && SCM_ROSTRINGP (address), address, SCM_ARG1, s_sys_inet_aton);
43 if (SCM_SUBSTRP (address))
44 address = scm_makfromstr (SCM_ROCHARS (address), SCM_ROLENGTH (address), 0);
02b754d3
GH
45 if (inet_aton (SCM_ROCHARS (address), &soka) == 0)
46 SCM_SYSERROR (s_sys_inet_aton);
47 return scm_ulong2num (ntohl (soka.s_addr));
0f2d19dd
JB
48}
49
50
51SCM_PROC (s_inet_ntoa, "inet-ntoa", 1, 0, 0, scm_inet_ntoa);
52#ifdef __STDC__
53SCM
54scm_inet_ntoa (SCM inetid)
55#else
56SCM
57scm_inet_ntoa (inetid)
58 SCM inetid;
59#endif
60{
61 struct in_addr addr;
62 char *s;
63 SCM answer;
64 addr.s_addr = htonl (scm_num2ulong (inetid, (char *) SCM_ARG1, s_inet_ntoa));
65 SCM_DEFER_INTS;
66 s = inet_ntoa (addr);
67 answer = scm_makfromstr (s, strlen (s), 0);
68 SCM_ALLOW_INTS;
69 return answer;
70}
71
72SCM_PROC (s_inet_netof, "inet-netof", 1, 0, 0, scm_inet_netof);
73#ifdef __STDC__
74SCM
75scm_inet_netof (SCM address)
76#else
77SCM
78scm_inet_netof (address)
79 SCM address;
80#endif
81{
82 struct in_addr addr;
83 addr.s_addr = htonl (scm_num2ulong (address, (char *) SCM_ARG1, s_inet_netof));
84 return scm_ulong2num ((unsigned long) inet_netof (addr));
85}
86
87SCM_PROC (s_lnaof, "lnaof", 1, 0, 0, scm_lnaof);
88#ifdef __STDC__
89SCM
90scm_lnaof (SCM address)
91#else
92SCM
93scm_lnaof (address)
94 SCM address;
95#endif
96{
97 struct in_addr addr;
98 addr.s_addr = htonl (scm_num2ulong (address, (char *) SCM_ARG1, s_lnaof));
99 return scm_ulong2num ((unsigned long) inet_lnaof (addr));
100}
101
102
103SCM_PROC (s_inet_makeaddr, "inet-makeaddr", 2, 0, 0, scm_inet_makeaddr);
104#ifdef __STDC__
105SCM
106scm_inet_makeaddr (SCM net, SCM lna)
107#else
108SCM
109scm_inet_makeaddr (net, lna)
110 SCM net;
111 SCM lna;
112#endif
113{
114 struct in_addr addr;
115 unsigned long netnum;
116 unsigned long lnanum;
117
118 netnum = scm_num2ulong (net, (char *) SCM_ARG1, s_inet_makeaddr);
119 lnanum = scm_num2ulong (lna, (char *) SCM_ARG2, s_inet_makeaddr);
120 addr = inet_makeaddr (netnum, lnanum);
121 return scm_ulong2num (ntohl (addr.s_addr));
122}
123
124
125/* !!! Doesn't take address format.
126 * Assumes hostent stream isn't reused.
127 */
128
02b754d3 129SCM_PROC (s_sys_gethost, "gethost", 0, 1, 0, scm_sys_gethost);
0f2d19dd
JB
130#ifdef __STDC__
131SCM
132scm_sys_gethost (SCM name)
133#else
134SCM
135scm_sys_gethost (name)
136 SCM name;
137#endif
138{
139 SCM ans = scm_make_vector (SCM_MAKINUM (5), SCM_UNSPECIFIED, SCM_BOOL_F);
140 SCM *ve = SCM_VELTS (ans);
141 SCM lst = SCM_EOL;
142 struct hostent *entry;
143 struct in_addr inad;
144 char **argv;
145 int i = 0;
146#ifdef HAVE_GETHOSTENT
147 if (SCM_UNBNDP (name))
148 {
149 SCM_DEFER_INTS;
150 entry = gethostent ();
151 }
152 else
153#endif
154 if (SCM_NIMP (name) && SCM_STRINGP (name))
155 {
156 SCM_DEFER_INTS;
157 entry = gethostbyname (SCM_CHARS (name));
158 }
159 else
160 {
161 inad.s_addr = htonl (scm_num2ulong (name, (char *) SCM_ARG1, s_sys_gethost));
162 SCM_DEFER_INTS;
163 entry = gethostbyaddr ((char *) &inad, sizeof (inad), AF_INET);
164 }
165 SCM_ALLOW_INTS;
166 if (!entry)
02b754d3 167 SCM_SYSERROR (s_sys_gethost);
0f2d19dd
JB
168 ve[0] = scm_makfromstr (entry->h_name, (scm_sizet) strlen (entry->h_name), 0);
169 ve[1] = scm_makfromstrs (-1, entry->h_aliases);
170 ve[2] = SCM_MAKINUM (entry->h_addrtype + 0L);
171 ve[3] = SCM_MAKINUM (entry->h_length + 0L);
172 if (sizeof (struct in_addr) != entry->h_length)
173 {
174 ve[4] = SCM_BOOL_F;
175 return ans;
176 }
177 for (argv = entry->h_addr_list; argv[i]; i++);
178 while (i--)
179 {
180 inad = *(struct in_addr *) argv[i];
181 lst = scm_cons (scm_ulong2num (ntohl (inad.s_addr)), lst);
182 }
183 ve[4] = lst;
184 return ans;
185}
186
187
02b754d3 188SCM_PROC (s_sys_getnet, "getnet", 0, 1, 0, scm_sys_getnet);
0f2d19dd
JB
189#ifdef __STDC__
190SCM
191scm_sys_getnet (SCM name)
192#else
193SCM
194scm_sys_getnet (name)
195 SCM name;
196#endif
197{
198 SCM ans;
199 SCM *ve;
200 struct netent *entry;
201
202 ans = scm_make_vector (SCM_MAKINUM (4), SCM_UNSPECIFIED, SCM_BOOL_F);
203 ve = SCM_VELTS (ans);
204 if (SCM_UNBNDP (name))
205 {
206 SCM_DEFER_INTS;
207 entry = getnetent ();
208 }
209 else if (SCM_NIMP (name) && SCM_STRINGP (name))
210 {
211 SCM_DEFER_INTS;
212 entry = getnetbyname (SCM_CHARS (name));
213 }
214 else
215 {
216 unsigned long netnum;
217 netnum = scm_num2ulong (name, (char *) SCM_ARG1, s_sys_getnet);
218 SCM_DEFER_INTS;
219 entry = getnetbyaddr (netnum, AF_INET);
220 }
221 SCM_ALLOW_INTS;
222 if (!entry)
02b754d3 223 SCM_SYSERROR (s_sys_getnet);
0f2d19dd
JB
224 ve[0] = scm_makfromstr (entry->n_name, (scm_sizet) strlen (entry->n_name), 0);
225 ve[1] = scm_makfromstrs (-1, entry->n_aliases);
226 ve[2] = SCM_MAKINUM (entry->n_addrtype + 0L);
227 ve[3] = scm_ulong2num (entry->n_net + 0L);
228 return ans;
229}
230
02b754d3 231SCM_PROC (s_sys_getproto, "getproto", 0, 1, 0, scm_sys_getproto);
0f2d19dd
JB
232#ifdef __STDC__
233SCM
234scm_sys_getproto (SCM name)
235#else
236SCM
237scm_sys_getproto (name)
238 SCM name;
239#endif
240{
241 SCM ans;
242 SCM *ve;
243 struct protoent *entry;
244
245 ans = scm_make_vector (SCM_MAKINUM (3), SCM_UNSPECIFIED, SCM_BOOL_F);
246 ve = SCM_VELTS (ans);
247 if (SCM_UNBNDP (name))
248 {
249 SCM_DEFER_INTS;
250 entry = getprotoent ();
251 }
252 else if (SCM_NIMP (name) && SCM_STRINGP (name))
253 {
254 SCM_DEFER_INTS;
255 entry = getprotobyname (SCM_CHARS (name));
256 }
257 else
258 {
259 unsigned long protonum;
260 protonum = scm_num2ulong (name, (char *) SCM_ARG1, s_sys_getproto);
261 SCM_DEFER_INTS;
262 entry = getprotobynumber (protonum);
263 }
264 SCM_ALLOW_INTS;
265 if (!entry)
02b754d3 266 SCM_SYSERROR (s_sys_getproto);
0f2d19dd
JB
267 ve[0] = scm_makfromstr (entry->p_name, (scm_sizet) strlen (entry->p_name), 0);
268 ve[1] = scm_makfromstrs (-1, entry->p_aliases);
269 ve[2] = SCM_MAKINUM (entry->p_proto + 0L);
270 return ans;
271}
272
273#ifdef __STDC__
274static SCM
275scm_return_entry (struct servent *entry)
276#else
277static SCM
278scm_return_entry (entry)
279 struct servent *entry;
280#endif
281{
282 SCM ans;
283 SCM *ve;
284
285 ans = scm_make_vector (SCM_MAKINUM (4), SCM_UNSPECIFIED, SCM_BOOL_F);
286 ve = SCM_VELTS (ans);
0f2d19dd
JB
287 ve[0] = scm_makfromstr (entry->s_name, (scm_sizet) strlen (entry->s_name), 0);
288 ve[1] = scm_makfromstrs (-1, entry->s_aliases);
289 ve[2] = SCM_MAKINUM (ntohs (entry->s_port) + 0L);
290 ve[3] = scm_makfromstr (entry->s_proto, (scm_sizet) strlen (entry->s_proto), 0);
291 SCM_ALLOW_INTS;
292 return ans;
293}
294
02b754d3 295SCM_PROC (s_sys_getserv, "getserv", 0, 2, 0, scm_sys_getserv);
0f2d19dd
JB
296#ifdef __STDC__
297SCM
298scm_sys_getserv (SCM name, SCM proto)
299#else
300SCM
301scm_sys_getserv (name, proto)
302 SCM name;
303 SCM proto;
304#endif
305{
306 struct servent *entry;
307 if (SCM_UNBNDP (name))
308 {
309 SCM_DEFER_INTS;
310 entry = getservent ();
02b754d3
GH
311 if (!entry)
312 SCM_SYSERROR (s_sys_getserv);
0f2d19dd
JB
313 return scm_return_entry (entry);
314 }
315 SCM_ASSERT (SCM_NIMP (proto) && SCM_STRINGP (proto), proto, SCM_ARG2, s_sys_getserv);
316 if (SCM_NIMP (name) && SCM_STRINGP (name))
317 {
318 SCM_DEFER_INTS;
319 entry = getservbyname (SCM_CHARS (name), SCM_CHARS (proto));
320 }
321 else
322 {
323 SCM_ASSERT (SCM_INUMP (name), name, SCM_ARG1, s_sys_getserv);
324 SCM_DEFER_INTS;
325 entry = getservbyport (SCM_INUM (name), SCM_CHARS (proto));
326 }
02b754d3
GH
327 if (!entry)
328 SCM_SYSERROR (s_sys_getserv);
0f2d19dd
JB
329 return scm_return_entry (entry);
330}
331
332SCM_PROC (s_sethost, "sethost", 0, 1, 0, scm_sethost);
333#ifdef __STDC__
334SCM
335scm_sethost (SCM arg)
336#else
337SCM
338scm_sethost (arg)
339 SCM arg;
340#endif
341{
342 if (SCM_UNBNDP (arg))
343 endhostent ();
344 else
345 sethostent (SCM_NFALSEP (arg));
346 return SCM_UNSPECIFIED;
347}
348
349SCM_PROC (s_setnet, "setnet", 0, 1, 0, scm_setnet);
350#ifdef __STDC__
351SCM
352scm_setnet (SCM arg)
353#else
354SCM
355scm_setnet (arg)
356 SCM arg;
357#endif
358{
359 if (SCM_UNBNDP (arg))
360 endnetent ();
361 else
362 setnetent (SCM_NFALSEP (arg));
363 return SCM_UNSPECIFIED;
364}
365
366SCM_PROC (s_setproto, "setproto", 0, 1, 0, scm_setproto);
367#ifdef __STDC__
368SCM
369scm_setproto (SCM arg)
370#else
371SCM
372scm_setproto (arg)
373 SCM arg;
374#endif
375{
376 if (SCM_UNBNDP (arg))
377 endprotoent ();
378 else
379 setprotoent (SCM_NFALSEP (arg));
380 return SCM_UNSPECIFIED;
381}
382
383SCM_PROC (s_setserv, "setserv", 0, 1, 0, scm_setserv);
384#ifdef __STDC__
385SCM
386scm_setserv (SCM arg)
387#else
388SCM
389scm_setserv (arg)
390 SCM arg;
391#endif
392{
393 if (SCM_UNBNDP (arg))
394 endservent ();
395 else
396 setservent (SCM_NFALSEP (arg));
397 return SCM_UNSPECIFIED;
398}
399
400#ifdef __STDC__
401void
402scm_init_socket (void)
403#else
404void
405scm_init_socket ()
406#endif
407{
408 scm_add_feature ("socket");
409#include "socket.x"
410}
411
412