]>
Commit | Line | Data |
---|---|---|
5c6e6747 | 1 | /* IPv4-only variant of gethostbyname. |
6d7e8eda | 2 | Copyright (C) 2016-2023 Free Software Foundation, Inc. |
5c6e6747 FW |
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 | |
5a82c748 | 17 | not, see <https://www.gnu.org/licenses/>. */ |
5c6e6747 FW |
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 | |
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 | } |