2 * WINGs WMHost function library
4 * Copyright (c) 1999-2003 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>
34 # define INADDR_NONE (-1)
37 /* Max hostname length (RFC 1123) */
38 #define W_MAXHOSTNAMELEN 255
40 typedef struct W_Host
{
49 static WMHashTable
*hostCache
= NULL
;
51 static Bool hostCacheEnabled
= True
;
53 static WMHost
*getHostFromCache(char *name
)
58 return WMHashGet(hostCache
, name
);
61 static WMHost
*getHostWithHostEntry(struct hostent
*host
, char *name
)
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
]));
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
)));
86 if (hostCacheEnabled
) {
88 hostCache
= WMCreateHashTable(WMStringPointerHashCallbacks
);
89 hPtr
->name
= wstrdup(name
);
90 wassertr(WMHashInsert(hostCache
, hPtr
->name
, hPtr
) == NULL
);
97 WMHost
*WMGetCurrentHost()
99 char name
[W_MAXHOSTNAMELEN
+ 1];
101 if (gethostname(name
, W_MAXHOSTNAMELEN
) < 0) {
102 wsyserror(_("Cannot get current host name"));
106 name
[W_MAXHOSTNAMELEN
] = 0;
108 return WMGetHostWithName(name
);
111 WMHost
*WMGetHostWithName(char *name
)
113 struct hostent
*host
;
116 wassertrv(name
!= NULL
, NULL
);
118 if (hostCacheEnabled
) {
119 if ((hPtr
= getHostFromCache(name
)) != NULL
) {
125 host
= gethostbyname(name
);
130 hPtr
= getHostWithHostEntry(host
, name
);
135 WMHost
*WMGetHostWithAddress(char *address
)
137 struct hostent
*host
;
141 wassertrv(address
!= NULL
, NULL
);
143 if (hostCacheEnabled
) {
144 if ((hPtr
= getHostFromCache(address
)) != NULL
) {
149 #ifndef HAVE_INET_ATON
150 if ((in
.s_addr
= inet_addr(address
)) == INADDR_NONE
)
153 if (inet_aton(address
, &in
) == 0)
157 host
= gethostbyaddr((char *)&in
, sizeof(in
), AF_INET
);
162 hPtr
= getHostWithHostEntry(host
, address
);
167 WMHost
*WMRetainHost(WMHost
* hPtr
)
173 void WMReleaseHost(WMHost
* hPtr
)
177 if (hPtr
->refCount
> 0)
180 WMFreeArray(hPtr
->names
);
181 WMFreeArray(hPtr
->addresses
);
184 WMHashRemove(hostCache
, hPtr
->name
);
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
);
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
)
231 wassertrv(hPtr
!= NULL
&& aPtr
!= NULL
, False
);
236 for (i
= 0; i
< WMGetArrayItemCount(aPtr
->addresses
); i
++) {
237 adr
= WMGetFromArray(aPtr
->addresses
, i
);
238 if (WMFindInArray(hPtr
->addresses
, matchAddress
, adr
) != WANotFound
) {
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
)
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
;