Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
71
cde/lib/tt/lib/mp/Imakefile
Normal file
71
cde/lib/tt/lib/mp/Imakefile
Normal file
@@ -0,0 +1,71 @@
|
||||
XCOMM $TOG: Imakefile /main/8 1999/08/30 10:52:07 mgreess $
|
||||
#define DoNormalLib NormalLibTt
|
||||
#define DoSharedLib SharedLibTt
|
||||
#define DoDebugLib DebugLibTt
|
||||
#define DoProfileLib ProfileLibTt
|
||||
#define LibName tt
|
||||
#define SoRev SOTTREV
|
||||
#define LibHeaders NO
|
||||
#define LibCreate NO
|
||||
|
||||
#define CplusplusSource YES
|
||||
DEPEND_DEFINES = $(CXXDEPENDINCLUDES) $(ISAM_INCLUDES)
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#include "../../tooltalk.tmpl"
|
||||
|
||||
DEFINES =
|
||||
INCLUDES = -I../../lib
|
||||
ISAM_INCLUDES = -I../../mini_isam
|
||||
|
||||
/* Use BSD-compatible accept() call */
|
||||
#ifdef RsArchitecture
|
||||
CXXEXTRA_DEFINES = -DCOMPAT_43
|
||||
#endif
|
||||
|
||||
|
||||
/*** NOTE!
|
||||
*** Every time a .o is added below it needs to be added to
|
||||
*** the lib/tt/lib Imakefile in MP_OBJS and SHARED_MP_OBJS
|
||||
***/
|
||||
|
||||
SRCS = mp_arg.C mp_arg_utils.C mp_auth.C \
|
||||
mp_auth_functions.C mp_c_file.C \
|
||||
mp_c_file_utils.C mp_c_message.C mp_c_message_utils.C \
|
||||
mp_c_mp.C mp_c_msg_context.C mp_c_msg_context_utils.C \
|
||||
mp_c_pattern.C mp_c_procid.C mp_c_procid_utils.C \
|
||||
mp_c_session.C mp_c_session_prop.C mp_c_session_utils.C \
|
||||
mp_context.C mp_context_utils.C mp_desktop.C \
|
||||
mp_desktop_utils.C mp_file.C mp_file_utils.C \
|
||||
mp_message.C mp_message_utils.C mp_mp.C \
|
||||
mp_mp_utils.C mp_msg_context.C mp_msg_context_utils.C \
|
||||
mp_pat_context.C mp_pat_context_utils.C mp_pattern.C \
|
||||
mp_pattern_utils.C mp_procid.C mp_procid_utils.C \
|
||||
mp_rpc_client.C mp_rpc_client_utils.C mp_rpc_fns.C \
|
||||
mp_session.C mp_session_prop.C mp_session_prop_utils.C \
|
||||
mp_session_utils.C mp_stream_socket.C mp_stream_socket_utils.C \
|
||||
mp_trace.C mp_xdr_functions.C
|
||||
|
||||
OBJS = mp_arg.o mp_arg_utils.o mp_auth.o \
|
||||
mp_auth_functions.o mp_c_file.o \
|
||||
mp_c_file_utils.o mp_c_message.o mp_c_message_utils.o \
|
||||
mp_c_mp.o mp_c_msg_context.o mp_c_msg_context_utils.o \
|
||||
mp_c_pattern.o mp_c_procid.o mp_c_procid_utils.o \
|
||||
mp_c_session.o mp_c_session_prop.o mp_c_session_utils.o \
|
||||
mp_context.o mp_context_utils.o mp_desktop.o \
|
||||
mp_desktop_utils.o mp_file.o mp_file_utils.o \
|
||||
mp_message.o mp_message_utils.o mp_mp.o \
|
||||
mp_mp_utils.o mp_msg_context.o mp_msg_context_utils.o \
|
||||
mp_pat_context.o mp_pat_context_utils.o mp_pattern.o \
|
||||
mp_pattern_utils.o mp_procid.o mp_procid_utils.o \
|
||||
mp_rpc_client.o mp_rpc_client_utils.o mp_rpc_fns.o \
|
||||
mp_session.o mp_session_prop.o mp_session_prop_utils.o \
|
||||
mp_session_utils.o mp_stream_socket.o mp_stream_socket_utils.o \
|
||||
mp_trace.o mp_xdr_functions.o
|
||||
|
||||
#include <Library.tmpl>
|
||||
|
||||
SubdirLibraryRule($(OBJS))
|
||||
|
||||
DependTarget()
|
||||
23
cde/lib/tt/lib/mp/mp.h
Normal file
23
cde/lib/tt/lib/mp/mp.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp.h /main/3 1995/10/23 10:18:24 rswiston $ */
|
||||
/*
|
||||
* mp.h -- public interface classes to the Message Passer
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef _MP_H
|
||||
#define _MP_H
|
||||
|
||||
#include <mp/mp_global.h>
|
||||
#include <mp/mp_arg.h>
|
||||
#include <mp/mp_file.h>
|
||||
#include <mp/mp_message.h>
|
||||
#include <mp/mp_mp.h>
|
||||
#include <mp/mp_procid.h>
|
||||
#include <mp/mp_pattern.h>
|
||||
#include <mp/mp_session.h>
|
||||
|
||||
#endif /* _MP_H */
|
||||
381
cde/lib/tt/lib/mp/mp_arg.C
Normal file
381
cde/lib/tt/lib/mp/mp_arg.C
Normal file
@@ -0,0 +1,381 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_arg.C /main/3 1995/10/23 10:18:54 rswiston $
|
||||
/*
|
||||
*
|
||||
* @(#)mp_arg.C 1.19 93/09/07
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_arg.C
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Implementation of the _Tt_arg & _Tt_arg_list classes representing
|
||||
* arguments to a method or a procedure.
|
||||
*/
|
||||
#include "mp/mp_global.h"
|
||||
#include "mp/mp_arg.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "util/tt_enumname.h"
|
||||
#include "util/tt_iostream.h"
|
||||
#include "util/tt_xdr_utils.h"
|
||||
#include "util/tt_global_env.h"
|
||||
|
||||
|
||||
/*
|
||||
* Construct a _Tt_arg with everything zeroed out
|
||||
*/
|
||||
_Tt_arg::
|
||||
_Tt_arg()
|
||||
{
|
||||
constructor_common();
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy constructor for _Tt_args.
|
||||
*/
|
||||
_Tt_arg::
|
||||
_Tt_arg(const _Tt_arg &a)
|
||||
{
|
||||
_mode = a._mode;
|
||||
_type = a._type;
|
||||
_name = a._name;
|
||||
_data_type = a._data_type;
|
||||
_data_int = a._data_int;
|
||||
_data_string = a._data_string;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the _Tt_arg pointed to by a _Tt_arg_ptr.
|
||||
*/
|
||||
_Tt_arg::
|
||||
_Tt_arg(const _Tt_arg_ptr &p)
|
||||
{
|
||||
_mode = p->_mode;
|
||||
_type = p->_type;
|
||||
_name = p->_name;
|
||||
_data_type = p->_data_type;
|
||||
_data_int = p->_data_int;
|
||||
_data_string = p->_data_string;
|
||||
}
|
||||
|
||||
_Tt_arg::
|
||||
_Tt_arg(const _Tt_string &t)
|
||||
{
|
||||
constructor_common();
|
||||
_type = t;
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructs a _Tt_arg where the mode and type are known.
|
||||
* No valid data is yet known.
|
||||
*
|
||||
*/
|
||||
_Tt_arg::
|
||||
_Tt_arg(Tt_mode m, _Tt_string &t)
|
||||
{
|
||||
constructor_common();
|
||||
_mode = m;
|
||||
_type = t;
|
||||
}
|
||||
|
||||
|
||||
_Tt_arg::
|
||||
_Tt_arg(const char *t)
|
||||
{
|
||||
_Tt_string ts(t);
|
||||
constructor_common();
|
||||
_type = ts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructs a _Tt_arg where the mode and type are known.
|
||||
* No valid data is yet known.
|
||||
*
|
||||
*/
|
||||
_Tt_arg::
|
||||
_Tt_arg(Tt_mode m, const char *t)
|
||||
{
|
||||
_Tt_string ts(t);
|
||||
constructor_common();
|
||||
_mode = m;
|
||||
_type = ts;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destroys any memory associated with _Tt_arg
|
||||
*/
|
||||
_Tt_arg::
|
||||
~_Tt_arg()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sets the data associated with this arg as an integer
|
||||
*/
|
||||
Tt_status _Tt_arg::
|
||||
set_data_int(int i)
|
||||
{
|
||||
_data_type = INT;
|
||||
_data_int = i;
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sets the data associated with this arg as a byte string
|
||||
*/
|
||||
Tt_status _Tt_arg::
|
||||
set_data_string(const _Tt_string &s)
|
||||
{
|
||||
_data_type = STRING;
|
||||
_data_string = s;
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Obtain the data for this arg as an int.
|
||||
* Return TT_ERR_NUM if the value is a string.
|
||||
*/
|
||||
Tt_status _Tt_arg::
|
||||
data_int(int &i) const
|
||||
{
|
||||
if (_data_type != INT) return TT_ERR_NUM;
|
||||
i = _data_int;
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtain the data for this arg as a string.
|
||||
* Return TT_ERR_POINTER if the value is an int.
|
||||
*/
|
||||
Tt_status _Tt_arg::
|
||||
data_string(_Tt_string &s) const
|
||||
{
|
||||
if (_data_type != STRING) return TT_ERR_POINTER;
|
||||
s = _data_string;
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prints out a _Tt_arg. Mainly used for debugging purposes only.
|
||||
*/
|
||||
void _Tt_arg::
|
||||
print(const _Tt_ostream &os) const
|
||||
{
|
||||
os << _tt_enumname(_mode) << " " << _type << ": ";
|
||||
|
||||
if (_name.len() > 0) {
|
||||
os << "<" << _name << ">\n";
|
||||
} else if (_data_type==INT) {
|
||||
os << _data_int << "\n";
|
||||
} else {
|
||||
_data_string.print(os, _Tt_string_user_width, 1);
|
||||
os << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* XDR encodes and decodes a _Tt_arg object. Returns 1 if successful and
|
||||
* 0 otherwise.
|
||||
*/
|
||||
bool_t _Tt_arg::
|
||||
xdr(XDR *xdrs)
|
||||
{
|
||||
if (! xdr_int(xdrs, (int *)&_mode)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _type.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (_tt_global->xdr_version() < TT_PUSH_ROTATE_XDR_VERSION) {
|
||||
//
|
||||
// Earlier versions of the XDR protocol included an
|
||||
// a never-used _Tt_string called _matched_type.
|
||||
//
|
||||
_Tt_string _matched_type;
|
||||
if (! _matched_type.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
if (! _name.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (! xdr_int(xdrs, (int *)&_data_type)) {
|
||||
return(0);
|
||||
}
|
||||
if (_data_type==INT) {
|
||||
if (! xdr_int(xdrs, &_data_int)) {
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
if (! _data_string.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* update_value is used when merging a reply with the original message.
|
||||
* The value cells of this arg are updated with the value cells in the
|
||||
* given arg.
|
||||
*/
|
||||
Tt_status _Tt_arg::
|
||||
update_value(const _Tt_arg &x)
|
||||
{
|
||||
_data_type = x._data_type;
|
||||
_data_int = x._data_int;
|
||||
_data_string = x._data_string;
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper whose only purpose is to invoke the xdr method on the given
|
||||
* pointer.
|
||||
*/
|
||||
bool_t
|
||||
tt_xdr_arg(XDR *xdrs, _Tt_arg_ptr *ptr)
|
||||
{
|
||||
return((*ptr)->xdr(xdrs));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* XDR encodes and decodes a list of _Tt_arg objects. p is assumed to
|
||||
* point to the list on which to append/get the objects.
|
||||
*/
|
||||
bool_t
|
||||
tt_xdr_arg_list(XDR *xdrs, _Tt_arg_list_ptr *p)
|
||||
{
|
||||
return((*p).xdr(xdrs));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_tt_arg_print(const _Tt_ostream &os, const _Tt_object *obj)
|
||||
{
|
||||
((_Tt_arg *)obj)->print(os);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common initialization code for _Tt_arg constructors.
|
||||
*/
|
||||
void _Tt_arg::
|
||||
constructor_common()
|
||||
{
|
||||
_mode = TT_MODE_UNDEFINED;
|
||||
_type = (char *)0;
|
||||
_name = (char *)0;
|
||||
_data_type = UNSET;
|
||||
_data_int = 0;
|
||||
_data_string = (char *)0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns non-zero score if \'this\', which must be a pattern arg, matches
|
||||
* the given arg, which must be a message arg. Matching is
|
||||
* less restrictive than equality, since the following exceptions
|
||||
* apply:
|
||||
* 1\) If the pattern type is ALL, it matches any type in the message.
|
||||
* 2\) If the message type is ALL, it matches any type in the pattern.
|
||||
* \[Somehow, the pattern type should get into the message, but
|
||||
* I don\'t know how yet.\]
|
||||
* 3\) If the pattern value is not set, it matches any value in the
|
||||
* message.
|
||||
* Although this method is only used in the server, it is too hard
|
||||
* to figure out how to get messages and patterns un-XDRed in
|
||||
* the server with args as a _Tt_s_arg instead of _Tt_arg.
|
||||
*/
|
||||
int _Tt_arg::
|
||||
match_score(const _Tt_arg &msg_arg, int &used_wildcard) const
|
||||
{
|
||||
// Comparing args works because XDR is defined as always
|
||||
// padding with zeroes.
|
||||
|
||||
int score = 1; // wildcard match scores only 1
|
||||
used_wildcard = 0;
|
||||
|
||||
// match modes
|
||||
if (_mode == msg_arg.mode()) {
|
||||
score++;
|
||||
} else if (_mode != TT_MODE_UNDEFINED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// match types
|
||||
if (_type == msg_arg.type()) {
|
||||
// check equality first, in case both are "ALL"
|
||||
score++;
|
||||
} else if (_type == "ALL") {
|
||||
used_wildcard = 1; // pattern ALL matches everything
|
||||
} else if (msg_arg.type() == "ALL") {
|
||||
used_wildcard = 1; // message ALL matches everything
|
||||
} else {
|
||||
return 0; // types mismatched
|
||||
}
|
||||
|
||||
// match values
|
||||
switch (_data_type) {
|
||||
case INT:
|
||||
case STRING:
|
||||
default:
|
||||
if (msg_arg.data_type() != _data_type) {
|
||||
return 0;
|
||||
}
|
||||
switch (_data_type) {
|
||||
case INT:
|
||||
if (msg_arg.data_int() != _data_int) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case STRING:
|
||||
if (msg_arg.data_string() != _data_string) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
score++;
|
||||
break;
|
||||
case UNSET:
|
||||
if (msg_arg.data_type() != _data_type) {
|
||||
used_wildcard = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// everything matches
|
||||
return score;
|
||||
}
|
||||
|
||||
//
|
||||
// Returns 1 if the typed values are equal, else 0. Ignores mode and
|
||||
// vtype. Used by _Tt_pat_context::deleteValue().
|
||||
//
|
||||
int _Tt_arg::
|
||||
operator==(const _Tt_arg &arg) const
|
||||
{
|
||||
if (_data_type != arg.data_type()) {
|
||||
return 0;
|
||||
}
|
||||
switch (_data_type) {
|
||||
case INT:
|
||||
if (_data_int != arg.data_int()) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case STRING:
|
||||
if (_data_string != arg.data_string()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
96
cde/lib/tt/lib/mp/mp_arg.h
Normal file
96
cde/lib/tt/lib/mp/mp_arg.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_arg.h /main/3 1995/10/23 10:19:02 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
* Tool Talk Message Passer (MP) - mp_arg.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*
|
||||
* _Tt_arg is an object that represents a positional argument in a
|
||||
* _Tt_message. This object implements methods to do the XDR encoding
|
||||
* and decoding of value types (which may be user-defined). This
|
||||
* module also implements XDR encoding and decoding of _Tt_arg_list
|
||||
* objects but this will eventually be integrated into the list
|
||||
* package.
|
||||
*/
|
||||
|
||||
#ifndef _MP_ARG_H
|
||||
#define _MP_ARG_H
|
||||
#include <mp/mp_global.h>
|
||||
#include <mp/mp_arg_utils.h>
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
class _Tt_message;
|
||||
class _Tt_arg : public _Tt_object {
|
||||
public:
|
||||
enum stored_data_type {UNSET,INT,STRING};
|
||||
_Tt_arg();
|
||||
_Tt_arg(const _Tt_arg &a);
|
||||
_Tt_arg(const _Tt_arg_ptr &p);
|
||||
_Tt_arg(const _Tt_string &t);
|
||||
_Tt_arg(Tt_mode m, _Tt_string &type);
|
||||
_Tt_arg(const char *t);
|
||||
_Tt_arg(Tt_mode m, const char *type);
|
||||
virtual ~_Tt_arg();
|
||||
Tt_status set_data_int(int i);
|
||||
Tt_status set_data_string(const _Tt_string &s);
|
||||
Tt_status set_mode(Tt_mode m) {
|
||||
_mode = m;
|
||||
return TT_OK;
|
||||
}
|
||||
Tt_status set_type(const _Tt_string &type) {
|
||||
_type = type;
|
||||
return TT_OK;
|
||||
}
|
||||
Tt_status set_name(const _Tt_string &name) {
|
||||
_name = name;
|
||||
return TT_OK;
|
||||
}
|
||||
Tt_mode mode() const {
|
||||
return _mode;
|
||||
}
|
||||
const _Tt_string &type() const {
|
||||
return _type;
|
||||
}
|
||||
const _Tt_string &name() const {
|
||||
return _name;
|
||||
}
|
||||
stored_data_type data_type() const {
|
||||
return _data_type;
|
||||
}
|
||||
Tt_status data_int(int &i) const;
|
||||
int data_int() const {
|
||||
return _data_int;
|
||||
}
|
||||
Tt_status data_string(_Tt_string &s) const;
|
||||
const _Tt_string &data_string() const {
|
||||
return _data_string;
|
||||
}
|
||||
void print(const _Tt_ostream &os) const;
|
||||
bool_t xdr(XDR *xdrs);
|
||||
Tt_status update_value(const _Tt_arg &x);
|
||||
int match_score(const _Tt_arg &arg,
|
||||
int &used_wildcard) const;
|
||||
int operator==(const _Tt_arg &arg) const;
|
||||
|
||||
protected:
|
||||
Tt_mode _mode;
|
||||
_Tt_string _type;
|
||||
_Tt_string _name;
|
||||
|
||||
stored_data_type _data_type;
|
||||
// Only one of the following two values will be set. This could
|
||||
// be a union, with _data_type as the discriminant, but it is
|
||||
// not worth the trouble.
|
||||
int _data_int;
|
||||
_Tt_string _data_string;
|
||||
private:
|
||||
void constructor_common();
|
||||
};
|
||||
void _tt_arg_print(const _Tt_ostream &os, const _Tt_object *obj);
|
||||
bool_t tt_xdr_arg(XDR *xdrs, _Tt_arg_ptr *ptr);
|
||||
bool_t tt_xdr_arg_list(XDR *xdrs, _Tt_arg_list_ptr *lptr);
|
||||
#endif /* _MP_ARG_H */
|
||||
14
cde/lib/tt/lib/mp/mp_arg_utils.C
Normal file
14
cde/lib/tt/lib/mp/mp_arg_utils.C
Normal file
@@ -0,0 +1,14 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_arg_utils.C /main/3 1995/10/23 10:19:09 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_arg_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <mp/mp_arg.h>
|
||||
|
||||
implement_list_of(_Tt_arg)
|
||||
20
cde/lib/tt/lib/mp/mp_arg_utils.h
Normal file
20
cde/lib/tt/lib/mp/mp_arg_utils.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_arg_utils.h /main/3 1995/10/23 10:19:16 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_arg_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef MP_ARG_UTILS_H
|
||||
#define MP_ARG_UTILS_H
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_list.h>
|
||||
|
||||
class _Tt_arg;
|
||||
declare_list_of(_Tt_arg)
|
||||
|
||||
#endif /* MP_ARG_UTILS_H */
|
||||
329
cde/lib/tt/lib/mp/mp_auth.C
Normal file
329
cde/lib/tt/lib/mp/mp_auth.C
Normal file
@@ -0,0 +1,329 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_auth.C /main/2 1999/08/30 14:13:40 mgreess $
|
||||
/*
|
||||
* @(#)mp_auth.C 1.84 96/01/10
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_auth.cc
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Implementation of the _Tt_auth class.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "mp/mp_auth.h"
|
||||
#include "mp/mp_auth_functions.h"
|
||||
#include "mp/mp_global.h"
|
||||
#include "util/tt_port.h"
|
||||
|
||||
_Tt_auth::
|
||||
_Tt_auth(_Tt_auth_level auth_level)
|
||||
{
|
||||
_auth_level = auth_level;
|
||||
_auth_cookie = "";
|
||||
}
|
||||
|
||||
|
||||
_Tt_auth::
|
||||
~_Tt_auth()
|
||||
{
|
||||
}
|
||||
|
||||
Tt_status _Tt_auth::
|
||||
generate_auth_cookie()
|
||||
{
|
||||
static char *funcname = "_Tt_auth::make_auth_cookie()";
|
||||
_tt_AuthFileEntry *entry;
|
||||
int exists;
|
||||
char *filename;
|
||||
int original_umask;
|
||||
int retval;
|
||||
Tt_status status;
|
||||
|
||||
_entries_head = _entries_tail = NULL;
|
||||
status = TT_OK;
|
||||
_auth_cookie = _tt_GenerateMagicCookie(_TT_ICEAUTH_MAGIC_COOKIE_LEN);
|
||||
|
||||
if (! (filename = _tt_AuthFileName())) {
|
||||
_tt_syslog(0, LOG_ERR, "%s: Missing TTAUTHORITY file.\n", funcname);
|
||||
return TT_AUTHFILE_MISSING;
|
||||
}
|
||||
|
||||
if (_tt_AuthLockSuccess !=
|
||||
(retval = _tt_LockAuthFile(filename,
|
||||
_TT_ICEAUTH_DEFAULT_RETRIES,
|
||||
_TT_ICEAUTH_DEFAULT_TIMEOUT,
|
||||
_TT_ICEAUTH_DEFAULT_DEADTIME))) {
|
||||
char *reason = "unknown error";
|
||||
|
||||
_tt_UnlockAuthFile(filename);
|
||||
if (retval == _tt_AuthLockTimeout) {
|
||||
reason = "timeout";
|
||||
status = TT_AUTHFILE_LOCK_TIMEOUT;
|
||||
}
|
||||
else {
|
||||
reason = "lock error";
|
||||
status = TT_AUTHFILE_LOCK;
|
||||
}
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: %s in locking authority file \"%s\".\n",
|
||||
funcname, reason, filename);
|
||||
return status;
|
||||
}
|
||||
|
||||
original_umask = umask(077);
|
||||
|
||||
exists = (0 == access(filename, F_OK));
|
||||
if (exists && (0 != access(filename, R_OK | W_OK)))
|
||||
{
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: \"%s\" not writable, auth entry not added.\n",
|
||||
funcname, filename);
|
||||
status = TT_AUTHFILE_ACCESS;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (exists && TT_OK != (status = read_auth_file(filename))) {
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: could not read \"%s\". New entry not written.\n",
|
||||
funcname, filename);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
entry = (_tt_AuthFileEntry*) malloc(sizeof(_tt_AuthFileEntry));
|
||||
if (NULL == entry) {
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: memory error. New entry not written.\n",
|
||||
funcname);
|
||||
status = TT_ERR_NOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
entry->protocol_name = strdup(_TT_ICEAUTH_PROTOCOL_NAME);
|
||||
entry->protocol_data_length = 0;
|
||||
entry->protocol_data = strdup("");
|
||||
entry->network_id = strdup((char*) _sessionid);
|
||||
entry->auth_name = strdup(_TT_ICEAUTH_AUTH_NAME);
|
||||
entry->auth_data_length = strlen((char*) _auth_cookie) + 1;
|
||||
entry->auth_data = strdup((char*) _auth_cookie);
|
||||
|
||||
status = modify_auth_entry(entry, &_entries_head);
|
||||
|
||||
status = write_auth_file(filename);
|
||||
if (TT_OK != status) {
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: could not write \"%s\". New entry not written.\n",
|
||||
funcname, filename);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
(void) umask(original_umask);
|
||||
_tt_UnlockAuthFile(filename);
|
||||
return status;
|
||||
}
|
||||
|
||||
Tt_status _Tt_auth::
|
||||
read_auth_entries(FILE *fp, _tt_AuthFileEntryList **headp)
|
||||
{
|
||||
static char *funcname = "_Tt_auth::read_auth_entries()";
|
||||
_tt_AuthFileEntry *entry;
|
||||
_tt_AuthFileEntryList *head;
|
||||
_tt_AuthFileEntryList *el_new;
|
||||
_tt_AuthFileEntryList *tail;
|
||||
int n;
|
||||
|
||||
entry = NULL;
|
||||
head = tail = NULL;
|
||||
n = 0;
|
||||
|
||||
while ((entry = _tt_ReadAuthFileEntry(fp)) != NULL) {
|
||||
|
||||
el_new = (_tt_AuthFileEntryList*) malloc(sizeof(_tt_AuthFileEntryList));
|
||||
if (NULL == el_new) {
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: memory error. New entry not written.\n",
|
||||
funcname);
|
||||
return TT_ERR_NOMEM;
|
||||
}
|
||||
|
||||
el_new->next = NULL;
|
||||
el_new->entry = entry;
|
||||
if (tail) /* if not first time through append */
|
||||
tail->next = el_new;
|
||||
else
|
||||
head = el_new; /* first time through, so assign */
|
||||
tail = el_new;
|
||||
n++;
|
||||
}
|
||||
|
||||
*headp = head;
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
Tt_status _Tt_auth::
|
||||
read_auth_file(char *filename)
|
||||
{
|
||||
static char *funcname = "Tt_auth::read_auth_file()";
|
||||
FILE *authfp;
|
||||
Tt_status status = TT_OK;
|
||||
|
||||
if (0 == (authfp = fopen (filename, "rb"))) {
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: unable to read auth entries from file \"%s\"\n",
|
||||
funcname, filename);
|
||||
return TT_AUTHFILE_ACCESS;
|
||||
}
|
||||
|
||||
status = read_auth_entries(authfp, &_entries_head);
|
||||
if (TT_OK != status)
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: unable to read auth entries from file \"%s\"\n",
|
||||
funcname, filename);
|
||||
|
||||
(void) fclose (authfp);
|
||||
return status;
|
||||
}
|
||||
|
||||
Tt_status _Tt_auth::
|
||||
modify_auth_entry(_tt_AuthFileEntry *entry, _tt_AuthFileEntryList **headp)
|
||||
{
|
||||
static char *funcname = "Tt_auth::modify_auth_entry()";
|
||||
_tt_AuthFileEntryList *list, *prev, *el_new;
|
||||
|
||||
for (prev=NULL, list=*headp; list; list=list->next) {
|
||||
if ((0 == strcmp(list->entry->protocol_name, entry->protocol_name)) &&
|
||||
(list->entry->protocol_data_length==entry->protocol_data_length) &&
|
||||
(0 == strncmp(list->entry->protocol_data, entry->protocol_data,
|
||||
entry->protocol_data_length)) &&
|
||||
(0 == strcmp(list->entry->network_id, entry->network_id)) &&
|
||||
(0 == strcmp(list->entry->auth_name, entry->auth_name)) ) {
|
||||
|
||||
_tt_FreeAuthFileEntry(list->entry);
|
||||
list->entry = entry;
|
||||
return TT_OK;
|
||||
}
|
||||
prev = list;
|
||||
}
|
||||
|
||||
el_new = (_tt_AuthFileEntryList*) malloc(sizeof(_tt_AuthFileEntryList));
|
||||
if (NULL == el_new) {
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: memory error. New entry not written.\n",
|
||||
funcname);
|
||||
return TT_ERR_NOMEM;
|
||||
}
|
||||
|
||||
el_new->next = NULL;
|
||||
el_new->entry = entry;
|
||||
if (NULL == prev)
|
||||
*headp = el_new;
|
||||
else
|
||||
prev->next = el_new;
|
||||
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
|
||||
Tt_status _Tt_auth::
|
||||
write_auth_file(char *filename)
|
||||
{
|
||||
static char *funcname = "Tt_auth::write_auth_file()";
|
||||
static char *suffix = "-n";
|
||||
FILE *fp;
|
||||
_tt_AuthFileEntryList *list;
|
||||
char *tmpnam;
|
||||
|
||||
tmpnam = (char*) malloc(strlen(filename) + strlen(suffix) + 1);
|
||||
if (NULL == tmpnam) {
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: memory error. New entry not written.\n",
|
||||
funcname);
|
||||
return TT_ERR_NOMEM;
|
||||
}
|
||||
|
||||
strcpy(tmpnam, filename);
|
||||
strcat(tmpnam, "-n"); /* for new */
|
||||
(void) unlink(tmpnam);
|
||||
fp = fopen (tmpnam, "wb"); /* umask is still set to 0077 */
|
||||
if (!fp) {
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: unable to open tmp file \"%s\"\n",
|
||||
funcname, tmpnam);
|
||||
return TT_AUTHFILE_ACCESS;
|
||||
}
|
||||
|
||||
for (list=_entries_head; list; list=list->next)
|
||||
_tt_WriteAuthFileEntry (fp, list->entry);
|
||||
|
||||
(void) fclose (fp);
|
||||
|
||||
(void) unlink(filename);
|
||||
if (link (tmpnam, filename) == -1)
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"%s: unable to link authority file %s, use %s\n",
|
||||
funcname, filename, tmpnam);
|
||||
else
|
||||
(void) unlink(tmpnam);
|
||||
|
||||
return TT_OK;
|
||||
}
|
||||
Tt_status _Tt_auth::
|
||||
retrieve_auth_cookie()
|
||||
{
|
||||
char *buff = NULL;
|
||||
_tt_AuthFileEntry *entry = NULL;
|
||||
|
||||
entry = _tt_GetAuthFileEntry(_TT_ICEAUTH_PROTOCOL_NAME,
|
||||
(char*) _sessionid,
|
||||
_TT_ICEAUTH_AUTH_NAME);
|
||||
if (NULL == entry)
|
||||
return TT_AUTHFILE_ENTRY_MISSING;
|
||||
|
||||
buff = (char*) malloc(entry->auth_data_length + 1);
|
||||
if (NULL == buff) return TT_ERR_NOMEM;
|
||||
|
||||
strncpy(buff, entry->auth_data, entry->auth_data_length);
|
||||
buff[entry->auth_data_length] = '\0';
|
||||
_auth_cookie = buff;
|
||||
|
||||
free(buff);
|
||||
_tt_FreeAuthFileEntry(entry);
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
Tt_status _Tt_auth::
|
||||
set_auth_level(_Tt_auth_level auth_level)
|
||||
{
|
||||
_auth_level = auth_level;
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
Tt_status _Tt_auth::
|
||||
set_sessionid(
|
||||
int rpc_program,
|
||||
_Tt_auth_level auth_level,
|
||||
_Tt_string hostaddr,
|
||||
int rpc_version)
|
||||
{
|
||||
char strid[BUFSIZ];
|
||||
const char *format = "%d/%d/%s/%d";
|
||||
|
||||
_rpc_program = rpc_program;
|
||||
_auth_level = auth_level;
|
||||
_hostaddr = hostaddr;
|
||||
_rpc_version = rpc_version;
|
||||
|
||||
sprintf(strid,
|
||||
format,
|
||||
_rpc_program,
|
||||
(int) _auth_level,
|
||||
(char*) _hostaddr,
|
||||
_rpc_version);
|
||||
_sessionid = strid;
|
||||
|
||||
return TT_OK;
|
||||
}
|
||||
101
cde/lib/tt/lib/mp/mp_auth.h
Normal file
101
cde/lib/tt/lib/mp/mp_auth.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $TOG: mp_auth.h /main/2 1999/09/10 15:01:41 mgreess $ */
|
||||
/*
|
||||
* @(#)mp_auth.h 1.36 95/01/25
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file contains the implementation of the _Tt_auth object which
|
||||
* implements the MIT-MAGIC-COOKIE authentication for the _TT_AUTH_ICEAUTH
|
||||
* authentication type. This class is simply a wrapper for calls to
|
||||
* code copied out of the X11 libICE library. Alternatively, one can
|
||||
* compile with the OPT_ICE define and call the ICE routines directly.
|
||||
*/
|
||||
#ifndef MP_AUTH_H
|
||||
#define MP_AUTH_H
|
||||
#include "tt_options.h"
|
||||
#include "mp/mp_auth_functions.h"
|
||||
#include "util/tt_object.h"
|
||||
#include "util/tt_list.h"
|
||||
#include "util/tt_string.h"
|
||||
|
||||
/*
|
||||
* As of the CDE release of ToolTalk, _TT_AUTH_XAUTH is no longer supported.
|
||||
* It has been removed along with all references in the TT code, but the
|
||||
* value of _TT_AUTH_DES was not changed to the now-missing value of 1.
|
||||
*/
|
||||
/*
|
||||
* As of 2.1.30, the libICE MIT-MAGIC-COOKIE authentication is added in
|
||||
* place of _TT_AUTH_XAUTH. The code was inlined from libICE in such a
|
||||
* way that it could be easily replaced by libICE itself.
|
||||
*/
|
||||
|
||||
#define _TT_ICEAUTH_AUTH_NAME "MIT-MAGIC-COOKIE-1"
|
||||
#define _TT_ICEAUTH_MAGIC_COOKIE_LEN 16
|
||||
#define _TT_ICEAUTH_PROTOCOL_NAME "TT"
|
||||
|
||||
#define _TT_ICEAUTH_DEFAULT_RETRIES 10 /* num of competitors we expect */
|
||||
#define _TT_ICEAUTH_DEFAULT_TIMEOUT 2 /* in seconds, be quick */
|
||||
#define _TT_ICEAUTH_DEFAULT_DEADTIME 600L /* 10 minutes in seconds */
|
||||
|
||||
|
||||
|
||||
enum _Tt_auth_level {
|
||||
_TT_AUTH_UNIX = 0, /* Unix "authentication" */
|
||||
_TT_AUTH_ICEAUTH= 1, /* ICE MIT-COOKIE authentication (default) */
|
||||
_TT_AUTH_DES = 2, /* Secure RPC (DES encryption) */
|
||||
_TT_AUTH_NONE = 3 /* No authentication */
|
||||
};
|
||||
|
||||
class _Tt_auth : public _Tt_object {
|
||||
public:
|
||||
_Tt_auth(_Tt_auth_level auth_level = _TT_AUTH_ICEAUTH);
|
||||
virtual ~_Tt_auth();
|
||||
|
||||
_Tt_auth_level auth_level() {
|
||||
return _auth_level;
|
||||
}
|
||||
const _Tt_string &auth_cookie() const {
|
||||
return _auth_cookie;
|
||||
}
|
||||
Tt_status generate_auth_cookie();
|
||||
Tt_status retrieve_auth_cookie();
|
||||
Tt_status set_auth_level(_Tt_auth_level auth_level);
|
||||
Tt_status set_sessionid(
|
||||
int rpc_program,
|
||||
_Tt_auth_level auth_level,
|
||||
_Tt_string hostaddr,
|
||||
int rpc_version);
|
||||
|
||||
protected:
|
||||
//
|
||||
// state variables
|
||||
//
|
||||
_Tt_auth_level _auth_level;
|
||||
_Tt_string _auth_cookie;
|
||||
_Tt_string _hostaddr;
|
||||
int _rpc_program;
|
||||
int _rpc_version;
|
||||
_Tt_string _sessionid;
|
||||
_Tt_string _ttauthfile;
|
||||
|
||||
private:
|
||||
//
|
||||
// variables associated with generating a .ttauthority file entry.
|
||||
//
|
||||
_tt_AuthFileEntryList *_entries_head;
|
||||
_tt_AuthFileEntryList *_entries_tail;
|
||||
|
||||
Tt_status read_auth_file(char*);
|
||||
Tt_status write_auth_file(char*);
|
||||
|
||||
Tt_status modify_auth_entry(_tt_AuthFileEntry*,
|
||||
_tt_AuthFileEntryList**);
|
||||
Tt_status read_auth_entries(FILE*,
|
||||
_tt_AuthFileEntryList**);
|
||||
};
|
||||
|
||||
#endif /* MP_AUTH_H */
|
||||
535
cde/lib/tt/lib/mp/mp_auth_functions.C
Normal file
535
cde/lib/tt/lib/mp/mp_auth_functions.C
Normal file
@@ -0,0 +1,535 @@
|
||||
/* $TOG: mp_auth_functions.C /main/3 1999/10/14 18:43:11 mgreess $ */
|
||||
/******************************************************************************
|
||||
|
||||
|
||||
Copyright 1993, 1998 The Open Group
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Author: Ralph Mor, X Consortium
|
||||
******************************************************************************/
|
||||
/*
|
||||
* This file was copied and altered from libICE/authutil.c
|
||||
* The 'Ice' prefix has been replaced by tt_ for functions
|
||||
* and by _tt_ for data types.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xos.h>
|
||||
#include "mp/mp_auth_functions.h"
|
||||
|
||||
#ifdef X_NOT_STDC_ENV
|
||||
extern int errno;
|
||||
extern long time ();
|
||||
extern char *getenv();
|
||||
#define Time_t long
|
||||
#else
|
||||
#include <time.h>
|
||||
#define Time_t time_t
|
||||
#endif
|
||||
#ifndef X_NOT_POSIX
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#ifndef WIN32
|
||||
extern unsigned sleep ();
|
||||
#else
|
||||
#define link rename
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int read_short(FILE *, unsigned short *);
|
||||
static int read_string(FILE *, char **);
|
||||
static int read_counted_string(FILE *, unsigned short *, char **);
|
||||
static int write_short(FILE *, unsigned short);
|
||||
static int write_string(FILE *, char *);
|
||||
static int write_counted_string(FILE *, unsigned short, char *);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The following routines are for manipulating the .TTauthority file
|
||||
*/
|
||||
|
||||
char *
|
||||
_tt_AuthFileName ()
|
||||
|
||||
{
|
||||
static char slashDotTTauthority[] = "/.TTauthority";
|
||||
char *name;
|
||||
static char *buf;
|
||||
static int bsize;
|
||||
int size;
|
||||
#ifdef WIN32
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 512
|
||||
#endif
|
||||
char dir[PATH_MAX];
|
||||
#endif
|
||||
|
||||
if (name = getenv ("TTAUTHORITY"))
|
||||
return (name);
|
||||
|
||||
name = getenv ("HOME");
|
||||
|
||||
if (!name)
|
||||
{
|
||||
#ifdef WIN32
|
||||
register char *ptr1;
|
||||
register char *ptr2;
|
||||
int len1 = 0, len2 = 0;
|
||||
|
||||
if ((ptr1 = getenv("HOMEDRIVE")) && (ptr2 = getenv("HOMEDIR"))) {
|
||||
len1 = strlen (ptr1);
|
||||
len2 = strlen (ptr2);
|
||||
} else if (ptr2 = getenv("USERNAME")) {
|
||||
len1 = strlen (ptr1 = "/users/");
|
||||
len2 = strlen (ptr2);
|
||||
}
|
||||
if ((len1 + len2 + 1) < PATH_MAX) {
|
||||
sprintf (dir, "%s%s", ptr1, (ptr2) ? ptr2 : "");
|
||||
name = dir;
|
||||
}
|
||||
if (!name)
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
size = strlen (name) + strlen (&slashDotTTauthority[1]) + 2;
|
||||
|
||||
if (size > bsize)
|
||||
{
|
||||
if (buf)
|
||||
free (buf);
|
||||
buf = (char*) malloc ((unsigned) size);
|
||||
if (!buf)
|
||||
return (NULL);
|
||||
bsize = size;
|
||||
}
|
||||
|
||||
strcpy (buf, name);
|
||||
strcat (buf, slashDotTTauthority + (name[1] == '\0' ? 1 : 0));
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
_tt_LockAuthFile(char *file_name, int retries, int timeout, long dead)
|
||||
{
|
||||
char creat_name[1025], link_name[1025];
|
||||
struct stat statb;
|
||||
Time_t now;
|
||||
int creat_fd = -1;
|
||||
|
||||
if ((int) strlen (file_name) > 1022)
|
||||
return (_tt_AuthLockError);
|
||||
|
||||
strcpy (creat_name, file_name);
|
||||
strcat (creat_name, "-c");
|
||||
strcpy (link_name, file_name);
|
||||
strcat (link_name, "-l");
|
||||
|
||||
if (stat (creat_name, &statb) != -1)
|
||||
{
|
||||
now = time ((Time_t *) 0);
|
||||
|
||||
/*
|
||||
* NFS may cause ctime to be before now, special
|
||||
* case a 0 deadtime to force lock removal
|
||||
*/
|
||||
|
||||
if (dead == 0 || now - statb.st_ctime > dead)
|
||||
{
|
||||
unlink (creat_name);
|
||||
unlink (link_name);
|
||||
}
|
||||
}
|
||||
|
||||
while (retries > 0)
|
||||
{
|
||||
if (creat_fd == -1)
|
||||
{
|
||||
creat_fd = creat (creat_name, 0666);
|
||||
|
||||
if (creat_fd == -1)
|
||||
{
|
||||
if (errno != EACCES)
|
||||
return (_tt_AuthLockError);
|
||||
}
|
||||
else
|
||||
close (creat_fd);
|
||||
}
|
||||
|
||||
if (creat_fd != -1)
|
||||
{
|
||||
if (link (creat_name, link_name) != -1)
|
||||
return (_tt_AuthLockSuccess);
|
||||
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
creat_fd = -1; /* force re-creat next time around */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (errno != EEXIST)
|
||||
return (_tt_AuthLockError);
|
||||
}
|
||||
|
||||
sleep ((unsigned) timeout);
|
||||
--retries;
|
||||
}
|
||||
|
||||
return (_tt_AuthLockTimeout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
_tt_UnlockAuthFile(char *file_name)
|
||||
{
|
||||
#ifndef WIN32
|
||||
char creat_name[1025];
|
||||
#endif
|
||||
char link_name[1025];
|
||||
|
||||
if ((int) strlen (file_name) > 1022)
|
||||
return;
|
||||
|
||||
#ifndef WIN32
|
||||
strcpy (creat_name, file_name);
|
||||
strcat (creat_name, "-c");
|
||||
#endif
|
||||
strcpy (link_name, file_name);
|
||||
strcat (link_name, "-l");
|
||||
|
||||
#ifndef WIN32
|
||||
unlink (creat_name);
|
||||
#endif
|
||||
unlink (link_name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
_tt_AuthFileEntry *
|
||||
_tt_ReadAuthFileEntry(FILE *auth_file)
|
||||
{
|
||||
_tt_AuthFileEntry local;
|
||||
_tt_AuthFileEntry *ret;
|
||||
|
||||
local.protocol_name = NULL;
|
||||
local.protocol_data = NULL;
|
||||
local.network_id = NULL;
|
||||
local.auth_name = NULL;
|
||||
local.auth_data = NULL;
|
||||
|
||||
if (!read_string (auth_file, &local.protocol_name))
|
||||
return (NULL);
|
||||
|
||||
if (!read_counted_string (auth_file,
|
||||
&local.protocol_data_length, &local.protocol_data))
|
||||
goto bad;
|
||||
|
||||
if (!read_string (auth_file, &local.network_id))
|
||||
goto bad;
|
||||
|
||||
if (!read_string (auth_file, &local.auth_name))
|
||||
goto bad;
|
||||
|
||||
if (!read_counted_string (auth_file,
|
||||
&local.auth_data_length, &local.auth_data))
|
||||
goto bad;
|
||||
|
||||
if (!(ret = (_tt_AuthFileEntry *) malloc (sizeof (_tt_AuthFileEntry))))
|
||||
goto bad;
|
||||
|
||||
*ret = local;
|
||||
|
||||
return (ret);
|
||||
|
||||
bad:
|
||||
|
||||
if (local.protocol_name) free (local.protocol_name);
|
||||
if (local.protocol_data) free (local.protocol_data);
|
||||
if (local.network_id) free (local.network_id);
|
||||
if (local.auth_name) free (local.auth_name);
|
||||
if (local.auth_data) free (local.auth_data);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
_tt_FreeAuthFileEntry(_tt_AuthFileEntry *auth)
|
||||
{
|
||||
if (auth)
|
||||
{
|
||||
if (auth->protocol_name) free (auth->protocol_name);
|
||||
if (auth->protocol_data) free (auth->protocol_data);
|
||||
if (auth->network_id) free (auth->network_id);
|
||||
if (auth->auth_name) free (auth->auth_name);
|
||||
if (auth->auth_data) free (auth->auth_data);
|
||||
free ((char *) auth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
_tt_WriteAuthFileEntry(FILE *auth_file, _tt_AuthFileEntry *auth)
|
||||
{
|
||||
if (!write_string (auth_file, auth->protocol_name))
|
||||
return (0);
|
||||
|
||||
if (!write_counted_string (auth_file,
|
||||
auth->protocol_data_length, auth->protocol_data))
|
||||
return (0);
|
||||
|
||||
if (!write_string (auth_file, auth->network_id))
|
||||
return (0);
|
||||
|
||||
if (!write_string (auth_file, auth->auth_name))
|
||||
return (0);
|
||||
|
||||
if (!write_counted_string (auth_file,
|
||||
auth->auth_data_length, auth->auth_data))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
_tt_AuthFileEntry *
|
||||
_tt_GetAuthFileEntry(char *protocol_name, char *network_id, char *auth_name)
|
||||
{
|
||||
FILE *auth_file;
|
||||
char *filename;
|
||||
_tt_AuthFileEntry *entry;
|
||||
|
||||
if (!(filename = _tt_AuthFileName ()))
|
||||
return (NULL);
|
||||
|
||||
if (access (filename, R_OK) != 0) /* checks REAL id */
|
||||
return (NULL);
|
||||
|
||||
if (!(auth_file = fopen (filename, "rb")))
|
||||
return (NULL);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!(entry = _tt_ReadAuthFileEntry (auth_file)))
|
||||
break;
|
||||
|
||||
if (strcmp (protocol_name, entry->protocol_name) == 0 &&
|
||||
strcmp (network_id, entry->network_id) == 0 &&
|
||||
strcmp (auth_name, entry->auth_name) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
_tt_FreeAuthFileEntry (entry);
|
||||
}
|
||||
|
||||
fclose (auth_file);
|
||||
|
||||
return (entry);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MIT-MAGIC-COOKIE-1 is a sample authentication method implemented by
|
||||
* the SI. It is not part of standard ICElib.
|
||||
*/
|
||||
|
||||
|
||||
char *
|
||||
_tt_GenerateMagicCookie(int len)
|
||||
{
|
||||
char *auth;
|
||||
long ldata[2];
|
||||
int seed;
|
||||
int value;
|
||||
int i;
|
||||
|
||||
if ((auth = (char *) malloc (len + 1)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
#ifdef ITIMER_REAL
|
||||
{
|
||||
struct timeval now;
|
||||
X_GETTIMEOFDAY (&now);
|
||||
ldata[0] = now.tv_sec;
|
||||
ldata[1] = now.tv_usec;
|
||||
seed = (int) ((ldata[0] << 11) ^ ldata[1]);
|
||||
}
|
||||
#else
|
||||
{
|
||||
long time ();
|
||||
|
||||
ldata[0] = time ((long *) 0);
|
||||
ldata[1] = getpid ();
|
||||
seed = (int) (ldata[0]) + (ldata[1] << 16);
|
||||
}
|
||||
#endif
|
||||
srand (seed);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
value = rand ();
|
||||
auth[i] = (
|
||||
( (value & 0xff000000) >> 24) ^
|
||||
( (value & 0xff0000) >> 16) ^
|
||||
( (value & 0xff00) >> 8) ^
|
||||
( (value & 0xff) )
|
||||
) & 0xff;
|
||||
}
|
||||
auth[len] = '\0';
|
||||
|
||||
return (auth);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* local routines
|
||||
*/
|
||||
|
||||
static int
|
||||
read_short(FILE *file, unsigned short *shortp)
|
||||
{
|
||||
unsigned char file_short[2];
|
||||
|
||||
if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
|
||||
return (0);
|
||||
|
||||
*shortp = file_short[0] * 256 + file_short[1];
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
read_string(FILE *file, char **stringp)
|
||||
{
|
||||
unsigned short len;
|
||||
char *data;
|
||||
|
||||
if (!read_short (file, &len))
|
||||
return (0);
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
data = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = (char*) malloc ((unsigned) len + 1);
|
||||
|
||||
if (!data)
|
||||
return (0);
|
||||
|
||||
if (fread (data, (int) sizeof (char), (int) len, file) != len)
|
||||
{
|
||||
free (data);
|
||||
return (0);
|
||||
}
|
||||
|
||||
data[len] = '\0';
|
||||
}
|
||||
|
||||
*stringp = data;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
read_counted_string(FILE *file, unsigned short *countp, char **stringp)
|
||||
{
|
||||
unsigned short len;
|
||||
char *data;
|
||||
|
||||
if (!read_short (file, &len))
|
||||
return (0);
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
data = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = (char*) malloc ((unsigned) len);
|
||||
|
||||
if (!data)
|
||||
return (0);
|
||||
|
||||
if (fread (data, (int) sizeof (char), (int) len, file) != len)
|
||||
{
|
||||
free (data);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
*stringp = data;
|
||||
*countp = len;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
write_short(FILE *file, unsigned short s)
|
||||
{
|
||||
unsigned char file_short[2];
|
||||
|
||||
file_short[0] = (s & (unsigned) 0xff00) >> 8;
|
||||
file_short[1] = s & 0xff;
|
||||
|
||||
if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
write_string(FILE *file, char *string)
|
||||
{
|
||||
unsigned short count = strlen (string);
|
||||
|
||||
if (!write_short (file, count))
|
||||
return (0);
|
||||
|
||||
if (fwrite (string, (int) sizeof (char), (int) count, file) != count)
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
write_counted_string(FILE *file, unsigned short count, char *string)
|
||||
{
|
||||
if (!write_short (file, count))
|
||||
return (0);
|
||||
|
||||
if (fwrite (string, (int) sizeof (char), (int) count, file) != count)
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
117
cde/lib/tt/lib/mp/mp_auth_functions.h
Normal file
117
cde/lib/tt/lib/mp/mp_auth_functions.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/* $TOG: mp_auth_functions.h /main/1 1999/08/30 10:55:06 mgreess $ */
|
||||
/******************************************************************************
|
||||
|
||||
|
||||
Copyright 1993, 1998 The Open Group
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Author: Ralph Mor, X Consortium
|
||||
******************************************************************************/
|
||||
/*
|
||||
* This file was copied and altered from libICE/ICEutil.h
|
||||
* The 'Ice' prefix has been replaced by tt_ for functions
|
||||
* and by _tt_ for data types.
|
||||
*/
|
||||
|
||||
#ifndef MP_AUTH_FUNCTIONS_H
|
||||
#define MP_AUTH_FUNCTIONS_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Data structure for entry in ICE authority file
|
||||
*/
|
||||
|
||||
typedef struct _tt_AuthFileEntry {
|
||||
char *protocol_name;
|
||||
unsigned short protocol_data_length;
|
||||
char *protocol_data;
|
||||
char *network_id;
|
||||
char *auth_name;
|
||||
unsigned short auth_data_length;
|
||||
char *auth_data;
|
||||
} _tt_AuthFileEntry;
|
||||
|
||||
typedef struct _tt_AuthFileEntryList {
|
||||
struct _tt_AuthFileEntryList *next;
|
||||
_tt_AuthFileEntry *entry;
|
||||
} _tt_AuthFileEntryList;
|
||||
|
||||
/*
|
||||
* Authentication data maintained in memory.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *protocol_name;
|
||||
char *network_id;
|
||||
char *auth_name;
|
||||
unsigned short auth_data_length;
|
||||
char *auth_data;
|
||||
} _tt_AuthDataEntry;
|
||||
|
||||
/*
|
||||
* Return values from tt_LockAuthFile
|
||||
*/
|
||||
|
||||
#define _tt_AuthLockSuccess 0 /* lock succeeded */
|
||||
#define _tt_AuthLockError 1 /* lock unexpectely failed, check errno */
|
||||
#define _tt_AuthLockTimeout 2 /* lock failed, timeouts expired */
|
||||
|
||||
|
||||
/*
|
||||
* Function Prototypes
|
||||
*/
|
||||
|
||||
extern char *_tt_AuthFileName (void);
|
||||
|
||||
extern int _tt_LockAuthFile (
|
||||
char * /* file_name */,
|
||||
int /* retries */,
|
||||
int /* timeout */,
|
||||
long /* dead */
|
||||
);
|
||||
|
||||
extern void _tt_UnlockAuthFile (
|
||||
char * /* file_name */
|
||||
);
|
||||
|
||||
extern _tt_AuthFileEntry *_tt_ReadAuthFileEntry (
|
||||
FILE * /* auth_file */
|
||||
);
|
||||
|
||||
extern void _tt_FreeAuthFileEntry (
|
||||
_tt_AuthFileEntry * /* auth */
|
||||
);
|
||||
|
||||
extern int _tt_WriteAuthFileEntry (
|
||||
FILE * /* auth_file */,
|
||||
_tt_AuthFileEntry * /* auth */
|
||||
);
|
||||
|
||||
extern _tt_AuthFileEntry *_tt_GetAuthFileEntry (
|
||||
char * /* protocol_name */,
|
||||
char * /* network_id */,
|
||||
char * /* auth_name */
|
||||
);
|
||||
|
||||
extern char *_tt_GenerateMagicCookie (
|
||||
int /* len */
|
||||
);
|
||||
|
||||
|
||||
#endif /* MP_AUTH_FUNCTIONS_H */
|
||||
23
cde/lib/tt/lib/mp/mp_c.h
Normal file
23
cde/lib/tt/lib/mp/mp_c.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c.h /main/3 1995/10/23 10:19:25 rswiston $ */
|
||||
/*
|
||||
* mp_c.h -- public interface classes to the client side of the Message Passer
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef _MP_C_H
|
||||
#define _MP_C_H
|
||||
|
||||
#include <mp/mp_c_global.h>
|
||||
#include <mp/mp_arg.h>
|
||||
#include <mp/mp_c_file.h>
|
||||
#include <mp/mp_c_message.h>
|
||||
#include <mp/mp_c_procid.h>
|
||||
#include <mp/mp_c_session.h>
|
||||
#include <mp/mp_c_mp.h>
|
||||
#include <mp/mp_pattern.h>
|
||||
|
||||
#endif /* _MP_C_H */
|
||||
208
cde/lib/tt/lib/mp/mp_c_file.C
Normal file
208
cde/lib/tt/lib/mp/mp_c_file.C
Normal file
@@ -0,0 +1,208 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_c_file.C /main/3 1995/10/23 10:19:32 rswiston $
|
||||
/*
|
||||
* Tool Talk Message Passer (MP) - mp_c_file.cc
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Implementation of the _Tt_file class representing a document.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "mp/mp_c_file.h"
|
||||
#include "mp/mp_c_mp.h"
|
||||
#include "mp/mp_c_global.h"
|
||||
#include "mp/mp_rpc_interface.h"
|
||||
#include "mp/mp_c_session.h"
|
||||
#include "mp/mp_c_procid.h"
|
||||
#include "mp/mp_c_message.h"
|
||||
#include "api/c/api_error.h"
|
||||
#include "util/tt_port.h"
|
||||
|
||||
//
|
||||
// Use parent class (_Tt_file) for construction and destruction.
|
||||
//
|
||||
_Tt_c_file::_Tt_c_file()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_c_file::_Tt_c_file(
|
||||
_Tt_string path
|
||||
) :
|
||||
_Tt_file( path )
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_c_file::~_Tt_c_file()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Joins the indicated file on behalf of the default procid. Joining a file
|
||||
// means that any file-scoped patterns for this procid are updated to
|
||||
// contain this file. It also means we have to indicated to procids in
|
||||
// other sessions that this procid is interested in messages addressed to
|
||||
// this file. This is done by storing the session for this procid in a
|
||||
// persistent property on this file. The details of that are in
|
||||
// _Tt_file::add_joined_file. Another responsibility of this method is to
|
||||
// process any queued messages that are destined for any ptype declared
|
||||
// by p. This client/server division in the way file-scope queued
|
||||
// messages are implemented reflects a goal of offloading any
|
||||
// computation from the server to its clients. This is specially true
|
||||
// of any computation that involves communicating with the database
|
||||
// servers.
|
||||
//
|
||||
// XXX: it's misleading to have a _Tt_procid_ptr input arg here when
|
||||
// in fact the default procid joins the file, not the specified
|
||||
// procid. Either figure out how to join the specified procid or
|
||||
// remove the parameter.
|
||||
//
|
||||
Tt_status
|
||||
_Tt_c_file::c_join(
|
||||
_Tt_procid_ptr &
|
||||
)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rs;
|
||||
_Tt_db_results dbStatus;
|
||||
_Tt_file_join_args args;
|
||||
_Tt_session_ptr d_session;
|
||||
_Tt_c_procid *sp;
|
||||
|
||||
sp = (_Tt_c_procid *)_tt_c_mp->default_procid().c_pointer();
|
||||
args.procid = _tt_c_mp->default_procid();
|
||||
args.path = getNetworkPath();
|
||||
d_session = sp->default_session();
|
||||
rs = d_session->call(TT_RPC_JOIN_FILE,
|
||||
(xdrproc_t)tt_xdr_file_join_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
if (status == TT_WRN_NOTFOUND) {
|
||||
// No file patterns updated on the server side.
|
||||
status = TT_OK;
|
||||
} else {
|
||||
sp->add_joined_file(getNetworkPath());
|
||||
// add our session to the list of sessions
|
||||
// interested in this file.
|
||||
if (status == TT_WRN_STALE_OBJID) {
|
||||
dbStatus = addSession(d_session->process_tree_id());
|
||||
status = _tt_get_api_error( dbStatus, _TT_API_FILE );
|
||||
if (status == TT_ERR_INTERNAL) {
|
||||
_tt_syslog( 0, LOG_WARNING,
|
||||
"_Tt_db_file::addSession(): %d",
|
||||
dbStatus );
|
||||
}
|
||||
}
|
||||
if (status != TT_OK) {
|
||||
return status;
|
||||
}
|
||||
// process any queued messages on this file
|
||||
// for any of the ptypes we've declared.
|
||||
process_message_queue();
|
||||
}
|
||||
|
||||
return((rs == TT_OK) ? status : rs);
|
||||
}
|
||||
|
||||
//
|
||||
// Removes the session for the given procid from the list of interested
|
||||
// sessions in this file. This method also invokes an rpc on the server
|
||||
// session to remove this file from the patterns registered by this
|
||||
// procid. The rpc call to the session will return a special status code
|
||||
// TT_WRN_STALE_OBJID if this method is to actually remove the session
|
||||
// from the file property of interested sessions. This is because the
|
||||
// server session keeps a counter of how many procids are interested in
|
||||
// each file.
|
||||
//
|
||||
Tt_status
|
||||
_Tt_c_file::c_quit(
|
||||
_Tt_procid_ptr &p
|
||||
)
|
||||
{
|
||||
_Tt_file_join_args args;
|
||||
Tt_status rs;
|
||||
Tt_status status;
|
||||
_Tt_session_ptr d_session;
|
||||
|
||||
if (p.is_null()) {
|
||||
return(TT_ERR_PROCID);
|
||||
}
|
||||
d_session = ((_Tt_c_procid *)p.c_pointer())->default_session();
|
||||
if (d_session.is_null()) {
|
||||
return(TT_ERR_SESSION);
|
||||
}
|
||||
args.procid = p;
|
||||
args.path = getNetworkPath();
|
||||
rs = d_session->call(TT_RPC_QUIT_FILE,
|
||||
(xdrproc_t)tt_xdr_file_join_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
if (status == TT_WRN_NOTFOUND) {
|
||||
status = TT_OK;
|
||||
} else if (status == TT_WRN_STALE_OBJID) {
|
||||
_Tt_db_results dbStatus;
|
||||
dbStatus = deleteSession( d_session->process_tree_id() );
|
||||
if (dbStatus == TT_DB_ERR_NO_SUCH_PROPERTY) {
|
||||
status = TT_OK;
|
||||
} else {
|
||||
status = _tt_get_api_error( dbStatus, _TT_API_FILE );
|
||||
}
|
||||
if (status == TT_ERR_INTERNAL) {
|
||||
_tt_syslog( 0, LOG_WARNING,
|
||||
"_Tt_db_file::deleteSession(): %d",
|
||||
dbStatus );
|
||||
status = TT_ERR_INTERNAL;
|
||||
}
|
||||
}
|
||||
p->del_joined_file(getNetworkPath());
|
||||
return((status == TT_OK) ? rs : status);
|
||||
}
|
||||
|
||||
//
|
||||
// Proces any queued messages in this file. If so, then for each
|
||||
// message destined for a ptype declared by the current default
|
||||
// procid, retrieve the message and dispatch it to our current
|
||||
// session. Note that messages are stored only once even if they're
|
||||
// destined for multiple ptypes so we only de-queue the message if
|
||||
// there are no destination ptypes once we're done dispatching the
|
||||
// message.
|
||||
//
|
||||
// The exact layout of how messages are stored is described in
|
||||
// _Tt_file::q_message below.
|
||||
//
|
||||
Tt_status
|
||||
_Tt_c_file::process_message_queue(
|
||||
int dispatch_msgs
|
||||
)
|
||||
{
|
||||
_Tt_message_list_ptr msgs;
|
||||
Tt_status status;
|
||||
_Tt_db_results dbStatus;
|
||||
|
||||
dbStatus = dequeueMessages( _tt_c_mp->default_procid()->ptypes(),
|
||||
msgs );
|
||||
status = _tt_get_api_error( dbStatus, _TT_API_FILE );
|
||||
if (status != TT_OK) {
|
||||
if (status == TT_ERR_INTERNAL) {
|
||||
_tt_syslog( 0, LOG_WARNING,
|
||||
"_Tt_db_file::dequeueMessages(): %d",
|
||||
dbStatus );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
if (! dispatch_msgs) {
|
||||
return TT_OK;
|
||||
}
|
||||
_Tt_message_list_cursor msg( msgs );
|
||||
while (msg.next()) {
|
||||
msg->set_state( TT_QUEUED );
|
||||
(void)((_Tt_c_message *)(*msg).c_pointer())->dispatch( 1 );
|
||||
}
|
||||
return TT_OK;
|
||||
}
|
||||
38
cde/lib/tt/lib/mp/mp_c_file.h
Normal file
38
cde/lib/tt/lib/mp/mp_c_file.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_file.h /main/3 1995/10/23 10:19:40 rswiston $ */
|
||||
/*
|
||||
* Tool Talk Message Passer (MP) - mp_c_file.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Declaration of the _Tt_c_file class.
|
||||
*/
|
||||
|
||||
#ifndef _MP_C_FILE_H
|
||||
#define _MP_C_FILE_H
|
||||
#include <mp/mp_file.h>
|
||||
#include <mp/mp_c_file_utils.h>
|
||||
|
||||
class _Tt_c_file : public _Tt_file {
|
||||
public:
|
||||
_Tt_c_file();
|
||||
_Tt_c_file(
|
||||
_Tt_string path
|
||||
);
|
||||
virtual ~_Tt_c_file();
|
||||
|
||||
Tt_status c_join(
|
||||
_Tt_procid_ptr &p
|
||||
);
|
||||
Tt_status c_quit(
|
||||
_Tt_procid_ptr &p
|
||||
);
|
||||
Tt_status process_message_queue(
|
||||
int dispatch = 1
|
||||
);
|
||||
};
|
||||
|
||||
#endif /* _MP_C_FILE_H */
|
||||
14
cde/lib/tt/lib/mp/mp_c_file_utils.C
Normal file
14
cde/lib/tt/lib/mp/mp_c_file_utils.C
Normal file
@@ -0,0 +1,14 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_c_file_utils.C /main/3 1995/10/23 10:19:48 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_c_file_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <mp/mp_c_file.h>
|
||||
|
||||
implement_ptr_to(_Tt_c_file)
|
||||
20
cde/lib/tt/lib/mp/mp_c_file_utils.h
Normal file
20
cde/lib/tt/lib/mp/mp_c_file_utils.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_file_utils.h /main/3 1995/10/23 10:19:55 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_c_file_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Utilities declarations for _Tt_c_file
|
||||
*/
|
||||
#ifndef MP_C_FILE_UTILS_H
|
||||
#define MP_C_FILE_UTILS_H
|
||||
#include <mp/mp_file_utils.h>
|
||||
|
||||
class _Tt_c_file;
|
||||
declare_derived_ptr_to(_Tt_c_file,_Tt_file)
|
||||
#endif /* MP_C_FILE_UTILS_H */
|
||||
24
cde/lib/tt/lib/mp/mp_c_global.h
Normal file
24
cde/lib/tt/lib/mp/mp_c_global.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_global.h /main/3 1995/10/23 10:20:03 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_c_global.h
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
*
|
||||
* _tt_c_mp and _tt_mp always point to the same object, but client-only
|
||||
* functions can use _tt_c_mp in order to access client-only functions.
|
||||
*/
|
||||
#if !defined(_MP_C_GLOBAL_H)
|
||||
#define _MP_C_GLOBAL_H
|
||||
|
||||
class _Tt_c_mp;
|
||||
extern _Tt_c_mp *_tt_c_mp;
|
||||
|
||||
#include "mp/mp_global.h"
|
||||
|
||||
#endif
|
||||
615
cde/lib/tt/lib/mp/mp_c_message.C
Normal file
615
cde/lib/tt/lib/mp/mp_c_message.C
Normal file
@@ -0,0 +1,615 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_c_message.C /main/5 1999/10/14 18:40:53 mgreess $
|
||||
/*
|
||||
* @(#)mp_c_message.C 1.46 95/04/27
|
||||
*
|
||||
* @(#)mp_c_message.C 1.36 93/09/07
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_c_message.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "api/c/api_spec_map_ref.h"
|
||||
#include "api/c/api_error.h"
|
||||
#include "mp/mp_c_global.h"
|
||||
#include "mp/mp_arg.h"
|
||||
#include "mp/mp_c_file.h"
|
||||
#include "mp/mp_c_message.h"
|
||||
#include "mp/mp_c_mp.h"
|
||||
#include "mp/mp_c_procid.h"
|
||||
#include "mp/mp_rpc_interface.h"
|
||||
#include "mp/mp_c_session.h"
|
||||
#include "util/tt_enumname.h"
|
||||
#include "mp/mp_trace.h"
|
||||
#include "util/tt_gettext.h"
|
||||
#include "util/tt_port.h"
|
||||
|
||||
|
||||
//
|
||||
// The methods in this file implement the client-only functionality
|
||||
// required for messages.
|
||||
//
|
||||
|
||||
|
||||
|
||||
_Tt_c_message::
|
||||
_Tt_c_message()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_c_message::
|
||||
~_Tt_c_message()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Will return 1 if this message has the update xdr flag turned on
|
||||
// indicating it is a reply to an old message rather than an entirely new
|
||||
// message.
|
||||
//
|
||||
int _Tt_c_message::
|
||||
is_a_diff()
|
||||
{
|
||||
return(_flags&(1<<_TT_MSG_UPDATE_XDR_MODE));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Dispatches a message. If observers_only is 1 then the only observer
|
||||
// patterns will be matched for this message. One of the important
|
||||
// responsibilities of this method is to fill in any fields in the
|
||||
// message that require database lookups. For example, if it is an
|
||||
// object-oriented message then this method will fill in the otype field
|
||||
// in the message by asking the right database for the type field of the
|
||||
// given object field. This is done to free ttsession from ever having to
|
||||
// do any database lookups. For file-scope messages, this method will
|
||||
// also append the list of remote sessions that have procids joined to
|
||||
// the file mentioned in this message. This is used by ttsession when
|
||||
// routing the message.
|
||||
//
|
||||
// A somewhat tricky case of freeing ttsession from invoking database
|
||||
// operations arises in message-queueing. When a file-scope message
|
||||
// requires queueing the return argument from the rpc call to dispatch
|
||||
// the message will indicate what ptypes the message should be queued
|
||||
// for. It is then this method which then goes ahead and queues the
|
||||
// message on the file.
|
||||
Tt_status _Tt_c_message::
|
||||
dispatch(int observers_only)
|
||||
{
|
||||
Tt_status status;
|
||||
_Tt_db_results dbStatus;
|
||||
Tt_status resolve_status = TT_OK;
|
||||
Tt_status rpc_status;
|
||||
_Tt_message_ptr mptr;
|
||||
_Tt_file_ptr fptr;
|
||||
// The following two pointers are not smart ptrs, to save
|
||||
// two trips into constructor and destructor per message send.
|
||||
// This doesn\'t mess up ref counting since the default procid
|
||||
// and session never change while in this method.
|
||||
_Tt_c_session *d_session;
|
||||
_Tt_c_procid *d_procid;
|
||||
_Tt_dispatch_reply_args args;
|
||||
|
||||
if (_message_class == TT_CLASS_UNDEFINED ||
|
||||
_message_class == TT_CLASS_LAST) {
|
||||
return(TT_ERR_CLASS);
|
||||
}
|
||||
if (_state != TT_CREATED && _state != TT_QUEUED) {
|
||||
// we shouldn't be re-sending a message whose state
|
||||
// isn't created or queued
|
||||
return(TT_ERR_STATE);
|
||||
}
|
||||
|
||||
d_procid = _tt_c_mp->default_c_procid().c_pointer();
|
||||
d_session = d_procid->default_session().c_pointer();
|
||||
|
||||
// take any necessary actions according to the message
|
||||
// paradigm (as well as check for legitimate paradigm
|
||||
// fields).
|
||||
switch (_paradigm) {
|
||||
case TT_HANDLER:
|
||||
if (handler().is_null()) {
|
||||
// Point-to-point messages must have a handler.
|
||||
return TT_ERR_PROCID;
|
||||
}
|
||||
// fall through to check scope
|
||||
case TT_PROCEDURE:
|
||||
if (_scope == TT_SCOPE_NONE) {
|
||||
return(TT_ERR_SCOPE);
|
||||
}
|
||||
break;
|
||||
case TT_OBJECT:
|
||||
if (_object.is_null()) {
|
||||
return TT_ERR_OBJID;
|
||||
}
|
||||
resolve_status = resolve();
|
||||
switch (resolve_status) {
|
||||
case TT_OK:
|
||||
case TT_WRN_STALE_OBJID:
|
||||
break;
|
||||
default:
|
||||
return(resolve_status);
|
||||
}
|
||||
break;
|
||||
case TT_OTYPE:
|
||||
if (_otype.is_null()) {
|
||||
return TT_ERR_OTYPE;
|
||||
}
|
||||
break;
|
||||
case TT_ADDRESS_LAST:
|
||||
default:
|
||||
return(TT_ERR_ADDRESS);
|
||||
}
|
||||
if ((_message_class == TT_OFFER) && (_paradigm != TT_PROCEDURE)) {
|
||||
return TT_ERR_ADDRESS;
|
||||
}
|
||||
//
|
||||
// Since we know the server's RPC version, we only try the
|
||||
// call if we know it will work, else we generate our own
|
||||
// TT_ERR_UNIMP. Prior to 1.2, we let RPC_PROCUNAVAIL become
|
||||
// TT_ERR_UNIMP. Now we use classic RPC versioning.
|
||||
//
|
||||
if ( (message_class() == TT_OFFER)
|
||||
&& (d_session->rpc_version() < TT_OFFER_RPC_VERSION))
|
||||
{
|
||||
return TT_ERR_UNIMP;
|
||||
}
|
||||
|
||||
if (_file.len() &&
|
||||
(_scope == TT_FILE || _scope == TT_BOTH ||
|
||||
_paradigm==TT_OTYPE || _paradigm == TT_OBJECT)) {
|
||||
// If the message is file-scoped then we append the
|
||||
// list of remote sessions to send the message to.
|
||||
|
||||
// XXX: For object-oriented msgs we don't know the
|
||||
// scope yet so we append the sessions anyway if the
|
||||
// file attribute is filled in. Probably need to
|
||||
// refine the protocol so that we first ask if the
|
||||
// message is file-scoped (pure dispatch) and then we
|
||||
// deliver accordingly. This is mostly just
|
||||
// performance-tuning.
|
||||
if (_tt_mp->find_file(_file, fptr, 1) == TT_OK) {
|
||||
_rsessions = fptr->getSessions();
|
||||
dbStatus = fptr->getDBResults();
|
||||
status = _tt_get_api_error( dbStatus, _TT_API_FILE );
|
||||
if (status == TT_ERR_INTERNAL) {
|
||||
_tt_syslog( 0, LOG_WARNING,
|
||||
"_Tt_db_file::getSessions(): %d",
|
||||
dbStatus );
|
||||
}
|
||||
if (status != TT_OK) {
|
||||
_rsessions = (_Tt_string_list *)0;
|
||||
return status;
|
||||
}
|
||||
// we set the msg guard bit for the _rsessions
|
||||
// field to 1 if it is non-empty.
|
||||
SET_GUARD(_full_msg_guards,
|
||||
(!_rsessions.is_null()),
|
||||
_TT_MSK_RSESSIONS);
|
||||
} else {
|
||||
return(TT_ERR_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
if (! _rsessions.is_null() && _rsessions->count()) {
|
||||
// now we dispatch file scope notifications to remote
|
||||
// sessions, this is done here to minimize the amount
|
||||
// of inter-server communication done.
|
||||
// If the message is handler-addressed, don\'t bother
|
||||
// doing this as pattern matching doesn\'t work on point-
|
||||
// to-point messages anyway, and sending it to the foreign
|
||||
// ttsession just seems to confuse it.
|
||||
if (_paradigm!=TT_HANDLER &&
|
||||
(_scope == TT_FILE || _scope == TT_BOTH)) {
|
||||
_tt_mp->check_if_sessions_alive();
|
||||
_flags |= (1<<_TT_MSG_OBSERVERS_ONLY);
|
||||
(void)dispatch_file_scope_notification(fptr);
|
||||
}
|
||||
}
|
||||
|
||||
// send the message to the default session
|
||||
if (!observers_only) {
|
||||
_flags &= ~(1<<_TT_MSG_OBSERVERS_ONLY);
|
||||
}
|
||||
mptr = this;
|
||||
args.status = TT_OK;
|
||||
args.qmsg_info = (_Tt_qmsg_info *)0;
|
||||
|
||||
switch (d_session->rpc_version()) {
|
||||
case 1:
|
||||
// version 1 (tooltalk version 1.0) dispatch routine
|
||||
// expects to return arguments
|
||||
rpc_status = d_session->call(_rpc_dispatch(),
|
||||
(xdrproc_t)tt_xdr_message,
|
||||
(char *)&mptr,
|
||||
(xdrproc_t)tt_xdr_dispatch_reply_args,
|
||||
(char *)&args);
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
// Only send _session field if scope is TT_FILE or TT_BOTH
|
||||
SET_GUARD(_full_msg_guards,
|
||||
(_scope==TT_FILE || _scope==TT_BOTH),
|
||||
_TT_MSK_SESSION);
|
||||
|
||||
// version 2 (tooltalk version 1.0.1) uses a one-way
|
||||
// rpc if the scope of the message doesn't imply
|
||||
// file-scope or if the message is already in queued
|
||||
// state.
|
||||
rpc_status = d_session->call(((_scope == TT_SESSION ||
|
||||
_scope == TT_FILE_IN_SESSION ||
|
||||
_state == TT_QUEUED) ?
|
||||
_rpc_dispatch_2() :
|
||||
_rpc_dispatch()),
|
||||
(xdrproc_t)tt_xdr_message,
|
||||
(char *)&mptr,
|
||||
(xdrproc_t)tt_xdr_dispatch_reply_args,
|
||||
(char *)&args);
|
||||
break;
|
||||
}
|
||||
//
|
||||
// _Tt_s_message::dispatch() has set the state to TT_SENT
|
||||
//
|
||||
Tt_state old_state = state();
|
||||
set_state( TT_SENT );
|
||||
switch (_message_class) {
|
||||
case TT_REQUEST:
|
||||
case TT_OFFER:
|
||||
set_awaiting_reply();
|
||||
}
|
||||
_Tt_msg_trace trace( *this, old_state );
|
||||
if (args.status == TT_ERR_FILE) {
|
||||
//
|
||||
// TT_ERR_FILE is used to indicate that the session
|
||||
// doesn't contain any processes joined to the file
|
||||
// contained in the message. But in this case, we
|
||||
// do not want to try to delete the default session
|
||||
// from the interest list, because we do not even know
|
||||
// if it is *on* the interest list.
|
||||
//
|
||||
args.status = TT_OK;
|
||||
}
|
||||
|
||||
// queue the message if necessary. XXX what to do if queueing fails?
|
||||
if (!(args.qmsg_info).is_null()) {
|
||||
if (_tt_mp->find_file(_file, fptr, 1) == TT_OK) {
|
||||
dbStatus = fptr->queueMessage(args.qmsg_info->ptypes,
|
||||
mptr);
|
||||
if (dbStatus != TT_DB_OK) {
|
||||
_tt_syslog( 0, LOG_WARNING,
|
||||
catgets( _ttcatd, 1, 18,
|
||||
"could not queue a message"
|
||||
" on file \"%s\" because "
|
||||
"of internal error %d" ),
|
||||
(char *)fptr->getLocalPath(),
|
||||
dbStatus );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rpc_status != TT_OK) {
|
||||
return rpc_status;
|
||||
}
|
||||
|
||||
if (args.status != TT_OK) {
|
||||
return args.status;
|
||||
}
|
||||
|
||||
return resolve_status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sends a message to the server for dispatching if this process exits
|
||||
// without calling tt_close.
|
||||
Tt_status _Tt_c_message::
|
||||
dispatch_on_exit()
|
||||
{
|
||||
Tt_status rpc_status;
|
||||
_Tt_message_ptr mptr;
|
||||
_Tt_c_session_ptr d_session;
|
||||
_Tt_c_procid_ptr d_procid;
|
||||
_Tt_dispatch_reply_args args;
|
||||
|
||||
d_procid = _tt_c_mp->default_c_procid();
|
||||
d_session = d_procid->default_session();
|
||||
|
||||
// take any necessary actions according to the message
|
||||
// paradigm (as well as check for legitimate paradigm
|
||||
// fields).
|
||||
switch (_paradigm) {
|
||||
case TT_PROCEDURE:
|
||||
case TT_HANDLER:
|
||||
if (_scope != TT_SESSION) {
|
||||
return(TT_ERR_SCOPE);
|
||||
}
|
||||
break;
|
||||
case TT_OBJECT:
|
||||
case TT_OTYPE:
|
||||
case TT_ADDRESS_LAST:
|
||||
default:
|
||||
return(TT_ERR_ADDRESS);
|
||||
}
|
||||
|
||||
mptr = this;
|
||||
args.status = TT_OK;
|
||||
args.qmsg_info = (_Tt_qmsg_info *)0;
|
||||
|
||||
|
||||
rpc_status = d_session->call(TT_RPC_DISPATCH_ON_EXIT,
|
||||
(xdrproc_t)tt_xdr_message,
|
||||
(char *)&mptr,
|
||||
(xdrproc_t)tt_xdr_dispatch_reply_args,
|
||||
(char *)&args);
|
||||
|
||||
if (rpc_status != TT_OK) {
|
||||
return rpc_status;
|
||||
} else if (args.status != TT_OK) {
|
||||
return args.status;
|
||||
}
|
||||
//
|
||||
// _Tt_s_message::dispatch() will set the state to TT_SENT
|
||||
// if we die. This is our only chance to trace it.
|
||||
//
|
||||
Tt_state old_state = state();
|
||||
set_state( TT_SENT );
|
||||
// Do not set_awaiting_reply().
|
||||
_Tt_msg_trace trace( *this, old_state );
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Set up special flags to optimize xdr'ing the message when it the
|
||||
// current client replies to it. See _Tt_message::xdr for a
|
||||
// description of the message xdr'ing scheme.
|
||||
//
|
||||
void _Tt_c_message::
|
||||
set_return_handler_flags()
|
||||
{
|
||||
const int req_fields = _TT_MSK_ID |
|
||||
_TT_MSK_MESSAGE_CLASS |
|
||||
_TT_MSK_SENDER |
|
||||
_TT_MSK_STATUS |
|
||||
_TT_MSK_FLAGS;
|
||||
|
||||
|
||||
// turning on this flag means that when xdr'ed the _out_args
|
||||
// arglist (which holds only TT_OUT/TT_INOUT args) is sent
|
||||
// rather than the normal _args arglist. (see _Tt_message::xdr)
|
||||
_flags |= (1<<_TT_MSG_UPDATE_XDR_MODE);
|
||||
|
||||
// turn on the required fields
|
||||
_ptr_guards = req_fields;
|
||||
|
||||
if (is_start_message()) {
|
||||
// if this message was a start message then we need to
|
||||
// send the handler_ptype field because the
|
||||
// _Tt_s_procid::update_message method needs to make
|
||||
// use of the field before it has matched up this
|
||||
// message with its server-side copy.
|
||||
SET_PTR_GUARD(_full_msg_guards&_TT_MSK_HANDLER_PTYPE,
|
||||
_TT_MSK_HANDLER_PTYPE);
|
||||
}
|
||||
|
||||
// set up _out_arg list by adding any arguments that are
|
||||
// TT_OUT or TT_INOUT.
|
||||
SET_GUARD(_full_msg_guards, 0, _TT_MSK_ARGS);
|
||||
if (_out_args.is_null() && !_args.is_null() && _args->count()) {
|
||||
_Tt_arg_list_cursor argc(_args);
|
||||
|
||||
_out_args = new _Tt_arg_list();
|
||||
while (argc.next()) {
|
||||
add_out_arg(*argc);
|
||||
}
|
||||
}
|
||||
|
||||
// An optimization assumes that we normally sent SESSION
|
||||
// scoped messages, so we don't update the guards for
|
||||
// the message scope. If this message isn't SESSION
|
||||
// scoped, we set the guard anyhow.
|
||||
if (_scope != TT_SESSION) {
|
||||
SET_PTR_GUARD(_full_msg_guards&_TT_MSK_SCOPE, _TT_MSK_SCOPE);
|
||||
}
|
||||
|
||||
SET_PTR_GUARD(_full_msg_guards&_TT_MSK_HANDLER, _TT_MSK_HANDLER);
|
||||
SET_PTR_GUARD(_full_msg_guards&_TT_MSK_STATUS_STRING,
|
||||
_TT_MSK_STATUS_STRING);
|
||||
SET_PTR_GUARD(_full_msg_guards&_TT_MSK_FILE, _TT_MSK_FILE);
|
||||
SET_PTR_GUARD(_full_msg_guards&_TT_MSK_OBJECT, _TT_MSK_OBJECT);
|
||||
SET_PTR_GUARD(_full_msg_guards&_TT_MSK_ARGS, _TT_MSK_ARGS);
|
||||
SET_PTR_GUARD(_full_msg_guards&_TT_MSK_CONTEXTS, _TT_MSK_CONTEXTS);
|
||||
SET_PTR_GUARD(_full_msg_guards&_TT_MSK_OFFEREES, _TT_MSK_OFFEREES);
|
||||
SET_PTR_GUARD(_full_msg_guards&_TT_MSK_OPNUM, _TT_MSK_OPNUM);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Looks up the otype of the object field of the message. If the lookup
|
||||
// fails then an error code is returned. If the otype of the message is
|
||||
// already filled in then the resolve succeeds (issue: should it check to
|
||||
// make sure the otype is valid for this object id?)
|
||||
//
|
||||
Tt_status _Tt_c_message::
|
||||
resolve()
|
||||
{
|
||||
if (_otype.len() == 0) {
|
||||
_Tt_api_spec_map_ref spec_map;
|
||||
_Tt_objid_spec_ptr spec;
|
||||
_Tt_string fresh_objid;
|
||||
Tt_status val2return = TT_OK;
|
||||
|
||||
// look up oid in object database;
|
||||
if (_object.len() == 0) {
|
||||
return(TT_ERR_OBJID);
|
||||
}
|
||||
|
||||
spec = spec_map.getSpec(_object);
|
||||
if (spec.is_null()) {
|
||||
return(TT_ERR_OBJID);
|
||||
}
|
||||
|
||||
switch (spec->getDBResults()) {
|
||||
case TT_DB_OK:
|
||||
val2return = TT_OK;
|
||||
break;
|
||||
case TT_DB_WRN_FORWARD_POINTER:
|
||||
fresh_objid = spec->getObjectID();
|
||||
set_object(fresh_objid);
|
||||
val2return = TT_WRN_STALE_OBJID;
|
||||
break;
|
||||
default:
|
||||
return(TT_ERR_OBJID);
|
||||
}
|
||||
// fill in otype and file field for oid;
|
||||
_otype = spec->getType();
|
||||
if (spec->getDBResults() != TT_DB_OK) {
|
||||
return(TT_ERR_OBJID);
|
||||
}
|
||||
SET_GUARD(_full_msg_guards, _otype.len(), _TT_MSK_OTYPE);
|
||||
|
||||
// fill in file field in message
|
||||
// --> what if get_path fails?
|
||||
_file = spec->getFile();
|
||||
if (spec->getDBResults() != TT_DB_OK) {
|
||||
_file = (char *)0;
|
||||
}
|
||||
SET_GUARD(_full_msg_guards, _file.len(), _TT_MSK_FILE);
|
||||
|
||||
return(val2return);
|
||||
}
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// This function dispatches in observer-only mode this message to all the
|
||||
// remote file-scope sessions interested in the file in this message. The
|
||||
// reason this is done here is to minimize inter-ttsession communication.
|
||||
// A side-benefit is that if message sending to a remote session fails
|
||||
// here, the remote session is removed from the _rsessions list and
|
||||
// ttsession won't try to contact the failed remote session. This method
|
||||
// also handles removing stale sessions from the file object (where a
|
||||
// stale session is one that is still listed in the file object's session
|
||||
// list because the client that was joined to the file in that session
|
||||
// didn't exit cleanly).
|
||||
//
|
||||
// XXX: what is the status that should be returned from this function?
|
||||
// Ideally one would want to know if every remote session got the
|
||||
// message or all of them failed? What about partial failures?
|
||||
Tt_status _Tt_c_message::
|
||||
dispatch_file_scope_notification(_Tt_file_ptr &fp)
|
||||
{
|
||||
_Tt_string sid;
|
||||
_Tt_string_list_cursor rc(_rsessions);
|
||||
_Tt_session_ptr rs;
|
||||
_Tt_message_ptr mptr = this;
|
||||
_Tt_dispatch_reply_args args;
|
||||
_Tt_db_results dbStatus;
|
||||
|
||||
while (rc.next()) {
|
||||
sid = *rc;
|
||||
if (_session->has_id(sid)) {
|
||||
rc.remove();
|
||||
continue;
|
||||
}
|
||||
if (TT_OK != _tt_c_mp->find_session(sid, rs, 1)) {
|
||||
//
|
||||
// stale session id on the file
|
||||
//
|
||||
dbStatus = fp->deleteSession(sid);
|
||||
rc.remove();
|
||||
if ( (dbStatus != TT_DB_OK)
|
||||
&& (dbStatus != TT_DB_ERR_NO_SUCH_PROPERTY))
|
||||
{
|
||||
_tt_syslog( 0, LOG_WARNING,
|
||||
catgets( _ttcatd, 1, 19,
|
||||
"could not delete stale "
|
||||
"session <%s> from "
|
||||
"interest list of file "
|
||||
"\"%s\" because of "
|
||||
"internal error %d" ),
|
||||
(char *)sid,
|
||||
(char *)fp->getLocalPath(),
|
||||
dbStatus );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// XXX: optimization: maybe we should have two
|
||||
// DISPATCH rpc calls, one that replies with just a
|
||||
// status and the other that replies with a
|
||||
// _Tt_dispatch_reply_args (which is only needed once
|
||||
// to know if the message needs to be queued).
|
||||
if (rs->call(_rpc_dispatch(),
|
||||
(xdrproc_t)tt_xdr_message, (char *)&mptr,
|
||||
(xdrproc_t)tt_xdr_dispatch_reply_args,
|
||||
(char *)&args)
|
||||
!= TT_OK)
|
||||
{
|
||||
// remove this session from message list to
|
||||
// minimize the chances of the server doing
|
||||
// bad rpc calls when looking for handlers.
|
||||
continue;
|
||||
}
|
||||
if (args.status == TT_ERR_FILE) {
|
||||
// indication from remote session that it
|
||||
// shouldn't be listed in this file's scope
|
||||
dbStatus = fp->deleteSession(sid);
|
||||
rc.remove();
|
||||
//
|
||||
// If the client that registered the file-scoped
|
||||
// pattern quits the file after the sender
|
||||
// does a getSessions call, then the session may
|
||||
// show up as stale, but will not be in the
|
||||
// database any more. This is why
|
||||
// TT_DB_ERR_NO_SUCH_PROPERPTY is an OK
|
||||
// return code.
|
||||
//
|
||||
if ( (dbStatus != TT_DB_OK)
|
||||
&& (dbStatus != TT_DB_ERR_NO_SUCH_PROPERTY))
|
||||
{
|
||||
_tt_syslog( 0, LOG_WARNING,
|
||||
catgets( _ttcatd, 1, 20,
|
||||
"could not delete "
|
||||
"uninterested session "
|
||||
"<%s> from interest list "
|
||||
"of file \"%s\" because "
|
||||
"of internal error %d" ),
|
||||
(char *)sid,
|
||||
(char *)fp->getLocalPath(),
|
||||
dbStatus );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
_Tt_rpc_procedure_number _Tt_c_message::
|
||||
_rpc_dispatch() const
|
||||
{
|
||||
if (_contexts.is_null()) {
|
||||
return TT_RPC_DISPATCH;
|
||||
}
|
||||
if (_contexts->count() <= 0) {
|
||||
return TT_RPC_DISPATCH;
|
||||
}
|
||||
return TT_RPC_DISPATCH_WITH_CONTEXT;
|
||||
}
|
||||
|
||||
_Tt_rpc_procedure_number _Tt_c_message::
|
||||
_rpc_dispatch_2() const
|
||||
{
|
||||
if (_contexts.is_null()) {
|
||||
return TT_RPC_DISPATCH_2;
|
||||
}
|
||||
if (_contexts->count() <= 0) {
|
||||
return TT_RPC_DISPATCH_2;
|
||||
}
|
||||
return TT_RPC_DISPATCH_2_WITH_CONTEXT;
|
||||
}
|
||||
37
cde/lib/tt/lib/mp/mp_c_message.h
Normal file
37
cde/lib/tt/lib/mp/mp_c_message.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_message.h /main/3 1995/10/23 10:20:18 rswiston $ */
|
||||
/*
|
||||
* mp_c_message.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file implements the client side of the _Tt_message object.
|
||||
*/
|
||||
#ifndef _MP_C_MESSAGE_H
|
||||
#define _MP_C_MESSAGE_H
|
||||
#include <mp/mp_message.h>
|
||||
#include <mp/mp_rpc_interface.h>
|
||||
#include <mp/mp_c_message_utils.h>
|
||||
|
||||
class _Tt_c_message : public _Tt_message {
|
||||
public:
|
||||
_Tt_c_message();
|
||||
~_Tt_c_message();
|
||||
void set_return_handler_flags();
|
||||
Tt_status dispatch(int observers_only = 0);
|
||||
Tt_status dispatch_on_exit();
|
||||
int is_a_diff();
|
||||
private:
|
||||
Tt_status dispatch_file_scope_notification(_Tt_file_ptr &f);
|
||||
Tt_status resolve();
|
||||
_Tt_rpc_procedure_number
|
||||
_rpc_dispatch() const;
|
||||
_Tt_rpc_procedure_number
|
||||
_rpc_dispatch_2() const;
|
||||
// See _Tt_c_procid::next_message() before adding data members!
|
||||
};
|
||||
|
||||
#endif /* _MP_C_MESSAGE_H */
|
||||
14
cde/lib/tt/lib/mp/mp_c_message_utils.C
Normal file
14
cde/lib/tt/lib/mp/mp_c_message_utils.C
Normal file
@@ -0,0 +1,14 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_c_message_utils.C /main/3 1995/10/23 10:20:25 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_c_message_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <mp/mp_c_message.h>
|
||||
|
||||
implement_ptr_to(_Tt_c_message)
|
||||
20
cde/lib/tt/lib/mp/mp_c_message_utils.h
Normal file
20
cde/lib/tt/lib/mp/mp_c_message_utils.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_message_utils.h /main/3 1995/10/23 10:20:32 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_c_message_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Utilities declarations for _Tt_s_message
|
||||
*/
|
||||
#ifndef MP_C_MESSAGE_UTILS_H
|
||||
#define MP_C_MESSAGE_UTILS_H
|
||||
#include <mp/mp_message_utils.h>
|
||||
|
||||
class _Tt_c_message;
|
||||
declare_derived_ptr_to(_Tt_c_message,_Tt_message)
|
||||
#endif /* MP_C_MESSAGE_UTILS_H */
|
||||
420
cde/lib/tt/lib/mp/mp_c_mp.C
Normal file
420
cde/lib/tt/lib/mp/mp_c_mp.C
Normal file
@@ -0,0 +1,420 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_c_mp.C /main/6 1999/10/14 18:41:09 mgreess $
|
||||
/*
|
||||
*
|
||||
* mp_c_mp.cc
|
||||
*
|
||||
* Implementations of client-only members of _Tt_mp object.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include "mp/mp_c_global.h"
|
||||
#include "mp/mp_c_mp.h"
|
||||
#include "mp/mp_c_session.h"
|
||||
#include "mp/mp_c_procid.h"
|
||||
#include "mp/mp_rpc_interface.h"
|
||||
#include "util/tt_global_env.h"
|
||||
#include "util/tt_port.h"
|
||||
#include "util/tt_threadspecific.h"
|
||||
|
||||
_Tt_c_mp *_tt_c_mp = (_Tt_c_mp *)0;
|
||||
|
||||
_Tt_c_mp::
|
||||
_Tt_c_mp() : _Tt_mp()
|
||||
{
|
||||
_flags &= ~(1<<_TT_MP_IN_SERVER);
|
||||
initial_session = initial_c_session =
|
||||
default_c_session = new _Tt_c_session;
|
||||
}
|
||||
|
||||
_Tt_c_mp::
|
||||
~_Tt_c_mp()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Initializes the _Tt_c_mp object. This initializes all the caches
|
||||
// maintained by this object as well as the "initial" session which is
|
||||
// the "default" session for a ToolTalk client.
|
||||
//
|
||||
// Returns:
|
||||
// TT_OK
|
||||
// TT_ERR_NOMP - the initial session could not be initialised.
|
||||
|
||||
Tt_status _Tt_c_mp::
|
||||
c_init()
|
||||
{
|
||||
Tt_status status;
|
||||
|
||||
|
||||
if (_flags&(1<<_TT_MP_INIT_DONE)) {
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
_file_cache = new _Tt_file_table( _Tt_file::networkPath_ );
|
||||
|
||||
// initialize "initial" session which is the server session in
|
||||
// server mode and the "default" session in client mode.
|
||||
|
||||
status = initial_c_session->c_init();
|
||||
if (status == TT_ERR_NOMP) {
|
||||
if (default_c_session.is_eq(initial_c_session)) {
|
||||
default_c_session = 0;
|
||||
}
|
||||
#ifdef OPT_XTHREADS
|
||||
_Tt_threadspecific* tss = (_Tt_threadspecific *) 0;
|
||||
xthread_get_specific(_tt_global->threadkey, (void **) &tss);
|
||||
|
||||
if (!tss) {
|
||||
// thread-specific storage not yet initialized -- do it
|
||||
tss = new _Tt_threadspecific(default_c_session,
|
||||
_default_c_procid);
|
||||
xthread_set_specific(_tt_global->threadkey, tss);
|
||||
}
|
||||
|
||||
_Tt_c_session_ptr cs = tss->thread_c_session();
|
||||
_Tt_c_session_ptr nullsess = (_Tt_c_session *) 0;
|
||||
if (!cs.is_null() && cs.is_eq(initial_c_session)) {
|
||||
tss->set_thread_c_session(nullsess);
|
||||
}
|
||||
#endif
|
||||
|
||||
initial_session = initial_c_session = 0;
|
||||
}
|
||||
|
||||
if (status == TT_OK && !in_server()) {
|
||||
// enter session object in session table
|
||||
_session_cache->insert(initial_session);
|
||||
}
|
||||
_flags |= (1<<_TT_MP_INIT_DONE);
|
||||
return(status);
|
||||
}
|
||||
|
||||
_Tt_procid_ptr & _Tt_c_mp::
|
||||
default_procid()
|
||||
{
|
||||
// XXX: (futures) For clients using multi-threading, this
|
||||
// function should index the default procid off the current
|
||||
// thread id so that there are no conflicts with other
|
||||
// threads.
|
||||
|
||||
return(default_c_procid());
|
||||
}
|
||||
|
||||
_Tt_c_procid_ptr & _Tt_c_mp::
|
||||
default_c_procid()
|
||||
{
|
||||
|
||||
#ifdef OPT_XTHREADS
|
||||
|
||||
// Return a thread-specific procid if one is set and libthread
|
||||
// has actually been linked in
|
||||
|
||||
if (_tt_global->multithreaded()) {
|
||||
_Tt_threadspecific* tss = (_Tt_threadspecific *) 0;
|
||||
xthread_get_specific(_tt_global->threadkey, (void **) &tss);
|
||||
|
||||
if (!tss) {
|
||||
// thread-specific storage not yet initialized -- do it
|
||||
tss = new _Tt_threadspecific(default_c_session,
|
||||
_default_c_procid);
|
||||
|
||||
xthread_set_specific(_tt_global->threadkey, tss);
|
||||
}
|
||||
|
||||
if (tss->thread_c_procid().is_null()) {
|
||||
tss->set_thread_c_procid(_default_c_procid);
|
||||
}
|
||||
|
||||
return tss->thread_c_procid();
|
||||
}
|
||||
#endif
|
||||
return(_default_c_procid);
|
||||
}
|
||||
|
||||
|
||||
Tt_status _Tt_c_mp::
|
||||
set_default_procid(
|
||||
_Tt_string id,
|
||||
int
|
||||
#ifdef OPT_XTHREADS
|
||||
thread_only
|
||||
#endif
|
||||
)
|
||||
{
|
||||
_Tt_procid_ptr p;
|
||||
|
||||
if (id.len() == 0) {
|
||||
return(TT_ERR_PROCID);
|
||||
}
|
||||
p = active_procs->lookup(id);
|
||||
if (p.is_null()) {
|
||||
return(TT_ERR_PROCID);
|
||||
}
|
||||
|
||||
_Tt_c_procid_ptr pp = (_Tt_c_procid *) p.c_pointer();
|
||||
|
||||
#ifdef OPT_XTHREADS
|
||||
if (thread_only) {
|
||||
_Tt_threadspecific* tss = (_Tt_threadspecific *) 0;
|
||||
xthread_get_specific(_tt_global->threadkey, (void **) &tss);
|
||||
|
||||
if (!tss) {
|
||||
// thread-specific storage not yet initialized -- do it
|
||||
tss = new _Tt_threadspecific(default_c_session, pp);
|
||||
xthread_set_specific(_tt_global->threadkey, tss);
|
||||
} else {
|
||||
tss->set_thread_c_procid(pp);
|
||||
}
|
||||
}
|
||||
else // fall through to set _default_c_procid
|
||||
#endif
|
||||
_default_c_procid = pp;
|
||||
|
||||
|
||||
return(TT_OK);
|
||||
}
|
||||
//
|
||||
// A client-only method that removes a procid from the active procid
|
||||
// cache and also deallocates any resources/network connections held by
|
||||
// the procid. If this is the last active procid to be removed then the
|
||||
// default session is also shut down. This method operates in this
|
||||
// fashion in order for it to be suitable for the semantics of the
|
||||
// "tt_close" api call which overloads the call to mean "close the last
|
||||
// procid" and "deallocate tooltalk resources (if no more procids left)".
|
||||
//
|
||||
Tt_status _Tt_c_mp::
|
||||
c_remove_procid(_Tt_procid_ptr &proc)
|
||||
{
|
||||
_Tt_session_ptr d_session;
|
||||
Tt_status rstatus;
|
||||
Tt_status status = TT_OK;
|
||||
_Tt_procid_table_cursor procs;
|
||||
int remove_session;
|
||||
_Tt_c_procid *cp;
|
||||
|
||||
if (proc.is_null()) {
|
||||
return(TT_ERR_INVALID);
|
||||
}
|
||||
|
||||
cp = (_Tt_c_procid *)proc.c_pointer();
|
||||
cp->close();
|
||||
// remove from list of active procs
|
||||
active_procs->remove(proc->id());
|
||||
|
||||
d_session = cp->default_session();
|
||||
if (d_session.is_null()) {
|
||||
return(TT_ERR_SESSION);
|
||||
}
|
||||
rstatus = d_session->call(TT_RPC_CLOSE_PROCID,
|
||||
(xdrproc_t)tt_xdr_procid,
|
||||
(char *)&proc,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
|
||||
if (!d_session.is_eq(initial_session)) {
|
||||
|
||||
// check to see if this is the last procid to
|
||||
// reference this session (this could be done quicker
|
||||
// by just checking the _refcount_ on the session but
|
||||
// then we'd have to be careful not to have any other
|
||||
// references to this session or else we'd fail to
|
||||
// remove it from the session cache)
|
||||
|
||||
procs.reset(active_procs);
|
||||
remove_session = 1;
|
||||
while (procs.next()) {
|
||||
cp = (_Tt_c_procid *)(*procs).c_pointer();
|
||||
if (cp->default_session()->address_string() ==
|
||||
d_session->address_string()) {
|
||||
remove_session = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// unlink d_session and remove from session cache if
|
||||
// this is the last procid to be using it.
|
||||
if (remove_session) {
|
||||
_session_cache->remove(d_session->address_string());
|
||||
}
|
||||
}
|
||||
|
||||
// this should cause the session to be disconnected if
|
||||
// remove_session is set since the last remaining
|
||||
// pointer to the session should be _default_session.
|
||||
// unless it's the initial session in which case it
|
||||
// should stay around.
|
||||
_Tt_string nullprocid = (char*)0;
|
||||
cp->set_default_session(nullprocid);
|
||||
|
||||
// Zero out the default procid if it matches the passed-in -- i.e.
|
||||
// thread-specific -- procid.
|
||||
if (proc.is_eq(_default_c_procid)) {
|
||||
_default_c_procid = (_Tt_c_procid *)0;
|
||||
}
|
||||
|
||||
#ifdef OPT_XTHREADS
|
||||
// Free the storage for the thread-specific procid
|
||||
|
||||
_Tt_threadspecific* tss = (_Tt_threadspecific *) 0;
|
||||
xthread_get_specific(_tt_global->threadkey, (void **) &tss);
|
||||
|
||||
if (tss) {
|
||||
tss->free_procid();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (rstatus != TT_OK) {
|
||||
status = rstatus;
|
||||
}
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Creates a new procid. If this is the first procid to be created then
|
||||
// we need to check for the start token being set which indicates this
|
||||
// procid was activated in response to a tooltalk start message. If this
|
||||
// is the case then this procid is "commited" to the default session.
|
||||
//
|
||||
Tt_status _Tt_c_mp::
|
||||
create_new_procid()
|
||||
{
|
||||
Tt_status status;
|
||||
const char *start_token;
|
||||
int commit = 0;
|
||||
_Tt_string session;
|
||||
_Tt_c_procid *cp = new _Tt_c_procid();
|
||||
_Tt_c_procid_ptr cpp = cp;
|
||||
|
||||
// initialize default procid
|
||||
|
||||
_default_c_procid = cp;
|
||||
#ifdef OPT_XTHREADS
|
||||
if (_tt_global->multithreaded()){
|
||||
_Tt_threadspecific* tss = (_Tt_threadspecific *) 0;
|
||||
xthread_get_specific(_tt_global->threadkey, (void **) &tss);
|
||||
|
||||
if (!tss) {
|
||||
// thread-specific storage not yet initialized -- do it
|
||||
tss = new _Tt_threadspecific(default_c_session, cpp);
|
||||
xthread_set_specific(_tt_global->threadkey, tss);
|
||||
} else {
|
||||
tss->set_thread_c_procid(cpp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Check if there is a START_MESSAGE for us.
|
||||
//
|
||||
start_token = _tt_get_first_set_env_var(2, TT_CDE_START_TOKEN, TT_START_TOKEN);
|
||||
session = _tt_get_first_set_env_var(2, TT_CDE_XATOM_NAME, TT_XATOM_NAME);
|
||||
if ((start_token != 0 && *start_token != 0 )
|
||||
&& default_c_session->has_id(session)) {
|
||||
cp->set_start_token(start_token);
|
||||
commit = 1;
|
||||
//
|
||||
// now clear the value of this environment variable so
|
||||
// that subsequent children of this process don't get
|
||||
// confused.
|
||||
//
|
||||
|
||||
|
||||
// This is done in a really ugly fashion, because older
|
||||
// versions of the ToolTalk library on Sun assumed that the
|
||||
// token was there if the _TT_TOKEN environment variable
|
||||
// existed, even if the value (after the '=') was null.
|
||||
// Unfortunately there is no portable way to completely
|
||||
// remove a environment variable from the environment. The
|
||||
// best we can do is change the environment variable name.
|
||||
// Since we're already being ugly, we do this in the brutal
|
||||
// fashion of just backing up from the environment variable
|
||||
// value into the name and punching over one of the
|
||||
// characters. In particular, we change the 4th character
|
||||
// in front of the equals sign (the 5th character in front
|
||||
// of the value) to an "A". This changes _TT_TOKEN to
|
||||
// _TT_TAKEN and _SUN_TT_TOKEN to _SUN_TT_TAKEN. This looks
|
||||
// OK enough (the token's been taken) that maybe people
|
||||
// looking in the environment won't be upset.
|
||||
|
||||
char *p;
|
||||
p = getenv(TT_CDE_START_TOKEN);
|
||||
if (p) {
|
||||
*(p-5) = 'A';
|
||||
}
|
||||
p = getenv(TT_START_TOKEN);
|
||||
if (p) {
|
||||
*(p-5) = 'A';
|
||||
}
|
||||
}
|
||||
|
||||
status = cp->init();
|
||||
if (commit) {
|
||||
// we should check for TT_CDE_START_TOKEN or
|
||||
// TT_START_TOKEN to be set. If
|
||||
// so then we commit this procid which is required to
|
||||
// join the session which caused this process to be
|
||||
// started.
|
||||
|
||||
(void)cp->commit();
|
||||
}
|
||||
if (status != TT_OK) {
|
||||
_default_c_procid = (_Tt_c_procid *)0;
|
||||
#ifdef OPT_XTHREADS
|
||||
_Tt_threadspecific* tss = (_Tt_threadspecific *) 0;
|
||||
xthread_get_specific(_tt_global->threadkey, (void **) &tss);
|
||||
|
||||
if (!tss) {
|
||||
// thread-specific storage not yet initialized -- do it
|
||||
tss = new _Tt_threadspecific(default_c_session,
|
||||
(_Tt_c_procid *) 0);
|
||||
xthread_set_specific(_tt_global->threadkey, tss);
|
||||
}
|
||||
else {
|
||||
tss->free_procid();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return(status);
|
||||
}
|
||||
active_procs->insert(default_c_procid());
|
||||
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns a count of how many procids are in the active procid cache.
|
||||
//
|
||||
int _Tt_c_mp::
|
||||
procid_count()
|
||||
{
|
||||
if (active_procs.is_null()) {
|
||||
return(0);
|
||||
} else {
|
||||
return(active_procs->count());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OPT_XTHREADS
|
||||
|
||||
//
|
||||
// Initializes structures needed for multithreading
|
||||
//
|
||||
void _Tt_c_mp::
|
||||
set_multithreaded()
|
||||
{
|
||||
if (_tt_global->multithreaded()) {
|
||||
_Tt_threadspecific* tss =
|
||||
new _Tt_threadspecific(default_c_session,
|
||||
(_Tt_c_procid *) 0);
|
||||
xthread_set_specific(_tt_global->threadkey, tss);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
46
cde/lib/tt/lib/mp/mp_c_mp.h
Normal file
46
cde/lib/tt/lib/mp/mp_c_mp.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_mp.h /main/5 1995/11/28 19:27:40 cde-sun $ */
|
||||
|
||||
/*
|
||||
* mp_c_mp.h
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file declares the _Tt_c_mp object which represents the client-only
|
||||
* global information for the MP component. There should only be one instance
|
||||
* of a _Tt_mp object in either server or client mode.
|
||||
*/
|
||||
#ifndef _MP_C_MP_H
|
||||
#define _MP_C_MP_H
|
||||
|
||||
#include "mp/mp.h"
|
||||
#include "mp/mp_c_session_utils.h"
|
||||
#include "mp/mp_c_procid_utils.h"
|
||||
|
||||
class _Tt_c_mp : public _Tt_mp {
|
||||
public:
|
||||
_Tt_c_mp();
|
||||
virtual ~_Tt_c_mp();
|
||||
Tt_status c_init();
|
||||
Tt_status set_default_procid(_Tt_string id,
|
||||
int thread_only = 0);
|
||||
_Tt_procid_ptr &default_procid();
|
||||
_Tt_c_procid_ptr &default_c_procid();
|
||||
Tt_status create_new_procid();
|
||||
Tt_status c_remove_procid(_Tt_procid_ptr &proc);
|
||||
_Tt_c_session_ptr initial_c_session;
|
||||
int procid_count();
|
||||
#ifdef OPT_XTHREADS
|
||||
void set_multithreaded();
|
||||
#endif
|
||||
|
||||
_Tt_c_session_ptr default_c_session;
|
||||
|
||||
protected:
|
||||
_Tt_c_procid_ptr _default_c_procid;
|
||||
};
|
||||
|
||||
#endif /* _MP_C_MP_H */
|
||||
68
cde/lib/tt/lib/mp/mp_c_msg_context.C
Normal file
68
cde/lib/tt/lib/mp/mp_c_msg_context.C
Normal file
@@ -0,0 +1,68 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_c_msg_context.C /main/3 1995/10/23 10:20:54 rswiston $
|
||||
/*
|
||||
*
|
||||
* @(#)mp_c_msg_context.C 1.4 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_c_msg_context.cc
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* _Tt_c_msg_context knows the client side of the context RPC interface.
|
||||
*/
|
||||
|
||||
#include <mp/mp_arg.h>
|
||||
#include <mp/mp_c_msg_context.h>
|
||||
#include <mp/mp_rpc_interface.h>
|
||||
#include <mp/mp_xdr_functions.h>
|
||||
|
||||
_Tt_c_msg_context::_Tt_c_msg_context()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_c_msg_context::~_Tt_c_msg_context()
|
||||
{
|
||||
}
|
||||
|
||||
Tt_status
|
||||
_Tt_c_msg_context::c_join(
|
||||
_Tt_session &session,
|
||||
_Tt_procid_ptr &procID
|
||||
)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
_Tt_context_join_args args;
|
||||
|
||||
args.procid = procID;
|
||||
args.context = this;
|
||||
rstatus = session.call( TT_RPC_JOIN_CONTEXT,
|
||||
(xdrproc_t)tt_xdr_context_join_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status );
|
||||
return (rstatus == TT_OK) ? status : rstatus;
|
||||
}
|
||||
|
||||
Tt_status
|
||||
_Tt_c_msg_context::c_quit(
|
||||
_Tt_session &session,
|
||||
_Tt_procid_ptr &procID
|
||||
)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
_Tt_context_join_args args;
|
||||
|
||||
args.procid = procID;
|
||||
args.context = this;
|
||||
rstatus = session.call( TT_RPC_QUIT_CONTEXT,
|
||||
(xdrproc_t)tt_xdr_context_join_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status );
|
||||
return (rstatus == TT_OK) ? status : rstatus;
|
||||
}
|
||||
40
cde/lib/tt/lib/mp/mp_c_msg_context.h
Normal file
40
cde/lib/tt/lib/mp/mp_c_msg_context.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_msg_context.h /main/3 1995/10/23 10:21:02 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_c_msg_context.h 1.4 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_c_msg_context.h
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* _Tt_c_msg_context knows the client side of the context RPC interface.
|
||||
*/
|
||||
|
||||
#ifndef _MP_C_MSG_CONTEXT_H
|
||||
#define _MP_C_MSG_CONTEXT_H
|
||||
|
||||
#include <mp/mp_msg_context.h>
|
||||
#include <mp/mp_c_msg_context_utils.h>
|
||||
#include <mp/mp_session.h>
|
||||
#include <mp/mp_procid_utils.h>
|
||||
|
||||
class _Tt_c_msg_context : public _Tt_msg_context {
|
||||
public:
|
||||
_Tt_c_msg_context();
|
||||
virtual ~_Tt_c_msg_context();
|
||||
|
||||
Tt_status c_join(
|
||||
_Tt_session &session,
|
||||
_Tt_procid_ptr &procID
|
||||
);
|
||||
Tt_status c_quit(
|
||||
_Tt_session &session,
|
||||
_Tt_procid_ptr &procID
|
||||
);
|
||||
};
|
||||
|
||||
#endif /* _MP_C_MSG_CONTEXT_H */
|
||||
18
cde/lib/tt/lib/mp/mp_c_msg_context_utils.C
Normal file
18
cde/lib/tt/lib/mp/mp_c_msg_context_utils.C
Normal file
@@ -0,0 +1,18 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_c_msg_context_utils.C /main/3 1995/10/23 10:21:09 rswiston $
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_c_msg_context_utils.C 1.2 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_c_msg_context_utils.cc
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <mp/mp_c_msg_context.h>
|
||||
#include <mp/mp_c_msg_context_utils.h>
|
||||
|
||||
implement_list_of(_Tt_c_msg_context)
|
||||
21
cde/lib/tt/lib/mp/mp_c_msg_context_utils.h
Normal file
21
cde/lib/tt/lib/mp/mp_c_msg_context_utils.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_msg_context_utils.h /main/3 1995/10/23 10:21:16 rswiston $ */
|
||||
/*
|
||||
* @(#)mp_c_msg_context_utils.h 1.2 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_c_msg_context_utils.h
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef MP_C_MSG_CONTEXT_UTILS_H
|
||||
#define MP_C_MSG_CONTEXT_UTILS_H
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_list.h>
|
||||
|
||||
class _Tt_c_msg_context;
|
||||
declare_list_of(_Tt_c_msg_context)
|
||||
|
||||
#endif /* MP_C_MSG_CONTEXT_UTILS_H */
|
||||
93
cde/lib/tt/lib/mp/mp_c_pattern.C
Normal file
93
cde/lib/tt/lib/mp/mp_c_pattern.C
Normal file
@@ -0,0 +1,93 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_c_pattern.C /main/3 1995/10/23 10:21:24 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_c_pattern.cc
|
||||
*
|
||||
* _Tt_pattern member functions called only on client side. Since there are
|
||||
* so few, I didn't bother making a _Tt_c_pattern class, but by breaking
|
||||
* this out into a separate file we can avoid defining _tt_c_mp in the
|
||||
* main mp_pattern.cc file, so that inadvertent references to it get
|
||||
* caught at compile time.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "mp/mp_c.h"
|
||||
#include "mp/mp_pattern.h"
|
||||
#include "api/c/api_error.h"
|
||||
#include "util/tt_port.h"
|
||||
|
||||
//
|
||||
// Constructor for a _Tt_pattern. Calls the base constructor and in
|
||||
// client-mode, sets the id of the pattern.
|
||||
//
|
||||
_Tt_pattern::
|
||||
_Tt_pattern()
|
||||
{
|
||||
if (! _tt_mp->in_server()) {
|
||||
set_id(_tt_c_mp->default_procid()->id());
|
||||
}
|
||||
base_constructor();
|
||||
}
|
||||
|
||||
//
|
||||
// Called by _Tt_procid::add_pattern only in client mode.
|
||||
//
|
||||
// Sets the id for this pattern which is unique. The uniqueness of the id
|
||||
// is guaranteed by giving the procid of the "sender" which is the procid
|
||||
// which is registering this pattern. To further distinguish among
|
||||
// different patterns registered by the same sender, there is a counter
|
||||
// maintainted by _Tt_mp and returned by generate_pattern_id. Thus the id
|
||||
// consists of <counter>:<sender_id>
|
||||
//
|
||||
// XXX: note that _Tt_procid::sender has a dependency on the format of
|
||||
// this message.
|
||||
//
|
||||
void _Tt_pattern::
|
||||
set_id(const _Tt_string &sender)
|
||||
{
|
||||
char id[256];
|
||||
|
||||
sprintf(id,"%d:%s",_tt_mp->generate_pattern_id(),(char *)sender);
|
||||
_pattern_id = id;
|
||||
}
|
||||
|
||||
//
|
||||
// If this pattern is file scoped, record this session on this pattern's
|
||||
// files.
|
||||
//
|
||||
Tt_status _Tt_pattern::
|
||||
join_files(const _Tt_string &sessID) const
|
||||
{
|
||||
if (! ((scopes() & (1<<TT_FILE)) || (scopes() & (1<<TT_BOTH)))) {
|
||||
// Not file-scoped
|
||||
return TT_OK;
|
||||
}
|
||||
Tt_status worstErr = TT_OK;
|
||||
_Tt_db_results dbStatus;
|
||||
Tt_status status;
|
||||
_Tt_c_file_ptr file;
|
||||
_Tt_string_list_cursor fileC( _files );
|
||||
while (fileC.next()) {
|
||||
status = _tt_mp->find_file( *fileC, file, 1 );
|
||||
if (status != TT_OK) {
|
||||
worstErr = status;
|
||||
continue;
|
||||
}
|
||||
dbStatus = file->addSession( sessID );
|
||||
status = _tt_get_api_error( dbStatus, _TT_API_FILE );
|
||||
if (status == TT_ERR_INTERNAL) {
|
||||
_tt_syslog( 0, LOG_ERR,
|
||||
"_Tt_db_file::addSession(): %d", dbStatus);
|
||||
}
|
||||
if (status != TT_OK) {
|
||||
worstErr = status;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return worstErr;
|
||||
}
|
||||
819
cde/lib/tt/lib/mp/mp_c_procid.C
Normal file
819
cde/lib/tt/lib/mp/mp_c_procid.C
Normal file
@@ -0,0 +1,819 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_c_procid.C /main/5 1999/09/17 18:27:38 mgreess $
|
||||
/*
|
||||
* @(#)mp_c_procid.C 1.30 93/07/30
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <tt_options.h>
|
||||
#include <util/tt_global_env.h>
|
||||
#include <util/tt_host.h>
|
||||
#include <util/tt_threadspecific.h>
|
||||
#include <mp/mp_c_file.h>
|
||||
#include <mp/mp_c_message.h>
|
||||
#include <mp/mp_c_mp.h>
|
||||
#include <mp/mp_c_global.h>
|
||||
#include <mp/mp_pattern.h>
|
||||
#include <mp/mp_c_procid.h>
|
||||
#include <mp/mp_rpc_interface.h>
|
||||
#include <mp/mp_c_session.h>
|
||||
#include <mp/mp_stream_socket.h>
|
||||
#include <util/tt_int_rec.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
//
|
||||
// This file contains client-side only methods for procids.
|
||||
//
|
||||
|
||||
|
||||
|
||||
_Tt_c_procid::
|
||||
_Tt_c_procid()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_c_procid::
|
||||
~_Tt_c_procid()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
_Tt_c_procid::
|
||||
_Tt_c_procid(const _Tt_string &id)
|
||||
{
|
||||
_id = id;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Used by the client library to register a new pattern. The real work is
|
||||
// done on the server-side.
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
add_pattern(_Tt_pattern_ptr &p)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
_Tt_add_pattern_args args;
|
||||
|
||||
|
||||
if (p->category() == TT_CATEGORY_LAST) {
|
||||
// category needs to be set
|
||||
return(TT_ERR_CATEGORY);
|
||||
}
|
||||
|
||||
args.procid = this;
|
||||
args.pattern = p;
|
||||
|
||||
rstatus = default_session()->call( p->contextsCount()
|
||||
? TT_RPC_ADD_PATTERN_WITH_CONTEXT
|
||||
: TT_RPC_ADD_PATTERN,
|
||||
(xdrproc_t)tt_xdr_add_pattern_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
if (rstatus != TT_OK) {
|
||||
return rstatus;
|
||||
}
|
||||
if (status != TT_OK) {
|
||||
return status;
|
||||
}
|
||||
return p->join_files( default_session()->process_tree_id() );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Invokes the right rpc call to cause this procid to be recognized as an
|
||||
// instance of the given ptype. The server-side does most of the work
|
||||
// here. The only subtlety here is that we keep a list of the ptypes that
|
||||
// this procid has declared itself as so that file-scope message queueing
|
||||
// can work properly.
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
declare_ptype(_Tt_string &ptid)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
_Tt_declare_ptype_args args;
|
||||
|
||||
args.procid = this;
|
||||
args.ptid = ptid;
|
||||
|
||||
rstatus = default_session()->call(TT_RPC_DECLARE_PTYPE,
|
||||
(xdrproc_t)tt_xdr_declare_ptype_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
if (rstatus == TT_OK && status == TT_OK) {
|
||||
if (_declared_ptypes.is_null()) {
|
||||
_declared_ptypes = new _Tt_string_list();
|
||||
}
|
||||
_declared_ptypes->push(ptid);
|
||||
}
|
||||
return((rstatus == TT_OK) ? status : rstatus);
|
||||
}
|
||||
|
||||
//
|
||||
// Invokes the right rpc call to cause this procid to stop being recognized
|
||||
// as an instance of the given ptype. The server-side does most of the work
|
||||
// here. The only subtlety here is that we keep a list of the ptypes that
|
||||
// this procid has declared itself as so that file-scope message queueing
|
||||
// can work properly, and that has to be updated too. We also use
|
||||
// this local list to return a bad error code if the ptype was never
|
||||
// declared \(I suppose it would be a optimization to only make the
|
||||
// RPC call if the ptype\'s in the list...\)
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
undeclare_ptype(_Tt_string &ptid)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
_Tt_declare_ptype_args args;
|
||||
|
||||
args.procid = this;
|
||||
args.ptid = ptid;
|
||||
|
||||
rstatus = default_session()->call(TT_RPC_UNDECLARE_PTYPE,
|
||||
(xdrproc_t)tt_xdr_declare_ptype_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
if (rstatus == TT_OK && status == TT_OK) {
|
||||
if (!_declared_ptypes.is_null()) {
|
||||
_Tt_string_list_cursor c(_declared_ptypes);
|
||||
int was_declared = 0;
|
||||
while (c.next()) {
|
||||
if (*c == ptid) {
|
||||
c.remove();
|
||||
was_declared = 1;
|
||||
}
|
||||
}
|
||||
if (!was_declared) {
|
||||
status = TT_ERR_PTYPE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return((rstatus == TT_OK) ? status : rstatus);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Invokes the right rpc call to test if a ptype is known by the current
|
||||
// ttsession.
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
exists_ptype(_Tt_string &ptid)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
_Tt_declare_ptype_args args;
|
||||
|
||||
args.procid = this;
|
||||
args.ptid = ptid;
|
||||
|
||||
rstatus = default_session()->call(TT_RPC_EXISTS_PTYPE,
|
||||
(xdrproc_t)tt_xdr_declare_ptype_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
return((rstatus == TT_OK) ? status : rstatus);
|
||||
}
|
||||
|
||||
//
|
||||
// Invokes the right rpc call to unblock any messages being held for
|
||||
// this ptype until this process is intialized.
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
unblock_ptype(const _Tt_string &ptid)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
_Tt_declare_ptype_args args;
|
||||
|
||||
args.procid = this;
|
||||
args.ptid = ptid;
|
||||
|
||||
rstatus = default_session()->call(TT_RPC_UNBLOCK_PTYPE,
|
||||
(xdrproc_t)tt_xdr_declare_ptype_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
return((rstatus == TT_OK) ? status : rstatus);
|
||||
}
|
||||
|
||||
//
|
||||
// Unregister a pattern for this procid. The pattern is identified by its
|
||||
// id which is matched up on the server-side to the real pattern object.
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
del_pattern(const _Tt_string &id)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
_Tt_del_pattern_args args;
|
||||
|
||||
if (id.len() == 0) {
|
||||
return(TT_ERR_INVALID);
|
||||
}
|
||||
|
||||
args.procid = this;
|
||||
args.pattern_id = id;
|
||||
|
||||
rstatus = default_session()->call(TT_RPC_DEL_PATTERN,
|
||||
(xdrproc_t)tt_xdr_del_pattern_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
return((rstatus == TT_OK) ? status : rstatus);
|
||||
}
|
||||
|
||||
|
||||
// Invokes the right rpc call to load a set of types, contained in a
|
||||
// string which is the image of an XDR types file, into the ttsession.
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
load_types(_Tt_string &typebuffer)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
_Tt_load_types_args args;
|
||||
|
||||
args.xdrtypes = typebuffer;
|
||||
|
||||
rstatus = default_session()->call(TT_RPC_LOAD_TYPES,
|
||||
(xdrproc_t)tt_xdr_load_types_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
return((rstatus == TT_OK) ? status : rstatus);
|
||||
}
|
||||
|
||||
_Tt_c_session_ptr& _Tt_c_procid::
|
||||
default_session()
|
||||
{
|
||||
#ifdef OPT_XTHREADS
|
||||
if (_tt_global->multithreaded()) {
|
||||
|
||||
// Use the thread-specific session if there is one
|
||||
|
||||
_Tt_threadspecific* tss = (_Tt_threadspecific *) 0;
|
||||
xthread_get_specific(_tt_global->threadkey, (void **) &tss);
|
||||
if (!tss) {
|
||||
// thread-specific storage not yet initialized -- do it
|
||||
tss = new _Tt_threadspecific(_tt_c_mp->default_c_session,
|
||||
this);
|
||||
xthread_set_specific(_tt_global->threadkey, tss);
|
||||
}
|
||||
|
||||
_Tt_c_session_ptr sptr = tss->thread_c_session();
|
||||
|
||||
if (!sptr.is_null()) {
|
||||
return tss->thread_c_session();
|
||||
}
|
||||
else {
|
||||
tss->set_thread_c_session(_default_session);
|
||||
return _default_session;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return _default_session;
|
||||
}
|
||||
#else
|
||||
return _default_session;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// In a multiple-procid, multiple-session usage this method means that
|
||||
// the current procid has done some action that requires it to be bound
|
||||
// to the current session. This method just turns on a flag in the procid
|
||||
// object that means it is now bound to the current session.
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
commit()
|
||||
{
|
||||
if (default_session().is_null()) {
|
||||
return(TT_ERR_NOMP);
|
||||
}
|
||||
_flags |= (1<<_TT_PROC_COMMITTED);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Initializes a procid for use. The main duties are to set the id of a
|
||||
// procid and to initialize a signalling channel. Setting the id involves
|
||||
// asking the server for a unique prefix to make the procid's id unique
|
||||
// among all procids currently registered with the session. (see set_id
|
||||
// method). The signalling channel is initialized here because it is the
|
||||
// main mechanism for the server to know if this procid has exited (since
|
||||
// breaking the signalling channel will wake up the server).
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
init()
|
||||
{
|
||||
int rpc_version = TT_RPC_VERSION;
|
||||
Tt_status status;
|
||||
|
||||
if (_default_session.is_null()) {
|
||||
|
||||
// set the default session to the initial session.
|
||||
|
||||
#ifdef OPT_XTHREADS
|
||||
if (_tt_global->multithreaded()) {
|
||||
|
||||
// Use the thread-specific session if there is one
|
||||
|
||||
_Tt_threadspecific* tss = (_Tt_threadspecific *) 0;
|
||||
xthread_get_specific(_tt_global->threadkey,
|
||||
(void **) &tss);
|
||||
if (!tss) {
|
||||
// thread-specific storage not yet
|
||||
// initialized -- do it
|
||||
tss = new _Tt_threadspecific(_tt_c_mp->
|
||||
default_c_session,
|
||||
this);
|
||||
xthread_set_specific(_tt_global->threadkey, tss);
|
||||
}
|
||||
|
||||
_Tt_c_session_ptr sptr = tss->thread_c_session();
|
||||
|
||||
if (!sptr.is_null()) {
|
||||
_default_session = sptr;
|
||||
}
|
||||
else {
|
||||
tss->set_thread_c_session(_tt_c_mp->
|
||||
default_c_session);
|
||||
_default_session = _tt_c_mp->default_c_session;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_default_session = _tt_c_mp->default_c_session;
|
||||
}
|
||||
#else
|
||||
_default_session = _tt_c_mp->default_c_session;
|
||||
#endif
|
||||
if (_default_session.is_null()) {
|
||||
return(TT_ERR_NOMP);
|
||||
}
|
||||
}
|
||||
|
||||
_version = TT_RPC_VERSION;
|
||||
_pid = getpid();
|
||||
if (! _tt_global->get_local_host(_proc_host)) {
|
||||
return(TT_ERR_NOMP);
|
||||
}
|
||||
_proc_host_ipaddr = _proc_host->addr();
|
||||
|
||||
status = _default_session->call(TT_RPC_ALLOC_PROCID_KEY,
|
||||
(xdrproc_t)xdr_void, 0,
|
||||
(xdrproc_t)tt_xdr_string,
|
||||
(char *)&_id);
|
||||
|
||||
|
||||
if (status != TT_OK) {
|
||||
return(status);
|
||||
}
|
||||
if (!_id.len()) {
|
||||
return(TT_ERR_INTERNAL);
|
||||
}
|
||||
_id = _id.cat(" ").cat(_default_session->address_string());
|
||||
|
||||
// now set up an fd channel which is used by the
|
||||
// server side to notify this procid of new messages
|
||||
// as well as a notification mechanism of this procid
|
||||
// going away (by breaking the fd channel).
|
||||
|
||||
if (set_fd_channel() && fd() != -1) {
|
||||
return(TT_OK);
|
||||
} else {
|
||||
return(TT_ERR_PROCID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Retrieves the next message for this procid. Conceptually, this means
|
||||
// retrieving the next message from the queue of undelivered messages
|
||||
// (the _undelivered field). This field is mainly kept on the server-side
|
||||
// so it involves an rpc call to the server to dequeue the next message
|
||||
// for this procid. For optimization's sake, this method is coded so the
|
||||
// rpc call actually returns a list of messages. This allows batching of
|
||||
// message delivery. The list is assigned to our local copy of
|
||||
// _undelivered and messages are consumed from this list until it is
|
||||
// exhausted at which time we invoke the rpc call again.
|
||||
//
|
||||
// If OPT_ADDMSG_DIRECT is defined then it will read the message directly
|
||||
// from the signalling socket.
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
next_message(_Tt_c_message_ptr &msg)
|
||||
{
|
||||
_Tt_procid_ptr proc = this;
|
||||
|
||||
if (! _unvoted.is_null()) {
|
||||
update_message( _unvoted, TT_ABSTAINED );
|
||||
_unvoted = 0;
|
||||
}
|
||||
|
||||
#ifdef OPT_ADDMSG_DIRECT
|
||||
if (default_session()->rpc_version() >= TT_ADDMSG_VERS) {
|
||||
if (_mxdr_stream == (XDR *)0) {
|
||||
_mxdr_stream = (XDR *)malloc(sizeof(XDR));
|
||||
xdrrec_create(_mxdr_stream, 0, 0,
|
||||
(char *)_socket.c_pointer(),
|
||||
(int (*)())_tt_xdr_readit,
|
||||
(int (*)())_tt_xdr_writeit);
|
||||
_mxdr_stream->x_op = XDR_DECODE;
|
||||
}
|
||||
msg = (_Tt_message *)0;
|
||||
(void)xdrrec_skiprecord(_mxdr_stream);
|
||||
if (! msg.xdr(_mxdr_stream)) {
|
||||
msg = (_Tt_message *)0;
|
||||
if (_flags&(1<<_TT_PROC_FD_CHANNEL_ON)) {
|
||||
dup2(_socket->sock(), _socket->fd());
|
||||
_flags &= ~(1<<_TT_PROC_FD_CHANNEL_ON);
|
||||
}
|
||||
return(TT_ERR_NOMP);
|
||||
}
|
||||
if (! msg.is_null()) {
|
||||
if (msg->state() == TT_STARTED && handling(msg)) {
|
||||
msg->set_state(TT_SENT);
|
||||
msg->set_start_message();
|
||||
}
|
||||
|
||||
// We need to notify the server that we've
|
||||
// read the message. Otherwise, it would never
|
||||
// know that it should send us messages
|
||||
// through the fd again. This notification
|
||||
// also tells the server to reset the timer
|
||||
// for this message.
|
||||
|
||||
// XXX: it would be nice to find a protocol
|
||||
// that didn't need this extra rpc call.
|
||||
|
||||
default_session()->call(TT_RPC_MSGREAD_2,
|
||||
(xdrproc_t)tt_xdr_procid,
|
||||
(char *)&proc,
|
||||
(xdrproc_t)xdr_void,
|
||||
(char *)0);
|
||||
return(TT_OK);
|
||||
}
|
||||
}
|
||||
#endif // OPT_ADDMSG_DIRECT
|
||||
|
||||
// We're here if we're talking to a version 1 server or if a
|
||||
// null message ptr was sent down the signalling fd. This
|
||||
// means that we are to use an rpc call to get the message for
|
||||
// us.
|
||||
|
||||
Tt_status rstatus = TT_OK;
|
||||
|
||||
if (_undelivered.is_null() || _undelivered->count() == 0) {
|
||||
_Tt_next_message_args args;
|
||||
|
||||
rstatus = default_session()->call(TT_RPC_NEXT_MESSAGE,
|
||||
(xdrproc_t)tt_xdr_procid,
|
||||
(char *)&proc,
|
||||
(xdrproc_t)tt_xdr_next_message_args,
|
||||
(char *)&args);
|
||||
switch (rstatus) {
|
||||
case TT_OK:
|
||||
_undelivered = args.msgs;
|
||||
// set the signalled flag to tell us whether we should
|
||||
// clear the new message signal when all messages have
|
||||
// been retrieved from the local _undelivered queue.
|
||||
if (args.clear_signal) {
|
||||
_flags &= ~(1<<_TT_PROC_SIGNALLED);
|
||||
} else {
|
||||
_flags |= (1<<_TT_PROC_SIGNALLED);
|
||||
}
|
||||
break;
|
||||
case TT_ERR_NOMP:
|
||||
// server got disconnected either because it
|
||||
// was killed or because of network errors.
|
||||
// We now dup the previous fd so that it won't
|
||||
// stay active.
|
||||
if (_flags&(1<<_TT_PROC_FD_CHANNEL_ON)) {
|
||||
dup2(_socket->sock(), _socket->fd());
|
||||
_flags &= ~(1<<_TT_PROC_FD_CHANNEL_ON);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (rstatus) {
|
||||
case TT_OK:
|
||||
case TT_WRN_NOTFOUND:
|
||||
break;
|
||||
default:
|
||||
return(rstatus);
|
||||
}
|
||||
|
||||
if (_undelivered.is_null() || _undelivered->count() == 0) {
|
||||
msg = 0;
|
||||
} else {
|
||||
msg = (_Tt_c_message *)_undelivered->bot().c_pointer();
|
||||
_undelivered->dequeue();
|
||||
|
||||
if (msg->queue() && msg->scope() == TT_FILE) {
|
||||
_Tt_file_ptr fptr;
|
||||
|
||||
if (_tt_mp->find_file(msg->file(), fptr, 1) == TT_OK) {
|
||||
((_Tt_c_file *)fptr.c_pointer())->
|
||||
process_message_queue(0);
|
||||
}
|
||||
}
|
||||
if (msg->state() == TT_STARTED && processing(*msg)) {
|
||||
msg->set_state(TT_SENT);
|
||||
msg->set_start_message();
|
||||
}
|
||||
|
||||
|
||||
#ifdef OPT_ADDMSG_DIRECT
|
||||
if (default_session()->rpc_version() >= TT_ADDMSG_VERS) {
|
||||
return(rstatus);
|
||||
}
|
||||
#endif
|
||||
// unless we're getting messages through the
|
||||
// signalling fd, we have to clear the input from the
|
||||
// fd if there are no more messages.
|
||||
|
||||
if ((! (_flags&(1<<_TT_PROC_SIGNALLED))) &&
|
||||
(_undelivered.is_null()
|
||||
|| _undelivered->count() == 0)) {
|
||||
clear_signal();
|
||||
}
|
||||
if ((msg->message_class() == TT_OFFER) && processing(*msg)) {
|
||||
_unvoted = msg;
|
||||
}
|
||||
}
|
||||
|
||||
return(rstatus);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Quits out of any joined files.
|
||||
//
|
||||
void _Tt_c_procid::
|
||||
close()
|
||||
{
|
||||
_Tt_string_list_cursor filec(_joined_files);
|
||||
_Tt_c_file_ptr fp;
|
||||
_Tt_procid_ptr pptr = this;
|
||||
|
||||
while (filec.next()) {
|
||||
if (_tt_mp->find_file(*filec, fp, 0) == TT_OK) {
|
||||
(void)fp->c_quit(pptr);
|
||||
}
|
||||
filec.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Sets the default session for this procid. If a zero-length string is
|
||||
// passed in as the session id then the procid is detached from the
|
||||
// current session.
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
set_default_session(_Tt_string &sid)
|
||||
{
|
||||
_Tt_c_session_ptr session;
|
||||
Tt_status status;
|
||||
|
||||
if (sid.len() == 0) { // detach from default session
|
||||
default_session() = (_Tt_c_session *)0;
|
||||
_flags &= ~(1<<_TT_PROC_COMMITTED);
|
||||
|
||||
status = TT_OK;
|
||||
} else { // set default session
|
||||
// can only join one session for now. If a session is
|
||||
// "committed" then we can't switch sessions for this procid.
|
||||
|
||||
_Tt_string this_id = default_session()->id();
|
||||
if (_flags&(1<<_TT_PROC_COMMITTED)) {
|
||||
if (sid != this_id) {
|
||||
return(TT_ERR_SESSION);
|
||||
}
|
||||
}
|
||||
|
||||
// initialize session from sid
|
||||
status = _tt_c_mp->find_session(sid, default_session(), 1, 1);
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Updates the message with the same id as "msg" that is presumed to be in
|
||||
// the queue of delivered messages for this procid on the server-side.
|
||||
// (see _Tt_s_procid::update_message for details). This method is
|
||||
// invoked when a handler is replying, failing, or rejecting a message.
|
||||
// It is also involved in the special case of an observer replying to its
|
||||
// start message.
|
||||
//
|
||||
Tt_status _Tt_c_procid::
|
||||
update_message(const _Tt_c_message_ptr &msg, Tt_state newstate)
|
||||
{
|
||||
Tt_status rstatus;
|
||||
_Tt_update_args args;
|
||||
int clr_obs = 0;
|
||||
|
||||
if (msg.is_null()) {
|
||||
return TT_ERR_POINTER;
|
||||
}
|
||||
switch (newstate) {
|
||||
case TT_HANDLED:
|
||||
if (msg->is_start_message()) {
|
||||
// OK to reply() instead of accept()
|
||||
break;
|
||||
}
|
||||
if (msg->message_class() != TT_REQUEST) {
|
||||
return TT_ERR_CLASS;
|
||||
}
|
||||
if (msg->handler().is_null()) {
|
||||
return TT_ERR_NOTHANDLER;
|
||||
}
|
||||
if (! is_equal( msg->handler())) {
|
||||
return TT_ERR_NOTHANDLER;
|
||||
}
|
||||
break;
|
||||
case TT_ABSTAINED:
|
||||
if (msg->message_class() != TT_OFFER) {
|
||||
return TT_ERR_CLASS;
|
||||
}
|
||||
break;
|
||||
case TT_REJECTED:
|
||||
if ((msg->state() != TT_SENT) && (msg->state() != TT_STARTED)) {
|
||||
return TT_ERR_STATE;
|
||||
}
|
||||
}
|
||||
// if this message is already in a "final" state then
|
||||
// don't allow the state change
|
||||
switch (msg->state()) {
|
||||
case TT_FAILED:
|
||||
case TT_HANDLED:
|
||||
case TT_RETURNED:
|
||||
return TT_ERR_STATE;
|
||||
}
|
||||
|
||||
msg->add_voter( this, newstate );
|
||||
|
||||
// optimize message xdr'ing for this case
|
||||
msg->set_return_handler_flags();
|
||||
args.message = msg;
|
||||
args.newstate = newstate;
|
||||
|
||||
// invoke the appropiate rpc procedure depending on the
|
||||
// version of the server we're connected with
|
||||
switch (default_session()->rpc_version()) {
|
||||
case 1:
|
||||
Tt_status status;
|
||||
|
||||
rstatus = default_session()->call(TT_RPC_UPDATE_MSG,
|
||||
(xdrproc_t)tt_xdr_update_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
msg->set_state(newstate);
|
||||
return((rstatus == TT_OK) ? status : rstatus);
|
||||
case 2:
|
||||
default:
|
||||
if (msg->is_start_message() && msg->handler().is_null()) {
|
||||
//
|
||||
// If this procid is an observer replying to
|
||||
// its start message then we have to
|
||||
// temporarily set its handler procid in order
|
||||
// to tell ttsession which procid we are.
|
||||
// See _tt_update_msg() for more details.
|
||||
//
|
||||
msg->set_observer_procid(this);
|
||||
clr_obs = 1;
|
||||
}
|
||||
rstatus = default_session()->call(TT_RPC_UPDATE_MSG_2,
|
||||
(xdrproc_t)tt_xdr_update_args,
|
||||
(char *)&args,
|
||||
(xdrproc_t)xdr_void,
|
||||
(char *)0);
|
||||
if (clr_obs) {
|
||||
// clear the handler procid if it was just set
|
||||
// for the special case of an observer
|
||||
// replying to a start message.
|
||||
|
||||
msg->clr_observer_procid();
|
||||
}
|
||||
|
||||
// update the state of the message to the new state
|
||||
msg->set_state(newstate);
|
||||
return(rstatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Sets the signalling channel for this procid to an fd which is
|
||||
// implemented here by opening a TCP socket so signal the procid. It is
|
||||
// desirable to use a TCP socket because it is "reliable" which means
|
||||
// that when signalling the procid fails, it's a good bet the procid has
|
||||
// gone away.
|
||||
//
|
||||
// This method is somewhat tricky because it has to open a socket and
|
||||
// leave the socket in a state ready to accept connections (the details
|
||||
// of this are in _Tt_stream_socket::init). Then it invokes an rpc call
|
||||
// telling the server the port number of the socket. At this point the
|
||||
// server-side method _Tt_s_procid::set_fd_channel will attempt to
|
||||
// connect to this socket. The _Tt_c_procid::fd method will complete this
|
||||
// socket connection (by invoking the _Tt_stream_socket::fd method) so
|
||||
// it should be called after this method is called. This is done above
|
||||
// in _Tt_c_procid::init.
|
||||
//
|
||||
// XXX: It seems like the code in _Tt_c_procid::fd should have just been
|
||||
// included before returning in this method.
|
||||
//
|
||||
int _Tt_c_procid::
|
||||
set_fd_channel(int p)
|
||||
{
|
||||
_Tt_fd_args fd_args;
|
||||
Tt_status rstatus;
|
||||
Tt_status status;
|
||||
|
||||
if (_flags&(1<<_TT_PROC_FD_CHANNEL_ON)) {
|
||||
return(1);
|
||||
}
|
||||
_socket = new _Tt_stream_socket(_proc_host, p);
|
||||
if (! _socket->init(1)) {
|
||||
_socket = (_Tt_stream_socket *)0;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
fd_args.procid = this;
|
||||
fd_args.start_token = _start_token;
|
||||
fd_args.fd = port();
|
||||
rstatus = default_session()->call(TT_RPC_SET_FD_CHANNEL,
|
||||
(xdrproc_t)tt_xdr_fd_args,
|
||||
(char *)&fd_args,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
if (rstatus != TT_OK || status != TT_OK) {
|
||||
return(0);
|
||||
}
|
||||
// clear the start token so the server won't attempt
|
||||
// to issue a proc_started event on the ptype each
|
||||
// time we contact it.
|
||||
_start_token = (char *)0;
|
||||
|
||||
_flags |= (1<<_TT_PROC_FD_CHANNEL_ON);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Clears the signalling socket by reading the byte that gets sent to it
|
||||
// by the server to notify the arrival of new messages. A read is avoided
|
||||
// if it would block.
|
||||
//
|
||||
void _Tt_c_procid::
|
||||
clear_signal()
|
||||
{
|
||||
char sig[2];
|
||||
|
||||
if (_flags&(1<<_TT_PROC_FD_CHANNEL_ON)) {
|
||||
sig[1] = 0;
|
||||
if (_socket->read_would_block() != 1) {
|
||||
return;
|
||||
}
|
||||
if (_socket->recv(sig, 1) < 0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Sets the default ptype for this procid.
|
||||
//
|
||||
void _Tt_c_procid::
|
||||
set_default_ptype(_Tt_string &ptid)
|
||||
{
|
||||
_default_ptype = ptid;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Sets the default file for this procid.
|
||||
//
|
||||
void _Tt_c_procid::
|
||||
set_default_file(const _Tt_string &file)
|
||||
{
|
||||
_default_file = file;
|
||||
}
|
||||
|
||||
68
cde/lib/tt/lib/mp/mp_c_procid.h
Normal file
68
cde/lib/tt/lib/mp/mp_c_procid.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_procid.h /main/4 1995/11/21 19:25:50 cde-sun $ */
|
||||
/* @(#)mp_c_procid.h 1.11 93/07/30
|
||||
*
|
||||
* Copyright (c) 1990, 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file implements the client side of the _Tt_procid object.
|
||||
*/
|
||||
#ifndef _MP_C_PROCID_H
|
||||
#define _MP_C_PROCID_H
|
||||
#include <mp/mp_procid.h>
|
||||
#include <mp/mp_c_session.h>
|
||||
#include <mp/mp_c_message_utils.h>
|
||||
#include "api/c/api_typecb_utils.h"
|
||||
|
||||
class _Tt_c_procid : public _Tt_procid {
|
||||
public:
|
||||
_Tt_c_procid();
|
||||
~_Tt_c_procid();
|
||||
_Tt_c_procid(const _Tt_string &id);
|
||||
Tt_status add_pattern(_Tt_pattern_ptr &p);
|
||||
Tt_status api_in(_Tt_string &s);
|
||||
_Tt_string api_out();
|
||||
void clear_signal();
|
||||
void close();
|
||||
Tt_status commit();
|
||||
Tt_status declare_ptype(_Tt_string &ptid);
|
||||
Tt_status undeclare_ptype(_Tt_string &ptid);
|
||||
Tt_status exists_ptype(_Tt_string &ptid);
|
||||
Tt_status unblock_ptype(const _Tt_string &ptid);
|
||||
Tt_status load_types(_Tt_string &typebuffer);
|
||||
_Tt_string &default_file() {
|
||||
return _default_file;
|
||||
}
|
||||
_Tt_string &default_ptype() {
|
||||
return _default_ptype;
|
||||
}
|
||||
_Tt_c_session_ptr &default_session();
|
||||
|
||||
Tt_status del_pattern(const _Tt_string &id);
|
||||
Tt_status init();
|
||||
Tt_status next_message(_Tt_c_message_ptr &m);
|
||||
void set_default_ptype(_Tt_string &ptid);
|
||||
void set_default_file(const _Tt_string &file);
|
||||
Tt_status set_default_session(_Tt_string &id);
|
||||
int set_fd_channel(int port = 0);
|
||||
Tt_status update_message(const _Tt_c_message_ptr &msg,
|
||||
Tt_state newstate);
|
||||
_Tt_typecb_table_ptr & ptype_callbacks() {
|
||||
return _ptype_callbacks;
|
||||
}
|
||||
_Tt_typecb_table_ptr & otype_callbacks() {
|
||||
return _otype_callbacks;
|
||||
}
|
||||
private:
|
||||
_Tt_string _default_file;
|
||||
_Tt_string _default_ptype;
|
||||
_Tt_c_session_ptr _default_session;
|
||||
_Tt_message_list_ptr _undelivered;
|
||||
_Tt_c_message_ptr _unvoted;
|
||||
_Tt_typecb_table_ptr _ptype_callbacks;
|
||||
_Tt_typecb_table_ptr _otype_callbacks;
|
||||
};
|
||||
|
||||
#endif /* _MP_C_PROCID_H */
|
||||
19
cde/lib/tt/lib/mp/mp_c_procid_utils.C
Normal file
19
cde/lib/tt/lib/mp/mp_c_procid_utils.C
Normal file
@@ -0,0 +1,19 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_c_procid_utils.C /main/3 1995/10/23 10:21:47 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_c_procid_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Declaration of auxiliary data structures for the _Tt_c_procid class
|
||||
*/
|
||||
|
||||
#include "mp/mp_c_procid.h"
|
||||
#include "mp/mp_c_procid_utils.h"
|
||||
|
||||
implement_derived_ptr_to(_Tt_c_procid,_Tt_procid)
|
||||
implement_table_of(_Tt_c_procid)
|
||||
23
cde/lib/tt/lib/mp/mp_c_procid_utils.h
Normal file
23
cde/lib/tt/lib/mp/mp_c_procid_utils.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_procid_utils.h /main/3 1995/10/23 10:21:54 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_c_procid_utils.h
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Utilities declarations for _Tt_procid_utils
|
||||
*/
|
||||
#ifndef _MP_C_PROCID_UTILS_H
|
||||
#define _MP_C_PROCID_UTILS_H
|
||||
#include "util/tt_object.h"
|
||||
|
||||
#include "mp/mp_procid_utils.h"
|
||||
|
||||
class _Tt_c_procid;
|
||||
declare_derived_ptr_to(_Tt_c_procid,_Tt_procid)
|
||||
declare_table_of(_Tt_c_procid)
|
||||
#endif /* MP_PROCID_UTILS_H */
|
||||
316
cde/lib/tt/lib/mp/mp_c_session.C
Normal file
316
cde/lib/tt/lib/mp/mp_c_session.C
Normal file
@@ -0,0 +1,316 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_c_session.C /main/5 1999/10/14 18:41:24 mgreess $
|
||||
/*
|
||||
* @(#)mp_c_session.C 1.23 94/10/03
|
||||
*
|
||||
* Copyright (c) 1990,1992,1993 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Implementation of the _Tt_session class.
|
||||
*/
|
||||
#include "util/tt_global_env.h"
|
||||
#include "util/tt_host.h"
|
||||
#include "util/tt_enumname.h"
|
||||
#include "mp/mp_global.h"
|
||||
#include "mp/mp_c_message.h"
|
||||
#include "mp/mp_mp.h"
|
||||
#include "mp/mp_pattern.h"
|
||||
#include "mp/mp_rpc_client.h"
|
||||
#include "mp/mp_rpc_interface.h"
|
||||
#include "mp/mp_c_session.h"
|
||||
#include "mp/mp_desktop.h"
|
||||
#include "mp/mp_xdr_functions.h"
|
||||
#include "util/tt_port.h"
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef OPT_UNIX_SOCKET_RPC
|
||||
# include <sys/socket.h>
|
||||
# include <sys/un.h>
|
||||
#endif // OPT_UNIX_SOCKET_RPC
|
||||
|
||||
// Use the parent class (_Tt_session) for construction and destruction.
|
||||
_Tt_c_session::_Tt_c_session () {}
|
||||
_Tt_c_session::~_Tt_c_session () {}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Initializes a session object. This means that we initialize our
|
||||
// desktop connection if this is a desktop session and find the address
|
||||
// of a server session. If none is found or if an address is found but we
|
||||
// are unable to connect to the session then we attempt to auto-start a
|
||||
// server session.
|
||||
//
|
||||
// Returns:
|
||||
// TT_OK
|
||||
// TT_ERR_ACCESS Could not init desktop (diagnostic emitted)
|
||||
// TT_ERR_NO_MATCH Advertised address's version is too new
|
||||
// (diagnostic emitted)
|
||||
// TT_ERR_INVALID Authorization error
|
||||
// TT_ERR_NOMP No server running or startable
|
||||
//
|
||||
Tt_status _Tt_c_session::
|
||||
c_init()
|
||||
{
|
||||
_Tt_string start_ttcmd;
|
||||
int tried = 0;
|
||||
int done = 0;
|
||||
Tt_status status;
|
||||
|
||||
if (env() == _TT_ENV_X11) {
|
||||
if (_displayname.len() == 0) {
|
||||
_displayname = _tt_global->xdisplayname;
|
||||
}
|
||||
}
|
||||
while (tried < 10) {
|
||||
_is_dead = 0;
|
||||
status = client_session_init();
|
||||
switch (status) {
|
||||
int pings;
|
||||
case TT_OK:
|
||||
// We try to ping the session to give it
|
||||
// reasonable time to start up.
|
||||
for (pings = 1; pings <= OPT_PING_TRIES; pings++) {
|
||||
status = ping();
|
||||
if (status != TT_ERR_NOMP) {
|
||||
// Fatal error or TT_OK
|
||||
return status;
|
||||
}
|
||||
sleep(OPT_PING_SLEEP);
|
||||
}
|
||||
|
||||
// Session could not be pinged. If this is an
|
||||
// X11 session, handle the case where there is
|
||||
// an invalid TT_CDE_XATOM_NAME xprop and a valid
|
||||
// TT_XATOM_NAME xprop, because in that case we
|
||||
// were trying to ping the dead TT_CDE_XATOM_NAME
|
||||
// session.
|
||||
|
||||
if (env() == _TT_ENV_X11) {
|
||||
_Tt_string desktop_addr;
|
||||
|
||||
if (_desktop->get_prop(TT_CDE_XATOM_NAME,
|
||||
desktop_addr) &&
|
||||
desktop_addr == _address_string) {
|
||||
|
||||
// Bogus session xprop found -- re-initialize
|
||||
// trying the TT_XATOM_NAME xprop.
|
||||
|
||||
if (_desktop->get_prop(TT_XATOM_NAME,
|
||||
_address_string)) {
|
||||
// Continue the initialization
|
||||
// loop WITHOUT attempting to start
|
||||
// a new ttsession
|
||||
tried++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If we\'re here, a session was found but could
|
||||
// not be pinged. Force re-initialization.
|
||||
_address_string = (char *) 0;
|
||||
break;
|
||||
}
|
||||
case TT_ERR_ACCESS:
|
||||
case TT_ERR_NO_MATCH:
|
||||
// Can't recover from these
|
||||
return status;
|
||||
case TT_WRN_NOTFOUND:
|
||||
case TT_ERR_INVALID:
|
||||
case TT_ERR_NOMP:
|
||||
// No ttsession.
|
||||
// If we haven\'t tried to start one already, do
|
||||
// so. If we have tried but failed, force
|
||||
// client_session_init to re-initialize.
|
||||
if (tried > 0) _address_string = (char *) 0;
|
||||
break;
|
||||
case TT_AUTHFILE_ACCESS:
|
||||
case TT_AUTHFILE_LOCK:
|
||||
case TT_AUTHFILE_LOCK_TIMEOUT:
|
||||
case TT_AUTHFILE_UNLOCK:
|
||||
case TT_AUTHFILE_MISSING:
|
||||
case TT_AUTHFILE_ENTRY_MISSING:
|
||||
case TT_AUTHFILE_WRITE:
|
||||
return TT_ERR_AUTHORIZATION;
|
||||
default:
|
||||
_tt_syslog( 0, LOG_ERR,
|
||||
"_Tt_session::client_session_init(): %s",
|
||||
_tt_enumname(status));
|
||||
return TT_ERR_INTERNAL;
|
||||
}
|
||||
//
|
||||
// Attempt to start a new server
|
||||
//
|
||||
if (env() != _TT_ENV_X11) {
|
||||
// can't auto-start anything other than an X
|
||||
// tooltalk session
|
||||
return TT_ERR_NOMP;
|
||||
}
|
||||
if (tried == 0) {
|
||||
int sysStat = startup_ttsession(start_ttcmd);
|
||||
int exitStat;
|
||||
if (WIFEXITED(sysStat)) {
|
||||
exitStat = WEXITSTATUS(sysStat);
|
||||
} else if (WIFSIGNALED(sysStat)) {
|
||||
_tt_syslog( 0, LOG_ERR,
|
||||
"libtt: system(\"%s\"): signal %d",
|
||||
(char *)start_ttcmd,
|
||||
WTERMSIG(sysStat) );
|
||||
exitStat = 11;
|
||||
} else {
|
||||
_tt_syslog( 0, LOG_ERR,
|
||||
"libtt: system(\"%s\"): %d",
|
||||
(char *)start_ttcmd, sysStat );
|
||||
exitStat = 11;
|
||||
}
|
||||
switch (exitStat) {
|
||||
case 1:
|
||||
// Race condition -- no ttsession was
|
||||
// found in the above code, but by the time
|
||||
// we got around to trying to start one,
|
||||
// another had appeared, so this one exited
|
||||
// normally.
|
||||
// Fall through.
|
||||
case 2:
|
||||
// another ttsession discovered.
|
||||
// Either way, loop around and connect to it
|
||||
// after nulling _address_string to make sure
|
||||
// we pick the address off the X server again
|
||||
// since the new server will have a new
|
||||
// address.
|
||||
_address_string = (char *)0;
|
||||
|
||||
// Since the other ttsession was just started,
|
||||
// let it have a chance to initialize
|
||||
sleep(2);
|
||||
|
||||
// fall through
|
||||
case 0:
|
||||
// ttsession started.
|
||||
break;
|
||||
default:
|
||||
return TT_ERR_NOMP;
|
||||
}
|
||||
} else {
|
||||
sleep(1);
|
||||
}
|
||||
tried++;
|
||||
}
|
||||
|
||||
return TT_ERR_NOMP;
|
||||
}
|
||||
|
||||
// Starts ttsession by executing either the hardcoded
|
||||
// default command "ttsession -s -d <displayname>"
|
||||
// or the command specified in TTSESSION_CMD or SUN_TTSESSION_CMD.
|
||||
// TTSESSION_CMD and SUN_TTSESSION_CMD provide a way of overriding the
|
||||
// standard options specified when tools auto-start
|
||||
// ttsession. For example, to switch from Classing
|
||||
// Engine format to xdr format for auto-start set
|
||||
// TTSESSION_CMD or SUN_TTSESSION_CMD to "ttsession -X".
|
||||
// The string used is returned in a parameter so c_init can use it in
|
||||
// error messages.
|
||||
|
||||
|
||||
int _Tt_c_session::
|
||||
startup_ttsession(_Tt_string &start_ttcmd)
|
||||
{
|
||||
// If TTSESSION_CMD or SUN_TTSESSION_CMD is specified, we use system() to run the
|
||||
// command since it might have shell metacharacters (a common
|
||||
// thing to do is TTSESSION_CMD or SUN_TTSESSION_CMD=truss ttsession >/tmp/trace
|
||||
// in order to truss ttsession startup)
|
||||
|
||||
char* pc_env_value = _tt_get_first_set_env_var(2, "TTSESSION_CMD", "SUN_TTSESSION_CMD");
|
||||
|
||||
if (pc_env_value) {
|
||||
start_ttcmd = pc_env_value;
|
||||
start_ttcmd = start_ttcmd.cat(" -d ");
|
||||
start_ttcmd = start_ttcmd.cat(_displayname);
|
||||
return system((char *)start_ttcmd);
|
||||
}
|
||||
// start_ttcmd is not really used but we set it so it can be used
|
||||
// in messages
|
||||
start_ttcmd = "ttsession -s -d ";
|
||||
start_ttcmd = start_ttcmd.cat(_displayname);
|
||||
|
||||
// This is basically a stripped down and specialized system() call...
|
||||
|
||||
int status;
|
||||
pid_t pid, w;
|
||||
|
||||
#if defined(__GNUG__)
|
||||
typedef void (*SIG_PF)(int);
|
||||
#endif
|
||||
SIG_PF istat, qstat, cstat;
|
||||
|
||||
#if defined(_AIX) || defined(OPT_BUG_USL) || defined(OPT_BUG_UXP)
|
||||
#define vfork fork
|
||||
#endif
|
||||
if((pid = vfork()) == 0) {
|
||||
fflush(stdout);
|
||||
(void) execlp("ttsession", "ttsession",
|
||||
"-s",
|
||||
"-d",
|
||||
(char *)_displayname,
|
||||
(char *)0);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
istat = signal(SIGINT, SIG_IGN);
|
||||
qstat = signal(SIGQUIT, SIG_IGN);
|
||||
cstat = signal(SIGCLD, SIG_DFL);
|
||||
|
||||
w = waitpid(pid, &status, 0);
|
||||
|
||||
(void) signal(SIGINT, istat);
|
||||
(void) signal(SIGQUIT, qstat);
|
||||
(void) signal(SIGCLD, cstat);
|
||||
|
||||
return((w == -1)? w: status);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Invokes an rpc call on the server session that causes all of the
|
||||
// given procid's patterns to have a session id for the current
|
||||
// session (this allows them to begin matching messages).
|
||||
//
|
||||
// See _Tt_s_session::s_join for the server-side of this method.
|
||||
//
|
||||
Tt_status _Tt_c_session::
|
||||
c_join(_Tt_procid_ptr &procid)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
|
||||
rstatus = call(TT_RPC_JOIN_SESSION,
|
||||
(xdrproc_t)tt_xdr_procid,
|
||||
(char *)&procid,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
return((rstatus == TT_OK) ? status : rstatus);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Invokes an rpc call on the server session that causes all of the
|
||||
// given procid's patterns to not have a session id for the current
|
||||
// session (this prevents them from matching messages).
|
||||
//
|
||||
// See _Tt_s_session::s_quit for the server-side of this method.
|
||||
//
|
||||
Tt_status _Tt_c_session::
|
||||
c_quit(_Tt_procid_ptr &procid)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
|
||||
rstatus = call(TT_RPC_QUIT_SESSION,
|
||||
(xdrproc_t)tt_xdr_procid, (char *)&procid,
|
||||
(xdrproc_t)xdr_int, (char *)&status);
|
||||
return((rstatus == TT_OK) ? status : rstatus);
|
||||
}
|
||||
38
cde/lib/tt/lib/mp/mp_c_session.h
Normal file
38
cde/lib/tt/lib/mp/mp_c_session.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_session.h /main/3 1995/10/23 10:22:09 rswiston $ */
|
||||
/*
|
||||
* mp_c_session.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file contains the implementation of the client side of
|
||||
* the _Tt_session object.
|
||||
*/
|
||||
#ifndef MP_C_SESSION_H
|
||||
#define MP_C_SESSION_H
|
||||
#include <mp/mp_session.h>
|
||||
#include <mp/mp_c_session_utils.h>
|
||||
|
||||
class _Tt_c_session : public _Tt_session {
|
||||
public:
|
||||
_Tt_c_session();
|
||||
virtual ~_Tt_c_session();
|
||||
|
||||
Tt_status c_addprop(_Tt_string prop, _Tt_string val);
|
||||
Tt_status c_getprop(_Tt_string prop, int i,
|
||||
_Tt_string &value);
|
||||
Tt_status c_init();
|
||||
Tt_status c_join(_Tt_procid_ptr &procid);
|
||||
Tt_status c_propcount(_Tt_string prop, int &cnt);
|
||||
Tt_status c_propname(int i, _Tt_string &prop);
|
||||
Tt_status c_propnames_count(int &cnt);
|
||||
Tt_status c_quit(_Tt_procid_ptr &procid);
|
||||
Tt_status c_setprop(_Tt_string prop, _Tt_string val);
|
||||
private:
|
||||
int startup_ttsession(_Tt_string &command);
|
||||
};
|
||||
|
||||
#endif /* MP_C_SESSION_H */
|
||||
189
cde/lib/tt/lib/mp/mp_c_session_prop.C
Normal file
189
cde/lib/tt/lib/mp/mp_c_session_prop.C
Normal file
@@ -0,0 +1,189 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_c_session_prop.C /main/3 1995/10/23 10:22:16 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_c_session_prop.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <mp/mp_global.h>
|
||||
#include <mp/mp_mp.h>
|
||||
#include <mp/mp_rpc_client.h>
|
||||
#include <mp/mp_rpc_interface.h>
|
||||
#include <mp/mp_c_session.h>
|
||||
#include <mp/mp_xdr_functions.h>
|
||||
|
||||
|
||||
/*
|
||||
* Set the session property to the value
|
||||
*/
|
||||
Tt_status _Tt_c_session::
|
||||
c_setprop(_Tt_string prop, _Tt_string val)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
_Tt_prop_args args;
|
||||
|
||||
if (prop.len() == 0) {
|
||||
return TT_ERR_INVALID;
|
||||
}
|
||||
args.prop = prop;
|
||||
args.value = val;
|
||||
args.num = 0;
|
||||
|
||||
rstatus = call(TT_RPC_SET_PROP,
|
||||
(xdrproc_t)tt_xdr_prop_args, (char *)&args,
|
||||
(xdrproc_t)xdr_int, (char *)&status);
|
||||
return((rstatus == TT_OK) ? status : rstatus);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add the value to the session property
|
||||
*/
|
||||
Tt_status _Tt_c_session::
|
||||
c_addprop(_Tt_string prop, _Tt_string val)
|
||||
{
|
||||
Tt_status status;
|
||||
Tt_status rstatus;
|
||||
_Tt_prop_args args;
|
||||
|
||||
if (prop.len() == 0) {
|
||||
return TT_ERR_INVALID;
|
||||
}
|
||||
args.prop = prop;
|
||||
args.value = val;
|
||||
args.num = 0;
|
||||
rstatus = call(TT_RPC_ADD_PROP,
|
||||
(xdrproc_t)tt_xdr_prop_args, (char *)&args,
|
||||
(xdrproc_t)xdr_int, (char *)&status);
|
||||
return((rstatus == TT_OK) ? status : rstatus);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the ith value of the session property
|
||||
*/
|
||||
Tt_status _Tt_c_session::
|
||||
c_getprop(_Tt_string prop, int i, _Tt_string &value)
|
||||
{
|
||||
_Tt_prop_args args;
|
||||
_Tt_rpc_result result;
|
||||
Tt_status rstatus;
|
||||
|
||||
|
||||
if (prop.len() == 0) {
|
||||
return TT_ERR_INVALID;
|
||||
}
|
||||
if (i < 0) {
|
||||
return TT_ERR_INVALID;
|
||||
}
|
||||
args.prop = prop;
|
||||
args.value = "";
|
||||
args.num = i;
|
||||
rstatus = call(TT_RPC_GET_PROP,
|
||||
(xdrproc_t)tt_xdr_prop_args, (char *)&args,
|
||||
(xdrproc_t)tt_xdr_rpc_result, (char *)&result);
|
||||
if (rstatus != TT_OK) {
|
||||
return(rstatus);
|
||||
}
|
||||
if (result.status == TT_OK) {
|
||||
value = result.str_val;
|
||||
return(TT_OK);
|
||||
} else {
|
||||
return result.status;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of values on the session property
|
||||
*/
|
||||
Tt_status _Tt_c_session::
|
||||
c_propcount(_Tt_string prop, int &cnt)
|
||||
{
|
||||
_Tt_prop_args args;
|
||||
_Tt_rpc_result result;
|
||||
Tt_status rstatus;
|
||||
|
||||
if (prop.len() == 0) {
|
||||
return TT_ERR_INVALID;
|
||||
}
|
||||
args.prop = prop;
|
||||
args.value = "";
|
||||
args.num = 0;
|
||||
rstatus = call(TT_RPC_PROP_COUNT,
|
||||
(xdrproc_t)tt_xdr_prop_args, (char *)&args,
|
||||
(xdrproc_t)tt_xdr_rpc_result, (char *)&result);
|
||||
if (rstatus != TT_OK) {
|
||||
return(rstatus);
|
||||
}
|
||||
if (result.status != TT_OK) {
|
||||
return result.status;
|
||||
}
|
||||
cnt = result.int_val;
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the ith session property name
|
||||
*/
|
||||
Tt_status _Tt_c_session::
|
||||
c_propname(int i, _Tt_string &prop)
|
||||
{
|
||||
_Tt_prop_args args;
|
||||
_Tt_rpc_result result;
|
||||
Tt_status rstatus;
|
||||
|
||||
if (i < 0) {
|
||||
return TT_ERR_INVALID;
|
||||
}
|
||||
args.prop = "";
|
||||
args.value = "";
|
||||
args.num = i;
|
||||
rstatus = call(TT_RPC_PROP_NAME,
|
||||
(xdrproc_t)tt_xdr_prop_args, (char *)&args,
|
||||
(xdrproc_t)tt_xdr_rpc_result, (char *)&result);
|
||||
if (rstatus != TT_OK) {
|
||||
return(rstatus);
|
||||
}
|
||||
prop = result.str_val;
|
||||
return result.status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of session properties
|
||||
*/
|
||||
Tt_status _Tt_c_session::
|
||||
c_propnames_count(int &cnt)
|
||||
{
|
||||
_Tt_prop_args args;
|
||||
_Tt_rpc_result result;
|
||||
Tt_status rstatus;
|
||||
|
||||
args.prop = "";
|
||||
args.value = "";
|
||||
args.num = 0;
|
||||
rstatus = call(TT_RPC_PROP_NAMES_COUNT,
|
||||
(xdrproc_t)tt_xdr_prop_args, (char *)&args,
|
||||
(xdrproc_t)tt_xdr_rpc_result,(char *)&result);
|
||||
if (rstatus != TT_OK) {
|
||||
return(rstatus);
|
||||
}
|
||||
if (result.status != TT_OK) {
|
||||
return result.status;
|
||||
} else {
|
||||
cnt = result.int_val;
|
||||
return TT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
16
cde/lib/tt/lib/mp/mp_c_session_utils.C
Normal file
16
cde/lib/tt/lib/mp/mp_c_session_utils.C
Normal file
@@ -0,0 +1,16 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_c_session_utils.C /main/3 1995/10/23 10:22:23 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_c_session_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Declaration of auxilliary data structures for the _Tt_c_session class
|
||||
*/
|
||||
#include <mp/mp_c_session.h>
|
||||
|
||||
implement_ptr_to(_Tt_c_session)
|
||||
21
cde/lib/tt/lib/mp/mp_c_session_utils.h
Normal file
21
cde/lib/tt/lib/mp/mp_c_session_utils.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_c_session_utils.h /main/3 1995/10/23 10:22:30 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_c_session_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Declaration of auxilliary data structures for the _Tt_c_session class
|
||||
*/
|
||||
#ifndef MP_C_SESSION_UTILS_H
|
||||
#define MP_C_SESSION_UTILS_H
|
||||
#include <mp/mp_session_utils.h>
|
||||
|
||||
class _Tt_c_session;
|
||||
declare_derived_ptr_to(_Tt_c_session,_Tt_session)
|
||||
|
||||
#endif /* MP_C_SESSION_UTILS_H */
|
||||
72
cde/lib/tt/lib/mp/mp_context.C
Normal file
72
cde/lib/tt/lib/mp/mp_context.C
Normal file
@@ -0,0 +1,72 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_context.C /main/3 1995/10/23 10:22:37 rswiston $
|
||||
/*
|
||||
*
|
||||
* @(#)mp_context.C 1.5 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_context.cc
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Implementation of the _Tt_context: a context slotname.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <mp/mp_context.h>
|
||||
|
||||
_Tt_context::
|
||||
_Tt_context()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_context::
|
||||
_Tt_context(const _Tt_context &c)
|
||||
{
|
||||
_slotName = c._slotName;
|
||||
}
|
||||
|
||||
_Tt_context::
|
||||
~_Tt_context()
|
||||
{
|
||||
}
|
||||
|
||||
Tt_status _Tt_context::
|
||||
setName(
|
||||
const char *slotname
|
||||
)
|
||||
{
|
||||
if (slotname == 0) {
|
||||
return TT_ERR_SLOTNAME;
|
||||
}
|
||||
const char *pc = slotname;
|
||||
if (*pc == '$') {
|
||||
pc++;
|
||||
}
|
||||
while (*pc != 0) {
|
||||
if ((! isalnum(*pc)) && (*pc != '_')) {
|
||||
return TT_ERR_SLOTNAME;
|
||||
}
|
||||
pc++;
|
||||
}
|
||||
_slotName = slotname;
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
void _Tt_context::
|
||||
print(
|
||||
const _Tt_ostream &os
|
||||
) const
|
||||
{
|
||||
_slotName.print( os );
|
||||
}
|
||||
|
||||
bool_t _Tt_context::
|
||||
xdr(
|
||||
XDR *xdrs
|
||||
)
|
||||
{
|
||||
return _slotName.xdr( xdrs );
|
||||
}
|
||||
49
cde/lib/tt/lib/mp/mp_context.h
Normal file
49
cde/lib/tt/lib/mp/mp_context.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_context.h /main/3 1995/10/23 10:22:44 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_context.h 1.5 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_context.h
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
*
|
||||
* _Tt_context is an object that represents a keyword.
|
||||
*/
|
||||
|
||||
#ifndef _MP_CONTEXT_H
|
||||
#define _MP_CONTEXT_H
|
||||
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_string.h>
|
||||
#include <api/c/tt_c.h>
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
class _Tt_context : public _Tt_object {
|
||||
public:
|
||||
_Tt_context();
|
||||
_Tt_context(const _Tt_context &);
|
||||
virtual ~_Tt_context();
|
||||
|
||||
Tt_status setName(
|
||||
const char *slotname
|
||||
);
|
||||
|
||||
void print(
|
||||
const _Tt_ostream &os
|
||||
) const;
|
||||
bool_t xdr(
|
||||
XDR *xdrs
|
||||
);
|
||||
|
||||
const _Tt_string &slotName() const { return _slotName; }
|
||||
|
||||
protected:
|
||||
_Tt_string _slotName;
|
||||
};
|
||||
|
||||
#endif /* _MP_CONTEXT_H */
|
||||
60
cde/lib/tt/lib/mp/mp_context_utils.C
Normal file
60
cde/lib/tt/lib/mp/mp_context_utils.C
Normal file
@@ -0,0 +1,60 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_context_utils.C /main/3 1995/10/23 10:22:52 rswiston $
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_context_utils.C 1.4 @(#)
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_context_utils.cc
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <mp/mp_context.h>
|
||||
#include <mp/mp_context_utils.h>
|
||||
#include <stdio.h>
|
||||
|
||||
implement_list_of(_Tt_context)
|
||||
|
||||
// _Tt_context_list supports the append_ordered method. Contexts
|
||||
// are ordered by slotname.
|
||||
|
||||
_Tt_context_list& _Tt_context_list::
|
||||
append_ordered(const _Tt_context_ptr &e)
|
||||
{
|
||||
|
||||
// Application programmers are either going to insert contexts in
|
||||
// alphabetical order or at random. So we start at the end,
|
||||
// find the last element less than the new one and insert after that.
|
||||
// If an equal element is found, replace the old one with this one.
|
||||
// No indication is returned if replacement is done; if you really care,
|
||||
// check the count before and after to see if it changed.
|
||||
|
||||
_Tt_context_list_ptr this_ptr = this;
|
||||
_Tt_context_list_cursor c(this_ptr);
|
||||
|
||||
while (c.prev()) {
|
||||
int t= c->slotName().cmp(e->slotName());
|
||||
if (t==0) {
|
||||
// c->slotName == e->slotName
|
||||
c.remove().insert(e);
|
||||
return *this;
|
||||
} else if (t<0) {
|
||||
// c->slotName < e->slotName
|
||||
// insert after here.
|
||||
c.insert(e);
|
||||
return *this;
|
||||
} else {
|
||||
// c->slotName > e->slotName
|
||||
// this element greater than new one, look further.
|
||||
}
|
||||
}
|
||||
|
||||
// There are no elements in the list smaller than this one, so
|
||||
// put the new one at the beginning.
|
||||
|
||||
push(e);
|
||||
return *this;
|
||||
}
|
||||
20
cde/lib/tt/lib/mp/mp_context_utils.h
Normal file
20
cde/lib/tt/lib/mp/mp_context_utils.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_context_utils.h /main/3 1995/10/23 10:22:59 rswiston $ */
|
||||
/* @(#)mp_context_utils.h 1.2 @(#)
|
||||
*
|
||||
* mp_context_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef MP_CONTEXT_UTILS_H
|
||||
#define MP_CONTEXT_UTILS_H
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_list.h>
|
||||
|
||||
class _Tt_context;
|
||||
declare_list_of(_Tt_context)
|
||||
|
||||
#endif /* MP_CONTEXT_UTILS_H */
|
||||
492
cde/lib/tt/lib/mp/mp_desktop.C
Normal file
492
cde/lib/tt/lib/mp/mp_desktop.C
Normal file
@@ -0,0 +1,492 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_desktop.C /main/7 1998/04/09 17:52:01 mgreess $
|
||||
/*
|
||||
*
|
||||
* @(#)mp_desktop.C 1.34 93/09/07
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
//
|
||||
// This file contains method for dealing with a "desktop" connection.
|
||||
// Typically this desktop is an X11 session but this way the interface
|
||||
// to the desktop is relatively free of Xisms allowing for more
|
||||
// independence from X11 in the future.
|
||||
//
|
||||
|
||||
|
||||
#include "tt_options.h"
|
||||
// Defining BSD_COMP gets us FIONREAD on SunOS 5.x, and shouldn\'t
|
||||
// hurt in other places.
|
||||
#define BSD_COMP
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#if defined(__STDC__) && !defined(linux)
|
||||
extern "C" { extern int ioctl (int, int, ...) ; };
|
||||
#endif
|
||||
#include "util/tt_global_env.h"
|
||||
#include "util/tt_ldpath.h"
|
||||
#include "util/tt_host.h"
|
||||
#include "util/tt_port.h"
|
||||
#include "util/tt_Xlib.h"
|
||||
#include "mp/mp_desktop.h"
|
||||
#include "mp/mp_mp.h"
|
||||
#include <unistd.h>
|
||||
#include <malloc.h>
|
||||
#include "util/tt_gettext.h"
|
||||
|
||||
static int parse_Xdisplay_string(_Tt_string display,
|
||||
_Tt_string &host,
|
||||
pid_t &svnum,
|
||||
_Tt_string &hostname);
|
||||
|
||||
|
||||
jmp_buf _Tt_desktop::io_exception;
|
||||
|
||||
// The following private class data is declared and allocated here
|
||||
// so that everybody that includes mp_desktop.h doesn't have to
|
||||
// also include X11/Xlib.h.
|
||||
|
||||
struct _Tt_desktop_private {
|
||||
Display *xd;
|
||||
};
|
||||
|
||||
_Tt_desktop::
|
||||
_Tt_desktop()
|
||||
{
|
||||
priv = (_Tt_desktop_private *)malloc(sizeof(_Tt_desktop_private));
|
||||
priv->xd = (Display *)0;
|
||||
}
|
||||
|
||||
|
||||
_Tt_desktop::
|
||||
~_Tt_desktop()
|
||||
{
|
||||
// Ungrab the server, in case the user
|
||||
// interrupted us during a grab.
|
||||
unlock();
|
||||
close();
|
||||
free((MALLOCTYPE *)priv);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Initializes a desktop object. This has the effect of connecting to the
|
||||
// appropiate X11 server. "dt_handle" is a string identifying which
|
||||
// desktop we want to talk to. For X11, this string will be the same as
|
||||
// what would be specified in the DISPLAY variable.
|
||||
//
|
||||
int _Tt_desktop::
|
||||
init(_Tt_string dt_handle, _Tt_dt_type /* t */)
|
||||
{
|
||||
char buf[32];
|
||||
_Tt_string h, hostname;
|
||||
pid_t s;
|
||||
int parse_status;
|
||||
int ret_val;
|
||||
|
||||
if (priv->xd != (Display *)0) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
// initialize our access to Xlib
|
||||
if (! _tt_load_xlib()) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
_Tt_string display;
|
||||
|
||||
// parse the dt_handle string to extract the host and server
|
||||
// number information.
|
||||
|
||||
parse_status = parse_Xdisplay_string(dt_handle, h, s, hostname);
|
||||
|
||||
// Now we examine the parse status to determine if this is a
|
||||
// local host or remote host and if we should use a unix
|
||||
// connection or not. We also enforce the use of screen 0 for
|
||||
// all connections.
|
||||
switch (parse_status) {
|
||||
case 1: // non-local host
|
||||
case 2: // local host
|
||||
// important to always use screen 0 for the case where
|
||||
// multiple displays are used.
|
||||
sprintf(buf,":%d.0",s);
|
||||
if (dt_handle[0] == ':') {
|
||||
display = buf;
|
||||
} else {
|
||||
display = hostname.cat(buf);
|
||||
}
|
||||
break;
|
||||
case 3: // local host and unix connection specified
|
||||
sprintf(buf,"unix:%d.0", s);
|
||||
display = buf;
|
||||
break;
|
||||
case 0:
|
||||
_tt_syslog( 0, LOG_ERR,
|
||||
catgets( _ttcatd, 1, 17,
|
||||
"could not parse X display name: \"%s\"" ),
|
||||
(char *)dt_handle );
|
||||
return(0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret_val = 1;
|
||||
int retries = 20;
|
||||
set_error_handler(_Tt_desktop::io_error_proc);
|
||||
if (0 == setjmp(io_exception)) {
|
||||
|
||||
// now connect to the indicated X11 server
|
||||
while (retries--) {
|
||||
if (priv->xd = (Display *)
|
||||
CALLX11(XOpenDisplay)((char *)display)) {
|
||||
// Xlib has already emitted diagnostic
|
||||
break;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
if (!priv->xd) ret_val = 0;
|
||||
} else {
|
||||
ret_val = 0;
|
||||
}
|
||||
restore_user_handler();
|
||||
return(ret_val);
|
||||
}
|
||||
|
||||
|
||||
// I/O error handler. Longjmp back to before the error occured.
|
||||
int _Tt_desktop::
|
||||
io_error_proc(void *)
|
||||
{
|
||||
longjmp(io_exception, 1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// Sets the error handler function which will get invoked on any I/O
|
||||
// errors received from the X11 connection
|
||||
void _Tt_desktop::
|
||||
set_error_handler(_Tt_dt_errfn efn)
|
||||
{
|
||||
user_io_handler = (int *)
|
||||
CALLX11(XSetIOErrorHandler)((XIOErrorHandler)efn);
|
||||
}
|
||||
|
||||
|
||||
// Restore the users I/O error handler.
|
||||
void _Tt_desktop::
|
||||
restore_user_handler()
|
||||
{
|
||||
CALLX11(XSetIOErrorHandler)((XIOErrorHandler)user_io_handler);
|
||||
}
|
||||
|
||||
|
||||
// Closes the connection to the X11 server.
|
||||
int _Tt_desktop::
|
||||
close()
|
||||
{
|
||||
int ret_val = 1;
|
||||
|
||||
set_error_handler(_Tt_desktop::io_error_proc);
|
||||
if (0 == setjmp(io_exception)) {
|
||||
|
||||
// delete all properties set and close connection to desktop
|
||||
if (priv->xd != (Display *)0) {
|
||||
CALLX11(XCloseDisplay)(priv->xd);
|
||||
}
|
||||
} else {
|
||||
ret_val = 0;
|
||||
}
|
||||
restore_user_handler();
|
||||
return(ret_val);
|
||||
}
|
||||
|
||||
|
||||
// Returns the fd to poll on when new events come from the desktop
|
||||
// connection.
|
||||
int _Tt_desktop::
|
||||
notify_fd()
|
||||
{
|
||||
return ConnectionNumber(priv->xd);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Method to call when an event comes in from the desktop connection.
|
||||
// This method will return 0 if the connection is broken indicating
|
||||
// either a network partition or the X11 server going down.
|
||||
//
|
||||
int _Tt_desktop::
|
||||
process_event()
|
||||
{
|
||||
XEvent xev;
|
||||
XMappingEvent *xm;
|
||||
int pending;
|
||||
int iostat;
|
||||
|
||||
if (priv->xd == (Display *)0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
CALLX11(XFlush)(priv->xd);
|
||||
xev.type = 0;
|
||||
iostat=ioctl(notify_fd(), FIONREAD, (char *)&pending);
|
||||
if (iostat == -1 || pending == 0) {
|
||||
// X server went down
|
||||
return(0);
|
||||
}
|
||||
if (priv->xd != (Display *)0) {
|
||||
CALLX11(XNextEvent)(priv->xd, &xev);
|
||||
if (xev.type == MappingNotify) {
|
||||
xm = (XMappingEvent *)&xev;
|
||||
CALLX11(XRefreshKeyboardMapping)(xm);
|
||||
}
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int _Tt_desktop::
|
||||
lock()
|
||||
{
|
||||
if (priv->xd != 0) {
|
||||
CALLX11(XGrabServer)(priv->xd);
|
||||
CALLX11(XFlush)(priv->xd);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _Tt_desktop::
|
||||
unlock()
|
||||
{
|
||||
if (priv->xd != 0) {
|
||||
CALLX11(XUngrabServer)(priv->xd);
|
||||
CALLX11(XFlush)(priv->xd);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Sets the value of the indicated property name to val.
|
||||
//
|
||||
int _Tt_desktop::
|
||||
set_prop(_Tt_string pname, _Tt_string &val)
|
||||
{
|
||||
Window rootw;
|
||||
Atom patom;
|
||||
char *v1;
|
||||
const unsigned char *v;
|
||||
|
||||
if (priv->xd == (Display *)0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
patom = CALLX11(XInternAtom)(priv->xd, (char *)pname, False);
|
||||
if (patom == None) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
rootw = DefaultRootWindow(priv->xd);
|
||||
v1 = (char *)val;
|
||||
v = (const unsigned char *)v1;
|
||||
CALLX11(XChangeProperty)(priv->xd, rootw,
|
||||
patom, XA_STRING, 8,
|
||||
PropModeReplace,
|
||||
v, val.len());
|
||||
CALLX11(XFlush)(priv->xd);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Deletes the indicated property from the desktop.
|
||||
//
|
||||
int _Tt_desktop::
|
||||
del_prop(_Tt_string pname)
|
||||
{
|
||||
Window rootw;
|
||||
Atom patom;
|
||||
|
||||
if (priv->xd == (Display *)0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
patom = CALLX11(XInternAtom)(priv->xd, (char *)pname, False);
|
||||
if (patom == None) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
rootw = DefaultRootWindow(priv->xd);
|
||||
CALLX11(XDeleteProperty)(priv->xd, rootw, patom);
|
||||
CALLX11(XFlush)(priv->xd);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Gets the value of the indicated property from the desktop.
|
||||
//
|
||||
int _Tt_desktop::
|
||||
get_prop(_Tt_string pname, _Tt_string &pval)
|
||||
{
|
||||
Atom anatom;
|
||||
int format;
|
||||
/* X11 requires these to longs and not ints */
|
||||
unsigned long items;
|
||||
unsigned long left_to_read;
|
||||
unsigned char *val = (unsigned char *)0;
|
||||
Atom tt_xatom;
|
||||
|
||||
if (priv->xd == (Display *)0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
tt_xatom = CALLX11(XInternAtom)(priv->xd, (char *)pname, False);
|
||||
if (tt_xatom == None) {
|
||||
return(0);
|
||||
}
|
||||
CALLX11(XGetWindowProperty)(priv->xd, DefaultRootWindow(priv->xd),
|
||||
tt_xatom,
|
||||
0, 20, False, XA_STRING,
|
||||
&anatom, &format, &items, &left_to_read,
|
||||
&val);
|
||||
if (val == (unsigned char *)0) {
|
||||
return(0);
|
||||
}
|
||||
pval = (char *)val;
|
||||
CALLX11(XFree)((caddr_t)val);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Parse a string in X11 "display" format and return the host and server
|
||||
// number found. If parse errors occur return 0, else return 1 if the
|
||||
// host is not the local host and 2 if the host is the local host. If the
|
||||
// host is specified as "unix" which means use the local host with a Unix
|
||||
// socket connection then return 3.
|
||||
//
|
||||
// XXX - the "hostname" paramater is an artifact of the fix for bug 1118012.
|
||||
// if/when session IDs are re-worked to use only the process tree
|
||||
// format internally, instead of the additional use of X session IDs,
|
||||
// the parse_Xdisplay_string() function should be re-written to
|
||||
// remove this.
|
||||
//
|
||||
static int
|
||||
parse_Xdisplay_string(_Tt_string display, _Tt_string &host, pid_t &svnum,_Tt_string &hostname)
|
||||
{
|
||||
int status = 1;
|
||||
int offset;
|
||||
_Tt_host_ptr h;
|
||||
_Tt_host_ptr localh;
|
||||
char *dstr;
|
||||
|
||||
offset = display.index(':');
|
||||
if (offset == -1) {
|
||||
return(0);
|
||||
}
|
||||
if (offset == 0) {
|
||||
|
||||
// use local host
|
||||
(void)_tt_global->get_local_host(h);
|
||||
host = h->stringaddr();
|
||||
hostname = h->name();
|
||||
status = 2;
|
||||
} else {
|
||||
// Get the hostid portion of an X display of the
|
||||
// format "hostid:X"
|
||||
//
|
||||
host = display.mid(0, offset);
|
||||
|
||||
if (host == "unix") {
|
||||
(void)_tt_global->get_local_host(h);
|
||||
host = h->stringaddr();
|
||||
hostname = h->name();
|
||||
status = 3;
|
||||
|
||||
} else {
|
||||
|
||||
if (! _tt_global->find_host_byname(host, h)) {
|
||||
if (! _tt_global->find_host(host, h, 1)) {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
host = h->stringaddr();
|
||||
hostname = h->name();
|
||||
if (_tt_global->get_local_host(localh)) {
|
||||
if (localh->stringaddr() == host) {
|
||||
status = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// now get the server number
|
||||
dstr = (char *)display + offset + 1;
|
||||
if (*dstr == ':') {
|
||||
// ugh, a decnet connection
|
||||
dstr++;
|
||||
}
|
||||
|
||||
long long_svnum;
|
||||
if (1 != sscanf(dstr, "%ld", &long_svnum)) {
|
||||
svnum = (pid_t)long_svnum;
|
||||
return(0);
|
||||
} else {
|
||||
svnum = (pid_t)long_svnum;
|
||||
}
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns a suitable name for this desktop session. Changing the value
|
||||
// returned from this method should be done with care because it could
|
||||
// compromise older versions of tooltalk clients/servers from
|
||||
// communicating since a canonical name for a tooltalk desktop session
|
||||
// contains the desktop session name in it and tooltalk session names
|
||||
// indicate to clients how to contact the session.
|
||||
//
|
||||
_Tt_string _Tt_desktop::
|
||||
session_name(_Tt_string dt_handle)
|
||||
{
|
||||
char cid[BUFSIZ];
|
||||
_Tt_string h, hostname;
|
||||
pid_t s;
|
||||
_Tt_string name = (char *)0;
|
||||
|
||||
if (0==parse_Xdisplay_string(dt_handle, h, s, hostname)) {
|
||||
return((char *)0);
|
||||
}
|
||||
sprintf(cid, "X %s %d", (char *)h, s);
|
||||
name = cid;
|
||||
return(name);
|
||||
}
|
||||
|
||||
_Tt_desktop_lock::
|
||||
_Tt_desktop_lock()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_desktop_lock::
|
||||
_Tt_desktop_lock( const _Tt_desktop_ptr &dt )
|
||||
{
|
||||
_dt = dt;
|
||||
if (! _dt.is_null()) {
|
||||
_dt->lock();
|
||||
}
|
||||
}
|
||||
|
||||
_Tt_desktop_lock::
|
||||
~_Tt_desktop_lock()
|
||||
{
|
||||
if (! _dt.is_null()) {
|
||||
_dt->unlock();
|
||||
}
|
||||
}
|
||||
73
cde/lib/tt/lib/mp/mp_desktop.h
Normal file
73
cde/lib/tt/lib/mp/mp_desktop.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_desktop.h /main/3 1995/10/23 10:23:14 rswiston $ */
|
||||
/*
|
||||
* mp_desktop.h 1.6 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_desktop.h
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef MP_DESKTOP_H
|
||||
#define MP_DESKTOP_H
|
||||
#include <setjmp.h>
|
||||
#include <mp/mp_global.h>
|
||||
#include <util/tt_object.h>
|
||||
|
||||
#if defined(ultrix)
|
||||
extern "C"
|
||||
{ extern struct XSizeHints;
|
||||
extern struct XStandardColormap;
|
||||
extern struct XTextProperty;
|
||||
extern struct XWMHints;
|
||||
extern struct XClassHint;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
enum _Tt_dt_type {
|
||||
_TT_DESKTOP_X11,
|
||||
_TT_DESKTOP_LAST
|
||||
};
|
||||
|
||||
typedef int (*_Tt_dt_errfn)(void *);
|
||||
|
||||
struct _Tt_desktop_private;
|
||||
|
||||
class _Tt_desktop : public _Tt_object {
|
||||
public:
|
||||
_Tt_desktop();
|
||||
virtual ~_Tt_desktop();
|
||||
int init(_Tt_string dt_handle, _Tt_dt_type t);
|
||||
int notify_fd();
|
||||
int process_event();
|
||||
int lock();
|
||||
int unlock();
|
||||
int set_prop(_Tt_string pname, _Tt_string &val);
|
||||
int del_prop(_Tt_string pname);
|
||||
int get_prop(_Tt_string pname, _Tt_string &val);
|
||||
_Tt_string session_name(_Tt_string dt_handle);
|
||||
void set_error_handler(_Tt_dt_errfn efn);
|
||||
private:
|
||||
int close();
|
||||
void restore_user_handler();
|
||||
static int io_error_proc(void *);
|
||||
int *user_io_handler;
|
||||
static jmp_buf io_exception;
|
||||
_Tt_desktop_private *priv;
|
||||
};
|
||||
|
||||
#include <mp/mp_desktop_utils.h>
|
||||
|
||||
class _Tt_desktop_lock : public _Tt_object {
|
||||
public:
|
||||
_Tt_desktop_lock();
|
||||
_Tt_desktop_lock( const _Tt_desktop_ptr &dt );
|
||||
virtual ~_Tt_desktop_lock();
|
||||
private:
|
||||
_Tt_desktop_ptr _dt;
|
||||
};
|
||||
|
||||
#endif /* MP_DESKTOP_H */
|
||||
16
cde/lib/tt/lib/mp/mp_desktop_utils.C
Normal file
16
cde/lib/tt/lib/mp/mp_desktop_utils.C
Normal file
@@ -0,0 +1,16 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_desktop_utils.C /main/3 1995/10/23 10:23:20 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_desktop_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <mp/mp_desktop.h>
|
||||
#include <mp/mp_desktop_utils.h>
|
||||
|
||||
implement_ptr_to(_Tt_desktop)
|
||||
implement_ptr_to(_Tt_desktop_lock)
|
||||
21
cde/lib/tt/lib/mp/mp_desktop_utils.h
Normal file
21
cde/lib/tt/lib/mp/mp_desktop_utils.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_desktop_utils.h /main/3 1995/10/23 10:23:27 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_desktop_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef MP_DESKTOP_UTILS_H
|
||||
#define MP_DESKTOP_UTILS_H
|
||||
|
||||
class _Tt_desktop;
|
||||
|
||||
declare_ptr_to(_Tt_desktop)
|
||||
declare_ptr_to(_Tt_desktop_lock)
|
||||
|
||||
|
||||
#endif /* MP_DESKTOP_UTILS_H */
|
||||
118
cde/lib/tt/lib/mp/mp_file.C
Normal file
118
cde/lib/tt/lib/mp/mp_file.C
Normal file
@@ -0,0 +1,118 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_file.C /main/3 1995/10/23 10:23:33 rswiston $
|
||||
/*
|
||||
*
|
||||
* @(#)mp_file.C 1.40 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_file.cc
|
||||
*
|
||||
* Copyright (c) 1990, 1991, 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Implementation of the _Tt_file class representing a document.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "api/c/api_api.h"
|
||||
#include "mp/mp_file.h"
|
||||
#include "mp/mp_mp.h"
|
||||
#include "util/tt_string.h"
|
||||
#include "util/tt_xdr_version.h"
|
||||
|
||||
_Tt_qmsg_info::_Tt_qmsg_info()
|
||||
{
|
||||
categories = new _Tt_int_rec_list;
|
||||
ptypes = new _Tt_string_list;
|
||||
version = TT_QMSG_INFO_VERSION;
|
||||
}
|
||||
|
||||
_Tt_qmsg_info::~_Tt_qmsg_info()
|
||||
{
|
||||
}
|
||||
|
||||
bool_t
|
||||
_Tt_qmsg_info::xdr(
|
||||
XDR *xdrs
|
||||
)
|
||||
{
|
||||
_Tt_xdr_version xvers(1);
|
||||
|
||||
return xdr_int( xdrs, &version )
|
||||
&& xdr_int( xdrs, &id )
|
||||
&& xdr_int( xdrs, &nparts )
|
||||
&& xdr_int( xdrs, &size )
|
||||
&& categories.xdr( xdrs )
|
||||
&& ptypes.xdr( xdrs )
|
||||
&& xdr_int( xdrs, &m_id )
|
||||
&& sender.xdr( xdrs );
|
||||
}
|
||||
|
||||
_Tt_file::_Tt_file()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_file::_Tt_file(
|
||||
const _Tt_string &path
|
||||
) :
|
||||
_Tt_db_file( path )
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_file::~_Tt_file()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// query - iterate through each node in this file and apply the given filter
|
||||
// to it. Returns one of the following codes:
|
||||
// TT_OK - successful
|
||||
// TT_ERR_DBAVAIL error occurred while accessing database
|
||||
// TT_WRN_STOPPED filter returns TT_FILTER_STOP
|
||||
// TT_ERR_INTERNAL
|
||||
//
|
||||
|
||||
Tt_status
|
||||
_Tt_file::query(
|
||||
_Tt_file_callback callback,
|
||||
Tt_filter_function filter,
|
||||
void *context,
|
||||
void *accumulator
|
||||
)
|
||||
{
|
||||
// Apply 'filter' function to each node belonging to this
|
||||
// file. If Filter returns FILTER_STOP then the query
|
||||
// function should return immediately.
|
||||
|
||||
_Tt_string_list_ptr specIDs = getObjects();
|
||||
_Tt_db_results dbStatus = getDBResults();
|
||||
switch (dbStatus) { // XXX
|
||||
case TT_DB_OK:
|
||||
break;
|
||||
case TT_DB_ERR_ILLEGAL_FILE:
|
||||
default:
|
||||
return TT_ERR_INTERNAL;
|
||||
}
|
||||
_Tt_string_list_cursor specID( specIDs );
|
||||
while (specID.next()) {
|
||||
if ( (*callback)( filter,
|
||||
(*specID).quote_nulls(),
|
||||
context,
|
||||
accumulator)
|
||||
== TT_FILTER_STOP)
|
||||
{
|
||||
return TT_WRN_STOPPED;
|
||||
}
|
||||
}
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
_Tt_string
|
||||
_Tt_file::networkPath_(
|
||||
_Tt_object_ptr &obj
|
||||
)
|
||||
{
|
||||
return ((_Tt_file *)obj.c_pointer())->getNetworkPath();
|
||||
}
|
||||
66
cde/lib/tt/lib/mp/mp_file.h
Normal file
66
cde/lib/tt/lib/mp/mp_file.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_file.h /main/3 1995/10/23 10:23:40 rswiston $ */
|
||||
/*
|
||||
* Tool Talk Message Passer (MP) - mp_file.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MP_FILE_H
|
||||
#define _MP_FILE_H
|
||||
|
||||
#include <mp/mp_global.h>
|
||||
#include <mp/mp_file_utils.h>
|
||||
#include <mp/mp_procid_utils.h>
|
||||
#include <mp/mp_message_utils.h>
|
||||
#include <mp/mp_session_utils.h>
|
||||
#include <db/tt_db_file.h>
|
||||
#include <util/tt_int_rec.h>
|
||||
|
||||
#define TT_QMSG_INFO_VERSION 1
|
||||
#define TT_FSCOPE_INFO_VERSION 1
|
||||
|
||||
typedef Tt_filter_action (*_Tt_file_callback)(
|
||||
Tt_filter_function fn,
|
||||
_Tt_string nodeid,
|
||||
void *context,
|
||||
void *accumulator
|
||||
);
|
||||
|
||||
class _Tt_qmsg_info : public _Tt_object {
|
||||
public:
|
||||
_Tt_qmsg_info();
|
||||
virtual ~_Tt_qmsg_info();
|
||||
int id;
|
||||
int nparts;
|
||||
int size;
|
||||
_Tt_int_rec_list_ptr categories;
|
||||
_Tt_string_list_ptr ptypes;
|
||||
bool_t xdr(XDR *xdrs);
|
||||
int version;
|
||||
int m_id; // message id
|
||||
_Tt_string sender; // message sender procid
|
||||
};
|
||||
|
||||
class _Tt_file : public _Tt_db_file {
|
||||
public:
|
||||
_Tt_file();
|
||||
_Tt_file( const _Tt_string &path );
|
||||
virtual ~_Tt_file();
|
||||
|
||||
Tt_status query(
|
||||
_Tt_file_callback fn,
|
||||
Tt_filter_function filter,
|
||||
void *context,
|
||||
void *accumulator
|
||||
);
|
||||
static _Tt_string networkPath_(
|
||||
_Tt_object_ptr &obj
|
||||
);
|
||||
};
|
||||
|
||||
#endif /* _MP_FILE_H */
|
||||
16
cde/lib/tt/lib/mp/mp_file_utils.C
Normal file
16
cde/lib/tt/lib/mp/mp_file_utils.C
Normal file
@@ -0,0 +1,16 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_file_utils.C /main/3 1995/10/23 10:23:49 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_file_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <mp/mp_file.h>
|
||||
|
||||
implement_list_of(_Tt_file)
|
||||
implement_table_of(_Tt_file)
|
||||
implement_ptr_to(_Tt_qmsg_info)
|
||||
26
cde/lib/tt/lib/mp/mp_file_utils.h
Normal file
26
cde/lib/tt/lib/mp/mp_file_utils.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_file_utils.h /main/3 1995/10/23 10:23:55 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_file_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Utilities declarations for _Tt_file
|
||||
*/
|
||||
#ifndef MP_FILE_UTILS_H
|
||||
#define MP_FILE_UTILS_H
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_string.h>
|
||||
#include <util/tt_list.h>
|
||||
#include <util/tt_table.h>
|
||||
|
||||
class _Tt_file;
|
||||
declare_list_of(_Tt_file)
|
||||
declare_table_of(_Tt_file)
|
||||
class _Tt_qmsg_info;
|
||||
declare_ptr_to(_Tt_qmsg_info)
|
||||
#endif /* MP_FILE_UTILS_H */
|
||||
47
cde/lib/tt/lib/mp/mp_global.h
Normal file
47
cde/lib/tt/lib/mp/mp_global.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_global.h /main/3 1995/10/23 10:24:02 rswiston $ */
|
||||
/*
|
||||
* mp.h -- public interface classes to the Message Passer
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef _MP_GLOBAL_H
|
||||
#define _MP_GLOBAL_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "util/tt_object.h"
|
||||
#include "util/tt_list.h"
|
||||
#include "util/tt_string.h"
|
||||
#include "mp/mp_xdr_functions.h"
|
||||
#include "api/c/tt_c.h"
|
||||
|
||||
#define _TT_TYPES_CE_VERSION 1
|
||||
#define _TT_XATOM_VERSION 1
|
||||
|
||||
class _Tt_mp;
|
||||
extern _Tt_mp *_tt_mp;
|
||||
|
||||
enum _Tt_mp_status {
|
||||
_MP_OK = TT_OK,
|
||||
_MP_ERR = TT_ERR_INTERNAL,
|
||||
_MP_NO_NODE = TT_ERR_OBJID,
|
||||
_MP_NO_VALUE = TT_ERR_NO_VALUE,
|
||||
_MP_STALE_NODEID = TT_WRN_STALE_OBJID,
|
||||
_MP_NODE_LOCKED = TT_STATUS_LAST + 1,
|
||||
_MP_ERR_TYPE = TT_ERR_OTYPE,
|
||||
_MP_ERR_DB = TT_ERR_DBAVAIL,
|
||||
_MP_ERR_DBOPEN = TT_ERR_DBAVAIL,
|
||||
_MP_ERR_ACCESS = TT_ERR_ACCESS
|
||||
};
|
||||
|
||||
|
||||
void dbg(char *fmt, char *f, int l, char *arg1 = (char *)0);
|
||||
#define DBG(msg) (dbg(msg, __FILE__, __LINE__))
|
||||
#define DBG1(fmt, arg1) (dbg(fmt, __FILE__, __LINE__, arg1))
|
||||
#define TRACE(msg) ((_tt_mp->trace) || ((msg) && (msg)->trace))
|
||||
#endif /* _MP_GLOBAL_H */
|
||||
6
cde/lib/tt/lib/mp/mp_lock_utils.C
Normal file
6
cde/lib/tt/lib/mp/mp_lock_utils.C
Normal file
@@ -0,0 +1,6 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_lock_utils.C /main/3 1995/10/23 10:24:09 rswiston $
|
||||
/* this file is obsolete and should be removed when convenient */
|
||||
6
cde/lib/tt/lib/mp/mp_lock_utils.h
Normal file
6
cde/lib/tt/lib/mp/mp_lock_utils.h
Normal file
@@ -0,0 +1,6 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_lock_utils.h /main/3 1995/10/23 10:24:16 rswiston $ */
|
||||
/* this file is obsolete and should be removed when convenient */
|
||||
1270
cde/lib/tt/lib/mp/mp_message.C
Normal file
1270
cde/lib/tt/lib/mp/mp_message.C
Normal file
File diff suppressed because it is too large
Load Diff
256
cde/lib/tt/lib/mp/mp_message.h
Normal file
256
cde/lib/tt/lib/mp/mp_message.h
Normal file
@@ -0,0 +1,256 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_message.h /main/3 1995/10/23 10:24:32 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_message.h 1.28 93/09/07
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_message.h
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file implements the _Tt_message object which represents the
|
||||
* message that is being sent and received by a process. The message
|
||||
* object in server mode implements the methods that are responsible for
|
||||
* delivering the message. Thus this is the heart of the message server.
|
||||
*/
|
||||
#ifndef _MP_MESSAGE_H
|
||||
#define _MP_MESSAGE_H
|
||||
#include <sys/types.h>
|
||||
#include "mp/mp_global.h"
|
||||
#include "mp/mp_arg_utils.h"
|
||||
#include "mp/mp_msg_context_utils.h"
|
||||
#include "mp/mp_message_utils.h"
|
||||
#include "mp/mp_pattern_utils.h"
|
||||
#include "mp/mp_procid_utils.h"
|
||||
#include "mp/mp_session_utils.h"
|
||||
#include "util/tt_iostream.h"
|
||||
|
||||
/*
|
||||
* The following enum defines bit masks used in xdr'ing a _Tt_message
|
||||
* structure. Since there are important cases where less fields need
|
||||
* to be transmitted (for example, whenever it is known that the
|
||||
* recipient has seen the message before, the entire structure need
|
||||
* not be transmitted) these bit fields control whether the relevant
|
||||
* piece of the _Tt_message struct is xdr'ed or not. For example, if
|
||||
* _TT_MSK_ID is off then the _id field of the _Tt_message isn't
|
||||
* transmitted.
|
||||
*/
|
||||
enum _Tt_message_ptr_masks {
|
||||
_TT_MSK_ID = (1<<0),
|
||||
_TT_MSK_MESSAGE_CLASS = (1<<1),
|
||||
_TT_MSK_STATE = (1<<2),
|
||||
_TT_MSK_PARADIGM = (1<<3),
|
||||
_TT_MSK_SCOPE = (1<<4),
|
||||
_TT_MSK_RELIABILITY = (1<<5),
|
||||
_TT_MSK_OPNUM = (1<<6),
|
||||
_TT_MSK_UID = (1<<7),
|
||||
_TT_MSK_GID = (1<<8),
|
||||
_TT_MSK_STATUS = (1<<9),
|
||||
_TT_MSK_FLAGS = (1<<10),
|
||||
_TT_MSK_SESSION = (1<<11),
|
||||
_TT_MSK_SENDER = (1<<12),
|
||||
_TT_MSK_HANDLER = (1<<13),
|
||||
_TT_MSK_FILE = (1<<14),
|
||||
_TT_MSK_OBJECT = (1<<15),
|
||||
_TT_MSK_OP = (1<<16),
|
||||
_TT_MSK_ARGS = (1<<17),
|
||||
_TT_MSK_OTYPE = (1<<18),
|
||||
_TT_MSK_SENDER_PTYPE = (1<<19),
|
||||
_TT_MSK_HANDLER_PTYPE = (1<<20),
|
||||
_TT_MSK_PATTERN_ID = (1<<21),
|
||||
_TT_MSK_RSESSIONS = (1<<22),
|
||||
_TT_MSK_STATUS_STRING = (1<<23),
|
||||
_TT_MSK_CONTEXTS = (1<<24),
|
||||
_TT_MSK_OFFEREES = (1<<25)
|
||||
};
|
||||
|
||||
#define SET_PTR_GUARD(test, msk)\
|
||||
if (test) (_ptr_guards) |= msk; else (_ptr_guards) &= ~(msk)
|
||||
|
||||
#define SET_GUARD(guard, test, msk)\
|
||||
if (test) (guard) |= msk; else (guard) &= ~(msk)
|
||||
|
||||
enum _Tt_message_flagbits {
|
||||
_TT_MSG_IS_REMOTE, /* message sender not in current session */
|
||||
_TT_MSG_OBSERVERS_ONLY, /* only attempt observer patterns */
|
||||
_TT_MSG_IS_SUPER, /* method invocation to parent class */
|
||||
_TT_MSG_UPDATE_XDR_MODE, /* message is being sent as an update */
|
||||
/* (used by the xdr method) */
|
||||
_TT_MSG_OBSERVERS_MATCH,
|
||||
_TT_MSG_IS_START_MSG,
|
||||
_TT_MSG_OBSERVER,
|
||||
_TT_MSG_AWAITING_REPLY
|
||||
};
|
||||
|
||||
class _Tt_message : public _Tt_object {
|
||||
public:
|
||||
void base_constructor();
|
||||
_Tt_message();
|
||||
virtual ~_Tt_message();
|
||||
/* getting message fields */
|
||||
|
||||
Tt_class message_class() const {
|
||||
return _message_class;
|
||||
}
|
||||
Tt_state state() const {
|
||||
return _state;
|
||||
}
|
||||
|
||||
Tt_scope scope() const {
|
||||
return _scope;
|
||||
}
|
||||
int opnum() const {
|
||||
return _opnum;
|
||||
}
|
||||
const _Tt_string &handler_ptype() const {
|
||||
return _handler_ptype;
|
||||
}
|
||||
Tt_disposition reliability() const {
|
||||
return _reliability;
|
||||
}
|
||||
|
||||
Tt_address paradigm() const {
|
||||
return _paradigm;
|
||||
}
|
||||
const _Tt_string &file() const {
|
||||
return _file;
|
||||
}
|
||||
const _Tt_session_ptr &session() const {
|
||||
return _session;
|
||||
}
|
||||
const _Tt_string &op() const {
|
||||
return _op;
|
||||
}
|
||||
const _Tt_arg_list_ptr &args() const {
|
||||
return _args;
|
||||
}
|
||||
_Tt_msg_context_ptr context(const char *slotname) const;
|
||||
_Tt_msg_context_ptr context(int i) const;
|
||||
int contextsCount() const;
|
||||
const _Tt_string &object() const {
|
||||
return _object;
|
||||
}
|
||||
const _Tt_string &otype() const {
|
||||
return _otype;
|
||||
}
|
||||
const _Tt_procid_ptr &sender() const {
|
||||
return _sender;
|
||||
}
|
||||
const _Tt_procid_ptr &handler() const {
|
||||
return _handler;
|
||||
}
|
||||
const _Tt_procid_list_ptr &abstainers() const {
|
||||
return _abstainers;
|
||||
}
|
||||
const _Tt_procid_list_ptr &accepters() const {
|
||||
return _accepters;
|
||||
}
|
||||
const _Tt_procid_list_ptr &rejecters() const {
|
||||
return _rejecters;
|
||||
}
|
||||
const _Tt_string &sender_ptype() const {
|
||||
return _sender_ptype;
|
||||
}
|
||||
int queue() const {
|
||||
return reliability() & TT_QUEUE;
|
||||
}
|
||||
int start() const {
|
||||
return reliability() & TT_START;
|
||||
}
|
||||
int id() const;
|
||||
const _Tt_string &api_id() const;
|
||||
uid_t uid() const;
|
||||
gid_t gid() const;
|
||||
int status() const {
|
||||
return _status;
|
||||
}
|
||||
_Tt_string &status_string();
|
||||
|
||||
/* setting message fields */
|
||||
Tt_status set_message_class(Tt_class mclass);
|
||||
Tt_status set_state(Tt_state state);
|
||||
Tt_status set_paradigm(Tt_address p);
|
||||
Tt_status set_scope(Tt_scope s);
|
||||
Tt_status set_file(_Tt_string file);
|
||||
Tt_status set_session(_Tt_session_ptr &s);
|
||||
Tt_status set_session(_Tt_string sessid);
|
||||
Tt_status set_op(_Tt_string op);
|
||||
Tt_status set_opnum(int o);
|
||||
Tt_status add_arg(_Tt_arg_ptr &arg);
|
||||
Tt_status add_context(_Tt_msg_context_ptr &context);
|
||||
Tt_status set_object(_Tt_string oid);
|
||||
Tt_status set_otype(_Tt_string ot);
|
||||
Tt_status set_sender(_Tt_procid_ptr &s);
|
||||
Tt_status set_handler_procid(const _Tt_procid_ptr &h);
|
||||
Tt_status unset_handler_procid(void);
|
||||
Tt_status add_voter(const _Tt_procid_ptr &p,
|
||||
Tt_state vote);
|
||||
Tt_status add_accepter(const _Tt_procid_ptr &p);
|
||||
Tt_status add_rejecter(const _Tt_procid_ptr &p);
|
||||
Tt_status set_sender_ptype(_Tt_string s);
|
||||
Tt_status set_handler_ptype(_Tt_string h);
|
||||
Tt_status set_reliability(Tt_disposition r);
|
||||
void set_super();
|
||||
Tt_status set_status(int st);
|
||||
Tt_status set_status_string(_Tt_string st);
|
||||
void set_start_message(int flag = 1);
|
||||
int is_start_message() const;
|
||||
void set_awaiting_reply(int flag = 1);
|
||||
int is_awaiting_reply() const;
|
||||
void print(const _Tt_ostream &sink) const;
|
||||
void update_message(const _Tt_message_ptr &m);
|
||||
int is_equal(const _Tt_message_ptr &m);
|
||||
void set_observer_procid(const _Tt_procid_ptr &h);
|
||||
void clr_observer_procid();
|
||||
int is_observer() {
|
||||
return(_flags&(1<<_TT_MSG_OBSERVER));
|
||||
}
|
||||
bool_t xdr(XDR *xdrs);
|
||||
_Tt_string &pattern_id();
|
||||
void set_pattern_id(_Tt_string id);
|
||||
Tt_status set_id();
|
||||
protected:
|
||||
void add_out_arg(_Tt_arg_ptr &arg);
|
||||
|
||||
_Tt_string _pattern_id;
|
||||
Tt_state _state;
|
||||
int _status;
|
||||
Tt_address _paradigm;
|
||||
Tt_scope _scope;
|
||||
Tt_disposition _reliability;
|
||||
int _opnum;
|
||||
_Tt_string _object;
|
||||
_Tt_string _file;
|
||||
_Tt_string _op;
|
||||
_Tt_string _otype;
|
||||
_Tt_session_ptr _session;
|
||||
_Tt_procid_ptr _sender;
|
||||
_Tt_procid_ptr _handler;
|
||||
_Tt_procid_list_ptr _abstainers;
|
||||
_Tt_procid_list_ptr _accepters;
|
||||
_Tt_procid_list_ptr _rejecters;
|
||||
_Tt_string _sender_ptype;
|
||||
_Tt_string _handler_ptype;
|
||||
_Tt_string_list_ptr _rsessions;
|
||||
int _id;
|
||||
_Tt_string _api_id;
|
||||
_Tt_arg_list_ptr _args;
|
||||
_Tt_arg_list_ptr _out_args;
|
||||
_Tt_msg_context_list_ptr _contexts;
|
||||
int _flags;
|
||||
int _ptr_guards;
|
||||
uid_t _uid;
|
||||
gid_t _gid;
|
||||
int _full_msg_guards;
|
||||
Tt_class _message_class;
|
||||
_Tt_string _status_string;
|
||||
|
||||
private:
|
||||
Tt_status _set_id(int id);
|
||||
};
|
||||
|
||||
bool_t tt_xdr_message(XDR *xdrs, _Tt_message_ptr *msgp);
|
||||
#endif /* _MP_MESSAGE_H */
|
||||
14
cde/lib/tt/lib/mp/mp_message_utils.C
Normal file
14
cde/lib/tt/lib/mp/mp_message_utils.C
Normal file
@@ -0,0 +1,14 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_message_utils.C /main/3 1995/10/23 10:24:39 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_message_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <mp/mp_message.h>
|
||||
|
||||
implement_list_of(_Tt_message)
|
||||
21
cde/lib/tt/lib/mp/mp_message_utils.h
Normal file
21
cde/lib/tt/lib/mp/mp_message_utils.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_message_utils.h /main/3 1995/10/23 10:24:47 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_message_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Utilities declarations for _Tt_message
|
||||
*/
|
||||
#ifndef MP_MESSAGE_UTILS_H
|
||||
#define MP_MESSAGE_UTILS_H
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_list.h>
|
||||
|
||||
class _Tt_message;
|
||||
declare_list_of(_Tt_message)
|
||||
#endif /* MP_MESSAGE_UTILS_H */
|
||||
293
cde/lib/tt/lib/mp/mp_mp.C
Normal file
293
cde/lib/tt/lib/mp/mp_mp.C
Normal file
@@ -0,0 +1,293 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_mp.C /main/7 1999/09/21 08:43:02 mgreess $
|
||||
/*
|
||||
*
|
||||
* mp_mp.cc -- Server and client state object for the Message Passer
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "mp/mp_global.h"
|
||||
#include "mp/mp_mp.h"
|
||||
#include "mp/mp_file.h"
|
||||
#include "mp/mp_session.h"
|
||||
#include "mp/mp_c_session.h"
|
||||
#include "mp/mp_procid.h"
|
||||
#include "mp/mp_rpc_client.h"
|
||||
#include "mp/mp_xdr_functions.h"
|
||||
#include "util/tt_base64.h"
|
||||
#include "util/tt_port.h"
|
||||
#include "util/tt_path.h"
|
||||
#include "api/c/api_error.h"
|
||||
#include <errno.h>
|
||||
#include <sys/resource.h>
|
||||
#include <malloc.h>
|
||||
#include "tt_options.h"
|
||||
|
||||
#if defined(_AIX)
|
||||
/* AIX's FD_ZERO macro uses bzero() without declaring it. */
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
//
|
||||
// This file contains methods for the _Tt_mp object which is an object
|
||||
// whose only function is to serve as a placeholder for global
|
||||
// data/objects relevant to the message-passer routines. Another major
|
||||
// use is to hold the various object caches that map object ids to a
|
||||
// single object of the given class.
|
||||
//
|
||||
// Really, the _Tt_mp object as we see it here should go away, being
|
||||
// replaced by _Tt_c_mp, which should represent the client's idea
|
||||
// of the ttsession server it's connected to, and _Tt_s_mp, which
|
||||
// represents the global state of a ttsession server.
|
||||
//
|
||||
|
||||
//
|
||||
// Global pointer to *the* _Tt_mp object. There should only be one
|
||||
// _Tt_mp object per tooltalk client.
|
||||
//
|
||||
_Tt_mp *_tt_mp = (_Tt_mp *)0;
|
||||
|
||||
//
|
||||
// Constructs a _Tt_mp object in the indicated mode.
|
||||
//
|
||||
_Tt_mp::
|
||||
_Tt_mp()
|
||||
{
|
||||
_flags = 0;
|
||||
FD_ZERO(&_session_fds);
|
||||
_session_cache = new _Tt_session_table(_tt_session_address);
|
||||
active_messages = 0;
|
||||
_current_message_id = _current_pattern_id = 0;
|
||||
active_procs = new _Tt_procid_table(_tt_procid_id, 50);
|
||||
}
|
||||
|
||||
_Tt_mp::
|
||||
~_Tt_mp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Returns the value of a counter and then increments the counter. Used
|
||||
// to make different messages sent by the same sender unique.
|
||||
//
|
||||
int _Tt_mp::
|
||||
generate_message_id()
|
||||
{
|
||||
return(_current_message_id++);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns the value of a counter and then increments the counter. Used
|
||||
// to make different patterns registered by the same sender unique.
|
||||
//
|
||||
int _Tt_mp::
|
||||
generate_pattern_id()
|
||||
{
|
||||
return(_current_pattern_id++);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Finds the _Tt_file object associated with the network pathname <path>.
|
||||
// Optionally creates the _Tt_file object. Returns:
|
||||
// TT_OK but: if (! createIfNot), then fp.is_null() is possible
|
||||
// TT_ERR_FILE
|
||||
// TT_ERR_PATH
|
||||
// TT_ERR_DBAVAIL
|
||||
// TT_ERR_DBEXIST
|
||||
// TT_ERR_INTERNAL can mean ENOMEM
|
||||
//
|
||||
Tt_status
|
||||
_Tt_mp::find_file(
|
||||
_Tt_string path,
|
||||
_Tt_file_ptr &file,
|
||||
int createIfNot
|
||||
)
|
||||
{
|
||||
_Tt_string network_path;
|
||||
if (_tt_is_network_path(path)) {
|
||||
network_path = path;
|
||||
}
|
||||
else {
|
||||
network_path = _Tt_db_file::getNetworkPath(path);
|
||||
}
|
||||
|
||||
if (_file_cache.is_null()) {
|
||||
if (!createIfNot) {
|
||||
return TT_OK;
|
||||
}
|
||||
else {
|
||||
_file_cache = new _Tt_file_table(_Tt_file::networkPath_);
|
||||
if (_file_cache.is_null()) {
|
||||
return TT_ERR_NOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
file = _file_cache->lookup( network_path );
|
||||
if (! file.is_null()) {
|
||||
return TT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get to this point, the file is not in the cache
|
||||
|
||||
Tt_status status = TT_OK;
|
||||
if (createIfNot) {
|
||||
file = new _Tt_file( path );
|
||||
if (file.is_null()) {
|
||||
return TT_ERR_NOMEM;
|
||||
}
|
||||
_Tt_db_results dbStatus = file->getDBResults();
|
||||
status = _tt_get_api_error( dbStatus, _TT_API_FILE );
|
||||
if (status == TT_OK) {
|
||||
_file_cache->insert( file );
|
||||
} else if (status == TT_ERR_INTERNAL) {
|
||||
_tt_syslog( 0, LOG_ERR,
|
||||
"_Tt_db_file::_Tt_db_file(): %d", dbStatus);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void _Tt_mp::remove_file(_Tt_string path)
|
||||
{
|
||||
_Tt_string network_path = _Tt_db_file::getNetworkPath(path);
|
||||
_file_cache->remove(network_path);
|
||||
}
|
||||
|
||||
void _Tt_mp::
|
||||
remove_session(_Tt_string id)
|
||||
{
|
||||
_session_cache->remove(id);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Attempts to find the _Tt_session object associated with the given
|
||||
// session id. If not found and create_ifnot is 1 then a new session is
|
||||
// created and initialized. When it is initialized, the auto_start
|
||||
// parameter is examined. If it is 1 then the new session will be
|
||||
// initialized with the c_init method that will do an auto-start of the
|
||||
// session if it isn't running. Otherwise, the "client_session_init"
|
||||
// method is used which just tries to connect to a running session.
|
||||
//
|
||||
// Note that the server does use _Tt_c_session since servers can
|
||||
// act as clients for one another when passing file scoped messages.
|
||||
//
|
||||
Tt_status _Tt_mp::
|
||||
find_session(_Tt_string id, _Tt_session_ptr &sp,
|
||||
int create_ifnot, int auto_start)
|
||||
{
|
||||
Tt_status result = TT_OK;
|
||||
|
||||
_Tt_session_ptr s;
|
||||
if (_session_cache->lookup(id,s)) {
|
||||
sp = s;
|
||||
result = TT_OK;
|
||||
} else {
|
||||
// If this is a session address, try the X session ID
|
||||
// XXX - this is a kludge to deal with X session
|
||||
// IDs now that we use addres_strings as the lookup
|
||||
// key. This should be removed if/when we expunge
|
||||
// our internal use of X session IDs.
|
||||
_Tt_session_table_cursor sc(_session_cache);
|
||||
|
||||
while (sc.next()) {
|
||||
if (sc->has_id(id)) {
|
||||
sp = *sc;
|
||||
|
||||
// Note: we return right here!
|
||||
return TT_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! create_ifnot || id.len() <= 0) {
|
||||
result = TT_ERR_SESSION;
|
||||
} else {
|
||||
_Tt_c_session_ptr s = new _Tt_c_session();
|
||||
|
||||
result = s->set_id(id);
|
||||
if (result != TT_OK) return result;
|
||||
|
||||
if (auto_start) result = s->c_init();
|
||||
if (result != TT_OK) return result;
|
||||
|
||||
if (result == TT_OK) result = s->client_session_init();
|
||||
if (result != TT_OK) return result;
|
||||
|
||||
_session_cache->insert(s);
|
||||
sp = s;
|
||||
result = TT_OK;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void _Tt_mp::
|
||||
save_session_fd(int fd)
|
||||
{
|
||||
FD_SET(fd, &_session_fds);
|
||||
}
|
||||
|
||||
|
||||
int _Tt_mp::
|
||||
find_session_by_fd(int fd, _Tt_session_ptr &sp)
|
||||
{
|
||||
_Tt_rpc_client_ptr rpc_client;
|
||||
_Tt_session_table_cursor sc(_session_cache);
|
||||
|
||||
while (sc.next()) {
|
||||
rpc_client = sc->_rpc_client;
|
||||
if (rpc_client->socket() == fd) {
|
||||
sp = *sc;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void _Tt_mp::
|
||||
check_if_sessions_alive()
|
||||
{
|
||||
fd_set s_fds;
|
||||
int fd, maxfds, n;
|
||||
timeval tmout;
|
||||
_Tt_session_ptr s;
|
||||
_Tt_string id;
|
||||
|
||||
tmout.tv_sec = 0;
|
||||
tmout.tv_usec = 0;
|
||||
s_fds = _session_fds;
|
||||
maxfds = _tt_getdtablesize();
|
||||
n = select(maxfds, (fd_set *) 0, &s_fds, (fd_set *) 0, &tmout);
|
||||
|
||||
if (n < 0) {
|
||||
return;
|
||||
}
|
||||
fd = 0;
|
||||
while (n > 0) {
|
||||
if (FD_ISSET(fd, &s_fds)) {
|
||||
if (! find_session_by_fd(fd, s)) {
|
||||
FD_CLR(fd, &_session_fds);
|
||||
} else if (s->ping() != TT_OK) {
|
||||
id = s->process_tree_id();
|
||||
_tt_mp->remove_session(id);
|
||||
FD_CLR(fd, &_session_fds);
|
||||
}
|
||||
n--;
|
||||
}
|
||||
fd++;
|
||||
}
|
||||
}
|
||||
65
cde/lib/tt/lib/mp/mp_mp.h
Normal file
65
cde/lib/tt/lib/mp/mp_mp.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $TOG: mp_mp.h /main/4 1999/09/17 18:29:12 mgreess $ */
|
||||
/*
|
||||
* mp_mp.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file implements the _Tt_mp object which represents the global
|
||||
* information for the MP component. There should only be one instance of
|
||||
* a _Tt_mp object in either server or client mode.
|
||||
*/
|
||||
#ifndef _MP_MP_H
|
||||
#define _MP_MP_H
|
||||
|
||||
#include "tt_options.h"
|
||||
#include "mp/mp_global.h"
|
||||
#include "util/tt_table.h"
|
||||
#include "mp/mp_file_utils.h"
|
||||
#include "mp/mp_procid_utils.h"
|
||||
#include "mp/mp_session_utils.h"
|
||||
|
||||
enum _Tt_mp_flags {
|
||||
_TT_MP_IN_SERVER,
|
||||
_TT_MP_INIT_DONE
|
||||
};
|
||||
|
||||
class _Tt_mp : public _Tt_object {
|
||||
public:
|
||||
_Tt_mp();
|
||||
virtual ~_Tt_mp();
|
||||
int in_server() {
|
||||
return(_flags&(1<<_TT_MP_IN_SERVER));
|
||||
};
|
||||
Tt_status find_file(_Tt_string path,
|
||||
_Tt_file_ptr &f,
|
||||
int create_ifnot);
|
||||
void remove_file(_Tt_string path);
|
||||
void remove_session(_Tt_string id);
|
||||
void save_session_fd(int fd);
|
||||
int find_session_by_fd(int fd, _Tt_session_ptr &sp);
|
||||
void check_if_sessions_alive();
|
||||
int generate_pattern_id(); int generate_message_id();
|
||||
_Tt_session_ptr initial_session;
|
||||
|
||||
int active_messages;
|
||||
Tt_status find_session(_Tt_string id,
|
||||
_Tt_session_ptr &sp,
|
||||
int create_ifnot,
|
||||
int auto_start = 0);
|
||||
_Tt_procid_table_ptr active_procs;
|
||||
|
||||
|
||||
protected:
|
||||
int _current_message_id;
|
||||
int _current_pattern_id;
|
||||
_Tt_file_table_ptr _file_cache;
|
||||
_Tt_session_table_ptr _session_cache;
|
||||
int _flags;
|
||||
fd_set _session_fds;
|
||||
};
|
||||
|
||||
#endif /* _MP_MP_H */
|
||||
17
cde/lib/tt/lib/mp/mp_mp_utils.C
Normal file
17
cde/lib/tt/lib/mp/mp_mp_utils.C
Normal file
@@ -0,0 +1,17 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_mp_utils.C /main/3 1995/10/23 10:25:08 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_mp_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
/*
|
||||
* #include <mp/mp.h>
|
||||
*
|
||||
* implement_ptr_to(_Tt_mp);
|
||||
*
|
||||
*/
|
||||
114
cde/lib/tt/lib/mp/mp_msg_context.C
Normal file
114
cde/lib/tt/lib/mp/mp_msg_context.C
Normal file
@@ -0,0 +1,114 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_msg_context.C /main/3 1995/10/23 10:25:15 rswiston $
|
||||
/*
|
||||
* @(#)mp_msg_context.C 1.14 94/11/17
|
||||
*
|
||||
* @(#)mp_msg_context.C 1.9 93/09/07
|
||||
*
|
||||
* Implementation of the _Tt_msg_context: a context slot in a message.
|
||||
*/
|
||||
|
||||
#include "mp/mp_arg.h"
|
||||
#include "mp/mp_msg_context.h"
|
||||
#include "util/tt_iostream.h"
|
||||
|
||||
_Tt_msg_context::_Tt_msg_context()
|
||||
{
|
||||
_value = new _Tt_arg;
|
||||
}
|
||||
|
||||
_Tt_msg_context::~_Tt_msg_context()
|
||||
{
|
||||
}
|
||||
|
||||
Tt_status
|
||||
_Tt_msg_context::setValue(
|
||||
const _Tt_string &value
|
||||
)
|
||||
{
|
||||
_value->set_mode( TT_INOUT );
|
||||
_value->set_type( "string" );
|
||||
return _value->set_data_string( value );
|
||||
}
|
||||
|
||||
Tt_status
|
||||
_Tt_msg_context::setValue(
|
||||
int value
|
||||
)
|
||||
{
|
||||
_value->set_mode( TT_INOUT );
|
||||
_value->set_type( "integer" );
|
||||
return _value->set_data_int( value );
|
||||
}
|
||||
|
||||
int
|
||||
_Tt_msg_context::isEnvEntry() const
|
||||
{
|
||||
if (_slotName.len() == 0) {
|
||||
return 0;
|
||||
}
|
||||
return _slotName[0] == '$';
|
||||
}
|
||||
|
||||
_Tt_string
|
||||
_Tt_msg_context::enVarName() const
|
||||
{
|
||||
_Tt_string name( ((char *)_slotName)+1 );
|
||||
return name;
|
||||
}
|
||||
|
||||
_Tt_string
|
||||
_Tt_msg_context::stringRep() const
|
||||
{
|
||||
_Tt_string rep;
|
||||
char temp[ 20 ];
|
||||
switch (_value->data_type()) {
|
||||
case _Tt_arg::UNSET:
|
||||
break;
|
||||
case _Tt_arg::STRING:
|
||||
rep = _value->data_string();
|
||||
break;
|
||||
case _Tt_arg::INT:
|
||||
sprintf( temp, "%d", _value->data_int());
|
||||
rep = temp;
|
||||
break;
|
||||
}
|
||||
return rep;
|
||||
}
|
||||
|
||||
void
|
||||
_Tt_msg_context::print(
|
||||
const _Tt_ostream &os
|
||||
) const
|
||||
{
|
||||
_Tt_context::print( os );
|
||||
os << ": ";
|
||||
if (!_value.is_null()) {
|
||||
_value->print( os );
|
||||
} else {
|
||||
os << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_Tt_msg_context::print_(
|
||||
const _Tt_ostream &os,
|
||||
const _Tt_object *obj
|
||||
)
|
||||
{
|
||||
((_Tt_msg_context *)obj)->print( os );
|
||||
}
|
||||
|
||||
bool_t
|
||||
_Tt_msg_context::xdr(
|
||||
XDR *xdrs
|
||||
)
|
||||
{
|
||||
if (! _Tt_context::xdr( xdrs )) {
|
||||
return 0;
|
||||
}
|
||||
return _value.xdr( xdrs );
|
||||
}
|
||||
57
cde/lib/tt/lib/mp/mp_msg_context.h
Normal file
57
cde/lib/tt/lib/mp/mp_msg_context.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_msg_context.h /main/3 1995/10/23 10:25:23 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_msg_context.h 1.6 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_msg_context.h
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* _Tt_msg_context is a context slot in a message.
|
||||
*/
|
||||
|
||||
#ifndef _MP_MSG_CONTEXT_H
|
||||
#define _MP_MSG_CONTEXT_H
|
||||
|
||||
#include <mp/mp_context.h>
|
||||
#include <mp/mp_msg_context_utils.h>
|
||||
#include <mp/mp_arg_utils.h>
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
class _Tt_msg_context : public _Tt_context {
|
||||
public:
|
||||
_Tt_msg_context();
|
||||
virtual ~_Tt_msg_context();
|
||||
|
||||
Tt_status setValue(
|
||||
const _Tt_string &value
|
||||
);
|
||||
Tt_status setValue(
|
||||
int value
|
||||
);
|
||||
int isEnvEntry() const;
|
||||
_Tt_string enVarName() const;
|
||||
_Tt_string stringRep() const;
|
||||
|
||||
void print(
|
||||
const _Tt_ostream &os
|
||||
) const;
|
||||
static void print_(
|
||||
const _Tt_ostream &os,
|
||||
const _Tt_object *obj
|
||||
);
|
||||
bool_t xdr(
|
||||
XDR *xdrs
|
||||
);
|
||||
|
||||
const _Tt_arg &value() const {return *_value;}
|
||||
|
||||
private:
|
||||
_Tt_arg_ptr _value;
|
||||
};
|
||||
|
||||
#endif /* _MP_MSG_CONTEXT_H */
|
||||
26
cde/lib/tt/lib/mp/mp_msg_context_utils.C
Normal file
26
cde/lib/tt/lib/mp/mp_msg_context_utils.C
Normal file
@@ -0,0 +1,26 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_msg_context_utils.C /main/3 1995/10/23 10:25:31 rswiston $
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_msg_context_utils.C 1.5 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_msg_context_utils.cc
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <mp/mp_msg_context.h>
|
||||
#include <mp/mp_context_utils.h>
|
||||
#include <mp/mp_msg_context_utils.h>
|
||||
|
||||
implement_list_of(_Tt_msg_context)
|
||||
|
||||
_Tt_msg_context_list & _Tt_msg_context_list::
|
||||
append_ordered(const _Tt_msg_context_ptr &e)
|
||||
{
|
||||
return (_Tt_msg_context_list &)this->_Tt_context_list::append_ordered(e);
|
||||
}
|
||||
|
||||
21
cde/lib/tt/lib/mp/mp_msg_context_utils.h
Normal file
21
cde/lib/tt/lib/mp/mp_msg_context_utils.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_msg_context_utils.h /main/3 1995/10/23 10:25:39 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_msg_context_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef MP_MSG_CONTEXT_UTILS_H
|
||||
#define MP_MSG_CONTEXT_UTILS_H
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_list.h>
|
||||
#include <mp/mp_context_utils.h>
|
||||
|
||||
class _Tt_msg_context;
|
||||
declare_derived_list_of(_Tt_msg_context,_Tt_context)
|
||||
|
||||
#endif /* MP_MSG_CONTEXT_UTILS_H */
|
||||
6
cde/lib/tt/lib/mp/mp_node.C
Normal file
6
cde/lib/tt/lib/mp/mp_node.C
Normal file
@@ -0,0 +1,6 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_node.C /main/3 1995/10/23 10:25:47 rswiston $
|
||||
/* This file is obsolete and should be removed when convenient */
|
||||
6
cde/lib/tt/lib/mp/mp_node.h
Normal file
6
cde/lib/tt/lib/mp/mp_node.h
Normal file
@@ -0,0 +1,6 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_node.h /main/3 1995/10/23 10:25:55 rswiston $ */
|
||||
/* This file is obsolete and should be removed when convenient */
|
||||
6
cde/lib/tt/lib/mp/mp_node_utils.C
Normal file
6
cde/lib/tt/lib/mp/mp_node_utils.C
Normal file
@@ -0,0 +1,6 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_node_utils.C /main/3 1995/10/23 10:26:02 rswiston $
|
||||
/* this file is obsolete and should be removed when convenient */
|
||||
6
cde/lib/tt/lib/mp/mp_node_utils.h
Normal file
6
cde/lib/tt/lib/mp/mp_node_utils.h
Normal file
@@ -0,0 +1,6 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_node_utils.h /main/3 1995/10/23 10:26:10 rswiston $ */
|
||||
/* this file is obsolete and should be removed when convenient */
|
||||
137
cde/lib/tt/lib/mp/mp_pat_context.C
Normal file
137
cde/lib/tt/lib/mp/mp_pat_context.C
Normal file
@@ -0,0 +1,137 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_pat_context.C /main/3 1995/10/23 10:26:16 rswiston $
|
||||
/*
|
||||
*
|
||||
* @(#)mp_pat_context.C 1.9 93/09/07
|
||||
*
|
||||
* Tool Talk Pattern Passer (MP) - mp_pat_context.cc
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Implementation of the _Tt_pat_context: a context slot in a pattern.
|
||||
*/
|
||||
|
||||
#include "mp/mp_arg.h"
|
||||
#include "mp/mp_msg_context.h"
|
||||
#include "mp/mp_pat_context.h"
|
||||
#include "util/tt_iostream.h"
|
||||
|
||||
_Tt_pat_context::
|
||||
_Tt_pat_context()
|
||||
{
|
||||
_values = new _Tt_arg_list;
|
||||
}
|
||||
|
||||
_Tt_pat_context::
|
||||
_Tt_pat_context(const _Tt_context &c) : _Tt_context(c)
|
||||
{
|
||||
_values = new _Tt_arg_list;
|
||||
}
|
||||
|
||||
_Tt_pat_context::
|
||||
~_Tt_pat_context()
|
||||
{
|
||||
}
|
||||
|
||||
Tt_status _Tt_pat_context::
|
||||
addValue(
|
||||
const _Tt_string &value
|
||||
)
|
||||
{
|
||||
_Tt_arg_ptr newVal = new _Tt_arg( TT_INOUT, "string" );
|
||||
if (newVal.is_null()) {
|
||||
return TT_ERR_NOMEM;
|
||||
}
|
||||
Tt_status status = newVal->set_data_string( value );
|
||||
if (status != TT_OK) {
|
||||
return status;
|
||||
}
|
||||
_values->append( newVal );
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
Tt_status _Tt_pat_context::
|
||||
addValue(
|
||||
int value
|
||||
)
|
||||
{
|
||||
_Tt_arg_ptr newVal = new _Tt_arg( TT_INOUT, "integer" );
|
||||
if (newVal.is_null()) {
|
||||
return TT_ERR_NOMEM;
|
||||
}
|
||||
Tt_status status = newVal->set_data_int( value );
|
||||
if (status != TT_OK) {
|
||||
return status;
|
||||
}
|
||||
_values->append( newVal );
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
Tt_status _Tt_pat_context::
|
||||
addValue(
|
||||
const _Tt_msg_context &msgCntxt
|
||||
)
|
||||
{
|
||||
_Tt_arg_ptr newVal = new _Tt_arg( msgCntxt.value() );
|
||||
if (newVal.is_null()) {
|
||||
return TT_ERR_NOMEM;
|
||||
}
|
||||
_values->append( newVal );
|
||||
return TT_OK;
|
||||
}
|
||||
|
||||
Tt_status _Tt_pat_context::
|
||||
deleteValue(
|
||||
const _Tt_msg_context &msgCntxt
|
||||
)
|
||||
{
|
||||
_Tt_arg_list_cursor argC( _values );
|
||||
while (argC.next()) {
|
||||
if (msgCntxt.value() == **argC) {
|
||||
argC.remove();
|
||||
return TT_OK;
|
||||
}
|
||||
}
|
||||
return TT_WRN_NOTFOUND;
|
||||
}
|
||||
|
||||
void _Tt_pat_context::
|
||||
print(
|
||||
const _Tt_ostream &os
|
||||
) const
|
||||
{
|
||||
_Tt_context::print( os );
|
||||
os << ":\n";
|
||||
if (! _values.is_null()) {
|
||||
_Tt_string indent = os.indent();
|
||||
os.set_indent( indent.cat( "\t" ));
|
||||
_Tt_arg_list_cursor argC( _values );
|
||||
while (argC.next()) {
|
||||
argC->print( os );
|
||||
}
|
||||
os.set_indent( indent );
|
||||
}
|
||||
}
|
||||
|
||||
void _Tt_pat_context::
|
||||
print_(
|
||||
const _Tt_ostream &os,
|
||||
const _Tt_object *obj
|
||||
)
|
||||
{
|
||||
((_Tt_pat_context *)obj)->print( os );
|
||||
}
|
||||
|
||||
bool_t _Tt_pat_context::
|
||||
xdr(
|
||||
XDR *xdrs
|
||||
)
|
||||
{
|
||||
if (! _Tt_context::xdr( xdrs )) {
|
||||
return 0;
|
||||
}
|
||||
return _values.xdr( xdrs );
|
||||
}
|
||||
60
cde/lib/tt/lib/mp/mp_pat_context.h
Normal file
60
cde/lib/tt/lib/mp/mp_pat_context.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_pat_context.h /main/3 1995/10/23 10:26:23 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_pat_context.h 1.4 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_pat_context.h
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* _Tt_pat_context is a context slot in a pattern.
|
||||
*/
|
||||
|
||||
#ifndef _MP_PAT_CONTEXT_H
|
||||
#define _MP_PAT_CONTEXT_H
|
||||
|
||||
#include <mp/mp_context.h>
|
||||
#include <mp/mp_pat_context_utils.h>
|
||||
#include <mp/mp_msg_context.h>
|
||||
#include <mp/mp_arg_utils.h>
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
class _Tt_pat_context : public _Tt_context {
|
||||
public:
|
||||
_Tt_pat_context();
|
||||
_Tt_pat_context(const _Tt_context &);
|
||||
virtual ~_Tt_pat_context();
|
||||
|
||||
Tt_status addValue(
|
||||
const _Tt_string &value
|
||||
);
|
||||
Tt_status addValue(
|
||||
int value
|
||||
);
|
||||
Tt_status addValue(
|
||||
const _Tt_msg_context &msgCntxt
|
||||
);
|
||||
Tt_status deleteValue(
|
||||
const _Tt_msg_context &msgCntxt
|
||||
);
|
||||
|
||||
void print(
|
||||
const _Tt_ostream &os
|
||||
) const;
|
||||
static void print_(
|
||||
const _Tt_ostream &os,
|
||||
const _Tt_object *obj
|
||||
);
|
||||
bool_t xdr(
|
||||
XDR *xdrs
|
||||
);
|
||||
|
||||
protected:
|
||||
_Tt_arg_list_ptr _values;
|
||||
};
|
||||
|
||||
#endif /* _MP_PAT_CONTEXT_H */
|
||||
26
cde/lib/tt/lib/mp/mp_pat_context_utils.C
Normal file
26
cde/lib/tt/lib/mp/mp_pat_context_utils.C
Normal file
@@ -0,0 +1,26 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_pat_context_utils.C /main/3 1995/10/23 10:26:29 rswiston $
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_pat_context_utils.C 1.4 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_pat_context_utils.cc
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <mp/mp_pat_context.h>
|
||||
#include <mp/mp_context_utils.h>
|
||||
#include <mp/mp_pat_context_utils.h>
|
||||
|
||||
implement_list_of(_Tt_pat_context)
|
||||
|
||||
_Tt_pat_context_list & _Tt_pat_context_list::
|
||||
append_ordered(const _Tt_pat_context_ptr &e)
|
||||
{
|
||||
return (_Tt_pat_context_list &)this->_Tt_context_list::append_ordered(e);
|
||||
}
|
||||
|
||||
27
cde/lib/tt/lib/mp/mp_pat_context_utils.h
Normal file
27
cde/lib/tt/lib/mp/mp_pat_context_utils.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_pat_context_utils.h /main/3 1995/10/23 10:26:36 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_pat_context_utils.h 1.4 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_pat_context_utils.h
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* _Tt_pat_context is a context slot in a pattern.
|
||||
*/
|
||||
|
||||
#ifndef MP_PAT_CONTEXT_UTILS_H
|
||||
#define MP_PAT_CONTEXT_UTILS_H
|
||||
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_list.h>
|
||||
#include <mp/mp_context_utils.h>
|
||||
|
||||
class _Tt_pat_context;
|
||||
declare_derived_list_of(_Tt_pat_context,_Tt_context)
|
||||
|
||||
#endif /* MP_PAT_CONTEXT_UTILS_H */
|
||||
459
cde/lib/tt/lib/mp/mp_pattern.C
Normal file
459
cde/lib/tt/lib/mp/mp_pattern.C
Normal file
@@ -0,0 +1,459 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_pattern.C /main/5 1999/10/14 18:48:24 mgreess $
|
||||
/*
|
||||
*
|
||||
* @(#)mp_pattern.C 1.28 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_pattern.cc
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include "api/c/api_spec_map_ref.h"
|
||||
#include "mp/mp_global.h"
|
||||
#include "mp/mp_arg.h"
|
||||
#include "mp/mp_pat_context.h"
|
||||
#include "mp/mp_mp.h"
|
||||
#include "mp/mp_pattern.h"
|
||||
#include "mp/mp_message.h"
|
||||
#include "mp/mp_session.h"
|
||||
#include "mp/mp_xdr_functions.h"
|
||||
#include "util/tt_enumname.h"
|
||||
#include "util/tt_global_env.h"
|
||||
#include "util/tt_port.h"
|
||||
|
||||
//
|
||||
// Base constructor for _Tt_pattern objects. Should be called by all
|
||||
// other _Tt_pattern constructors.
|
||||
//
|
||||
void _Tt_pattern::
|
||||
base_constructor()
|
||||
{
|
||||
server_callback = 0;
|
||||
_category = TT_CATEGORY_LAST;
|
||||
_classes = 0;
|
||||
_paradigms = 0;
|
||||
_reliabilities = 0;
|
||||
_scopes = 0;
|
||||
_states = 0;
|
||||
_files = new _Tt_string_list();
|
||||
_handler_ptypes = new _Tt_string_list();
|
||||
_handlers = new _Tt_string_list();
|
||||
_objects = new _Tt_string_list();
|
||||
_observer_ptypes = new _Tt_string_list();
|
||||
_opnums = new _Tt_int_rec_list();
|
||||
_ops = new _Tt_string_list();
|
||||
_args = new _Tt_arg_list();
|
||||
_contexts = new _Tt_pat_context_list;
|
||||
_otypes = new _Tt_string_list();
|
||||
_sender_ptypes = new _Tt_string_list();
|
||||
_senders = new _Tt_string_list();
|
||||
_sessions = new _Tt_string_list();
|
||||
_flags = 0;
|
||||
}
|
||||
|
||||
_Tt_pattern::
|
||||
~_Tt_pattern()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Deletes the given argument from the _files field of this object.
|
||||
//
|
||||
Tt_status _Tt_pattern::
|
||||
del_file(const _Tt_string &f)
|
||||
{
|
||||
_Tt_string_list_cursor fcursor(_files);
|
||||
|
||||
while (fcursor.next()) {
|
||||
if (*fcursor == f) {
|
||||
fcursor.remove();
|
||||
}
|
||||
}
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Deletes the given argument from the _sessions field of this object.
|
||||
//
|
||||
Tt_status _Tt_pattern::
|
||||
del_session(const _Tt_string &s)
|
||||
{
|
||||
_Tt_string_list_cursor scursor(_sessions);
|
||||
|
||||
while (scursor.next()) {
|
||||
if (*scursor == s) {
|
||||
scursor.remove();
|
||||
}
|
||||
}
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Adds the given object id to the _objects field. Will return
|
||||
// TT_WRN_STALE_OBJID if the oid is a stale object id.
|
||||
//
|
||||
Tt_status _Tt_pattern::
|
||||
add_object(const _Tt_string &oid)
|
||||
{
|
||||
_Tt_api_spec_map_ref spec_map;
|
||||
_Tt_objid_spec_ptr spec = spec_map.getSpec(oid);
|
||||
Tt_status status;
|
||||
|
||||
if (spec.is_null()) {
|
||||
return(TT_ERR_OBJID);
|
||||
}
|
||||
|
||||
switch (spec->getDBResults()) {
|
||||
case TT_DB_OK:
|
||||
status = TT_OK;
|
||||
break;
|
||||
case TT_DB_WRN_FORWARD_POINTER:
|
||||
status = TT_WRN_STALE_OBJID;
|
||||
break;
|
||||
default:
|
||||
return(TT_ERR_OBJID);
|
||||
}
|
||||
add_field(oid, _objects);
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Generic function for adding an integer to a _Tt_int_rec_list if it
|
||||
// isn't already there.
|
||||
//
|
||||
void _Tt_pattern::
|
||||
add_field(int v, _Tt_int_rec_list_ptr &vlist)
|
||||
{
|
||||
_Tt_int_rec_list_cursor c(vlist);
|
||||
|
||||
while (c.next()) {
|
||||
if (c->val == v) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
vlist->push(new _Tt_int_rec((int)v));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Generic function for adding a string to a _Tt_string_list if it
|
||||
// isn't already there.
|
||||
//
|
||||
void _Tt_pattern::
|
||||
add_field(const _Tt_string &v, _Tt_string_list_ptr &vlist)
|
||||
{
|
||||
_Tt_string_list_cursor c(vlist);
|
||||
|
||||
while (c.next()) {
|
||||
if (*c == v) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
vlist->push(v);
|
||||
}
|
||||
|
||||
|
||||
_Tt_pat_context_ptr _Tt_pattern::
|
||||
context(const char *slotname) const
|
||||
{
|
||||
_Tt_pat_context_list_cursor contextC( _contexts );
|
||||
while (contextC.next()) {
|
||||
if (contextC->slotName() == slotname) {
|
||||
return *contextC;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
_Tt_pat_context_ptr _Tt_pattern::
|
||||
context(int i) const
|
||||
{
|
||||
if ((i >= 0) && (i < _contexts->count())) {
|
||||
return (*_contexts)[ i ];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int _Tt_pattern::
|
||||
contextsCount() const
|
||||
{
|
||||
if (_contexts.is_null()) {
|
||||
return 0;
|
||||
}
|
||||
return _contexts->count();
|
||||
}
|
||||
|
||||
Tt_status
|
||||
_Tt_pattern::add_netfile(
|
||||
const _Tt_string &filepath,
|
||||
int fallback_2_local_netfile
|
||||
)
|
||||
{
|
||||
_Tt_string abspath;
|
||||
Tt_status status = TT_OK;
|
||||
int __scopes = scopes();
|
||||
|
||||
if ((__scopes&(1<<TT_FILE)) || (__scopes&(1<<TT_BOTH))) {
|
||||
abspath = _Tt_db_file::getNetworkPath(filepath);
|
||||
if ((abspath.len() == 0) && (! fallback_2_local_netfile)) {
|
||||
return TT_ERR_FILE;
|
||||
}
|
||||
}
|
||||
if (abspath.len() == 0) {
|
||||
abspath = _tt_local_network_path(filepath);
|
||||
if (abspath.len() == 0) {
|
||||
return TT_ERR_FILE;
|
||||
}
|
||||
}
|
||||
return(add_file(abspath));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// XDR encodes/decodes a pattern.
|
||||
//
|
||||
bool_t _Tt_pattern::
|
||||
xdr(XDR *xdrs)
|
||||
{
|
||||
if (! tt_xdr_string(xdrs, &_pattern_id)) {
|
||||
return(0);
|
||||
}
|
||||
if (! xdr_int(xdrs, (int *)&_category)) {
|
||||
return(0);
|
||||
}
|
||||
if (! xdr_int(xdrs, (int *)&_classes)) {
|
||||
return(0);
|
||||
}
|
||||
if (! xdr_int(xdrs, (int *)&_states)) {
|
||||
return(0);
|
||||
}
|
||||
if (! xdr_int(xdrs, (int *)&_paradigms)) {
|
||||
return(0);
|
||||
}
|
||||
if (! xdr_int(xdrs, (int *)&_scopes)) {
|
||||
return(0);
|
||||
}
|
||||
if (! xdr_int(xdrs, (int *)&_reliabilities)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _files.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _sessions.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _ops.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _opnums.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _objects.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _otypes.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _senders.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _handlers.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _sender_ptypes.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _handler_ptypes.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (! _args.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
if (_tt_global->xdr_version() >= TT_CONTEXTS_XDR_VERSION) {
|
||||
if (! _contexts.xdr(xdrs)) {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Function wrapper so that the xdr method for a pattern can be invoked
|
||||
// from the C RPC interface.
|
||||
//
|
||||
bool_t tt_xdr_pattern(XDR *xdrs, _Tt_pattern_ptr *pat)
|
||||
{
|
||||
return((*pat)->xdr(xdrs));
|
||||
}
|
||||
|
||||
//
|
||||
// methods and functions associated with printing patterns
|
||||
//
|
||||
|
||||
static const char *
|
||||
int_to_class(int r)
|
||||
{
|
||||
return(_tt_enumname((Tt_class)r));
|
||||
}
|
||||
|
||||
static const char *
|
||||
int_to_paradigm(int r)
|
||||
{
|
||||
return(_tt_enumname((Tt_address) r));
|
||||
}
|
||||
|
||||
static const char *
|
||||
int_to_state(int r)
|
||||
{
|
||||
return(_tt_enumname((Tt_state) r));
|
||||
}
|
||||
|
||||
static const char *
|
||||
int_to_scope(int r)
|
||||
{
|
||||
return(_tt_enumname((Tt_scope) r));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Used to print out a generic list of integers. The given conversion
|
||||
// function ppfn returns an appropiate string to print for each integer.
|
||||
// See all the int_to_* functions above.
|
||||
//
|
||||
static void
|
||||
print_enum_mask(const _Tt_ostream &os, int start, int end, int mask,
|
||||
const char *(*ppfn)(int a))
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=start;i <= end;i++) {
|
||||
if (mask&(1<<i)) {
|
||||
os << (*ppfn)(i) << " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Used by the generic list and table packages to print out elements.
|
||||
// Should not be used otherwise.
|
||||
//
|
||||
void
|
||||
_tt_int_rec_print(const _Tt_ostream &os, const _Tt_object *obj)
|
||||
{
|
||||
((_Tt_int_rec *)obj)->print(os);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Prints out a pattern object. Used for debugging and for printing out
|
||||
// patterns being considered when tracing is turned on.
|
||||
//
|
||||
void _Tt_pattern::
|
||||
print(const _Tt_ostream &os) const
|
||||
{
|
||||
os << "id:\t\t";
|
||||
os << _pattern_id << "\n";
|
||||
os << "category:\t" << _tt_enumname(_category) << "\n";
|
||||
if (_classes != 0) {
|
||||
os << "classes:\t";
|
||||
print_enum_mask(os,(int)TT_CLASS_UNDEFINED,(int)TT_CLASS_LAST,
|
||||
_classes, int_to_class);
|
||||
os << "\n";
|
||||
}
|
||||
if (_states != 0) {
|
||||
os << "states:\t\t";
|
||||
print_enum_mask(os,(int)TT_CREATED, (int)TT_STATE_LAST,
|
||||
_states, int_to_state);
|
||||
os << "\n";
|
||||
}
|
||||
if (_paradigms != 0) {
|
||||
os << "addresses:\t";
|
||||
print_enum_mask(os,(int)TT_PROCEDURE,(int)TT_HANDLER,
|
||||
_paradigms, int_to_paradigm);
|
||||
os << "\n";
|
||||
}
|
||||
if (_scopes != 0) {
|
||||
os << "scopes:\t\t";
|
||||
print_enum_mask(os,(int)TT_SCOPE_NONE,(int)TT_FILE_IN_SESSION,
|
||||
_scopes, int_to_scope);
|
||||
os << "\n";
|
||||
}
|
||||
if (_files->count()) {
|
||||
os << "files:\t\t";
|
||||
_files->print(_tt_string_print, os);
|
||||
os << "\n";
|
||||
}
|
||||
if (_sessions->count()) {
|
||||
os << "sessions:\t";
|
||||
_sessions->print(_tt_string_print, os);
|
||||
os << "\n";
|
||||
}
|
||||
if (_ops->count()) {
|
||||
os << "ops:\t\t";
|
||||
_ops->print(_tt_string_print, os);
|
||||
os << "\n";
|
||||
}
|
||||
if (_args->count()) {
|
||||
os << "args:\n";
|
||||
_Tt_string indent = os.indent();
|
||||
os.set_indent( indent.cat( "\t" ));
|
||||
_Tt_arg_list_cursor argC( _args );
|
||||
while (argC.next()) {
|
||||
argC->print( os );
|
||||
}
|
||||
os.set_indent( indent );
|
||||
}
|
||||
if (_contexts->count()) {
|
||||
os << "contexts:\n";
|
||||
_Tt_string indent = os.indent();
|
||||
os.set_indent( indent.cat( "\t" ));
|
||||
_Tt_pat_context_list_cursor contextC( _contexts );
|
||||
while (contextC.next()) {
|
||||
contextC->print( os );
|
||||
}
|
||||
os.set_indent( indent );
|
||||
}
|
||||
if (_opnums->count()) {
|
||||
os << "opnums:\t";
|
||||
_opnums->print(_tt_int_rec_print, os);
|
||||
os << "\n";
|
||||
}
|
||||
if (_otypes->count()) {
|
||||
os << "otypes:\t";
|
||||
_otypes->print(_tt_string_print, os);
|
||||
os << "\n";
|
||||
}
|
||||
if (_senders->count()) {
|
||||
os << "senders:\t";
|
||||
_senders->print(_tt_string_print, os);
|
||||
os << "\n";
|
||||
}
|
||||
if (_handlers->count()) {
|
||||
os << "handlers:\t";
|
||||
_handlers->print(_tt_string_print, os);
|
||||
os << "\n";
|
||||
}
|
||||
if (_sender_ptypes->count()) {
|
||||
os << "sender_ptypes:\t";
|
||||
_sender_ptypes->print(_tt_string_print, os);
|
||||
os << "\n";
|
||||
}
|
||||
if (_handler_ptypes->count()) {
|
||||
os << "handler_ptypes:\t";
|
||||
_handler_ptypes->print(_tt_string_print, os);
|
||||
os << "\n";
|
||||
}
|
||||
}
|
||||
175
cde/lib/tt/lib/mp/mp_pattern.h
Normal file
175
cde/lib/tt/lib/mp/mp_pattern.h
Normal file
@@ -0,0 +1,175 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_pattern.h /main/3 1995/10/23 10:26:51 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_pattern.h 1.15 30 Jul 1993
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_pattern.h
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file implements the _Tt_pattern object which represents the
|
||||
* pattern that a process can register in order to receive messages. The
|
||||
* fundamental method on a _Tt_pattern object add and return pattern
|
||||
* fields and match a pattern to a message.
|
||||
*/
|
||||
|
||||
#ifndef _MP_PATTERN_H
|
||||
#define _MP_PATTERN_H
|
||||
|
||||
#include <mp/mp_global.h>
|
||||
#include <mp/mp_message.h>
|
||||
#include <mp/mp_pat_context_utils.h>
|
||||
#include <mp/mp_pattern_utils.h>
|
||||
#include <mp/mp_mp.h>
|
||||
#include <mp/mp_xdr_functions.h>
|
||||
#include <mp/mp_procid.h>
|
||||
#include <util/tt_int_rec.h>
|
||||
|
||||
typedef Tt_callback_action (*_Tt_server_callback)(
|
||||
const _Tt_message_ptr &msg,
|
||||
void *server_data
|
||||
);
|
||||
|
||||
enum _Tt_pattern_flags {
|
||||
_TT_PATTERN_IS_REGISTERED,
|
||||
_TT_PATTERN_IN_SESSION
|
||||
};
|
||||
|
||||
class _Tt_pattern : public _Tt_object {
|
||||
public:
|
||||
void base_constructor();
|
||||
_Tt_pattern();
|
||||
virtual ~_Tt_pattern();
|
||||
Tt_category category() const;
|
||||
Tt_status set_category(Tt_category c);
|
||||
void set_procid(const _Tt_procid_ptr &pid);
|
||||
int classes() const;
|
||||
int states() const;
|
||||
int paradigms() const;
|
||||
int scopes() const;
|
||||
int reliabilities() const;
|
||||
const _Tt_string_list_ptr &files() const;
|
||||
const _Tt_string_list_ptr &sessions() const;
|
||||
const _Tt_string_list_ptr &ops() const;
|
||||
const _Tt_int_rec_list_ptr &opnums() const;
|
||||
const _Tt_string_list_ptr &objects() const;
|
||||
const _Tt_string_list_ptr &otypes() const;
|
||||
const _Tt_string_list_ptr &senders() const;
|
||||
const _Tt_string_list_ptr &handlers() const;
|
||||
const _Tt_string_list_ptr &sender_ptypes() const;
|
||||
const _Tt_string_list_ptr &handler_ptypes() const;
|
||||
const _Tt_arg_list_ptr &args() const;
|
||||
_Tt_pat_context_ptr context(const char *slotname) const;
|
||||
_Tt_pat_context_ptr context(int i) const;
|
||||
int contextsCount() const;
|
||||
Tt_status add_message_class(Tt_class mclass);
|
||||
Tt_status add_paradigm(Tt_address p);
|
||||
Tt_status add_scope(Tt_scope s);
|
||||
Tt_status add_file(const _Tt_string &file);
|
||||
Tt_status add_netfile(
|
||||
const _Tt_string &file,
|
||||
int fallback_2_local_netfile = 0
|
||||
);
|
||||
Tt_status del_file(const _Tt_string &file);
|
||||
Tt_status add_session(const _Tt_string &s);
|
||||
Tt_status del_session(const _Tt_string &s);
|
||||
Tt_status add_op(const _Tt_string &op);
|
||||
Tt_status add_opnum(int o);
|
||||
Tt_status add_object(const _Tt_string &oid);
|
||||
Tt_status add_otype(const _Tt_string &ot);
|
||||
Tt_status add_sender(const _Tt_string &s);
|
||||
Tt_status add_handler(const _Tt_string &h);
|
||||
Tt_status add_sender_ptype(const _Tt_string &s);
|
||||
Tt_status add_state(Tt_state s);
|
||||
Tt_status add_handler_ptype(const _Tt_string &h);
|
||||
Tt_status add_observer_ptype(const _Tt_string &o);
|
||||
Tt_status add_reliability(Tt_disposition r);
|
||||
Tt_status add_arg(const _Tt_arg_ptr &arg);
|
||||
Tt_status add_context(
|
||||
const _Tt_pat_context_ptr &context);
|
||||
bool_t xdr(XDR *xdrs);
|
||||
void set_id(const _Tt_string &sender);
|
||||
_Tt_string id() const;
|
||||
const _Tt_procid_ptr &procid() const;
|
||||
_Tt_string &sender();
|
||||
int is_registered() const;
|
||||
void set_registered();
|
||||
void clr_registered();
|
||||
void set_in_session();
|
||||
void clr_in_session();
|
||||
int in_session() const;
|
||||
Tt_status join_files(const _Tt_string &sessID) const;
|
||||
void print(const _Tt_ostream &os) const;
|
||||
|
||||
_Tt_server_callback server_callback;
|
||||
protected:
|
||||
// convenience methods to add values to integer list and
|
||||
// string list fields. (see comment below for a description of
|
||||
// the different types of pattern fields.
|
||||
void add_field(int val,
|
||||
_Tt_int_rec_list_ptr &vlist);
|
||||
void add_field(const _Tt_string &val,
|
||||
_Tt_string_list_ptr &vlist);
|
||||
|
||||
// procid that registered this pattern
|
||||
_Tt_procid_ptr _procid;
|
||||
|
||||
// id of this pattern. For dynamic patterns, ids are relative
|
||||
// to the procid that registered the pattern. For patterns
|
||||
// generated from signatures, patterns are relative to the
|
||||
// current session. In either case, pattern ids are unique
|
||||
// among all patterns in a session (and BAD things happen if this
|
||||
// isn't the case.)
|
||||
_Tt_string _pattern_id;
|
||||
|
||||
// bit vector of _Tt_pattern_flags that are on or off for this
|
||||
// object.
|
||||
int _flags;
|
||||
|
||||
// pattern fields. There are three kinds of fields in a
|
||||
// pattern. The simplest of these are string fields which are
|
||||
// just lists of strings. Then there are integer lists (only
|
||||
// opums). Finally, there are fields which represent
|
||||
// collections of enum values. For example _classes is
|
||||
// conceptually a list of Tt_class enums. For these fields we
|
||||
// optimize storage as well as matching by representing them
|
||||
// as integers such that if enum value x is in the list then
|
||||
// <pfield>&(1<<x) is true where pfield is the given pattern
|
||||
// field. This means matching on these fields is fast and they
|
||||
// take up less space (much less than a real list of integers).
|
||||
//
|
||||
// The drawback is that enums with more than 32 members or
|
||||
// enums where each member is assigned a number > 32 aren't
|
||||
// supported.
|
||||
|
||||
Tt_category _category;
|
||||
int _classes;
|
||||
int _paradigms;
|
||||
int _reliabilities;
|
||||
int _scopes;
|
||||
int _states;
|
||||
_Tt_int_rec_list_ptr _opnums;
|
||||
_Tt_arg_list_ptr _args;
|
||||
_Tt_pat_context_list_ptr _contexts;
|
||||
_Tt_string_list_ptr _files;
|
||||
_Tt_string_list_ptr _handler_ptypes;
|
||||
_Tt_string_list_ptr _handlers;
|
||||
_Tt_string_list_ptr _objects;
|
||||
_Tt_string_list_ptr _observer_ptypes;
|
||||
_Tt_string_list_ptr _ops;
|
||||
_Tt_string_list_ptr _otypes;
|
||||
_Tt_string_list_ptr _sender_ptypes;
|
||||
_Tt_string_list_ptr _senders;
|
||||
_Tt_string_list_ptr _sessions;
|
||||
|
||||
friend class _Tt_mp;
|
||||
friend class _Tt_message;
|
||||
};
|
||||
#include <mp/mp_pattern_inlines.h>
|
||||
|
||||
bool_t tt_xdr_pattern(XDR *xdrs, _Tt_pattern_ptr *pat);
|
||||
#endif /* _MP_PATTERN_H */
|
||||
292
cde/lib/tt/lib/mp/mp_pattern_inlines.h
Normal file
292
cde/lib/tt/lib/mp/mp_pattern_inlines.h
Normal file
@@ -0,0 +1,292 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_pattern_inlines.h /main/3 1995/10/23 10:26:59 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_pattern_inlines.h 1.6 30 Jul 1993
|
||||
*
|
||||
* mp_pattern_inlines.h
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
// inline functions definitions for selected _Tt_pattern methods.
|
||||
|
||||
inline Tt_category _Tt_pattern::
|
||||
category() const
|
||||
{
|
||||
return _category;
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
set_category(Tt_category c)
|
||||
{
|
||||
_category = c;
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline void _Tt_pattern::
|
||||
set_procid(const _Tt_procid_ptr &pid)
|
||||
{
|
||||
_procid = pid;
|
||||
}
|
||||
|
||||
inline int _Tt_pattern::
|
||||
classes() const
|
||||
{
|
||||
return _classes;
|
||||
}
|
||||
|
||||
inline int _Tt_pattern::
|
||||
states() const
|
||||
{
|
||||
return _states;
|
||||
}
|
||||
|
||||
inline int _Tt_pattern::
|
||||
paradigms() const
|
||||
{
|
||||
return _paradigms;
|
||||
}
|
||||
|
||||
inline int _Tt_pattern::
|
||||
scopes() const
|
||||
{
|
||||
return _scopes;
|
||||
}
|
||||
|
||||
inline int _Tt_pattern::
|
||||
reliabilities() const
|
||||
{
|
||||
return _reliabilities;
|
||||
}
|
||||
|
||||
inline const _Tt_string_list_ptr & _Tt_pattern::
|
||||
files() const
|
||||
{
|
||||
return _files;
|
||||
}
|
||||
|
||||
inline const _Tt_string_list_ptr & _Tt_pattern::
|
||||
sessions() const
|
||||
{
|
||||
return _sessions;
|
||||
}
|
||||
|
||||
inline const _Tt_string_list_ptr & _Tt_pattern::
|
||||
ops() const
|
||||
{
|
||||
return _ops;
|
||||
}
|
||||
|
||||
inline const _Tt_int_rec_list_ptr & _Tt_pattern::
|
||||
opnums() const
|
||||
{
|
||||
return _opnums;
|
||||
}
|
||||
|
||||
inline const _Tt_string_list_ptr & _Tt_pattern::
|
||||
objects() const
|
||||
{
|
||||
return _objects;
|
||||
}
|
||||
|
||||
inline const _Tt_string_list_ptr & _Tt_pattern::
|
||||
otypes() const
|
||||
{
|
||||
return _otypes;
|
||||
}
|
||||
|
||||
inline const _Tt_string_list_ptr & _Tt_pattern::
|
||||
senders() const
|
||||
{
|
||||
return _senders;
|
||||
}
|
||||
|
||||
inline const _Tt_string_list_ptr & _Tt_pattern::
|
||||
handlers() const
|
||||
{
|
||||
return _handlers;
|
||||
}
|
||||
|
||||
inline const _Tt_string_list_ptr & _Tt_pattern::
|
||||
sender_ptypes() const
|
||||
{
|
||||
return _sender_ptypes;
|
||||
}
|
||||
|
||||
|
||||
inline const _Tt_string_list_ptr & _Tt_pattern::
|
||||
handler_ptypes() const
|
||||
{
|
||||
return _handler_ptypes;
|
||||
}
|
||||
|
||||
|
||||
inline const _Tt_arg_list_ptr & _Tt_pattern::
|
||||
args() const
|
||||
{
|
||||
return _args;
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_message_class(Tt_class mclass)
|
||||
{
|
||||
_classes |= (1<<mclass);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_paradigm(Tt_address p)
|
||||
{
|
||||
_paradigms |= (1<<p);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_scope(Tt_scope s)
|
||||
{
|
||||
_scopes |= (1<<s);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_file(const _Tt_string &file)
|
||||
{
|
||||
add_field(file, _files);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_session(const _Tt_string &s)
|
||||
{
|
||||
add_field(s, _sessions);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_op(const _Tt_string &op)
|
||||
{
|
||||
add_field(op, _ops);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_opnum(int o)
|
||||
{
|
||||
add_field(o, _opnums);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_otype(const _Tt_string &ot)
|
||||
{
|
||||
add_field(ot, _otypes);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_sender(const _Tt_string &s)
|
||||
{
|
||||
add_field(s, _senders);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_handler(const _Tt_string &h)
|
||||
{
|
||||
add_field(h, _handlers);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_sender_ptype(const _Tt_string &s)
|
||||
{
|
||||
add_field(s, _sender_ptypes);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_state(Tt_state s)
|
||||
{
|
||||
_states |= (1<<s);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_handler_ptype(const _Tt_string &h)
|
||||
{
|
||||
add_field(h, _handler_ptypes);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_reliability(Tt_disposition r)
|
||||
{
|
||||
_reliabilities |= (1<<r);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_arg(const _Tt_arg_ptr &arg)
|
||||
{
|
||||
_args->append(arg);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline Tt_status _Tt_pattern::
|
||||
add_context(const _Tt_pat_context_ptr &context)
|
||||
{
|
||||
_contexts->append_ordered(context);
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
inline _Tt_string _Tt_pattern::
|
||||
id() const
|
||||
{
|
||||
return _pattern_id;
|
||||
}
|
||||
|
||||
inline const _Tt_procid_ptr & _Tt_pattern::
|
||||
procid() const
|
||||
{
|
||||
return _procid;
|
||||
}
|
||||
|
||||
inline int _Tt_pattern::
|
||||
is_registered() const
|
||||
{
|
||||
return _flags&(1<<_TT_PATTERN_IS_REGISTERED);
|
||||
}
|
||||
|
||||
inline void _Tt_pattern::
|
||||
set_registered()
|
||||
{
|
||||
_flags |= (1<<_TT_PATTERN_IS_REGISTERED);
|
||||
}
|
||||
|
||||
inline void _Tt_pattern::
|
||||
clr_registered()
|
||||
{
|
||||
_flags &= ~(1<<_TT_PATTERN_IS_REGISTERED);
|
||||
}
|
||||
|
||||
inline void _Tt_pattern::
|
||||
set_in_session()
|
||||
{
|
||||
_flags |= (1<<_TT_PATTERN_IN_SESSION);
|
||||
}
|
||||
|
||||
inline void _Tt_pattern::
|
||||
clr_in_session()
|
||||
{
|
||||
_flags &= ~(1<<_TT_PATTERN_IN_SESSION);
|
||||
}
|
||||
|
||||
inline int _Tt_pattern::
|
||||
in_session() const
|
||||
{
|
||||
return(_flags&(1<<_TT_PATTERN_IN_SESSION));
|
||||
}
|
||||
38
cde/lib/tt/lib/mp/mp_pattern_utils.C
Normal file
38
cde/lib/tt/lib/mp/mp_pattern_utils.C
Normal file
@@ -0,0 +1,38 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_pattern_utils.C /main/3 1995/10/23 10:27:06 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_pattern_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <mp/mp_pattern.h>
|
||||
|
||||
_Tt_patlist::
|
||||
_Tt_patlist()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_patlist::
|
||||
~_Tt_patlist()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_patlist::
|
||||
_Tt_patlist(_Tt_string o)
|
||||
{
|
||||
_op = o;
|
||||
}
|
||||
|
||||
_Tt_string
|
||||
_tt_patlist_op(_Tt_object_ptr &o)
|
||||
{
|
||||
return(((_Tt_patlist *)o.c_pointer())->op());
|
||||
}
|
||||
|
||||
implement_list_of(_Tt_pattern)
|
||||
implement_list_of(_Tt_patlist)
|
||||
implement_table_of(_Tt_patlist)
|
||||
38
cde/lib/tt/lib/mp/mp_pattern_utils.h
Normal file
38
cde/lib/tt/lib/mp/mp_pattern_utils.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_pattern_utils.h /main/3 1995/10/23 10:27:13 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_pattern_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Utilities declarations for _Tt_pattern
|
||||
*/
|
||||
#ifndef MP_PATTERN_UTILS_H
|
||||
#define MP_PATTERN_UTILS_H
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_list.h>
|
||||
#include <util/tt_string.h>
|
||||
#include <util/tt_table.h>
|
||||
|
||||
class _Tt_pattern;
|
||||
declare_list_of(_Tt_pattern)
|
||||
|
||||
class _Tt_patlist : public _Tt_object {
|
||||
public:
|
||||
_Tt_patlist();
|
||||
~_Tt_patlist();
|
||||
_Tt_patlist(_Tt_string o);
|
||||
void set_op(_Tt_string o){ _op = o; };
|
||||
_Tt_string op(){ return _op; };
|
||||
_Tt_pattern_list_ptr patterns;
|
||||
private:
|
||||
_Tt_string _op;
|
||||
};
|
||||
_Tt_string _tt_patlist_op(_Tt_object_ptr &o);
|
||||
declare_list_of(_Tt_patlist)
|
||||
declare_table_of(_Tt_patlist)
|
||||
#endif /* MP_PATTERN_UTILS_H */
|
||||
315
cde/lib/tt/lib/mp/mp_procid.C
Normal file
315
cde/lib/tt/lib/mp/mp_procid.C
Normal file
@@ -0,0 +1,315 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_procid.C /main/4 1997/07/30 15:43:53 samborn $
|
||||
/*
|
||||
*
|
||||
* mp_procid.cc -- methods for communicating with active processes
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "util/tt_host.h"
|
||||
#include "mp/mp_file.h"
|
||||
#include "mp/mp_message.h"
|
||||
#include "mp/mp_mp.h"
|
||||
#include "mp/mp_pattern.h"
|
||||
#include "mp/mp_procid.h"
|
||||
#include "mp/mp_session.h"
|
||||
#include "mp/mp_stream_socket.h"
|
||||
#include "util/tt_int_rec.h"
|
||||
#include "util/tt_global_env.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#if defined(sgi)
|
||||
#include <CC/libc.h>
|
||||
#endif
|
||||
|
||||
|
||||
_Tt_procid::
|
||||
_Tt_procid()
|
||||
{
|
||||
_fd = -1;
|
||||
_pid = 0;
|
||||
_version = 0;
|
||||
_flags = 0;
|
||||
_mxdr_stream = (XDR *)0;
|
||||
}
|
||||
|
||||
|
||||
_Tt_procid::
|
||||
~_Tt_procid()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns the fd which will be used to signal this procid if there are
|
||||
// new messages for it. -1 means error. This method is only used in
|
||||
// client mode. This method caches the fd returned from the
|
||||
// _Tt_stream_socket::fd method. This method has the side-effect that it
|
||||
// will accept the connection on the socket if not already done. See the
|
||||
// comments in _Tt_c_procid::set_fd_channel for more details.
|
||||
//
|
||||
int _Tt_procid::
|
||||
fd()
|
||||
{
|
||||
if (_socket.is_null()) {
|
||||
return(-1);
|
||||
} else if (_fd == -1) {
|
||||
_fd = _socket->fd();
|
||||
}
|
||||
|
||||
return(_fd);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns the string version of the id for this procid. See
|
||||
// _Tt_c_procid::init() for a description of the format for this id.
|
||||
//
|
||||
// XXX: Warning! Do not inline the following. Causes weirdness with
|
||||
// the table package.
|
||||
//
|
||||
const _Tt_string & _Tt_procid::
|
||||
id() const
|
||||
{
|
||||
// return string representation
|
||||
return(_id);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns 1 if this procid's id is the same as the one given.
|
||||
//
|
||||
int _Tt_procid::
|
||||
is_equal(_Tt_string &i)
|
||||
{
|
||||
if (_id.len()) {
|
||||
return(_id == i);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns the TCP port to connect to to signal a procid for a new
|
||||
// message. This method is only used in server mode.
|
||||
//
|
||||
int _Tt_procid::
|
||||
port() const
|
||||
{
|
||||
if (_socket.is_null()) {
|
||||
return(-1);
|
||||
} else {
|
||||
return(_socket->port());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// XDR encodes/decodes a procid.
|
||||
//
|
||||
bool_t _Tt_procid::
|
||||
xdr(XDR *xdrs)
|
||||
{
|
||||
long localpid;
|
||||
|
||||
if (! _id.xdr(xdrs)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
localpid = _pid;
|
||||
}
|
||||
if (! xdr_long(xdrs, &localpid)) {
|
||||
return 0;
|
||||
}
|
||||
if (xdrs->x_op == XDR_DECODE) {
|
||||
_pid = (pid_t)localpid;
|
||||
}
|
||||
|
||||
return(_proc_host_ipaddr.xdr(xdrs));
|
||||
}
|
||||
|
||||
|
||||
void _Tt_procid::
|
||||
print(const _Tt_ostream &os) const
|
||||
{
|
||||
os << _id << " [" << _pid;
|
||||
if (! _proc_host.is_null()) {
|
||||
os << "@" << _proc_host->name();
|
||||
}
|
||||
os << "]\n";
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns 1 if this procid is handling m or is voting on it.
|
||||
//
|
||||
int _Tt_procid::
|
||||
processing(const _Tt_message &m)
|
||||
{
|
||||
switch (m.state()) {
|
||||
case TT_FAILED:
|
||||
case TT_HANDLED:
|
||||
case TT_RETURNED:
|
||||
// if message state is already final then it can't be
|
||||
// handled by anyone.
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!m.handler().is_null()) {
|
||||
return m.handler()->is_equal( this );
|
||||
} else if (m.message_class() == TT_OFFER) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Wrapper to invoke the _Tt_procid_ptr::xdr method.
|
||||
//
|
||||
bool_t
|
||||
tt_xdr_procid(XDR *xdrs, _Tt_procid_ptr *patp)
|
||||
{
|
||||
return((*patp).xdr(xdrs));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Wrapper to invoke the _Tt_message_list_ptr::xdr method.
|
||||
//
|
||||
bool_t
|
||||
tt_xdr_message_list(XDR *xdrs, _Tt_message_list_ptr *mptr)
|
||||
{
|
||||
return((*mptr).xdr(xdrs));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Add the given path to the list of files this procid object has
|
||||
// joined.
|
||||
//
|
||||
void _Tt_procid::
|
||||
add_joined_file(_Tt_string fpath)
|
||||
{
|
||||
if (joined_to_file(fpath)) {
|
||||
return;
|
||||
}
|
||||
if (_joined_files.is_null()) {
|
||||
_joined_files = new _Tt_string_list();
|
||||
}
|
||||
_joined_files->push(fpath);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Delete the given path from the list of files this procid object has
|
||||
// joined.
|
||||
//
|
||||
void _Tt_procid::
|
||||
del_joined_file(_Tt_string fpath)
|
||||
{
|
||||
if (_joined_files.is_null()) {
|
||||
return;
|
||||
}
|
||||
_Tt_string_list_cursor jc(_joined_files);
|
||||
|
||||
while (jc.next()) {
|
||||
if (*jc == fpath) {
|
||||
jc.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Return 1 if the given path represents a file this procid object has
|
||||
// joined.
|
||||
//
|
||||
int _Tt_procid::
|
||||
joined_to_file(_Tt_string fpath)
|
||||
{
|
||||
if (_joined_files.is_null()) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
_Tt_string_list_cursor jc(_joined_files);
|
||||
|
||||
while (jc.next()) {
|
||||
if (*jc == fpath) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Invokes _Tt_procid::id method on o which is assumed to point to a
|
||||
// _Tt_procid. Used by the table package to generate keys.
|
||||
//
|
||||
_Tt_string
|
||||
_tt_procid_id(_Tt_object_ptr &o)
|
||||
{
|
||||
return(((_Tt_procid *)o.c_pointer())->id());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef OPT_ADDMSG_DIRECT
|
||||
//
|
||||
// If this option is turned on, these functions are used to read/write
|
||||
// a given counted buffer to the given _Tt_stream_socket object.
|
||||
// "iohandle" is really a pointer to this _Tt_stream_socket object (it
|
||||
// is given to xdrrec_create, and then XDR will give it to these
|
||||
// functions to do the read/writes to an xdr stream. See
|
||||
// _Tt_s_procid::signal_new_message(_Tt_message_ptr &m), and
|
||||
// _Tt_c_procid::next_message.)
|
||||
//
|
||||
|
||||
|
||||
|
||||
int
|
||||
_tt_xdr_readit(char *iohandle, char *buf, int nbytes)
|
||||
{
|
||||
int rval;
|
||||
fd_set readfds;
|
||||
timeval tmout;
|
||||
int fd;
|
||||
_Tt_stream_socket *sptr = (_Tt_stream_socket *)iohandle;
|
||||
|
||||
fd = sptr->fd();
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(fd,&readfds);
|
||||
tmout.tv_sec = 0;
|
||||
tmout.tv_usec = 0;
|
||||
if (select(FD_SETSIZE, &readfds, 0, 0, &tmout) <= 0) {
|
||||
if (errno == EBADF) {
|
||||
_tt_syslog( 0, LOG_ERR, "_tt_xdr_readit(): %m" );
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
if (!FD_ISSET(fd, &readfds)) {
|
||||
_tt_syslog( 0, LOG_ERR, "_tt_xdr_readit(): !FD_ISSET()" );
|
||||
return(0);
|
||||
}
|
||||
rval = sptr->recv(buf, nbytes);
|
||||
return((rval) ? rval : -1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_tt_xdr_writeit(char *iohandle, char *buf, int nbytes)
|
||||
{
|
||||
return(((_Tt_stream_socket *)iohandle)->send(buf,nbytes));
|
||||
}
|
||||
#endif // OPT_ADDMSG_DIRECT
|
||||
136
cde/lib/tt/lib/mp/mp_procid.h
Normal file
136
cde/lib/tt/lib/mp/mp_procid.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_procid.h /main/3 1995/10/23 10:27:28 rswiston $ */
|
||||
/*
|
||||
* mp_procid.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file contains the implementation of _Tt_procid which is an object
|
||||
* that represents an active process communicating with a message server.
|
||||
* There are two instances of this object depending on whether the object
|
||||
* is in client or server mode. The client instance is basically just a
|
||||
* handle on it's id. The server instance maintains information such as
|
||||
* what patterns are registered for a process, what signalling channel is
|
||||
* used, and also what messages are waiting to be delivered to the client
|
||||
* instance of the procid.
|
||||
*/
|
||||
#ifndef MP_PROCID_H
|
||||
#define MP_PROCID_H
|
||||
|
||||
#include "util/tt_table.h"
|
||||
#include "util/tt_host_utils.h"
|
||||
#include "mp/mp_global.h"
|
||||
#include "mp/mp_stream_socket_utils.h"
|
||||
#include "mp/mp_session_utils.h"
|
||||
#include "mp/mp_message_utils.h"
|
||||
#include "mp/mp_pattern_utils.h"
|
||||
#include "mp/mp_procid_utils.h"
|
||||
#include "mp_xdr_functions.h"
|
||||
#define _TT_MESSAGE_TIMEOUT 300 /* default message timeout in seconds */
|
||||
|
||||
|
||||
#ifdef OPT_ADDMSG_DIRECT
|
||||
/*
|
||||
* if this option is turned on then TT_ADDMSG_VERS should be set to
|
||||
* the version number at which addmsg_direct is used. The code assumes
|
||||
* that all versions later than this version also support this
|
||||
* optimization.
|
||||
*
|
||||
* XXX: This should probably be changed to a mechanism that allows
|
||||
* clients to tell their session that they would like this optimization
|
||||
* to be used. The session can then deny their request meaning it doesn't
|
||||
* support the optimization.
|
||||
*/
|
||||
# define TT_ADDMSG_VERS 3
|
||||
#else
|
||||
/*
|
||||
* defining this as -1 assures that no code will make use of it
|
||||
*/
|
||||
# define TT_ADDMSG_VERS -1
|
||||
#endif
|
||||
|
||||
|
||||
enum _Tt_procid_flagbits {
|
||||
_TT_PROC_ACTIVE, /* is an active proc */
|
||||
_TT_PROC_FD_CHANNEL_ON, /* fd channel is valid */
|
||||
_TT_PROC_COMMITTED, /* committed to default session */
|
||||
_TT_PROC_IS_LOCAL, /* is local to server's machine */
|
||||
_TT_PROC_SIGNALLED, /* has been signalled about new msgs */
|
||||
_TT_PROC_MSGSENT /* msg sent directly to proc */
|
||||
};
|
||||
|
||||
class _Tt_procid : public _Tt_object {
|
||||
public:
|
||||
_Tt_procid();
|
||||
virtual ~_Tt_procid();
|
||||
void add_joined_file(_Tt_string fpath);
|
||||
void del_joined_file(_Tt_string fpath);
|
||||
int fd();
|
||||
const _Tt_string &id() const;
|
||||
int is_equal(const _Tt_procid_ptr &p) {
|
||||
return(_id == p->_id);
|
||||
}
|
||||
int is_equal(_Tt_string &id);
|
||||
int joined_to_file(_Tt_string fpath);
|
||||
int processing(const _Tt_message &m);
|
||||
_Tt_pattern_list_ptr &patterns() {
|
||||
return _patterns;
|
||||
}
|
||||
pid_t pid() const {
|
||||
return _pid;
|
||||
}
|
||||
int port() const;
|
||||
void print(const _Tt_ostream &os) const;
|
||||
_Tt_host_ptr &proc_host() {
|
||||
return _proc_host;
|
||||
}
|
||||
int program() const {
|
||||
return _program;
|
||||
}
|
||||
void set_start_token(const _Tt_string &token) {
|
||||
_start_token = token;
|
||||
}
|
||||
_Tt_string &start_token() {
|
||||
return _start_token;
|
||||
}
|
||||
int version() const {
|
||||
return _version;
|
||||
}
|
||||
_Tt_string &proc_host_ipaddr() {
|
||||
return _proc_host_ipaddr;
|
||||
}
|
||||
_Tt_string_list_ptr &ptypes() {
|
||||
return _declared_ptypes;
|
||||
}
|
||||
bool_t xdr(XDR *xdrs);
|
||||
|
||||
protected:
|
||||
int _fd;
|
||||
int _flags;
|
||||
int _program;
|
||||
int _version;
|
||||
pid_t _pid;
|
||||
_Tt_string _id;
|
||||
_Tt_string _start_token;
|
||||
_Tt_string _proc_host_ipaddr;
|
||||
_Tt_string_list_ptr _joined_files;
|
||||
_Tt_string_list_ptr _declared_ptypes;
|
||||
_Tt_pattern_list_ptr _patterns;
|
||||
_Tt_host_ptr _proc_host;
|
||||
_Tt_stream_socket_ptr _socket;
|
||||
XDR *_mxdr_stream;
|
||||
};
|
||||
|
||||
_Tt_string _tt_procid_id(_Tt_object_ptr &o);
|
||||
bool_t tt_xdr_procid(XDR *xdrs, _Tt_procid_ptr *patp);
|
||||
bool_t tt_xdr_message_list(XDR *xdrs, _Tt_message_list_ptr *mptr);
|
||||
|
||||
#ifdef OPT_ADDMSG_DIRECT
|
||||
int _tt_xdr_readit(char *iohandle, char *buf, int nbytes);
|
||||
int _tt_xdr_writeit(char *iohandle, char *buf, int nbytes);
|
||||
#endif /* OPT_ADDMSG_DIRECT */
|
||||
#endif /* MP_PROCID_H */
|
||||
|
||||
15
cde/lib/tt/lib/mp/mp_procid_utils.C
Normal file
15
cde/lib/tt/lib/mp/mp_procid_utils.C
Normal file
@@ -0,0 +1,15 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_procid_utils.C /main/3 1995/10/23 10:27:36 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_procid_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <mp/mp_procid.h>
|
||||
|
||||
implement_list_of(_Tt_procid)
|
||||
implement_table_of(_Tt_procid)
|
||||
24
cde/lib/tt/lib/mp/mp_procid_utils.h
Normal file
24
cde/lib/tt/lib/mp/mp_procid_utils.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_procid_utils.h /main/3 1995/10/23 10:27:43 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_procid_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Utilities declarations for _Tt_procid
|
||||
*/
|
||||
#ifndef MP_PROCID_UTILS_H
|
||||
#define MP_PROCID_UTILS_H
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_string.h>
|
||||
#include <util/tt_table.h>
|
||||
|
||||
class _Tt_procid;
|
||||
declare_list_of(_Tt_procid)
|
||||
declare_table_of(_Tt_procid)
|
||||
|
||||
#endif /* MP_PROCID_UTILS_H */
|
||||
56
cde/lib/tt/lib/mp/mp_rpc.h
Normal file
56
cde/lib/tt/lib/mp/mp_rpc.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $TOG: mp_rpc.h /main/5 1999/08/30 10:55:41 mgreess $ */
|
||||
/*
|
||||
*
|
||||
* @(#)mp_rpc.h 1.15 93/09/07
|
||||
*
|
||||
* Copyright (c) 1990,1993 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Common declarations for RPC implementation classes.
|
||||
*/
|
||||
#ifndef _TT_MP_RPC
|
||||
#define _TT_MP_RPC
|
||||
#include "tt_options.h"
|
||||
|
||||
#if defined(linux)
|
||||
# define __SVR4_I386_ABI_L1__
|
||||
#endif
|
||||
#include <rpc/rpc.h>
|
||||
#if defined(linux)
|
||||
# undef __SVR4_I386_ABI_L1__
|
||||
#endif
|
||||
|
||||
#if defined(ultrix) || defined(_AIX)
|
||||
extern "C" {
|
||||
void svcerr_auth (SVCXPRT *, enum auth_stat);
|
||||
SVCXPRT *svcfd_create(int,int,int);
|
||||
void svc_getreqset(fd_set *);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(OPT_TLI)
|
||||
# include <netconfig.h>
|
||||
# include <tiuser.h>
|
||||
#else
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
#endif /* OPT_TLI */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "util/tt_object.h"
|
||||
#include "util/tt_ptr.h"
|
||||
#include "util/tt_int_rec.h"
|
||||
#include "mp/mp_rpc_fns.h"
|
||||
#include "util/tt_host_utils.h"
|
||||
|
||||
enum _Tt_rpcsrv_err {
|
||||
_TT_RPCSRV_OK,
|
||||
_TT_RPCSRV_ERR,
|
||||
_TT_RPCSRV_TMOUT,
|
||||
_TT_RPCSRV_FDERR
|
||||
};
|
||||
|
||||
#endif /* _TT_MP_RPC */
|
||||
335
cde/lib/tt/lib/mp/mp_rpc_client.C
Normal file
335
cde/lib/tt/lib/mp/mp_rpc_client.C
Normal file
@@ -0,0 +1,335 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_rpc_client.C /main/9 1999/09/08 18:21:02 mgreess $
|
||||
/*
|
||||
*
|
||||
* mp_rpc_client.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <sys/time.h> // ultrix
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "tt_options.h"
|
||||
#include "mp/mp_auth.h"
|
||||
#include "mp/mp_rpc_client.h"
|
||||
#include "mp/mp_xdr_functions.h"
|
||||
#include "util/tt_host.h"
|
||||
#include "util/tt_port.h"
|
||||
|
||||
#if defined(ultrix)
|
||||
extern "C"
|
||||
{ extern struct XSizeHints;
|
||||
extern struct XStandardColormap;
|
||||
extern struct XTextProperty;
|
||||
extern struct XWMHints;
|
||||
extern struct XClassHint;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(_AIX)
|
||||
/* AIX's FD_ZERO macro uses bzero() without declaring it. */
|
||||
#include <strings.h>
|
||||
/* And arpa/inet.h has a buggy declaration of inet_addr */
|
||||
extern "C" in_addr_t inet_addr(const char *);
|
||||
#endif
|
||||
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <memory.h>
|
||||
|
||||
#if defined(sgi)
|
||||
/* SGI's FD_ZERO macro uses bzero() without declaring it. */
|
||||
#include <CC/libc.h>
|
||||
#endif
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <util/tt_global_env.h>
|
||||
#include <mp/mp_rpc_fns.h>
|
||||
|
||||
/*
|
||||
* Constructs an rpc client.
|
||||
*/
|
||||
_Tt_rpc_client::
|
||||
_Tt_rpc_client(int conn_socket)
|
||||
{
|
||||
_socket = conn_socket;
|
||||
_client = (CLIENT *)0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destroys an rpc client (breaks off connections)
|
||||
*/
|
||||
_Tt_rpc_client::
|
||||
~_Tt_rpc_client()
|
||||
{
|
||||
if (_client != (CLIENT *)0) {
|
||||
clnt_destroy(_client);
|
||||
}
|
||||
_host = (_Tt_host *)0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the socket associated with an rpc client. --> it would be
|
||||
* nice to use this socket rather than open up a new one when signalling
|
||||
* procids.
|
||||
*/
|
||||
int _Tt_rpc_client::
|
||||
socket()
|
||||
{
|
||||
return(_socket);
|
||||
}
|
||||
|
||||
/*
|
||||
* create client connection to host,program,version
|
||||
*/
|
||||
int _Tt_rpc_client::
|
||||
init(_Tt_host_ptr &host, int program, int version,
|
||||
uid_t servuid, _Tt_auth &auth)
|
||||
{
|
||||
int optval;
|
||||
static caddr_t saved_opaque = 0;
|
||||
static int saved_len = 0;
|
||||
|
||||
optval = (_socket == RPC_ANYSOCK);
|
||||
_auth = auth;
|
||||
_host = host;
|
||||
_program = program;
|
||||
_version = version;
|
||||
_server_uid = servuid;
|
||||
if (_client != (CLIENT *)0) {
|
||||
if (_auth.auth_level() == _TT_AUTH_UNIX) {
|
||||
auth_destroy(_client->cl_auth);
|
||||
}
|
||||
clnt_destroy(_client);
|
||||
}
|
||||
#if defined(OPT_SECURE_RPC)
|
||||
if (_auth.auth_level() == _TT_AUTH_DES) {
|
||||
if (_server_uid == 0) {
|
||||
host2netname(_servername, (char *)_host->name(), 0);
|
||||
} else {
|
||||
user2netname(_servername, _server_uid, 0);
|
||||
}
|
||||
}
|
||||
#endif /* OPT_SECURE_RPC */
|
||||
#ifndef OPT_TLI
|
||||
|
||||
memset(&_server_addr, 0, sizeof(_server_addr));
|
||||
_server_addr.sin_family = AF_INET;
|
||||
_server_addr.sin_port = htons((optval) ? 0 : 4000);
|
||||
_server_addr.sin_addr.s_addr = inet_addr((char *)(_host->stringaddr()));
|
||||
_client = clnttcp_create(&_server_addr, _program,
|
||||
_version, &_socket, 4000, 4000);
|
||||
if (_client == 0) {
|
||||
// XXX only when in some kind of debug mode
|
||||
//clnt_pcreateerror("_Tt_rpc_client::init(): clnttcp_create()");
|
||||
return 0;
|
||||
}
|
||||
if (_auth.auth_level() == _TT_AUTH_UNIX) {
|
||||
_client->cl_auth = authunix_create_default();
|
||||
}
|
||||
|
||||
if (optval) {
|
||||
#ifndef linux
|
||||
if (setsockopt(_socket, SOL_SOCKET, SO_USELOOPBACK,
|
||||
(char *)&optval, sizeof(int)) == -1) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_rpc_client::init(): "
|
||||
"setsockopt(SO_USELOOPBACK): %m");
|
||||
}
|
||||
#endif
|
||||
if (setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY,
|
||||
(char *)&optval, sizeof(int)) == -1) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_rpc_client::init(): "
|
||||
"setsockopt(TCP_NODELAY): %m");
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
_client = clnt_create((char *)_host->name(),
|
||||
_program, _version, "circuit_v");
|
||||
if (_client == 0) {
|
||||
// XXX only when in some kind of debug mode
|
||||
//clnt_pcreateerror( "_Tt_rpc_client::init(): clnt_create()" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!clnt_control(_client, CLGET_FD, (char *)&_socket)) {
|
||||
// I cannot imagine how this could ever fail at this point.
|
||||
return 0;
|
||||
}
|
||||
// We used to call _tt_tli_set_nodelay here on the RPC connection.
|
||||
// This stopped working mysteriously, suddenly the endpoint started
|
||||
// coming back in state T_DATAXFER instead of T_IDLE from clnt_create.
|
||||
// Fortunately, in the meantime the TIRPC library has started
|
||||
// setting NODELAY on RPC/TCP connections, so we don't need to
|
||||
// do it here anymore anyway.
|
||||
|
||||
if (_auth.auth_level() == _TT_AUTH_UNIX) {
|
||||
_client->cl_auth = authunix_create_default();
|
||||
}
|
||||
|
||||
#endif // !OPT_TLI
|
||||
|
||||
// Set close-on-exec bit so a libtt client which forks and execs won't
|
||||
// be short some fd's in the child.
|
||||
if (-1==fcntl(_socket, F_SETFD, 1)) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_rpc_client::init(): "
|
||||
"fcntl(F_SETFD): %m");
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* invoke rpc procedure
|
||||
*/
|
||||
clnt_stat _Tt_rpc_client::
|
||||
call(int procnum, xdrproc_t inproc, char *in,
|
||||
xdrproc_t outproc, char *out, int timeout)
|
||||
{
|
||||
fd_set bogus;
|
||||
timeval tmout;
|
||||
timeval total_timeout;
|
||||
struct sigaction curr_action;
|
||||
int need2reset_sigpipe = 0;
|
||||
_Tt_auth_iceauth_args args;
|
||||
|
||||
if (_client == (CLIENT *)0) {
|
||||
return(RPC_CANTSEND);
|
||||
}
|
||||
total_timeout.tv_sec = ((timeout < 0) ? 0 : timeout);
|
||||
total_timeout.tv_usec = 0;
|
||||
clnt_control(_client, CLSET_TIMEOUT, (char *) &total_timeout);
|
||||
|
||||
switch (_auth.auth_level()) {
|
||||
case _TT_AUTH_UNIX:
|
||||
break;
|
||||
case _TT_AUTH_ICEAUTH:
|
||||
break;
|
||||
#if defined(OPT_SECURE_RPC)
|
||||
case _TT_AUTH_DES:
|
||||
#ifdef OPT_TLI
|
||||
_client->cl_auth =
|
||||
authdes_seccreate(_servername, 60, (char *)_host->name(),
|
||||
(des_block *)0);
|
||||
if (_client->cl_auth == 0) {
|
||||
_tt_syslog( 0, LOG_WARNING, "authdes_seccreate(): 0" );
|
||||
// XXX what todo when authdes_seccreate() fails?
|
||||
return RPC_AUTHERROR;
|
||||
}
|
||||
#else
|
||||
_client->cl_auth =
|
||||
authdes_create(_servername, 60, &_server_addr,
|
||||
(des_block *)0);
|
||||
if (_client->cl_auth == 0) {
|
||||
_tt_syslog( 0, LOG_WARNING, "authdes_seccreate(): 0" );
|
||||
// XXX what todo when authdes_seccreate() fails?
|
||||
return RPC_AUTHERROR;
|
||||
}
|
||||
#endif /* OPT_TLI */
|
||||
break;
|
||||
#endif /* OPT_SECURE_RPC */
|
||||
case _TT_AUTH_NONE:
|
||||
break;
|
||||
default:
|
||||
return(RPC_AUTHERROR);
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
FD_ZERO(&bogus);
|
||||
FD_SET(_socket, &bogus);
|
||||
tmout.tv_sec = 0;
|
||||
tmout.tv_usec = 0;
|
||||
select(FD_SETSIZE, &bogus, 0, 0, &tmout);
|
||||
|
||||
if (FD_ISSET(_socket, &bogus)) {
|
||||
return(RPC_CANTSEND);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OPT_BUG_USL) || defined(OPT_BUG_UXP)
|
||||
if (timeout <= 0)
|
||||
{
|
||||
outproc = (xdrproc_t) NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// tcp write errors (when the rpc_server on the other end dies)
|
||||
// cause a SIGPIPE. We need to make sure the SIGPIPE is caught,
|
||||
// or the process dies.
|
||||
//
|
||||
if (sigaction(SIGPIPE, 0, &curr_action) != 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "sigaction(): %m" );
|
||||
}
|
||||
#if defined(OPT_BUG_SUNOS_5) || defined(OPT_BUG_UW_1)
|
||||
if ((SIG_TYP)curr_action.sa_handler == SIG_DFL)
|
||||
#else
|
||||
#if defined(OPT_BUG_UW_2) || defined(OPT_BUG_UXP)
|
||||
if ((void(*)(int))curr_action.sa_handler == SIG_DFL)
|
||||
#else
|
||||
if (curr_action.sa_handler == SIG_DFL)
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
need2reset_sigpipe = 1;
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
}
|
||||
|
||||
if (_TT_AUTH_ICEAUTH == _auth.auth_level()) {
|
||||
args.auth_level = _auth.auth_level();
|
||||
args.auth_cookie = _auth.auth_cookie();
|
||||
args.inproc = (xdr_auth_proc_t) inproc;
|
||||
args.inargs = (caddr_t) in;
|
||||
|
||||
_clnt_stat = clnt_call(_client, procnum,
|
||||
(xdrproc_t) tt_xdr_auth_iceauth_args,
|
||||
(char*) &args,
|
||||
outproc, out,
|
||||
total_timeout);
|
||||
}
|
||||
else {
|
||||
_clnt_stat = clnt_call(_client, procnum,
|
||||
inproc, in,
|
||||
outproc, out,
|
||||
total_timeout);
|
||||
}
|
||||
#if defined(OPT_BUG_USL) || defined(OPT_BUG_UXP)
|
||||
if (timeout <= 0)
|
||||
{
|
||||
total_timeout.tv_sec = 10;
|
||||
total_timeout.tv_usec = 0;
|
||||
clnt_control(_client, CLSET_TIMEOUT, (char *) &total_timeout);
|
||||
clnt_call(_client, NULLPROC, (xdrproc_t) xdr_void, (char *)NULL,
|
||||
(xdrproc_t) xdr_void, (char *) NULL, total_timeout);
|
||||
}
|
||||
#endif
|
||||
if (need2reset_sigpipe) {
|
||||
signal(SIGPIPE, SIG_DFL);
|
||||
}
|
||||
#if !defined(OPT_BUG_RPCINTR)
|
||||
if (_clnt_stat == RPC_INTR) {
|
||||
return(RPC_CANTSEND);
|
||||
}
|
||||
#endif
|
||||
if (_auth.auth_level() == _TT_AUTH_DES) {
|
||||
auth_destroy(_client->cl_auth);
|
||||
}
|
||||
|
||||
return(_clnt_stat);
|
||||
}
|
||||
|
||||
|
||||
56
cde/lib/tt/lib/mp/mp_rpc_client.h
Normal file
56
cde/lib/tt/lib/mp/mp_rpc_client.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $TOG: mp_rpc_client.h /main/4 1999/08/30 10:57:12 mgreess $ */
|
||||
/*
|
||||
*
|
||||
* mp_rpc_server.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Declaration of
|
||||
* _Tt_rpc_client which represents the ttsession
|
||||
* RPC client.
|
||||
*/
|
||||
#ifndef _TT_MP_RPC_CLIENT
|
||||
#define _TT_MP_RPC_CLIENT
|
||||
#include "mp/mp_auth.h"
|
||||
#include "mp/mp_rpc.h"
|
||||
|
||||
class _Tt_rpc_client : public _Tt_object {
|
||||
public:
|
||||
_Tt_rpc_client(int conn_socket = RPC_ANYSOCK);
|
||||
virtual ~_Tt_rpc_client();
|
||||
// create client connection to host,program,version
|
||||
int init(_Tt_host_ptr &host,
|
||||
int program, int version,
|
||||
uid_t servuid,
|
||||
_Tt_auth &auth);
|
||||
int socket();
|
||||
// invoke rpc procedure
|
||||
clnt_stat call(int procnum,
|
||||
xdrproc_t inproc,
|
||||
char *in,
|
||||
xdrproc_t outproc,
|
||||
char *out,
|
||||
int timeout);
|
||||
CLIENT *rpc_handle() { return _client; };
|
||||
private:
|
||||
_Tt_host_ptr _host;
|
||||
int _program;
|
||||
int _version;
|
||||
int _socket;
|
||||
uid_t _server_uid;
|
||||
_Tt_auth _auth;
|
||||
char _servername[MAXNETNAMELEN];
|
||||
CLIENT *_client;
|
||||
clnt_stat _clnt_stat;
|
||||
#if defined(OPT_TLI)
|
||||
int _server_addr;
|
||||
#else
|
||||
sockaddr_in _server_addr;
|
||||
#endif /* OPT_TLI */
|
||||
};
|
||||
|
||||
#endif /* _TT_MP_RPC_CLIENT */
|
||||
15
cde/lib/tt/lib/mp/mp_rpc_client_utils.C
Normal file
15
cde/lib/tt/lib/mp/mp_rpc_client_utils.C
Normal file
@@ -0,0 +1,15 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_rpc_client_utils.C /main/3 1995/10/23 10:28:13 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_rpc_client_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <mp/mp_rpc_client_utils.h>
|
||||
#include <mp/mp_rpc_client.h>
|
||||
|
||||
implement_ptr_to(_Tt_rpc_client)
|
||||
19
cde/lib/tt/lib/mp/mp_rpc_client_utils.h
Normal file
19
cde/lib/tt/lib/mp/mp_rpc_client_utils.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_rpc_client_utils.h /main/3 1995/10/23 10:28:19 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_rpc_client_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef MP_RPC_CLIENT_UTILS_H
|
||||
#define MP_RPC_CLIENT_UTILS_H
|
||||
#include <util/tt_object.h>
|
||||
|
||||
class _Tt_rpc_client;
|
||||
declare_ptr_to(_Tt_rpc_client)
|
||||
|
||||
#endif /* MP_RPC_CLIENT_UTILS_H */
|
||||
95
cde/lib/tt/lib/mp/mp_rpc_fns.C
Normal file
95
cde/lib/tt/lib/mp/mp_rpc_fns.C
Normal file
@@ -0,0 +1,95 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_rpc_fns.C /main/4 1996/04/21 19:12:28 drk $ */
|
||||
/*
|
||||
* mp_rpc_fns.C
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <tt_options.h>
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
#if defined(OPT_TLI)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <tiuser.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
/*
|
||||
* Sets the TCP_NODELAY option for a tli stream bound using tcp. This
|
||||
* option is crucial to good message performance since otherwise there is
|
||||
* a 200 ms delay between messages. This code is based on the source code
|
||||
* for tli rpc (since documentation was sorely lacking).
|
||||
*/
|
||||
extern "C"
|
||||
int
|
||||
_tt_tli_set_nodelay(int fd)
|
||||
{
|
||||
struct t_optmgmt *options;
|
||||
struct sochdr {
|
||||
struct opthdr opthdr;
|
||||
long value;
|
||||
} sochdr;
|
||||
|
||||
options = (struct t_optmgmt *)t_alloc(fd, T_OPTMGMT, 0);
|
||||
if (options == (struct t_optmgmt *)0) {
|
||||
return (0);
|
||||
}
|
||||
sochdr.opthdr.level = IPPROTO_TCP;
|
||||
sochdr.opthdr.name = TCP_NODELAY;
|
||||
sochdr.opthdr.len = 4;
|
||||
sochdr.value = 1;
|
||||
options->opt.maxlen = sizeof(sochdr);
|
||||
options->opt.len = sizeof(sochdr);
|
||||
options->opt.buf = (char *) &sochdr;
|
||||
options->flags = T_NEGOTIATE;
|
||||
if (t_optmgmt(fd, options, options) == -1) {
|
||||
t_error("t_optmgmt");
|
||||
return(0);
|
||||
}
|
||||
options->opt.buf = 0;
|
||||
(void) t_free((char *)options, T_OPTMGMT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
int
|
||||
_tt_bind_endpoint(int fd,
|
||||
char *s,
|
||||
char *r)
|
||||
{
|
||||
return(t_bind(fd, (struct t_bind *)s, (struct t_bind *)r));
|
||||
}
|
||||
#endif /* OPT_TLI */
|
||||
|
||||
|
||||
/*
|
||||
* XXX: the following are needed because of bugs in the C++ header files
|
||||
* for these functions. Should use the native definitions when the header
|
||||
* files are fixed.
|
||||
*/
|
||||
|
||||
extern "C"
|
||||
void
|
||||
_tt_svc_freeargs(SVCXPRT *transp,
|
||||
xdrproc_t inproc,
|
||||
char *in)
|
||||
{
|
||||
svc_freeargs(transp, inproc, in);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int
|
||||
_tt_svc_getargs(SVCXPRT *transp,
|
||||
xdrproc_t inproc,
|
||||
char *in)
|
||||
{
|
||||
return(svc_getargs(transp, inproc, in));
|
||||
}
|
||||
29
cde/lib/tt/lib/mp/mp_rpc_fns.h
Normal file
29
cde/lib/tt/lib/mp/mp_rpc_fns.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_rpc_fns.h /main/3 1995/10/23 10:28:33 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_rpc_fns.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file just implements two function wrappers around two RPC
|
||||
* functions in order to workaround a problem with the C++ header files
|
||||
* (bug has already been submitted).
|
||||
*/
|
||||
#ifndef _TT_MP_RPC_FNS_H
|
||||
#define _TT_MP_RPC_FNS_H
|
||||
#include <stdlib.h>
|
||||
#include <tt_options.h>
|
||||
|
||||
extern "C" { void _tt_svc_freeargs(SVCXPRT *, xdrproc_t, char *); }
|
||||
extern "C" { int _tt_svc_getargs(SVCXPRT *, xdrproc_t, char *); }
|
||||
|
||||
#ifdef OPT_TLI
|
||||
extern "C" { int _tt_bind_endpoint(int, char *, char *); }
|
||||
extern "C" { int _tt_tli_set_nodelay(int fd); }
|
||||
#endif /* OPT_TLI */
|
||||
|
||||
#endif /* _TT_MP_RPC_FNS_H */
|
||||
146
cde/lib/tt/lib/mp/mp_rpc_interface.h
Normal file
146
cde/lib/tt/lib/mp/mp_rpc_interface.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $TOG: mp_rpc_interface.h /main/4 1999/08/30 10:57:58 mgreess $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* @(#)mp_rpc_interface.h 1.9 93/07/30
|
||||
*
|
||||
* mp_rpc_interface.h
|
||||
*
|
||||
* Constants that must be known by both client and server in the
|
||||
* ttsession RPC interface.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#if !defined(_MP_RPC_INTERFACE_H)
|
||||
#define _MP_RPC_INTERFACE_H
|
||||
|
||||
/*
|
||||
* Current ToolTalk RPC protocol version
|
||||
*
|
||||
* 1 1.0 Classic
|
||||
* 2 1.0.1 Asynchronous (i.e. faster) RPCs
|
||||
* 3 1.2 TT_OFFER, TT_HANDLE_PUSH, TT_HANDLE_ROTATE, affecting
|
||||
* any RPC that can send ttsession a new message or pattern:
|
||||
* TT_RPC_DISPATCH
|
||||
* TT_RPC_DISPATCH_2
|
||||
* TT_RPC_DISPATCH_WITH_CONTEXT
|
||||
* TT_RPC_DISPATCH_2_WITH_CONTEXT
|
||||
* TT_RPC_ADD_PATTERN
|
||||
* TT_RPC_ADD_PATTERN_WITH_CONTEXT
|
||||
*/
|
||||
const int TT_RPC_VERSION = 4;
|
||||
const int TT_OFFER_RPC_VERSION = 4;
|
||||
/*
|
||||
* Current ToolTalk XDR protocol version. See tt_xdr_version.h
|
||||
*
|
||||
* 1 1.0 Classic; used by default for all on-disk data structures
|
||||
* 2 1.0.1 new _Tt_string::xdr(); more efficient _Tt_message::xdr(); etc?
|
||||
* 3 1.1 contexts in _Tt_pattern::xdr(), _Tt_signature::xdr();
|
||||
* used in any types database with contextful signatures.
|
||||
* 4 1.2 PUSH, ROTATE in _Tt_pattern::xdr(), _Tt_signature::xdr();
|
||||
* _Tt_arg::_matched_type in _Tt_arg::xdr();
|
||||
* used in any types database with push/rotate signatures.
|
||||
* However, we still use version 3 for the wire, because
|
||||
* PUSH/ROTATE only make a difference in the types database.
|
||||
*/
|
||||
const int TT_XDR_VERSION = 3;
|
||||
const int TT_TYPESDB_DEFAULT_XDR_VERSION = 1;
|
||||
const int TT_CONTEXTS_XDR_VERSION = 3;
|
||||
const int TT_PUSH_ROTATE_XDR_VERSION = 4;
|
||||
|
||||
/*
|
||||
* Default timeout for RPC requests (in seconds).
|
||||
* Use a very large value to indicate almost infinity.
|
||||
* In addition to accommodating a loaded ttsession, it will also
|
||||
* facilitate debugging.
|
||||
* ONE HUNDRED MILLION IS THE MAXIMUM PERMITTED VALUE
|
||||
* ON SunOS 4.1. Use ONE MILLION to leave room for possible weird system
|
||||
* dependencies. That will still allow the sender to wait a patient 11.6 days.
|
||||
*/
|
||||
#define TT_RPC_TMOUT 1000000
|
||||
|
||||
/*
|
||||
* RPC procedure numbers
|
||||
*/
|
||||
/*
|
||||
* Note that each rpc procedure number cannot be re-used. Adding a new
|
||||
* rpc procedure thus means allocating a new number below (and then
|
||||
* bumping up TT_RPC_LAST) and adding the dispatch function to the
|
||||
* _tt_rpc_dispatch_table in mp_rpc_implement.cc. The only exception
|
||||
* to this is TT_RPC_VRFY_SESSION which has an out-of-sequence rpc
|
||||
* number (it is chosen to minimize the likelyhood of being implemented
|
||||
* by another program since the purpose of it is to identify a tooltalk
|
||||
* session.)
|
||||
*/
|
||||
typedef enum {
|
||||
TT_RPC_NULLPROC = 0,
|
||||
TT_RPC_DISPATCH = 1,
|
||||
TT_RPC_UPDATE_MSG = 2,
|
||||
TT_RPC_JOIN_FILE = 3,
|
||||
TT_RPC_QUIT_FILE = 4,
|
||||
TT_RPC_JOIN_SESSION = 5,
|
||||
TT_RPC_QUIT_SESSION = 6,
|
||||
TT_RPC_NEXT_MESSAGE = 7,
|
||||
TT_RPC_ADD_PATTERN = 8,
|
||||
TT_RPC_DEL_PATTERN = 9,
|
||||
TT_RPC_DECLARE_PTYPE = 10,
|
||||
TT_RPC_SET_FD_CHANNEL = 11,
|
||||
TT_RPC_SET_PROP = 12,
|
||||
TT_RPC_ADD_PROP = 13,
|
||||
TT_RPC_GET_PROP = 14,
|
||||
TT_RPC_PROP_COUNT = 15,
|
||||
TT_RPC_PROP_NAME = 16,
|
||||
TT_RPC_PROP_NAMES_COUNT = 17,
|
||||
TT_RPC_ALLOC_PROCID_KEY = 18,
|
||||
TT_RPC_CLOSE_PROCID = 19,
|
||||
TT_RPC_OTYPE_DERIVEDS_COUNT = 20,
|
||||
TT_RPC_OTYPE_DERIVED = 21,
|
||||
TT_RPC_OTYPE_BASE = 22,
|
||||
TT_RPC_OTYPE_IS_DERIVED = 23,
|
||||
TT_RPC_OTYPE_OSIG_COUNT = 24,
|
||||
TT_RPC_OTYPE_HSIG_COUNT = 25,
|
||||
TT_RPC_OTYPE_OSIG_OP = 26,
|
||||
TT_RPC_OTYPE_HSIG_OP = 27,
|
||||
TT_RPC_OTYPE_OSIG_ARGS_COUNT = 28,
|
||||
TT_RPC_OTYPE_HSIG_ARGS_COUNT = 29,
|
||||
TT_RPC_OTYPE_OSIG_ARG_MODE = 30,
|
||||
TT_RPC_OTYPE_HSIG_ARG_MODE = 31,
|
||||
TT_RPC_OTYPE_OSIG_ARG_TYPE = 32,
|
||||
TT_RPC_OTYPE_HSIG_ARG_TYPE = 33,
|
||||
TT_RPC_HDISPATCH = 34,
|
||||
TT_RPC_HUPDATE_MSG = 35,
|
||||
|
||||
/* version 2 numbers */
|
||||
|
||||
TT_RPC_DISPATCH_2 = 36,
|
||||
TT_RPC_UPDATE_MSG_2 = 37,
|
||||
TT_RPC_MSGREAD_2 = 38,
|
||||
|
||||
/* S493 numbers */
|
||||
|
||||
TT_RPC_DISPATCH_ON_EXIT = 39,
|
||||
TT_RPC_UNDECLARE_PTYPE = 40,
|
||||
TT_RPC_EXISTS_PTYPE = 41,
|
||||
TT_RPC_UNBLOCK_PTYPE = 42,
|
||||
TT_RPC_JOIN_CONTEXT = 43,
|
||||
TT_RPC_QUIT_CONTEXT = 44,
|
||||
TT_RPC_DISPATCH_WITH_CONTEXT = 45,
|
||||
TT_RPC_DISPATCH_2_WITH_CONTEXT = 46,
|
||||
TT_RPC_ADD_PATTERN_WITH_CONTEXT = 47,
|
||||
|
||||
/* S1093 numbers */
|
||||
|
||||
TT_RPC_LOAD_TYPES = 48,
|
||||
|
||||
/* Add new RPC numbers before here and bump TT_RPC_LAST */
|
||||
TT_RPC_LAST = 49,
|
||||
|
||||
/* This high number is treated specially */
|
||||
TT_RPC_VRFY_SESSION = 400
|
||||
} _Tt_rpc_procedure_number;
|
||||
|
||||
#endif /* _MP_RPC_INTERFACE_H */
|
||||
917
cde/lib/tt/lib/mp/mp_session.C
Normal file
917
cde/lib/tt/lib/mp/mp_session.C
Normal file
@@ -0,0 +1,917 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_session.C /main/13 1999/09/16 13:46:46 mgreess $
|
||||
/*
|
||||
* @(#)mp_session.C 1.84 96/01/10
|
||||
*
|
||||
* Tool Talk Message Passer (MP) - mp_session.cc
|
||||
*
|
||||
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Implementation of the _Tt_session class.
|
||||
*/
|
||||
#include "util/tt_global_env.h"
|
||||
#include "util/tt_xdr_version.h"
|
||||
#include "util/tt_host.h"
|
||||
#include "util/tt_port.h"
|
||||
#include "util/tt_gettext.h"
|
||||
#include "mp/mp_global.h"
|
||||
#include "mp/mp_message.h"
|
||||
#include "mp/mp_mp.h"
|
||||
#include "mp/mp_c_global.h"
|
||||
#include "mp/mp_c_session.h"
|
||||
#include "mp/mp_c_mp.h"
|
||||
#include "mp/mp_pattern.h"
|
||||
#include "mp/mp_rpc_client.h"
|
||||
#include "mp/mp_rpc_interface.h"
|
||||
#include "mp/mp_session.h"
|
||||
#include "mp/mp_desktop.h"
|
||||
#include "mp/mp_xdr_functions.h"
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef OPT_UNIX_SOCKET_RPC
|
||||
# include <sys/socket.h>
|
||||
# include <sys/un.h>
|
||||
#endif // OPT_UNIX_SOCKET_RPC
|
||||
|
||||
|
||||
_Tt_session::
|
||||
_Tt_session()
|
||||
{
|
||||
_env = _TT_ENV_LAST;
|
||||
_is_server = 0; // default server mode
|
||||
_is_dead = 0;
|
||||
_rpc_version = 0;
|
||||
}
|
||||
|
||||
|
||||
_Tt_session::
|
||||
~_Tt_session()
|
||||
{
|
||||
if (! _desktop.is_null()) {
|
||||
if (_is_server && _env == _TT_ENV_X11 && (_id.len() > 0)) {
|
||||
if ( (! _desktop->del_prop(TT_XATOM_NAME))
|
||||
|| (! _desktop->del_prop(TT_CDE_XATOM_NAME)))
|
||||
{
|
||||
_tt_syslog( 0, LOG_WARNING,
|
||||
catgets( _ttcatd, 1, 14,
|
||||
"could not delete the X "
|
||||
"root window property %s "
|
||||
"advertising this "
|
||||
"session" ),
|
||||
TT_XATOM_NAME );
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef OPT_UNIX_SOCKET_RPC
|
||||
if (_is_server && _socket_name.len()) {
|
||||
(void)unlink((char *)_socket_name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef OPT_UNIX_SOCKET_RPC
|
||||
//
|
||||
// Returns the name of the socket file if the unix socket rpc option is
|
||||
// enabled. Note that the name should be unique for all sessions running
|
||||
// on the same machine so it has to be derived from the session id
|
||||
// (which has the required uniqueness properties).
|
||||
//
|
||||
char * _Tt_session::
|
||||
local_socket_name()
|
||||
{
|
||||
#define SPRFX "/tmp/.TT"
|
||||
|
||||
if (_socket_name.len() == 0) {
|
||||
char *sname = (char *)malloc(_id.len() + strlen(SPRFX) + 1);
|
||||
char *sc;
|
||||
|
||||
sprintf(sname,"%s%s", SPRFX, (char *)_id);
|
||||
sc = sname;
|
||||
while (*sc) {
|
||||
if (*sc == ' ') {
|
||||
*sc = '_';
|
||||
}
|
||||
sc++;
|
||||
}
|
||||
_socket_name = sname;
|
||||
free((MALLOCTYPE *)sname);
|
||||
}
|
||||
|
||||
return((char *)_socket_name);
|
||||
}
|
||||
|
||||
//
|
||||
// Opens a connection to the unix socket bound to the given socket name.
|
||||
// If successful returns the fd for the connection. Otherwise, returns
|
||||
// -1.
|
||||
//
|
||||
int
|
||||
c_open_unix_socket(char *socket_name)
|
||||
{
|
||||
int sock;
|
||||
struct sockaddr_un server_addr;
|
||||
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "c_open_unix_socket(): socket(): %m" );
|
||||
return -1;
|
||||
}
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sun_family = AF_UNIX;
|
||||
strcpy(server_addr.sun_path, socket_name);
|
||||
#if defined(ultrix) || defined(_AIX) || defined(hpux) || defined(__osf__)
|
||||
int servlen = strlen(server_addr.sun_path) + sizeof(server_addr.sun_fam\
|
||||
ily);
|
||||
if (connect(sock, (sockaddr *)&server_addr, servlen) < 0) {
|
||||
#else
|
||||
if (connect(sock, (sockaddr *)&server_addr, sizeof(sockaddr_un)) < 0) {
|
||||
#endif
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(sock);
|
||||
}
|
||||
|
||||
#endif // OPT_UNIX_SOCKET_RPC
|
||||
|
||||
|
||||
//
|
||||
// Called if an event comes in from our desktop connection.
|
||||
//
|
||||
int _Tt_session::
|
||||
desktop_event_callback()
|
||||
{
|
||||
if (! _desktop->process_event()) {
|
||||
return (-1);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Initializes a session with the assumption that the server session is
|
||||
// already running. If the server session isn't running then this method
|
||||
// will return an error as opposed to attempting to autostart a new
|
||||
// session (see _Tt_session::c_init). This is intended as a lower-level
|
||||
// init function used by c_init or whenever autostarting is not required.
|
||||
//
|
||||
// Returns:
|
||||
// TT_OK
|
||||
// TT_ERR_ACCESS Could not init desktop (diagnostic emitted)
|
||||
// TT_WRN_NOTFOUND No advertised address
|
||||
// TT_ERR_INVALID Could not parse advertised address
|
||||
// TT_ERR_NO_MATCH Advertised address's version is too new
|
||||
// (diagnostic emitted)
|
||||
// TT_ERR_ADDRESS Could not find advertised host
|
||||
// TT_ERR_NOMP Could not init as rpc client
|
||||
//
|
||||
Tt_status _Tt_session::
|
||||
client_session_init()
|
||||
{
|
||||
// this is a client of this session. Note that since this
|
||||
// function may be called in the server, we can't use
|
||||
// _tt_mp->in_server().
|
||||
//
|
||||
Tt_status err;
|
||||
int rpc_init_done = 0;
|
||||
_Tt_host_ptr lh;
|
||||
|
||||
|
||||
_is_server = 0;
|
||||
if (env() == _TT_ENV_X11 && _desktop.is_null()) {
|
||||
_desktop = new _Tt_desktop();
|
||||
if (! _desktop->init(_displayname, _TT_DESKTOP_X11)) {
|
||||
return(TT_ERR_ACCESS);
|
||||
}
|
||||
}
|
||||
if (_address_string.len() == 0) {
|
||||
if (find_advertised_address(_address_string) != TT_OK) {
|
||||
return(TT_WRN_NOTFOUND);
|
||||
}
|
||||
}
|
||||
if (_address_string.len() == 0) {
|
||||
// Don't call parsed_address() with an empty string,
|
||||
// or it will think we're trying to create an address
|
||||
// string instead of parse it. parsed_address()
|
||||
// shouldn't be this cute. XXX
|
||||
return TT_ERR_INVALID;
|
||||
}
|
||||
if ((err = parsed_address(_address_string)) != TT_OK) {
|
||||
_address_string = (char *)0;
|
||||
return(err);
|
||||
}
|
||||
if (_TT_AUTH_ICEAUTH == _auth.auth_level() &&
|
||||
(err = _auth.retrieve_auth_cookie()) != TT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (! _tt_global->find_host(_hostaddr, _host, 1)) {
|
||||
return(TT_ERR_ADDRESS);
|
||||
}
|
||||
|
||||
if (_id.len() == 0) {
|
||||
(void)set_id();
|
||||
}
|
||||
|
||||
#ifdef OPT_UNIX_SOCKET_RPC
|
||||
if (_tt_global->get_local_host(lh)) {
|
||||
// if we are in the same host as the server session
|
||||
// then we attempt to connect to its advertised unix
|
||||
// socket to set up an rpc connection. If we succeed
|
||||
// then we set rpc_init_done to 1 to prevent a normal
|
||||
// tcp rpc connection from being made.
|
||||
if (lh->stringaddr() == _host->stringaddr()) {
|
||||
_u_sock = c_open_unix_socket(local_socket_name());
|
||||
if (_u_sock != -1) {
|
||||
_rpc_client = new _Tt_rpc_client(_u_sock);
|
||||
if (_rpc_client->init(lh, _rpc_program,
|
||||
_rpc_version,
|
||||
_server_uid,
|
||||
&_auth)) {
|
||||
rpc_init_done = 1;
|
||||
// Since we opened the fd ourselves,
|
||||
// clnt_destroy won\'t close it
|
||||
// unless we tell it it\'s OK.
|
||||
clnt_control(_rpc_client->rpc_handle(),
|
||||
CLSET_FD_CLOSE,
|
||||
(char *) NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // OPT_UNIX_SOCKET_RPC
|
||||
if (! rpc_init_done) {
|
||||
_rpc_client = new _Tt_rpc_client();
|
||||
if (! _rpc_client->init(_host, _rpc_program, _rpc_version,
|
||||
_server_uid, _auth)) {
|
||||
return(TT_ERR_NOMP);
|
||||
}
|
||||
}
|
||||
|
||||
// Get and save the file descriptor for this session.
|
||||
_tt_mp->save_session_fd(_rpc_client->socket());
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Verifies that the server side of the session is alive and is a
|
||||
// ToolTalk session. Currently this is done by first invoking rpc
|
||||
// procedure 0 to see if the session is responding to rpc requests. If
|
||||
// that succeeds then we invoke rpc procedure TT_RPC_VRFY_SESSION which
|
||||
// is a reasonably large number. The reply to this procedure should be
|
||||
// the session id of the session we're talking to. This is a fairly good
|
||||
// (but not foolproof!) method of verifying that this is a ToolTalk
|
||||
// session.
|
||||
//
|
||||
// In fact it seems to be too picky, if the session id we have is
|
||||
// different only in the IP address, it may just be an alternate
|
||||
// IP address for the very same session.
|
||||
//
|
||||
// Returns:
|
||||
// TT_OK
|
||||
// TT_ERR_NOMP Session unreachable or a hoaxer
|
||||
// TT_ERR_NO_MATCH Session has wrong version
|
||||
// TT_ERR_INVALID Could not parse advertised address
|
||||
// TT_ERR_AUTHORIZATION RPC authorization error
|
||||
//
|
||||
Tt_status _Tt_session::
|
||||
ping()
|
||||
{
|
||||
Tt_status is_live;
|
||||
_Tt_string sid;
|
||||
|
||||
// We used to call the NULLPROC here first, but that seems
|
||||
// to be a waste of a round-trip since it doesn't tell
|
||||
// us anything that the TT_RPC_VRFY_SESSION call doesn't.
|
||||
|
||||
is_live = call((int)TT_RPC_VRFY_SESSION,
|
||||
(xdrproc_t)xdr_void, 0,
|
||||
(xdrproc_t)tt_xdr_string,
|
||||
(char *)&sid);
|
||||
|
||||
// We used to string-compare the returned session id with the one we
|
||||
// have, but that was too picky since the IP address can usefully be
|
||||
// different. Skip the check for now, perhaps we should check at
|
||||
// least some of the components (UNIX pid?) We already know the
|
||||
// transient RPC number is good, and most everything else is
|
||||
// constant. We do make a minimal check that the id string is non
|
||||
// null, this might catch the (unlikely) case where the program at
|
||||
// the other end isn't a ttsession but does happen to have a
|
||||
// procedure with a number the same as TT_RPC_VRFY_SESSION,
|
||||
// although in that case I'd expect the RPC to fail in the
|
||||
// XDR routines.
|
||||
|
||||
if (is_live == TT_OK && 0 == sid.len()) {
|
||||
is_live = TT_ERR_NOMP;
|
||||
}
|
||||
|
||||
|
||||
if (is_live == TT_ERR_UNIMP) {
|
||||
is_live = TT_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
// And finally, for reasons I haven't quite figured out,
|
||||
// if the session id we have *isn't* equal to the one returned
|
||||
// by ttsession, file scoped messages fail. I suspect
|
||||
// pattern matching somewhere compares the ids.
|
||||
// So, if the ttsession thinks its name is different, replace
|
||||
// our idea of the name with its idea of its name.
|
||||
|
||||
if (is_live == TT_OK) {
|
||||
set_id(sid);
|
||||
}
|
||||
|
||||
return(is_live);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Invokes an rpc call named by the rpc_proc parameter on the server
|
||||
// session and returns any results. If timeout is anything other than -1
|
||||
// then it will be used as the timeout value. Otherwise a suitable
|
||||
// timeout value is chosen. If rebind is 1 then a new rpc connection will
|
||||
// be attempted if this rpc fails.
|
||||
//
|
||||
// Returns:
|
||||
// TT_OK
|
||||
// TT_ERR_NOMP Could not talk to session
|
||||
// TT_ERR_VERSION_MISMATCH RPC VERSMISMATCH
|
||||
// TT_ERR_UNIMP rpc_proc not implemented by session
|
||||
// TT_ERR_INVALID Could not parse address
|
||||
// TT_ERR_AUTHORIZATION RPC authorization error
|
||||
//
|
||||
Tt_status _Tt_session::
|
||||
call(int rpc_proc,
|
||||
xdrproc_t xdr_arg_fn, char *arg,
|
||||
xdrproc_t xdr_res_fn, char *res,
|
||||
int timeout, int rebind)
|
||||
{
|
||||
//
|
||||
// Ensure global xdr version is set to proper value for this session.
|
||||
//
|
||||
int xdr_version_2_use = _rpc_version;
|
||||
//
|
||||
// Some rpc calls use an xdr version number that is greater
|
||||
// than the version number of the rpc protocol they exist in.
|
||||
// See e.g. _tt_rpc_add_pattern_with_context().
|
||||
//
|
||||
switch (rpc_proc) {
|
||||
case TT_RPC_ADD_PATTERN_WITH_CONTEXT:
|
||||
if (xdr_version_2_use < TT_CONTEXTS_XDR_VERSION) {
|
||||
xdr_version_2_use = TT_CONTEXTS_XDR_VERSION;
|
||||
}
|
||||
break;
|
||||
}
|
||||
_Tt_xdr_version ver(xdr_version_2_use);
|
||||
Tt_status status;
|
||||
clnt_stat rpc_status;
|
||||
int processing;
|
||||
int retry;
|
||||
int tmout;
|
||||
|
||||
if (_rpc_client.is_null()) {
|
||||
return(TT_ERR_INTERNAL);
|
||||
}
|
||||
|
||||
if (timeout == -1) {
|
||||
switch (rpc_proc) {
|
||||
case TT_RPC_HDISPATCH:
|
||||
case TT_RPC_HUPDATE_MSG:
|
||||
rebind = 1;
|
||||
/* fall through */
|
||||
case TT_RPC_DISPATCH_2:
|
||||
case TT_RPC_DISPATCH_2_WITH_CONTEXT:
|
||||
case TT_RPC_UPDATE_MSG_2:
|
||||
case TT_RPC_MSGREAD_2:
|
||||
tmout = -1;
|
||||
break;
|
||||
default:
|
||||
tmout = TT_RPC_TMOUT;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
tmout = timeout;
|
||||
}
|
||||
|
||||
retry = 5;
|
||||
processing = 1;
|
||||
status = TT_ERR_NOMP;
|
||||
while (processing && retry >= 0) {
|
||||
if (_is_dead) {
|
||||
// We sometimes hang if we call a dead session
|
||||
rpc_status = RPC_CANTRECV;
|
||||
if (! _rpc_client->init(_host, _rpc_program,
|
||||
_rpc_version,
|
||||
_server_uid,
|
||||
_auth)) {
|
||||
status = TT_ERR_NOMP;
|
||||
processing = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
rpc_status = _rpc_client->call(rpc_proc, xdr_arg_fn,
|
||||
arg, xdr_res_fn, res,
|
||||
tmout);
|
||||
}
|
||||
switch (rpc_status) {
|
||||
case RPC_SUCCESS:
|
||||
status = TT_OK;
|
||||
processing = 0;
|
||||
break;
|
||||
case RPC_CANTRECV:
|
||||
_is_dead = 1;
|
||||
status = TT_ERR_NOMP;
|
||||
retry--;
|
||||
break;
|
||||
case RPC_VERSMISMATCH:
|
||||
case RPC_PROGVERSMISMATCH:
|
||||
status = TT_ERR_VERSION_MISMATCH;
|
||||
processing = 0;
|
||||
break;
|
||||
case RPC_TIMEDOUT:
|
||||
if (tmout == 0 || tmout == -1) {
|
||||
// rpc always returns a timeout error if we're
|
||||
// in message-passing mode
|
||||
status = TT_OK;
|
||||
} else {
|
||||
// network errors
|
||||
status = TT_ERR_NOMP;
|
||||
}
|
||||
processing = 0;
|
||||
break;
|
||||
case RPC_CANTSEND:
|
||||
if (!rebind) {
|
||||
status = TT_ERR_NOMP;
|
||||
retry--;
|
||||
break;
|
||||
}
|
||||
// try to rebind _rpc_client and try again
|
||||
if (! _rpc_client->init(_host, _rpc_program,
|
||||
_rpc_version,
|
||||
_server_uid,
|
||||
_auth)) {
|
||||
status = TT_ERR_NOMP;
|
||||
processing = 0;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case RPC_PROCUNAVAIL:
|
||||
// We get this if there is a mild version
|
||||
// mismatch, e.g. a 1.1 library talking to
|
||||
// a 1.0.x server, and one of the new
|
||||
// API calls is used. This is relatively
|
||||
// benign, just let the user know that
|
||||
// his call is unimplemented in this system
|
||||
status = TT_ERR_UNIMP;
|
||||
processing = 0;
|
||||
break;
|
||||
case RPC_AUTHERROR:
|
||||
status = TT_ERR_AUTHORIZATION;
|
||||
processing = 0;
|
||||
break;
|
||||
default:
|
||||
status = TT_ERR_INTERNAL;
|
||||
processing = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == TT_ERR_NOMP &&
|
||||
!_tt_mp->in_server() &&
|
||||
!_tt_c_mp->default_c_session.is_null() &&
|
||||
has_id(_tt_c_mp->default_c_session->address_string())) {
|
||||
_tt_c_mp->default_c_session = NULL;
|
||||
}
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Attempts to find the address of the server session. This is done
|
||||
// according to what kind of environment or session type we're in.
|
||||
//
|
||||
Tt_status _Tt_session::
|
||||
find_advertised_address(_Tt_string &session_addr)
|
||||
{
|
||||
switch (env()) {
|
||||
case _TT_ENV_X11:
|
||||
if ((! _desktop->get_prop(TT_CDE_XATOM_NAME, session_addr)) &&
|
||||
(! _desktop->get_prop(TT_XATOM_NAME, session_addr))) {
|
||||
return(TT_ERR_NOMP);
|
||||
}
|
||||
return(TT_OK);
|
||||
case _TT_ENV_PROCESS_TREE:
|
||||
if (_address_string.len() == 0) {
|
||||
session_addr = _tt_get_first_set_env_var(2, TT_CDE_XATOM_NAME, TT_XATOM_NAME);
|
||||
} else {
|
||||
session_addr = _address_string;
|
||||
}
|
||||
return(TT_OK);
|
||||
case _TT_ENV_LAST:
|
||||
default:
|
||||
return(TT_ERR_NOMP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns a number indicating what type of session we're in.
|
||||
//
|
||||
_Tt_env _Tt_session::
|
||||
env()
|
||||
{
|
||||
if (_tt_mp->in_server()) {
|
||||
if (_env == _TT_ENV_LAST && getenv("DISPLAY")) {
|
||||
_env = _TT_ENV_X11;
|
||||
}
|
||||
return(_env);
|
||||
} else if (_env != _TT_ENV_LAST) {
|
||||
return(_env);
|
||||
} else {
|
||||
if (_tt_get_first_set_env_var(2, TT_CDE_XATOM_NAME, TT_XATOM_NAME)) {
|
||||
return(_env = _TT_ENV_PROCESS_TREE);
|
||||
} else if (getenv("DISPLAY")) {
|
||||
return(_env = _TT_ENV_X11);
|
||||
} else {
|
||||
return(_TT_ENV_LAST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Sets the session-type for the session. This affects how the session id
|
||||
// is advertised to potential clients.
|
||||
//
|
||||
void _Tt_session::
|
||||
set_env(_Tt_env session_env, _Tt_string arg)
|
||||
{
|
||||
_env = session_env;
|
||||
switch (_env) {
|
||||
case _TT_ENV_X11:
|
||||
_displayname = arg;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Returns the ToolTalk session id for the X session named by xdisp. Note
|
||||
// that no actual contact is attempted.
|
||||
//
|
||||
_Tt_string _Tt_session::
|
||||
Xid(_Tt_string xdisp)
|
||||
{
|
||||
return _desktop->session_name(xdisp);
|
||||
}
|
||||
|
||||
/*
|
||||
void _Tt_session::
|
||||
print(FILE *fs) const
|
||||
{
|
||||
fprintf(fs,"_Tt_session::\n");
|
||||
}
|
||||
*/
|
||||
|
||||
//
|
||||
// Used to set or get the address string of a session as well as set
|
||||
// appropiately the _rpc_version field of the session. If addr_string is
|
||||
// null, then parsed_address will set the address string of the session.
|
||||
// In this case, it sets _rpc_version to the default TT_RPC_VERSION. If
|
||||
// addr_string is not null then parsed_address will attempt to parse the
|
||||
// string and extract the information in it. In this case, if the
|
||||
// addr_string happens to be an fcs1 version of session addresses then
|
||||
// _rpc_version is set to 1, otherwise it is set to TT_RPC_VERSION.
|
||||
//
|
||||
// Note that the intended convention for address strings is that only the
|
||||
// information that is known to this method will be parsed out of them.
|
||||
// If there is any information beyond that then it is left uninterpreted.
|
||||
// This means that future ToolTalk versions are free to append
|
||||
// information to the end of an address string (as is already done
|
||||
// below) without compromising compatibility with older clients.
|
||||
//
|
||||
// Returns:
|
||||
// TT_OK
|
||||
// TT_ERR_INVALID Could not parse address
|
||||
// TT_ERR_NO_MATCH Address version is too new (diagnostic emitted)
|
||||
//
|
||||
Tt_status _Tt_session::
|
||||
parsed_address(_Tt_string &addr_string)
|
||||
{
|
||||
#define IPVADDRLEN 16
|
||||
char session_host[IPVADDRLEN];
|
||||
char strid[BUFSIZ];
|
||||
int junk_version = 1;
|
||||
Tt_status status;
|
||||
const char *addr_format_fmt = "%%ld %%d %%d %%d %%lu %%%ds %%d";
|
||||
char addr_format[32];
|
||||
const char *fcs1_addr_format_fmt = "%%ld %%d %%d %%d %%lu %%%ds";
|
||||
char fcs1_addr_format[32];
|
||||
|
||||
//
|
||||
// Note: the fcs 1.0 version of tooltalk uses the first 6
|
||||
// fields in addr_format. Changing these first 6 fields
|
||||
// compromises binary compatibility with the 1.0 version.
|
||||
// Additional fields can be added at the end of addr_format as
|
||||
// long as if the parsing fails then the old format
|
||||
// (fcs1_addr_format) is tried.
|
||||
//
|
||||
_rpc_version = TT_RPC_VERSION;
|
||||
if (addr_string.len() == 0) {
|
||||
int ipaddr_len;
|
||||
|
||||
// set address string
|
||||
if (_host.is_null()) {
|
||||
return(TT_ERR_INTERNAL);
|
||||
}
|
||||
if (_host->stringaddr().len() == 0) {
|
||||
return(TT_ERR_INTERNAL);
|
||||
}
|
||||
|
||||
ipaddr_len = _host->stringaddr().len();
|
||||
if (ipaddr_len > IPVADDRLEN) ipaddr_len = IPVADDRLEN;
|
||||
|
||||
sprintf(fcs1_addr_format, fcs1_addr_format_fmt, ipaddr_len);
|
||||
sprintf(addr_format, addr_format_fmt, ipaddr_len);
|
||||
|
||||
// put version number for format first (this is so we
|
||||
// can change the format later)
|
||||
sprintf(strid, "%02d ", _TT_XATOM_VERSION);
|
||||
sprintf(strid+3, addr_format,
|
||||
(long)_pid,
|
||||
_rpc_program,
|
||||
junk_version,
|
||||
(int)_auth.auth_level(),
|
||||
(long)_server_uid,
|
||||
(char *)_host->stringaddr(),
|
||||
_rpc_version);
|
||||
|
||||
addr_string = strid;
|
||||
if ((status = _auth.set_sessionid(
|
||||
_rpc_program,
|
||||
_auth.auth_level(),
|
||||
_host->stringaddr(),
|
||||
_rpc_version)) != TT_OK) {
|
||||
_tt_syslog(0, LOG_ERR,"_auth.set_sessionid() != TT_OK");
|
||||
return(status);
|
||||
}
|
||||
} else {
|
||||
// get (parse) address string
|
||||
char *str = (char *)addr_string;
|
||||
|
||||
sprintf(fcs1_addr_format, fcs1_addr_format_fmt, IPVADDRLEN);
|
||||
sprintf(addr_format, addr_format_fmt, IPVADDRLEN);
|
||||
|
||||
// check version number of format first
|
||||
|
||||
// XXX: note that if _TT_XATOM_VERSION is ever changed
|
||||
// then backward compatibility is seriously
|
||||
// compromised.
|
||||
|
||||
if (atoi(str) != _TT_XATOM_VERSION) {
|
||||
_tt_syslog( 0, LOG_ERR,
|
||||
catgets( _ttcatd, 1, 15,
|
||||
"address version is %d, but "
|
||||
"I only understand %d! (address: "
|
||||
"<%s>)" ),
|
||||
atoi(str), _TT_XATOM_VERSION,
|
||||
addr_string.operator const char *() );
|
||||
return TT_ERR_NO_MATCH;
|
||||
}
|
||||
|
||||
// XXX: Originally, the fcs1_addr_format put in a
|
||||
// field describing the rpc version of the server.
|
||||
// However, the fcs1 version of client_session_init
|
||||
// erroneously initialized the rpc connection with the
|
||||
// *server* rpc version rather than its own. Thus we
|
||||
// can't use the rpc version field in fcs1_addr_format
|
||||
// because then old fcs1.0 clients would mistakenly
|
||||
// initialize themselves as version 1+ clients. Thus
|
||||
// (sigh) we have to add a field at the end of
|
||||
// fcs1_addr_format that is the real rpc version of
|
||||
// the server. This is the reason that the first rpc
|
||||
// version parsed from addr_format is thrown away.
|
||||
|
||||
long long_pid;
|
||||
long long_server_uid;
|
||||
_Tt_auth_level auth_level;
|
||||
if (7 != sscanf(str+3, addr_format,
|
||||
&long_pid,
|
||||
&_rpc_program,
|
||||
&junk_version, /* always 1 ... */
|
||||
&auth_level,
|
||||
&long_server_uid,
|
||||
session_host,
|
||||
&_rpc_version)) {
|
||||
|
||||
// new format scan failed. Try to parse the
|
||||
// string for the old format
|
||||
|
||||
if (6 != sscanf(str+3, fcs1_addr_format,
|
||||
&long_pid,
|
||||
&_rpc_program,
|
||||
&_rpc_version,
|
||||
&auth_level,
|
||||
&long_server_uid,
|
||||
session_host)) {
|
||||
_pid = (pid_t) long_pid;
|
||||
_server_uid = (uid_t) long_server_uid;
|
||||
return(TT_ERR_INVALID);
|
||||
} else {
|
||||
_rpc_version = 1;
|
||||
}
|
||||
}
|
||||
_pid = (pid_t) long_pid;
|
||||
_server_uid = (uid_t) long_server_uid;
|
||||
_hostaddr = session_host;
|
||||
_auth.set_auth_level(auth_level);
|
||||
if ((status = _auth.set_sessionid(
|
||||
_rpc_program,
|
||||
auth_level,
|
||||
_hostaddr,
|
||||
_rpc_version)) != TT_OK) {
|
||||
_tt_syslog(0, LOG_ERR,"_auth.set_sessionid() != TT_OK");
|
||||
return(status);
|
||||
}
|
||||
}
|
||||
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Sets the id of a session. Note that addressing information (the rpc
|
||||
// number and version) are not part of the id. This makes it possible in
|
||||
// the future to provide server address rebinding.
|
||||
//
|
||||
Tt_status _Tt_session::
|
||||
set_id(char *id)
|
||||
{
|
||||
char host[64];
|
||||
char dpname[125];
|
||||
int svnum;
|
||||
char *ssid;
|
||||
|
||||
if (id != (char *)0) {
|
||||
_id = id;
|
||||
switch (_id[0]) {
|
||||
case 'X':
|
||||
// construct a suitable DISPLAY name from the id
|
||||
// which should have the format "X <host> <server_num>"
|
||||
if (sscanf((char *)id, "X %s %d", host, &svnum) != 2) {
|
||||
return(TT_ERR_SESSION);
|
||||
}
|
||||
sprintf(dpname, "%s:%d", host, svnum);
|
||||
_displayname = dpname;
|
||||
_server_num = svnum;
|
||||
_env = _TT_ENV_X11;
|
||||
break;
|
||||
case 'P':
|
||||
// A process-tree session id is just an address string
|
||||
// preceded by "P ".
|
||||
_address_string = _id.mid(2, _id.len());
|
||||
_env = _TT_ENV_PROCESS_TREE;
|
||||
break;
|
||||
default:
|
||||
return(TT_ERR_SESSION);
|
||||
}
|
||||
|
||||
} else {
|
||||
// set the "id" which is the publicly visible *logical*
|
||||
// address of this session.
|
||||
ssid = _tt_get_first_set_env_var(2, TT_CDE_START_SID, TT_START_SID);
|
||||
if (ssid != (char *)0) {
|
||||
_id = ssid;
|
||||
} else {
|
||||
switch (env()) {
|
||||
case _TT_ENV_X11:
|
||||
_type = "X";
|
||||
if (! _displayname.len()) {
|
||||
_displayname = _tt_global->xdisplayname;
|
||||
}
|
||||
_id = Xid(_displayname);
|
||||
break;
|
||||
case _TT_ENV_PROCESS_TREE:
|
||||
_type = "P";
|
||||
_server_num = _pid;
|
||||
// sami said originally:
|
||||
// we need to include the address string in
|
||||
// the id of a process-tree session because
|
||||
// there is no alternate means of finding
|
||||
// the address (ie. for X11 the id could be
|
||||
// rid of address info because the X server
|
||||
// served as the alternate way of finding
|
||||
// the address).
|
||||
// rfm sez, 16 June 94:
|
||||
// Of course that alternate way was a bad
|
||||
// idea since it means other users can't
|
||||
// send messages using the session because
|
||||
// they can't contact the X server.
|
||||
_id = process_tree_id();
|
||||
break;
|
||||
case _TT_ENV_LAST:
|
||||
default:
|
||||
return(TT_ERR_INTERNAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(TT_OK);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns a process-tree id for this session. This is essentially just
|
||||
// the address of the session preceded by a "P". The purpose of this is
|
||||
// that whenever this exact session needs to be advertised to a
|
||||
// persistent medium (as is done with file-scope messages) this version
|
||||
// of the session id is used so that if the session goes down and comes
|
||||
// up again, the session id stored on disk will become stale.
|
||||
//
|
||||
_Tt_string _Tt_session::
|
||||
process_tree_id()
|
||||
{
|
||||
_Tt_string result = "P ";
|
||||
|
||||
return(result.cat(_address_string));
|
||||
}
|
||||
|
||||
|
||||
bool_t _Tt_session::
|
||||
xdr(XDR *xdrs)
|
||||
{
|
||||
return(_id.xdr(xdrs) && _address_string.xdr(xdrs));
|
||||
}
|
||||
|
||||
|
||||
_Tt_string _Tt_session::
|
||||
address_string()
|
||||
{
|
||||
return(_address_string);
|
||||
}
|
||||
|
||||
_Tt_string _Tt_session::
|
||||
displayname()
|
||||
{
|
||||
return(_displayname);
|
||||
}
|
||||
|
||||
|
||||
_Tt_string
|
||||
_tt_session_address(_Tt_object_ptr &o)
|
||||
{
|
||||
return ((_Tt_session *)o.c_pointer())->address_string();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Returns 1 if the given id is the same as the id of this session or if
|
||||
// it is a process-tree id then it has the same address as this session.
|
||||
//
|
||||
int _Tt_session::
|
||||
has_id(const _Tt_string &id)
|
||||
{
|
||||
if (id == _id) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (id.len() == 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (id == _address_string) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (id[0] == 'P') {
|
||||
_Tt_string addr = id.mid(2,id.len());
|
||||
return(addr == _address_string);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// ...for strings list
|
||||
int _Tt_session::
|
||||
has_id(const _Tt_string_list_ptr slist_p)
|
||||
{
|
||||
_Tt_string_list_cursor c(slist_p);
|
||||
|
||||
while (c.next()) {
|
||||
if (has_id(*c)) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
153
cde/lib/tt/lib/mp/mp_session.h
Normal file
153
cde/lib/tt/lib/mp/mp_session.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $TOG: mp_session.h /main/4 1999/08/30 10:59:15 mgreess $ */
|
||||
/*
|
||||
* @(#)mp_session.h 1.36 95/01/25
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file contains the implementation of the _Tt_session object which
|
||||
* represents the minimal message-passing domain. The primary
|
||||
* responsibility of the _Tt_session is to advertise its presence in
|
||||
* whatever form is appropriate (ie. as an X atom for X11, in the root
|
||||
* directory of an NSE environment, etc.). When the _Tt_session object is
|
||||
* created as part of a client application it represents mostly a
|
||||
* connection to a _Tt_session object that is part of the message server.
|
||||
* This server instance is responsible for storing session-queued
|
||||
* messages, handling RPC requests to the server, and storing client
|
||||
* properties. When clients will be able to join multiple sessions the
|
||||
* server instance of _Tt_session will also be responsible for
|
||||
* forwarding messages to other sessions (ie. the clients still pass
|
||||
* messages through the same default session (to insure the proper
|
||||
* flowcontrol) but those messages are passed on to their respective
|
||||
* sessions.
|
||||
*/
|
||||
#ifndef MP_SESSION_H
|
||||
#define MP_SESSION_H
|
||||
#include "tt_options.h"
|
||||
#include "util/tt_host_utils.h"
|
||||
#include "mp/mp_auth.h"
|
||||
#include "mp/mp_global.h"
|
||||
#include "mp/mp_mp.h"
|
||||
#include "mp/mp_rpc.h"
|
||||
#include "mp/mp_desktop_utils.h"
|
||||
#include "mp/mp_rpc_client_utils.h"
|
||||
#include "mp/mp_session_utils.h"
|
||||
#include "mp/mp_session_prop_utils.h"
|
||||
#include "mp/mp_message_utils.h"
|
||||
#include "mp/mp_pattern_utils.h"
|
||||
#include "mp/mp_procid_utils.h"
|
||||
|
||||
/*
|
||||
* string used to advertise a tt session in both the X and
|
||||
* process-tree sessions. Note that in X ICCCM compliance
|
||||
* dictates that the atom name be prefixed by the vendor
|
||||
* string. Since there's no good reason for them to be different,
|
||||
* the same name is used for process-tree sessions.
|
||||
*/
|
||||
#define TT_XATOM_NAME "_SUN_TT_SESSION"
|
||||
#define TT_CDE_XATOM_NAME "TT_SESSION"
|
||||
#define TT_START_TOKEN "_SUN_TT_TOKEN"
|
||||
#define TT_CDE_START_TOKEN "TT_TOKEN"
|
||||
#define TT_FILE_HINT "_SUN_TT_FILE"
|
||||
#define TT_CDE_FILE_HINT "TT_FILE"
|
||||
#define TT_START_SID "_SUN_TT_SID"
|
||||
#define TT_CDE_START_SID "_TT_SID"
|
||||
enum _Tt_env {
|
||||
_TT_ENV_X11,
|
||||
_TT_ENV_PROCESS_TREE,
|
||||
_TT_ENV_LAST
|
||||
};
|
||||
|
||||
|
||||
class _Tt_session : public _Tt_object {
|
||||
public:
|
||||
_Tt_session();
|
||||
virtual ~_Tt_session();
|
||||
|
||||
_Tt_string address_string();
|
||||
_Tt_string auth_cookie() {
|
||||
return _auth.auth_cookie();
|
||||
}
|
||||
_Tt_auth_level auth_level() {
|
||||
return _auth.auth_level();
|
||||
}
|
||||
Tt_status call(int rpc_proc,
|
||||
xdrproc_t xdr_arg_fn, char *arg,
|
||||
xdrproc_t xdr_res_fn, char *res,
|
||||
int timeout = -1, int rebind = 0);
|
||||
_Tt_env env();
|
||||
const _Tt_host_ptr &host() {
|
||||
return _host;
|
||||
}
|
||||
const _Tt_string &id() const {
|
||||
return _id;
|
||||
}
|
||||
|
||||
Tt_status ping();
|
||||
//void print(FILE *fs = stdout) const;
|
||||
int rpc_program() {
|
||||
return _rpc_program;
|
||||
}
|
||||
int rpc_version() {
|
||||
return _rpc_version;
|
||||
}
|
||||
Tt_status set_auth_level(_Tt_auth_level auth_level) {
|
||||
return _auth.set_auth_level(auth_level);
|
||||
}
|
||||
void set_env(_Tt_env env, _Tt_string arg);
|
||||
_Tt_string Xid(_Tt_string xdisp);
|
||||
bool_t xdr(XDR *xdrs);
|
||||
int desktop_event_callback();
|
||||
_Tt_string displayname();
|
||||
Tt_status set_id(char *sid = (char *)0);
|
||||
Tt_status client_session_init();
|
||||
_Tt_string process_tree_id();
|
||||
|
||||
// Determine if this session is in a list of sessions.
|
||||
int has_id(const _Tt_string &id);
|
||||
int has_id(const _Tt_string_list_ptr slist_p);
|
||||
|
||||
protected:
|
||||
Tt_status auto_start_init();
|
||||
Tt_status client_session_init_byid(_Tt_string sid);
|
||||
Tt_status find_advertised_address(_Tt_string &addr);
|
||||
Tt_status parsed_address(_Tt_string &session_addr);
|
||||
|
||||
//
|
||||
// state variables
|
||||
//
|
||||
_Tt_string _address_string;
|
||||
_Tt_auth _auth;
|
||||
_Tt_string _displayname;
|
||||
_Tt_env _env;
|
||||
_Tt_host_ptr _host;
|
||||
_Tt_string _hostaddr;
|
||||
_Tt_string _id;
|
||||
int _is_server;
|
||||
int _is_dead;
|
||||
pid_t _pid;
|
||||
_Tt_session_prop_list_ptr _properties;
|
||||
_Tt_message_list_ptr _queued_messages;
|
||||
_Tt_rpc_client_ptr _rpc_client;
|
||||
int _rpc_program;
|
||||
int _rpc_version;
|
||||
pid_t _server_num;
|
||||
uid_t _server_uid;
|
||||
_Tt_string _type;
|
||||
_Tt_desktop_ptr _desktop;
|
||||
#ifdef OPT_UNIX_SOCKET_RPC
|
||||
int _u_sock;
|
||||
char *local_socket_name();
|
||||
_Tt_string _socket_name;
|
||||
#endif /* OPT_UNIX_SOCKET_RPC */
|
||||
|
||||
friend class _Tt_s_mp;
|
||||
friend class _Tt_s_session;
|
||||
friend _Tt_mp::find_session_by_fd(int, _Tt_session_ptr &);
|
||||
};
|
||||
|
||||
_Tt_string _tt_session_address(_Tt_object_ptr &o);
|
||||
#endif /* MP_SESSION_H */
|
||||
39
cde/lib/tt/lib/mp/mp_session_prop.C
Normal file
39
cde/lib/tt/lib/mp/mp_session_prop.C
Normal file
@@ -0,0 +1,39 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_session_prop.C /main/3 1995/10/23 10:29:02 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_session_prop.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include "mp/mp_session_prop.h"
|
||||
#include "util/tt_string.h"
|
||||
|
||||
|
||||
_Tt_session_prop::
|
||||
_Tt_session_prop()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_session_prop::
|
||||
_Tt_session_prop(_Tt_string name, _Tt_string_list_ptr values)
|
||||
{
|
||||
_name = name;
|
||||
_values = values;
|
||||
}
|
||||
|
||||
_Tt_session_prop::
|
||||
_Tt_session_prop(_Tt_string name, _Tt_string value)
|
||||
{
|
||||
_name = name;
|
||||
_values = new _Tt_string_list();
|
||||
_values->append(value);
|
||||
}
|
||||
|
||||
_Tt_session_prop::
|
||||
~_Tt_session_prop()
|
||||
{
|
||||
}
|
||||
28
cde/lib/tt/lib/mp/mp_session_prop.h
Normal file
28
cde/lib/tt/lib/mp/mp_session_prop.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_session_prop.h /main/3 1995/10/23 10:29:09 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_session_prop.h
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#if !defined(_MP_SESSION_PROP_H)
|
||||
#define _MP_SESSION_PROP_H
|
||||
|
||||
#include "util/tt_string.h"
|
||||
|
||||
class _Tt_session_prop : public _Tt_object {
|
||||
public:
|
||||
_Tt_session_prop();
|
||||
_Tt_session_prop(_Tt_string name, _Tt_string_list_ptr values);
|
||||
_Tt_session_prop(_Tt_string name, _Tt_string value);
|
||||
virtual ~_Tt_session_prop();
|
||||
_Tt_string _name;
|
||||
_Tt_string_list_ptr _values;
|
||||
};
|
||||
|
||||
#endif
|
||||
16
cde/lib/tt/lib/mp/mp_session_prop_utils.C
Normal file
16
cde/lib/tt/lib/mp/mp_session_prop_utils.C
Normal file
@@ -0,0 +1,16 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_session_prop_utils.C /main/3 1995/10/23 10:29:16 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_session_prop_utils.cc
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "mp/mp_session_prop.h"
|
||||
#include "mp/mp_session_prop_utils.h"
|
||||
|
||||
implement_list_of(_Tt_session_prop)
|
||||
21
cde/lib/tt/lib/mp/mp_session_prop_utils.h
Normal file
21
cde/lib/tt/lib/mp/mp_session_prop_utils.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_session_prop_utils.h /main/3 1995/10/23 10:29:23 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_session_prop_utils.h
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#if !defined(_MP_SESSION_PROP_UTILS_H)
|
||||
#define _MP_SESSION_PROP_UTILS_H
|
||||
#include "util/tt_list.h"
|
||||
|
||||
class _Tt_session_prop;
|
||||
declare_list_of(_Tt_session_prop)
|
||||
|
||||
|
||||
#endif
|
||||
17
cde/lib/tt/lib/mp/mp_session_utils.C
Normal file
17
cde/lib/tt/lib/mp/mp_session_utils.C
Normal file
@@ -0,0 +1,17 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_session_utils.C /main/3 1995/10/23 10:29:30 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_session_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Declaration of auxilliary data structures for the _Tt_session class
|
||||
*/
|
||||
#include <mp/mp_session.h>
|
||||
|
||||
implement_list_of(_Tt_session)
|
||||
implement_table_of(_Tt_session)
|
||||
24
cde/lib/tt/lib/mp/mp_session_utils.h
Normal file
24
cde/lib/tt/lib/mp/mp_session_utils.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_session_utils.h /main/3 1995/10/23 10:29:36 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_session_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Declaration of auxilliary data structures for the _Tt_session class
|
||||
*/
|
||||
#ifndef MP_SESSION_UTILS_H
|
||||
#define MP_SESSION_UTILS_H
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_string.h>
|
||||
#include <util/tt_table.h>
|
||||
class _Tt_session;
|
||||
|
||||
declare_list_of(_Tt_session)
|
||||
declare_table_of(_Tt_session)
|
||||
|
||||
#endif /* MP_SESSION_UTILS_H */
|
||||
590
cde/lib/tt/lib/mp/mp_stream_socket.C
Normal file
590
cde/lib/tt/lib/mp/mp_stream_socket.C
Normal file
@@ -0,0 +1,590 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $TOG: mp_stream_socket.C /main/10 1998/03/19 18:58:53 mgreess $
|
||||
/*
|
||||
*
|
||||
* mp_socket.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include "tt_options.h"
|
||||
#include <stdio.h>
|
||||
#include "mp/mp_stream_socket.h"
|
||||
#if defined(linux)
|
||||
#include <sys/poll.h>
|
||||
#else
|
||||
#include <poll.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <memory.h>
|
||||
#include <errno.h>
|
||||
#include "util/tt_global_env.h"
|
||||
#include "util/tt_host.h"
|
||||
#include "util/tt_port.h"
|
||||
|
||||
#if defined(OPT_TLI)
|
||||
# include <mp/mp_rpc_fns.h>
|
||||
# include <tiuser.h>
|
||||
# if defined(OPT_BUG_USL)
|
||||
extern int t_errno;
|
||||
# endif
|
||||
#else
|
||||
# include <netinet/tcp.h>
|
||||
#endif
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#if defined(ultrix)
|
||||
extern "C" unsigned long inet_addr(char *);
|
||||
#endif
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#if defined(OPT_BUG_USL)
|
||||
extern char *t_errlist[];
|
||||
|
||||
char *t_strerror(int t_errno)
|
||||
{
|
||||
return(t_errlist[t_errno]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Constructs a socket object. Using (char *)0 for host means use the
|
||||
* current host. Specifying a portnum of 0 indicates that the first
|
||||
* available port number should be chosen.
|
||||
*/
|
||||
_Tt_stream_socket::
|
||||
_Tt_stream_socket()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_stream_socket::
|
||||
_Tt_stream_socket(_Tt_host_ptr &host, int portnum)
|
||||
{
|
||||
_msgsock = -1;
|
||||
_host = host;
|
||||
memset(&_hostaddr, 0, sizeof(_hostaddr));
|
||||
_hostaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
_hostaddr.sin_port = htons(portnum);
|
||||
_hostaddr.sin_family = AF_INET;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Closes the connection on the socket.
|
||||
*/
|
||||
_Tt_stream_socket::
|
||||
~_Tt_stream_socket()
|
||||
{
|
||||
#ifndef OPT_TLI
|
||||
close(_sock);
|
||||
close(_msgsock);
|
||||
#else
|
||||
t_close(_sock);
|
||||
if (_msgsock != _sock) {
|
||||
t_close(_msgsock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int _Tt_stream_socket::
|
||||
sock()
|
||||
{
|
||||
return(_sock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the file descriptor associated with a socket.
|
||||
*/
|
||||
int _Tt_stream_socket::
|
||||
fd()
|
||||
{
|
||||
if (_is_source) {
|
||||
if ((_msgsock != -1) || (accept() != -1)) {
|
||||
return(_msgsock);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
} else {
|
||||
return(_sock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the external port number attached to a socket.
|
||||
*/
|
||||
int _Tt_stream_socket::
|
||||
port()
|
||||
{
|
||||
#if defined(OPT_TLI)
|
||||
return(_port);
|
||||
#else
|
||||
return((int)ntohs(_hostaddr.sin_port));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initializes a stream socket. This method must be called before using a
|
||||
* socket to receive messages. The method assumes that if hostname is
|
||||
* (char *)0 then this is the "from" end of a socket. Otherwise, it is
|
||||
* assumed that this is an object which connects to a socket (presumed
|
||||
* already open) on the host named in _host.
|
||||
*/
|
||||
int _Tt_stream_socket::
|
||||
init(int init_as_source)
|
||||
{
|
||||
_Tt_host host;
|
||||
|
||||
#if defined(OPT_TLI)
|
||||
_sock = t_open("/dev/tcp", O_RDWR, 0);
|
||||
if (_sock < 0) {
|
||||
_tt_syslog( 0, LOG_ERR,
|
||||
"_Tt_stream_socket::init(): t_open(): %s",
|
||||
t_strerror( t_errno ) );
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int len;
|
||||
int optval;
|
||||
_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (_sock < 0) {
|
||||
_tt_syslog( 0, LOG_ERR,
|
||||
"_Tt_stream_socket::init(): socket(): %m" );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (-1==fcntl(_sock, F_SETFD, 1)) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"fcntl(F_SETFD): %m");
|
||||
}
|
||||
|
||||
_is_source = init_as_source;
|
||||
if (init_as_source) { /* 'from' end of socket */
|
||||
#if !defined(OPT_TLI)
|
||||
optval = 1;
|
||||
#ifndef linux
|
||||
if (setsockopt(_sock, SOL_SOCKET, SO_USELOOPBACK,
|
||||
(char *)&optval, sizeof(int)) == -1) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"setsockopt(SO_USELOOPBACK): %m" );
|
||||
close(_sock);
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
if (setsockopt(_sock, IPPROTO_TCP, TCP_NODELAY,
|
||||
(char *)&optval, sizeof(int)) == -1) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"setsockopt(TCP_NODELAY): %m" );
|
||||
}
|
||||
|
||||
if (bind(_sock, (struct sockaddr *)&_hostaddr,
|
||||
sizeof(_hostaddr)) < 0) {
|
||||
close(_sock);
|
||||
return(0);
|
||||
}
|
||||
len = sizeof(sockaddr_in);
|
||||
#if defined(_AIX) && (OSMAJORVERSION==4) && (OSMINORVERSION==2)
|
||||
if (getsockname(_sock, (sockaddr *)&_hostaddr, (size_t *)&len)
|
||||
< 0) {
|
||||
#else
|
||||
if (getsockname(_sock, (sockaddr *)&_hostaddr, &len) < 0) {
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
return(listen(_sock,5) == 0);
|
||||
#else
|
||||
struct t_bind *bind;
|
||||
|
||||
if ((bind = (struct t_bind *)t_alloc(_sock, T_BIND, T_ADDR)) ==
|
||||
(struct t_bind *)0) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"t_alloc(T_BIND): %s",
|
||||
t_strerror( t_errno ) );
|
||||
return(0);
|
||||
}
|
||||
// We use random port selection.
|
||||
// This means that we always let t_bind choose a
|
||||
// suitable port number for us and we ignore the
|
||||
// portnum argument given in the constructor for this
|
||||
// class. If we were ever to claim _Tt_stream_socket
|
||||
// as a general C++ wrapper class for socket/TLI, this
|
||||
// would have to change.
|
||||
bind->addr.len = 0;
|
||||
bind->qlen = 8;
|
||||
if (t_bind(_sock, bind, bind) < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"t_bind(): %s", t_strerror( t_errno ) );
|
||||
t_free((char *)bind, T_BIND);
|
||||
return(0);
|
||||
}
|
||||
_port = ntohs(((sockaddr_in *)(bind->addr.buf))->sin_port);
|
||||
t_free((char *)bind, T_BIND);
|
||||
_srequest = (struct t_call *)t_alloc(_sock, T_CALL, T_ADDR);
|
||||
if (_srequest == (t_call *)0) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"t_alloc(T_CALL): %s",
|
||||
t_strerror( t_errno ) );
|
||||
return(0);
|
||||
}
|
||||
#endif // !OPT_TLI
|
||||
} else { // 'to' end of socket
|
||||
//
|
||||
// If both Client and Server or (To and From) sockets are
|
||||
// on the same host, it is better to use the localhost ip
|
||||
// address. This removes ToolTalks dependency on the state
|
||||
// of the network and permits standalone operation.
|
||||
//
|
||||
// In this instance 'local_host' is the host where ttsession
|
||||
// is running. '_host' is the host where the 'procid'
|
||||
// proccess is running. If both are on the same host, copy
|
||||
// in the the localhost ip address rather than the actual
|
||||
// "configured" ip address.
|
||||
//
|
||||
_Tt_host_ptr local_host;
|
||||
if ( (_tt_global->get_local_host(local_host) ) &&
|
||||
( _host->stringaddr() == local_host->stringaddr() ) ) {
|
||||
//
|
||||
// _host_ == local_host => (both on same host)
|
||||
//
|
||||
_hostaddr.sin_addr.s_addr = inet_addr((char *)"127.0.0.1");
|
||||
} else {
|
||||
//
|
||||
// _host_ != local_host => (on different hosts)
|
||||
//
|
||||
memcpy((char *)&_hostaddr.sin_addr,
|
||||
(char *)_host->addr(),
|
||||
_host->addr_length());
|
||||
}
|
||||
#if !defined(OPT_TLI)
|
||||
// set up socket options to insure that a close will
|
||||
// immediately send the message to a socket. This is
|
||||
// essential for the use of sockets as signalling
|
||||
// mechanisms.
|
||||
|
||||
if (setsockopt(_sock, IPPROTO_TCP, TCP_NODELAY,
|
||||
(char *)&optval, sizeof(int)) == -1) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"setsockopt(TCP_NODELAY): %m" );
|
||||
}
|
||||
|
||||
|
||||
#ifndef linux
|
||||
if (setsockopt(_sock, SOL_SOCKET, SO_USELOOPBACK,
|
||||
(char *)&optval, sizeof(int)) == -1) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"setsockopt(SO_USELOOPBACK): %m" );
|
||||
close(_sock);
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
if (setsockopt(_sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *)&optval, sizeof(int)) == -1) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"setsockopt(SO_REUSEADDR): %m" );
|
||||
close(_sock);
|
||||
return(0);
|
||||
}
|
||||
|
||||
#if defined(sun)
|
||||
// XXX: It's not at all clear that we need to do this
|
||||
// anywhere.. default seems to be don't linger anyway.
|
||||
if (setsockopt(_sock, SOL_SOCKET, ~SO_LINGER,
|
||||
(char *)&optval, sizeof(int)) == -1) {
|
||||
_tt_syslog( 0, LOG_WARNING, "_Tt_stream_socket::init(): "
|
||||
"setsockopt(~SO_LINGER): %m" );
|
||||
}
|
||||
|
||||
#endif // sun
|
||||
if (connect(_sock,
|
||||
(struct sockaddr *)&_hostaddr,
|
||||
sizeof(_hostaddr)) < 0) {
|
||||
close(_sock);
|
||||
return(0);
|
||||
}
|
||||
#else
|
||||
t_call *sndcall, *rcvcall;
|
||||
|
||||
if (t_bind(_sock, 0, 0) < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"t_bind(,0,0): %s", t_strerror( t_errno ) );
|
||||
return(0);
|
||||
}
|
||||
(void)_tt_tli_set_nodelay(_sock);
|
||||
sndcall = (t_call *)t_alloc(_sock, T_CALL, 0);
|
||||
if (sndcall == 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"t_alloc(T_CALL,0): %s",
|
||||
t_strerror( t_errno ) );
|
||||
return(0);
|
||||
}
|
||||
sndcall->addr.maxlen = sizeof(_hostaddr);
|
||||
sndcall->addr.len = sizeof(_hostaddr);
|
||||
sndcall->addr.buf = (char *)&_hostaddr;
|
||||
sndcall->opt.len = 0;
|
||||
sndcall->udata.len = 0;
|
||||
rcvcall = (t_call *)t_alloc(_sock, T_CALL, T_OPT|T_ADDR);
|
||||
if (rcvcall == 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::init(): "
|
||||
"t_alloc(T_CALL, T_OPT|T_ADDR): %s",
|
||||
t_strerror( t_errno ) );
|
||||
if (t_free((char *)sndcall, T_CALL) < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "t_free(): %s",
|
||||
t_strerror( t_errno ) );
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
rcvcall->udata.maxlen = 0;
|
||||
if (t_connect(_sock, sndcall, rcvcall) < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "t_connect(): %s",
|
||||
t_strerror( t_errno ) );
|
||||
sndcall->addr.buf = 0;
|
||||
if (t_free((char *)sndcall, T_CALL) < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "t_free(sndcall): %s",
|
||||
t_strerror( t_errno ) );
|
||||
}
|
||||
if (t_free((char *)rcvcall, T_CALL) < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "t_free(rcvcall): %s",
|
||||
t_strerror( t_errno ) );
|
||||
}
|
||||
t_close(_sock);
|
||||
return(0);
|
||||
}
|
||||
sndcall->addr.buf = 0;
|
||||
if (t_free((char *)sndcall, T_CALL) < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "t_free(sndcall): %s",
|
||||
t_strerror( t_errno ) );
|
||||
}
|
||||
if (t_free((char *)rcvcall, T_CALL) < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "t_free(rcvcall): %s",
|
||||
t_strerror( t_errno ) );
|
||||
}
|
||||
#endif // !OPT_TLI
|
||||
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sends a message to a socket. Since the socket object is used by the mp
|
||||
* primarily to signal clients, a close is done after the write to insure
|
||||
* the message gets flushed out to the receiving socket.
|
||||
*
|
||||
* --> It would be extremely helpful if all the really "fatal" cases of
|
||||
* failing to write to a socket can be identified since this information
|
||||
* could be fed back to the mp server to determine when a process has
|
||||
* died or is no longer listening on a socket.
|
||||
*/
|
||||
int _Tt_stream_socket::
|
||||
send(char *msg, int len)
|
||||
{
|
||||
int rval;
|
||||
|
||||
#ifndef OPT_TLI
|
||||
if ((rval = ::send(_sock, msg, len, 0)) == len) {
|
||||
return(rval);
|
||||
} else {
|
||||
close(_sock);
|
||||
return(0);
|
||||
}
|
||||
#else
|
||||
#if defined(OPT_BUG_USL)
|
||||
t_sync(_sock);
|
||||
#endif
|
||||
if ((rval = t_snd(_sock, msg, len, 0)) == len) {
|
||||
return(rval);
|
||||
} else {
|
||||
_tt_syslog(0, LOG_ERR,
|
||||
"==> ERROR FROM SEND: len = %d, rval = %d, err = %d\n",
|
||||
len, rval, t_errno);
|
||||
t_close(_sock);
|
||||
return(0);
|
||||
}
|
||||
#endif // !OPT_TLI
|
||||
}
|
||||
|
||||
|
||||
int _Tt_stream_socket::
|
||||
accept()
|
||||
{
|
||||
if (_msgsock == -1) {
|
||||
#ifndef OPT_TLI
|
||||
int addrlen = sizeof(sockaddr_in);
|
||||
sockaddr_in saddr;
|
||||
|
||||
#if defined(_AIX) && (OSMAJORVERSION==4) && (OSMINORVERSION==2)
|
||||
_msgsock = ::accept(_sock, (struct sockaddr *)&saddr,
|
||||
(size_t *)&addrlen);
|
||||
#else
|
||||
_msgsock = ::accept(_sock, (struct sockaddr *)&saddr,
|
||||
&addrlen);
|
||||
#endif
|
||||
if (_msgsock < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::accept(): "
|
||||
"accept(): %m" );
|
||||
return -1;
|
||||
}
|
||||
if (-1==fcntl(_msgsock, F_SETFD, 1)) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::accept(): "
|
||||
"fcntl(F_SETFD): %m");
|
||||
}
|
||||
#else
|
||||
int rval;
|
||||
struct t_call *call_data;
|
||||
struct t_bind *bind_data;
|
||||
|
||||
call_data = (struct t_call *)t_alloc(_sock, T_CALL, T_ALL);
|
||||
|
||||
if (t_listen(_sock, call_data) < 0) {
|
||||
_Tt_string errstr(t_strerror(t_errno));
|
||||
if (t_errno == TSYSERR) {
|
||||
// Add in errno info
|
||||
errstr = errstr.cat(": ").cat(strerror(errno));
|
||||
}
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::accept(): "
|
||||
"t_listen(): %s", (char *) errstr );
|
||||
return(-1);
|
||||
}
|
||||
// Since we expect no further connections on this
|
||||
// endpoint, it would theoretically be possible
|
||||
// to use the same fd in arg 1 and arg 2 of t_accept.
|
||||
// This appears to be an actual advantage of TLI over
|
||||
// sockets -- I don't think you can do this with
|
||||
// sockets. However, I can't get it to work!
|
||||
// So what I do is open a new endpoint, accept to
|
||||
// that, and then close the original fd since we
|
||||
// don't need it any more.
|
||||
|
||||
_msgsock = t_open("/dev/tcp", O_RDWR, 0);
|
||||
if (_msgsock < 0) {
|
||||
_tt_syslog( 0, LOG_ERR,
|
||||
"_Tt_stream_socket::accept(): "
|
||||
"t_open(): %s",
|
||||
t_strerror( t_errno ) );
|
||||
t_free((char *)call_data, T_CALL);
|
||||
return -1;
|
||||
}
|
||||
bind_data = (struct t_bind *)t_alloc(_msgsock, T_BIND, T_ALL);
|
||||
if (t_bind(_msgsock, bind_data, bind_data) < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "_Tt_stream_socket::accept(): "
|
||||
"t_bind(): %s", t_strerror( t_errno ) );
|
||||
if (bind_data) t_free((char *)bind_data, T_BIND);
|
||||
if (call_data) t_free((char *)call_data, T_CALL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rval = t_accept(_sock, _msgsock, call_data);
|
||||
if (rval == -1) {
|
||||
_tt_syslog( 0, LOG_ERR, "t_accept(): %s",
|
||||
t_strerror( t_errno ) );
|
||||
t_free((char *)bind_data, T_BIND);
|
||||
t_free((char *)call_data, T_CALL);
|
||||
return(-1);
|
||||
} else {
|
||||
(void)_tt_tli_set_nodelay(_msgsock);
|
||||
if (-1==fcntl(_msgsock, F_SETFD, 1)) {
|
||||
_tt_syslog( 0, LOG_ERR,
|
||||
"_Tt_stream_socket::accept(): "
|
||||
"fcntl(F_SETFD): %m");
|
||||
}
|
||||
}
|
||||
t_free((char *)bind_data, T_BIND);
|
||||
t_free((char *)call_data, T_CALL);
|
||||
t_close(_sock);
|
||||
_sock = _msgsock;
|
||||
#endif // !OPT_TLI
|
||||
}
|
||||
|
||||
return(_msgsock);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Receives a message from a socket. This method will block if there is
|
||||
* no input so if nonblocking is required it should be called only after
|
||||
* the socket fd has been checked for activity.
|
||||
*
|
||||
* --> sockets can be set to be nonblocking. Should this be the default
|
||||
* for the sockets the mp opens?
|
||||
*/
|
||||
int _Tt_stream_socket::
|
||||
recv(char *msg, int msglen)
|
||||
{
|
||||
int rval;
|
||||
|
||||
if (_msgsock == -1 && accept() == -1) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
#ifndef OPT_TLI
|
||||
if ((rval = ::recv(_msgsock, msg, msglen, 0)) < 0) {
|
||||
close(_msgsock);
|
||||
return(-1);
|
||||
}
|
||||
#else
|
||||
int flags;
|
||||
|
||||
rval = t_rcv(_msgsock, msg, msglen, &flags);
|
||||
if (rval == -1) {
|
||||
if (t_errno == TLOOK) {
|
||||
if (t_look(_msgsock) == T_DISCONNECT &&
|
||||
t_rcvdis(_msgsock,(struct t_discon *)0) < 0) {
|
||||
_tt_syslog( 0, LOG_ERR, "t_rcvdis(): %s",
|
||||
t_strerror( t_errno ) );
|
||||
return(-1);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
_tt_syslog( 0, LOG_ERR, "t_rcv(): %s",
|
||||
t_strerror( t_errno ) );
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
#endif // !OPT_TLI
|
||||
msg[rval] = 0;
|
||||
return(rval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// read_would_block is not a predicate. It returns 1 if a read
|
||||
// is safe (would not block. It returns 0 if a read would block,
|
||||
// and -1 if there is some error condition.
|
||||
|
||||
int _Tt_stream_socket::
|
||||
read_would_block()
|
||||
{
|
||||
struct pollfd fds[1];
|
||||
|
||||
fds[0].fd = _msgsock;
|
||||
fds[0].events = POLLIN;
|
||||
fds[0].revents = 0;
|
||||
|
||||
while(-1 == poll(fds, (sizeof fds)/(sizeof (struct pollfd)), 0)) {
|
||||
if (errno==EAGAIN || errno==EINTR) {
|
||||
// interrupted, try again.
|
||||
} else {
|
||||
// something is wrong
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != (fds[0].revents & (POLLHUP|POLLNVAL|POLLERR)) ) {
|
||||
return -1;
|
||||
} else if (0 != (fds[0].revents & POLLIN) ) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
57
cde/lib/tt/lib/mp/mp_stream_socket.h
Normal file
57
cde/lib/tt/lib/mp/mp_stream_socket.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_stream_socket.h /main/3 1995/10/23 10:29:57 rswiston $ */
|
||||
/*
|
||||
* mp_stream_socket.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file implements the _Tt_stream_socket which is an object used to
|
||||
* deal with TCP sockets. The methods for this object handle creation,
|
||||
* destruction and communicating over TCP sockets. Note that the
|
||||
* implementation of stream sockets is tailored specifically to the use
|
||||
* of sockets by the MP as a signalling mechanism. The methods here are
|
||||
* not intended to be a general C++ wrapper for sockets.
|
||||
*/
|
||||
#ifndef MP_STREAM_SOCKET_H
|
||||
#define MP_STREAM_SOCKET_H
|
||||
#include <sys/types.h>
|
||||
#include <tt_options.h>
|
||||
|
||||
#ifdef OPT_TLI
|
||||
# include <tiuser.h>
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_ptr.h>
|
||||
#include <util/tt_host_utils.h>
|
||||
|
||||
class _Tt_stream_socket : public _Tt_object {
|
||||
public:
|
||||
_Tt_stream_socket();
|
||||
_Tt_stream_socket(_Tt_host_ptr &host, int port);
|
||||
virtual ~_Tt_stream_socket();
|
||||
int init(int init_as_source);
|
||||
int send(char *msg, int len);
|
||||
int recv(char *msg, int len);
|
||||
int port();
|
||||
int fd();
|
||||
int sock();
|
||||
int read_would_block();
|
||||
private:
|
||||
int accept();
|
||||
int _is_source;
|
||||
int _msgsock;
|
||||
int _sock;
|
||||
_Tt_host_ptr _host;
|
||||
sockaddr_in _hostaddr;
|
||||
#ifdef OPT_TLI
|
||||
int _port;
|
||||
t_call *_srequest;
|
||||
#endif /* OPT_TLI */
|
||||
};
|
||||
|
||||
|
||||
#endif /* MP_STREAM_SOCKET_H */
|
||||
15
cde/lib/tt/lib/mp/mp_stream_socket_utils.C
Normal file
15
cde/lib/tt/lib/mp/mp_stream_socket_utils.C
Normal file
@@ -0,0 +1,15 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_stream_socket_utils.C /main/3 1995/10/23 10:30:06 rswiston $
|
||||
/*
|
||||
*
|
||||
* mp_stream_socket_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <mp/mp_stream_socket_utils.h>
|
||||
#include <mp/mp_stream_socket.h>
|
||||
|
||||
implement_ptr_to(_Tt_stream_socket)
|
||||
19
cde/lib/tt/lib/mp/mp_stream_socket_utils.h
Normal file
19
cde/lib/tt/lib/mp/mp_stream_socket_utils.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_stream_socket_utils.h /main/3 1995/10/23 10:30:16 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* mp_stream_socket_utils.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef MP_STREAM_SOCKET_UTILS_H
|
||||
#define MP_STREAM_SOCKET_UTILS_H
|
||||
#include <util/tt_object.h>
|
||||
|
||||
class _Tt_stream_socket;
|
||||
declare_ptr_to(_Tt_stream_socket)
|
||||
|
||||
#endif /* MP_STREAM_SOCKET_UTILS_H */
|
||||
40
cde/lib/tt/lib/mp/mp_trace.C
Normal file
40
cde/lib/tt/lib/mp/mp_trace.C
Normal file
@@ -0,0 +1,40 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: mp_trace.C /main/4 1995/11/21 19:25:54 cde-sun $
|
||||
/*
|
||||
* @(#)mp_trace.cc 1.2 93/08/15
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*/
|
||||
#include "mp/mp_trace.h"
|
||||
|
||||
_Tt_msg_trace::_Tt_msg_trace(
|
||||
_Tt_message &msg,
|
||||
_Tt_dispatch_reason reason
|
||||
)
|
||||
{
|
||||
entry( msg, reason );
|
||||
}
|
||||
|
||||
_Tt_msg_trace::_Tt_msg_trace(
|
||||
_Tt_message &msg,
|
||||
const _Tt_procid &recipient
|
||||
)
|
||||
{
|
||||
entry( msg, recipient );
|
||||
}
|
||||
|
||||
_Tt_msg_trace::_Tt_msg_trace(
|
||||
_Tt_message &msg,
|
||||
Tt_state old_state
|
||||
)
|
||||
{
|
||||
entry( msg, old_state );
|
||||
}
|
||||
|
||||
_Tt_msg_trace::~_Tt_msg_trace()
|
||||
{
|
||||
exitq();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user