2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 //%% (c) Copyright 1993, 1994 Hewlett-Packard Company
24 //%% (c) Copyright 1993, 1994 International Business Machines Corp.
25 //%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
26 //%% (c) Copyright 1993, 1994 Novell, Inc.
27 //%% $TOG: tt_host_equiv.C /main/9 1999/10/14 18:41:50 mgreess $
32 * Copyright (c) 1994 by Sun Microsystems, Inc.
35 #include <util/tt_host_equiv.h>
37 #define X_INCLUDE_NETDB_H
38 #define XOS_USE_XT_LOCKING
39 #include <X11/Xos_r.h>
41 static int _cache_it(_Tt_hostname_cache_ptr, _Tt_string &);
43 // This null constructor is required by the _table_of macro:
44 // DO NOT use it! Use the one below that that's a _Tt_string &.
48 hostname = (_Tt_string) 0;
52 _Tt_hostname_cache(_Tt_string & new_hostname)
54 hostname = new_hostname;
55 addr_list = new _Tt_string_list;
64 _Tt_string _Tt_hostname_cache::
65 h_keyfn (_Tt_object_ptr & p)
67 return ((_Tt_hostname_cache *)p.c_pointer())->hostname_val();
74 new _Tt_hostname_cache_table((_Tt_object_table_keyfn) & _Tt_hostname_cache::h_keyfn);
83 // return a string which uniquely identifies host,
84 // based on the contents of host and the supplied
85 // string localhost. The intent of this function
86 // is to allow one to get a name which IDs
87 // a useful minimum string of a host across
89 // i.e. if you have A.Eng.Sun.COM,
90 // and localhost.Eng.Sun.COM, return A,
91 // because you both are in the same domain.
93 // However, if if you have B.Corp.Sun.COM and
94 // localhost.Eng.Sun.COM return B.Corp
96 _Tt_string _Tt_host_equiv::
97 prefix_host(const _Tt_string & host, const _Tt_string & localhost)
100 _Tt_string h_prefix = host, l_prefix = localhost,
101 h, l, rpart_host, rpart_localhost;
104 printf("DEBUG prefix_host: host = %s, localhost = %s\n",
105 (char *) host, (char *) localhost);
108 while (rpart_host == rpart_localhost) {
112 if ((i = h.rindex('.')) == -1 ||
113 (j = l.rindex('.')) == -1) {
117 rpart_host = h.split(i, h_prefix);
118 rpart_localhost = l.split(j, l_prefix);
122 printf("DEBUG prefix_host: returning %s\n", (char *) h);
127 // Determine if two hostnames refer to the same host.
128 // This is required because a user may pass in a
129 // simple hostname or a hostname with a fully qualified
130 // domain name (FQDN) attached.
133 hostname_equiv(const _Tt_string & host1, const _Tt_string & host2)
135 // First try a simple comparison.
136 if (host1 == host2) {
138 printf("DEBUG hostname_equiv: host1 == host2, returning 1\n");
143 int is_found = 0, long_count = 0, short_count = 0;
144 _Tt_string shorthost, longhost;
145 _Tt_string short_prefix, long_prefix;
146 _Tt_string short_tmp, long_tmp;
148 if (host1.len() > host2.len()) {
152 // "longhost" may actually be equal to the
153 // len of "shorthost".
158 // Find how many .'s are in the names, in case
159 // one or both of the names are an FQDN.
161 short_tmp = shorthost;
162 while (long_tmp.index('.') != -1) {
164 long_tmp = long_tmp.split('.', long_prefix);
167 while (short_tmp.index('.') != -1) {
169 short_tmp = short_tmp.split('.', short_prefix);
172 // loop until we determine short is a prefix of long, or
173 // until we run out of things to compare.
175 short_tmp = shorthost;
177 short_count >= 0 && long_count > 0;
178 long_count--, short_count--) {
180 // Get the chunk upto the next dot
181 long_tmp = long_tmp.split('.', long_prefix);
182 short_tmp = short_tmp.split('.', short_prefix);
184 if (short_prefix.len() == 0) {
185 // shorthost has no dots in it,
186 // so do just one comparison.
188 if (short_tmp != long_prefix) {
190 printf("DEBUG hostname_equiv: short_tmp %s != long_prefix %s, returning 0\n",
191 (char *) short_tmp, (char *) long_prefix);
199 if (short_prefix != long_prefix) {
201 printf("DEBUG hostname_equiv: short_prefix %s != long_prefix %s, returning 0\n",
202 (char *) short_prefix, (char *) long_prefix);
210 printf("DEBUG hostname_equiv: is_found != 1, returning 0\n");
212 return 0; // no prefix was found
215 // One name is a prefix of the other.
216 // Now do a name lookup on both strings,
217 // get the IP addresses, and compare them
218 // to determine if the names do truly
219 // reference the same machine.
222 // Lookup the both entries int the cache to see if we`ve
223 // already mapped them. If we haven't, map & cache them.
225 _Tt_hostname_cache_ptr sh, lh;
227 sh = _cache_table->lookup(shorthost);
229 sh = new _Tt_hostname_cache(shorthost);
231 if (_cache_it(sh, shorthost) == 1) {
232 _cache_table->insert(sh);
235 printf("DEBUG hostname_equiv: sh.is_null(): returning 0\n");
241 lh = _cache_table->lookup(longhost);
243 lh = new _Tt_hostname_cache(longhost);
245 if (_cache_it(lh, longhost) == 1) {
246 _cache_table->insert(lh);
249 printf("DEBUG hostname_equiv: lh.is_null(): returning 0\n");
255 // Now sort through the address list looking
258 // This will probably never happen but why
260 if (sh->addr_length != lh->addr_length) {
262 printf("DEBUG hostname_equiv: sh->addr_length %d != h->addr_length %d, returning 0\n",
263 sh->addr_length, lh->addr_length);
268 _Tt_string_list_cursor sh_c(sh->addr_list);
269 _Tt_string_list_cursor lh_c(lh->addr_list);
271 while (sh_c.next()) {
272 while (lh_c.next()) {
274 printf("DEBUG hostname_equiv: checking address at 0x%x w/ 0x%x\n",
275 (char *) *sh_c, (char *) *lh_c);
277 // Do the IP addresses match?
278 if (memcmp((char *) *sh_c, (char *) *lh_c,
279 sh->addr_length) == 0) {
282 printf("DEBUG hostname_equiv: found match!\n");
294 // This is done here instead of in the constructor because
295 // gethostbyname can fail and I don't want things that can fail
296 // to be in a constructor.
298 _cache_it(_Tt_hostname_cache_ptr cache_ptr, _Tt_string & hostname)
300 _Tt_hostname_cache_ptr sh, lh;
301 struct hostent *host_ret;
302 _Xgethostbynameparams host_buf;
307 memset((char*) &host_buf, 0, sizeof(_Xgethostbynameparams));
308 if ((host_ret = _XGethostbyname((char*) hostname, host_buf)) == NULL) {
312 // cache the parts of the entry we're
313 // interested in. We have to do this
314 // since gethostbyname() returns a pointer
315 // to static memory, and since struct hostent's
316 // have pointers in them.
318 cache_ptr->addr_length = host_ret->h_length;
320 // Copy the list of IP addresses
321 for (h_addr_list = host_ret->h_addr_list;
325 if (! *h_addr_list) {
326 break; // no more addresses
330 _Tt_string new_addr((const unsigned char *)h_addr_list,
333 cache_ptr->addr_list->append(new_addr);