- s/sprintf/snprintf
[wmaker-crm.git] / WINGs / host.c
blob45c3544fc494c23ffec4b6653948ee56da8ddc6a
1 /*
2 * WINGs WMHost function library
4 * Copyright (c) 1999-2001 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 "wconfig.h"
26 #include <unistd.h>
27 #include <string.h>
28 #include <netdb.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
33 #include "WUtil.h"
36 /* For Solaris */
37 #ifndef INADDR_NONE
38 # define INADDR_NONE (-1)
39 #endif
41 /* Max hostname length (RFC 1123) */
42 #define W_MAXHOSTNAMELEN 255
45 typedef struct W_Host {
46 char *name;
48 WMArray *names;
49 WMArray *addresses;
51 int refCount;
52 } W_Host;
55 static WMHashTable *hostCache = NULL;
57 static Bool hostCacheEnabled = True;
61 static WMHost*
62 getHostFromCache(char *name)
64 if (!hostCache)
65 return NULL;
67 return WMHashGet(hostCache, name);
71 static WMHost*
72 getHostWithHostEntry(struct hostent *host, char *name)
74 WMHost *hPtr;
75 struct in_addr in;
76 int i;
78 hPtr = (WMHost*)wmalloc(sizeof(WMHost));
79 memset(hPtr, 0, sizeof(WMHost));
81 hPtr->names = WMCreateArrayWithDestructor(1, wfree);
82 hPtr->addresses = WMCreateArrayWithDestructor(1, wfree);
84 WMAddToArray(hPtr->names, wstrdup(host->h_name));
86 for (i=0; host->h_aliases[i]!=NULL; i++) {
87 WMAddToArray(hPtr->names, wstrdup(host->h_aliases[i]));
90 for (i=0; host->h_addr_list[i]!=NULL; i++) {
91 memcpy((void*)&in.s_addr, (const void*)host->h_addr_list[i],
92 host->h_length);
93 WMAddToArray(hPtr->addresses, wstrdup(inet_ntoa(in)));
96 hPtr->refCount = 1;
98 if (hostCacheEnabled) {
99 if (!hostCache)
100 hostCache = WMCreateHashTable(WMStringPointerHashCallbacks);
101 hPtr->name = wstrdup(name);
102 wassertr(WMHashInsert(hostCache, hPtr->name, hPtr)==NULL);
103 hPtr->refCount++;
106 return hPtr;
110 WMHost*
111 WMGetCurrentHost()
113 char name[W_MAXHOSTNAMELEN+1];
115 if (gethostname(name, W_MAXHOSTNAMELEN) < 0) {
116 wsyserror(_("Cannot get current host name"));
117 return NULL;
120 name[W_MAXHOSTNAMELEN] = 0;
122 return WMGetHostWithName(name);
126 WMHost*
127 WMGetHostWithName(char *name)
129 struct hostent *host;
130 WMHost *hPtr;
132 wassertrv(name!=NULL, NULL);
134 if (hostCacheEnabled) {
135 if ((hPtr = getHostFromCache(name)) != NULL) {
136 WMRetainHost(hPtr);
137 return hPtr;
141 host = gethostbyname(name);
142 if (host == NULL) {
143 return NULL;
146 hPtr = getHostWithHostEntry(host, name);
148 return hPtr;
152 WMHost*
153 WMGetHostWithAddress(char *address)
155 struct hostent *host;
156 struct in_addr in;
157 WMHost *hPtr;
159 wassertrv(address!=NULL, NULL);
161 if (hostCacheEnabled) {
162 if ((hPtr = getHostFromCache(address)) != NULL) {
163 WMRetainHost(hPtr);
164 return hPtr;
168 #ifndef HAVE_INET_ATON
169 if ((in.s_addr = inet_addr(address)) == INADDR_NONE)
170 return NULL;
171 #else
172 if (inet_aton(address, &in) == 0)
173 return NULL;
174 #endif
176 host = gethostbyaddr((char*)&in, sizeof(in), AF_INET);
177 if (host == NULL) {
178 return NULL;
181 hPtr = getHostWithHostEntry(host, address);
183 return hPtr;
187 WMHost*
188 WMRetainHost(WMHost *hPtr)
190 hPtr->refCount++;
191 return hPtr;
195 void
196 WMReleaseHost(WMHost *hPtr)
198 hPtr->refCount--;
200 if (hPtr->refCount > 0)
201 return;
203 WMFreeArray(hPtr->names);
204 WMFreeArray(hPtr->addresses);
206 if (hPtr->name) {
207 WMHashRemove(hostCache, hPtr->name);
208 wfree(hPtr->name);
211 wfree(hPtr);
215 void
216 WMSetHostCacheEnabled(Bool flag)
218 hostCacheEnabled = flag;
222 Bool
223 WMIsHostCacheEnabled()
225 return hostCacheEnabled;
229 void
230 WMFlushHostCache()
232 if (hostCache && WMCountHashTable(hostCache)>0) {
233 WMArray *hostArray = WMCreateArray(WMCountHashTable(hostCache));
234 WMHashEnumerator enumer = WMEnumerateHashTable(hostCache);
235 WMHost *hPtr;
236 int i;
238 while ((hPtr = WMNextHashEnumeratorItem(&enumer))) {
239 /* we can't release the host here, because we can't change the
240 * hash while using the enumerator functions. */
241 WMAddToArray(hostArray, hPtr);
243 for (i=0; i<WMGetArrayItemCount(hostArray); i++)
244 WMReleaseHost(WMGetFromArray(hostArray, i));
245 WMFreeArray(hostArray);
246 WMResetHashTable(hostCache);
251 static int
252 matchAddress(void *item, void *cdata)
254 return (strcmp((char*) item, (char*) cdata)==0);
258 Bool
259 WMIsHostEqualToHost(WMHost* hPtr, WMHost* aPtr)
261 char *adr;
262 int i;
264 wassertrv(hPtr!=NULL && aPtr!=NULL, False);
266 if (hPtr == aPtr)
267 return True;
269 for (i=0; i<WMGetArrayItemCount(aPtr->addresses); i++) {
270 adr = WMGetFromArray(aPtr->addresses, i);
271 if (WMFindInArray(hPtr->addresses, matchAddress, adr) != WANotFound) {
272 return True;
276 return False;
280 char*
281 WMGetHostName(WMHost *hPtr)
283 return (WMGetArrayItemCount(hPtr->names) > 0 ?
284 WMGetFromArray(hPtr->names, 0) : NULL);
285 /*return WMGetFromArray(hPtr->names, 0);*/
289 WMArray*
290 WMGetHostNames(WMHost *hPtr)
292 return hPtr->names;
296 char*
297 WMGetHostAddress(WMHost *hPtr)
299 return (WMGetArrayItemCount(hPtr->addresses) > 0 ?
300 WMGetFromArray(hPtr->addresses, 0) : NULL);
304 WMArray*
305 WMGetHostAddresses(WMHost *hPtr)
307 return hPtr->addresses;