remove OSF1 support
[oweals/cde.git] / cde / lib / tt / lib / util / tt_host.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
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.C /main/9 1999/10/14 18:41:36 mgreess $                                                     
28 /*
29  *
30  * @(#)tt_host.C        1.12 93/09/07
31  *
32  * Copyright (c) 1990 by Sun Microsystems, Inc.
33  */
34
35 #include <sys/types.h>
36 #include <util/tt_host.h>
37 #include <sys/param.h>
38
39 #if defined(_AIX)
40 /* AIX's arpa/inet.h has a buggy declaration of inet_addr */
41 extern "C" in_addr_t inet_addr(const char *);
42 #endif
43
44 #include <sys/socket.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
47 #include <string.h>
48 #if !defined(linux) && !defined(CSRG_BASED) && !defined(sun)
49 #include <osfcn.h>
50 #endif
51
52 #define X_INCLUDE_NETDB_H
53 #define XOS_USE_XT_LOCKING
54 #include <X11/Xos_r.h>
55
56 #include "util/tt_port.h"   
57
58 #if defined(OPT_BUG_SUNOS_4) && defined(__GNUG__)
59         extern "C" { int endhostent(); }
60 #endif
61
62 #define         IP_QUALIFIER    "tcp"
63 #define         TLI_QUALIFIER   "tli"
64
65
66
67 /* 
68  * Null constructor.
69  */
70 _Tt_host::
71 _Tt_host()
72 {
73         _addr = (char *)0;
74         _name = (char *)0;
75         _netname = (char *)0;
76 }
77
78
79 /* 
80  * Destructor. Sets _name to NULL so that reference counting can free up the
81  * space if possible.
82  */
83 _Tt_host::
84 ~_Tt_host()
85 {
86         _addr = (char *)0;
87         _name = (char *)0;
88         _netname = (char *)0;
89 }
90
91
92 /* 
93  * Initializes a _Tt_host object from a hostent structure which is the
94  * standard structure returned by gethostbyaddr and gethostbyname.
95  */
96 int _Tt_host::
97 init_from_hostent(hostent *h)
98 {
99         char            str[40];
100         char            *ip_addr;
101
102         if (h != (hostent *)0) {
103                 _name = h->h_name;
104                 _addr.set((const unsigned char *)h->h_addr, h->h_length);
105                 ip_addr = (char *)_addr;
106                 sprintf(str, "%d.%d.%d.%d",
107                        (int)((unsigned char *)ip_addr)[0],
108                        (int)((unsigned char *)ip_addr)[1],
109                        (int)((unsigned char *)ip_addr)[2],
110                        (int)((unsigned char *)ip_addr)[3]);
111                 _string_address = str;
112                 // We use the ip address but we qualify it with the
113                 // keyword IP_QUALIFIER so that SVR4 clients can
114                 // interoperate with this name.
115
116                 _name = h->h_name;
117                 _netname = IP_QUALIFIER;
118                 _netname = _netname.cat(":").cat(_string_address);
119                 return(1);
120         } else {
121                 return(0);
122         }
123 }
124
125
126 /* 
127  * Initializes a _Tt_host object from an IP address.
128  * 
129  * --> This method should attempt to cache results as much as possible to
130  * avoid repeated calls to gethostbyaddr (which may, in the abscence of
131  * DNS trigger YP lookups). (and in the presence of DNS trigger DNS
132  * lookups which can be just as bad...)
133  */
134 int _Tt_host::
135 init_byaddr(_Tt_string addr)
136 {
137         int result;
138         struct hostent          *addr_ret;
139         _Xgethostbynameparams   addr_buf;
140
141         memset((char*) &addr_buf, 0, sizeof(_Xgethostbynameparams));
142         addr_ret = _XGethostbyaddr((char *)addr, 4, AF_INET, addr_buf);
143         result = init_from_hostent(addr_ret);
144 #ifdef OPT_BUG_SUNOS_5
145         // gethostbyaddr is effectively built on gethostent.  If
146         // endhostent is not called, storage is left around to save the
147         // name service connection, etc.  bug 1111175
148         endhostent();
149 #endif
150         return result;
151 }
152
153
154 /* 
155  * Initializes a _Tt_host object from a string representing the host
156  * address in Internet '.' notation.
157  */
158 int _Tt_host::
159 init_bystringaddr(_Tt_string addr)
160 {
161         unsigned long   *ip_address;
162         unsigned long   ip_address_buf;
163         struct hostent          *addr_ret;
164         _Xgethostbynameparams   addr_buf;
165
166         memset((char*) &addr_buf, 0, sizeof(_Xgethostbynameparams));
167         ip_address = &ip_address_buf;
168
169         *ip_address = inet_addr((char *)addr);
170         if (*ip_address == INADDR_NONE) {
171                 return(0);
172         }
173
174         _addr.set((const unsigned char *)ip_address, 4);
175         addr_ret = _XGethostbyaddr((char *)_addr, 4, AF_INET, addr_buf);
176         if (! init_from_hostent(addr_ret)) {
177                 // given an ip address we can still communicate with
178                 // this host but we may not know it's name
179                 _string_address = addr;
180                 _netname = IP_QUALIFIER;
181                 _netname = _netname.cat(":").cat(_string_address);
182                 // we couldn't find out the name of the host so we'll
183                 // just call it by it's ip address
184                 _name = addr;
185         }
186 #ifdef OPT_BUG_SUNOS_5
187         // gethostbyaddr is effectively built on gethostent.  If
188         // endhostent is not called, storage is left around to save the
189         // name service connection, etc.  bug 1111175
190         endhostent();
191 #endif
192         return(1);
193 }
194
195 /* 
196  * Initializes a _Tt_host object from a host name.
197  * 
198  */
199 int _Tt_host::
200 init_byname(_Tt_string name)
201 {
202         _Tt_string      qual;
203         _Tt_string      host;
204         int             result;
205         struct hostent          *host_ret;
206         _Xgethostbynameparams   host_buf;
207
208         memset((char*) &host_buf, 0, sizeof(_Xgethostbynameparams));
209         if (name.len() == 0) {
210                 _name = _tt_gethostname();
211         } else {
212                 qual = name.split(':',_name);
213                 if (_name.len()== 0) {
214                         // unqualified name
215                         _name = qual;
216                 } else {
217                         if (qual == IP_QUALIFIER) {
218                                 return(init_bystringaddr(_name));
219                         } else if (qual == TLI_QUALIFIER) {
220                                 /* just leave _name alone */;
221                         } else {
222                                 // unknown qualifier!
223                                 return(0);
224                         }
225                 }
226         }
227         host_ret = _XGethostbyname((char *)_name, host_buf);
228         if (host_ret == NULL) {
229                 result = init_bystringaddr(_name);
230         } else {
231                 result = init_from_hostent(host_ret);
232         }
233 #ifdef OPT_BUG_SUNOS_5
234         // gethostbyname is effectively built on gethostent.  If
235         // endhostent is not called, storage is left around to save the
236         // name service connection, etc.  bug 1111175
237         endhostent();
238 #endif
239         return result;
240 }
241
242
243 /* 
244  * Returns the length of the host address.
245  */
246 int _Tt_host::
247 addr_length() const
248 {
249         return(_addr.len());
250 }
251
252
253 bool_t _Tt_host::
254 xdr(XDR *xdrs)
255 {
256         return(_addr.xdr(xdrs));
257 }
258
259 _Tt_string
260 _tt_host_addr(_Tt_object_ptr &o)
261 {
262         return(((_Tt_host *)o.c_pointer())->addr());
263 }
264
265
266 _Tt_string
267 _tt_host_name(_Tt_object_ptr &o)
268 {
269         return(((_Tt_host *)o.c_pointer())->name());
270 }