1 /* IPv4-only variant of gethostbyname.
2 Copyright (C) 2016-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation; either version 2.1 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, see <https://www.gnu.org/licenses/>. */
18
19 #include <errno.h>
20 #include <netdb.h>
21 #include <rpc/rpc.h>
22 #include <scratch_buffer.h>
23 #include <string.h>
24
25 int
__libc_rpc_gethostbyname(const char * host,struct sockaddr_in * addr)26 __libc_rpc_gethostbyname (const char *host, struct sockaddr_in *addr)
27 {
28 struct hostent hostbuf;
29 struct hostent *hp = NULL;
30 int herr;
31 struct scratch_buffer tmpbuf;
32 scratch_buffer_init (&tmpbuf);
33
34 while (__gethostbyname2_r (host, AF_INET,
35 &hostbuf, tmpbuf.data, tmpbuf.length, &hp,
36 &herr) != 0
37 || hp == NULL)
38 if (herr != NETDB_INTERNAL || errno != ERANGE)
39 {
40 struct rpc_createerr *ce = &get_rpc_createerr ();
41 ce->cf_stat = RPC_UNKNOWNHOST;
42 scratch_buffer_free (&tmpbuf);
43 return -1;
44 }
45 else
46 {
47 if (!scratch_buffer_grow (&tmpbuf))
48 {
49 /* If memory allocation failed, allocating the RPC error
50 structure might could as well, so this could lead to a
51 crash. */
52 struct rpc_createerr *ce = &get_rpc_createerr ();
53 ce->cf_stat = RPC_SYSTEMERROR;
54 ce->cf_error.re_errno = ENOMEM;
55 return -1;
56 }
57 }
58
59 if (hp->h_addrtype != AF_INET || hp->h_length != sizeof (addr->sin_addr))
60 {
61 struct rpc_createerr *ce = &get_rpc_createerr ();
62 ce->cf_stat = RPC_SYSTEMERROR;
63 ce->cf_error.re_errno = EAFNOSUPPORT;
64 scratch_buffer_free (&tmpbuf);
65 return -1;
66 }
67
68 addr->sin_family = AF_INET;
69 addr->sin_port = htons (0);
70 memcpy (&addr->sin_addr, hp->h_addr, sizeof (addr->sin_addr));
71 scratch_buffer_free (&tmpbuf);
72 return 0;
73 }
74