* _scm.h: Removed #include <errno.h>.
[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)
5d2d2ffc 361 SCM_SYSERROR_MSG ("no such network ~A",
d46e4713 362 scm_listify (net, SCM_UNDEFINED), errno);
370312ae
GH
363 ve[0] = scm_makfromstr (entry->n_name, (scm_sizet) strlen (entry->n_name), 0);
364 ve[1] = scm_makfromstrs (-1, entry->n_aliases);
365 ve[2] = SCM_MAKINUM (entry->n_addrtype + 0L);
366 ve[3] = scm_ulong2num (entry->n_net + 0L);
367 return ans;
368}
1bbd0b84 369#undef FUNC_NAME
0e958795 370#endif
370312ae 371
0e958795 372#ifdef HAVE_GETPROTOENT
a1ec6916 373SCM_DEFINE (scm_getproto, "getproto", 0, 1, 0,
d46e4713 374 (SCM protocol),
b380b885
MD
375 "@deffnx procedure getprotobyname name\n"
376 "@deffnx procedure getprotobynumber number\n"
377 "Look up a network protocol by name or by number. @code{getprotobyname}\n"
378 "takes a string argument, and @code{getprotobynumber} takes an integer\n"
379 "argument. @code{getproto} will accept either type, behaving like\n"
380 "@code{getprotoent} (see below) if no arguments are supplied.")
1bbd0b84 381#define FUNC_NAME s_scm_getproto
370312ae
GH
382{
383 SCM ans;
384 SCM *ve;
385 struct protoent *entry;
386
00ffa0e7 387 ans = scm_c_make_vector (3, SCM_UNSPECIFIED);
370312ae 388 ve = SCM_VELTS (ans);
d46e4713 389 if (SCM_UNBNDP (protocol))
370312ae 390 {
370312ae 391 entry = getprotoent ();
07513939
JB
392 if (! entry)
393 {
1dd05fd8
MG
394 /* There's no good way to tell whether zero means an error
395 or end-of-file, so we always return #f. See `gethost'
396 for details. */
397 return SCM_BOOL_F;
07513939 398 }
370312ae 399 }
a6d9e5ab 400 else if (SCM_STRINGP (protocol))
370312ae 401 {
a6d9e5ab
DH
402 SCM_STRING_COERCE_0TERMINATION_X (protocol);
403 entry = getprotobyname (SCM_STRING_CHARS (protocol));
370312ae
GH
404 }
405 else
406 {
407 unsigned long protonum;
d46e4713 408 protonum = SCM_NUM2ULONG (1,protocol);
370312ae
GH
409 entry = getprotobynumber (protonum);
410 }
370312ae 411 if (!entry)
70d63753 412 SCM_SYSERROR_MSG ("no such protocol ~A",
d46e4713 413 scm_listify (protocol, SCM_UNDEFINED), errno);
370312ae
GH
414 ve[0] = scm_makfromstr (entry->p_name, (scm_sizet) strlen (entry->p_name), 0);
415 ve[1] = scm_makfromstrs (-1, entry->p_aliases);
416 ve[2] = SCM_MAKINUM (entry->p_proto + 0L);
417 return ans;
418}
1bbd0b84 419#undef FUNC_NAME
0e958795 420#endif
370312ae 421
370312ae 422static SCM
1bbd0b84 423scm_return_entry (struct servent *entry)
370312ae
GH
424{
425 SCM ans;
426 SCM *ve;
427
00ffa0e7 428 ans = scm_c_make_vector (4, SCM_UNSPECIFIED);
370312ae
GH
429 ve = SCM_VELTS (ans);
430 ve[0] = scm_makfromstr (entry->s_name, (scm_sizet) strlen (entry->s_name), 0);
431 ve[1] = scm_makfromstrs (-1, entry->s_aliases);
432 ve[2] = SCM_MAKINUM (ntohs (entry->s_port) + 0L);
433 ve[3] = scm_makfromstr (entry->s_proto, (scm_sizet) strlen (entry->s_proto), 0);
370312ae
GH
434 return ans;
435}
436
0e958795 437#ifdef HAVE_GETSERVENT
a1ec6916 438SCM_DEFINE (scm_getserv, "getserv", 0, 2, 0,
d46e4713 439 (SCM name, SCM protocol),
b380b885
MD
440 "@deffnx procedure getservbyname name protocol\n"
441 "@deffnx procedure getservbyport port protocol\n"
442 "Look up a network service by name or by service number, and return a\n"
443 "network service object. The @var{protocol} argument specifies the name\n"
444 "of the desired protocol; if the protocol found in the network service\n"
445 "database does not match this name, a system error is signalled.\n\n"
446 "The @code{getserv} procedure will take either a service name or number\n"
447 "as its first argument; if given no arguments, it behaves like\n"
448 "@code{getservent} (see below).")
1bbd0b84 449#define FUNC_NAME s_scm_getserv
370312ae
GH
450{
451 struct servent *entry;
452 if (SCM_UNBNDP (name))
453 {
370312ae 454 entry = getservent ();
07513939
JB
455 if (!entry)
456 {
1dd05fd8
MG
457 /* There's no good way to tell whether zero means an error
458 or end-of-file, so we always return #f. See `gethost'
459 for details. */
460 return SCM_BOOL_F;
07513939 461 }
370312ae
GH
462 return scm_return_entry (entry);
463 }
a6d9e5ab
DH
464 SCM_VALIDATE_STRING (2, protocol);
465 SCM_STRING_COERCE_0TERMINATION_X (protocol);
466 if (SCM_STRINGP (name))
370312ae 467 {
a6d9e5ab
DH
468 SCM_STRING_COERCE_0TERMINATION_X (name);
469 entry = getservbyname (SCM_STRING_CHARS (name), SCM_STRING_CHARS (protocol));
370312ae
GH
470 }
471 else
472 {
3b3b36dd 473 SCM_VALIDATE_INUM (1,name);
a6d9e5ab 474 entry = getservbyport (htons (SCM_INUM (name)), SCM_STRING_CHARS (protocol));
370312ae
GH
475 }
476 if (!entry)
70d63753 477 SCM_SYSERROR_MSG("no such service ~A",
1bbd0b84 478 scm_listify (name, SCM_UNDEFINED), errno);
370312ae
GH
479 return scm_return_entry (entry);
480}
1bbd0b84 481#undef FUNC_NAME
0e958795 482#endif
370312ae 483
0e958795 484#if defined(HAVE_SETHOSTENT) && defined(HAVE_ENDHOSTENT)
a1ec6916 485SCM_DEFINE (scm_sethost, "sethost", 0, 1, 0,
d46e4713 486 (SCM stayopen),
b380b885
MD
487 "If @var{stayopen} is omitted, this is equivalent to @code{endhostent}.\n"
488 "Otherwise it is equivalent to @code{sethostent stayopen}.")
1bbd0b84 489#define FUNC_NAME s_scm_sethost
370312ae 490{
d46e4713 491 if (SCM_UNBNDP (stayopen))
370312ae
GH
492 endhostent ();
493 else
d46e4713 494 sethostent (SCM_NFALSEP (stayopen));
370312ae
GH
495 return SCM_UNSPECIFIED;
496}
1bbd0b84 497#undef FUNC_NAME
0e958795 498#endif
370312ae 499
0e958795 500#if defined(HAVE_SETNETENT) && defined(HAVE_ENDNETENT)
a1ec6916 501SCM_DEFINE (scm_setnet, "setnet", 0, 1, 0,
d46e4713 502 (SCM stayopen),
b380b885
MD
503 "If @var{stayopen} is omitted, this is equivalent to @code{endnetent}.\n"
504 "Otherwise it is equivalent to @code{setnetent stayopen}.")
1bbd0b84 505#define FUNC_NAME s_scm_setnet
370312ae 506{
d46e4713 507 if (SCM_UNBNDP (stayopen))
370312ae
GH
508 endnetent ();
509 else
d46e4713 510 setnetent (SCM_NFALSEP (stayopen));
370312ae
GH
511 return SCM_UNSPECIFIED;
512}
1bbd0b84 513#undef FUNC_NAME
0e958795 514#endif
370312ae 515
0e958795 516#if defined(HAVE_SETPROTOENT) && defined(HAVE_ENDPROTOENT)
a1ec6916 517SCM_DEFINE (scm_setproto, "setproto", 0, 1, 0,
d46e4713 518 (SCM stayopen),
b380b885
MD
519 "If @var{stayopen} is omitted, this is equivalent to @code{endprotoent}.\n"
520 "Otherwise it is equivalent to @code{setprotoent stayopen}.")
1bbd0b84 521#define FUNC_NAME s_scm_setproto
370312ae 522{
d46e4713 523 if (SCM_UNBNDP (stayopen))
370312ae
GH
524 endprotoent ();
525 else
d46e4713 526 setprotoent (SCM_NFALSEP (stayopen));
370312ae
GH
527 return SCM_UNSPECIFIED;
528}
1bbd0b84 529#undef FUNC_NAME
0e958795 530#endif
370312ae 531
0e958795 532#if defined(HAVE_SETSERVENT) && defined(HAVE_ENDSERVENT)
a1ec6916 533SCM_DEFINE (scm_setserv, "setserv", 0, 1, 0,
d46e4713 534 (SCM stayopen),
b380b885
MD
535 "If @var{stayopen} is omitted, this is equivalent to @code{endservent}.\n"
536 "Otherwise it is equivalent to @code{setservent stayopen}.")
1bbd0b84 537#define FUNC_NAME s_scm_setserv
370312ae 538{
d46e4713 539 if (SCM_UNBNDP (stayopen))
370312ae
GH
540 endservent ();
541 else
d46e4713 542 setservent (SCM_NFALSEP (stayopen));
370312ae
GH
543 return SCM_UNSPECIFIED;
544}
1bbd0b84 545#undef FUNC_NAME
0e958795 546#endif
370312ae
GH
547
548
549void
550scm_init_net_db ()
551{
552#ifdef INADDR_ANY
553 scm_sysintern ("INADDR_ANY", scm_ulong2num (INADDR_ANY));
554#endif
555#ifdef INADDR_BROADCAST
556 scm_sysintern ("INADDR_BROADCAST", scm_ulong2num (INADDR_BROADCAST));
557#endif
558#ifdef INADDR_NONE
559 scm_sysintern ("INADDR_NONE", scm_ulong2num (INADDR_NONE));
560#endif
561#ifdef INADDR_LOOPBACK
562 scm_sysintern ("INADDR_LOOPBACK", scm_ulong2num (INADDR_LOOPBACK));
563#endif
564
565 scm_add_feature ("net-db");
8dc9439f 566#ifndef SCM_MAGIC_SNARFER
a0599745 567#include "libguile/net_db.x"
8dc9439f 568#endif
370312ae 569}
89e00824
ML
570
571/*
572 Local Variables:
573 c-file-style: "gnu"
574 End:
575*/