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