summaryrefslogtreecommitdiffstats
path: root/contrib/idn/idnkit-1.0-src/wsock/wsock20/dllfunc.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/idn/idnkit-1.0-src/wsock/wsock20/dllfunc.c')
-rw-r--r--contrib/idn/idnkit-1.0-src/wsock/wsock20/dllfunc.c592
1 files changed, 592 insertions, 0 deletions
diff --git a/contrib/idn/idnkit-1.0-src/wsock/wsock20/dllfunc.c b/contrib/idn/idnkit-1.0-src/wsock/wsock20/dllfunc.c
new file mode 100644
index 0000000..cec2d06
--- /dev/null
+++ b/contrib/idn/idnkit-1.0-src/wsock/wsock20/dllfunc.c
@@ -0,0 +1,592 @@
+/*
+ * dllfunc.c - wrapper functions
+ */
+
+/*
+ * Copyright (c) 2000,2002 Japan Network Information Center.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set forth bellow.
+ *
+ * LICENSE TERMS AND CONDITIONS
+ *
+ * The following License Terms and Conditions apply, unless a different
+ * license is obtained from Japan Network Information Center ("JPNIC"),
+ * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
+ * Chiyoda-ku, Tokyo 101-0047, Japan.
+ *
+ * 1. Use, Modification and Redistribution (including distribution of any
+ * modified or derived work) in source and/or binary forms is permitted
+ * under this License Terms and Conditions.
+ *
+ * 2. Redistribution of source code must retain the copyright notices as they
+ * appear in each source code file, this License Terms and Conditions.
+ *
+ * 3. Redistribution in binary form must reproduce the Copyright Notice,
+ * this License Terms and Conditions, in the documentation and/or other
+ * materials provided with the distribution. For the purposes of binary
+ * distribution the "Copyright Notice" refers to the following language:
+ * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
+ *
+ * 4. The name of JPNIC may not be used to endorse or promote products
+ * derived from this Software without specific prior written approval of
+ * JPNIC.
+ *
+ * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <windows.h>
+#include <svcguid.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <process.h>
+
+#include "dlldef.h"
+
+#ifndef EAI_MEMORY
+#define EAI_MEMORY WSA_NOT_ENOUGH_MEMORY
+#endif
+#ifndef EAI_FAIL
+#define EAI_FAIL WSANO_RECOVERY
+#endif
+
+static GUID guid_habn = SVCID_INET_HOSTADDRBYNAME;
+static GUID guid_habis = SVCID_INET_HOSTADDRBYINETSTRING;
+
+#define SVCID_IS_HABN(p) (memcmp(p, &guid_habn, sizeof(GUID)) == 0)
+#define SVCID_IS_HABIS(p) (memcmp(p, &guid_habis, sizeof(GUID)) == 0)
+
+/*
+ * Rename addrinfo to my_addrinfo for avoiding possible name conflict.
+ */
+struct my_addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ char *ai_canonname;
+ struct sockaddr *ai_addr;
+ struct my_addrinfo *ai_next;
+};
+
+typedef struct obj_lock {
+ void *key;
+ struct obj_lock *next;
+} obj_lock_t;
+
+#define OBJLOCKHASH_SIZE 127
+static obj_lock_t *obj_lock_hash[OBJLOCKHASH_SIZE];
+
+static int obj_hash(void *key);
+static int obj_islocked(void *key);
+static void obj_lock(void *key);
+static void obj_unlock(void *key);
+static char *decode_name_dynamic(const char *name, idn_resconf_t idnctx);
+static struct my_addrinfo
+ *copy_decode_addrinfo_dynamic(struct my_addrinfo *aip,
+ idn_resconf_t idnctx);
+static void free_copied_addrinfo(struct my_addrinfo *aip);
+
+WRAPPER_EXPORT int WSAAPI
+gethostname(char FAR * name, int namelen) {
+ int ret;
+
+ TRACE("ENTER gethostname\n");
+ ret = _org_gethostname(name, namelen);
+ TRACE("LEAVE gethostname %d <%-.100s>\n", ret, name);
+
+ return (ret);
+}
+
+WRAPPER_EXPORT struct hostent FAR * WSAAPI
+gethostbyname(const char FAR * name) {
+ struct hostent FAR *ret;
+ char nbuff[256];
+ char hbuff[256];
+ BOOL stat;
+ idn_resconf_t encodeCtx;
+
+ TRACE("ENTER gethostbyname <%-.100s>\n",
+ (name != NULL ? name : "NULL"));
+
+ encodeCtx = idnGetContext();
+
+ if (encodeCtx == NULL || name == NULL) {
+ ret = _org_gethostbyname(name);
+ } else {
+ stat = idnConvReq(encodeCtx, name, nbuff, sizeof(nbuff));
+ if (stat == FALSE) {
+ TRACE("idnConvReq failed\n");
+ ret = NULL;
+ } else {
+ TRACE("Converted Name <%s>\n",
+ dumpName(nbuff, hbuff, sizeof(hbuff)));
+ ret = _org_gethostbyname(nbuff);
+ }
+ }
+
+ if (ret != NULL && encodeCtx != NULL) {
+ TRACE("Resulting Name <%s>\n",
+ dumpName(ret->h_name, hbuff, sizeof(hbuff)));
+ stat = idnConvRsp(encodeCtx, ret->h_name,
+ nbuff, sizeof(nbuff));
+ if (stat == FALSE) {
+ TRACE("Decoding failed - return the name verbatim\n");
+ } else {
+ TRACE("Converted Back <%s>\n",
+ dumpName(nbuff, hbuff, sizeof(hbuff)));
+ strcpy(ret->h_name, nbuff);
+ }
+ }
+
+ if (ret == NULL) {
+ TRACE("LEAVE gethostbyname NULL\n");
+ } else {
+ TRACE("LEAVE gethostbyname <%s>\n",
+ dumpHost(ret, hbuff, sizeof(hbuff)));
+ }
+ return (ret);
+}
+
+WRAPPER_EXPORT struct hostent FAR * WSAAPI
+gethostbyaddr(const char FAR * addr, int len, int type) {
+ struct hostent FAR *ret;
+ char nbuff[256];
+ char abuff[256];
+ char hbuff[256];
+ BOOL stat;
+ idn_resconf_t encodeCtx;
+
+ TRACE("ENTER gethostbyaddr <%s>\n",
+ dumpAddr(addr, len, abuff, sizeof(abuff)));
+
+ encodeCtx = idnGetContext();
+
+ ret = _org_gethostbyaddr(addr, len, type);
+
+ if (ret != NULL && encodeCtx != NULL) {
+ TRACE("Resulting Name <%s>\n",
+ dumpName(ret->h_name, hbuff, sizeof(hbuff)));
+ stat = idnConvRsp(encodeCtx, ret->h_name,
+ nbuff, sizeof(nbuff));
+ if (stat == FALSE) {
+ TRACE("Decoding failed - return the name verbatim\n");
+ } else {
+ TRACE("Converted Back <%s>\n",
+ dumpName(nbuff, hbuff, sizeof(hbuff)));
+ strcpy(ret->h_name, nbuff);
+ }
+ }
+
+ if (ret == NULL) {
+ TRACE("LEAVE gethostbyaddr NULL\n");
+ } else {
+ TRACE("LEAVE gethostbyaddr <%s>\n",
+ dumpHost(ret, hbuff, sizeof(hbuff)));
+ }
+ return (ret);
+}
+
+WRAPPER_EXPORT HANDLE WSAAPI
+WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,
+ const char FAR * name, char FAR * buf, int buflen)
+{
+ HANDLE ret;
+ char nbuff[256];
+ char hbuff[256];
+ idn_resconf_t encodeCtx;
+
+ TRACE("ENTER WSAAsyncGetHostByName <%-.100s>\n", name);
+
+ encodeCtx = idnGetContext();
+
+ if (encodeCtx == NULL || name == NULL) {
+ ret = _org_WSAAsyncGetHostByName(hWnd, wMsg,
+ name, buf, buflen);
+ } else {
+ idnHook(hWnd, wMsg, buf, encodeCtx);
+ idnConvReq(encodeCtx, name, nbuff, sizeof(nbuff));
+ TRACE("Converted Name <%s>\n",
+ dumpName(nbuff, hbuff, sizeof(hbuff)));
+ ret = _org_WSAAsyncGetHostByName(hWnd, wMsg, nbuff,
+ buf, buflen);
+ }
+
+ TRACE("LEAVE WSAAsyncGetHostByName HANDLE %08x\n", ret);
+
+ return (ret);
+}
+
+WRAPPER_EXPORT HANDLE WSAAPI
+WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, const char FAR * addr,
+ int len, int type, char FAR * buf, int buflen)
+{
+ HANDLE ret;
+ char abuff[256];
+ idn_resconf_t encodeCtx;
+
+ encodeCtx = idnGetContext();
+
+ if (encodeCtx != NULL) {
+ idnHook(hWnd, wMsg, buf, encodeCtx);
+ }
+
+ TRACE("ENTER WSAAsyncGetHostByAddr <%s>\n",
+ dumpAddr(addr, len, abuff, sizeof(abuff)));
+ ret = _org_WSAAsyncGetHostByAddr(hWnd, wMsg, addr, len, type,
+ buf, buflen);
+ TRACE("LEAVE WSAAsyncGetHostByAddr HANDLE %08x\n", ret);
+
+ return (ret);
+}
+
+WRAPPER_EXPORT INT WSAAPI
+WSALookupServiceBeginA(LPWSAQUERYSETA lpqsRestrictions,
+ DWORD dwControlFlags, LPHANDLE lphLookup)
+{
+ INT ret;
+ char nbuff[256];
+ char hbuff[256];
+ LPSTR name = lpqsRestrictions->lpszServiceInstanceName;
+ LPGUID class = lpqsRestrictions->lpServiceClassId;
+ idn_resconf_t encodeCtx;
+
+ TRACE("ENTER WSALookupServiceBeginA <%-.100s>\n",
+ name == NULL ? "<NULL>" : name);
+
+ encodeCtx = idnGetContext();
+
+ if (name != NULL && encodeCtx != NULL && SVCID_IS_HABN(class) == 0) {
+ idnConvReq(encodeCtx, name, nbuff, sizeof(nbuff));
+ TRACE("Converted Name <%s>\n",
+ dumpName(nbuff, hbuff, sizeof(hbuff)));
+ /* strcpy(lpqsRestrictions->lpszQueryString, nbuff); */
+ lpqsRestrictions->lpszServiceInstanceName = nbuff;
+ }
+ ret = _org_WSALookupServiceBeginA(lpqsRestrictions,
+ dwControlFlags, lphLookup);
+ TRACE("LEAVE WSALookupServiceBeginA %d\n", ret);
+
+ return (ret);
+}
+
+WRAPPER_EXPORT INT WSAAPI
+WSALookupServiceNextA(HANDLE hLookup, DWORD dwControlFlags,
+ LPDWORD lpdwBufferLength, LPWSAQUERYSETA lpqsResults)
+{
+ INT ret;
+ char nbuff[256];
+ char hbuff[256];
+ LPGUID class;
+ idn_resconf_t encodeCtx;
+
+ TRACE("ENTER WSALookupServiceNextA\n");
+
+ encodeCtx = idnGetContext();
+
+ ret = _org_WSALookupServiceNextA(hLookup, dwControlFlags,
+ lpdwBufferLength, lpqsResults);
+ class = lpqsResults->lpServiceClassId;
+
+ if (ret == 0 &&
+ encodeCtx != NULL &&
+ (dwControlFlags & LUP_RETURN_NAME) &&
+ (SVCID_IS_HABN(class) || SVCID_IS_HABIS(class))) {
+ TRACE("Resulting Name <%s>\n",
+ dumpName(lpqsResults->lpszServiceInstanceName,
+ hbuff, sizeof(hbuff)));
+ if (idnConvRsp(encodeCtx,
+ lpqsResults->lpszServiceInstanceName,
+ nbuff, sizeof(nbuff)) == FALSE) {
+ TRACE("Decoding failed - return the name verbatim\n");
+ } else {
+ TRACE("Converted Back <%s>\n",
+ dumpName(nbuff, hbuff, sizeof(hbuff)));
+ strcpy(lpqsResults->lpszServiceInstanceName, nbuff);
+ }
+ }
+ TRACE("LEAVE WSALookupServiceNextA %d <%s>\n", ret, nbuff);
+
+ return (ret);
+}
+
+WRAPPER_EXPORT INT WSAAPI
+WSALookupServiceBeginW(LPWSAQUERYSETW lpqsRestrictions,
+ DWORD dwControlFlags, LPHANDLE lphLookup)
+{
+ INT ret;
+
+ TRACE("ENTER WSALookupServiceBeginW\n");
+ ret = _org_WSALookupServiceBeginW(lpqsRestrictions,
+ dwControlFlags,lphLookup);
+ TRACE("LEAVE WSALookupServiceBeginW %d\n", ret);
+
+ return (ret);
+}
+
+WRAPPER_EXPORT INT WSAAPI
+WSALookupServiceNextW(HANDLE hLookup, DWORD dwControlFlags,
+ LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
+{
+ INT ret;
+
+ TRACE("ENTER WSALookupServiceNextW\n");
+ ret = _org_WSALookupServiceNextW(hLookup, dwControlFlags,
+ lpdwBufferLength, lpqsResults);
+ TRACE("LEAVE WSALookupServiceNextW %d\n", ret);
+
+ return (ret);
+}
+
+WRAPPER_EXPORT INT WSAAPI
+WSALookupServiceEnd(HANDLE hLookup) {
+ INT ret;
+
+ TRACE("ENTER WSALookupServiceEnd\n");
+ ret = _org_WSALookupServiceEnd(hLookup);
+ TRACE("LEAVE WSALookupServiceEnd %d\n", ret);
+
+ return (ret);
+}
+
+static int
+obj_hash(void *key) {
+ /*
+ * Hash function for obj_*.
+ * 'key' is supposed to be an address.
+ */
+ unsigned long v = (unsigned long)key;
+
+ return ((v >> 3) % OBJLOCKHASH_SIZE);
+}
+
+static int
+obj_islocked(void *key)
+{
+ /*
+ * Check if the object specified by 'key' is locked.
+ * Return 1 if so, 0 otherwise.
+ */
+ int h = obj_hash(key);
+ obj_lock_t *olp = obj_lock_hash[h];
+
+ while (olp != NULL) {
+ if (olp->key == key)
+ return (1);
+ olp = olp->next;
+ }
+ return (0);
+}
+
+static void
+obj_lock(void *key)
+{
+ /*
+ * Lock an object specified by 'key'.
+ */
+ int h = obj_hash(key);
+ obj_lock_t *olp;
+
+ olp = malloc(sizeof(obj_lock_t));
+ if (olp != NULL) {
+ olp->key = key;
+ olp->next = obj_lock_hash[h];
+ obj_lock_hash[h] = olp;
+ }
+}
+
+static void
+obj_unlock(void *key)
+{
+ /*
+ * Unlock an object specified by 'key'.
+ */
+ int h = obj_hash(key);
+ obj_lock_t *olp, *olp0;
+
+ olp = obj_lock_hash[h];
+ olp0 = NULL;
+ while (olp != NULL) {
+ if (olp->key == key) {
+ if (olp0 == NULL)
+ obj_lock_hash[h] = olp->next;
+ else
+ olp0->next = olp->next;
+ free(olp);
+ return;
+ }
+ olp0 = olp;
+ olp = olp->next;
+ }
+}
+
+static char *
+decode_name_dynamic(const char *name, idn_resconf_t idnctx) {
+ BOOL stat;
+ char buf[256], tmp[256];
+ char *s;
+
+ if (idnConvRsp(idnctx, name, buf, sizeof(buf)) == TRUE) {
+ TRACE("Converted Back <%s>\n",
+ dumpName(buf, tmp, sizeof(tmp)));
+ name = buf;
+ } else {
+ TRACE("Decoding failed - return the name verbatim\n");
+ }
+ s = malloc(strlen(name) + 1);
+ if (s == NULL)
+ return (NULL);
+ else
+ return (strcpy(s, name));
+}
+
+static struct my_addrinfo *
+copy_decode_addrinfo_dynamic(struct my_addrinfo *aip, idn_resconf_t idnctx)
+{
+ struct my_addrinfo *newaip;
+
+ if (aip == NULL)
+ return (NULL);
+
+ newaip = malloc(sizeof(struct my_addrinfo) + aip->ai_addrlen);
+ if (newaip == NULL)
+ return (NULL);
+
+ *newaip = *aip;
+ newaip->ai_addr = (struct sockaddr *)(newaip + 1);
+ memcpy(newaip->ai_addr, aip->ai_addr, aip->ai_addrlen);
+
+ if (newaip->ai_canonname != NULL)
+ newaip->ai_canonname = decode_name_dynamic(aip->ai_canonname,
+ idnctx);
+
+ newaip->ai_next = copy_decode_addrinfo_dynamic(aip->ai_next, idnctx);
+ return (newaip);
+}
+
+static void
+free_copied_addrinfo(struct my_addrinfo *aip) {
+ while (aip != NULL) {
+ struct my_addrinfo *next = aip->ai_next;
+
+ if (aip->ai_canonname != NULL)
+ free(aip->ai_canonname);
+ free(aip);
+ aip = next;
+ }
+}
+
+WRAPPER_EXPORT int WSAAPI
+getaddrinfo(const char *nodename, const char *servname,
+ const struct my_addrinfo *hints, struct my_addrinfo **res)
+{
+ char namebuf[256];
+ BOOL stat;
+ struct my_addrinfo *aip;
+ int err;
+ idn_resconf_t encodeCtx;
+
+ TRACE("ENTER getaddrinfo <%-.100s>\n", nodename ? nodename : "NULL");
+
+ encodeCtx = idnGetContext();
+
+ if (nodename == NULL || encodeCtx == NULL) {
+ TRACE("conversion unnecessary\n");
+ err = _org_getaddrinfo(nodename, servname, hints, res);
+ } else {
+ stat = idnConvReq(encodeCtx, nodename,
+ namebuf, sizeof(namebuf));
+ if (stat == TRUE) {
+ nodename = namebuf;
+ TRACE("Converted Name <%-.100s>\n", namebuf);
+ }
+
+ err = _org_getaddrinfo(nodename, servname, hints, &aip);
+ if (err == 0 && aip != NULL) {
+ *res = copy_decode_addrinfo_dynamic(aip, encodeCtx);
+ if (*res == NULL)
+ err = EAI_FAIL;
+ else
+ obj_lock(*res);
+ if (aip != NULL)
+ _org_freeaddrinfo(aip);
+ }
+ }
+
+ TRACE("LEAVE getaddrinfo %d\n", err);
+ return (err);
+}
+
+WRAPPER_EXPORT void WSAAPI
+freeaddrinfo(struct my_addrinfo *aip) {
+ TRACE("ENTER freeaddrinfo aip=%p\n", (void *)aip);
+
+ if (obj_islocked(aip)) {
+ /*
+ * We allocated the data.
+ */
+ obj_unlock(aip);
+ free_copied_addrinfo(aip);
+ } else {
+ /*
+ * It was allocated the original getaddrinfo().
+ */
+ TRACE("Not allocated by the wrapper\n");
+ _org_freeaddrinfo(aip);
+ }
+ TRACE("LEAVE freeaddrinfo\n");
+}
+
+WRAPPER_EXPORT int WSAAPI
+getnameinfo(const struct sockaddr *sa, DWORD salen,
+ char *host, DWORD hostlen, char *serv,
+ DWORD servlen, int flags)
+{
+ char name[256];
+ size_t namelen = sizeof(name);
+ int code;
+ BOOL stat;
+ idn_resconf_t encodeCtx;
+
+ TRACE("ENTER getnameinfo\n");
+
+ encodeCtx = idnGetContext();
+
+ if (host == NULL || hostlen == 0 || encodeCtx == NULL) {
+ TRACE("conversion unnecessary\n");
+ code = _org_getnameinfo(sa, salen, host, hostlen,
+ serv, servlen, flags);
+ } else {
+ code = _org_getnameinfo(sa, salen, name, namelen,
+ serv, servlen, flags);
+ if (code == 0 && name[0] != '\0') {
+ stat = idnConvRsp(encodeCtx, name, host, hostlen);
+ if (stat == FALSE) {
+ TRACE("Decoding failed - return the name verbatim\n");
+ if (strlen(name) >= hostlen) {
+ code = EAI_FAIL;
+ } else {
+ strcpy(host, name);
+ }
+ } else {
+ TRACE("Converted Back <%s>\n",
+ dumpName(host, name, sizeof(name)));
+ }
+ }
+ }
+
+ TRACE("LEAVE getnameinfo %d\n", code);
+ return (code);
+}