Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / tt / slib / mp_self_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 //%%  $XConsortium: mp_self_procid.C /main/3 1995/10/23 12:00:55 rswiston $                                                     
28 /*
29  * @(#)mp_self_procid.cc        1.3 93/07/25
30  * 
31  * Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
32  */
33 #include <unistd.h>
34 #include <errno.h>
35 #include "mp_self_procid.h"
36 #include "mp_s_mp.h"
37 #include "mp/mp_session.h"
38 #include "mp/mp_message.h"
39 #include "mp/mp_arg.h"
40 #include "mp_s_pattern.h"
41 #include "util/tt_global_env.h"
42 #include "util/tt_host.h"
43 #include "util/tt_port.h"
44 #include "util/tt_trace.h"
45
46 _Tt_self_procid::_Tt_self_procid()
47 {
48 }
49
50 _Tt_self_procid::~_Tt_self_procid()
51 {
52 }
53
54 Tt_status
55 _Tt_self_procid::init()
56 {
57         _id = _tt_s_mp->alloc_procid_key();
58         _id = _id.cat(" ").cat(_tt_s_mp->initial_session->address_string());
59         _pid = getpid();
60         // XXX Probably could just set _version and return at this point
61         
62         // _Tt_s_procid::init() expects _proc_host_ipaddr to be initialized
63         if (! _tt_global->get_local_host(_proc_host)) {
64                 return(TT_ERR_NOMP);
65         }
66         _proc_host_ipaddr = _proc_host->addr();
67         return _Tt_s_procid::init();
68 }
69
70 //
71 // We just go ahead and process the messages when we signal ourself
72 // that we have new messages.
73 //
74 Tt_status
75 _Tt_self_procid::signal_new_message()
76 {
77         // XXX do we need to muck with _TT_PROC_SIGNALLED?  I think not.
78         _Tt_next_message_args args;
79         Tt_status status = next_message( args );
80         _Tt_message_list_cursor msgC( args.msgs );
81
82         while (status == TT_OK) {
83                 //
84                 // In theory, we should at this point do the things
85                 // that _Tt_c_procid::next_message() and tt_message_receive()
86                 // do: check the queue for file-scoped messages,
87                 // and run pattern callbacks.  But ttsession declares
88                 // no ptypes, and we lack the client-side machinery
89                 // for callbacks.  So we use our own.
90                 //
91                 msgC.reset();
92                 while (msgC.next()) {
93                         _process_msg( *msgC );
94                 }
95                 status = next_message( args );
96         }
97         if (status == TT_WRN_NOTFOUND) {
98                 return TT_OK;
99         }
100         return status;
101 }
102
103 Tt_callback_action
104 _Tt_self_procid::handle_Session_Trace(
105         const _Tt_message_ptr &msg,
106         void                  *proc
107 )
108 {
109         return ((_Tt_self_procid *)proc)->_handle_Session_Trace( msg );
110 }
111
112 Tt_callback_action
113 _Tt_self_procid::observe_Saved(
114         const _Tt_message_ptr &msg,
115         void                  *proc
116 )
117 {
118         return ((_Tt_self_procid *)proc)->_observe_Saved( msg );
119 }
120
121 _Tt_s_pattern *
122 _Tt_self_procid::s_pattern_create()
123 {
124         _Tt_s_pattern *pat = new _Tt_s_pattern();
125         pat->set_id(_tt_s_mp->initial_session->address_string());
126         return pat;
127 }
128
129 //
130 // This is a very simple callback server-side pattern callback scheme.
131 // It does not do everything that client-side callbacks do.
132 //
133 Tt_status
134 _Tt_self_procid::_process_msg(
135         const _Tt_message_ptr &msg
136 )
137 {
138         _Tt_string pat_id = msg->pattern_id();
139         if (pat_id.len() == 0) {
140                 return TT_OK;
141         }
142         _Tt_pattern_list_cursor patC( _patterns );
143         while (patC.next()) {
144                 if (patC->id() == pat_id) {
145                         if (patC->server_callback != 0) {
146                                 if (    (*(patC->server_callback))( msg, this )
147                                      == TT_CALLBACK_PROCESSED)
148                                 {
149                                         break;
150                                 }
151                         }
152                 }
153         }
154         return TT_OK;
155 }
156
157 Tt_status
158 _Tt_self_procid::_reply(
159         const _Tt_message_ptr &msg
160 )
161 {
162         return update_message( msg, TT_HANDLED );
163 }
164
165 Tt_status
166 _Tt_self_procid::_fail(
167         const _Tt_message_ptr &msg,
168         int return_status
169 )
170 {
171         Tt_status status = msg->set_status( return_status );
172         if (status != TT_OK) {
173                 return status;
174         }
175         return update_message( msg, TT_FAILED );
176 }
177
178 Tt_status
179 _Tt_self_procid::update_message(
180         const _Tt_message_ptr &msg,
181         Tt_state               new_state
182 )
183 {
184         //
185         // This is the sort of checking done by
186         // _Tt_c_procid::update_message().
187         //
188         if (msg->message_class() != TT_REQUEST) {
189                 return TT_ERR_CLASS;
190         }
191         if (msg->handler().is_null()) {
192                 return TT_ERR_NOTHANDLER;
193         }
194         _Tt_procid_ptr me = (_Tt_procid *)this;
195         if (! me->is_equal( msg->handler() )) {
196                 return TT_ERR_NOTHANDLER;
197         }
198         switch (msg->state()) {
199               case TT_FAILED:
200               case TT_HANDLED:
201                 return(TT_ERR_INVALID);
202               default:
203                 break;
204         }
205         return _Tt_s_procid::update_message( msg, new_state );
206 }
207
208 Tt_callback_action
209 _Tt_self_procid::_handle_Session_Trace(
210         const _Tt_message_ptr &msg
211 )
212 {
213         _Tt_arg_list_ptr args = new _Tt_arg_list( *msg->args() );
214         _Tt_arg_list_cursor argC( args );
215         if (! argC.next()) {
216                 _fail( msg, TT_DESKTOP_EPROTO );
217                 return TT_CALLBACK_PROCESSED;
218         }
219         _Tt_string script;
220         Tt_status status = (*argC)->data_string( script );
221         if (status != TT_OK) {
222                 _fail( msg, (int)status );
223                 return TT_CALLBACK_PROCESSED;
224         }
225         if ((script.len() == 0) && (msg->file().len() > 0)) {
226                 script = _tt_network_path_to_local_path(msg->file());
227         }
228         if (argC.next()) {
229                 _fail( msg, TT_DESKTOP_ENOTSUP );
230                 return TT_CALLBACK_PROCESSED;
231         }
232         if (_tt_putenv( TRACE_SCRIPT, script ) == 0) {
233                 _fail( msg, TT_DESKTOP_ENOMEM );
234                 return TT_CALLBACK_PROCESSED;
235         }
236         tt_trace_control( 0 );
237         tt_trace_control( 1 );
238         _reply( msg );
239         return TT_CALLBACK_PROCESSED;
240 }
241
242 Tt_callback_action
243 _Tt_self_procid::_observe_Saved(
244         const _Tt_message_ptr &
245 )
246 {
247         if (kill( getpid(), SIGTYPES ) < 0) {
248                 _tt_syslog(0, LOG_ERR, "kill(): %m");
249         }
250         return TT_CALLBACK_PROCESSED;
251 }