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"
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
38 # define INADDR_NONE (-1)
41 /* Max hostname length (RFC 1123) */
42 #define W_MAXHOSTNAMELEN 255
45 typedef struct W_Host
{
55 static WMHashTable
*hostCache
= NULL
;
57 static Bool hostCacheEnabled
= True
;
62 getHostFromCache(char *name
)
67 return WMHashGet(hostCache
, name
);
72 getHostWithHostEntry(struct hostent
*host
, char *name
)
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
],
93 WMAddToArray(hPtr
->addresses
, wstrdup(inet_ntoa(in
)));
98 if (hostCacheEnabled
) {
100 hostCache
= WMCreateHashTable(WMStringPointerHashCallbacks
);
101 hPtr
->name
= wstrdup(name
);
102 wassertr(WMHashInsert(hostCache
, hPtr
->name
, hPtr
)==NULL
);
113 char name
[W_MAXHOSTNAMELEN
+1];
115 if (gethostname(name
, W_MAXHOSTNAMELEN
) < 0) {
116 wsyserror(_("Cannot get current host name"));
120 name
[W_MAXHOSTNAMELEN
] = 0;
122 return WMGetHostWithName(name
);
127 WMGetHostWithName(char *name
)
129 struct hostent
*host
;
132 wassertrv(name
!=NULL
, NULL
);
134 if (hostCacheEnabled
) {
135 if ((hPtr
= getHostFromCache(name
)) != NULL
) {
141 host
= gethostbyname(name
);
146 hPtr
= getHostWithHostEntry(host
, name
);
153 WMGetHostWithAddress(char *address
)
155 struct hostent
*host
;
159 wassertrv(address
!=NULL
, NULL
);
161 if (hostCacheEnabled
) {
162 if ((hPtr
= getHostFromCache(address
)) != NULL
) {
168 #ifndef HAVE_INET_ATON
169 if ((in
.s_addr
= inet_addr(address
)) == INADDR_NONE
)
172 if (inet_aton(address
, &in
) == 0)
176 host
= gethostbyaddr((char*)&in
, sizeof(in
), AF_INET
);
181 hPtr
= getHostWithHostEntry(host
, address
);
188 WMRetainHost(WMHost
*hPtr
)
196 WMReleaseHost(WMHost
*hPtr
)
200 if (hPtr
->refCount
> 0)
203 WMFreeArray(hPtr
->names
);
204 WMFreeArray(hPtr
->addresses
);
207 WMHashRemove(hostCache
, hPtr
->name
);
216 WMSetHostCacheEnabled(Bool flag
)
218 hostCacheEnabled
= flag
;
223 WMIsHostCacheEnabled()
225 return hostCacheEnabled
;
232 if (hostCache
&& WMCountHashTable(hostCache
)>0) {
233 WMArray
*hostArray
= WMCreateArray(WMCountHashTable(hostCache
));
234 WMHashEnumerator enumer
= WMEnumerateHashTable(hostCache
);
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
);
252 matchAddress(void *item
, void *cdata
)
254 return (strcmp((char*) item
, (char*) cdata
)==0);
259 WMIsHostEqualToHost(WMHost
* hPtr
, WMHost
* aPtr
)
264 wassertrv(hPtr
!=NULL
&& aPtr
!=NULL
, False
);
269 for (i
=0; i
<WMGetArrayItemCount(aPtr
->addresses
); i
++) {
270 adr
= WMGetFromArray(aPtr
->addresses
, i
);
271 if (WMFindInArray(hPtr
->addresses
, matchAddress
, adr
) != WANotFound
) {
281 WMGetHostName(WMHost
*hPtr
)
283 return (WMGetArrayItemCount(hPtr
->names
) > 0 ?
284 WMGetFromArray(hPtr
->names
, 0) : NULL
);
285 /*return WMGetFromArray(hPtr->names, 0);*/
290 WMGetHostNames(WMHost
*hPtr
)
297 WMGetHostAddress(WMHost
*hPtr
)
299 return (WMGetArrayItemCount(hPtr
->addresses
) > 0 ?
300 WMGetFromArray(hPtr
->addresses
, 0) : NULL
);
305 WMGetHostAddresses(WMHost
*hPtr
)
307 return hPtr
->addresses
;