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