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.
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
33 /* Tell stupid Solaris what's going on */
35 #define INADDR_NONE (-1)
39 typedef struct W_Host
{
49 static WMHashTable
*hostCache
= NULL
;
50 static Bool hostCacheEnabled
= True
;
53 /* Max hostname length (RFC 1123) */
54 #define W_MAXHOSTNAMELEN 255
58 getHostFromCache(char *name
)
63 return WMHashGet(hostCache
, name
);
68 getHostWithHostEntry(struct hostent
*host
, char *name
)
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
],
89 WMPutInBag(hPtr
->addresses
, wstrdup(inet_ntoa(in
)));
94 if (hostCacheEnabled
) {
96 hostCache
= WMCreateHashTable(WMStringPointerHashCallbacks
);
97 hPtr
->name
= wstrdup(name
);
98 wassertr(WMHashInsert(hostCache
, hPtr
->name
, hPtr
)==NULL
);
109 char name
[W_MAXHOSTNAMELEN
+1];
111 if (gethostname(name
, W_MAXHOSTNAMELEN
) < 0) {
112 wsyserror("Cannot get current host name");
116 name
[W_MAXHOSTNAMELEN
] = '\0';
118 return WMGetHostWithName(name
);
123 WMGetHostWithName(char* name
)
125 struct hostent
*host
;
129 wwarning("NULL host name in 'WMGetHostWithName()'");
133 if (hostCacheEnabled
) {
134 if ((hPtr
= getHostFromCache(name
)) != NULL
) {
140 host
= gethostbyname(name
);
145 hPtr
= getHostWithHostEntry(host
, name
);
152 WMGetHostWithAddress(char* address
)
154 struct hostent
*host
;
158 if (address
== NULL
) {
159 wwarning("NULL address in 'WMGetHostWithAddress()'");
163 if (hostCacheEnabled
) {
164 if ((hPtr
= getHostFromCache(address
)) != NULL
) {
170 #ifndef HAVE_INET_ATON
171 if ((in
.s_addr
= inet_addr(address
)) == INADDR_NONE
)
174 if (inet_aton(address
, &in
.s_addr
) == 0)
178 host
= gethostbyaddr((char*)&in
, sizeof(in
), AF_INET
);
183 hPtr
= getHostWithHostEntry(host
, address
);
190 WMRetainHost(WMHost
*hPtr
)
198 WMReleaseHost(WMHost
*hPtr
)
204 if (hPtr
->refCount
> 0)
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
);
216 WMHashRemove(hostCache
, hPtr
->name
);
225 WMSetHostCacheEnabled(Bool flag
)
227 hostCacheEnabled
= flag
;
232 WMIsHostCacheEnabled()
234 return hostCacheEnabled
;
241 if (hostCache
&& WMCountHashTable(hostCache
)>0) {
242 WMBag
*hostBag
= WMCreateBag(WMCountHashTable(hostCache
));
243 WMHashEnumerator enumer
= WMEnumerateHashTable(hostCache
);
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
));
255 WMResetHashTable(hostCache
);
261 WMIsHostEqualToHost(WMHost
* hPtr
, WMHost
* aPtr
)
266 wassertrv(hPtr
!=NULL
&& aPtr
!=NULL
, False
);
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)
285 WMGetHostName(WMHost
*hPtr
)
287 return (WMGetBagItemCount(hPtr
->names
) > 0 ?
288 WMGetFromBag(hPtr
->names
, 0) : NULL
);
289 /*return WMGetFromBag(hPtr->names, 0);*/
294 WMGetHostNames(WMHost
*hPtr
)
301 WMGetHostAddress(WMHost
*hPtr
)
303 return (WMGetBagItemCount(hPtr
->addresses
) > 0 ?
304 WMGetFromBag(hPtr
->addresses
, 0) : NULL
);
309 WMGetHostAddresses(WMHost
*hPtr
)
311 return hPtr
->addresses
;