Small fix for an enum
[wmaker-crm.git] / WINGs / host.c
blob0e6317530939a01e5c91e7a2b1446c3494d6b6ea
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.
22 #include "../src/config.h"
24 #include <unistd.h>
25 #include <string.h>
26 #include <netdb.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
31 #include "WUtil.h"
34 /* For Solaris */
35 #ifndef INADDR_NONE
36 # define INADDR_NONE (-1)
37 #endif
39 /* Max hostname length (RFC 1123) */
40 #define W_MAXHOSTNAMELEN 255
43 typedef struct W_Host {
44 char *name;
46 WMBag *names;
47 WMBag *addresses;
49 int refCount;
50 } W_Host;
53 static WMHashTable *hostCache = NULL;
55 static Bool hostCacheEnabled = True;
59 static WMHost*
60 getHostFromCache(char *name)
62 if (!hostCache)
63 return NULL;
65 return WMHashGet(hostCache, name);
69 static WMHost*
70 getHostWithHostEntry(struct hostent *host, char *name)
72 WMHost *hPtr;
73 struct in_addr in;
74 int i;
76 hPtr = (WMHost*)wmalloc(sizeof(WMHost));
77 memset(hPtr, 0, sizeof(WMHost));
79 hPtr->names = WMCreateBag(1);
80 hPtr->addresses = WMCreateBag(1);
82 WMPutInBag(hPtr->names, wstrdup(host->h_name));
84 for (i=0; host->h_aliases[i]!=NULL; i++) {
85 WMPutInBag(hPtr->names, wstrdup(host->h_aliases[i]));
88 for (i=0; host->h_addr_list[i]!=NULL; i++) {
89 memcpy((void*)&in.s_addr, (const void*)host->h_addr_list[i],
90 host->h_length);
91 WMPutInBag(hPtr->addresses, wstrdup(inet_ntoa(in)));
94 hPtr->refCount = 1;
96 if (hostCacheEnabled) {
97 if (!hostCache)
98 hostCache = WMCreateHashTable(WMStringPointerHashCallbacks);
99 hPtr->name = wstrdup(name);
100 wassertr(WMHashInsert(hostCache, hPtr->name, hPtr)==NULL);
101 hPtr->refCount++;
104 return hPtr;
108 WMHost*
109 WMGetCurrentHost()
111 char name[W_MAXHOSTNAMELEN+1];
113 if (gethostname(name, W_MAXHOSTNAMELEN) < 0) {
114 wsyserror("Cannot get current host name");
115 return NULL;
118 name[W_MAXHOSTNAMELEN] = '\0';
120 return WMGetHostWithName(name);
124 WMHost*
125 WMGetHostWithName(char* name)
127 struct hostent *host;
128 WMHost *hPtr;
130 if (name == NULL) {
131 wwarning("NULL host name in 'WMGetHostWithName()'");
132 return NULL;
135 if (hostCacheEnabled) {
136 if ((hPtr = getHostFromCache(name)) != NULL) {
137 WMRetainHost(hPtr);
138 return hPtr;
142 host = gethostbyname(name);
143 if (host == NULL) {
144 return NULL;
147 hPtr = getHostWithHostEntry(host, name);
149 return hPtr;
153 WMHost*
154 WMGetHostWithAddress(char* address)
156 struct hostent *host;
157 struct in_addr in;
158 WMHost *hPtr;
160 if (address == NULL) {
161 wwarning("NULL address in 'WMGetHostWithAddress()'");
162 return NULL;
165 if (hostCacheEnabled) {
166 if ((hPtr = getHostFromCache(address)) != NULL) {
167 WMRetainHost(hPtr);
168 return hPtr;
172 #ifndef HAVE_INET_ATON
173 if ((in.s_addr = inet_addr(address)) == INADDR_NONE)
174 return NULL;
175 #else
176 if (inet_aton(address, &in) == 0)
177 return NULL;
178 #endif
180 host = gethostbyaddr((char*)&in, sizeof(in), AF_INET);
181 if (host == NULL) {
182 return NULL;
185 hPtr = getHostWithHostEntry(host, address);
187 return hPtr;
191 WMHost*
192 WMRetainHost(WMHost *hPtr)
194 hPtr->refCount++;
195 return hPtr;
199 void
200 WMReleaseHost(WMHost *hPtr)
202 int i;
204 hPtr->refCount--;
206 if (hPtr->refCount > 0)
207 return;
209 for (i=0; i<WMGetBagItemCount(hPtr->names); i++)
210 wfree(WMGetFromBag(hPtr->names, i));
211 for (i=0; i<WMGetBagItemCount(hPtr->addresses); i++)
212 wfree(WMGetFromBag(hPtr->addresses, i));
214 WMFreeBag(hPtr->names);
215 WMFreeBag(hPtr->addresses);
217 if (hPtr->name) {
218 WMHashRemove(hostCache, hPtr->name);
219 wfree(hPtr->name);
222 wfree(hPtr);
226 void
227 WMSetHostCacheEnabled(Bool flag)
229 hostCacheEnabled = flag;
233 Bool
234 WMIsHostCacheEnabled()
236 return hostCacheEnabled;
240 void
241 WMFlushHostCache()
243 if (hostCache && WMCountHashTable(hostCache)>0) {
244 WMBag *hostBag = WMCreateBag(WMCountHashTable(hostCache));
245 WMHashEnumerator enumer = WMEnumerateHashTable(hostCache);
246 WMHost *hPtr;
247 int i;
249 while ((hPtr = WMNextHashEnumeratorItem(&enumer))) {
250 /* we can't release the host here, because we can't change the
251 * hash while using the enumerator functions. */
252 WMPutInBag(hostBag, hPtr);
254 for (i=0; i<WMGetBagItemCount(hostBag); i++)
255 WMReleaseHost(WMGetFromBag(hostBag, i));
256 WMFreeBag(hostBag);
257 WMResetHashTable(hostCache);
262 Bool
263 WMIsHostEqualToHost(WMHost* hPtr, WMHost* aPtr)
265 int i, j;
266 char *adr1, *adr2;
268 wassertrv(hPtr!=NULL && aPtr!=NULL, False);
270 if (hPtr == aPtr)
271 return True;
273 for (i=0; i<WMGetBagItemCount(aPtr->addresses); i++) {
274 adr1 = WMGetFromBag(aPtr->addresses, i);
275 for (j=0; j<WMGetBagItemCount(hPtr->addresses); j++) {
276 adr2 = WMGetFromBag(hPtr->addresses, j);
277 if (strcmp(adr1, adr2)==0)
278 return True;
282 return False;
286 char*
287 WMGetHostName(WMHost *hPtr)
289 return (WMGetBagItemCount(hPtr->names) > 0 ?
290 WMGetFromBag(hPtr->names, 0) : NULL);
291 /*return WMGetFromBag(hPtr->names, 0);*/
295 WMBag*
296 WMGetHostNames(WMHost *hPtr)
298 return hPtr->names;
302 char*
303 WMGetHostAddress(WMHost *hPtr)
305 return (WMGetBagItemCount(hPtr->addresses) > 0 ?
306 WMGetFromBag(hPtr->addresses, 0) : NULL);
310 WMBag*
311 WMGetHostAddresses(WMHost *hPtr)
313 return hPtr->addresses;