Fix for stupid Solaris (maybe other Sysv systems too).
[wmaker-crm.git] / WINGs / host.c
blob617856296d843ade3b3523a3fb850a7aabbca1ba
1 /*
2 * WINGs WMHost function library
4 * Copyright (c) 1999-2000 Dan Pascu
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include <unistd.h>
24 #include <string.h>
25 #include <netdb.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
30 #include "WUtil.h"
33 /* Tell stupid Solaris what's going on */
34 #ifndef INADDR_NONE
35 #define INADDR_NONE (-1)
36 #endif
39 typedef struct W_Host {
40 char *name;
42 WMBag *names;
43 WMBag *addresses;
45 int refCount;
46 } W_Host;
49 static WMHashTable *hostCache = NULL;
50 static Bool hostCacheEnabled = True;
53 /* Max hostname length (RFC 1123) */
54 #define W_MAXHOSTNAMELEN 255
57 static WMHost*
58 getHostFromCache(char *name)
60 if (!hostCache)
61 return NULL;
63 return WMHashGet(hostCache, name);
67 static WMHost*
68 getHostWithHostEntry(struct hostent *host, char *name)
70 WMHost *hPtr;
71 struct in_addr in;
72 int i;
74 hPtr = (WMHost*)wmalloc(sizeof(WMHost));
75 memset(hPtr, 0, sizeof(WMHost));
77 hPtr->names = WMCreateBag(1);
78 hPtr->addresses = WMCreateBag(1);
80 WMPutInBag(hPtr->names, wstrdup(host->h_name));
82 for (i=0; host->h_aliases[i]!=NULL; i++) {
83 WMPutInBag(hPtr->names, wstrdup(host->h_aliases[i]));
86 for (i=0; host->h_addr_list[i]!=NULL; i++) {
87 memcpy((void*)&in.s_addr, (const void*)host->h_addr_list[i],
88 host->h_length);
89 WMPutInBag(hPtr->addresses, wstrdup(inet_ntoa(in)));
92 hPtr->refCount = 1;
94 if (hostCacheEnabled) {
95 if (!hostCache)
96 hostCache = WMCreateHashTable(WMStringPointerHashCallbacks);
97 hPtr->name = wstrdup(name);
98 wassertr(WMHashInsert(hostCache, hPtr->name, hPtr)==NULL);
99 hPtr->refCount++;
102 return hPtr;
106 WMHost*
107 WMGetCurrentHost()
109 char name[W_MAXHOSTNAMELEN+1];
111 if (gethostname(name, W_MAXHOSTNAMELEN) < 0) {
112 wsyserror("Cannot get current host name");
113 return NULL;
116 name[W_MAXHOSTNAMELEN] = '\0';
118 return WMGetHostWithName(name);
122 WMHost*
123 WMGetHostWithName(char* name)
125 struct hostent *host;
126 WMHost *hPtr;
128 if (name == NULL) {
129 wwarning("NULL host name in 'WMGetHostWithName()'");
130 return NULL;
133 if (hostCacheEnabled) {
134 if ((hPtr = getHostFromCache(name)) != NULL) {
135 WMRetainHost(hPtr);
136 return hPtr;
140 host = gethostbyname(name);
141 if (host == NULL) {
142 return NULL;
145 hPtr = getHostWithHostEntry(host, name);
147 return hPtr;
151 WMHost*
152 WMGetHostWithAddress(char* address)
154 struct hostent *host;
155 struct in_addr in;
156 WMHost *hPtr;
158 if (address == NULL) {
159 wwarning("NULL address in 'WMGetHostWithAddress()'");
160 return NULL;
163 if (hostCacheEnabled) {
164 if ((hPtr = getHostFromCache(address)) != NULL) {
165 WMRetainHost(hPtr);
166 return hPtr;
170 #ifndef HAVE_INET_ATON
171 if ((in.s_addr = inet_addr(address)) == INADDR_NONE)
172 return NULL;
173 #else
174 if (inet_aton(address, &in.s_addr) == 0)
175 return NULL;
176 #endif
178 host = gethostbyaddr((char*)&in, sizeof(in), AF_INET);
179 if (host == NULL) {
180 return NULL;
183 hPtr = getHostWithHostEntry(host, address);
185 return hPtr;
189 WMHost*
190 WMRetainHost(WMHost *hPtr)
192 hPtr->refCount++;
193 return hPtr;
197 void
198 WMReleaseHost(WMHost *hPtr)
200 int i;
202 hPtr->refCount--;
204 if (hPtr->refCount > 0)
205 return;
207 for (i=0; i<WMGetBagItemCount(hPtr->names); i++)
208 wfree(WMGetFromBag(hPtr->names, i));
209 for (i=0; i<WMGetBagItemCount(hPtr->addresses); i++)
210 wfree(WMGetFromBag(hPtr->addresses, i));
212 WMFreeBag(hPtr->names);
213 WMFreeBag(hPtr->addresses);
215 if (hPtr->name) {
216 WMHashRemove(hostCache, hPtr->name);
217 wfree(hPtr->name);
220 wfree(hPtr);
224 void
225 WMSetHostCacheEnabled(Bool flag)
227 hostCacheEnabled = flag;
231 Bool
232 WMIsHostCacheEnabled()
234 return hostCacheEnabled;
238 void
239 WMFlushHostCache()
241 if (hostCache && WMCountHashTable(hostCache)>0) {
242 WMBag *hostBag = WMCreateBag(WMCountHashTable(hostCache));
243 WMHashEnumerator enumer = WMEnumerateHashTable(hostCache);
244 WMHost *hPtr;
245 int i;
247 while ((hPtr = WMNextHashEnumeratorItem(&enumer))) {
248 /* we can't release the host here, because we can't change the
249 * hash while using the enumerator functions. */
250 WMPutInBag(hostBag, hPtr);
252 for (i=0; i<WMGetBagItemCount(hostBag); i++)
253 WMReleaseHost(WMGetFromBag(hostBag, i));
254 WMFreeBag(hostBag);
255 WMResetHashTable(hostCache);
260 Bool
261 WMIsHostEqualToHost(WMHost* hPtr, WMHost* aPtr)
263 int i, j;
264 char *adr1, *adr2;
266 wassertrv(hPtr!=NULL && aPtr!=NULL, False);
268 if (hPtr == aPtr)
269 return True;
271 for (i=0; i<WMGetBagItemCount(aPtr->addresses); i++) {
272 adr1 = WMGetFromBag(aPtr->addresses, i);
273 for (j=0; j<WMGetBagItemCount(hPtr->addresses); j++) {
274 adr2 = WMGetFromBag(hPtr->addresses, j);
275 if (strcmp(adr1, adr2)==0)
276 return True;
280 return False;
284 char*
285 WMGetHostName(WMHost *hPtr)
287 return (WMGetBagItemCount(hPtr->names) > 0 ?
288 WMGetFromBag(hPtr->names, 0) : NULL);
289 /*return WMGetFromBag(hPtr->names, 0);*/
293 WMBag*
294 WMGetHostNames(WMHost *hPtr)
296 return hPtr->names;
300 char*
301 WMGetHostAddress(WMHost *hPtr)
303 return (WMGetBagItemCount(hPtr->addresses) > 0 ?
304 WMGetFromBag(hPtr->addresses, 0) : NULL);
308 WMBag*
309 WMGetHostAddresses(WMHost *hPtr)
311 return hPtr->addresses;