2 * WINGs WMHost function library
4 * Copyright (c) 1999 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 typedef struct W_Host
{
45 static WMHashTable
*hostCache
= NULL
;
46 static Bool hostCacheEnabled
= True
;
49 /* Max hostname length (RFC 1123) */
50 #define W_MAXHOSTNAMELEN 255
55 char name
[W_MAXHOSTNAMELEN
+1];
57 if (gethostname(name
, W_MAXHOSTNAMELEN
) < 0) {
58 wsyserror("Cannot get current host name");
62 name
[W_MAXHOSTNAMELEN
] = '\0';
64 return WMGetHostWithName(name
);
69 WMGetHostWithName(char* name
)
77 wwarning("NULL host name in 'WMGetHostWithName()'");
82 hostCache
= WMCreateHashTable(WMStringPointerHashCallbacks
);
84 hPtr
= WMHashGet(hostCache
, name
);
90 host
= gethostbyname(name
);
92 wwarning("Invalid host name/address '%s'", name
);
96 hPtr
= (WMHost
*)wmalloc(sizeof(WMHost
));
97 memset(hPtr
, 0, sizeof(WMHost
));
99 hPtr
->names
= WMCreateBag(1);
100 hPtr
->addresses
= WMCreateBag(1);
102 WMPutInBag(hPtr
->names
, wstrdup(host
->h_name
));
104 for (i
=0; host
->h_aliases
[i
]!=NULL
; i
++) {
105 WMPutInBag(hPtr
->names
, wstrdup(host
->h_aliases
[i
]));
108 hPtr
->nameCount
= WMGetBagItemCount(hPtr
->names
);
110 for (i
=0; host
->h_addr_list
[i
]!=NULL
; i
++) {
111 memcpy((void*)&in
.s_addr
, (const void*)host
->h_addr_list
[i
],
113 WMPutInBag(hPtr
->addresses
, wstrdup(inet_ntoa(in
)));
116 hPtr
->addressCount
= WMGetBagItemCount(hPtr
->addresses
);
120 if (hostCacheEnabled
) {
121 hPtr
->name
= wstrdup(name
);
122 wassertr(WMHashInsert(hostCache
, hPtr
->name
, hPtr
)==NULL
);
131 WMGetHostWithAddress(char* address
)
133 if (address
== NULL
) {
134 wwarning("NULL address in 'WMGetHostWithAddress()'");
138 return WMGetHostWithName(address
);
140 hostaddr
.s_addr
= inet_addr((char*)[address cString
]);
141 if (hostaddr
.s_addr
== -1) {
145 h
= gethostbyaddr((char*)&hostaddr
, sizeof(hostaddr
), AF_INET
);
151 WMRetainHost(WMHost
*hPtr
)
159 WMReleaseHost(WMHost
*hPtr
)
165 if (hPtr
->refCount
> 0)
168 for (i
=0; i
<WMGetBagItemCount(hPtr
->names
); i
++)
169 wfree(WMGetFromBag(hPtr
->names
, i
));
170 for (i
=0; i
<WMGetBagItemCount(hPtr
->addresses
); i
++)
171 wfree(WMGetFromBag(hPtr
->addresses
, i
));
173 WMFreeBag(hPtr
->names
);
174 WMFreeBag(hPtr
->addresses
);
177 WMHashRemove(hostCache
, hPtr
->name
);
186 WMSetHostCacheEnabled(Bool flag
)
188 hostCacheEnabled
= flag
;
193 WMIsHostCacheEnabled()
195 return hostCacheEnabled
;
202 if (hostCache
&& WMCountHashTable(hostCache
)>0) {
203 WMBag
*hostBag
= WMCreateBag(WMCountHashTable(hostCache
));
204 WMHashEnumerator enumer
= WMEnumerateHashTable(hostCache
);
208 while ((hPtr
= WMNextHashEnumeratorItem(&enumer
))) {
209 /* we can't release the host here, because we can't change the
210 * hash while using the enumerator functions. */
211 WMPutInBag(hostBag
, hPtr
);
213 for (i
=0; i
<WMGetBagItemCount(hostBag
); i
++)
214 WMReleaseHost(WMGetFromBag(hostBag
, i
));
216 WMResetHashTable(hostCache
);
222 WMIsHostEqualToHost(WMHost
* hPtr
, WMHost
* aPtr
)
226 wassertrv(hPtr
!=NULL
&& aPtr
!=NULL
, False
);
231 for (i
=0; i
<aPtr
->addressCount
; i
++) {
232 if (WMGetFirstInBag(hPtr
->addresses
, WMGetFromBag(aPtr
->addresses
, i
)))
241 WMGetHostName(WMHost
*hPtr
)
243 return WMGetFromBag(hPtr
->names
, 0);
248 WMGetHostNames(WMHost
*hPtr
)
255 WMGetHostAddress(WMHost
*hPtr
)
257 return (hPtr
->addressCount
> 0 ? WMGetFromBag(hPtr
->addresses
, 0) : NULL
);
262 WMGetHostAddresses(WMHost
*hPtr
)
264 return hPtr
->addresses
;