Files
wmaker/WINGs/host.c
T

266 lines
5.4 KiB
C
Raw Normal View History

/*
* WINGs WMHost function library
1999-12-14 21:35:28 +00:00
*
2003-01-16 23:30:45 +00:00
* Copyright (c) 1999-2003 Dan Pascu
1999-12-14 21:35:28 +00:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
2001-07-23 20:31:32 +00:00
#include "wconfig.h"
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "WUtil.h"
2000-04-17 21:52:14 +00:00
/* For Solaris */
#ifndef INADDR_NONE
2000-04-17 21:24:58 +00:00
# define INADDR_NONE (-1)
#endif
2000-04-17 21:52:14 +00:00
/* Max hostname length (RFC 1123) */
#define W_MAXHOSTNAMELEN 255
typedef struct W_Host {
2009-08-20 00:59:40 +02:00
char *name;
2009-08-20 00:59:40 +02:00
WMArray *names;
WMArray *addresses;
2009-08-20 00:59:40 +02:00
int refCount;
} W_Host;
static WMHashTable *hostCache = NULL;
2000-04-17 21:52:14 +00:00
static Bool hostCacheEnabled = True;
2009-08-20 00:59:40 +02:00
static WMHost *getHostFromCache(char *name)
1999-12-14 21:35:28 +00:00
{
2009-08-20 00:59:40 +02:00
if (!hostCache)
return NULL;
2009-08-20 00:59:40 +02:00
return WMHashGet(hostCache, name);
}
2009-08-20 00:59:40 +02:00
static WMHost *getHostWithHostEntry(struct hostent *host, char *name)
{
2009-08-20 00:59:40 +02:00
WMHost *hPtr;
struct in_addr in;
int i;
2009-08-20 00:59:40 +02:00
hPtr = (WMHost *) wmalloc(sizeof(WMHost));
memset(hPtr, 0, sizeof(WMHost));
2009-08-20 00:59:40 +02:00
hPtr->names = WMCreateArrayWithDestructor(1, wfree);
hPtr->addresses = WMCreateArrayWithDestructor(1, wfree);
2009-08-20 00:59:40 +02:00
WMAddToArray(hPtr->names, wstrdup(host->h_name));
2009-08-20 00:59:40 +02:00
for (i = 0; host->h_aliases[i] != NULL; i++) {
WMAddToArray(hPtr->names, wstrdup(host->h_aliases[i]));
}
2009-08-20 00:59:40 +02:00
for (i = 0; host->h_addr_list[i] != NULL; i++) {
memcpy((void *)&in.s_addr, (const void *)host->h_addr_list[i], host->h_length);
WMAddToArray(hPtr->addresses, wstrdup(inet_ntoa(in)));
}
2009-08-20 00:59:40 +02:00
hPtr->refCount = 1;
2009-08-20 00:59:40 +02:00
if (hostCacheEnabled) {
if (!hostCache)
hostCache = WMCreateHashTable(WMStringPointerHashCallbacks);
hPtr->name = wstrdup(name);
wassertr(WMHashInsert(hostCache, hPtr->name, hPtr) == NULL);
hPtr->refCount++;
}
2009-08-20 00:59:40 +02:00
return hPtr;
}
2009-08-20 00:59:40 +02:00
WMHost *WMGetCurrentHost()
1999-12-14 21:35:28 +00:00
{
2009-08-20 00:59:40 +02:00
char name[W_MAXHOSTNAMELEN + 1];
1999-12-14 21:35:28 +00:00
2009-08-20 00:59:40 +02:00
if (gethostname(name, W_MAXHOSTNAMELEN) < 0) {
wsyserror(_("Cannot get current host name"));
return NULL;
}
1999-12-14 21:35:28 +00:00
2009-08-20 00:59:40 +02:00
name[W_MAXHOSTNAMELEN] = 0;
1999-12-14 21:35:28 +00:00
2009-08-20 00:59:40 +02:00
return WMGetHostWithName(name);
1999-12-14 21:35:28 +00:00
}
2009-08-20 00:59:40 +02:00
WMHost *WMGetHostWithName(char *name)
1999-12-14 21:35:28 +00:00
{
2009-08-20 00:59:40 +02:00
struct hostent *host;
WMHost *hPtr;
1999-12-14 21:35:28 +00:00
2009-08-20 00:59:40 +02:00
wassertrv(name != NULL, NULL);
1999-12-14 21:35:28 +00:00
2009-08-20 00:59:40 +02:00
if (hostCacheEnabled) {
if ((hPtr = getHostFromCache(name)) != NULL) {
WMRetainHost(hPtr);
return hPtr;
}
}
1999-12-14 21:35:28 +00:00
2009-08-20 00:59:40 +02:00
host = gethostbyname(name);
if (host == NULL) {
return NULL;
}
1999-12-14 21:35:28 +00:00
2009-08-20 00:59:40 +02:00
hPtr = getHostWithHostEntry(host, name);
1999-12-14 21:35:28 +00:00
2009-08-20 00:59:40 +02:00
return hPtr;
1999-12-14 21:35:28 +00:00
}
2009-08-20 00:59:40 +02:00
WMHost *WMGetHostWithAddress(char *address)
{
2009-08-20 00:59:40 +02:00
struct hostent *host;
struct in_addr in;
WMHost *hPtr;
wassertrv(address != NULL, NULL);
if (hostCacheEnabled) {
if ((hPtr = getHostFromCache(address)) != NULL) {
WMRetainHost(hPtr);
return hPtr;
}
}
1999-12-14 21:35:28 +00:00
#ifndef HAVE_INET_ATON
2009-08-20 00:59:40 +02:00
if ((in.s_addr = inet_addr(address)) == INADDR_NONE)
return NULL;
1999-12-14 21:35:28 +00:00
#else
2009-08-20 00:59:40 +02:00
if (inet_aton(address, &in) == 0)
return NULL;
#endif
1999-12-14 21:35:28 +00:00
2009-08-20 00:59:40 +02:00
host = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
if (host == NULL) {
return NULL;
}
1999-12-14 21:35:28 +00:00
2009-08-20 00:59:40 +02:00
hPtr = getHostWithHostEntry(host, address);
1999-12-14 21:35:28 +00:00
2009-08-20 00:59:40 +02:00
return hPtr;
}
2009-08-20 00:59:40 +02:00
WMHost *WMRetainHost(WMHost * hPtr)
{
2009-08-20 00:59:40 +02:00
hPtr->refCount++;
return hPtr;
}
2009-08-20 00:59:40 +02:00
void WMReleaseHost(WMHost * hPtr)
{
2009-08-20 00:59:40 +02:00
hPtr->refCount--;
2009-08-20 00:59:40 +02:00
if (hPtr->refCount > 0)
return;
2009-08-20 00:59:40 +02:00
WMFreeArray(hPtr->names);
WMFreeArray(hPtr->addresses);
2009-08-20 00:59:40 +02:00
if (hPtr->name) {
WMHashRemove(hostCache, hPtr->name);
wfree(hPtr->name);
}
2009-08-20 00:59:40 +02:00
wfree(hPtr);
}
2009-08-20 00:59:40 +02:00
void WMSetHostCacheEnabled(Bool flag)
{
2009-08-20 00:59:40 +02:00
hostCacheEnabled = ((flag == 0) ? 0 : 1);
}
2009-08-20 00:59:40 +02:00
Bool WMIsHostCacheEnabled()
{
2009-08-20 00:59:40 +02:00
return hostCacheEnabled;
}
2009-08-20 00:59:40 +02:00
void WMFlushHostCache()
{
2009-08-20 00:59:40 +02:00
if (hostCache && WMCountHashTable(hostCache) > 0) {
WMArray *hostArray = WMCreateArray(WMCountHashTable(hostCache));
WMHashEnumerator enumer = WMEnumerateHashTable(hostCache);
WMHost *hPtr;
int i;
while ((hPtr = WMNextHashEnumeratorItem(&enumer))) {
/* we can't release the host here, because we can't change the
* hash while using the enumerator functions. */
WMAddToArray(hostArray, hPtr);
}
for (i = 0; i < WMGetArrayItemCount(hostArray); i++)
WMReleaseHost(WMGetFromArray(hostArray, i));
WMFreeArray(hostArray);
WMResetHashTable(hostCache);
}
}
2009-08-20 00:59:40 +02:00
static int matchAddress(void *item, void *cdata)
{
2009-08-20 00:59:40 +02:00
return (strcmp((char *)item, (char *)cdata) == 0);
}
2009-08-20 00:59:40 +02:00
Bool WMIsHostEqualToHost(WMHost * hPtr, WMHost * aPtr)
{
2009-08-20 00:59:40 +02:00
char *adr;
int i;
2009-08-20 00:59:40 +02:00
wassertrv(hPtr != NULL && aPtr != NULL, False);
2009-08-20 00:59:40 +02:00
if (hPtr == aPtr)
return True;
2009-08-20 00:59:40 +02:00
for (i = 0; i < WMGetArrayItemCount(aPtr->addresses); i++) {
adr = WMGetFromArray(aPtr->addresses, i);
if (WMFindInArray(hPtr->addresses, matchAddress, adr) != WANotFound) {
return True;
}
}
2009-08-20 00:59:40 +02:00
return False;
}
2009-08-20 00:59:40 +02:00
char *WMGetHostName(WMHost * hPtr)
{
2009-08-20 00:59:40 +02:00
return (WMGetArrayItemCount(hPtr->names) > 0 ? WMGetFromArray(hPtr->names, 0) : NULL);
/*return WMGetFromArray(hPtr->names, 0); */
}
2009-08-20 00:59:40 +02:00
WMArray *WMGetHostNames(WMHost * hPtr)
{
2009-08-20 00:59:40 +02:00
return hPtr->names;
}
2009-08-20 00:59:40 +02:00
char *WMGetHostAddress(WMHost * hPtr)
{
2009-08-20 00:59:40 +02:00
return (WMGetArrayItemCount(hPtr->addresses) > 0 ? WMGetFromArray(hPtr->addresses, 0) : NULL);
}
2009-08-20 00:59:40 +02:00
WMArray *WMGetHostAddresses(WMHost * hPtr)
{
2009-08-20 00:59:40 +02:00
return hPtr->addresses;
}