1 /*	$NetBSD: dllfunc.c,v 1.3 2014/12/10 04:37:56 christos Exp $	*/
2 
3 /*
4  * dllfunc.c - wrapper functions
5  */
6 
7 /*
8  * Copyright (c) 2000,2002 Japan Network Information Center.
9  * All rights reserved.
10  *
11  * By using this file, you agree to the terms and conditions set forth bellow.
12  *
13  * 			LICENSE TERMS AND CONDITIONS
14  *
15  * The following License Terms and Conditions apply, unless a different
16  * license is obtained from Japan Network Information Center ("JPNIC"),
17  * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
18  * Chiyoda-ku, Tokyo 101-0047, Japan.
19  *
20  * 1. Use, Modification and Redistribution (including distribution of any
21  *    modified or derived work) in source and/or binary forms is permitted
22  *    under this License Terms and Conditions.
23  *
24  * 2. Redistribution of source code must retain the copyright notices as they
25  *    appear in each source code file, this License Terms and Conditions.
26  *
27  * 3. Redistribution in binary form must reproduce the Copyright Notice,
28  *    this License Terms and Conditions, in the documentation and/or other
29  *    materials provided with the distribution.  For the purposes of binary
30  *    distribution the "Copyright Notice" refers to the following language:
31  *    "Copyright (c) 2000-2002 Japan Network Information Center.  All rights reserved."
32  *
33  * 4. The name of JPNIC may not be used to endorse or promote products
34  *    derived from this Software without specific prior written approval of
35  *    JPNIC.
36  *
37  * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
38  *    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39  *    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
40  *    PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL JPNIC BE LIABLE
41  *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
45  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
46  *    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47  *    ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
48  */
49 
50 #include <windows.h>
51 #include <svcguid.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <process.h>
56 
57 #include "dlldef.h"
58 
59 #ifndef EAI_MEMORY
60 #define EAI_MEMORY	WSA_NOT_ENOUGH_MEMORY
61 #endif
62 #ifndef EAI_FAIL
63 #define EAI_FAIL	WSANO_RECOVERY
64 #endif
65 
66 static GUID guid_habn = SVCID_INET_HOSTADDRBYNAME;
67 static GUID guid_habis = SVCID_INET_HOSTADDRBYINETSTRING;
68 
69 #define SVCID_IS_HABN(p) (memcmp(p, &guid_habn, sizeof(GUID)) == 0)
70 #define SVCID_IS_HABIS(p) (memcmp(p, &guid_habis, sizeof(GUID)) == 0)
71 
72 /*
73  * Rename addrinfo to my_addrinfo for avoiding possible name conflict.
74  */
75 struct my_addrinfo {
76 	int     ai_flags;
77 	int     ai_family;
78 	int     ai_socktype;
79 	int     ai_protocol;
80 	size_t  ai_addrlen;
81 	char   *ai_canonname;
82 	struct sockaddr  *ai_addr;
83 	struct my_addrinfo  *ai_next;
84 };
85 
86 typedef struct obj_lock {
87 	void *key;
88 	struct obj_lock *next;
89 } obj_lock_t;
90 
91 #define OBJLOCKHASH_SIZE	127
92 static obj_lock_t *obj_lock_hash[OBJLOCKHASH_SIZE];
93 
94 static int	obj_hash(void *key);
95 static int	obj_islocked(void *key);
96 static void	obj_lock(void *key);
97 static void	obj_unlock(void *key);
98 static char	*decode_name_dynamic(const char *name, idn_resconf_t idnctx);
99 static struct my_addrinfo
100 		*copy_decode_addrinfo_dynamic(struct my_addrinfo *aip,
101 					      idn_resconf_t idnctx);
102 static void	free_copied_addrinfo(struct my_addrinfo *aip);
103 
104 WRAPPER_EXPORT int WSAAPI
gethostname(char FAR * name,int namelen)105 gethostname(char FAR * name, int namelen) {
106 	int ret;
107 
108 	TRACE("ENTER gethostname\n");
109 	ret = _org_gethostname(name, namelen);
110 	TRACE("LEAVE gethostname %d <%-.100s>\n", ret, name);
111 
112 	return (ret);
113 }
114 
115 WRAPPER_EXPORT struct hostent FAR * WSAAPI
gethostbyname(const char FAR * name)116 gethostbyname(const char FAR * name) {
117 	struct hostent FAR *ret;
118 	char    nbuff[256];
119 	char    hbuff[256];
120 	BOOL    stat;
121 	idn_resconf_t	encodeCtx;
122 
123 	TRACE("ENTER gethostbyname <%-.100s>\n",
124 	      (name != NULL ? name : "NULL"));
125 
126 	encodeCtx = idnGetContext();
127 
128 	if (encodeCtx == NULL || name == NULL) {
129 		ret = _org_gethostbyname(name);
130 	} else {
131 		stat = idnConvReq(encodeCtx, name, nbuff, sizeof(nbuff));
132 		if (stat == FALSE) {
133 			TRACE("idnConvReq failed\n");
134 			ret = NULL;
135 		} else {
136 			TRACE("Converted Name <%s>\n",
137 			      dumpName(nbuff, hbuff, sizeof(hbuff)));
138 			ret = _org_gethostbyname(nbuff);
139 		}
140 	}
141 
142 	if (ret != NULL && encodeCtx != NULL) {
143 		TRACE("Resulting Name <%s>\n",
144 		      dumpName(ret->h_name, hbuff, sizeof(hbuff)));
145 		stat = idnConvRsp(encodeCtx, ret->h_name,
146 				  nbuff, sizeof(nbuff));
147 		if (stat == FALSE) {
148 			TRACE("Decoding failed - return the name verbatim\n");
149 		} else {
150 			TRACE("Converted Back <%s>\n",
151 			      dumpName(nbuff, hbuff, sizeof(hbuff)));
152 			strcpy(ret->h_name, nbuff);
153 		}
154 	}
155 
156 	if (ret == NULL) {
157 		TRACE("LEAVE gethostbyname NULL\n");
158 	} else {
159 		TRACE("LEAVE gethostbyname <%s>\n",
160 		      dumpHost(ret, hbuff, sizeof(hbuff)));
161 	}
162 	return (ret);
163 }
164 
165 WRAPPER_EXPORT struct hostent FAR * WSAAPI
gethostbyaddr(const char FAR * addr,int len,int type)166 gethostbyaddr(const char FAR * addr, int len, int type) {
167 	struct hostent FAR *ret;
168 	char    nbuff[256];
169 	char    abuff[256];
170 	char    hbuff[256];
171 	BOOL    stat;
172 	idn_resconf_t	encodeCtx;
173 
174 	TRACE("ENTER gethostbyaddr <%s>\n",
175 	      dumpAddr(addr, len, abuff, sizeof(abuff)));
176 
177 	encodeCtx = idnGetContext();
178 
179 	ret = _org_gethostbyaddr(addr, len, type);
180 
181 	if (ret != NULL && encodeCtx != NULL) {
182 		TRACE("Resulting Name <%s>\n",
183 		      dumpName(ret->h_name, hbuff, sizeof(hbuff)));
184 		stat = idnConvRsp(encodeCtx, ret->h_name,
185 				  nbuff, sizeof(nbuff));
186 		if (stat == FALSE) {
187 			TRACE("Decoding failed - return the name verbatim\n");
188 		} else {
189 			TRACE("Converted Back <%s>\n",
190 			      dumpName(nbuff, hbuff, sizeof(hbuff)));
191 			strcpy(ret->h_name, nbuff);
192 		}
193 	}
194 
195 	if (ret == NULL) {
196 		TRACE("LEAVE gethostbyaddr NULL\n");
197 	} else {
198 		TRACE("LEAVE gethostbyaddr <%s>\n",
199 		      dumpHost(ret, hbuff, sizeof(hbuff)));
200 	}
201 	return (ret);
202 }
203 
204 WRAPPER_EXPORT HANDLE WSAAPI
WSAAsyncGetHostByName(HWND hWnd,u_int wMsg,const char FAR * name,char FAR * buf,int buflen)205 WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,
206 		      const char FAR * name, char FAR * buf, int buflen)
207 {
208 	HANDLE  ret;
209 	char    nbuff[256];
210 	char    hbuff[256];
211 	idn_resconf_t	encodeCtx;
212 
213 	TRACE("ENTER WSAAsyncGetHostByName <%-.100s>\n", name);
214 
215 	encodeCtx = idnGetContext();
216 
217 	if (encodeCtx == NULL || name == NULL) {
218 		ret = _org_WSAAsyncGetHostByName(hWnd, wMsg,
219 						 name, buf, buflen);
220 	} else {
221 		idnHook(hWnd, wMsg, buf, encodeCtx);
222 		idnConvReq(encodeCtx, name, nbuff, sizeof(nbuff));
223 		TRACE("Converted Name <%s>\n",
224 		      dumpName(nbuff, hbuff, sizeof(hbuff)));
225 		ret = _org_WSAAsyncGetHostByName(hWnd, wMsg, nbuff,
226 						 buf, buflen);
227 	}
228 
229 	TRACE("LEAVE WSAAsyncGetHostByName HANDLE %08x\n", ret);
230 
231 	return (ret);
232 }
233 
234 WRAPPER_EXPORT HANDLE WSAAPI
WSAAsyncGetHostByAddr(HWND hWnd,u_int wMsg,const char FAR * addr,int len,int type,char FAR * buf,int buflen)235 WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, const char FAR * addr,
236 		      int len, int type, char FAR * buf, int buflen)
237 {
238 	HANDLE  ret;
239 	char    abuff[256];
240 	idn_resconf_t	encodeCtx;
241 
242 	encodeCtx = idnGetContext();
243 
244 	if (encodeCtx != NULL) {
245 		idnHook(hWnd, wMsg, buf, encodeCtx);
246 	}
247 
248 	TRACE("ENTER WSAAsyncGetHostByAddr <%s>\n",
249 	      dumpAddr(addr, len, abuff, sizeof(abuff)));
250 	ret = _org_WSAAsyncGetHostByAddr(hWnd, wMsg, addr, len, type,
251 					 buf, buflen);
252 	TRACE("LEAVE WSAAsyncGetHostByAddr HANDLE %08x\n", ret);
253 
254 	return (ret);
255 }
256 
257 WRAPPER_EXPORT INT WSAAPI
WSALookupServiceBeginA(LPWSAQUERYSETA lpqsRestrictions,DWORD dwControlFlags,LPHANDLE lphLookup)258 WSALookupServiceBeginA(LPWSAQUERYSETA lpqsRestrictions,
259 		       DWORD dwControlFlags, LPHANDLE lphLookup)
260 {
261 	INT     ret;
262 	char    nbuff[256];
263 	char    hbuff[256];
264 	LPSTR   name = lpqsRestrictions->lpszServiceInstanceName;
265 	LPGUID  class = lpqsRestrictions->lpServiceClassId;
266 	idn_resconf_t	encodeCtx;
267 
268 	TRACE("ENTER WSALookupServiceBeginA <%-.100s>\n",
269 	      name == NULL ? "<NULL>" : name);
270 
271 	encodeCtx = idnGetContext();
272 
273 	if (name != NULL && encodeCtx != NULL && SVCID_IS_HABN(class) == 0) {
274 		idnConvReq(encodeCtx, name, nbuff, sizeof(nbuff));
275 		TRACE("Converted Name <%s>\n",
276 		      dumpName(nbuff, hbuff, sizeof(hbuff)));
277 		/* strcpy(lpqsRestrictions->lpszQueryString, nbuff); */
278 		lpqsRestrictions->lpszServiceInstanceName = nbuff;
279 	}
280 	ret = _org_WSALookupServiceBeginA(lpqsRestrictions,
281 					  dwControlFlags, lphLookup);
282 	TRACE("LEAVE WSALookupServiceBeginA %d\n", ret);
283 
284 	return (ret);
285 }
286 
287 WRAPPER_EXPORT INT WSAAPI
WSALookupServiceNextA(HANDLE hLookup,DWORD dwControlFlags,LPDWORD lpdwBufferLength,LPWSAQUERYSETA lpqsResults)288 WSALookupServiceNextA(HANDLE hLookup, DWORD dwControlFlags,
289 		      LPDWORD lpdwBufferLength, LPWSAQUERYSETA lpqsResults)
290 {
291 	INT     ret;
292 	char    nbuff[256];
293 	char    hbuff[256];
294 	LPGUID  class;
295 	idn_resconf_t	encodeCtx;
296 
297 	TRACE("ENTER WSALookupServiceNextA\n");
298 
299 	encodeCtx = idnGetContext();
300 
301 	ret = _org_WSALookupServiceNextA(hLookup, dwControlFlags,
302 					 lpdwBufferLength, lpqsResults);
303 	class = lpqsResults->lpServiceClassId;
304 
305 	if (ret == 0 &&
306 	    encodeCtx != NULL &&
307 	    (dwControlFlags & LUP_RETURN_NAME) &&
308 	    (SVCID_IS_HABN(class) || SVCID_IS_HABIS(class))) {
309 		TRACE("Resulting Name <%s>\n",
310 		      dumpName(lpqsResults->lpszServiceInstanceName,
311 			       hbuff, sizeof(hbuff)));
312 		if (idnConvRsp(encodeCtx,
313 			       lpqsResults->lpszServiceInstanceName,
314 			       nbuff, sizeof(nbuff)) == FALSE) {
315 			TRACE("Decoding failed - return the name verbatim\n");
316 		} else {
317 			TRACE("Converted Back <%s>\n",
318 			      dumpName(nbuff, hbuff, sizeof(hbuff)));
319 			strcpy(lpqsResults->lpszServiceInstanceName, nbuff);
320 		}
321 	}
322 	TRACE("LEAVE WSALookupServiceNextA %d <%s>\n", ret, nbuff);
323 
324 	return (ret);
325 }
326 
327 WRAPPER_EXPORT INT WSAAPI
WSALookupServiceBeginW(LPWSAQUERYSETW lpqsRestrictions,DWORD dwControlFlags,LPHANDLE lphLookup)328 WSALookupServiceBeginW(LPWSAQUERYSETW lpqsRestrictions,
329 		       DWORD dwControlFlags, LPHANDLE lphLookup)
330 {
331 	INT     ret;
332 
333 	TRACE("ENTER WSALookupServiceBeginW\n");
334 	ret = _org_WSALookupServiceBeginW(lpqsRestrictions,
335 					  dwControlFlags,lphLookup);
336 	TRACE("LEAVE WSALookupServiceBeginW %d\n", ret);
337 
338 	return (ret);
339 }
340 
341 WRAPPER_EXPORT INT WSAAPI
WSALookupServiceNextW(HANDLE hLookup,DWORD dwControlFlags,LPDWORD lpdwBufferLength,LPWSAQUERYSETW lpqsResults)342 WSALookupServiceNextW(HANDLE hLookup, DWORD dwControlFlags,
343 		      LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
344 {
345 	INT     ret;
346 
347 	TRACE("ENTER WSALookupServiceNextW\n");
348 	ret = _org_WSALookupServiceNextW(hLookup, dwControlFlags,
349 					 lpdwBufferLength, lpqsResults);
350 	TRACE("LEAVE WSALookupServiceNextW %d\n", ret);
351 
352 	return (ret);
353 }
354 
355 WRAPPER_EXPORT INT WSAAPI
WSALookupServiceEnd(HANDLE hLookup)356 WSALookupServiceEnd(HANDLE  hLookup) {
357 	INT     ret;
358 
359 	TRACE("ENTER WSALookupServiceEnd\n");
360 	ret = _org_WSALookupServiceEnd(hLookup);
361 	TRACE("LEAVE WSALookupServiceEnd %d\n", ret);
362 
363 	return (ret);
364 }
365 
366 static int
obj_hash(void * key)367 obj_hash(void *key) {
368 	/*
369 	 * Hash function for obj_*.
370 	 * 'key' is supposed to be an address.
371 	 */
372 	unsigned long v = (unsigned long)key;
373 
374 	return ((v >> 3) % OBJLOCKHASH_SIZE);
375 }
376 
377 static int
obj_islocked(void * key)378 obj_islocked(void *key)
379 {
380 	/*
381 	 * Check if the object specified by 'key' is locked.
382 	 * Return 1 if so, 0 otherwise.
383 	 */
384 	int h = obj_hash(key);
385 	obj_lock_t *olp = obj_lock_hash[h];
386 
387 	while (olp != NULL) {
388 		if (olp->key == key)
389 			return (1);
390 		olp = olp->next;
391 	}
392 	return (0);
393 }
394 
395 static void
obj_lock(void * key)396 obj_lock(void *key)
397 {
398 	/*
399 	 * Lock an object specified by 'key'.
400 	 */
401 	int h = obj_hash(key);
402 	obj_lock_t *olp;
403 
404 	olp = malloc(sizeof(obj_lock_t));
405 	if (olp != NULL) {
406 		olp->key = key;
407 		olp->next = obj_lock_hash[h];
408 		obj_lock_hash[h] = olp;
409 	}
410 }
411 
412 static void
obj_unlock(void * key)413 obj_unlock(void *key)
414 {
415 	/*
416 	 * Unlock an object specified by 'key'.
417 	 */
418 	int h = obj_hash(key);
419 	obj_lock_t *olp, *olp0;
420 
421 	olp = obj_lock_hash[h];
422 	olp0 = NULL;
423 	while (olp != NULL) {
424 		if (olp->key == key) {
425 			if (olp0 == NULL)
426 				obj_lock_hash[h] = olp->next;
427 			else
428 				olp0->next = olp->next;
429 			free(olp);
430 			return;
431 		}
432 		olp0 = olp;
433 		olp = olp->next;
434 	}
435 }
436 
437 static char *
decode_name_dynamic(const char * name,idn_resconf_t idnctx)438 decode_name_dynamic(const char *name, idn_resconf_t idnctx) {
439 	BOOL stat;
440 	char buf[256], tmp[256];
441 	char *s;
442 
443 	if (idnConvRsp(idnctx, name, buf, sizeof(buf)) == TRUE) {
444 		TRACE("Converted Back <%s>\n",
445 		      dumpName(buf, tmp, sizeof(tmp)));
446 		name = buf;
447 	} else {
448 		TRACE("Decoding failed - return the name verbatim\n");
449 	}
450 	s = malloc(strlen(name) + 1);
451 	if (s == NULL)
452 		return (NULL);
453 	else
454 		return (strcpy(s, name));
455 }
456 
457 static struct my_addrinfo *
copy_decode_addrinfo_dynamic(struct my_addrinfo * aip,idn_resconf_t idnctx)458 copy_decode_addrinfo_dynamic(struct my_addrinfo *aip, idn_resconf_t idnctx)
459 {
460 	struct my_addrinfo *newaip;
461 
462 	if (aip == NULL)
463 		return (NULL);
464 
465 	newaip = malloc(sizeof(struct my_addrinfo) + aip->ai_addrlen);
466 	if (newaip == NULL)
467 		return (NULL);
468 
469 	*newaip = *aip;
470 	newaip->ai_addr = (struct sockaddr *)(newaip + 1);
471 	memcpy(newaip->ai_addr, aip->ai_addr, aip->ai_addrlen);
472 
473 	if (newaip->ai_canonname != NULL)
474 		newaip->ai_canonname = decode_name_dynamic(aip->ai_canonname,
475 							   idnctx);
476 
477 	newaip->ai_next = copy_decode_addrinfo_dynamic(aip->ai_next, idnctx);
478 	return (newaip);
479 }
480 
481 static void
free_copied_addrinfo(struct my_addrinfo * aip)482 free_copied_addrinfo(struct my_addrinfo *aip) {
483 	while (aip != NULL) {
484 		struct my_addrinfo *next = aip->ai_next;
485 
486 		if (aip->ai_canonname != NULL)
487 			free(aip->ai_canonname);
488 		free(aip);
489 		aip = next;
490 	}
491 }
492 
493 WRAPPER_EXPORT int WSAAPI
getaddrinfo(const char * nodename,const char * servname,const struct my_addrinfo * hints,struct my_addrinfo ** res)494 getaddrinfo(const char *nodename, const char *servname,
495 	    const struct my_addrinfo *hints, struct my_addrinfo **res)
496 {
497 	char namebuf[256];
498 	BOOL stat;
499 	struct my_addrinfo *aip;
500 	int err;
501 	idn_resconf_t	encodeCtx;
502 
503 	TRACE("ENTER getaddrinfo <%-.100s>\n", nodename ? nodename : "NULL");
504 
505 	encodeCtx = idnGetContext();
506 
507 	if (nodename == NULL || encodeCtx == NULL) {
508 		TRACE("conversion unnecessary\n");
509 		err = _org_getaddrinfo(nodename, servname, hints, res);
510 	} else {
511 		stat = idnConvReq(encodeCtx, nodename,
512 				  namebuf, sizeof(namebuf));
513 		if (stat == TRUE) {
514 			nodename = namebuf;
515 			TRACE("Converted Name <%-.100s>\n", namebuf);
516 		}
517 
518 		err = _org_getaddrinfo(nodename, servname, hints, &aip);
519 		if (err == 0 && aip != NULL) {
520 			*res = copy_decode_addrinfo_dynamic(aip, encodeCtx);
521 			if (*res == NULL)
522 				err = EAI_FAIL;
523 			else
524 				obj_lock(*res);
525 			if (aip != NULL)
526 				_org_freeaddrinfo(aip);
527 		}
528 	}
529 
530 	TRACE("LEAVE getaddrinfo %d\n", err);
531 	return (err);
532 }
533 
534 WRAPPER_EXPORT void WSAAPI
freeaddrinfo(struct my_addrinfo * aip)535 freeaddrinfo(struct my_addrinfo *aip) {
536 	TRACE("ENTER freeaddrinfo aip=%p\n", (void *)aip);
537 
538 	if (obj_islocked(aip)) {
539 		/*
540 		 * We allocated the data.
541 		 */
542 		obj_unlock(aip);
543 		free_copied_addrinfo(aip);
544 	} else {
545 		/*
546 		 * It was allocated the original getaddrinfo().
547 		 */
548 		TRACE("Not allocated by the wrapper\n");
549 		_org_freeaddrinfo(aip);
550 	}
551 	TRACE("LEAVE freeaddrinfo\n");
552 }
553 
554 WRAPPER_EXPORT int WSAAPI
getnameinfo(const struct sockaddr * sa,DWORD salen,char * host,DWORD hostlen,char * serv,DWORD servlen,int flags)555 getnameinfo(const struct sockaddr *sa, DWORD salen,
556 	    char *host, DWORD hostlen, char *serv,
557 	    DWORD servlen, int flags)
558 {
559 	char name[256];
560 	size_t namelen = sizeof(name);
561 	int code;
562 	BOOL stat;
563 	idn_resconf_t	encodeCtx;
564 
565 	TRACE("ENTER getnameinfo\n");
566 
567 	encodeCtx = idnGetContext();
568 
569 	if (host == NULL || hostlen == 0 || encodeCtx == NULL) {
570 		TRACE("conversion unnecessary\n");
571 		code = _org_getnameinfo(sa, salen, host, hostlen,
572 					serv, servlen, flags);
573 	} else {
574 		code = _org_getnameinfo(sa, salen, name, namelen,
575 					serv, servlen, flags);
576 		if (code == 0 && name[0] != '\0') {
577 			stat = idnConvRsp(encodeCtx, name, host, hostlen);
578 			if (stat == FALSE) {
579 				TRACE("Decoding failed - return the name verbatim\n");
580 				if (strlen(name) >= hostlen) {
581 					code = EAI_FAIL;
582 				} else {
583 					strcpy(host, name);
584 				}
585 			} else {
586 				TRACE("Converted Back <%s>\n",
587 				      dumpName(host, name, sizeof(name)));
588 			}
589 		}
590 	}
591 
592 	TRACE("LEAVE getnameinfo %d\n", code);
593 	return (code);
594 }
595