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