Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / host.c
blob53f940747b552cc6560e9f68a6c01b1d37e3cf1d
1 /*
2 * WINGs WMHost function library
3 *
4 * Copyright (c) 1999-2003 Dan Pascu
5 *
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.
10 *
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.
15 *
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.
19 */
21 #include "wconfig.h"
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"
32 /* For Solaris */
33 #ifndef INADDR_NONE
34 # define INADDR_NONE (-1)
35 #endif
37 /* Max hostname length (RFC 1123) */
38 #define W_MAXHOSTNAMELEN 255
40 typedef struct W_Host {
41 char *name;
43 WMArray *names;
44 WMArray *addresses;
46 int refCount;
47 } W_Host;
49 static WMHashTable *hostCache = NULL;
51 static Bool hostCacheEnabled = True;
53 static WMHost *getHostFromCache(char *name)
54 {
55 if (!hostCache)
56 return NULL;
58 return WMHashGet(hostCache, name);
59 }
61 static WMHost *getHostWithHostEntry(struct hostent *host, char *name)
62 {
63 WMHost *hPtr;
64 struct in_addr in;
65 int i;
67 hPtr = (WMHost *) wmalloc(sizeof(WMHost));
68 memset(hPtr, 0, sizeof(WMHost));
70 hPtr->names = WMCreateArrayWithDestructor(1, wfree);
71 hPtr->addresses = WMCreateArrayWithDestructor(1, wfree);
73 WMAddToArray(hPtr->names, wstrdup(host->h_name));
75 for (i = 0; host->h_aliases[i] != NULL; i++) {
76 WMAddToArray(hPtr->names, wstrdup(host->h_aliases[i]));
77 }
79 for (i = 0; host->h_addr_list[i] != NULL; i++) {
80 memcpy((void *)&in.s_addr, (const void *)host->h_addr_list[i], host->h_length);
81 WMAddToArray(hPtr->addresses, wstrdup(inet_ntoa(in)));
82 }
84 hPtr->refCount = 1;
86 if (hostCacheEnabled) {
87 if (!hostCache)
88 hostCache = WMCreateHashTable(WMStringPointerHashCallbacks);
89 hPtr->name = wstrdup(name);
90 wassertr(WMHashInsert(hostCache, hPtr->name, hPtr) == NULL);
91 hPtr->refCount++;
92 }
94 return hPtr;
95 }
97 WMHost *WMGetCurrentHost()
98 {
99 char name[W_MAXHOSTNAMELEN + 1];
101 if (gethostname(name, W_MAXHOSTNAMELEN) < 0) {
102 wsyserror(_("Cannot get current host name"));
103 return NULL;
106 name[W_MAXHOSTNAMELEN] = 0;
108 return WMGetHostWithName(name);
111 WMHost *WMGetHostWithName(char *name)
113 struct hostent *host;
114 WMHost *hPtr;
116 wassertrv(name != NULL, NULL);
118 if (hostCacheEnabled) {
119 if ((hPtr = getHostFromCache(name)) != NULL) {
120 WMRetainHost(hPtr);
121 return hPtr;
125 host = gethostbyname(name);
126 if (host == NULL) {
127 return NULL;
130 hPtr = getHostWithHostEntry(host, name);
132 return hPtr;
135 WMHost *WMGetHostWithAddress(char *address)
137 struct hostent *host;
138 struct in_addr in;
139 WMHost *hPtr;
141 wassertrv(address != NULL, NULL);
143 if (hostCacheEnabled) {
144 if ((hPtr = getHostFromCache(address)) != NULL) {
145 WMRetainHost(hPtr);
146 return hPtr;
149 #ifndef HAVE_INET_ATON
150 if ((in.s_addr = inet_addr(address)) == INADDR_NONE)
151 return NULL;
152 #else
153 if (inet_aton(address, &in) == 0)
154 return NULL;
155 #endif
157 host = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
158 if (host == NULL) {
159 return NULL;
162 hPtr = getHostWithHostEntry(host, address);
164 return hPtr;
167 WMHost *WMRetainHost(WMHost * hPtr)
169 hPtr->refCount++;
170 return hPtr;
173 void WMReleaseHost(WMHost * hPtr)
175 hPtr->refCount--;
177 if (hPtr->refCount > 0)
178 return;
180 WMFreeArray(hPtr->names);
181 WMFreeArray(hPtr->addresses);
183 if (hPtr->name) {
184 WMHashRemove(hostCache, hPtr->name);
185 wfree(hPtr->name);
188 wfree(hPtr);
191 void WMSetHostCacheEnabled(Bool flag)
193 hostCacheEnabled = ((flag == 0) ? 0 : 1);
196 Bool WMIsHostCacheEnabled()
198 return hostCacheEnabled;
201 void WMFlushHostCache()
203 if (hostCache && WMCountHashTable(hostCache) > 0) {
204 WMArray *hostArray = WMCreateArray(WMCountHashTable(hostCache));
205 WMHashEnumerator enumer = WMEnumerateHashTable(hostCache);
206 WMHost *hPtr;
207 int i;
209 while ((hPtr = WMNextHashEnumeratorItem(&enumer))) {
210 /* we can't release the host here, because we can't change the
211 * hash while using the enumerator functions. */
212 WMAddToArray(hostArray, hPtr);
214 for (i = 0; i < WMGetArrayItemCount(hostArray); i++)
215 WMReleaseHost(WMGetFromArray(hostArray, i));
216 WMFreeArray(hostArray);
217 WMResetHashTable(hostCache);
221 static int matchAddress(void *item, void *cdata)
223 return (strcmp((char *)item, (char *)cdata) == 0);
226 Bool WMIsHostEqualToHost(WMHost * hPtr, WMHost * aPtr)
228 char *adr;
229 int i;
231 wassertrv(hPtr != NULL && aPtr != NULL, False);
233 if (hPtr == aPtr)
234 return True;
236 for (i = 0; i < WMGetArrayItemCount(aPtr->addresses); i++) {
237 adr = WMGetFromArray(aPtr->addresses, i);
238 if (WMFindInArray(hPtr->addresses, matchAddress, adr) != WANotFound) {
239 return True;
243 return False;
246 char *WMGetHostName(WMHost * hPtr)
248 return (WMGetArrayItemCount(hPtr->names) > 0 ? WMGetFromArray(hPtr->names, 0) : NULL);
249 /*return WMGetFromArray(hPtr->names, 0); */
252 WMArray *WMGetHostNames(WMHost * hPtr)
254 return hPtr->names;
257 char *WMGetHostAddress(WMHost * hPtr)
259 return (WMGetArrayItemCount(hPtr->addresses) > 0 ? WMGetFromArray(hPtr->addresses, 0) : NULL);
262 WMArray *WMGetHostAddresses(WMHost * hPtr)
264 return hPtr->addresses;