Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / tt / lib / mp / mp_procid.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: mp_procid.C /main/4 1997/07/30 15:43:53 samborn $                                                   
28 /*
29  *
30  * mp_procid.cc -- methods for communicating with active processes
31  *
32  * Copyright (c) 1990 by Sun Microsystems, Inc.
33  */
34 #include <errno.h>
35 #include <fcntl.h>
36 #include "util/tt_host.h"
37 #include "mp/mp_file.h"
38 #include "mp/mp_message.h"
39 #include "mp/mp_mp.h"
40 #include "mp/mp_pattern.h"
41 #include "mp/mp_procid.h"
42 #include "mp/mp_session.h"
43 #include "mp/mp_stream_socket.h"
44 #include "util/tt_int_rec.h"
45 #include "util/tt_global_env.h"
46 #include <arpa/inet.h>
47
48 #if defined(sgi)
49 #include <CC/libc.h>
50 #endif
51
52
53 _Tt_procid::
54 _Tt_procid()
55 {
56         _fd = -1;
57         _pid = 0;
58         _version = 0;
59         _flags = 0;
60         _mxdr_stream = (XDR *)0;
61 }
62
63      
64 _Tt_procid::
65 ~_Tt_procid()
66 {
67 }
68
69
70 // 
71 // Returns the fd which will be used to signal this procid if there are
72 // new messages for it. -1 means error. This method is only used in
73 // client mode. This method caches the fd returned from the
74 // _Tt_stream_socket::fd method. This method has the side-effect that it
75 // will accept the connection on the socket if not already done. See the
76 // comments in _Tt_c_procid::set_fd_channel for more details.
77 // 
78 int _Tt_procid::
79 fd()
80 {
81         if (_socket.is_null()) {
82                 return(-1);
83         } else if (_fd == -1) {
84                 _fd = _socket->fd();
85         }
86         
87         return(_fd);
88 }
89
90
91 //
92 // Returns the string version of the id for this procid. See
93 // _Tt_c_procid::init() for a description of the format for this id.
94 //
95 //  XXX: Warning! Do not inline the following. Causes weirdness with
96 //  the table package.
97 //
98 const _Tt_string & _Tt_procid::
99 id() const
100 {
101         // return string representation
102         return(_id);
103 }
104
105
106 //
107 // Returns 1 if this procid's id is the same as the one given.
108 //
109 int _Tt_procid::
110 is_equal(_Tt_string &i)
111 {
112         if (_id.len()) {
113                 return(_id == i);
114         } else  {
115                 return(0);
116         }
117 }
118
119
120 //
121 // Returns the TCP port to connect to to signal a procid for a new
122 // message. This method is only used in server mode.
123 //
124 int _Tt_procid::
125 port() const
126 {
127         if (_socket.is_null()) {
128                 return(-1);
129         } else {
130                 return(_socket->port());
131         }
132 }
133
134
135 //
136 // XDR encodes/decodes a procid.
137 //
138 bool_t _Tt_procid::
139 xdr(XDR *xdrs)
140 {
141         long localpid;
142         
143         if (! _id.xdr(xdrs)) {
144                 return 0;
145         }
146         
147         if (xdrs->x_op == XDR_ENCODE) {
148                 localpid = _pid;
149         }
150         if (! xdr_long(xdrs, &localpid)) {
151                 return 0;
152         }
153         if (xdrs->x_op == XDR_DECODE) {
154                 _pid = (pid_t)localpid;
155         }
156         
157         return(_proc_host_ipaddr.xdr(xdrs));
158 }
159
160
161 void _Tt_procid::
162 print(const _Tt_ostream &os) const
163 {
164         os << _id << " [" << _pid;
165         if (! _proc_host.is_null()) {
166                 os << "@" << _proc_host->name();
167         }
168         os << "]\n";
169 }
170
171
172 //
173 // Returns 1 if this procid is handling m or is voting on it.
174 //
175 int _Tt_procid::
176 processing(const _Tt_message &m)
177 {
178         switch (m.state()) {
179               case TT_FAILED:
180               case TT_HANDLED:
181               case TT_RETURNED:
182                 // if message state is already final then it can't be
183                 // handled by anyone.
184                 return 0;
185               default:
186                 break;
187         }
188         if (!m.handler().is_null()) {
189                 return m.handler()->is_equal( this );
190         } else if (m.message_class() == TT_OFFER) {
191                 return 1;
192         } else {
193                 return 0;
194         }
195 }
196
197
198 //
199 // Wrapper to invoke the _Tt_procid_ptr::xdr method.
200 //
201 bool_t
202 tt_xdr_procid(XDR *xdrs, _Tt_procid_ptr *patp)
203 {
204         return((*patp).xdr(xdrs));
205 }
206
207
208 //
209 // Wrapper to invoke the _Tt_message_list_ptr::xdr method.
210 //
211 bool_t
212 tt_xdr_message_list(XDR *xdrs, _Tt_message_list_ptr *mptr)
213 {
214         return((*mptr).xdr(xdrs));
215 }
216
217
218 //
219 // Add the given path to the list of files this procid object has
220 // joined. 
221 //
222 void _Tt_procid::
223 add_joined_file(_Tt_string fpath)
224 {
225         if (joined_to_file(fpath)) {
226                 return;
227         }
228         if (_joined_files.is_null()) {
229                 _joined_files = new _Tt_string_list();
230         }
231         _joined_files->push(fpath);
232 }
233
234
235 // 
236 // Delete the given path from the list of files this procid object has
237 // joined. 
238 //
239 void _Tt_procid::
240 del_joined_file(_Tt_string fpath)
241 {
242         if (_joined_files.is_null()) {
243                 return;
244         }
245         _Tt_string_list_cursor  jc(_joined_files);
246         
247         while (jc.next()) {
248                 if (*jc == fpath) {
249                         jc.remove();
250                 }
251         }
252 }
253
254
255 //
256 // Return 1 if the given path represents a file this procid object has 
257 // joined. 
258 //
259 int _Tt_procid::
260 joined_to_file(_Tt_string fpath)
261 {
262         if (_joined_files.is_null()) {
263                 return(0);
264         }
265         
266         _Tt_string_list_cursor  jc(_joined_files);
267         
268         while (jc.next()) {
269                 if (*jc == fpath) {
270                         return(1);
271                 }
272         }
273         return(0);
274 }
275
276
277 // 
278 // Invokes _Tt_procid::id method on o which is assumed to point to a
279 // _Tt_procid. Used by the table package to generate keys.
280 // 
281 _Tt_string
282 _tt_procid_id(_Tt_object_ptr &o)
283 {
284         return(((_Tt_procid *)o.c_pointer())->id());
285 }
286
287
288
289
290 #ifdef OPT_ADDMSG_DIRECT
291 //
292 // If this option is turned on, these functions are used to read/write
293 // a given counted buffer to the given _Tt_stream_socket object.
294 // "iohandle" is really a pointer to this _Tt_stream_socket object (it
295 // is given to xdrrec_create, and then XDR will give it to these
296 // functions to do the read/writes to an xdr stream. See
297 // _Tt_s_procid::signal_new_message(_Tt_message_ptr &m), and
298 // _Tt_c_procid::next_message.) 
299 //
300
301
302
303 int
304 _tt_xdr_readit(char *iohandle, char *buf, int nbytes)
305 {
306         int                     rval;
307         fd_set                  readfds;
308         timeval                 tmout;
309         int                     fd;
310         _Tt_stream_socket       *sptr = (_Tt_stream_socket *)iohandle;
311
312         fd = sptr->fd();
313         FD_ZERO(&readfds);
314         FD_SET(fd,&readfds);
315         tmout.tv_sec = 0;
316         tmout.tv_usec = 0;
317         if (select(FD_SETSIZE, &readfds, 0, 0, &tmout) <= 0) {
318                 if (errno == EBADF) {
319                         _tt_syslog( 0, LOG_ERR, "_tt_xdr_readit(): %m" );
320                         return(-1);
321                 }
322         }
323         if (!FD_ISSET(fd, &readfds)) {
324                 _tt_syslog( 0, LOG_ERR, "_tt_xdr_readit(): !FD_ISSET()" );
325                 return(0);
326         }
327         rval = sptr->recv(buf, nbytes);
328         return((rval) ? rval : -1);
329 }
330
331
332 int
333 _tt_xdr_writeit(char *iohandle, char *buf, int nbytes)
334 {
335         return(((_Tt_stream_socket *)iohandle)->send(buf,nbytes));
336 }
337 #endif  // OPT_ADDMSG_DIRECT