diff options
Diffstat (limited to 'src/util/wshelper/hesservb.c')
| -rw-r--r-- | src/util/wshelper/hesservb.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/util/wshelper/hesservb.c b/src/util/wshelper/hesservb.c new file mode 100644 index 000000000000..01db3a4bf04d --- /dev/null +++ b/src/util/wshelper/hesservb.c @@ -0,0 +1,137 @@ +/* + * @doc HESIOD + * + * @module hesservb.c | + * + * + * Contains the definition for hes_getservbyname, + * + * WSHelper DNS/Hesiod Library for WINSOCK + * + */ + +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getservbyname.c 5.3 (Berkeley) 5/19/86"; +#endif /* LIBC_SCCS and not lint */ + +#include <hesiod.h> +#include <windows.h> +#include <winsock.h> +#include <windns.h> + +#include <string.h> + +#include <stdio.h> +#include <ctype.h> + +#define cistrcmp stricmp + +#define LISTSIZE 15 + + +/* + This function will query a Hesiod server for a servent structure given + a service name and protocol. This is a replacement for the Winsock + getservbyname function which normally just uses a local services + file. This allows a site to use a centralized database for adding new + services. + + defined in hesservb.c + + \param[in] name pointer to the official name of the service, eg "POP3". + \param[in] proto pointer to the protocol to use when contacting the service, e.g. "TCP" + + \retval NULL if there was an error or a pointer to a servent structure. The caller must + never attempt to modify this structure or to free any of its components. + Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before + issuing another hes_getservbyname call + +*/ + +extern DWORD dwHesServIndex; +struct servent * +WINAPI +hes_getservbyname(char *name, char *proto) +{ + struct servent *p; + register char **cp; + register char** hesinfo; + register int i = 0; + + char buf[DNS_MAX_NAME_BUFFER_LENGTH]; + char* l; + + hesinfo = hes_resolve(name, "service"); + cp = hesinfo; + if (cp == NULL) + return(NULL); + p = (struct servent*)(TlsGetValue(dwHesServIndex)); + if (p == NULL) { + LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct servent)); + if (lpvData != NULL) { + TlsSetValue(dwHesServIndex, lpvData); + p = (struct servent*)lpvData; + } else + return NULL; + } + if (!p->s_name) + p->s_name = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH); + if (!p->s_proto) + p->s_proto = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH); + if (!p->s_aliases) + p->s_aliases = LocalAlloc(LPTR, LISTSIZE*sizeof(LPSTR)); + + for (;*cp; cp++) { + register char *servicename, *protoname, *port; + strcpy(buf, *cp); + l = buf; + while(*l && (*l == ' ' || *l == '\t')) l++; + servicename = l; + while(*l && *l != ' ' && *l != '\t' && *l != ';') l++; + if (*l == '\0') continue; /* malformed entry */ + *l++ = '\0'; + while(*l && (*l == ' ' || *l == '\t')) l++; + protoname = l; + while(*l && *l != ' ' && *l != ';') l++; + if (*l == '\0') continue; /* malformed entry */ + *l++ = '\0'; + if (cistrcmp(proto, protoname)) continue; /* wrong port */ + while(*l && (*l == ' ' || *l == '\t' || *l == ';')) l++; + if (*l == '\0') continue; /* malformed entry */ + port = l; + while(*l && (*l != ' ' && *l != '\t' && *l != ';')) l++; + if (*l) *l++ = '\0'; + if (*l != '\0') { + do { + char* tmp = l; + while(*l && !isspace(*l)) l++; + if (*l) *l++ = 0; + if (p->s_aliases[i]) + p->s_aliases[i] = LocalAlloc(LPTR, strlen(tmp)); + strcpy(p->s_aliases[i], tmp); + i++; + } while(*l); + } + p->s_aliases[i] = NULL; + for (; i<LISTSIZE; i++) + { + if (p->s_aliases[i]){ + LocalFree(p->s_aliases[i]); + p->s_aliases[i] = NULL; + } + } + strcpy(p->s_name, servicename); + p->s_port = htons((u_short)atoi(port)); + strcpy(p->s_proto, protoname); + if (hesinfo) + hes_free(hesinfo); + return (p); + } + return(NULL); +} |
