1 /* "net_db.c" network database support
2 * Copyright (C) 1995,1996 Free Software Foundation, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this software; see the file COPYING. If not, write to
16 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice.
43 /* Written in 1994 by Aubrey Jaffer.
44 * Thanks to Hallvard.Tretteberg@si.sintef.no for inspiration and discussion.
45 * Rewritten by Gary Houston to be a closer interface to the C socket library.
46 * Split into net_db.c and socket.c.
60 #include <sys/types.h>
61 #include <sys/socket.h>
63 #include <netinet/in.h>
64 #include <arpa/inet.h>
66 /* Some systems do not declare this. It seems unlikely to produce a
74 #endif /* STDC_HEADERS */
76 extern int inet_aton ();
78 SCM_PROC (s_inet_aton
, "inet-aton", 1, 0, 0, scm_inet_aton
);
81 scm_inet_aton (address
)
86 SCM_ASSERT (SCM_NIMP (address
) && SCM_ROSTRINGP (address
), address
, SCM_ARG1
, s_inet_aton
);
87 if (SCM_SUBSTRP (address
))
88 address
= scm_makfromstr (SCM_ROCHARS (address
), SCM_ROLENGTH (address
), 0);
89 if (inet_aton (SCM_ROCHARS (address
), &soka
) == 0)
90 scm_syserror (s_inet_aton
);
91 return scm_ulong2num (ntohl (soka
.s_addr
));
95 SCM_PROC (s_inet_ntoa
, "inet-ntoa", 1, 0, 0, scm_inet_ntoa
);
98 scm_inet_ntoa (inetid
)
104 addr
.s_addr
= htonl (scm_num2ulong (inetid
, (char *) SCM_ARG1
, s_inet_ntoa
));
106 s
= inet_ntoa (addr
);
107 answer
= scm_makfromstr (s
, strlen (s
), 0);
112 SCM_PROC (s_inet_netof
, "inet-netof", 1, 0, 0, scm_inet_netof
);
115 scm_inet_netof (address
)
119 addr
.s_addr
= htonl (scm_num2ulong (address
, (char *) SCM_ARG1
, s_inet_netof
));
120 return scm_ulong2num ((unsigned long) inet_netof (addr
));
123 SCM_PROC (s_lnaof
, "inet-lnaof", 1, 0, 0, scm_lnaof
);
130 addr
.s_addr
= htonl (scm_num2ulong (address
, (char *) SCM_ARG1
, s_lnaof
));
131 return scm_ulong2num ((unsigned long) inet_lnaof (addr
));
135 SCM_PROC (s_inet_makeaddr
, "inet-makeaddr", 2, 0, 0, scm_inet_makeaddr
);
138 scm_inet_makeaddr (net
, lna
)
143 unsigned long netnum
;
144 unsigned long lnanum
;
146 netnum
= scm_num2ulong (net
, (char *) SCM_ARG1
, s_inet_makeaddr
);
147 lnanum
= scm_num2ulong (lna
, (char *) SCM_ARG2
, s_inet_makeaddr
);
148 addr
= inet_makeaddr (netnum
, lnanum
);
149 return scm_ulong2num (ntohl (addr
.s_addr
));
153 /* !!! Doesn't take address format.
154 * Assumes hostent stream isn't reused.
157 SCM_PROC (s_gethost
, "gethost", 0, 1, 0, scm_gethost
);
163 SCM ans
= scm_make_vector (SCM_MAKINUM (5), SCM_UNSPECIFIED
, SCM_BOOL_F
);
164 SCM
*ve
= SCM_VELTS (ans
);
166 struct hostent
*entry
;
170 if (SCM_UNBNDP (name
))
173 #ifdef HAVE_GETHOSTENT
174 entry
= gethostent ();
179 else if (SCM_NIMP (name
) && SCM_ROSTRINGP (name
))
181 SCM_COERCE_SUBSTR (name
);
183 entry
= gethostbyname (SCM_ROCHARS (name
));
187 inad
.s_addr
= htonl (scm_num2ulong (name
, (char *) SCM_ARG1
, s_gethost
));
189 entry
= gethostbyaddr ((char *) &inad
, sizeof (inad
), AF_INET
);
196 if (SCM_UNBNDP (name
))
199 args
= scm_listify (name
, SCM_UNDEFINED
);
202 case HOST_NOT_FOUND
: errmsg
= "host %s not found"; break;
203 case TRY_AGAIN
: errmsg
= "nameserver failure (try later)"; break;
204 case NO_RECOVERY
: errmsg
= "non-recoverable error"; break;
205 case NO_DATA
: errmsg
= "no address associated with %s"; break;
206 default: errmsg
= "undefined error"; break;
208 scm_syserror_msg (s_gethost
, errmsg
, args
, h_errno
);
210 ve
[0] = scm_makfromstr (entry
->h_name
, (scm_sizet
) strlen (entry
->h_name
), 0);
211 ve
[1] = scm_makfromstrs (-1, entry
->h_aliases
);
212 ve
[2] = SCM_MAKINUM (entry
->h_addrtype
+ 0L);
213 ve
[3] = SCM_MAKINUM (entry
->h_length
+ 0L);
214 if (sizeof (struct in_addr
) != entry
->h_length
)
219 for (argv
= entry
->h_addr_list
; argv
[i
]; i
++);
222 inad
= *(struct in_addr
*) argv
[i
];
223 lst
= scm_cons (scm_ulong2num (ntohl (inad
.s_addr
)), lst
);
230 SCM_PROC (s_getnet
, "getnet", 0, 1, 0, scm_getnet
);
238 struct netent
*entry
;
240 ans
= scm_make_vector (SCM_MAKINUM (4), SCM_UNSPECIFIED
, SCM_BOOL_F
);
241 ve
= SCM_VELTS (ans
);
242 if (SCM_UNBNDP (name
))
245 entry
= getnetent ();
247 else if (SCM_NIMP (name
) && SCM_ROSTRINGP (name
))
249 SCM_COERCE_SUBSTR (name
);
251 entry
= getnetbyname (SCM_ROCHARS (name
));
255 unsigned long netnum
;
256 netnum
= scm_num2ulong (name
, (char *) SCM_ARG1
, s_getnet
);
258 entry
= getnetbyaddr (netnum
, AF_INET
);
263 if (SCM_UNBNDP (name
))
264 scm_syserror (s_getnet
);
266 scm_syserror_msg (s_getnet
, "no such network %s",
267 scm_listify (name
, SCM_UNDEFINED
), errno
);
269 ve
[0] = scm_makfromstr (entry
->n_name
, (scm_sizet
) strlen (entry
->n_name
), 0);
270 ve
[1] = scm_makfromstrs (-1, entry
->n_aliases
);
271 ve
[2] = SCM_MAKINUM (entry
->n_addrtype
+ 0L);
272 ve
[3] = scm_ulong2num (entry
->n_net
+ 0L);
276 SCM_PROC (s_getproto
, "getproto", 0, 1, 0, scm_getproto
);
284 struct protoent
*entry
;
286 ans
= scm_make_vector (SCM_MAKINUM (3), SCM_UNSPECIFIED
, SCM_BOOL_F
);
287 ve
= SCM_VELTS (ans
);
288 if (SCM_UNBNDP (name
))
291 entry
= getprotoent ();
293 else if (SCM_NIMP (name
) && SCM_ROSTRINGP (name
))
295 SCM_COERCE_SUBSTR (name
);
297 entry
= getprotobyname (SCM_ROCHARS (name
));
301 unsigned long protonum
;
302 protonum
= scm_num2ulong (name
, (char *) SCM_ARG1
, s_getproto
);
304 entry
= getprotobynumber (protonum
);
309 if (SCM_UNBNDP (name
))
310 scm_syserror (s_getproto
);
312 scm_syserror_msg (s_getproto
, "no such protocol %s",
313 scm_listify (name
, SCM_UNDEFINED
), errno
);
315 ve
[0] = scm_makfromstr (entry
->p_name
, (scm_sizet
) strlen (entry
->p_name
), 0);
316 ve
[1] = scm_makfromstrs (-1, entry
->p_aliases
);
317 ve
[2] = SCM_MAKINUM (entry
->p_proto
+ 0L);
322 static SCM scm_return_entry
SCM_P ((struct servent
*entry
));
325 scm_return_entry (entry
)
326 struct servent
*entry
;
331 ans
= scm_make_vector (SCM_MAKINUM (4), SCM_UNSPECIFIED
, SCM_BOOL_F
);
332 ve
= SCM_VELTS (ans
);
333 ve
[0] = scm_makfromstr (entry
->s_name
, (scm_sizet
) strlen (entry
->s_name
), 0);
334 ve
[1] = scm_makfromstrs (-1, entry
->s_aliases
);
335 ve
[2] = SCM_MAKINUM (ntohs (entry
->s_port
) + 0L);
336 ve
[3] = scm_makfromstr (entry
->s_proto
, (scm_sizet
) strlen (entry
->s_proto
), 0);
341 SCM_PROC (s_getserv
, "getserv", 0, 2, 0, scm_getserv
);
344 scm_getserv (name
, proto
)
348 struct servent
*entry
;
349 if (SCM_UNBNDP (name
))
352 entry
= getservent ();
354 scm_syserror (s_getserv
);
356 return scm_return_entry (entry
);
358 SCM_ASSERT (SCM_NIMP (proto
) && SCM_ROSTRINGP (proto
), proto
, SCM_ARG2
, s_getserv
);
359 SCM_COERCE_SUBSTR (proto
);
360 if (SCM_NIMP (name
) && SCM_ROSTRINGP (name
))
362 SCM_COERCE_SUBSTR (name
);
364 entry
= getservbyname (SCM_ROCHARS (name
), SCM_ROCHARS (proto
));
368 SCM_ASSERT (SCM_INUMP (name
), name
, SCM_ARG1
, s_getserv
);
370 entry
= getservbyport (htons (SCM_INUM (name
)), SCM_ROCHARS (proto
));
373 scm_syserror_msg (s_getserv
, "no such service %s",
374 scm_listify (name
, SCM_UNDEFINED
), errno
);
376 return scm_return_entry (entry
);
379 SCM_PROC (s_sethost
, "sethost", 0, 1, 0, scm_sethost
);
385 if (SCM_UNBNDP (arg
))
388 sethostent (SCM_NFALSEP (arg
));
389 return SCM_UNSPECIFIED
;
392 SCM_PROC (s_setnet
, "setnet", 0, 1, 0, scm_setnet
);
398 if (SCM_UNBNDP (arg
))
401 setnetent (SCM_NFALSEP (arg
));
402 return SCM_UNSPECIFIED
;
405 SCM_PROC (s_setproto
, "setproto", 0, 1, 0, scm_setproto
);
411 if (SCM_UNBNDP (arg
))
414 setprotoent (SCM_NFALSEP (arg
));
415 return SCM_UNSPECIFIED
;
418 SCM_PROC (s_setserv
, "setserv", 0, 1, 0, scm_setserv
);
424 if (SCM_UNBNDP (arg
))
427 setservent (SCM_NFALSEP (arg
));
428 return SCM_UNSPECIFIED
;
436 scm_sysintern ("INADDR_ANY", scm_ulong2num (INADDR_ANY
));
438 #ifdef INADDR_BROADCAST
439 scm_sysintern ("INADDR_BROADCAST", scm_ulong2num (INADDR_BROADCAST
));
442 scm_sysintern ("INADDR_NONE", scm_ulong2num (INADDR_NONE
));
444 #ifdef INADDR_LOOPBACK
445 scm_sysintern ("INADDR_LOOPBACK", scm_ulong2num (INADDR_LOOPBACK
));
448 scm_add_feature ("net-db");