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