~ubuntu-branches/ubuntu/natty/ibm-3270/natty

« back to all changes in this revision

Viewing changes to wpr3287/resolver.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2009-12-14 11:48:53 UTC
  • mfrom: (1.1.4 upstream) (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091214114853-mywixml32hct9jr1
Tags: 3.3.10ga4-2
* Fix section to match override.
* Use debhelper compat level 7.
* Use 3.0 (quilt) source format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright 2007 by Paul Mattes.
3
 
 *  Permission to use, copy, modify, and distribute this software and its
4
 
 *  documentation for any purpose and without fee is hereby granted,
5
 
 *  provided that the above copyright notice appear in all copies and that
6
 
 *  both that copyright notice and this permission notice appear in
7
 
 *  supporting documentation.
8
 
 *
9
 
 * x3270, c3270, wc3270, s3270, tcl3270, pr3287 and wpr3287 are distributed in
10
 
 * the hope that they will be useful, but WITHOUT ANY WARRANTY; without even
11
 
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
 
 * See the file LICENSE for more details.
 
2
 * Copyright (c) 2007-2009, Paul Mattes.
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions are met:
 
7
 *     * Redistributions of source code must retain the above copyright
 
8
 *       notice, this list of conditions and the following disclaimer.
 
9
 *     * Redistributions in binary form must reproduce the above copyright
 
10
 *       notice, this list of conditions and the following disclaimer in the
 
11
 *       documentation and/or other materials provided with the distribution.
 
12
 *     * Neither the names of Paul Mattes nor the names of his contributors
 
13
 *       may be used to endorse or promote products derived from this software
 
14
 *       without specific prior written permission.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY PAUL MATTES "AS IS" AND ANY EXPRESS OR IMPLIED
 
17
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 
19
 * EVENT SHALL PAUL MATTES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
20
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
21
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
22
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
23
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
24
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
25
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13
26
 */
14
27
 
15
28
/*
17
30
 *              Hostname resolution.
18
31
 */
19
32
 
20
 
/*
21
 
 * This file is compiled three different ways:
22
 
 *
23
 
 * - With no special #defines, it defines hostname resolution for the main
24
 
 *   program: resolve_host_and_port().  On non-Windows platforms, the name
25
 
 *   look-up is directly in the function.  On Windows platforms, the name
26
 
 *   look-up is done by the function dresolve_host_and_port() in an
27
 
 *   OS-specific DLL.
28
 
 *
29
 
 * - With W3N4 #defined, it defines dresolve_host_and_port() as IPv4-only
30
 
 *   hostname resolution for a Windows DLL.  This is for Windows 2000 or
31
 
 *   earlier.
32
 
 *
33
 
 * - With W3N46 #defined, it defines dresolve_host_and_port() as IPv4/IPv6
34
 
 *   hostname resolution for a Windows DLL.  This is for Windows XP or
35
 
 *   later.
36
 
 */
37
 
 
38
33
#include "globals.h"
39
34
 
40
 
#if defined(W3N4) || defined(W3N46) /*[*/
41
 
#if !defined(_WIN32)
42
 
#error W3N4/W3N46 valid only on Windows.
43
 
#endif /*]*/
44
 
#define ISDLL 1
45
 
#endif /*]*/
46
 
 
47
35
#if !defined(_WIN32) /*[*/
48
36
#include <sys/socket.h>
49
37
#include <netinet/in.h>
50
38
#include <netdb.h>
 
39
#include <arpa/inet.h>
51
40
#else /*][*/
52
 
#if defined(W3N46) /*[*/
53
 
  /* Compiling DLL for WinXP or later: Expose getaddrinfo()/freeaddrinfo(). */
54
 
#undef _WIN32_WINNT
55
 
#define _WIN32_WINNT 0x0501
56
 
#endif /*]*/
57
41
#include <winsock2.h>
58
42
#include <ws2tcpip.h>
59
 
#if defined(W3N4) /*[*/
60
 
  /* Compiling DLL for Win2K or earlier: No IPv6. */
61
 
#undef AF_INET6
62
 
#endif /*]*/
63
43
#endif /*]*/
64
44
 
65
45
#include <stdio.h>
66
46
#include "resolverc.h"
67
47
#include "w3miscc.h"
68
48
 
69
 
#if defined(_WIN32) && !defined(ISDLL) /*[*/
70
 
typedef int rhproc(const char *, char *, unsigned short *, struct sockaddr *,
71
 
        socklen_t *, char *, int);
72
 
#define DLL_RESOLVER_NAME "dresolve_host_and_port"
 
49
#if defined(_MSC_VER) /*[*/
 
50
#include "Msc/deprecated.h"
 
51
#endif /*]*/
 
52
 
 
53
#if defined(_WIN32) /*[*/
 
54
static int win32_getaddrinfo(const char *node, const char *service,
 
55
        const struct addrinfo *hints, struct addrinfo **res);
 
56
static void win32_freeaddrinfo(struct addrinfo *res);
 
57
static int win32_getnameinfo(const struct sockaddr *sa, socklen_t salen,
 
58
        char *host, size_t hostlen, char *serv, size_t servlen, int flags);
 
59
#undef getaddrinfo
 
60
#define getaddrinfo     win32_getaddrinfo
 
61
#undef freeaddrinfo
 
62
#define freeaddrinfo    win32_freeaddrinfo
 
63
#undef getnameinfo
 
64
#define getnameinfo     win32_getnameinfo
73
65
#endif /*]*/
74
66
 
75
67
/*
77
69
 * Returns 0 for success, -1 for fatal error (name resolution impossible),
78
70
 *  -2 for simple error (cannot resolve the name).
79
71
 */
80
 
#if !defined(ISDLL) /*[*/
81
 
int
82
 
resolve_host_and_port(const char *host, char *portname, unsigned short *pport,
83
 
        struct sockaddr *sa, socklen_t *sa_len, char *errmsg, int em_len)
84
 
#else /*][*/
85
 
int
86
 
dresolve_host_and_port(const char *host, char *portname, unsigned short *pport,
87
 
        struct sockaddr *sa, socklen_t *sa_len, char *errmsg, int em_len)
88
 
#endif /*]*/
89
 
{
90
 
#if !defined(_WIN32) || defined(ISDLL) /*[*/
91
 
 
92
 
        /* Non-Windows version, or Windows DLL version. */
93
 
#if defined(AF_INET6) /*[*/
94
 
        struct addrinfo  hints, *res;
95
 
        int              rc;
96
 
 
97
 
        /* Use getaddrinfo() to resolve the hostname and port together. */
98
 
        (void) memset(&hints, '\0', sizeof(struct addrinfo));
99
 
        hints.ai_flags = 0;
100
 
        hints.ai_family = PF_UNSPEC;
101
 
        hints.ai_socktype = SOCK_STREAM;
102
 
        hints.ai_protocol = IPPROTO_TCP;
103
 
        rc = getaddrinfo(host, portname, &hints, &res);
104
 
        if (rc != 0) {
105
 
                snprintf(errmsg, em_len, "%s/%s: %s", host, portname,
106
 
                                gai_strerror(rc));
107
 
                return -2;
108
 
        }
109
 
        switch (res->ai_family) {
110
 
        case AF_INET:
111
 
                *pport =
112
 
                    ntohs(((struct sockaddr_in *)res->ai_addr)->sin_port);
113
 
                break;
114
 
        case AF_INET6:
115
 
                *pport =
116
 
                    ntohs(((struct sockaddr_in6 *)res->ai_addr)->sin6_port);
117
 
                break;
118
 
        default:
119
 
                snprintf(errmsg, em_len, "%s: unknown family %d", host,
120
 
                        res->ai_family);
121
 
                freeaddrinfo(res);
122
 
                return -1;
123
 
        }
124
 
        (void) memcpy(sa, res->ai_addr, res->ai_addrlen);
125
 
        *sa_len = res->ai_addrlen;
126
 
        freeaddrinfo(res);
127
 
 
128
 
#else /*][*/
129
 
 
130
 
        struct hostent  *hp;
131
 
        struct servent  *sp;
132
 
        unsigned short   port;
133
 
        unsigned long    lport;
134
 
        char            *ptr;
135
 
        struct sockaddr_in *sin = (struct sockaddr_in *)sa;
136
 
 
137
 
        /* Get the port number. */
138
 
        lport = strtoul(portname, &ptr, 0);
139
 
        if (ptr == portname || *ptr != '\0' || lport == 0L || lport & ~0xffff) {
140
 
                if (!(sp = getservbyname(portname, "tcp"))) {
141
 
                        snprintf(errmsg, em_len,
142
 
                            "Unknown port number or service: %s",
143
 
                            portname);
144
 
                        return -1;
145
 
                }
146
 
                port = sp->s_port;
147
 
        } else
148
 
                port = htons((unsigned short)lport);
149
 
        *pport = ntohs(port);
150
 
 
151
 
        /* Use gethostbyname() to resolve the hostname. */
152
 
        hp = gethostbyname(host);
153
 
        if (hp == (struct hostent *) 0) {
154
 
                sin->sin_family = AF_INET;
155
 
                sin->sin_addr.s_addr = inet_addr(host);
156
 
                if (sin->sin_addr.s_addr == (unsigned long)-1) {
157
 
                        snprintf(errmsg, em_len, "Unknown host:\n%s", host);
158
 
                        return -2;
159
 
                }
160
 
        } else {
161
 
                sin->sin_family = hp->h_addrtype;
162
 
                (void) memmove(&sin->sin_addr, hp->h_addr, hp->h_length);
163
 
        }
164
 
        sin->sin_port = port;
165
 
        *sa_len = sizeof(struct sockaddr_in);
166
 
 
167
 
#endif /*]*/
168
 
#else /*][*/
169
 
 
170
 
        /* Win32 version: Use the right DLL. */
171
 
        static int loaded = FALSE;
172
 
        static FARPROC p = NULL;
173
 
 
174
 
        if (!loaded) {
175
 
                OSVERSIONINFO info;
176
 
                HMODULE handle;
177
 
                char *dllname;
178
 
 
179
 
                /* Figure out if we are pre- or post XP. */
180
 
                memset(&info, '\0', sizeof(info));
181
 
                info.dwOSVersionInfoSize = sizeof(info);
182
 
 
183
 
                if (GetVersionEx(&info) == 0) {
184
 
                        snprintf(errmsg, em_len,
185
 
                                "Can't retrieve OS version: %s",
186
 
                                win32_strerror(GetLastError()));
187
 
                        return -1;
188
 
                }
189
 
 
190
 
                /*
191
 
                 * For pre-XP, load the IPv4-only DLL.
192
 
                 * For XP and later, use the IPv4/IPv6 DLL.
193
 
                 */
194
 
                if (info.dwMajorVersion < 5 ||
195
 
                    (info.dwMajorVersion == 5 && info.dwMinorVersion < 1))
196
 
                        dllname = "w3n4.dll";
197
 
                else
198
 
                        dllname = "w3n46.dll";
199
 
                handle = LoadLibrary(dllname);
200
 
                if (handle == NULL) {
201
 
                        snprintf(errmsg, em_len, "Can't load %s: %s",
202
 
                                dllname, win32_strerror(GetLastError()));
203
 
                        return -1;
204
 
                }
205
 
 
206
 
                /* Look up the entry point we need. */
207
 
                p = GetProcAddress(handle, DLL_RESOLVER_NAME);
208
 
                if (p == NULL) {
209
 
                        snprintf(errmsg, em_len,
210
 
                                "Can't resolve " DLL_RESOLVER_NAME
211
 
                                " in %s: %s", dllname,
212
 
                                win32_strerror(GetLastError()));
213
 
                        return -1;
214
 
                }
215
 
 
216
 
                loaded = TRUE;
217
 
        }
218
 
 
219
 
        /* Use the DLL function to resolve the hostname and port. */
220
 
        return ((rhproc *)p)(host, portname, pport, sa, sa_len, errmsg, em_len);
221
 
#endif /*]*/
222
 
 
223
 
        return 0;
224
 
}
 
72
int
 
73
resolve_host_and_port(const char *host, char *portname, int ix,
 
74
        unsigned short *pport, struct sockaddr *sa, socklen_t *sa_len,
 
75
        char *errmsg, int em_len, int *lastp)
 
76
{
 
77
#if defined(_WIN32) /*[*/
 
78
        OSVERSIONINFO info;
 
79
        Boolean has_getaddrinfo = False;
 
80
 
 
81
        /* Figure out if we should use gethostbyname() or getaddrinfo(). */
 
82
        memset(&info, '\0', sizeof(info));
 
83
        info.dwOSVersionInfoSize = sizeof(info);
 
84
        if (GetVersionEx(&info) == 0) {
 
85
                fprintf(stderr, "Can't get Windows version\n");
 
86
                exit(1);
 
87
        }
 
88
        has_getaddrinfo =
 
89
            (info.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS &&
 
90
             info.dwMajorVersion >= 5 &&
 
91
             info.dwMinorVersion >= 1);
 
92
 
 
93
        if (has_getaddrinfo)
 
94
#endif /*]*/
 
95
        {
 
96
#if defined(AF_INET6) /*[*/
 
97
                struct addrinfo  hints, *res0, *res;
 
98
                int              rc;
 
99
 
 
100
                /*
 
101
                 * Use getaddrinfo() to resolve the hostname and port
 
102
                 * together.
 
103
                 */
 
104
                (void) memset(&hints, '\0', sizeof(struct addrinfo));
 
105
                hints.ai_flags = 0;
 
106
                hints.ai_family = PF_UNSPEC;
 
107
                hints.ai_socktype = SOCK_STREAM;
 
108
                hints.ai_protocol = IPPROTO_TCP;
 
109
                rc = getaddrinfo(host, portname, &hints, &res0);
 
110
                if (rc != 0) {
 
111
                        snprintf(errmsg, em_len, "%s/%s:\n%s", host,
 
112
                                        portname? portname: "(none)",
 
113
                                        gai_strerror(rc));
 
114
                        return -2;
 
115
                }
 
116
                res = res0;
 
117
 
 
118
                /*
 
119
                 * Return the reqested element.
 
120
                 * Hopefully the list will not change between calls.
 
121
                 */
 
122
                while (ix && res->ai_next != NULL) {
 
123
                        res = res->ai_next;
 
124
                        ix--;
 
125
                }
 
126
                if (res == NULL) {
 
127
                        /* Ran off the end?  The list must have changed. */
 
128
                        snprintf(errmsg, em_len, "%s/%s:\n%s", host,
 
129
                                portname? portname: "(none)",
 
130
                                gai_strerror(EAI_AGAIN));
 
131
                        freeaddrinfo(res);
 
132
                        return -2;
 
133
                }
 
134
 
 
135
                switch (res->ai_family) {
 
136
                case AF_INET:
 
137
                        *pport = ntohs(((struct sockaddr_in *)
 
138
                                    res->ai_addr)->sin_port);
 
139
                        break;
 
140
                case AF_INET6:
 
141
                        *pport = ntohs(((struct sockaddr_in6 *)
 
142
                                    res->ai_addr)->sin6_port);
 
143
                        break;
 
144
                default:
 
145
                        snprintf(errmsg, em_len, "%s:\nunknown family %d", host,
 
146
                                res->ai_family);
 
147
                        freeaddrinfo(res);
 
148
                        return -1;
 
149
                }
 
150
                (void) memcpy(sa, res->ai_addr, res->ai_addrlen);
 
151
                *sa_len = res->ai_addrlen;
 
152
                if (lastp != NULL)
 
153
                        *lastp = (res->ai_next == NULL);
 
154
                freeaddrinfo(res0);
 
155
#endif /*]*/
 
156
        }
 
157
#if defined(_WIN32) /*[*/
 
158
        else
 
159
#endif /*]*/
 
160
 
 
161
#if defined(_WIN32) || !defined(AF_INET6) /*[*/
 
162
        {
 
163
                struct hostent  *hp;
 
164
                struct servent  *sp;
 
165
                unsigned short   port;
 
166
                unsigned long    lport;
 
167
                char            *ptr;
 
168
                struct sockaddr_in *sin = (struct sockaddr_in *)sa;
 
169
 
 
170
                /* Get the port number. */
 
171
                lport = strtoul(portname, &ptr, 0);
 
172
                if (ptr == portname || *ptr != '\0' || lport == 0L ||
 
173
                            lport & ~0xffff) {
 
174
                        if (!(sp = getservbyname(portname, "tcp"))) {
 
175
                                snprintf(errmsg, em_len,
 
176
                                    "Unknown port number or service: %s",
 
177
                                    portname);
 
178
                                return -1;
 
179
                        }
 
180
                        port = sp->s_port;
 
181
                } else
 
182
                        port = htons((unsigned short)lport);
 
183
                *pport = ntohs(port);
 
184
 
 
185
                /* Use gethostbyname() to resolve the hostname. */
 
186
                hp = gethostbyname(host);
 
187
                if (hp == (struct hostent *) 0) {
 
188
                        sin->sin_family = AF_INET;
 
189
                        sin->sin_addr.s_addr = inet_addr(host);
 
190
                        if (sin->sin_addr.s_addr == (unsigned long)-1) {
 
191
                                snprintf(errmsg, em_len,
 
192
                                        "Unknown host:\n%s", host);
 
193
                                return -2;
 
194
                        }
 
195
                        if (lastp != NULL)
 
196
                                *lastp = True;
 
197
                } else {
 
198
                        int i;
 
199
 
 
200
                        for (i = 0; i < ix; i++) {
 
201
                                if (hp->h_addr_list[i] == NULL) {
 
202
                                        snprintf(errmsg, em_len,
 
203
                                                "Unknown host:\n%s", host);
 
204
                                        return -2;
 
205
                                }
 
206
                        }
 
207
                        sin->sin_family = hp->h_addrtype;
 
208
                        (void) memmove(&sin->sin_addr,
 
209
                                hp->h_addr_list[i],
 
210
                                hp->h_length);
 
211
                        if (lastp != NULL)
 
212
                                *lastp = (hp->h_addr_list[i + 1] == NULL);
 
213
                }
 
214
                sin->sin_port = port;
 
215
                *sa_len = sizeof(struct sockaddr_in);
 
216
        }
 
217
 
 
218
#endif /*]*/
 
219
 
 
220
        return 0;
 
221
}
 
222
 
 
223
/*
 
224
 * Resolve a sockaddr into a numeric hostname and port.
 
225
 * Returns 0 for success, -1 for failure.
 
226
 */
 
227
int
 
228
numeric_host_and_port(const struct sockaddr *sa, socklen_t salen, char *host,
 
229
        size_t hostlen, char *serv, size_t servlen, char *errmsg, int em_len)
 
230
{
 
231
#if defined(_WIN32) /*[*/
 
232
        OSVERSIONINFO info;
 
233
        Boolean has_getnameinfo = False;
 
234
 
 
235
        /* Figure out if we should use inet_ntoa() or getnameinfo(). */
 
236
        memset(&info, '\0', sizeof(info));
 
237
        info.dwOSVersionInfoSize = sizeof(info);
 
238
        if (GetVersionEx(&info) == 0) {
 
239
                fprintf(stderr, "Can't get Windows version\n");
 
240
                exit(1);
 
241
        }
 
242
        has_getnameinfo =
 
243
            (info.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS &&
 
244
             info.dwMajorVersion >= 5 &&
 
245
             info.dwMinorVersion >= 1);
 
246
 
 
247
        if (has_getnameinfo)
 
248
#endif /*]*/
 
249
        {
 
250
#if defined(AF_INET6) /*[*/
 
251
                int      rc;
 
252
 
 
253
                /* Use getnameinfo(). */
 
254
                rc = getnameinfo(sa, salen, host, hostlen, serv, servlen,
 
255
                        NI_NUMERICHOST | NI_NUMERICSERV);
 
256
                if (rc != 0) {
 
257
                        snprintf(errmsg, em_len, "%s", gai_strerror(rc));
 
258
                        return -1;
 
259
                }
 
260
#endif /*]*/
 
261
        }
 
262
#if defined(_WIN32) /*[*/
 
263
        else
 
264
#endif /*]*/
 
265
 
 
266
#if defined(_WIN32) || !defined(AF_INET6) /*[*/
 
267
        {
 
268
                struct sockaddr_in *sin = (struct sockaddr_in *)sa;
 
269
 
 
270
                /* Use inet_ntoa() and snprintf(). */
 
271
                snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr));
 
272
                snprintf(serv, servlen, "%u", ntohs(sin->sin_port));
 
273
        }
 
274
 
 
275
#endif /*]*/
 
276
 
 
277
        return 0;
 
278
}
 
279
 
 
280
#if defined(_WIN32) /*[*/
 
281
/*
 
282
 * Windows-specific versions of getaddrinfo(), freeaddrinfo() and
 
283
 * gai_strerror().
 
284
 * The symbols are resolved from ws2_32.dll at run-time, instead of
 
285
 * by linking against ws2_32.lib, because they are not defined on all
 
286
 * versions of Windows.
 
287
 */
 
288
typedef int (__stdcall *gai_fn)(const char *, const char *,
 
289
        const struct addrinfo *, struct addrinfo **);
 
290
typedef void (__stdcall *fai_fn)(struct addrinfo*);
 
291
typedef int (__stdcall *gni_fn)(const struct sockaddr *, socklen_t, char *,
 
292
        size_t, char *, size_t, int);
 
293
 
 
294
/* Resolve a symbol in ws2_32.dll. */
 
295
static FARPROC
 
296
get_ws2_32(const char *symbol)
 
297
{
 
298
        static HMODULE ws2_32_handle = NULL;
 
299
        FARPROC p;
 
300
 
 
301
        if (ws2_32_handle == NULL) {
 
302
                ws2_32_handle = LoadLibrary("ws2_32.dll");
 
303
                if (ws2_32_handle == NULL) {
 
304
                        fprintf(stderr, "Can't load ws2_32.dll: %s\n",
 
305
                                win32_strerror(GetLastError()));
 
306
                        exit(1);
 
307
                }
 
308
        }
 
309
        p = GetProcAddress(ws2_32_handle, symbol);
 
310
        if (p == NULL) {
 
311
                fprintf(stderr, "Can't resolve %s in ws2_32.dll: %s\n",
 
312
                        symbol, win32_strerror(GetLastError()));
 
313
                exit(1);
 
314
        }
 
315
        return p;
 
316
}
 
317
 
 
318
static int
 
319
win32_getaddrinfo(const char *node, const char *service,
 
320
        const struct addrinfo *hints, struct addrinfo **res)
 
321
{
 
322
        static FARPROC gai_p = NULL;
 
323
 
 
324
        if (gai_p == NULL)
 
325
                gai_p = get_ws2_32("getaddrinfo");
 
326
        return ((gai_fn)gai_p)(node, service, hints, res);
 
327
}
 
328
 
 
329
static void
 
330
win32_freeaddrinfo(struct addrinfo *res)
 
331
{
 
332
        static FARPROC fai_p = NULL;
 
333
 
 
334
        if (fai_p == NULL)
 
335
                fai_p = get_ws2_32("freeaddrinfo");
 
336
        ((fai_fn)fai_p)(res);
 
337
}
 
338
 
 
339
static int
 
340
win32_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
 
341
        size_t hostlen, char *serv, size_t servlen, int flags)
 
342
{
 
343
        static FARPROC gni_p = NULL;
 
344
 
 
345
        if (gni_p == NULL)
 
346
                gni_p = get_ws2_32("getnameinfo");
 
347
        return ((gni_fn)gni_p)(sa, salen, host, hostlen, serv, servlen, flags);
 
348
}
 
349
#endif /*]*/