Tooltalk fixes for OpenBSD. This consists mainly of #ifdefs, casts and some small...
[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 librararies 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 #ifdef __osf__
49 #include <unistd.h>
50 #else
51 #if !defined(USL) && !defined(__uxp__) && !defined(linux) && !defined(CSRG_BASED)
52 #include <osfcn.h>
53 #endif
54 #endif /* __osf */
55
56 #define X_INCLUDE_NETDB_H
57 #define XOS_USE_XT_LOCKING
58 #include <X11/Xos_r.h>
59
60 #include "util/tt_port.h"   
61
62 #if defined(OPT_BUG_SUNOS_4) && defined(__GNUG__)
63         extern "C" { int endhostent(); }
64 #endif
65
66 #define         IP_QUALIFIER    "tcp"
67 #define         TLI_QUALIFIER   "tli"
68
69
70
71 /* 
72  * Null constructor.
73  */
74 _Tt_host::
75 _Tt_host()
76 {
77         _addr = (char *)0;
78         _name = (char *)0;
79         _netname = (char *)0;
80 }
81
82
83 /* 
84  * Destructor. Sets _name to NULL so that reference counting can free up the
85  * space if possible.
86  */
87 _Tt_host::
88 ~_Tt_host()
89 {
90         _addr = (char *)0;
91         _name = (char *)0;
92         _netname = (char *)0;
93 }
94
95
96 /* 
97  * Initializes a _Tt_host object from a hostent structure which is the
98  * standard structure returned by gethostbyaddr and gethostbyname.
99  */
100 int _Tt_host::
101 init_from_hostent(hostent *h)
102 {
103         char            str[40];
104         char            *ip_addr;
105
106         if (h != (hostent *)0) {
107                 _name = h->h_name;
108                 _addr.set((const unsigned char *)h->h_addr, h->h_length);
109                 ip_addr = (char *)_addr;
110                 sprintf(str, "%d.%d.%d.%d",
111                        (int)((unsigned char *)ip_addr)[0],
112                        (int)((unsigned char *)ip_addr)[1],
113                        (int)((unsigned char *)ip_addr)[2],
114                        (int)((unsigned char *)ip_addr)[3]);
115                 _string_address = str;
116                 // We use the ip address but we qualify it with the
117                 // keyword IP_QUALIFIER so that SVR4 clients can
118                 // interoperate with this name.
119
120                 _name = h->h_name;
121                 _netname = IP_QUALIFIER;
122                 _netname = _netname.cat(":").cat(_string_address);
123                 return(1);
124         } else {
125                 return(0);
126         }
127 }
128
129
130 /* 
131  * Initializes a _Tt_host object from an IP address.
132  * 
133  * --> This method should attempt to cache results as much as possible to
134  * avoid repeated calls to gethostbyaddr (which may, in the abscence of
135  * DNS trigger YP lookups). (and in the presence of DNS trigger DNS
136  * lookups which can be just as bad...)
137  */
138 int _Tt_host::
139 init_byaddr(_Tt_string addr)
140 {
141         int result;
142         struct hostent          *addr_ret;
143         _Xgethostbynameparams   addr_buf;
144
145         memset((char*) &addr_buf, 0, sizeof(_Xgethostbynameparams));
146         addr_ret = _XGethostbyaddr((char *)addr, 4, AF_INET, addr_buf);
147         result = init_from_hostent(addr_ret);
148 #ifdef OPT_BUG_SUNOS_5
149         // gethostbyaddr is effectively built on gethostent.  If
150         // endhostent is not called, storage is left around to save the
151         // name service connection, etc.  bug 1111175
152         endhostent();
153 #endif
154         return result;
155 }
156
157
158 /* 
159  * Initializes a _Tt_host object from a string representing the host
160  * address in Internet '.' notation.
161  */
162 int _Tt_host::
163 init_bystringaddr(_Tt_string addr)
164 {
165         
166 #ifdef __osf__
167         unsigned int    *ip_address;
168         unsigned int    ip_address_buf;
169 #else
170         unsigned long   *ip_address;
171         unsigned long   ip_address_buf;
172 #endif
173         struct hostent          *addr_ret;
174         _Xgethostbynameparams   addr_buf;
175
176         memset((char*) &addr_buf, 0, sizeof(_Xgethostbynameparams));
177         ip_address = &ip_address_buf;
178
179         *ip_address = inet_addr((char *)addr);
180         if (*ip_address == -1) {
181                 return(0);
182         }
183
184         _addr.set((const unsigned char *)ip_address, 4);
185         addr_ret = _XGethostbyaddr((char *)_addr, 4, AF_INET, addr_buf);
186         if (! init_from_hostent(addr_ret)) {
187                 // given an ip address we can still communicate with
188                 // this host but we may not know it's name
189                 _string_address = addr;
190                 _netname = IP_QUALIFIER;
191                 _netname = _netname.cat(":").cat(_string_address);
192                 // we couldn't find out the name of the host so we'll
193                 // just call it by it's ip address
194                 _name = addr;
195         }
196 #ifdef OPT_BUG_SUNOS_5
197         // gethostbyaddr is effectively built on gethostent.  If
198         // endhostent is not called, storage is left around to save the
199         // name service connection, etc.  bug 1111175
200         endhostent();
201 #endif
202         return(1);
203 }
204
205 /* 
206  * Initializes a _Tt_host object from a host name.
207  * 
208  */
209 int _Tt_host::
210 init_byname(_Tt_string name)
211 {
212         _Tt_string      qual;
213         _Tt_string      host;
214         int             result;
215         struct hostent          *host_ret;
216         _Xgethostbynameparams   host_buf;
217
218         memset((char*) &host_buf, 0, sizeof(_Xgethostbynameparams));
219         if (name.len() == 0) {
220                 _name = _tt_gethostname();
221         } else {
222                 qual = name.split(':',_name);
223                 if (_name.len()== 0) {
224                         // unqualified name
225                         _name = qual;
226                 } else {
227                         if (qual == IP_QUALIFIER) {
228                                 return(init_bystringaddr(_name));
229                         } else if (qual == TLI_QUALIFIER) {
230                                 /* just leave _name alone */;
231                         } else {
232                                 // unknown qualifier!
233                                 return(0);
234                         }
235                 }
236         }
237         host_ret = _XGethostbyname((char *)_name, host_buf);
238         if (host_ret == NULL) {
239                 result = init_bystringaddr(_name);
240         } else {
241                 result = init_from_hostent(host_ret);
242         }
243 #ifdef OPT_BUG_SUNOS_5
244         // gethostbyname is effectively built on gethostent.  If
245         // endhostent is not called, storage is left around to save the
246         // name service connection, etc.  bug 1111175
247         endhostent();
248 #endif
249         return result;
250 }
251
252
253 /* 
254  * Returns the length of the host address.
255  */
256 int _Tt_host::
257 addr_length() const
258 {
259         return(_addr.len());
260 }
261
262
263 bool_t _Tt_host::
264 xdr(XDR *xdrs)
265 {
266         return(_addr.xdr(xdrs));
267 }
268
269 _Tt_string
270 _tt_host_addr(_Tt_object_ptr &o)
271 {
272         return(((_Tt_host *)o.c_pointer())->addr());
273 }
274
275
276 _Tt_string
277 _tt_host_name(_Tt_object_ptr &o)
278 {
279         return(((_Tt_host *)o.c_pointer())->name());
280 }