* configure.in: don't append threads.doc to EXTRA_DOT_DOC_FILES,
[bpt/guile.git] / libguile / net_db.c
CommitLineData
370312ae 1/* "net_db.c" network database support
e6e2e95a 2 * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 Free Software Foundation, Inc.
370312ae
GH
3 *
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)
7 * any later version.
8 *
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.
13 *
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
82892bed
JB
16 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307 USA
370312ae
GH
18 *
19 * As a special exception, the Free Software Foundation gives permission
20 * for additional uses of the text contained in its release of GUILE.
21 *
22 * The exception is that, if you link the GUILE library with other files
23 * to produce an executable, this does not by itself cause the
24 * resulting executable to be covered by the GNU General Public License.
25 * Your use of that executable is in no way restricted on account of
26 * linking the GUILE library code into it.
27 *
28 * This exception does not however invalidate any other reasons why
29 * the executable file might be covered by the GNU General Public License.
30 *
31 * This exception applies only to the code released by the
32 * Free Software Foundation under the name GUILE. If you copy
33 * code from other Free Software Foundation releases into a copy of
34 * GUILE, as the General Public License permits, the exception does
35 * not apply to the code that you add in this way. To avoid misleading
36 * anyone as to the status of such modified files, you must delete
37 * this exception notice from them.
38 *
39 * If you write modifications of your own for GUILE, it is your choice
40 * whether to permit this exception to apply to your modifications.
82892bed 41 * If you do not wish that, delete this exception notice. */
370312ae 42
1bbd0b84
GB
43/* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
44 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
45
46
370312ae
GH
47/* Written in 1994 by Aubrey Jaffer.
48 * Thanks to Hallvard.Tretteberg@si.sintef.no for inspiration and discussion.
49 * Rewritten by Gary Houston to be a closer interface to the C socket library.
50 * Split into net_db.c and socket.c.
51 */
52\f
53
e6e2e95a
MD
54#include <errno.h>
55
a0599745
MD
56#include "libguile/_scm.h"
57#include "libguile/feature.h"
58#include "libguile/strings.h"
59#include "libguile/vectors.h"
370312ae 60
a0599745
MD
61#include "libguile/validate.h"
62#include "libguile/net_db.h"
370312ae
GH
63
64#ifdef HAVE_STRING_H
65#include <string.h>
66#endif
67
68#include <sys/types.h>
cae76441 69#include <sys/socket.h>
370312ae
GH
70#include <netdb.h>
71#include <netinet/in.h>
72#include <arpa/inet.h>
73
74\f
75
76#ifndef STDC_HEADERS
77int close ();
78#endif /* STDC_HEADERS */
79
0d26a8bc 80#ifndef HAVE_INET_ATON
370312ae 81extern int inet_aton ();
ed0e0e30 82#endif
370312ae 83
a1ec6916 84SCM_DEFINE (scm_inet_aton, "inet-aton", 1, 0, 0,
1bbd0b84 85 (SCM address),
b380b885
MD
86 "Converts a string containing an Internet host address in the traditional\n"
87 "dotted decimal notation into an integer.\n\n"
88 "@smalllisp\n"
d9b6c170
MD
89 "(inet-aton \"127.0.0.1\") @result{} 2130706433\n\n"
90 "@end smalllisp")
1bbd0b84 91#define FUNC_NAME s_scm_inet_aton
370312ae
GH
92{
93 struct in_addr soka;
94
a6d9e5ab
DH
95 SCM_VALIDATE_STRING (1, address);
96 SCM_STRING_COERCE_0TERMINATION_X (address);
97 if (inet_aton (SCM_STRING_CHARS (address), &soka) == 0)
1bbd0b84 98 SCM_MISC_ERROR ("bad address", SCM_EOL);
370312ae
GH
99 return scm_ulong2num (ntohl (soka.s_addr));
100}
1bbd0b84 101#undef FUNC_NAME
370312ae
GH
102
103
a1ec6916 104SCM_DEFINE (scm_inet_ntoa, "inet-ntoa", 1, 0, 0,
1bbd0b84 105 (SCM inetid),
b380b885
MD
106 "Converts an integer Internet host address into a string with the\n"
107 "traditional dotted decimal representation.\n\n"
108 "@smalllisp\n"
6ec589e2 109 "(inet-ntoa 2130706433) @result{} \"127.0.0.1\"\n"
d9b6c170 110 "@end smalllisp")
1bbd0b84 111#define FUNC_NAME s_scm_inet_ntoa
370312ae
GH
112{
113 struct in_addr addr;
114 char *s;
115 SCM answer;
1bbd0b84 116 addr.s_addr = htonl (SCM_NUM2ULONG (1,inetid));
370312ae
GH
117 s = inet_ntoa (addr);
118 answer = scm_makfromstr (s, strlen (s), 0);
370312ae
GH
119 return answer;
120}
1bbd0b84 121#undef FUNC_NAME
370312ae 122
0e958795 123#ifdef HAVE_INET_NETOF
a1ec6916 124SCM_DEFINE (scm_inet_netof, "inet-netof", 1, 0, 0,
1bbd0b84 125 (SCM address),
b380b885
MD
126 "Returns the network number part of the given integer Internet address.\n\n"
127 "@smalllisp\n"
128 "(inet-netof 2130706433) @result{} 127\n"
129 "@end smalllisp")
1bbd0b84 130#define FUNC_NAME s_scm_inet_netof
370312ae
GH
131{
132 struct in_addr addr;
1bbd0b84 133 addr.s_addr = htonl (SCM_NUM2ULONG (1,address));
370312ae
GH
134 return scm_ulong2num ((unsigned long) inet_netof (addr));
135}
1bbd0b84 136#undef FUNC_NAME
0e958795 137#endif
370312ae 138
0e958795 139#ifdef HAVE_INET_LNAOF
a1ec6916 140SCM_DEFINE (scm_lnaof, "inet-lnaof", 1, 0, 0,
1bbd0b84 141 (SCM address),
b380b885
MD
142 "Returns the local-address-with-network part of the given Internet\n"
143 "address.\n\n"
144 "@smalllisp\n"
145 "(inet-lnaof 2130706433) @result{} 1\n"
146 "@end smalllisp")
1bbd0b84 147#define FUNC_NAME s_scm_lnaof
370312ae
GH
148{
149 struct in_addr addr;
1bbd0b84 150 addr.s_addr = htonl (SCM_NUM2ULONG (1,address));
370312ae
GH
151 return scm_ulong2num ((unsigned long) inet_lnaof (addr));
152}
1bbd0b84 153#undef FUNC_NAME
0e958795 154#endif
370312ae 155
0e958795 156#ifdef HAVE_INET_MAKEADDR
a1ec6916 157SCM_DEFINE (scm_inet_makeaddr, "inet-makeaddr", 2, 0, 0,
1bbd0b84 158 (SCM net, SCM lna),
b380b885
MD
159 "Makes an Internet host address by combining the network number @var{net}\n"
160 "with the local-address-within-network number @var{lna}.\n\n"
161 "@smalllisp\n"
162 "(inet-makeaddr 127 1) @result{} 2130706433\n"
163 "@end smalllisp")
1bbd0b84 164#define FUNC_NAME s_scm_inet_makeaddr
370312ae
GH
165{
166 struct in_addr addr;
167 unsigned long netnum;
168 unsigned long lnanum;
169
2eca09c5 170#if 0 /* GJB:FIXME:: */
3b3b36dd
GB
171 SCM_VALIDATE_INUM_COPY (1,net,netnum);
172 SCM_VALIDATE_INUM_COPY (2,lna,lnanum);
2cf37714
GB
173#else
174 netnum = SCM_NUM2ULONG (1, net);
175 lnanum = SCM_NUM2ULONG (2, lna);
176#endif
370312ae
GH
177 addr = inet_makeaddr (netnum, lnanum);
178 return scm_ulong2num (ntohl (addr.s_addr));
179}
1bbd0b84 180#undef FUNC_NAME
0e958795 181#endif
370312ae 182
5c11cc9d
GH
183SCM_SYMBOL (scm_host_not_found_key, "host-not-found");
184SCM_SYMBOL (scm_try_again_key, "try-again");
185SCM_SYMBOL (scm_no_recovery_key, "no-recovery");
186SCM_SYMBOL (scm_no_data_key, "no-data");
370312ae 187
5c11cc9d
GH
188static void scm_resolv_error (const char *subr, SCM bad_value)
189{
5a5f3646 190#ifdef NETDB_INTERNAL
5c11cc9d
GH
191 if (h_errno == NETDB_INTERNAL)
192 {
193 /* errno supposedly contains a useful value. */
194 scm_syserror (subr);
195 }
196 else
5a5f3646 197#endif
5c11cc9d
GH
198 {
199 SCM key;
200 const char *errmsg;
201
202 switch (h_errno)
203 {
204 case HOST_NOT_FOUND:
205 key = scm_host_not_found_key;
206 errmsg = "Unknown host";
207 break;
208 case TRY_AGAIN:
209 key = scm_try_again_key;
210 errmsg = "Host name lookup failure";
211 break;
212 case NO_RECOVERY:
213 key = scm_no_recovery_key;
214 errmsg = "Unknown server error";
215 break;
216 case NO_DATA:
217 key = scm_no_data_key;
218 errmsg = "No address associated with name";
219 break;
220 default:
221 scm_misc_error (subr, "Unknown resolver error", SCM_EOL);
222 errmsg = NULL;
223 }
224
225#ifdef HAVE_HSTRERROR
d9b6c170 226 errmsg = (const char *) hstrerror (h_errno);
5c11cc9d
GH
227#endif
228 scm_error (key, subr, errmsg, scm_cons (bad_value, SCM_EOL), SCM_EOL);
229 }
230}
231
232/* Should take an extra arg for address format (will be needed for IPv6).
233 Should use reentrant facilities if available.
370312ae
GH
234 */
235
a1ec6916 236SCM_DEFINE (scm_gethost, "gethost", 0, 1, 0,
d46e4713 237 (SCM host),
b380b885
MD
238 "@deffnx procedure gethostbyname hostname\n"
239 "@deffnx procedure gethostbyaddr address\n"
240 "Look up a host by name or address, returning a host object. The\n"
241 "@code{gethost} procedure will accept either a string name or an integer\n"
242 "address; if given no arguments, it behaves like @code{gethostent} (see\n"
243 "below). If a name or address is supplied but the address can not be\n"
244 "found, an error will be thrown to one of the keys:\n"
245 "@code{host-not-found}, @code{try-again}, @code{no-recovery} or\n"
246 "@code{no-data}, corresponding to the equivalent @code{h_error} values.\n"
247 "Unusual conditions may result in errors thrown to the\n"
248 "@code{system-error} or @code{misc_error} keys.")
1bbd0b84 249#define FUNC_NAME s_scm_gethost
370312ae 250{
00ffa0e7 251 SCM ans = scm_c_make_vector (5, SCM_UNSPECIFIED);
370312ae
GH
252 SCM *ve = SCM_VELTS (ans);
253 SCM lst = SCM_EOL;
254 struct hostent *entry;
255 struct in_addr inad;
256 char **argv;
257 int i = 0;
d46e4713 258 if (SCM_UNBNDP (host))
370312ae 259 {
cd34a384 260#ifdef HAVE_GETHOSTENT
370312ae 261 entry = gethostent ();
cd34a384
JB
262#else
263 entry = NULL;
264#endif
07513939
JB
265 if (! entry)
266 {
267 /* As far as I can tell, there's no good way to tell whether
268 zero means an error or end-of-file. The trick of
269 clearing errno before calling gethostent and checking it
270 afterwards doesn't cut it, because, on Linux, it seems to
271 try to contact some other server (YP?) and fails, which
272 is a benign failure. */
07513939
JB
273 return SCM_BOOL_F;
274 }
370312ae 275 }
a6d9e5ab 276 else if (SCM_STRINGP (host))
370312ae 277 {
a6d9e5ab
DH
278 SCM_STRING_COERCE_0TERMINATION_X (host);
279 entry = gethostbyname (SCM_STRING_CHARS (host));
370312ae
GH
280 }
281 else
282 {
d46e4713 283 inad.s_addr = htonl (SCM_NUM2ULONG (1,host));
370312ae
GH
284 entry = gethostbyaddr ((char *) &inad, sizeof (inad), AF_INET);
285 }
370312ae 286 if (!entry)
d46e4713 287 scm_resolv_error (FUNC_NAME, host);
5c11cc9d
GH
288
289 ve[0] = scm_makfromstr (entry->h_name,
290 (scm_sizet) strlen (entry->h_name), 0);
370312ae
GH
291 ve[1] = scm_makfromstrs (-1, entry->h_aliases);
292 ve[2] = SCM_MAKINUM (entry->h_addrtype + 0L);
293 ve[3] = SCM_MAKINUM (entry->h_length + 0L);
294 if (sizeof (struct in_addr) != entry->h_length)
295 {
296 ve[4] = SCM_BOOL_F;
297 return ans;
298 }
299 for (argv = entry->h_addr_list; argv[i]; i++);
300 while (i--)
301 {
302 inad = *(struct in_addr *) argv[i];
303 lst = scm_cons (scm_ulong2num (ntohl (inad.s_addr)), lst);
304 }
305 ve[4] = lst;
306 return ans;
307}
1bbd0b84 308#undef FUNC_NAME
370312ae
GH
309
310
07513939
JB
311/* In all subsequent getMUMBLE functions, when we're called with no
312 arguments, we're supposed to traverse the tables entry by entry.
313 However, there doesn't seem to be any documented way to distinguish
314 between end-of-table and an error; in both cases the functions
315 return zero. Gotta love Unix. For the time being, we clear errno,
316 and if we get a zero and errno is set, we signal an error. This
317 doesn't seem quite right (what if errno gets set as part of healthy
318 operation?), but it seems to work okay. We'll see. */
319
0e958795 320#if defined(HAVE_GETNETENT) && defined(HAVE_GETNETBYNAME) && defined(HAVE_GETNETBYADDR)
a1ec6916 321SCM_DEFINE (scm_getnet, "getnet", 0, 1, 0,
d46e4713 322 (SCM net),
b380b885
MD
323 "@deffnx procedure getnetbyname net-name\n"
324 "@deffnx procedure getnetbyaddr net-number\n"
325 "Look up a network by name or net number in the network database. The\n"
326 "@var{net-name} argument must be a string, and the @var{net-number}\n"
327 "argument must be an integer. @code{getnet} will accept either type of\n"
328 "argument, behaving like @code{getnetent} (see below) if no arguments are\n"
329 "given.")
1bbd0b84 330#define FUNC_NAME s_scm_getnet
370312ae
GH
331{
332 SCM ans;
333 SCM *ve;
334 struct netent *entry;
335
00ffa0e7 336 ans = scm_c_make_vector (4, SCM_UNSPECIFIED);
370312ae 337 ve = SCM_VELTS (ans);
d46e4713 338 if (SCM_UNBNDP (net))
370312ae 339 {
370312ae 340 entry = getnetent ();
07513939
JB
341 if (! entry)
342 {
1dd05fd8
MG
343 /* There's no good way to tell whether zero means an error
344 or end-of-file, so we always return #f. See `gethost'
345 for details. */
346 return SCM_BOOL_F;
07513939 347 }
370312ae 348 }
a6d9e5ab 349 else if (SCM_STRINGP (net))
370312ae 350 {
a6d9e5ab
DH
351 SCM_STRING_COERCE_0TERMINATION_X (net);
352 entry = getnetbyname (SCM_STRING_CHARS (net));
370312ae
GH
353 }
354 else
355 {
356 unsigned long netnum;
d46e4713 357 netnum = SCM_NUM2ULONG (1, net);
370312ae
GH
358 entry = getnetbyaddr (netnum, AF_INET);
359 }
370312ae 360 if (!entry)
e0c08f17 361 SCM_SYSERROR_MSG ("no such network ~A", SCM_LIST1 (net), errno);
370312ae
GH
362 ve[0] = scm_makfromstr (entry->n_name, (scm_sizet) strlen (entry->n_name), 0);
363 ve[1] = scm_makfromstrs (-1, entry->n_aliases);
364 ve[2] = SCM_MAKINUM (entry->n_addrtype + 0L);
365 ve[3] = scm_ulong2num (entry->n_net + 0L);
366 return ans;
367}
1bbd0b84 368#undef FUNC_NAME
0e958795 369#endif
370312ae 370
0e958795 371#ifdef HAVE_GETPROTOENT
a1ec6916 372SCM_DEFINE (scm_getproto, "getproto", 0, 1, 0,
d46e4713 373 (SCM protocol),
b380b885
MD
374 "@deffnx procedure getprotobyname name\n"
375 "@deffnx procedure getprotobynumber number\n"
376 "Look up a network protocol by name or by number. @code{getprotobyname}\n"
377 "takes a string argument, and @code{getprotobynumber} takes an integer\n"
378 "argument. @code{getproto} will accept either type, behaving like\n"
379 "@code{getprotoent} (see below) if no arguments are supplied.")
1bbd0b84 380#define FUNC_NAME s_scm_getproto
370312ae
GH
381{
382 SCM ans;
383 SCM *ve;
384 struct protoent *entry;
385
00ffa0e7 386 ans = scm_c_make_vector (3, SCM_UNSPECIFIED);
370312ae 387 ve = SCM_VELTS (ans);
d46e4713 388 if (SCM_UNBNDP (protocol))
370312ae 389 {
370312ae 390 entry = getprotoent ();
07513939
JB
391 if (! entry)
392 {
1dd05fd8
MG
393 /* There's no good way to tell whether zero means an error
394 or end-of-file, so we always return #f. See `gethost'
395 for details. */
396 return SCM_BOOL_F;
07513939 397 }
370312ae 398 }
a6d9e5ab 399 else if (SCM_STRINGP (protocol))
370312ae 400 {
a6d9e5ab
DH
401 SCM_STRING_COERCE_0TERMINATION_X (protocol);
402 entry = getprotobyname (SCM_STRING_CHARS (protocol));
370312ae
GH
403 }
404 else
405 {
406 unsigned long protonum;
d46e4713 407 protonum = SCM_NUM2ULONG (1,protocol);
370312ae
GH
408 entry = getprotobynumber (protonum);
409 }
370312ae 410 if (!entry)
e0c08f17 411 SCM_SYSERROR_MSG ("no such protocol ~A", SCM_LIST1 (protocol), errno);
370312ae
GH
412 ve[0] = scm_makfromstr (entry->p_name, (scm_sizet) strlen (entry->p_name), 0);
413 ve[1] = scm_makfromstrs (-1, entry->p_aliases);
414 ve[2] = SCM_MAKINUM (entry->p_proto + 0L);
415 return ans;
416}
1bbd0b84 417#undef FUNC_NAME
0e958795 418#endif
370312ae 419
370312ae 420static SCM
1bbd0b84 421scm_return_entry (struct servent *entry)
370312ae
GH
422{
423 SCM ans;
424 SCM *ve;
425
00ffa0e7 426 ans = scm_c_make_vector (4, SCM_UNSPECIFIED);
370312ae
GH
427 ve = SCM_VELTS (ans);
428 ve[0] = scm_makfromstr (entry->s_name, (scm_sizet) strlen (entry->s_name), 0);
429 ve[1] = scm_makfromstrs (-1, entry->s_aliases);
430 ve[2] = SCM_MAKINUM (ntohs (entry->s_port) + 0L);
431 ve[3] = scm_makfromstr (entry->s_proto, (scm_sizet) strlen (entry->s_proto), 0);
370312ae
GH
432 return ans;
433}
434
0e958795 435#ifdef HAVE_GETSERVENT
a1ec6916 436SCM_DEFINE (scm_getserv, "getserv", 0, 2, 0,
d46e4713 437 (SCM name, SCM protocol),
b380b885
MD
438 "@deffnx procedure getservbyname name protocol\n"
439 "@deffnx procedure getservbyport port protocol\n"
440 "Look up a network service by name or by service number, and return a\n"
441 "network service object. The @var{protocol} argument specifies the name\n"
442 "of the desired protocol; if the protocol found in the network service\n"
443 "database does not match this name, a system error is signalled.\n\n"
444 "The @code{getserv} procedure will take either a service name or number\n"
445 "as its first argument; if given no arguments, it behaves like\n"
446 "@code{getservent} (see below).")
1bbd0b84 447#define FUNC_NAME s_scm_getserv
370312ae
GH
448{
449 struct servent *entry;
450 if (SCM_UNBNDP (name))
451 {
370312ae 452 entry = getservent ();
07513939
JB
453 if (!entry)
454 {
1dd05fd8
MG
455 /* There's no good way to tell whether zero means an error
456 or end-of-file, so we always return #f. See `gethost'
457 for details. */
458 return SCM_BOOL_F;
07513939 459 }
370312ae
GH
460 return scm_return_entry (entry);
461 }
a6d9e5ab
DH
462 SCM_VALIDATE_STRING (2, protocol);
463 SCM_STRING_COERCE_0TERMINATION_X (protocol);
464 if (SCM_STRINGP (name))
370312ae 465 {
a6d9e5ab
DH
466 SCM_STRING_COERCE_0TERMINATION_X (name);
467 entry = getservbyname (SCM_STRING_CHARS (name), SCM_STRING_CHARS (protocol));
370312ae
GH
468 }
469 else
470 {
3b3b36dd 471 SCM_VALIDATE_INUM (1,name);
a6d9e5ab 472 entry = getservbyport (htons (SCM_INUM (name)), SCM_STRING_CHARS (protocol));
370312ae
GH
473 }
474 if (!entry)
e0c08f17 475 SCM_SYSERROR_MSG("no such service ~A", SCM_LIST1 (name), errno);
370312ae
GH
476 return scm_return_entry (entry);
477}
1bbd0b84 478#undef FUNC_NAME
0e958795 479#endif
370312ae 480
0e958795 481#if defined(HAVE_SETHOSTENT) && defined(HAVE_ENDHOSTENT)
a1ec6916 482SCM_DEFINE (scm_sethost, "sethost", 0, 1, 0,
d46e4713 483 (SCM stayopen),
b380b885
MD
484 "If @var{stayopen} is omitted, this is equivalent to @code{endhostent}.\n"
485 "Otherwise it is equivalent to @code{sethostent stayopen}.")
1bbd0b84 486#define FUNC_NAME s_scm_sethost
370312ae 487{
d46e4713 488 if (SCM_UNBNDP (stayopen))
370312ae
GH
489 endhostent ();
490 else
d46e4713 491 sethostent (SCM_NFALSEP (stayopen));
370312ae
GH
492 return SCM_UNSPECIFIED;
493}
1bbd0b84 494#undef FUNC_NAME
0e958795 495#endif
370312ae 496
0e958795 497#if defined(HAVE_SETNETENT) && defined(HAVE_ENDNETENT)
a1ec6916 498SCM_DEFINE (scm_setnet, "setnet", 0, 1, 0,
d46e4713 499 (SCM stayopen),
b380b885
MD
500 "If @var{stayopen} is omitted, this is equivalent to @code{endnetent}.\n"
501 "Otherwise it is equivalent to @code{setnetent stayopen}.")
1bbd0b84 502#define FUNC_NAME s_scm_setnet
370312ae 503{
d46e4713 504 if (SCM_UNBNDP (stayopen))
370312ae
GH
505 endnetent ();
506 else
d46e4713 507 setnetent (SCM_NFALSEP (stayopen));
370312ae
GH
508 return SCM_UNSPECIFIED;
509}
1bbd0b84 510#undef FUNC_NAME
0e958795 511#endif
370312ae 512
0e958795 513#if defined(HAVE_SETPROTOENT) && defined(HAVE_ENDPROTOENT)
a1ec6916 514SCM_DEFINE (scm_setproto, "setproto", 0, 1, 0,
d46e4713 515 (SCM stayopen),
b380b885
MD
516 "If @var{stayopen} is omitted, this is equivalent to @code{endprotoent}.\n"
517 "Otherwise it is equivalent to @code{setprotoent stayopen}.")
1bbd0b84 518#define FUNC_NAME s_scm_setproto
370312ae 519{
d46e4713 520 if (SCM_UNBNDP (stayopen))
370312ae
GH
521 endprotoent ();
522 else
d46e4713 523 setprotoent (SCM_NFALSEP (stayopen));
370312ae
GH
524 return SCM_UNSPECIFIED;
525}
1bbd0b84 526#undef FUNC_NAME
0e958795 527#endif
370312ae 528
0e958795 529#if defined(HAVE_SETSERVENT) && defined(HAVE_ENDSERVENT)
a1ec6916 530SCM_DEFINE (scm_setserv, "setserv", 0, 1, 0,
d46e4713 531 (SCM stayopen),
b380b885
MD
532 "If @var{stayopen} is omitted, this is equivalent to @code{endservent}.\n"
533 "Otherwise it is equivalent to @code{setservent stayopen}.")
1bbd0b84 534#define FUNC_NAME s_scm_setserv
370312ae 535{
d46e4713 536 if (SCM_UNBNDP (stayopen))
370312ae
GH
537 endservent ();
538 else
d46e4713 539 setservent (SCM_NFALSEP (stayopen));
370312ae
GH
540 return SCM_UNSPECIFIED;
541}
1bbd0b84 542#undef FUNC_NAME
0e958795 543#endif
370312ae
GH
544
545
546void
547scm_init_net_db ()
548{
549#ifdef INADDR_ANY
550 scm_sysintern ("INADDR_ANY", scm_ulong2num (INADDR_ANY));
551#endif
552#ifdef INADDR_BROADCAST
553 scm_sysintern ("INADDR_BROADCAST", scm_ulong2num (INADDR_BROADCAST));
554#endif
555#ifdef INADDR_NONE
556 scm_sysintern ("INADDR_NONE", scm_ulong2num (INADDR_NONE));
557#endif
558#ifdef INADDR_LOOPBACK
559 scm_sysintern ("INADDR_LOOPBACK", scm_ulong2num (INADDR_LOOPBACK));
560#endif
561
562 scm_add_feature ("net-db");
8dc9439f 563#ifndef SCM_MAGIC_SNARFER
a0599745 564#include "libguile/net_db.x"
8dc9439f 565#endif
370312ae 566}
89e00824
ML
567
568/*
569 Local Variables:
570 c-file-style: "gnu"
571 End:
572*/