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 libraries 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: mp_mp.C /main/7 1999/09/21 08:43:02 mgreess $
30 * mp_mp.cc -- Server and client state object for the Message Passer
32 * Copyright (c) 1990,1992 by Sun Microsystems, Inc.
35 #include "mp/mp_global.h"
37 #include "mp/mp_file.h"
38 #include "mp/mp_session.h"
39 #include "mp/mp_c_session.h"
40 #include "mp/mp_procid.h"
41 #include "mp/mp_rpc_client.h"
42 #include "mp/mp_xdr_functions.h"
43 #include "util/tt_base64.h"
44 #include "util/tt_port.h"
45 #include "util/tt_path.h"
46 #include "api/c/api_error.h"
48 #include <sys/resource.h>
50 #include "tt_options.h"
53 /* AIX's FD_ZERO macro uses bzero() without declaring it. */
58 // This file contains methods for the _Tt_mp object which is an object
59 // whose only function is to serve as a placeholder for global
60 // data/objects relevant to the message-passer routines. Another major
61 // use is to hold the various object caches that map object ids to a
62 // single object of the given class.
64 // Really, the _Tt_mp object as we see it here should go away, being
65 // replaced by _Tt_c_mp, which should represent the client's idea
66 // of the ttsession server it's connected to, and _Tt_s_mp, which
67 // represents the global state of a ttsession server.
71 // Global pointer to *the* _Tt_mp object. There should only be one
72 // _Tt_mp object per tooltalk client.
74 _Tt_mp *_tt_mp = (_Tt_mp *)0;
77 // Constructs a _Tt_mp object in the indicated mode.
83 FD_ZERO(&_session_fds);
84 _session_cache = new _Tt_session_table(_tt_session_address);
86 _current_message_id = _current_pattern_id = 0;
87 active_procs = new _Tt_procid_table(_tt_procid_id, 50);
98 // Returns the value of a counter and then increments the counter. Used
99 // to make different messages sent by the same sender unique.
102 generate_message_id()
104 return(_current_message_id++);
109 // Returns the value of a counter and then increments the counter. Used
110 // to make different patterns registered by the same sender unique.
113 generate_pattern_id()
115 return(_current_pattern_id++);
122 // Finds the _Tt_file object associated with the network pathname <path>.
123 // Optionally creates the _Tt_file object. Returns:
124 // TT_OK but: if (! createIfNot), then fp.is_null() is possible
129 // TT_ERR_INTERNAL can mean ENOMEM
138 _Tt_string network_path;
139 if (_tt_is_network_path(path)) {
143 network_path = _Tt_db_file::getNetworkPath(path);
146 if (_file_cache.is_null()) {
151 _file_cache = new _Tt_file_table(_Tt_file::networkPath_);
152 if (_file_cache.is_null()) {
158 file = _file_cache->lookup( network_path );
159 if (! file.is_null()) {
164 // If we get to this point, the file is not in the cache
166 Tt_status status = TT_OK;
168 file = new _Tt_file( path );
169 if (file.is_null()) {
172 _Tt_db_results dbStatus = file->getDBResults();
173 status = _tt_get_api_error( dbStatus, _TT_API_FILE );
174 if (status == TT_OK) {
175 _file_cache->insert( file );
176 } else if (status == TT_ERR_INTERNAL) {
177 _tt_syslog( 0, LOG_ERR,
178 "_Tt_db_file::_Tt_db_file(): %d", dbStatus);
184 void _Tt_mp::remove_file(_Tt_string path)
186 _Tt_string network_path = _Tt_db_file::getNetworkPath(path);
187 _file_cache->remove(network_path);
191 remove_session(_Tt_string id)
193 _session_cache->remove(id);
198 // Attempts to find the _Tt_session object associated with the given
199 // session id. If not found and create_ifnot is 1 then a new session is
200 // created and initialized. When it is initialized, the auto_start
201 // parameter is examined. If it is 1 then the new session will be
202 // initialized with the c_init method that will do an auto-start of the
203 // session if it isn't running. Otherwise, the "client_session_init"
204 // method is used which just tries to connect to a running session.
206 // Note that the server does use _Tt_c_session since servers can
207 // act as clients for one another when passing file scoped messages.
210 find_session(_Tt_string id, _Tt_session_ptr &sp,
211 int create_ifnot, int auto_start)
213 Tt_status result = TT_OK;
216 if (_session_cache->lookup(id,s)) {
220 // If this is a session address, try the X session ID
221 // XXX - this is a kludge to deal with X session
222 // IDs now that we use addres_strings as the lookup
223 // key. This should be removed if/when we expunge
224 // our internal use of X session IDs.
225 _Tt_session_table_cursor sc(_session_cache);
228 if (sc->has_id(id)) {
231 // Note: we return right here!
237 if (! create_ifnot || id.len() <= 0) {
238 result = TT_ERR_SESSION;
240 _Tt_c_session_ptr s = new _Tt_c_session();
242 result = s->set_id(id);
243 if (result != TT_OK) return result;
245 if (auto_start) result = s->c_init();
246 if (result != TT_OK) return result;
248 if (result == TT_OK) result = s->client_session_init();
249 if (result != TT_OK) return result;
251 _session_cache->insert(s);
260 save_session_fd(int fd)
262 FD_SET(fd, &_session_fds);
267 find_session_by_fd(int fd, _Tt_session_ptr &sp)
269 _Tt_rpc_client_ptr rpc_client;
270 _Tt_session_table_cursor sc(_session_cache);
273 rpc_client = sc->_rpc_client;
274 if (rpc_client->socket() == fd) {
284 check_if_sessions_alive()
294 s_fds = _session_fds;
295 maxfds = _tt_getdtablesize();
296 n = select(maxfds, (fd_set *) 0, &s_fds, (fd_set *) 0, &tmout);
303 if (FD_ISSET(fd, &s_fds)) {
304 if (! find_session_by_fd(fd, s)) {
305 FD_CLR(fd, &_session_fds);
306 } else if (s->ping() != TT_OK) {
307 id = s->process_tree_id();
308 _tt_mp->remove_session(id);
309 FD_CLR(fd, &_session_fds);