mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 12:28:22 +01:00
319 lines
6.2 KiB
C
319 lines
6.2 KiB
C
/*
|
|
* WINGs WMHost function library
|
|
*
|
|
* Copyright (c) 1999-2000 Dan Pascu
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
|
|
#include "../src/config.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"
|
|
|
|
|
|
/* For Solaris */
|
|
#ifndef INADDR_NONE
|
|
# define INADDR_NONE (-1)
|
|
#endif
|
|
|
|
/* Max hostname length (RFC 1123) */
|
|
#define W_MAXHOSTNAMELEN 255
|
|
|
|
|
|
typedef struct W_Host {
|
|
char *name;
|
|
|
|
WMBag *names;
|
|
WMBag *addresses;
|
|
|
|
int refCount;
|
|
} W_Host;
|
|
|
|
|
|
static WMHashTable *hostCache = NULL;
|
|
|
|
static Bool hostCacheEnabled = True;
|
|
|
|
|
|
|
|
static WMHost*
|
|
getHostFromCache(char *name)
|
|
{
|
|
if (!hostCache)
|
|
return NULL;
|
|
|
|
return WMHashGet(hostCache, name);
|
|
}
|
|
|
|
|
|
static WMHost*
|
|
getHostWithHostEntry(struct hostent *host, char *name)
|
|
{
|
|
WMHost *hPtr;
|
|
struct in_addr in;
|
|
int i;
|
|
|
|
hPtr = (WMHost*)wmalloc(sizeof(WMHost));
|
|
memset(hPtr, 0, sizeof(WMHost));
|
|
|
|
hPtr->names = WMCreateBag(1);
|
|
hPtr->addresses = WMCreateBag(1);
|
|
|
|
WMPutInBag(hPtr->names, wstrdup(host->h_name));
|
|
|
|
for (i=0; host->h_aliases[i]!=NULL; i++) {
|
|
WMPutInBag(hPtr->names, wstrdup(host->h_aliases[i]));
|
|
}
|
|
|
|
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);
|
|
WMPutInBag(hPtr->addresses, wstrdup(inet_ntoa(in)));
|
|
}
|
|
|
|
hPtr->refCount = 1;
|
|
|
|
if (hostCacheEnabled) {
|
|
if (!hostCache)
|
|
hostCache = WMCreateHashTable(WMStringPointerHashCallbacks);
|
|
hPtr->name = wstrdup(name);
|
|
wassertr(WMHashInsert(hostCache, hPtr->name, hPtr)==NULL);
|
|
hPtr->refCount++;
|
|
}
|
|
|
|
return hPtr;
|
|
}
|
|
|
|
|
|
WMHost*
|
|
WMGetCurrentHost()
|
|
{
|
|
char name[W_MAXHOSTNAMELEN+1];
|
|
|
|
if (gethostname(name, W_MAXHOSTNAMELEN) < 0) {
|
|
wsyserror("Cannot get current host name");
|
|
return NULL;
|
|
}
|
|
|
|
name[W_MAXHOSTNAMELEN] = '\0';
|
|
|
|
return WMGetHostWithName(name);
|
|
}
|
|
|
|
|
|
WMHost*
|
|
WMGetHostWithName(char* name)
|
|
{
|
|
struct hostent *host;
|
|
WMHost *hPtr;
|
|
|
|
if (name == NULL) {
|
|
wwarning("NULL host name in 'WMGetHostWithName()'");
|
|
return NULL;
|
|
}
|
|
|
|
if (hostCacheEnabled) {
|
|
if ((hPtr = getHostFromCache(name)) != NULL) {
|
|
WMRetainHost(hPtr);
|
|
return hPtr;
|
|
}
|
|
}
|
|
|
|
host = gethostbyname(name);
|
|
if (host == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
hPtr = getHostWithHostEntry(host, name);
|
|
|
|
return hPtr;
|
|
}
|
|
|
|
|
|
WMHost*
|
|
WMGetHostWithAddress(char* address)
|
|
{
|
|
struct hostent *host;
|
|
struct in_addr in;
|
|
WMHost *hPtr;
|
|
|
|
if (address == NULL) {
|
|
wwarning("NULL address in 'WMGetHostWithAddress()'");
|
|
return NULL;
|
|
}
|
|
|
|
if (hostCacheEnabled) {
|
|
if ((hPtr = getHostFromCache(address)) != NULL) {
|
|
WMRetainHost(hPtr);
|
|
return hPtr;
|
|
}
|
|
}
|
|
|
|
#ifndef HAVE_INET_ATON
|
|
if ((in.s_addr = inet_addr(address)) == INADDR_NONE)
|
|
return NULL;
|
|
#else
|
|
if (inet_aton(address, &in) == 0)
|
|
return NULL;
|
|
#endif
|
|
|
|
host = gethostbyaddr((char*)&in, sizeof(in), AF_INET);
|
|
if (host == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
hPtr = getHostWithHostEntry(host, address);
|
|
|
|
return hPtr;
|
|
}
|
|
|
|
|
|
WMHost*
|
|
WMRetainHost(WMHost *hPtr)
|
|
{
|
|
hPtr->refCount++;
|
|
return hPtr;
|
|
}
|
|
|
|
|
|
void
|
|
WMReleaseHost(WMHost *hPtr)
|
|
{
|
|
int i;
|
|
|
|
hPtr->refCount--;
|
|
|
|
if (hPtr->refCount > 0)
|
|
return;
|
|
|
|
for (i=0; i<WMGetBagItemCount(hPtr->names); i++)
|
|
wfree(WMGetFromBag(hPtr->names, i));
|
|
for (i=0; i<WMGetBagItemCount(hPtr->addresses); i++)
|
|
wfree(WMGetFromBag(hPtr->addresses, i));
|
|
|
|
WMFreeBag(hPtr->names);
|
|
WMFreeBag(hPtr->addresses);
|
|
|
|
if (hPtr->name) {
|
|
WMHashRemove(hostCache, hPtr->name);
|
|
wfree(hPtr->name);
|
|
}
|
|
|
|
wfree(hPtr);
|
|
}
|
|
|
|
|
|
void
|
|
WMSetHostCacheEnabled(Bool flag)
|
|
{
|
|
hostCacheEnabled = flag;
|
|
}
|
|
|
|
|
|
Bool
|
|
WMIsHostCacheEnabled()
|
|
{
|
|
return hostCacheEnabled;
|
|
}
|
|
|
|
|
|
void
|
|
WMFlushHostCache()
|
|
{
|
|
if (hostCache && WMCountHashTable(hostCache)>0) {
|
|
WMBag *hostBag = WMCreateBag(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. */
|
|
WMPutInBag(hostBag, hPtr);
|
|
}
|
|
for (i=0; i<WMGetBagItemCount(hostBag); i++)
|
|
WMReleaseHost(WMGetFromBag(hostBag, i));
|
|
WMFreeBag(hostBag);
|
|
WMResetHashTable(hostCache);
|
|
}
|
|
}
|
|
|
|
|
|
Bool
|
|
WMIsHostEqualToHost(WMHost* hPtr, WMHost* aPtr)
|
|
{
|
|
int i, j;
|
|
char *adr1, *adr2;
|
|
|
|
wassertrv(hPtr!=NULL && aPtr!=NULL, False);
|
|
|
|
if (hPtr == aPtr)
|
|
return True;
|
|
|
|
for (i=0; i<WMGetBagItemCount(aPtr->addresses); i++) {
|
|
adr1 = WMGetFromBag(aPtr->addresses, i);
|
|
for (j=0; j<WMGetBagItemCount(hPtr->addresses); j++) {
|
|
adr2 = WMGetFromBag(hPtr->addresses, j);
|
|
if (strcmp(adr1, adr2)==0)
|
|
return True;
|
|
}
|
|
}
|
|
|
|
return False;
|
|
}
|
|
|
|
|
|
char*
|
|
WMGetHostName(WMHost *hPtr)
|
|
{
|
|
return (WMGetBagItemCount(hPtr->names) > 0 ?
|
|
WMGetFromBag(hPtr->names, 0) : NULL);
|
|
/*return WMGetFromBag(hPtr->names, 0);*/
|
|
}
|
|
|
|
|
|
WMBag*
|
|
WMGetHostNames(WMHost *hPtr)
|
|
{
|
|
return hPtr->names;
|
|
}
|
|
|
|
|
|
char*
|
|
WMGetHostAddress(WMHost *hPtr)
|
|
{
|
|
return (WMGetBagItemCount(hPtr->addresses) > 0 ?
|
|
WMGetFromBag(hPtr->addresses, 0) : NULL);
|
|
}
|
|
|
|
|
|
WMBag*
|
|
WMGetHostAddresses(WMHost *hPtr)
|
|
{
|
|
return hPtr->addresses;
|
|
}
|
|
|
|
|
|
|
|
|