Initial import of the CDE 2.1.30 sources from the Open Group.

This commit is contained in:
Peter Howkins
2012-03-10 18:21:40 +00:00
commit 83b6996daa
18978 changed files with 3945623 additions and 0 deletions

52
cde/lib/tt/slib/Imakefile Normal file
View File

@@ -0,0 +1,52 @@
XCOMM $TOG: Imakefile /main/7 1999/08/30 11:01:36 mgreess $
#define DoNormalLib YES
#define DoSharedLib NO
#define DoDebugLib NO
#define DoProfileLib NO
#define LibName stt
#define LibHeaders NO
#define LibInstall NO
#define CplusplusSource YES
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
#include <Threads.tmpl>
#include "../tooltalk.tmpl"
DEFINES =
INCLUDES = -I. -I../lib
SRCS = \
mp_ce_attrs.C mp_observer.C mp_observer_utils.C \
mp_otype.C mp_otype_utils.C mp_ptype.C \
mp_ptype_utils.C mp_rpc_implement.C mp_rpc_server.C \
mp_rpc_server_utils.C \
mp_s_file.C mp_s_file_utils.C \
mp_s_message.C mp_s_message_utils.C mp_s_mp.C \
mp_s_pattern.C mp_s_pattern_utils.C mp_s_procid.C \
mp_s_procid_utils.C mp_s_msg_context.C mp_s_pat_context.C \
mp_s_session.C mp_s_session_prop.C mp_s_session_utils.C \
mp_s_xdr_functions.C mp_self_procid.C \
mp_signature.C mp_signature_utils.C mp_typedb.C \
mp_typedb_utils.C tt_isstrerror.C
OBJS = \
mp_ce_attrs.o mp_observer.o mp_observer_utils.o \
mp_otype.o mp_otype_utils.o mp_ptype.o \
mp_ptype_utils.o mp_rpc_implement.o mp_rpc_server.o \
mp_rpc_server_utils.o \
mp_s_file.o mp_s_file_utils.o \
mp_s_message.o mp_s_message_utils.o mp_s_mp.o \
mp_s_pattern.o mp_s_pattern_utils.o mp_s_procid.o \
mp_s_procid_utils.o mp_s_msg_context.o mp_s_pat_context.o \
mp_s_session.o mp_s_session_prop.o mp_s_session_utils.o \
mp_s_xdr_functions.o mp_self_procid.o \
mp_signature.o mp_signature_utils.o mp_typedb.o \
mp_typedb_utils.o tt_isstrerror.o
#include <Library.tmpl>
DependTarget()

View File

@@ -0,0 +1,11 @@
XCOMM $XConsortium: admindefines /main/2 1996/05/07 19:19:28 drk $
#ifdef sun
/*
* Some tooltalk header files contain inline references to internal
* functions. Attempting to compile with -g fails because these
* inline references expand into unresolved symbols. Until tooltalk
* is fixed force use of -g0. See CDExc20311 for details.
*/
# define DebuggableCplusplusDebugFlags -g0
#endif

99
cde/lib/tt/slib/ce.h Normal file
View File

@@ -0,0 +1,99 @@
/*%% (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: ce.h /main/3 1995/10/23 11:48:35 rswiston $ */
/* @(#)ce.h 1.3 %%
*
* XXX: This is a copy of the OW 3.1 CE include file. It's a horrible
* thing to do, but we copy this into the ToolTalk build tree because
* of the way the OW, DeskSet, and ToolTalk builds are intertwined.
* Currently ToolTalk must be built before DeskSet and after Classing
* Engine, because DeskSet uses ToolTalk and ToolTalk uses Classing
* Engine. But, Classing Engine is built as part of DeskSet! To
* break this vicious circle, we copy out the CE include we need to
* compile ToolTalk. Since we expect to completely get off of
* Classing Engine in the next feature release of ToolTalk, this
* is only a temporary measure.
*/
/*
* Classing Engine data types
*/
#ifndef ce_hdr_DEFINED
#define ce_hdr_DEFINED
#include <xview/xv_c_types.h>
/* CE API flags */
#define CE_FLAG_TEST_ALL 0
#define CE_FLAG_TEST_PERMISSIONS 1
/* Name Space handle - an index in the global table of name spaces */
typedef void *CE_NAMESPACE;
/* Entry handle */
typedef void *CE_ENTRY;
/* Attribute handle */
typedef void *CE_ATTRIBUTE;
#if defined(__cplusplus) || defined(__STDC__)
typedef void *(*CE_NAMESPACE_MAP_FUNCTION)(CE_NAMESPACE, void *);
typedef void *(*CE_ENTRY_MAP_FUNCTION)(CE_NAMESPACE, CE_ENTRY, void *);
typedef void *(*CE_ATTR_MAP_FUNCTION)(CE_ATTRIBUTE, char *, void *);
#else
typedef void *(*CE_NAMESPACE_MAP_FUNCTION)();
typedef void *(*CE_ENTRY_MAP_FUNCTION)();
typedef void *(*CE_ATTR_MAP_FUNCTION)();
#endif
/* the extern routines for the classing engine */
EXTERN_FUNCTION( int ce_abort_write, (int) );
EXTERN_FUNCTION( int ce_add_attribute,
(CE_NAMESPACE, CE_ENTRY *, CONST char *, CONST char *, CONST char *, int) );
EXTERN_FUNCTION( int ce_add_entry, (CE_NAMESPACE, CE_ENTRY) );
EXTERN_FUNCTION( int ce_add_namespace, (char *, CE_NAMESPACE *) );
EXTERN_FUNCTION( int ce_alloc_entry, (CE_NAMESPACE, CE_ENTRY *) );
EXTERN_FUNCTION( int ce_alloc_ns_entry, (CE_NAMESPACE, CE_ENTRY *) );
EXTERN_FUNCTION( int ce_commit_write, (int) );
EXTERN_FUNCTION( int ce_begin, (void *) );
EXTERN_FUNCTION( int ce_clone_namespace, (CE_NAMESPACE *) );
EXTERN_FUNCTION( int ce_db_changed, (_VOID_) );
EXTERN_FUNCTION( int ce_end, (_VOID_) );
EXTERN_FUNCTION(char *ce_get_attribute,
(CE_NAMESPACE, CE_ENTRY, CE_ATTRIBUTE) );
EXTERN_FUNCTION( CE_ATTRIBUTE ce_get_attribute_id, (CE_NAMESPACE, CONST char *) );
EXTERN_FUNCTION( char *ce_get_attribute_name, (CE_ATTRIBUTE) );
EXTERN_FUNCTION( int ce_get_attribute_size,
(CE_NAMESPACE, CE_ENTRY, CE_ATTRIBUTE) );
EXTERN_FUNCTION( char *ce_get_attribute_type,
(CE_NAMESPACE, CE_ENTRY, CE_ATTRIBUTE) );
EXTERN_FUNCTION( int ce_get_dbs, (int *, char ***, char ***) );
EXTERN_FUNCTION( CE_ENTRY ce_get_entry, (CE_NAMESPACE, int, DOTDOTDOT) );
EXTERN_FUNCTION( int ce_get_entry_db_info,
(CE_NAMESPACE, CE_ENTRY, char **, char **) );
EXTERN_FUNCTION( CE_NAMESPACE ce_get_namespace_id, (char *) );
EXTERN_FUNCTION( char *ce_get_namespace_name, (CE_NAMESPACE) );
EXTERN_FUNCTION( CE_ENTRY ce_get_ns_entry, (CE_NAMESPACE) );
EXTERN_FUNCTION(void *ce_map_through_attrs,
(CE_NAMESPACE, CE_ENTRY, CE_ATTR_MAP_FUNCTION, void *) );
EXTERN_FUNCTION( void *ce_map_through_entries,
(CE_NAMESPACE, CE_ENTRY_MAP_FUNCTION, void *) );
EXTERN_FUNCTION( void *ce_map_through_namespaces,
(CE_NAMESPACE_MAP_FUNCTION, void *) );
EXTERN_FUNCTION( void *ce_map_through_ns_attrs,
(CE_NAMESPACE, CE_ATTR_MAP_FUNCTION, void *) );
EXTERN_FUNCTION( int ce_modify_attribute,
(CE_NAMESPACE, CE_ENTRY *, char *, char *, char *, int) );
EXTERN_FUNCTION( int ce_remove_attribute,
(CE_NAMESPACE, CE_ENTRY, CE_ATTRIBUTE) );
EXTERN_FUNCTION( int ce_remove_entry, (CE_NAMESPACE, CE_ENTRY) );
EXTERN_FUNCTION( int ce_remove_namespace, (CE_NAMESPACE) );
EXTERN_FUNCTION( int ce_start_write, (char *) );
EXTERN_FUNCTION( int ce_test_ok_to_write, (char *, int) );
#endif ce_hdr_DEFINED

39
cde/lib/tt/slib/ce_err.h Normal file
View 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: ce_err.h /main/3 1995/10/23 11:48:51 rswiston $ */
/* @(#)ce_err.h 1.2 @(#)
* See ce.h in this directory for an explanation of why this piece of
* the Classing Engine is in the ToolTalk directory.
*/
/*
* Error messages used by the CE
*/
#ifndef ce_err_h
#define ce_err_h
#define CE_ERR_INTERNAL_ERROR -1
#define CE_ERR_ERROR_READING_DB 1
#define CE_ERR_WRITE_IN_PROGRESS 2
#define CE_ERR_DB_NOT_LOADED 3
#define CE_ERR_WRITE_NOT_STARTED 4
#define CE_ERR_NAMESPACE_EXISTS 5
#define CE_ERR_NAMESPACE_NOT_EMPTY 6
#define CE_ERR_NAMESPACE_DOES_NOT_EXIST 7
#define CE_ERR_NS_ENTRY_EXISTS 8
#define CE_ERR_ENTRY_NOT_ALLOCED 9
#define CE_ERR_ATTRIBUTE_EXISTS 10
#define CE_ERR_NO_MEMORY 11
#define CE_ERR_NO_PERMISSION_TO_WRITE 12
#define CE_ERR_WRONG_ARGUMENTS 13
#define CE_ERR_ERROR_WRITING_DB 14
#define CE_ERR_OPENING_DB 15
#define CE_ERR_DB_LOCKED 16
#define CE_ERR_ERROR_OPENING_FILE 17
#define CE_ERR_WRONG_DATABASE_VERSION 18
#define CE_ERR_UNKNOWN_DATABASE_NAME 19
#define CE_ERR_BAD_DATABASE_FILE 20
#endif ce_err_h

View File

@@ -0,0 +1,97 @@
//%% (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_ce_attrs.C /main/3 1995/10/23 11:49:31 rswiston $
/* @(#)mp_ce_attrs.C 1.3 @(#)
*
* mp_ce_attrs.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp_ce_attrs.h"
//
// Given an the _Tt_ce_attr enum value x, this method should return the
// string that corresponds to it in a Classing Engine database. Changing
// the strings returned by this method should be done with care as it may
// disable binary compatibility with older Classing Engine databases.
//
const char *
_tt_ce_attr_string(_Tt_ce_attr x)
{
switch (x) {
case _TYPE_NAME:
return "TYPE_NAME";
case _TT_OP:
return "TT_OP";
case _TT_ARG:
return "TT_ARG";
case _TT_SCOPE:
return "TT_SCOPE";
case _TT_MSET_SCOPE:
return "TT_MSET_SCOPE";
case _TT_DISPOSITION:
return "TT_DISPOSITION";
case _TT_MSET_DISPOSITION:
return "TT_MSET_DISPOSITION";
case _TT_MSET_OPNUM:
return "TT_MSET_OPNUM";
case _TT_OPNUM:
return "TT_OPNUM";
case _TT_MSET_HANDLER_PTYPE:
return "TT_MSET_HANDLER_PTYPE";
case _TT_HANDLER_PTYPE:
return "TT_HANDLER_PTYPE";
case _TT_MSET_OTYPE:
return "TT_MSET_OTYPE";
case _TT_OTYPE:
return "TT_OTYPE";
case _TT_PARENT:
return "TT_PARENT";
case _TT_OUT:
return "TT_OUT";
case _TT_IN:
return "TT_IN";
case _TT_INOUT:
return "TT_INOUT";
case _TT_SESSION:
return "TT_SESSION";
case _TT_FILE:
return "TT_FILE";
case _TT_BOTH:
return "TT_BOTH";
case _TT_FILE_IN_SESSION:
return "TT_FILE_IN_SESSION";
case _TT_DISCARD:
return "TT_DISCARD";
case _TT_QUEUE:
return "TT_QUEUE";
case _TT_START:
return "TT_START";
case _TT_CATEGORY:
return "TT_CATEGORY";
case _TT_OBSERVE:
return "TT_OBSERVE";
case _TT_HANDLE:
return "TT_HANDLE";
case _TT_CLASS:
return "TT_CLASS";
case _TT_REQUEST:
return "TT_REQUEST";
case _TT_NOTICE:
return "TT_NOTICE";
case _TT_TOOLTALK_TYPE:
return "SUN_TOOLTALK_TYPE";
case _TT_TOOLTALK_PTYPE:
return "SUN_TOOLTALK_PTYPE";
case _TT_TOOLTALK_OTYPE:
return "SUN_TOOLTALK_OTYPE";
case _TT_TOOLTALK_SIGNATURE:
return "SUN_TOOLTALK_SIGNATURE";
case _TT_CE_ATTR_LAST:
default:
return "! _Tt_ce_attr";
}
}

View File

@@ -0,0 +1,53 @@
/*%% (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_ce_attrs.h /main/3 1995/10/23 11:49:51 rswiston $ */
/*
*
* mp_ce_attrs.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
enum _Tt_ce_attr {
_TYPE_NAME = 0,
_TT_OP,
_TT_ARG,
_TT_SCOPE,
_TT_MSET_SCOPE,
_TT_DISPOSITION,
_TT_MSET_DISPOSITION,
_TT_MSET_OPNUM,
_TT_OPNUM,
_TT_MSET_HANDLER_PTYPE,
_TT_HANDLER_PTYPE,
_TT_MSET_OTYPE,
_TT_OTYPE,
_TT_PARENT,
_TT_OUT,
_TT_IN,
_TT_INOUT,
_TT_SESSION,
_TT_FILE,
_TT_BOTH,
_TT_FILE_IN_SESSION,
_TT_DISCARD,
_TT_QUEUE,
_TT_START,
_TT_CATEGORY,
_TT_OBSERVE,
_TT_HANDLE,
_TT_CLASS,
_TT_REQUEST,
_TT_NOTICE,
_TT_TOOLTALK_TYPE,
_TT_TOOLTALK_PTYPE,
_TT_TOOLTALK_OTYPE,
_TT_TOOLTALK_SIGNATURE,
_TT_CE_ATTR_LAST
};
const char *_tt_ce_attr_string(_Tt_ce_attr);

View File

@@ -0,0 +1,51 @@
//%% (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_observer.C /main/3 1995/10/23 11:50:12 rswiston $
/*
*
* mp_observer.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp_observer.h"
//
// Methods for _Tt_observer objects which just serve as records that
// hold the message fields in a _Tt_message object that can be
// different for static observers. See _Tt_s_message documentation for
// more details.
//
_Tt_observer::
_Tt_observer()
{
_ptid = (char *)0;
_reliability = TT_DISCARD;
_opnum = -1;
}
_Tt_observer::
_Tt_observer(_Tt_string ptid, int opnum,
Tt_disposition reliability, Tt_scope s)
{
_ptid = ptid;
_reliability = reliability;
_opnum = opnum;
_scope = s;
}
_Tt_observer::
~_Tt_observer()
{
}

View 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. */
/*%% $XConsortium: mp_observer.h /main/3 1995/10/23 11:50:34 rswiston $ */
/*
*
* mp_observer.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#ifndef _MP_OBSERVER_H
#define _MP_OBSERVER_H
#include <mp/mp_global.h>
class _Tt_observer : public _Tt_object {
public:
_Tt_observer();
_Tt_observer(_Tt_string ptid,
int opnum,
Tt_disposition reliability,
Tt_scope s = TT_SCOPE_NONE);
virtual ~_Tt_observer();
_Tt_string &ptid() {
return _ptid;
}
Tt_disposition reliability() {
return _reliability;
}
void set_reliability(Tt_disposition r) {
_reliability = r;
}
Tt_state state() {
return _state;
}
int opnum() {
return _opnum;
}
Tt_scope scope() {
return _scope;
}
void set_scope(Tt_scope s) {
_scope = s;
}
void set_state(Tt_state s) {
_state = s;
}
private:
Tt_state _state;
Tt_scope _scope;
_Tt_string _ptid;
int _opnum;
Tt_disposition _reliability;
};
#endif /* _MP_OBSERVER_H */

View 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_observer_utils.C /main/3 1995/10/23 11:50:56 rswiston $
/*
*
* mp_observer_utils.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp_observer_utils.h"
#include "mp_observer.h"
implement_list_of(_Tt_observer)

View 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_observer_utils.h /main/3 1995/10/23 11:51:11 rswiston $ */
/*
*
* mp_observer_utils.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#ifndef MP_OBSERVER_UTILS_H
#define MP_OBSERVER_UTILS_H
#include <util/tt_object.h>
#include <util/tt_list.h>
class _Tt_observer;
declare_list_of(_Tt_observer)
#endif /* MP_OBSERVER_UTILS_H */

347
cde/lib/tt/slib/mp_otype.C Normal file
View File

@@ -0,0 +1,347 @@
//%% (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_otype.C /main/4 1998/03/20 14:27:39 mgreess $
/*
* mp_otype.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include <stdlib.h>
#if defined(linux)
# include <g++/minmax.h>
#else
# include <macros.h>
#endif
#include "mp/mp_global.h"
#include "mp_s_mp.h"
#include "mp_otype.h"
#include "mp_otype_utils.h"
#include "mp_ce_attrs.h"
#include "util/tt_enumname.h"
#include "util/tt_iostream.h"
//
// This file contains methods for _Tt_otype objects which embody the
// behavior of otype definitions.
//
_Tt_otype::
_Tt_otype()
{
_ancestors = new _Tt_string_list();
_children = (_Tt_string_list *)0;
_inhs = new _Tt_signature_list();
_osigs = new _Tt_signature_list();
_hsigs = new _Tt_signature_list();
visitp = 0;
ce_entry = 0;
}
bool_t _Tt_otype::
xdr(XDR *xdrs)
{
return(_otid.xdr(xdrs) &&
_ancestors.xdr(xdrs) &&
_inhs.xdr(xdrs) &&
_osigs.xdr(xdrs) &&
_hsigs.xdr(xdrs) &&
xdr_int(xdrs, &visitp));
}
_Tt_otype::
_Tt_otype(_Tt_string otid)
{
_ancestors = new _Tt_string_list();
_children = (_Tt_string_list *)0;
_inhs = new _Tt_signature_list();
_osigs = new _Tt_signature_list();
_hsigs = new _Tt_signature_list();
_otid = otid;
visitp = 0;
ce_entry = 0;
}
_Tt_otype::
~_Tt_otype()
{
}
void _Tt_otype::
set_otid(_Tt_string otid)
{
_otid = otid;
}
void _Tt_otype::
set_ancestors(_Tt_string_list_ptr ancs)
{
_ancestors = ancs;
}
//
// Appends an inherited signature to this object if there isn't the
// same signature already.
//
void _Tt_otype::
append_inhs(_Tt_signature_ptr sig)
{
if (_inhs.is_null()) {
_inhs = new _Tt_signature_list();
_inhs->push(sig);
} else {
_Tt_signature_list_cursor sc(_inhs);
while (sc.next()) {
if (**sc == *sig) {
return;
}
}
_inhs->append(sig);
}
}
//
// Appends an observer signature to this object if there isn't the
// same signature already.
//
void _Tt_otype::
append_osig(_Tt_signature_ptr sig)
{
sig->set_pattern_category(TT_OBSERVE);
if (_osigs.is_null()) {
_osigs = new _Tt_signature_list();
_osigs->push(sig);
} else {
_Tt_signature_list_cursor sc(_osigs);
while (sc.next()) {
if (**sc == *sig) {
return;
}
}
_osigs->append(sig);
}
}
//
// Appends a handler signature to this object if there isn't the same
// signature already.
//
void _Tt_otype::
append_hsig(_Tt_signature_ptr sig, Tt_category category)
{
sig->set_pattern_category(category);
if (_hsigs.is_null()) {
_hsigs = new _Tt_signature_list();
_hsigs->push(sig);
} else {
_Tt_signature_list_cursor sc(_hsigs);
while (sc.next()) {
if (**sc == *sig) {
return;
}
}
_hsigs->append(sig);
}
}
//
// Appends a list of observer signatures to this object.
//
void _Tt_otype::
append_osigs(_Tt_signature_list_ptr sigs)
{
_Tt_signature_list_cursor sc(sigs);
while (sc.next()) {
sc->set_pattern_category(TT_OBSERVE);
}
if (_osigs.is_null()) {
_osigs = sigs;
} else {
_osigs->append_destructive(sigs);
}
}
//
// Appends a list of handler signature to this object.
//
void _Tt_otype::
append_hsigs(_Tt_signature_list_ptr sigs, Tt_category category)
{
_Tt_signature_list_cursor sc(sigs);
while (sc.next()) {
sc->set_pattern_category(category);
}
if (_hsigs.is_null()) {
_hsigs = sigs;
} else {
_hsigs->append_destructive(sigs);
}
}
//
// Prints out a _Tt_otype object. Note that the format used to print
// the object is the format used to represent this object to the
// Classing Engine. It is important to preserve this characteristic
// for compatibility's sake.
//
void _Tt_otype::
print(const _Tt_ostream &os) const
{
_Tt_string_list_cursor anc;
FILE *fs = os.theFILE();
if (_otid.len()) {
fprintf(fs, "\t(\n\t\t(%s,%s,<",
_tt_ce_attr_string(_TYPE_NAME),
_tt_ce_attr_string(_TT_TOOLTALK_OTYPE));
_otid.print(fs);
fputs(">)\n", fs);
fprintf(fs,"\t\t(%s,string,<%s>)\n",
_tt_ce_attr_string(_TT_TOOLTALK_TYPE),
_tt_ce_attr_string(_TT_TOOLTALK_OTYPE));
if (! _ancestors.is_null()) {
anc.reset(_ancestors);
while (anc.next()) {
fprintf(fs,"\t\t(%s,string,<%s>)\n",
_tt_ce_attr_string(_TT_PARENT),
(char *)*anc);
}
}
fprintf(fs,"\t)");
}
}
//
// Returns a list of descendant otypes from this otype.
//
_Tt_string_list_ptr & _Tt_otype::
children()
{
_Tt_otype_table_cursor c;
_Tt_string_list_ptr plist;
_Tt_string parname;
_Tt_otype_ptr cparent;
if (!_children.is_null()) {
return _children;
}
_children = new _Tt_string_list;
c.reset(_tt_s_mp->otable);
while(c.next()) {
plist = c->parents();
if (!plist.is_null() && plist->count()!=0) {
parname = plist->top();
if (! _tt_s_mp->otable->lookup(parname,cparent)) {
if (cparent->otid() == otid()) {
_children->append(c->otid());
}
}
}
}
return _children;
}
_Tt_string_list_ptr & _Tt_otype::
parents()
{
return _ancestors;
}
_Tt_signature_list_ptr &_Tt_otype::
hsigs()
{
return _hsigs;
}
_Tt_signature_list_ptr &_Tt_otype::
osigs()
{
return _osigs;
}
int _Tt_otype::
xdr_version_required() const
{
int version = _Tt_signature::xdr_version_required_( _hsigs );
return max(version, _Tt_signature::xdr_version_required_( _osigs ));
}
//
// Prints out an otype object in source format. This means that the
// otype is printed out in such a fashion that the result is parseable
// by tt_type_comp and when parsed would reproduce the essential
// structure of this object.
//
void _Tt_otype::
pretty_print(const _Tt_ostream &os) const
{
_Tt_string_list_cursor anc;
FILE *fs = os.theFILE();
fprintf(fs,"otype ");
_otid.print(fs);
if (! _ancestors.is_null() && _ancestors->count()) {
fprintf(fs," :");
anc.reset(_ancestors);
while (anc.next()) {
fprintf(fs," %s", (char *)*anc);
}
}
fprintf(fs," {\n");
_Tt_signature::pretty_print_( os, _hsigs, TT_HANDLE, 0 );
_Tt_signature::pretty_print_( os, _hsigs, TT_HANDLE_PUSH, 0 );
_Tt_signature::pretty_print_( os, _hsigs, TT_HANDLE_ROTATE, 0 );
_Tt_signature::pretty_print_( os, _osigs, TT_OBSERVE, 0 );
fprintf(fs,"};\n");
}
//
// Returns the otid of the given _Tt_object which is assumed to be a
// _Tt_otype object. This is used by the generic table package to
// generate a key for an entry in the table.
//
_Tt_string
_tt_otype_otid(_Tt_object_ptr &o)
{
return(((_Tt_otype *)o.c_pointer())->otid());
}
//
// Invokes the print method on the given _Tt_object which is assumed to
// really point to a _Tt_otype object. This is used by the generic table
// and list objects in their print methods.
//
void
_tt_otype_print(const _Tt_ostream &os, const _Tt_object *obj)
{
((_Tt_otype *)obj)->print(os);
}

View File

@@ -0,0 +1,64 @@
/*%% (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_otype.h /main/3 1995/10/23 11:51:41 rswiston $ */
/*
* Tool Talk Message Passer (MP) - mp_otype.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* Declaration of the _Tt_otype class representing an in-memory object type
* definition.
*/
#ifndef _MP_OTYPE_H
#define _MP_OTYPE_H
#include "mp_signature.h"
#include "util/tt_table.h"
typedef char **(*_Tt_otype_filter)(char *otid,
void *context,
void *accumulator);
class _Tt_types_table;
class _Tt_otype : public _Tt_object {
public:
_Tt_otype();
_Tt_otype(_Tt_string otid);
virtual ~_Tt_otype();
_Tt_string_list_ptr &children();
_Tt_string_list_ptr &parents();
const _Tt_string & otid() const {return _otid;};
void set_otid(_Tt_string s);
_Tt_signature_list_ptr &hsigs();
_Tt_signature_list_ptr &osigs();
void set_ancestors(_Tt_string_list_ptr ancs);
void append_inhs(_Tt_signature_ptr sig);
void append_osig(_Tt_signature_ptr sig);
void append_hsig(_Tt_signature_ptr sig,
Tt_category category);
void append_osigs(_Tt_signature_list_ptr sigs);
void append_hsigs(_Tt_signature_list_ptr sigs,
Tt_category category);
void print(const _Tt_ostream &os) const;
void pretty_print(const _Tt_ostream &os) const;
bool_t xdr(XDR *xdrs);
void *ce_entry;
int xdr_version_required() const;
friend class _Tt_types_table;
private:
friend class _Tt_typedb;
_Tt_string _otid;
_Tt_string_list_ptr _ancestors;
_Tt_string_list_ptr _children;
_Tt_signature_list_ptr _inhs;
_Tt_signature_list_ptr _osigs;
_Tt_signature_list_ptr _hsigs;
int visitp;
};
_Tt_string _tt_otype_otid(_Tt_object_ptr &o);
void _tt_ptype_print(const _Tt_ostream &os, const _Tt_object *obj);
#endif /* _MP_OTYPE_H */

View 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_otype_utils.C /main/3 1995/10/23 11:51:51 rswiston $
/*
*
* mp_otype_utils.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp_otype_utils.h"
#include "mp_otype.h"
implement_list_of(_Tt_otype)
implement_table_of(_Tt_otype)

View File

@@ -0,0 +1,22 @@
/*%% (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_otype_utils.h /main/3 1995/10/23 11:52:03 rswiston $ */
/*
*
* mp_otype_utils.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#ifndef MP_OTYPE_UTILS_H
#define MP_OTYPE_UTILS_H
#include <util/tt_object.h>
#include <util/tt_string.h>
#include <util/tt_table.h>
class _Tt_otype;
declare_list_of(_Tt_otype)
declare_table_of(_Tt_otype)
#endif /* MP_OTYPE_UTILS_H */

889
cde/lib/tt/slib/mp_ptype.C Normal file
View File

@@ -0,0 +1,889 @@
//%% (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_ptype.C /main/4 1998/03/20 14:27:56 mgreess $
#include <stdlib.h>
#if defined(linux)
# include <g++/minmax.h>
#else
# include <macros.h>
#endif
#include "util/tt_global_env.h"
#include "util/tt_port.h"
#include "util/tt_gettext.h"
#include "mp/mp_session.h"
#include "mp_ce_attrs.h"
#include "mp_signature.h"
#include "mp_ptype.h"
#include "mp_s_mp.h"
#include "mp_s_message.h"
#include "util/tt_enumname.h"
#include <fcntl.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
//
// _Tt_ptype_prop represents a ptype property. Some common properties
// include the start string, per_session, and per_file properties.
//
// XXX: In fact there are only three properties in use. Perhaps it would
// be better to just add those fields to the ptype object than have a
// full attribute/value list.
//
_Tt_ptype_prop::
_Tt_ptype_prop()
{
}
_Tt_ptype_prop::
_Tt_ptype_prop(_Tt_string aname, _Tt_string avalue)
{
_name = aname; /* shared */
_value = avalue;
}
_Tt_ptype_prop::
~_Tt_ptype_prop()
{
}
bool_t _Tt_ptype_prop::
xdr(XDR *xdrs)
{
return(_name.xdr(xdrs) && _value.xdr(xdrs));
}
_Tt_string _Tt_ptype_prop::
name()
{
return _name;
}
_Tt_string _Tt_ptype_prop::
value()
{
return _value;
}
//
// Prints out a ptype prop. Note that this method is used to print out
// ptype properties in a way compatible with a Classing Engine format
// file. Therefore, changing the output of this method could hurt
// compatibility with CE databases.
//
void _Tt_ptype_prop::
print(const _Tt_ostream &os) const
{
os << "\t\t(" << _name << ",string,<" << _value << ">)\n";
}
//
// Prints out a ptype property in "source" format. It is used by
// _Tt_ptype::pretty_print to print out a ptype definition in such a way
// that it can be parsed by tt_type_comp.
//
void _Tt_ptype_prop::
pretty_print(const _Tt_ostream &os) const
{
if (_name == "start") {
os << _name << " \"" << _value;
// if the start string ends with a double-quote then
// just print it out without a double-quote at the
// end. Otherwise print out the double-quote at the
// end. This nonsense is made necessary because
// version 1 tt_type_comp would parse the start string
// so that the ending double-quote was made part of
// the string.
if (_value[_value.len() - 1] != '\"') {
os << '"';
}
os << ";\n";
} else {
os << _name << " " << _value << ";\n";
}
}
_Tt_ptype::
_Tt_ptype()
{
if (_tt_mp && _tt_mp->in_server()) {
_queued_messages = new _Tt_s_message_list();
}
_props = new _Tt_ptype_prop_list();
_osigs = new _Tt_signature_list();
_hsigs = new _Tt_signature_list();
_start_pid = 0;
_launching = 0;
ce_entry = 0;
}
_Tt_ptype::
~_Tt_ptype()
{
}
//
// Returns the value of the given property name for this ptype.
//
int _Tt_ptype::
getprop(_Tt_string propname, _Tt_string &value)
{
_Tt_ptype_prop_list_cursor propc;
propc.reset(_props);
while (propc.next()) {
if (propc->name() == propname) {
value = propc->value();
return(1);
}
}
return(0);
}
//
// Launches a new instance of this ptype. The message that caused the
// start is also given so that selected fields from the message can be
// defined as environment variables.
//
// The design of the starting mechanism is biased towards starting the
// fewest number of applications per message. This is done as follows:
//
// - If there are no messages queued on this ptype then a new instance of
// the ptype is launched and the message is put on the queue of messages
// for this ptype. If not done already, a start token is assigned to this
// ptype. (see _Tt_ptype::launch for details)
//
// - If there are messages queued on this ptype then the message is
// simply added to the end of the queue.
//
// The messages get dequeued as follows:
//
// - When the procid that was started joins this session, it will send us
// the start token back. This tells us which procid corresponds to the
// ptype instance that we just started. We then take the first message on
// the ptype queue and send it to the procid (without
// pattern-matching!). See _Tt_ptype::proc_started for details.
//
// - Eventually, the procid will accept or reply to this message. At this
// point we know all the patterns that this procid will register in order to
// further accept messages queued for its ptype. So we proceed to attempt
// delivery of the rest of the queued messages on this ptype. This is done
// by trying the first message, if it is delivered then we continue with the
// next message. If the message causes another start then it is put at the
// front of the queue and things proceed the same way as for the first
// message that caused a start. None of the other messages are dequeued.
// See _Tt_ptype::proc_replied for details.
//
// What this algorithm accomplishes is starting the minimum amount of
// ptype instances per queue of messages. However, it doesn't handle the
// case that before the ptype instance that we started, another instance
// gets started (perhaps by the user) and registers patterns before the
// one we are waiting on.
//
// Cycle detection/Launch failure
//
// If a newly-started ptype fails (ie. it core-dumps while starting or
// else gets aborted) then we have to be careful not to keep starting the
// same ptype. There is the danger that if we're too conservative and
// just immediately fail all the messages, then some messages won't end
// up getting sent. On the other hand if we keep trying to deliver the
// messages we may end up in a cycle continually trying to fork a bad
// application.
//
// The position taken here leans towards the conservative side:
//
// - messages are re-delivered against the current patterns but they are
// tagged so that they won't cause any more starts of this ptype.
//
// The idea behind this compromise is that either an app died abnormally
// in which case the safest option is to not try to start it again or
// else it was terminated by the user in which case we should also not
// start another instance. For requests, the sender will get a TT_FAILED
// state back along with a status field indicating the app was
// terminated. In these cases the sender can take appropiate action.
// Notifications that are important (such as a "content_changed" message
// for LinkService) should be queued in any case so that they will
// eventually get delivered.
//
// See _Tt_ptype::launch_failed for details.
//
Tt_status _Tt_ptype::
start(_Tt_s_message_ptr &m, const _Tt_msg_trace &trace)
{
Tt_status status;
_queued_messages->append(m);
if ((! launching()) && _queued_messages->count() == 1) {
// m was the first message for this ptype, launch a
// new instance
status = launch(m, trace);
if (status != TT_OK) {
_tt_syslog(0, LOG_ERR, "_Tt_ptype::launch(): %s",
_tt_enumname( status ));
// launching the ptype failed. dequeue the
// message from this ptype since it is going
// to get failed at a higher-layer.
(void)_queued_messages->pop();
return(status);
}
}
return(TT_OK);
}
//
// Launches an instance of this ptype. Sets up some environment
// variables (documented below) crucial to the start process. This
// method should never be used directly but rather it is used only by
// _Tt_ptype::start if that method determines that launching a new
// instance of this ptype is really necessary.
//
Tt_status _Tt_ptype::
launch(_Tt_s_message_ptr &m, const _Tt_msg_trace &trace)
{
_Tt_string start_string_prop("start");
_Tt_string start_cmd = (char *)0;
_Tt_ptype_prop_list_cursor propc;
char *cargv[4];
int maxfds;
pid_t pid;
//
// Find out what the start string for this ptype is.
//
if (! getprop(start_string_prop, start_cmd)) {
// no start string specified in ptype
// XXX: should the type compiler catch this
// condition?
return(TT_ERR_PTYPE);
}
//
// set the _launching flag. This flag will only get cleared
// when it is known that the procid corresponding to this
// starting ptype has appeared (see _Tt_ptype::proc_replied).
//
_launching = 1;
//
// fork and exec the start string for this ptype.
//
switch ((pid = fork())) {
case -1:
_tt_syslog(0, LOG_ERR, "fork(): %m");
return(TT_ERR_INTERNAL);
case 0:
//
// Establish the environment for the new process. Note that
// the actual names of the variables are defined in
// mp_session.h
//
// The TT_CDE_FILE_HINT or TT_FILE_HINT environment variable
//is used by the started application only. It points to the
//file field of the start message.
if (0 != m->file().len() &&
_tt_put_all_env_var( 2,
_tt_network_path_to_local_path(m->file()),
TT_CDE_FILE_HINT, TT_FILE_HINT)
!= 2) {
exit(1);
}
// The TT_CDE_START_TOKEN or TT_START_TOKEN environment
// variable is used by the client-side library. It is a
// signal to the client-side method
// _Tt_mp::create_new_procid that the launched process is an
// instance of the ptype pointed to by this environment
// variable. This token is then handed back to the server by
// _Tt_c_procid::set_fd_channel so that the server can match
// up the actual procid with the instance of the ptype it
// was launching.
if (_tt_put_all_env_var(2, _ptid,
TT_CDE_START_TOKEN,
TT_START_TOKEN)
!= 2) {
exit(1);
}
// The TT_CDE_XATOM_NAME and TT_XATOM_NAME environment
// variables point to the address string for the server
// session. These will get used by the client-side library
// to connect to this session.
if (_tt_put_all_env_var(2,
_tt_mp->initial_session->address_string(),
TT_CDE_XATOM_NAME, TT_XATOM_NAME)
!= 2) {
exit(1);
}
// The TT_CDE_START_SID or TT_START_SID environment variable
// points to the server session's id. Note that since the
// TT_CDE_XATOM_NAME and TT_XATOM_NAME environment variables
// are set above to the address, the client-side library
// would think this it is starting in a process-tree
// session. However, if TT_CDE_START_SID or TT_START_SID is
// also set then it will get used to set the id of the
// client session (which should always be the same as the
// one for the server session). See _Tt_session::set_id
if (_tt_put_all_env_var(2, _tt_mp->initial_session->id(),
TT_CDE_START_SID,
TT_START_SID)
!= 2) {
exit(1);
}
// set up DISPLAY variable so started application will start
// up in the same X display as this one.
if (0!=_tt_mp->initial_session->displayname().len() &&
_tt_putenv("DISPLAY",
_tt_mp->initial_session->displayname())
== 0) {
exit(1);
}
m->set_start_env();
maxfds = _tt_global->maxfds();
int i;
for (i = 3; i < maxfds; i++) {
// fcntl(i, F_SETFD, 1);
close(i);
}
_tt_restoredtablesize();
#ifdef _POWER
cargv[0] = "/bin/bsh";
cargv[1] = "-c";
cargv[2] = (char *)start_cmd;
cargv[3] = (char *)0;
trace << "execv(\"/bin/bsh -c " << start_cmd << "\");";
execv("/bin/bsh", cargv);
#else
cargv[0] = "/bin/sh";
cargv[1] = "-c";
cargv[2] = (char *)start_cmd;
cargv[3] = (char *)0;
trace << "execv(\"/bin/sh -c " << start_cmd << "\");";
execv("/bin/sh", cargv);
#endif
exit(1);
default:
_start_pid = pid;
return(TT_OK);
}
}
//
// Returns the value of the _launching flag which, if true, indicates
// that an instance of this ptype has be launched but its associated
// procid hasn't connected to the server yet.
//
int _Tt_ptype::
launching() const
{
return(_launching);
}
//
// Returns the pid of the process launched for this ptype.
//
pid_t _Tt_ptype::
start_pid() const
{
return(_start_pid);
}
//
// Called to notify this ptype that the procid that corresponds to the
// start instance of this ptype replied to its start message. This means
// that we can start delivering the messages queued on this ptype object.
//
void _Tt_ptype::
proc_replied()
{
_Tt_s_message_list_cursor qmsgs;
// if the procid called tt_message_accept, which turns into
// _Tt_s_procid::unblock_ptype on this side, then proc_replied
// will have already been done and _launching will be zero.
// In that case, we don\'t have to do anything here, so we bail
// out early.
if (!_launching) {
return;
}
_startmsg = (_Tt_s_message *)0;
_launching = 0;
// re-deliver the rest of the messages until one of them fails
// to get delivered.
qmsgs.reset(_queued_messages);
while (qmsgs.next()) {
qmsgs->set_state(TT_SENT);
// note that _Tt_s_message::deliver won't re-queue
// this message on the ptype because formally this
// message has already been in the TT_STARTED phase.
// Thus if deliver returns 0 (which means that it
// wasn't delivered to anyone) then we just launch a
// new ptype to handle the message and return. (See
// comment for _Tt_ptype::start).
//
_Tt_msg_trace trace( **qmsgs, TTDR_MESSAGE_ACCEPT );
if (! qmsgs->deliver( trace )) {
// msg couldn't be delivered without causing
// another start, so launch another instance
// of this ptype to handle the rest of the
// messages.
Tt_status status = launch(*qmsgs, trace);
if (status != TT_OK) {
_tt_syslog(0, LOG_ERR,
"_Tt_ptype::launch(): %s",
_tt_enumname( status ));
}
_launching = 1;
return;
}
qmsgs.remove();
}
}
//
// Called to notify this ptype what the procid is that corresponds to the
// started instance of this ptype.
//
void _Tt_ptype::
proc_started(const _Tt_s_procid_ptr &pr)
{
if (_queued_messages->count() == 0) {
return;
}
_startmsg = _queued_messages->top();
(void) _queued_messages->pop();
if (_tt_global->xdr_version() == 1) {
// FCS 1.0 library always expects handler to be set
_startmsg->set_handler_procid(pr);
} else {
// Only set handler_procid if pr is meant to
// be a handler. This is true if _startmsg doesn't
// have a static observer set.
if (_startmsg->is_handler_copy()) {
_startmsg->set_handler_procid(pr);
}
}
_startmsg->set_start_message();
if (pr->add_message(_startmsg)) {
// clear _startmsg since it's been sent already
_startmsg = (_Tt_s_message *)0;
return;
} else {
// send failed for startmsg, fail all messages. We
// can't try to launch again because the ptype we're
// trying to start may be coming up and crashing right
// away. If so, then we would cause an infinite loop
// trying to restart it every time. Our only choice
// is to be pessimistic and just fail all the
// messages.
launch_failed();
return;
}
}
//
// Called in order to notify this object that the process that was forked
// to launch this ptype exited without connecting to its default session
// first. The method then proceeds to fail all messages that were queued
// for this ptype (since it isn't known that retrying the launch would
// succeed and if it doesn't it could lead to excessive fork activity.)
//
void _Tt_ptype::
launch_failed()
{
_Tt_s_message_list_cursor qmsgs;
if (! _startmsg.is_null()) {
_startmsg->set_status((int)TT_ERR_PTYPE_START);
_Tt_msg_trace trace( *_startmsg, TTDR_ERR_PTYPE_START );
_startmsg->change_state( 0, TT_FAILED, trace );
}
// fail the rest of the messages
qmsgs.reset(_queued_messages);
while (qmsgs.next()) {
qmsgs->set_status((int)TT_ERR_PTYPE_START);
_Tt_msg_trace trace( **qmsgs, TTDR_ERR_PTYPE_START );
qmsgs->change_state( 0, TT_FAILED, trace );
qmsgs.remove();
}
_launching = 0;
}
//
// Used by the generic table package to generate keys. Should not be used
// otherwise.
//
_Tt_string
_tt_ptype_ptid(_Tt_object_ptr &o)
{
return(((_Tt_ptype *)o.c_pointer())->ptid());
}
void _Tt_ptype::
set_ptid(_Tt_string ptid)
{
_ptid = ptid;
}
_Tt_signature_list_ptr & _Tt_ptype::
osigs()
{
return(_osigs);
}
_Tt_signature_list_ptr & _Tt_ptype::
hsigs()
{
return(_hsigs);
}
//
// Appends a list of observer signatures to this ptype.
//
void _Tt_ptype::
append_osigs(_Tt_signature_list_ptr &sigs)
{
_Tt_signature_list_cursor sc(sigs);
while (sc.next()) {
sc->set_pattern_category(TT_OBSERVE);
}
if (_osigs.is_null()) {
_osigs = sigs;
} else {
_osigs->append_destructive(sigs);
}
}
//
// Appends a list of handler signatures to this ptype.
//
void _Tt_ptype::
append_hsigs(_Tt_signature_list_ptr &sigs, Tt_category category)
{
_Tt_signature_list_cursor sc(sigs);
while (sc.next()) {
sc->set_pattern_category(category);
}
if (_hsigs.is_null()) {
_hsigs = sigs;
} else {
_hsigs->append_destructive(sigs);
}
}
//
// Appends a single observer signature to this ptype.
//
void _Tt_ptype::
append_osig(_Tt_signature_ptr sig)
{
_Tt_signature_list_cursor obsigs;
sig->set_pattern_category(TT_OBSERVE);
obsigs.reset(_osigs);
while (obsigs.next()) {
if (**obsigs == *sig) {
return;
}
}
_osigs->append(sig);
}
//
// Appends a single handler signature to this ptype.
//
void _Tt_ptype::
append_hsig(_Tt_signature_ptr sig, Tt_category category)
{
_Tt_signature_list_cursor obsigs;
sig->set_pattern_category(category);
obsigs.reset(_hsigs);
while (obsigs.next()) {
if (**obsigs == *sig) {
return;
}
}
_hsigs->append(sig);
}
void _Tt_ptype::
appendprop(_Tt_string name, _Tt_string value)
{
_props->append(new _Tt_ptype_prop(name, value));
}
//
// Prints out this ptype object in such a way that the resulting output
// can be reparsed by tt_type_comp to yield another ptype object with the
// same characteristics as this one. As such the output resulting from
// this method is strictly dependent on the syntax for ptype definitions
// and should not be changed lightly.
//
void _Tt_ptype::
pretty_print(const _Tt_ostream &os) const
{
_Tt_ptype_prop_list_cursor props;
os << "ptype " << _ptid << " {\n";
props.reset(_props);
while (props.next()) {
props->pretty_print(os);
}
_Tt_signature::pretty_print_( os, _hsigs, TT_HANDLE, 1 );
_Tt_signature::pretty_print_( os, _hsigs, TT_HANDLE_PUSH, 1 );
_Tt_signature::pretty_print_( os, _hsigs, TT_HANDLE_ROTATE, 1 );
_Tt_signature::pretty_print_( os, _osigs, TT_OBSERVE, 1 );
os << "};\n";
}
int _Tt_ptype::
xdr_version_required() const
{
int version = _Tt_signature::xdr_version_required_( _hsigs );
return max(version, _Tt_signature::xdr_version_required_( _osigs ));
}
//
// Used by the generic list and table packages to print out elements.
// Should not be used otherwise.
//
void
_tt_print_ptype_prop(const _Tt_ostream &os, const _Tt_object *obj)
{
((_Tt_ptype_prop *)obj)->print(os);
}
//
// Used by the generic list and table packages to print out elements.
// Should not be used otherwise.
//
void
_tt_print_signature(const _Tt_ostream &os, const _Tt_object *obj)
{
((_Tt_signature *)obj)->print(os);
}
//
// Used to print out this ptype definition so that it can be incorporated
// into a Classing Engine database. This method should not be changed
// lightly since it could compromise compatibility with older type
// databases.
//
void _Tt_ptype::
print(const _Tt_ostream &os) const
{
os << "\t(\n\t\t(" << _tt_ce_attr_string(_TYPE_NAME) << ','
<< _tt_ce_attr_string(_TT_TOOLTALK_PTYPE) << ",<"
<< _ptid << ">)\n";
os << "\t\t(" << _tt_ce_attr_string(_TT_TOOLTALK_TYPE)
<< ",string,<" << _tt_ce_attr_string(_TT_TOOLTALK_PTYPE)
<< ">)\n";
if (_props->count()) {
_props->print(_tt_print_ptype_prop, os);
}
os << "\t)";
if (_hsigs->count()) {
_hsigs->print(_tt_print_signature, os);
}
if (_osigs->count()) {
_osigs->print(_tt_print_signature, os);
}
}
bool_t _Tt_ptype::
xdr(XDR *xdrs)
{
if (! _ptid.xdr(xdrs)) {
return(0);
}
if (! _props.xdr(xdrs)) {
return(0);
}
if (! _osigs.xdr(xdrs)) {
return(0);
}
if (! _hsigs.xdr(xdrs)) {
return(0);
}
return(1);
}
//
// Check that ptype contains no duplicate signatures.
// Return 1 if duplicate found, else 0.
//
int _Tt_ptype::
check_semantics()
{
int result = 0;
_Tt_signature_list_cursor s1(_hsigs);
while (s1.next()) {
_Tt_signature_list_cursor s2(s1);
while (s2.next()) {
if (**s1 == **s2) {
_tt_syslog(stdout, LOG_ERR,
catgets(_ttcatd, 2, 2,
"indistinguishable signatures"
"found for ptype %s -"),
(char *) ptid());
s1->pretty_print(stdout);
s2->pretty_print(stdout);
result = 1;
}
}
}
return result;
}
//
// Used to merge a new ptype definition represented by "pt" with this
// ptype. This method is used by tt_type_comp to merge new definitions of
// existing ptypes. The behavior supported is that any signatures in the
// old definition that are not in the new definition remain, any
// signatures in the new definition are appended to the definition, and
// any signatures in the new definition that are in the old definition
// replace the ones in the old definition. Note that the last case
// means that only attribute changes are possible for the new
// signature (eg. different disposition value, etc.) since the op and
// args are by definition the same.
//
/*
void _Tt_ptype::
merge_with(_Tt_ptype_ptr &pt)
{
_Tt_ptype_prop_list_cursor propc;
_Tt_ptype_prop_list_cursor oldpropc;
_Tt_signature_list_cursor oldsigs;
_Tt_signature_list_cursor newsigs;
_Tt_string oname;
// merge attributes
oldpropc.reset(_props);
while (oldpropc.next()) {
propc.reset(pt->_props);
while (propc.next()) {
oname = oldpropc->name();
if (oname == propc->name()) {
oldpropc.remove();
break;
}
}
}
_props->append_destructive(pt->_props);
// merge observer signatures
oldsigs.reset(_osigs);
while (oldsigs.next()) {
newsigs.reset(pt->_osigs);
while (newsigs.next()) {
if (newsigs->is_equal(*oldsigs)) {
oldsigs.remove();
break;
}
}
}
_osigs->append_destructive(pt->_osigs);
// merge handler signatures
oldsigs.reset(_hsigs);
while (oldsigs.next()) {
newsigs.reset(pt->_hsigs);
while (newsigs.next()) {
if (newsigs->is_equal(*oldsigs)) {
oldsigs.remove();
break;
}
}
}
_hsigs->append_destructive(pt->_hsigs);
}
*/
int
operator==(_Tt_ptype &a, _Tt_ptype& b)
{
// Two ptypes are equal if they are the same object, or their
// ptids are equal strings.
if (&a == &b) {
return 1;
} else if (a.ptid() == b.ptid()) {
return 1;
} else {
return 0;
}
}
int
operator!=(_Tt_ptype &a, _Tt_ptype &b)
{
return !(a==b);
}
//
// Used by the generic list and table packages to print elements. Should
// not be used otherwise.
//
void
_tt_ptype_print(const _Tt_ostream &os, const _Tt_object *obj)
{
((_Tt_ptype *)obj)->print(os);
}

View File

@@ -0,0 +1,99 @@
/*%% (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_ptype.h /main/3 1995/10/23 11:52:31 rswiston $ */
/*
* Tool Talk Message Passer (MP) - mp_ptype.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* Declaration of the _Tt_ptype class representing an in-memory process type
* definition.
*/
#ifndef _MP_PTYPE_H
#define _MP_PTYPE_H
#include "mp/mp_global.h"
#include "mp/mp_trace.h"
#include "mp_s_message_utils.h"
#include "mp_s_procid_utils.h"
#include "mp_signature_utils.h"
#include "util/tt_table.h"
/*
* _Tt_ptype is an in-memory representation of a process type
* definition in a ptype database.
*/
declare_list_of(_Tt_ptype_prop)
class _Tt_ptype_prop : public _Tt_object {
public:
_Tt_ptype_prop();
_Tt_ptype_prop(_Tt_string name, _Tt_string value);
virtual ~_Tt_ptype_prop();
_Tt_string name();
_Tt_string value();
void print(const _Tt_ostream &os) const;
void pretty_print(const _Tt_ostream &os) const;
bool_t xdr(XDR *xdrs);
private:
_Tt_string _name;
_Tt_string _value;
};
class _Tt_ptype_ptr;
class _Tt_ptype : public _Tt_object {
public:
_Tt_ptype();
virtual ~_Tt_ptype();
_Tt_signature_list_ptr &osigs();
_Tt_signature_list_ptr &hsigs();
void proc_replied();
void proc_started(const _Tt_s_procid_ptr &pr);
const _Tt_string & ptid() const {return _ptid;};
int getprop(_Tt_string propname,
_Tt_string &value);
Tt_status start(_Tt_s_message_ptr &m,
const _Tt_msg_trace &trace);
void set_ptid(_Tt_string ptid);
void append_osigs(_Tt_signature_list_ptr &sigs);
void append_hsigs(_Tt_signature_list_ptr &sigs,
Tt_category category);
void append_osig(_Tt_signature_ptr sig);
void append_hsig(_Tt_signature_ptr sig,
Tt_category category);
void appendprop(_Tt_string name, _Tt_string value);
void print(const _Tt_ostream &os) const;
void pretty_print(const _Tt_ostream &os) const;
int check_semantics();
bool_t xdr(XDR *xdrs);
pid_t start_pid() const;
int launching() const;
void launch_failed();
void merge_with(_Tt_ptype_ptr &pt);
void *ce_entry;
int xdr_version_required() const;
private:
friend class _Tt_typedb;
Tt_status launch(_Tt_s_message_ptr &m,
const _Tt_msg_trace &trace);
int _launching;
pid_t _start_pid;
_Tt_string _ptid;
_Tt_ptype_prop_list_ptr _props;
_Tt_s_message_list_ptr _queued_messages;
_Tt_s_message_ptr _startmsg;
_Tt_signature_list_ptr _osigs;
_Tt_signature_list_ptr _hsigs;
friend int operator==(_Tt_ptype&,_Tt_ptype&);
friend int operator!=(_Tt_ptype&,_Tt_ptype&);
};
_Tt_string _tt_ptype_ptid(_Tt_object_ptr &o);
void _tt_otype_print(const _Tt_ostream &os, const _Tt_object *obj);
#endif /* _MP_PTYPE_H */

View 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_ptype_utils.C /main/3 1995/10/23 11:52:43 rswiston $
/*
*
* mp_ptype_utils.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp_ptype_utils.h"
#include "mp_ptype.h"
implement_list_of(_Tt_ptype)
implement_table_of(_Tt_ptype)
implement_list_of(_Tt_ptype_prop)

View File

@@ -0,0 +1,25 @@
/*%% (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_ptype_utils.h /main/3 1995/10/23 11:52:55 rswiston $ */
/*
*
* mp_ptype_utils.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* Utilities declarations for _Tt_ptype
*/
#ifndef MP_PTYPE_UTILS_H
#define MP_PTYPE_UTILS_H
#include "util/tt_object.h"
#include "util/tt_list.h"
#include "util/tt_string.h"
#include "util/tt_table.h"
class _Tt_ptype;
declare_list_of(_Tt_ptype)
declare_table_of(_Tt_ptype)
#endif /* MP_PTYPE_UTILS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
/*%% (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_implement.h /main/3 1995/10/23 11:53:25 rswiston $ */
/*
*
* mp_rpc_implement.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#ifndef _MP_RPC_IMPLEMENT_H
#define _MP_RPC_IMPLEMENT_H
#include "mp/mp_rpc_interface.h"
void _tt_service_rpc(svc_req *rqstp, SVCXPRT *transp);
#endif /* _MP_RPC_IMPLEMENT_H */

View File

@@ -0,0 +1,451 @@
//%% (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_server.C /main/11 1999/08/30 11:03:00 mgreess $
/*
*
* @(#)mp_rpc_server.C 1.46 94/11/17
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "tt_options.h"
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <errno.h>
#include "mp_rpc_server.h"
#include "util/tt_port.h"
#include "util/tt_gettext.h"
#include "util/tt_global_env.h"
#include "mp/mp_mp.h"
#include "mp/mp_rpc.h"
#if defined(OPT_TLI)
#include <netdir.h>
static int gettransient(int, netconfig *, netbuf *);
#if defined(OPT_BUG_SUNOS_5) || defined(OPT_BUG_UXP)
extern "C" { char * nc_sperror(); }
#endif
# if defined(OPT_BUG_USL) || defined(OPT_BUG_UXP)
extern int t_errno;
extern char *t_strerror(int t_errno);
# endif
#else
#include <rpc/pmap_clnt.h>
#include <netinet/tcp.h>
static int gettransient(int,int,int *);
#endif /* OPT_TLI */
#if defined(OPT_BUG_USL)
typedef void (*SERVICE_FN_TYPE)(const struct svc_req *, const SVCXPRT*);
#elif defined(OPT_BUG_AIX)
typedef void (*SERVICE_FN_TYPE)();
#else
typedef void (*SERVICE_FN_TYPE)(struct svc_req *, SVCXPRT*);
#endif
/*
* Constructs an rpc server for the given program, version and socket.
*/
_Tt_rpc_server::
_Tt_rpc_server(int program, int version, int Rsocket, _Tt_auth &auth)
{
_version = version;
_socket = Rsocket;
_program = program;
_auth = auth;
}
/*
* Destroys an rpc server. Unsets the program,version mapping in the
* portmapper.
*/
_Tt_rpc_server::
~_Tt_rpc_server()
{
#ifndef OPT_TLI
/*
* pmap_unset(_program, _version);
*/
#else
for (int version = _version; version >= 1; version--) {
rpcb_unset(_program, version, (netconfig *)0);
}
#endif // OPT_TLI
}
/*
* Initializes an rpc server with a service function. If _program is set
* to -1 then an unused program number is obtained using the gettransient
* function. If _socket is anything other than RPC_ANYSOCK then it will
* be used to create the rpc transport using svfd_create and the rpc
* numbers will not be registered with the portmapper.
*/
int _Tt_rpc_server::
init(void (*service_fn)(struct svc_req *, SVCXPRT *))
{
char *bufopt = (char *)0;
#ifndef OPT_TLI
bufopt = getenv("TT_BUFSIZE");
unsigned int buffersize = (bufopt != (char *)0) ? atoi(bufopt) : 32000;
if (_socket != RPC_ANYSOCK) {
_transp = svcfd_create(_socket, buffersize, buffersize);
if (_transp == (SVCXPRT *)0) {
return(0);
}
if (!svc_register(_transp, _program, _version,
(SERVICE_FN_TYPE)service_fn, 0))
{
_tt_syslog(0, LOG_ERR, "svc_register(): %m");
return(0);
}
return(1);
}
if (_program == -1) {
if (! (_program =
gettransient(IPPROTO_TCP, _version, &_socket))) {
return(0);
}
} else {
_socket = socket(AF_INET, SOCK_STREAM, 0);
if (_socket < 0) {
_tt_syslog(0, LOG_ERR,
"_Tt_rpc_server::init(): socket(): %m");
return 0;
}
}
int optval = 1;
if (setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY,
(char *)&optval, sizeof(int)) == -1) {
_tt_syslog(0, LOG_ERR, "setsockopt(TCP_NODELAY): %m");
}
if (setsockopt(_socket, SOL_SOCKET, SO_RCVBUF, (char *)&buffersize,
sizeof(int)) == -1) {
_tt_syslog(0, LOG_ERR, "setsockopt(SO_RCVBUF): %m");
}
if (setsockopt(_socket, SOL_SOCKET, SO_SNDBUF, (char *)&buffersize,
sizeof(int)) == -1) {
_tt_syslog(0, LOG_ERR, "setsockopt(SO_SNDBUF): %m");
}
_transp = svctcp_create(_socket, buffersize, buffersize);
if (_transp == (SVCXPRT *)0) {
return(0);
}
if ( !svc_register(_transp, _program, _version,
(SERVICE_FN_TYPE)service_fn, IPPROTO_TCP)
|| !svc_register(_transp, _program, 1,
(SERVICE_FN_TYPE)service_fn, 0))
{
_tt_syslog(0, LOG_ERR, "svc_register(): %m");
return(0);
}
#else
netconfig *nconf;
void *handlep;
t_info tinfo;
int fd;
if ((handlep = setnetconfig()) == (void *)0) {
_tt_syslog(0, LOG_ERR, "setnetconfig(): %s", nc_sperror());
return(0);
}
// Find a connection-oriented transport.
while (nconf = getnetconfig(handlep)) {
if ((nconf->nc_semantics == NC_TPI_COTS) ||
(nconf->nc_semantics == NC_TPI_COTS_ORD)) {
// Make sure this netconfig maps to an address
if (0 == strcmp(nconf->nc_protofmly, NC_INET))
break;
}
}
// If we failed to find a suitable transport, exit.
if (nconf == (netconfig *)0) {
endnetconfig(handlep);
_tt_syslog(0, LOG_ERR,
catgets(_ttcatd, 2, 3,
"No connection-oriented transport"));
return(0);
}
fd = t_open(nconf->nc_device, O_RDWR, &tinfo);
if (fd == -1) {
_tt_syslog(0, LOG_ERR,
"_Tt_rpc_server::init(): t_open(): %s",
t_strerror( t_errno ) );
endnetconfig(handlep);
return 0;
}
// No longer need to try to set NODELAY here as TIRPC does it for us
// tinfo.tsdu can be negative, but that's not a valid buf size.
u_int buf_size = 0;
if (tinfo.tsdu > 0) {
buf_size = (u_int)tinfo.tsdu;
}
_transp = svc_tli_create(fd, nconf, (struct t_bind *)0,
buf_size, buf_size);
if (_transp == (SVCXPRT *)0) {
_tt_syslog(0, LOG_ERR, "svc_tli_create(): 0");
(void)t_close(fd);
return(0);
}
if (_program == -1 &&
(! (_program = gettransient(_version, nconf,
&_transp->xp_ltaddr)))) {
_tt_syslog(0, LOG_ERR, "gettransient(): 0");
return(0);
}
for (int version = _version; version >= 1; version--) {
if (!svc_reg(_transp, _program, version,
(SERVICE_FN_TYPE)service_fn, nconf)) {
_tt_syslog(0, LOG_ERR, "svc_reg(,,%d): 0", version);
return(0);
}
}
// it is important to not call endnetconfig until one is done
// using nconf as endnetconfig frees the nconf storage.
(void)endnetconfig(handlep);
#endif /* OPT_TLI */
// now figure out what fd the rpc package is using
int maxfds = _tt_global->maxfds();
for (int i=0; i < maxfds; i++) {
if (FD_ISSET(i, &svc_fdset)) {
_rpc_fd = i;
}
}
return(1);
}
/*
* Runs an rpc server. If a non-negative timeout is given then this
* function will return if the timeout expired before any rpc requests
* came in. The values returned are: -1 for error, 0 for timeout, 1
* for when timeout is 0 and an rpc request was serviced.
*/
_Tt_rpcsrv_err _Tt_rpc_server::
run_until(int *stop, int timeout, _Tt_int_rec_list_ptr &efds)
{
fd_set readfds;
timeval tmout;
int fd;
int done = 0;
int select_stat;
_Tt_rpcsrv_err status = _TT_RPCSRV_OK;
tmout.tv_sec = timeout;
tmout.tv_usec = 0;
_Tt_int_rec_list_cursor efds_c(efds);
do {
// Add our fd's to a copy of the rpc fdset.
readfds = svc_fdset;
efds_c.reset();
while (efds_c.next()) {
fd = efds_c->val;
// NOTE that it is crucially important that the bit
// for fd 0 not be set. fd 0 (stdin) is always set
// to /dev/null, which is always active.
// The reason fd 0 is in efds at all is that
// _Tt_self_procid uses it as a dummy entry
// for ttsession itself, which doesn\'t need a
// signalling channel.
// I haven\'t verified this, but I bet it\'s possible
// for negative entries to be in the efds list too,
// representing signalling channels that were found
// active on a previous pass but are not yet cleared
// out.
if (fd > 0) {
FD_SET(fd, &readfds);
}
}
// Drop the global mutex around any polling or RPC calls.
_tt_global->drop_mutex();
select_stat =
select(FD_SETSIZE,&readfds, 0, 0,
(timeout >= 0) ? &tmout : (timeval *)0);
_tt_global->grab_mutex();
switch (select_stat) {
case -1:
return(_TT_RPCSRV_ERR);
case 0:
return(_TT_RPCSRV_TMOUT);
default:
// check for exception fds
efds_c.reset();
while (efds_c.next()) {
fd = efds_c->val;
if (fd < 0) continue; // -1 => not valid fd
if (FD_ISSET(fd, &readfds)) {
efds_c->val = (0 - fd);
status = _TT_RPCSRV_FDERR;
done = 1;
}
// Clear our fd from the fdset so
// svc_getreqset() won't get confused (bug
// 2000972).
FD_CLR(fd, &readfds);
}
svc_getreqset(&readfds);
}
} while ((! done) && ((stop == 0) || (! *stop)));
return status;
}
/*
* Returns an unused transient program number. Definition taken out of
* the RPC manual.
*/
#ifdef OPT_TLI
static int
gettransient(int vers, netconfig *nconf, netbuf *address)
#else
static int
gettransient(int proto, int vers, int *sockp)
#endif /* OPT_TLI */
{
int prognum;
#ifndef OPT_TLI
int found;
int s;
int len;
int socktype;
sockaddr_in addr;
sockaddr_in tport;
sockaddr_in uport;
switch (proto) {
case IPPROTO_UDP:
socktype = SOCK_DGRAM;
break;
case IPPROTO_TCP:
socktype = SOCK_STREAM;
break;
default:
return(0);
}
if (*sockp == RPC_ANYSOCK) {
s = socket(AF_INET, socktype, 0);
if (s < 0) {
_tt_syslog(0, LOG_ERR, "gettransient(): socket(): %m");
return 0;
}
*sockp = s;
} else {
s = *sockp;
}
memset(&addr, 0, sizeof(addr));
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(0);
addr.sin_family = AF_INET;
len = sizeof(addr);
bind(s, (sockaddr *)&addr, len);
#if defined (_AIX) && (OSMAJORVERSION==4) && (OSMINORVERSION==2)
if (getsockname(s, (sockaddr *)&addr, (size_t *)&len) < 0) {
#else
if (getsockname(s, (sockaddr *)&addr, &len) < 0) {
#endif
_tt_syslog(0, LOG_ERR, "getsockname(): %m");
return(0);
}
int optval = 0;
#if !defined(linux)
if (setsockopt(s, SOL_SOCKET, SO_USELOOPBACK,
(char *)&optval, sizeof(optval)) == -1) {
}
#endif
#endif /* !OPT_TLI */
// Search for a transient rpc number in the range 0x40000000 -
// 0x5fffffff by starting in the middle of the range searching
// up and then searching down if that fails. The reason for
// this is to make it less likely for other programs to grab
// this transient number (since pmap_getport doesn't complain
// if you try to grab a number for udp and we have it grabbed
// for tcp).
// search up in the range 0x4fffffff - 0x5fffffff
for (prognum = 0x4fffffff; prognum <= 0x5fffffff; prognum++) {
/* XXX: pmap_set allows the same prognum for different */
/* protocols so we hack around that by attemptint to */
/* set both tcp and udp. */
#ifndef OPT_TLI
found = (!pmap_getport(&uport, prognum, vers,
IPPROTO_UDP) &&
!pmap_getport(&tport, prognum, vers, proto));
if (found &&
(found = pmap_set(prognum,
vers,
proto,
ntohs(addr.sin_port))) &&
(vers==1 || (found = pmap_set(prognum,
1,
proto,
ntohs(addr.sin_port))))) {
return(prognum);
}
#else
if (rpcb_set(prognum, vers, nconf, address) &&
(vers==1 || rpcb_set(prognum, 1, nconf, address))) {
return(prognum);
}
#endif /* !OPT_TLI */
}
// search down in the range 0x4ffffffe - 0x40000000
for (prognum = 0x4ffffffe; prognum >= 0x40000000; prognum--) {
/* XXX: pmap_set allows the same prognum for different */
/* protocols so we hack around that by attemptint to */
/* set both tcp and udp. */
#ifndef OPT_TLI
found = (!pmap_getport(&uport, prognum, vers,
IPPROTO_UDP) &&
!pmap_getport(&tport, prognum, vers, proto));
if (found &&
(found = pmap_set(prognum,
vers,
proto,
ntohs(addr.sin_port)))) {
return(prognum);
}
#else
if (rpcb_set(prognum, vers, nconf, address)) {
return(prognum);
}
#endif /* !OPT_TLI */
}
return(0);
}

View File

@@ -0,0 +1,41 @@
/*%% (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_server.h /main/4 1999/08/30 11:03:46 mgreess $ */
/*
*
* @(#)mp_rpc_server.h 1.8 93/09/07
*
* Copyright (c) 1990,1993 by Sun Microsystems, Inc.
*
* Implementation of _Tt_rpc_server which represents a provider of an
* RPC service and _Tt_rpc_client which represents the corresponding
* RPC client.
*/
#ifndef _TT_MP_RPC_SERVER_H
#define _TT_MP_RPC_SERVER_H
#include "mp/mp_auth.h"
#include "mp/mp_rpc.h"
class _Tt_rpc_server : public _Tt_object {
public:
_Tt_rpc_server() {};
_Tt_rpc_server(int program, int version, int Rsocket, _Tt_auth &auth);
virtual ~_Tt_rpc_server();
int init(void (*service_fn)(svc_req *, SVCXPRT *));
_Tt_rpcsrv_err run_until(int *stop, int sec_timeout,
_Tt_int_rec_list_ptr &efds);
int program() { return _program; };
int version() { return _version; };
private:
_Tt_auth _auth;
int _program;
int _version;
int _socket;
int _rpc_fd;
SVCXPRT *_transp;
};
#endif /* _TT_MP_RPC_SERVER_H */

View 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_server_utils.C /main/3 1995/10/23 11:54:00 rswiston $
/*
*
* mp_rpc_server_utils.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp_rpc_server_utils.h"
#include "mp_rpc_server.h"
implement_ptr_to(_Tt_rpc_server)

View 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_rpc_server_utils.h /main/3 1995/10/23 11:54:12 rswiston $ */
/*
*
* mp_rpc_server_utils.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#ifndef MP_RPC_SERVER_UTILS_H
#define MP_RPC_SERVER_UTILS_H
#include <util/tt_object.h>
class _Tt_rpc_server;
declare_ptr_to(_Tt_rpc_server)
#endif /* MP_RPC_SERVER_UTILS_H */

View 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_s_arg.h /main/3 1995/10/23 11:54:22 rswiston $ */
/* -*-C++-*-
* Tool Talk Message Passer (MP) - mp_s_arg.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
*
* _Tt_s_arg is the server only part of the _Tt_arg class.
*/
#ifndef _MP_S_ARG_H
#define _MP_S_ARG_H
// See mp_s_arg.cc for why this is void.
#endif /* _MP_S_ARG_H */

View 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_s_arg_utils.h /main/3 1995/10/23 11:54:33 rswiston $ */
/*
*
* mp_s_arg_utils.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#ifndef MP_S_ARG_UTILS_H
#define MP_S_ARG_UTILS_H
// See mp_s_arg.cc for why this is empty
#endif /* MP_S_ARG_UTILS_H */

115
cde/lib/tt/slib/mp_s_file.C Normal file
View File

@@ -0,0 +1,115 @@
//%% (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_s_file.C /main/3 1995/10/23 11:54:43 rswiston $
/*
*
* mp_s_file.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include "mp_s_mp.h"
#include "mp/mp_pattern.h"
#include "mp_s_file.h"
//
// Use parent class (_Tt_file) for construction and destruction.
//
_Tt_s_file::_Tt_s_file()
{
}
_Tt_s_file::_Tt_s_file(
const _Tt_string &path
)
{
networkPath = path;
}
_Tt_s_file::~_Tt_s_file()
{
}
Tt_status
_Tt_s_file::s_join(
_Tt_s_procid_ptr &p
)
{
_Tt_pattern_list_cursor pats(p->patterns());
int scopes;
int fpatterns_found = 0;
while (pats.next()) {
scopes = pats->scopes();
if (scopes&(1<<TT_FILE)) {
fpatterns_found = 1;
}
if (scopes&(1<<TT_FILE) ||
scopes&(1<<TT_FILE_IN_SESSION)) {
pats->add_file(networkPath);
_tt_s_mp->mod_file_scope(networkPath, 1);
}
}
if (fpatterns_found) {
p->add_joined_file(networkPath);
}
// note: TT_WRN_NOTFOUND is returned if there are no
// TT_FILE patterns that were updated. This is just an
// indication to the client side that it doesn't need
// to update the database. If patterns were found and
// this is the first procid in the session to join
// this file then TT_WRN_STALE_OBJID is returned
// telling the client side to update the database.
return((fpatterns_found) ?
((procs_joined() == 1) ? TT_WRN_STALE_OBJID : TT_OK)
: TT_WRN_NOTFOUND);
}
Tt_status
_Tt_s_file::s_quit(
_Tt_s_procid_ptr &p
)
{
_Tt_pattern_list_cursor pats(p->patterns());
int scopes;
int fpatterns_found = 0;
while (pats.next()) {
scopes = pats->scopes();
if (scopes&(1<<TT_FILE)) {
fpatterns_found = 1;
}
if (scopes&(1<<TT_FILE) ||
scopes&(1<<TT_FILE_IN_SESSION)) {
pats->del_file(networkPath);
_tt_s_mp->mod_file_scope(networkPath, 0);
}
}
if (fpatterns_found) {
p->del_joined_file(networkPath);
} else {
return TT_WRN_NOTFOUND;
}
if (_tt_s_mp->in_file_scope(networkPath)) {
return TT_OK;
} else {
// Tells _Tt_c_file::c_quit() to delete this session from file
return TT_WRN_STALE_OBJID;
}
}
int
_Tt_s_file::procs_joined()
{
_Tt_s_procid_table_cursor procs(_tt_s_mp->active_procs);
int nprocs = 0;
while (procs.next()) {
if (procs->joined_to_file(networkPath)) {
nprocs++;
}
}
return(nprocs);
}

View 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_s_file.h /main/3 1995/10/23 11:54:56 rswiston $ */
/*
* Tool Talk Message Passer (MP) - mp_s_file.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* Declaration of the _Tt_s_file class.
*/
#ifndef _MP_S_FILE_H
#define _MP_S_FILE_H
#include "mp/mp_file.h"
#include "mp_s_procid_utils.h"
class _Tt_s_file : public _Tt_object {
public:
_Tt_s_file();
_Tt_s_file(
const _Tt_string &path
);
virtual ~_Tt_s_file();
Tt_status s_join(_Tt_s_procid_ptr &p);
Tt_status s_quit(_Tt_s_procid_ptr &p);
protected:
int procs_joined();
private:
_Tt_string networkPath;
};
#endif /* _MP_S_FILE_H */

View 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_s_file_utils.C /main/3 1995/10/23 11:55:10 rswiston $
/*
*
* mp_s_file_utils.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp_s_file.h"
#include "mp_s_file_utils.h"
implement_ptr_to(_Tt_s_file)

View 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_s_file_utils.h /main/3 1995/10/23 11:55:21 rswiston $ */
/*
*
* mp_s_file_utils.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* Utilities declarations for _Tt_c_file
*/
#ifndef MP_S_FILE_UTILS_H
#define MP_S_FILE_UTILS_H
#include <mp/mp_file_utils.h>
class _Tt_s_file;
declare_ptr_to(_Tt_s_file)
#endif /* MP_S_FILE_UTILS_H */

View 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_s_global.h /main/3 1995/10/23 11:55:30 rswiston $ */
/*
*
* mp_s_global.h
*
* Copyright (c) 1992 by Sun Microsystems, Inc.
*
*
* _tt_s_mp and _tt_mp always point to the same object, but server-only
* functions can use _tt_s_mp in order to access server-only functions.
*/
#if !defined(_MP_S_GLOBAL_H)
#define _MP_S_GLOBAL_H
class _Tt_s_mp;
extern _Tt_s_mp *_tt_s_mp;
#include "mp/mp_global.h"
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,116 @@
/*%% (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_s_message.h /main/3 1995/10/23 11:55:57 rswiston $ */
/* -*-C++-*-
*
* @(#)mp_s_message.h 1.13 94/11/17
*
* Tool Talk Message Passer (MP) - mp_s_message.h
*
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
*
* This file implements the server side of the _Tt_message object.
*/
#ifndef _MP_S_MESSAGE_H
#define _MP_S_MESSAGE_H
#include "mp/mp_message.h"
#include "mp/mp_trace.h"
#include "mp_otype_utils.h"
#include "mp_signature_utils.h"
#include "mp_observer_utils.h"
#include "mp_s_message_utils.h"
#include "mp_s_procid_utils.h"
class _Tt_s_pattern;
class _Tt_s_message : public _Tt_message {
public:
_Tt_s_message();
virtual ~_Tt_s_message();
_Tt_s_message(_Tt_s_message *m, _Tt_observer_ptr &o);
Tt_scope scope() const;
int opnum() const;
Tt_state state() const;
const _Tt_string &handler_ptype() const;
Tt_disposition reliability() const;
void qmsg_info(_Tt_qmsg_info_ptr &qm);
Tt_status indoctrinate(const _Tt_msg_trace &trace);
Tt_status dispatch(const _Tt_msg_trace &trace);
Tt_status set_start_env() const;
int deliver(const _Tt_msg_trace &trace,
int deliver_to_observers = 1);
void deliver_to_observers_and_handlers(
const _Tt_msg_trace &trace );
void set_return_sender_flags();
void set_send_handler_flags();
Tt_status change_state(const _Tt_procid_ptr &changer,
Tt_state s,
const _Tt_msg_trace &trace );
void remove_procid(const _Tt_procid_ptr &p);
int is_handler_copy() const {
return(_observer.is_null());
}
const _Tt_observer_ptr &observer() const {
return _observer;
}
Tt_status set_state(Tt_state state);
Tt_status set_scope(Tt_scope s);
Tt_status set_reliability(Tt_disposition r);
void add_eligible_voter(const _Tt_procid_ptr &p);
private:
int already_tried(const _Tt_procid_ptr &proc);
Tt_status started(const _Tt_msg_trace &trace);
Tt_status hdispatch();
void handle_no_recipients(
const _Tt_msg_trace &trace);
Tt_status handler_dispatch(const _Tt_msg_trace &trace);
int match_handler(const _Tt_s_pattern &pat,
const _Tt_msg_trace &trace,
int &best_match,
Tt_category &best_category,
unsigned int &best_timestamp) const;
int match_handler(const _Tt_signature &sig,
const _Tt_msg_trace &trace,
int &best_match,
Tt_category &best_category,
unsigned int &best_timestamp) const;
int match_observer(const _Tt_s_pattern &pat,
const _Tt_s_procid_ptr &proc,
const _Tt_msg_trace &trace);
int match_observer(const _Tt_signature &pat,
const _Tt_msg_trace &trace);
int match_patterns(_Tt_pattern_list_ptr &patterns,
const _Tt_msg_trace &trace,
_Tt_pattern_ptr &best_pattern,
int deliver_to_observers);
Tt_status match_signatures(_Tt_signature_list_ptr &s,
const _Tt_msg_trace &trace);
int match_super_sig(_Tt_otype_ptr ot,
_Tt_signature_ptr &sig,
const _Tt_msg_trace &trace);
Tt_status object_oriented_dispatch(
const _Tt_msg_trace &trace);
Tt_status procedural_dispatch(
const _Tt_msg_trace &trace);
Tt_status queued(const _Tt_msg_trace &trace);
Tt_status rejected(const _Tt_msg_trace &trace);
void report_state_change();
int needs_observer_match();
Tt_status add_voter(const _Tt_procid_ptr &p,
Tt_state vote,
const _Tt_msg_trace &trace);
Tt_status count_ballots(const _Tt_procid_ptr &last_voter,
const _Tt_msg_trace &trace);
unsigned int _when_last_matched;
_Tt_procid_list_ptr _tried;
int _state_reported;
_Tt_observer_list_ptr _observers;
_Tt_observer_ptr _observer;
int _num_recipients_yet_to_vote;
_Tt_s_message_ptr _original;
};
#endif /* _MP_S_MESSAGE_H */

View 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_s_message_utils.C /main/3 1995/10/23 11:56:08 rswiston $
/*
*
* mp_s_message_utils.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp_s_message.h"
implement_list_of(_Tt_s_message)

View 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_s_message_utils.h /main/3 1995/10/23 11:56:19 rswiston $ */
/*
*
* mp_s_message_utils.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* Utilities declarations for _Tt_s_message
*/
#ifndef MP_S_MESSAGE_UTILS_H
#define MP_S_MESSAGE_UTILS_H
#include <mp/mp_message_utils.h>
declare_derived_list_of(_Tt_s_message,_Tt_message)
#endif /* MP_S_MESSAGE_UTILS_H */

679
cde/lib/tt/slib/mp_s_mp.C Normal file
View File

@@ -0,0 +1,679 @@
//%% (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_s_mp.C /main/6 1996/05/09 20:30:03 drk $
/*
*
* @(#)mp_s_mp.C 1.42 95/09/18
*
* Copyright 1990,1993 Sun Microsystems, Inc. All rights reserved.
*/
#include "mp_s_global.h"
#include "mp_s_mp.h"
#include "mp/mp_mp.h"
#include "mp_s_procid.h"
#include "mp_self_procid.h"
#include "mp_rpc_implement.h"
#include "mp_rpc_server.h"
#include "mp_s_session.h"
#include "mp/mp_xdr_functions.h"
#include "mp_ptype.h"
#include "mp_otype.h"
#include "mp/mp_arg.h"
#include "mp_s_pattern.h"
#include "mp_signature.h"
#include "mp_s_message.h"
#include "mp_typedb.h"
#include "mp/mp_file.h"
#include "util/tt_global_env.h"
#include "util/tt_base64.h"
#include "util/tt_host.h"
#include "util/tt_port.h"
#include <errno.h>
#include <sys/resource.h>
#include <time.h>
#include <unistd.h>
#include <nl_types.h>
#include <util/tt_gettext.h>
#include <tt_const.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// global pointer to the _Tt_s_mp object. There should only be one
// instance of this object.
_Tt_s_mp *_tt_s_mp = (_Tt_s_mp *)0;
_Tt_s_mp::
_Tt_s_mp() : _Tt_mp()
{
_flags |= (1<<_TT_MP_IN_SERVER);
initial_session = initial_s_session = new _Tt_s_session;
_active_fds = new _Tt_int_rec_list();
_active_fds_procids = new _Tt_string_list();
_mp_start_time = (int)time(0);
_min_timeout = -1;
_next_procid_key = 0;
xfd = -1;
exit_main_loop = 0;
max_active_messages = 2000;
fin = 0;
fout = 0;
ptable = new _Tt_ptype_table(_tt_ptype_ptid, 50);
otable = new _Tt_otype_table(_tt_otype_otid, 50);
sigs = new _Tt_sigs_by_op_table(_tt_sigs_by_op_op, 250);
opful_pats = new _Tt_patlist_table(_tt_patlist_op, 250);
opless_pats = new _Tt_pattern_list();
active_procs = new _Tt_s_procid_table(_tt_procid_id, 250);
now = 1;
when_last_observer_registered = 1;
update_args.message = new _Tt_s_message();
_self = (_Tt_s_procid *)new _Tt_self_procid();
}
_Tt_s_mp::
~_Tt_s_mp()
{
//
// Emulate a tt_close() for _self.
// XXX Commented out because currently s_remove_procid() neither:
// - deletes this session from the interest list, nor
// - sends an on_exit message (since _self submits none)
//
// if (! _self.is_null()) {
// s_remove_procid( _self );
// }
}
//
// Initializes a _Tt_s_mp object. This entails initializing
// the initial session which is the default session that other clients
// connect to. This method will also initialize the global _Tt_s_mp
// object if the session is initialized. This is important since the
// _Tt_s_mp::init method assumes that the session has been initialized.
// XXX: the existence of the s_init and init methods is left over from
// an earlier incomplete split of _Tt_mp into server and client subclasses.
// Really, there should be just one virtual init method.
//
Tt_status _Tt_s_mp::
s_init()
{
Tt_status status;
active_messages = 0;
// initialize "initial" session which is the server session in
// server mode and the "default" session in client mode.
status = initial_s_session->s_init();
if (status == TT_OK) {
status = init();
}
return(status);
}
//
// Initializes the _Tt_s_mp object. This entails putting the two special
// "pseudo-procids" into the _active_fds and _active_fds_procids lists
// (see comment for _Tt_s_mp::find_proc)
//
Tt_status _Tt_s_mp::
init()
{
if (xfd != -1) {
// put in fd for X connection
_active_fds->push(new _Tt_int_rec(xfd));
_active_fds_procids->push(_Tt_string("X"));
}
#ifdef OPT_UNIX_SOCKET_RPC
/* XXX: UNIX_SOCKET */
if (unix_fd != -1) {
// put in fd for local rpc connections
_active_fds->push(new _Tt_int_rec(unix_fd));
_active_fds_procids->push(_Tt_string("U"));
}
/* XXX: UNIX_SOCKET */
#endif // OPT_UNIX_SOCKET_RPC
return(TT_OK);
}
//
// Initialize our _Tt_self_procid and register patterns for the
// messages we are interested in.
//
Tt_status
_Tt_s_mp::init_self()
{
// Grab the global mutex to lock out other threads
_tt_global->grab_mutex();
// Increment the counter for the number of RPC calls
// handled during the life of this process. This has
// to be done here since init_self() ultimately calls
// something which calls updateFileSystemEntries(),
// yet it's not done through an API or RPC call. Thus,
// this line here is somewhat of a bandaid. XXX
_tt_global->event_counter++;
// Use the lame do-loop hack to avoid repeating the drop_mutex
// code after every possible failure...
Tt_status status = TT_OK;;
do {
//
// tt_open(), tt_fd()
//
Tt_status status = _self->init();
if (status != TT_OK) {
break;
}
status = add_procid( _self );
if (status != TT_OK) {
break;
}
_self->set_fd();
status = _handle_Session_Trace();
if (status != TT_OK) {
break;
}
status = _observe_Saved();
if (status != TT_OK) {
break;
}
} while (0);
_tt_global->drop_mutex();
return TT_OK;
}
Tt_status
_Tt_s_mp::_handle_Session_Trace()
{
//
// tt_pattern_create(), tt_pattern_category_set(),
// tt_pattern_scope_add(), tt_pattern_session_add(),
// tt_pattern_op_add(), tt_pattern_arg_add()
//
_Tt_s_pattern_ptr pat = _Tt_self_procid::s_pattern_create();
Tt_status status = pat->set_category( TT_HANDLE );
if (status != TT_OK) {
return status;
}
status = pat->add_message_class( TT_REQUEST );
if (status != TT_OK) {
return status;
}
status = pat->add_scope( TT_SESSION );
if (status != TT_OK) {
return status;
}
status = pat->add_session( _tt_s_mp->initial_s_session->address_string() );
if (status != TT_OK) {
return status;
}
status = pat->add_op( "Session_Trace" );
if (status != TT_OK) {
return status;
}
_Tt_arg_ptr arg = new _Tt_arg( TT_IN, "string" );
status = pat->add_arg( arg );
if (status != TT_OK) {
return status;
}
pat->server_callback = _Tt_self_procid::handle_Session_Trace;
//
// tt_pattern_register()
//
status = _self->add_pattern( pat );
if (status != TT_OK) {
return status;
}
//
// tt_session_join()
//
// _Tt_s_procid_ptr s_proc = (_Tt_s_procid *)_self.c_pointer();
// status = _tt_s_mp->initial_s_session->s_join( s_proc );
// if (status != TT_OK) {
// return status;
// }
return TT_OK;
}
Tt_status
_Tt_s_mp::_observe_Saved()
{
//
// tt_pattern_create(), tt_pattern_category_set(),
// tt_pattern_scope_add(), tt_pattern_op_add(), tt_pattern_arg_add()
//
_Tt_s_pattern_ptr pat = _Tt_self_procid::s_pattern_create();
Tt_status status = pat->set_category( TT_OBSERVE );
if (status != TT_OK) {
return status;
}
status = pat->add_message_class( TT_NOTICE );
if (status != TT_OK) {
return status;
}
status = pat->add_scope( TT_BOTH );
if (status != TT_OK) {
return status;
}
status = pat->add_session( _tt_s_mp->initial_s_session->address_string() );
if (status != TT_OK) {
return status;
}
_Tt_string_list_ptr ttpath = _Tt_typedb::tt_path();
if (ttpath.is_null()) {
return TT_ERR_NOMEM;
}
_Tt_string_list_cursor pathC( ttpath );
while (pathC.next()) {
status = pat->add_netfile( *pathC, 1 );
if (status != TT_OK) {
return status;
}
}
status = pat->add_op( "Saved" );
if (status != TT_OK) {
return status;
}
_Tt_arg_ptr arg = new _Tt_arg( TT_IN, "File" );
status = pat->add_arg( arg );
if (status != TT_OK) {
return status;
}
pat->server_callback = _Tt_self_procid::observe_Saved;
//
// tt_pattern_register()
//
status = _self->add_pattern( pat );
if (status != TT_OK) {
return status;
}
status = pat->join_files(_tt_s_mp->initial_s_session->process_tree_id());
if (status != TT_OK) {
return status;
}
return TT_OK;
}
//
// Installs a list of signatures. Each signature is installed in a table
// called sigs_table that maps op names to lists of signatures with that
// same opname. This cuts down on the number of signatures that need to
// be examined to dispatch a message.
//
void _Tt_s_mp::
install_signatures(_Tt_signature_list_ptr &s)
{
_Tt_signature_list_cursor sigC(s);
_Tt_sigs_by_op_ptr sigs_byop;
while (sigC.next()) {
sigs_byop = (_Tt_sigs_by_op *)0;
if (! sigs->lookup(sigC->op(),sigs_byop)) {
sigs_byop = new _Tt_sigs_by_op(sigC->op());
sigs_byop->sigs = new _Tt_signature_list();
sigs->insert(sigs_byop);
}
sigs_byop->sigs->push(*sigC);
}
}
void _Tt_s_mp::
remove_signatures(const _Tt_ptype &ptype)
{
_Tt_sigs_by_op_table_cursor sigs_byopC(sigs);
while (sigs_byopC.next()) {
_Tt_signature_list_cursor sigC(sigs_byopC->sigs);
while (sigC.next()) {
if (sigC->ptid() == ptype.ptid()) {
sigC.remove();
}
}
}
}
void _Tt_s_mp::
remove_signatures(const _Tt_otype &otype)
{
_Tt_sigs_by_op_table_cursor sigs_byopC(sigs);
while (sigs_byopC.next()) {
_Tt_signature_list_cursor sigC(sigs_byopC->sigs);
while (sigC.next()) {
if (sigC->otid() == otype.otid()) {
sigC.remove();
}
}
}
}
//
// Iterates through the given table of ptypes and installs all the
// signatures contained in each ptype.
//
void _Tt_s_mp::
install_ptable(_Tt_ptype_table_ptr &p)
{
_Tt_ptype_table_cursor ptypes;
ptable = p;
ptypes.reset(ptable);
while (ptypes.next()) {
remove_signatures(**ptypes);
install_signatures(ptypes->hsigs());
install_signatures(ptypes->osigs());
}
}
//
// Iterates through the given table of otypes and installs all the
// signatures contained in each otype.
//
void _Tt_s_mp::
install_otable(_Tt_otype_table_ptr &o)
{
_Tt_otype_table_cursor otypes;
otable = o;
otypes.reset(otable);
while (otypes.next()) {
remove_signatures(**otypes);
install_signatures(otypes->hsigs());
install_signatures(otypes->osigs());
}
}
//
// It is important that the mp contain exactly one object for each
// procid that is registered because there is state that is contained
// in this instance of a procid that shouldn't be duplicated. This
// method takes a generic \(neither server nor client\) procid and
// returns either
// the _Tt_s_procid object that the mp has for the given id or else creates
// a new object if create_ifnot is equal to 1. When a procid is
// initialized, it's signalling fd is added to two parallel lists,
// _active_fds and _active_fds_procids. _active_fds contains a list
// of fds whereas _active_fds_procids contains a list of procid ids.
// Each position in the two lists corresponds to each other. This is
// equivalent to having a single list of records where each record
// contains an fd and a procid id. These lists are used by the
// _Tt_s_mp::main_loop to poll all the fds in the list and match them
// with their respective procids.
//
// The _active_fds_procids list can contain two "pseudo-procids" that
// are used to keep track of some special fds. These can be "U" for
// the special unix socket fd (used if OPT_UNIX_SOCKET_RPC is defined)
// that clients use to establish a unix socket rpc connection, and "X"
// for the fd that represents the connection to our desktop session.
// See _Tt_s_mp::main_loop to see how they are used.
//
// XXX: Replacing the parallel list structure with a list of records
// would increase readability.
//
int
_Tt_s_mp::find_proc(
const _Tt_procid_ptr &procid,
_Tt_s_procid_ptr &proc_returned,
int create_ifnot
)
{
_Tt_s_procid_ptr sp;
if (! procid.is_null()) {
if (! _last_proc_hit.is_null()) {
if (_last_proc_hit->is_equal(procid)) {
proc_returned = _last_proc_hit;
return(1);
}
}
active_procs->lookup(procid->id(),sp);
}
if (!sp.is_null()) {
_last_proc_hit = sp;
proc_returned = sp;
return(1);
}
if (create_ifnot) {
sp = new _Tt_s_procid(procid);
/* procid not found, add it to list */
if (sp->init() == TT_OK) {
proc_returned = sp;
add_procid( sp );
return(1);
} else {
return(0);
}
} else {
return(0);
}
}
//
// Called in order to generate a unique key for a new procid. This key is
// prepended to a procid's session in order to form an id that is unique
// among all procids joined to the server's session.
//
_Tt_string _Tt_s_mp::
alloc_procid_key()
{
int key = _next_procid_key++;
_Tt_string result(_tt_base64_encode((unsigned long)key));
result = result.cat(".").cat(_tt_base64_encode((unsigned long)_mp_start_time));
return(result);
}
//
// This is the main loop of the message server. This method is
// responsible for servicing events such as rpc requests, disconnect
// signals from procids, connection requests for unix socket rpc
// requests, and events generated from our desktop connection (if
// applicable). The main loop checks for the values of exit_main_loop
// and of fin and fout (see comments in bin/ttsession/mp_server.C)
// before invoking the _Tt_rpc_server::run method which will block on
// rpc requests and polling on the supplied list of file descriptors
// supplied in the _active_fds list.
//
void _Tt_s_mp::
main_loop()
{
_Tt_int_rec_list_cursor fds;
_Tt_string_list_cursor fd_procid;
_Tt_s_procid_ptr sp;
while (! exit_main_loop && (fin == fout)) {
switch (initial_s_session->_rpc_server->run_until(&exit_main_loop,
_min_timeout,
_active_fds)) {
case _TT_RPCSRV_ERR:
case _TT_RPCSRV_OK:
break;
case _TT_RPCSRV_TMOUT:
break;
case _TT_RPCSRV_FDERR:
// this error code is returned if any of the
// file descriptors in _active_fds has input
// pending. In the case of file descriptors
// associated with procid signalling channels
// this means that the connection to them was
// lost, in the case of the file descriptor
// being associated with the desktop
// connection this means that there was an
// event generated by the desktop server.
// Otherwise, if the file descriptor was the
// one associated with the unix socket rpc
// socket then this is a new connection
// request.
//
// Note that the _Tt_rpc_server::run method
// will indicate which fd was active by
// negating its value thus the test for being
// less than zero indicates that was the fd we
// were looking for.
fds.reset(_active_fds);
fd_procid.reset(_active_fds_procids);
while (fds.next() && fd_procid.next()) {
if (fds->val < 0) {
if (*fd_procid == "X") {
// X event came in
fds->val *= -1;
if (initial_session->desktop_event_callback()==-1) {
exit_main_loop = 1;
xfd = -2;
break;
}
#ifdef OPT_UNIX_SOCKET_RPC
} else if ((0 - fds->val)==unix_fd) {
// connection request
// for local rpc transport.
fds->val = unix_fd;
initial_s_session->u_rpc_init();
#endif // OPT_UNIX_SOCKET_RPC
} else {
// signalling channel
// became active for
// some procid. This
// means the
// connection was lost
// since the
// signalling channel
// is a write-only
// connection.
if (active_procs->lookup(*fd_procid,sp)) {
// Before cleaning up,
// send any on_exit
// messages.
sp->send_on_exit_messages();
sp->set_active(-1);
active_procs->remove(sp->id());
}
fds.remove();
fd_procid.remove();
}
}
}
break;
default:
break;
}
}
}
//
// Returns 1 if there exist file-scope patterns for the given pathname.
// Uses the two parallel lists _file_scope_paths and
// _file_scope_refcounts which form a logical list of records of file
// pathnames to number of patterns registered.
//
// XXX: Use of parallel lists is confusing. Recoding using a single list
// of records would improve readability.
//
int _Tt_s_mp::
in_file_scope(const _Tt_string &f)
{
if (_file_scope_refcounts.is_null()) {
return(0);
}
_Tt_int_rec_list_cursor refcounts(_file_scope_refcounts);
_Tt_string_list_cursor paths(_file_scope_paths);
while (refcounts.next() && paths.next()) {
if (*paths == f) {
return(1);
}
}
return(0);
}
//
// Adds (subtracts) number of file-scope patterns registered for the
// given pathname if add_scope is 1 (0). If the refcount of patterns goes
// to 0 then the pathname is removed from the _file_scope_refcounts and
// _file_scope_paths lists. See comment for _Tt_s_mp::in_file_scope for
// an explanation of these lists.
//
void _Tt_s_mp::
mod_file_scope(const _Tt_string &f, int add_scope)
{
if (_file_scope_refcounts.is_null()) {
_file_scope_refcounts = new _Tt_int_rec_list();
_file_scope_paths = new _Tt_string_list();
}
_Tt_int_rec_list_cursor refcounts(_file_scope_refcounts);
_Tt_string_list_cursor paths(_file_scope_paths);
while (refcounts.next() && paths.next()) {
if (*paths == f) {
refcounts->val += (add_scope ? 1 : -1);
if (refcounts->val == 0) {
refcounts.remove();
paths.remove();
}
return;
}
}
if (add_scope) {
_file_scope_refcounts->push(new _Tt_int_rec(1));
_file_scope_paths->push(f);
}
}
Tt_status
_Tt_s_mp::add_procid(
_Tt_s_procid_ptr &proc
)
{
_active_fds->push(new _Tt_int_rec(-1));
_active_fds_procids->push(proc->id());
active_procs->insert(proc);
_last_proc_hit = proc;
return TT_OK;
}
//
// Called in response to a client invoking the tt_close api call. This
// method will deallocate any resources that this procid holds and will
// remove the procid reference from any global data-structures.
//
Tt_status _Tt_s_mp::
s_remove_procid(_Tt_s_procid &proc)
{
proc.cancel_on_exit_messages();
// de-activate this procid
proc.set_active(0);
// remove from list of active procs
active_procs->remove(proc.id());
return(TT_OK);
}

120
cde/lib/tt/slib/mp_s_mp.h Normal file
View File

@@ -0,0 +1,120 @@
/*%% (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_s_mp.h /main/4 1996/08/30 17:02:52 drk $ */
/*
* @(#)mp_s_mp.h 1.20 94/11/17
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* This file implements the _Tt_s_mp object which represents the global
* information for the server MP component. There should only be one
* instance of a _Tt_s_mp object in the server.
*/
#ifndef _MP_S_MP_H
#define _MP_S_MP_H
#include "tt_options.h"
#include "mp/mp_mp.h"
#include "util/tt_table.h"
#include <rpc/rpc.h>
#include <signal.h>
#include "mp/mp_global.h"
#include "mp/mp_session_utils.h"
#include "mp_s_session_utils.h"
#include "mp/mp_file_utils.h"
#include "mp/mp_procid.h"
#include "mp/mp_procid_utils.h"
#include "mp_s_procid.h"
#include "mp_s_procid_utils.h"
#include "mp/mp_pattern_utils.h"
#include "mp_typedb_utils.h"
#include "mp_ptype_utils.h"
#include "mp_otype_utils.h"
#include "mp_rpc_implement.h"
#include "mp_signature_utils.h"
#include "util/tt_int_rec.h"
const int SIGTYPES = SIGUSR2;
class _Tt_s_mp : public _Tt_mp {
public:
_Tt_s_mp();
virtual ~_Tt_s_mp();
Tt_status init();
void main_loop();
_Tt_string alloc_procid_key();
int find_proc(const _Tt_procid_ptr &procid,
_Tt_s_procid_ptr &p,
int create_ifnot);
void set_timeout(int timeout);
void install_ptable(_Tt_ptype_table_ptr &p);
void install_otable(_Tt_otype_table_ptr &o);
void remove_signatures(const _Tt_ptype &p);
void remove_signatures(const _Tt_otype &o);
void install_signatures(_Tt_signature_list_ptr &s);
_Tt_ptype_table_ptr ptable;
_Tt_otype_table_ptr otable;
_Tt_sigs_by_op_table_ptr sigs;
_Tt_patlist_table_ptr opful_pats;
_Tt_pattern_list_ptr opless_pats;
unsigned int now;
unsigned int when_last_observer_registered;
_Tt_update_args update_args;
int max_active_messages;
_Tt_string udb;
_Tt_string sdb;
_Tt_string ndb;
int map_ptypes;
_Tt_pid_t_rec_list_ptr failed_proc_starts;
int exit_main_loop;
int unix_cred_chk_flag;
int xfd;
#ifdef OPT_UNIX_SOCKET_RPC
int unix_fd;
#endif
int fin;
int fout;
int in_file_scope(const _Tt_string &f);
void mod_file_scope(const _Tt_string &f,
int add);
_Tt_s_procid_table_ptr active_procs;
_Tt_s_session_ptr initial_s_session;
Tt_status add_procid(_Tt_s_procid_ptr &proc);
Tt_status s_remove_procid(_Tt_s_procid &proc);
Tt_status s_init();
Tt_status init_self();
_Tt_typedb_ptr tdb;
pid_t garbage_collector_pid;
private:
Tt_status _handle_Session_Trace();
Tt_status _observe_Saved();
//
// These are used to clean out dead ttsession's from dbserver.
// The SIGCHLD from its PID (garbage_collector_pid - above) can be
// ignored. Garbage collection occurs at startup and once per
// day and sets _next_garbage_run to be current time + 24 hours.
//
void _collect_garbage();
long _next_garbage_run;
int _mp_start_time;
int _next_procid_key;
_Tt_int_rec_list_ptr _active_fds;
_Tt_string_list_ptr _active_fds_procids;
_Tt_int_rec_list_ptr _file_scope_refcounts;
_Tt_string_list_ptr _file_scope_paths;
_Tt_s_procid_ptr _last_proc_hit;
_Tt_s_procid_ptr _self;
int _min_timeout;
friend class _Tt_s_procid;
};
extern _Tt_s_mp *_tt_s_mp;
#endif /* _MP_S_MP_H */

View 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_s_msg_context.C /main/3 1995/10/23 11:56:51 rswiston $
/*
*
* @(#)mp_s_msg_context.C 1.4 29 Jul 1993
*
* Tool Talk Message Passer (MP) - mp_s_msg_context.cc
*
* Copyright (c) 1992 by Sun Microsystems, Inc.
*
* _Tt_s_msg_context knows the server side of the context RPC interface.
*/
#include <mp/mp_arg.h>
#include <mp/mp_procid.h>
#include "mp_s_pattern.h"
#include "mp_s_msg_context.h"
_Tt_s_msg_context::_Tt_s_msg_context()
{
}
_Tt_s_msg_context::~_Tt_s_msg_context()
{
}
Tt_status
_Tt_s_msg_context::s_join(
_Tt_procid_ptr &procID
) const
{
_Tt_pattern_list_cursor patC( procID->patterns() );
Tt_status status;
Tt_status worstStatus = TT_OK;
while (patC.next()) {
status = ((_Tt_s_pattern &)**patC).join_context( *this );
switch (status) {
case TT_OK:
case TT_WRN_NOTFOUND:
break;
default:
worstStatus = status;
}
}
return worstStatus;
}
Tt_status
_Tt_s_msg_context::s_quit(
_Tt_procid_ptr &procID
) const
{
_Tt_pattern_list_cursor patC( procID->patterns() );
Tt_status status;
Tt_status worstStatus = TT_OK;
while (patC.next()) {
status = ((_Tt_s_pattern &)**patC).quit_context( *this );
switch (status) {
case TT_OK:
case TT_WRN_NOTFOUND:
break;
default:
worstStatus = status;
}
}
return worstStatus;
}

View 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_s_msg_context.h /main/3 1995/10/23 11:57:02 rswiston $ */
/* -*-C++-*-
*
* @(#)mp_s_msg_context.h 1.3 29 Jul 1993
*
* Tool Talk Message Passer (MP) - mp_s_msg_context.h
*
* Copyright (c) 1992 by Sun Microsystems, Inc.
*
* _Tt_s_msg_context knows the client side of the context RPC interface.
*/
#ifndef _MP_S_MSG_CONTEXT_H
#define _MP_S_MSG_CONTEXT_H
#include <mp/mp_msg_context.h>
#include <mp/mp_session.h>
#include <mp/mp_procid_utils.h>
class _Tt_s_msg_context : public _Tt_msg_context {
public:
_Tt_s_msg_context();
virtual ~_Tt_s_msg_context();
Tt_status s_join(
_Tt_procid_ptr &procID
) const;
Tt_status s_quit(
_Tt_procid_ptr &procID
) const;
};
#endif /* _MP_S_MSG_CONTEXT_H */

View 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.
//%% $XConsortium: mp_s_pat_context.C /main/3 1995/10/23 11:57:14 rswiston $
/*
*
* @(#)mp_s_pat_context.C 1.6 29 Jul 1993
*
* Tool Talk Pattern Passer (MP) - mp_s_pat_context.cc
*
* Copyright (c) 1992 by Sun Microsystems, Inc.
*
* _Tt_s_pat_context knows server-side context matching.
*/
#include <mp/mp_arg.h>
#include <mp/mp_message.h>
#include "mp_s_pat_context.h"
_Tt_s_pat_context::
_Tt_s_pat_context()
{
}
_Tt_s_pat_context::
_Tt_s_pat_context(const _Tt_context &c) : _Tt_pat_context(c)
{
}
_Tt_s_pat_context::
~_Tt_s_pat_context()
{
}
int _Tt_s_pat_context::
matchVal(
const _Tt_message &msg
)
{
_Tt_msg_context_ptr msgCntxt = msg.context( slotName() );
if (msgCntxt.is_null()) {
return 0;
}
if (_values->count() == 0) {
// No values means we are a wild card.
return 1;
}
_Tt_arg_list_cursor argC( _values );
while (argC.next()) {
if (**argC == msgCntxt->value()) {
return 2;
}
}
return 0;
}

View File

@@ -0,0 +1,33 @@
/*%% (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_s_pat_context.h /main/3 1995/10/23 11:57:25 rswiston $ */
/* -*-C++-*-
*
* @(#)mp_s_pat_context.h 1.4 29 Jul 1993
*
* Tool Talk Message Passer (MP) - mp_s_pat_context.h
*
* Copyright (c) 1992 by Sun Microsystems, Inc.
*
* _Tt_s_pat_context knows server-side context matching.
*/
#ifndef _MP_S_PAT_CONTEXT_H
#define _MP_S_PAT_CONTEXT_H
#include <mp/mp_pat_context.h>
class _Tt_s_pat_context : public _Tt_pat_context {
public:
_Tt_s_pat_context();
_Tt_s_pat_context(const _Tt_context &c);
virtual ~_Tt_s_pat_context();
int matchVal(
const _Tt_message &msg
);
};
#endif /* _MP_S_PAT_CONTEXT_H */

View File

@@ -0,0 +1,525 @@
//%% (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_s_pattern.C /main/3 1995/10/23 11:57:37 rswiston $
/*
* @(#)mp_s_pattern.C 1.27 93/09/07
*
* mp_s_pattern.cc
*
* Copyright (c) 1990, 1992 by Sun Microsystems, Inc.
*/
#include "mp_s_global.h"
#include "mp/mp_arg.h"
#include "mp_s_pat_context.h"
#include "mp/mp_mp.h"
#include "mp_s_mp.h"
#include "mp_s_pattern.h"
#include "mp_s_message.h"
#include "mp_signature.h"
#include "mp_observer.h"
#include "mp_ptype.h"
#include "mp_rpc_implement.h"
#include "mp_s_session.h"
#include "mp/mp_xdr_functions.h"
#include "util/tt_enumname.h"
#include "mp/mp_trace.h"
#include "util/tt_global_env.h"
#include "util/tt_assert.h"
//
// Creates a pattern from a signature object by extracting the relevant
// fields from the signature.
//
_Tt_s_pattern::
_Tt_s_pattern(const _Tt_signature_ptr &sig)
{
_timestamp = 0;
set_id(_tt_s_mp->initial_session->address_string());
set_category(sig->category());
add_scope(sig->scope());
add_op(sig->op());
if (sig->opnum() != -1) {
add_opnum(sig->opnum());
}
if (sig->category()!=TT_OBSERVE) {
add_handler_ptype(sig->ptid());
}
if (sig->otid().len() > 0) {
add_otype(sig->otid());
add_paradigm(TT_OTYPE);
add_paradigm(TT_OBJECT);
} else {
add_paradigm(TT_PROCEDURE);
}
add_reliability(sig->reliability());
add_message_class(sig->message_class());
// We share the arg list from the signature
// by just assigning the pointer and letting the ref-counting
// system do its thing. Conceivably, this might cause
// consternation if we ever let clients update patterns created
// from signatures, since updating the arg list would change
// the in-memory copy of the signature and every other pattern
// generated from the signature! However, the most likely
// way such updates would be generated would be to send a whole
// new pattern over from the client, so sharing the arg list
// wouldn\'t cause trouble.
_args = sig->args();
// We *cannot* share the context list from the signature as
// the signature contains plain _Tt_context entries, while
// the pattern should contain _Tt_pat_context entries.
_Tt_context_list_cursor c(sig->contexts());
while (c.next()) {
_Tt_pat_context_ptr nc = new _Tt_pat_context(**c);
add_context(nc);
}
}
_Tt_s_pattern::_Tt_s_pattern ()
{
_timestamp = 0;
}
_Tt_s_pattern::~_Tt_s_pattern ()
{
}
//
// Matches a pattern with a message and returns a number indicating how
// well the pattern matches the message. 0 indicates no match whereas a
// positive number indicates some level of matching. The greater the
// level, the "better" the pattern matches the message. A level of 1
// indicates all the pattern fields are wildcards so this is the minimum
// level of matching. Any level greater than 1 is controlled by the
// number returned from each field match. Thus twiddling these numbers
// gives some control as to what field matches are to be considered more
// important than others. Presently, the algorithm for selecting match
// numbers is that wildcard matches count as 0 whereas any specific match
// counts as 1. The total is added up for each field and returned as the
// value of the match. The variable tm below holds the total count of
// matches. It is initially 1 because wildcard matches don't increment
// it. In any submethod called to do matching the variable tm is passed
// to the method to be incremented.
//
int _Tt_s_pattern::
match(const _Tt_s_message &msg, const _Tt_msg_trace &trace) const
{
int tm = 1;
if (msg.is_handler_copy()) {
// message is the original
if ( (! _generating_ptype.is_null())
&& (category() == TT_OBSERVE))
{
//
// A static observer pattern can only match
// the message copy promised to it,
// and cannot match the original.
//
return 0;
}
} else {
// message is a copy promised to observer ptype
if ( (_generating_ptype.is_null())
|| ( msg.observer()->ptid()
!= _generating_ptype->ptid()))
{
//
// If this pattern is not owned by the
// promised ptype, or is owned by no
// ptype, then this pattern cannot
// fulfill the promise.
//
return 0;
}
}
trace << "Tt_message & Tt_pattern {\n";
trace.incr_indent();
trace << "timestamp:\t" << _timestamp << "\n";
trace << *this;
trace.decr_indent();
trace << "} ";
// The code for this method is quite repetitive. For each
// field, the list is checked to see if there are any values. If
// there are and the appropiate match method returns 0 then the
// pattern fails to match. The only exception is match_scopes
// which defaults to not matching if there are no values specified.
// This function used to not match the op field of the
// message, because in the usual code path it is
// hashed on the basis of the op field so it would be
// redundant to check the op field here. However, when
// matching TT_HANDLER messages just to get callbacks run,
// this is not the case. To save a little time, we skip
// the op check if the message paradigm is not TT_HANDLER,
// even though that looks really funny here!
if (0 != _ops->count()) {
if (msg.paradigm() == TT_HANDLER &&
! match_field(msg.op(), _ops,
tm, trace, "op" ))
{
return(0);
}
tm++;
}
if (_reliabilities != 0) {
if (!(_reliabilities&(1<<msg.reliability()))) {
trace << "== 0; /* Tt_disposition */\n";
return(0);
}
tm++;
}
if (_states != 0) {
if (!(_states&(1<<msg.state()))) {
trace << "== 0; /* Tt_state */\n";
return(0);
}
tm++;
}
if (_classes != 0) {
if (!(_classes&(1<<TT_CLASS_UNDEFINED))
&& !(_classes&(1<< msg.message_class()))) {
trace << "== 0; /* Tt_class */\n";
return(0);
}
tm++;
}
if (_paradigms != 0) {
if (!(_paradigms&(1<<msg.paradigm()))) {
trace << "== 0; /* Tt_address */\n";
return(0);
}
tm++;
}
if (_handlers->count()) {
_Tt_string h;
if (! msg.handler().is_null()) {
h = msg.handler()->id();
}
if (! match_field(h, _handlers, tm, trace, "handler")) {
return(0);
}
}
if (_handler_ptypes->count() &&
! match_field(msg.handler_ptype(), _handler_ptypes,
tm, trace, "handler_ptype" ))
{
return(0);
}
if (! match_scopes(msg, tm, trace)) {
return(0);
}
if (msg.scope() == TT_SESSION) {
if (_files->count() &&
! match_field(msg.file(), _files,
tm, trace, "file"))
{
return(0);
}
}
if (_objects->count() &&
! match_field(msg.object(), _objects,
tm, trace, "object"))
{
return(0);
}
if (_otypes->count() &&
! match_field(msg.otype(), _otypes,
tm, trace, "otype"))
{
return(0);
}
if (_senders->count() &&
! match_field(msg.sender()->id(), _senders,
tm, trace, "sender"))
{
return(0);
}
if (_sender_ptypes->count() &&
! match_field(msg.sender_ptype(), _sender_ptypes,
tm, trace, "sender_ptype"))
{
return(0);
}
if (_args->count() && ! match_args(msg, tm, trace)) {
return(0);
}
if (! match_contexts(msg, tm, trace)) {
return(0);
}
trace << "== " << tm << ";\n";
return(tm);
}
//
// Generic matching function for lists of integers. If the given pattern
// values, pvals, is empty then 0 is returned indicating a mismatch.
// Otherwise, 1 is returned if "val" is in the list and the variable tm
// is incremented to update the matching score in _Tt_pattern::match.
//
int _Tt_s_pattern::
match_field(int val, const _Tt_int_rec_list_ptr &pvals, int &tm,
const _Tt_msg_trace &trace, const char *failure_note) const
{
_Tt_int_rec_list_cursor c(pvals);
while (c.next()) {
if (val == c->val) {
tm++;
return(1);
}
}
if (failure_note != 0) {
trace << "== 0; /* " << failure_note << " */\n";
}
return(0);
}
//
// Generic matching function for lists of strings. If the given pattern
// values, pvals, is empty then 0 is returned indicating a mismatch.
// Otherwise, 1 is returned if "val" is in the list and the variable tm
// is incremented to update the matching score in _Tt_pattern::match.
//
int _Tt_s_pattern::
match_field(const _Tt_string &val, const _Tt_string_list_ptr &pvals,
int &tm, const _Tt_msg_trace &trace,
const char *failure_note) const
{
_Tt_string_list_cursor c(pvals);
if (val.len() != 0) {
while (c.next()) {
if (val == *c) {
tm++;
return(1);
}
}
}
if (failure_note != 0) {
trace << "== 0; /* " << failure_note << " */\n";
}
return(0);
}
//
// Matches the scope of the message with the pattern scopes. For the
// different scopes, matching is defined differently as specified below.
//
int _Tt_s_pattern::
match_scopes(const _Tt_message &msg, int &tm,
const _Tt_msg_trace &trace) const
{
Tt_scope s = msg.scope();
int valid_scope_mask = 0;
int rval;
ASSERT(TT_SCOPE_NONE==0 && TT_SESSION==1 && TT_FILE==2 &&
TT_BOTH==3 && TT_FILE_IN_SESSION==4,
"Tt_scope enum values changed. This breaks the following "
"code, and also breaks binary compatibility for libtt users. "
"You probably don't want to do that, do you?")
static int valid_scope_masks[] = {
0, // TT_SCOPE_NONE
(1<<TT_SESSION) | (1<<TT_BOTH), // TT_SESSION
(1<<TT_FILE) | (1<<TT_BOTH), // TT_FILE
(1<<TT_SESSION) | (1<<TT_FILE) | (1<<TT_BOTH), // TT_BOTH
(1<<TT_FILE_IN_SESSION)}; // TT_FILE_IN_SESSION
if (! (_scopes & valid_scope_masks[s])) {
trace << "== 0; /* " << _tt_enumname(s) << " != Tt_scopes */\n";
return 0;
}
// if this is not a file-scoped message and the pattern
// doesn't contain a value for the _sessions list then we
// immediately fail the match.
if (s != TT_FILE &&
(msg.session().is_null() || _sessions->count() == 0)) {
trace << "== 0; /* pattern not joined to "
"tt_message_session() */\n";
return 0;
}
switch (s) {
case TT_FILE:
return match_field(msg.file(), _files,
tm, trace, "file" );
case TT_FILE_IN_SESSION:
if (msg.session()->has_id(_sessions)) {
return((_files->count() == 0)
|| match_field(msg.file(), _files,
tm, trace, "file"));
} else {
trace << "== 0; /* file in session */\n";
return(0);
}
case TT_SESSION:
// The session-scope case is so common that we avoid
// matching the session id by setting a flag on a
// pattern that we know is in the session (see
// _Tt_s_procid::add_pattern and
// _Tt_session::mod_session_id_in_patterns to see how
// the flag is set). This flag is turned on if this
// pattern is joined to the current session or not.
if (in_session()) {
return(1);
} else {
trace << "== 0; /* session */\n";
}
return(0);
case TT_BOTH:
rval = (msg.session()->has_id(_sessions) +
match_field(msg.file(), _files, tm, trace, 0));
if (rval == 0) {
trace << "== 0; /* file and session */\n";
}
return(rval);
case TT_SCOPE_NONE:
default:
trace << "== 0; /* Tt_scope */\n";
return(0);
}
}
//
// Returns 1 if the message's args match the pattern args. The
// _Tt_arg::is_match method is used to do the bulk of the work.
//
int _Tt_s_pattern::
match_args(const _Tt_message &msg, int &tm,
const _Tt_msg_trace &trace) const
{
if (msg.args()->count() == 0) {
// arg matching was specified but the
// message doesn't contain any args.
trace << "== 0; /* args */\n";
return(0);
}
_Tt_arg_list_cursor p_args(_args);
_Tt_arg_list_cursor m_args(msg.args());
int cumulative_args_score = 0;
while (p_args.next()) {
if (!m_args.next()) {
trace << "== 0; /* args */\n";
return(0);
}
int used_wildcard;
int score = p_args->match_score(*m_args, used_wildcard);
if (score <= 0) {
trace << "== 0; /* args */\n";
return(0);
}
cumulative_args_score += score;
}
tm += cumulative_args_score;
return(1);
}
//
// Returns 1 if the message's contexts match pattern's contexts.
//
int _Tt_s_pattern::
match_contexts(const _Tt_message &msg, int &tm,
const _Tt_msg_trace &trace) const
{
_Tt_pat_context_list_cursor cntxtC( _contexts );
while (cntxtC.next()) {
if (((_Tt_s_pat_context &)**cntxtC).matchVal( msg ) == 0) {
trace << "== 0; /* contexts */\n";
return 0;
}
}
tm++;
return 1;
}
// Routines to set and get the ptype that this pattern was generated
// from, and to test if it was so generate.
_Tt_ptype_ptr &_Tt_s_pattern::
generating_ptype(_Tt_ptype_ptr &pt)
{
_generating_ptype = pt;
return pt;
}
_Tt_ptype_ptr &_Tt_s_pattern::
generating_ptype()
{
return _generating_ptype;
}
int _Tt_s_pattern::
is_from_ptype()
{
return !_generating_ptype.is_null();
}
Tt_status _Tt_s_pattern::
join_context(const _Tt_msg_context &msgCntxt)
{
_Tt_pat_context_list_cursor contextC( _contexts );
while (contextC.next()) {
if (contextC->slotName() == msgCntxt.slotName()) {
return contextC->addValue( msgCntxt );
}
}
return TT_WRN_NOTFOUND;
}
Tt_status _Tt_s_pattern::
quit_context(const _Tt_msg_context &msgCntxt)
{
_Tt_pat_context_list_cursor contextC( _contexts );
while (contextC.next()) {
if (contextC->slotName() == msgCntxt.slotName()) {
return contextC->deleteValue( msgCntxt );
}
}
return TT_WRN_NOTFOUND;
}

View 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_s_pattern.h /main/3 1995/10/23 11:57:50 rswiston $ */
/* -*-C++-*-
*
* @(#)mp_s_pattern.h 1.7 29 Jul 1993
*
* Tool Talk Message Passer (MP) - mp_s_pattern.h
*
* Copyright (c) 1990, 1992 by Sun Microsystems, Inc.
*
* This file implements the server side of the _Tt_pattern object.
*/
#ifndef _MP_S_PATTERN_H
#define _MP_S_PATTERN_H
#include "mp/mp_pattern.h"
#include "mp/mp_arg_utils.h"
#include "mp_ptype_utils.h"
#include "mp_s_pattern_utils.h"
#include "mp_signature_utils.h"
class _Tt_msg_trace;
class _Tt_s_message;
class _Tt_s_pattern : public _Tt_pattern {
public:
_Tt_s_pattern();
_Tt_s_pattern(const _Tt_signature_ptr &sig);
virtual ~_Tt_s_pattern();
int match(
const _Tt_s_message &m,
const _Tt_msg_trace &trace
) const;
Tt_status add_arg(const _Tt_arg_ptr &arg);
Tt_status join_context(const _Tt_msg_context &context);
Tt_status quit_context(const _Tt_msg_context &context);
_Tt_ptype_ptr &generating_ptype(); // ptype it was generated
// by declaring
_Tt_ptype_ptr &generating_ptype(_Tt_ptype_ptr &pt); // set it
int is_from_ptype(); // true if generated by
// declaring a ptype
unsigned int timestamp() const
{ return _timestamp; }
void set_timestamp(unsigned int stamp)
{ _timestamp = stamp; }
protected:
// server-only methods that aid in matching patterns and
// messages.
int match_field(
int val,
const _Tt_int_rec_list_ptr &pvals,
int &tm,
const _Tt_msg_trace &trace,
const char *failure_note
) const;
int match_field(
const _Tt_string &val,
const _Tt_string_list_ptr &pvals,
int &tm,
const _Tt_msg_trace &trace,
const char *failure_note
) const;
int match_scopes(
const _Tt_message &m,
int &tm,
const _Tt_msg_trace &trace
) const;
int match_args(
const _Tt_message &m,
int &tm,
const _Tt_msg_trace &trace
) const;
int match_contexts(
const _Tt_message &m,
int &tm,
const _Tt_msg_trace &trace
) const;
private:
_Tt_ptype_ptr _generating_ptype;
unsigned int _timestamp;
friend class _Tt_mp;
friend class _Tt_message;
};
#include "mp_s_pattern_inlines.h"
#endif /* _MP_S_PATTERN_H */

View 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_s_pattern_inlines.h /main/3 1995/10/23 11:58:03 rswiston $ */
/*
*
* mp_s_pattern_inlines.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
// inline functions definitions for selected _Tt_s_pattern methods.
inline Tt_status _Tt_s_pattern::
add_arg(const _Tt_arg_ptr &arg)
{
_args->append(arg);
return(TT_OK);
}

View 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_s_pattern_utils.C /main/3 1995/10/23 11:58:17 rswiston $
/*
*
* mp_s_pattern_utils.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp_s_pattern.h"
implement_ptr_to(_Tt_s_pattern)

View 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_s_pattern_utils.h /main/3 1995/10/23 11:58:28 rswiston $ */
/*
*
* mp_s_pattern_utils.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#ifndef MP_S_PATTERN_UTILS_H
#define MP_S_PATTERN_UTILS_H
#include <mp/mp_pattern_utils.h>
class _Tt_s_pattern;
declare_derived_ptr_to(_Tt_s_pattern,_Tt_pattern)
#endif /* MP_S_PATTERN_UTILS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
/*%% (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_s_procid.h /main/3 1995/10/23 11:59:00 rswiston $ */
/* %w% @(#)
*
* Copyright (c) 1990, 1992 by Sun Microsystems, Inc.
*
* This file implements the server side of the _Tt_procid object.
*/
#ifndef _MP_S_PROCID_H
#define _MP_S_PROCID_H
#include "mp/mp_procid.h"
#include "mp/mp_trace.h"
#include "mp_ptype_utils.h"
#include "mp_s_procid_utils.h"
#include "mp_s_message_utils.h"
#include "mp_s_pattern_utils.h"
class _Tt_s_procid : public _Tt_procid {
public:
_Tt_s_procid();
_Tt_s_procid(const _Tt_s_procid_ptr &p);
_Tt_s_procid(const _Tt_procid_ptr &p);
~_Tt_s_procid();
int add_message(const _Tt_s_message_ptr &m);
Tt_status add_pattern(const _Tt_s_pattern_ptr &p);
Tt_status add_signature_patterns(_Tt_ptype_ptr &ptype,
Tt_category category);
Tt_status remove_signature_patterns(_Tt_ptype_ptr &ptype);
Tt_status declare_ptype(_Tt_string ptid);
Tt_status undeclare_ptype(_Tt_string ptid);
Tt_status unblock_ptype(_Tt_string ptid);
Tt_status exists_ptype(_Tt_string ptid);
Tt_status del_pattern(_Tt_string id);
void del_pattern(_Tt_pattern_ptr &p);
//
// Must be virtual, since _Tt_self_procid redefines it
//
virtual Tt_status init();
int is_active() const {
return(_flags&(1<<_TT_PROC_ACTIVE));
}
int is_ptype(_Tt_string ptid);
Tt_status next_message(_Tt_next_message_args &args);
int service_timeout(int timeout);
void activate();
void deactivate(int remove_fds);
void set_active(int on);
int set_fd(int fd = 0);
int set_fd_channel(int port = 0);
void set_timeout_for_message(const _Tt_message &m);
//
// Must be virtual, since _Tt_self_procid redefines them,
// and we put self_procids into lists of s_procids.
//
virtual Tt_status signal_new_message();
virtual Tt_status update_message(const _Tt_message_ptr &m,
Tt_state newstate);
#ifdef OPT_ADDMSG_DIRECT
Tt_status signal_new_message(_Tt_message_ptr &m);
void msgread();
#endif
int timeout() {
return _itimeout;
}
Tt_status add_on_exit_message(_Tt_s_message_ptr &m);
void cancel_on_exit_messages();
void send_on_exit_messages();
private:
int _itimeout;
// messages not yet tt_message_receive()d
_Tt_message_list_ptr _undelivered;
// requests and offers not yet reacted to
_Tt_message_list_ptr _delivered;
_Tt_s_message_list_ptr _on_exit_messages;
};
#endif /* _MP_S_PROCID_H */

View 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_s_procid_utils.C /main/3 1995/10/23 11:59:11 rswiston $
/*
*
* @(#) 29 Jul 1993
*
* Copyright (c) 1992 by Sun Microsystems, Inc.
*/
#include "mp_s_procid_utils.h"
#include "mp_s_procid.h"
implement_list_of(_Tt_s_procid)
implement_table_of(_Tt_s_procid)

View 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_s_procid_utils.h /main/3 1995/10/23 11:59:22 rswiston $ */
/*
*
* @(#) 29 Jul 1993
*
* Copyright (c) 1992 by Sun Microsystems, Inc.
*/
#ifndef MP_S_PROCID_UTILS_H
#define MP_S_PROCID_UTILS_H
#include "util/tt_list.h"
#include "util/tt_table.h"
#include "mp/mp_procid_utils.h"
declare_derived_list_of(_Tt_s_procid,_Tt_procid)
declare_table_of(_Tt_s_procid)
#endif /* MP_S_PROCID_UTILS_H */

View File

@@ -0,0 +1,559 @@
//%% (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_s_session.C /main/6 1999/09/10 19:15:11 mgreess $
/*
* mp_s_session.C 1.25 29 Jul 1993
*
* mp_s_session.cc - Server-only methods of the session object
*
* Copyright (c) 1990,1992 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include "mp/mp_global.h"
#include "mp_s_message.h"
#include "mp_s_mp.h"
#include "mp/mp_mp.h"
#include "mp_s_pattern.h"
#include "mp_s_procid.h"
#include "mp_rpc_server.h"
#include "mp_rpc_implement.h"
#include "mp_s_session.h"
#include "mp/mp_desktop.h"
#include "mp/mp_xdr_functions.h"
#include "util/tt_global_env.h"
#include "util/tt_host.h"
#include "util/tt_enumname.h"
#include "util/tt_port.h"
#include "util/tt_gettext.h"
#include <unistd.h>
#include "util/tt_port.h"
#include <X11/Xlib.h>
#ifdef OPT_UNIX_SOCKET_RPC
# include <sys/socket.h>
# include <sys/un.h>
# include "mp_rpc_server_utils.h"
#endif // OPT_UNIX_SOCKET_RPC
// Use the parent class (_Tt_session) for construction and destruction.
_Tt_s_session::_Tt_s_session () {}
_Tt_s_session::~_Tt_s_session ()
{
#ifdef OPT_UNIX_SOCKET_RPC
if (_socket_name.len()) {
// A UNIX domain socket that was bound to a pathname
// and therefore must be removed by the owner when the session
// server exits. This ensures that when the next session
// server starts, it can choose the same pathname and bind
// to it. The pathname cannot refer to a file existing
// on the system.
(void)unlink(_socket_name);
}
#endif // OPT_UNIX_SOCKET_RPC
}
//
// Callback for i/o errors detected for the desktop session. The default
// action is to exit immediately.
//
int
_tt_xio_handler(Display * /* xdisp */)
{
exit(0);
return 0;
}
#ifdef OPT_UNIX_SOCKET_RPC
//
// Utility routine to open a unix domain socket and bind it to the given
// socket name.
//
// XXX: It would be more elegant to add unix domain support to the
// _Tt_stream_socket class rather than have these special routines for
// dealing with them.
//
static int
s_open_unix_socket(char *socket_name)
{
/* open a unix socket */
int sock;
struct sockaddr_un server_addr;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
_tt_syslog(0, LOG_ERR, "s_open_unix_socket(): socket(): %m");
return(-1);
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
(void)unlink(socket_name);
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 (bind(sock, (struct sockaddr *)&server_addr,servlen) < 0) {
#else
if (bind(sock, (struct sockaddr *)&server_addr,
sizeof(struct sockaddr_un)) < 0) {
#endif
return(-1);
}
if (listen(sock, 5) != 0) {
return(-1);
}
return(sock);
}
//
// Called in response to a client request for a new rpc connection. We
// accept the connection on the unix socket and then use the standard
// _Tt_rpc_server object, which acts accordingly if given an open file
// descriptor in its constructor (see that method for more details) to
// open the rpc connection.
//
void _Tt_s_session::
u_rpc_init()
{
int msgsock;
_Tt_rpc_server_ptr server_object;
// connection request came in for the unix socket
msgsock = accept(_u_sock, (struct sockaddr *)0, 0);
if (msgsock == -1) {
return;
}
server_object = new _Tt_rpc_server(_rpc_program,
TT_RPC_VERSION,
msgsock,
_auth);
if (! server_object->init(_tt_service_rpc)) {
_tt_syslog(0, LOG_ERR, "u_rpc_init: server_object->init(): 0");
}
}
#endif // OPT_UNIX_SOCKET_RPC
//
// This is the server-side init routine for the _Tt_session object. The
// basic duties for this method are to advertise the server address
// accordingly after initializing the rpc server object. If we are in a
// desktop session then we first check for a session already running and
// return an error code if we find one.
//
// Returns:
// TT_OK
// TT_ERR_SESSION Found a live session (diagnostic has been emitted)
// TT_ERR_NOMP Could not initialize (diagnostic has been emitted)
//
Tt_status _Tt_s_session::
s_init()
{
_Tt_session rsession;
Tt_status status;
_Tt_string h;
_Tt_desktop_lock_ptr dt_lock;
// this is the server session for this session
_is_server = 1;
if (env() == _TT_ENV_X11) {
if (_displayname.len() == 0) {
_displayname = _tt_global->xdisplayname;
}
_desktop = new _Tt_desktop();
if (! _desktop->init(_displayname, _TT_DESKTOP_X11)) {
return(TT_ERR_NOMP);
}
_desktop->set_error_handler((_Tt_dt_errfn)_tt_xio_handler);
// set this field in the _Tt_s_mp object which will
// then be used to add the fd for the desktop
// connection to the list of fds that get polled.
_tt_s_mp->xfd = _desktop->notify_fd();
//
// Grab the X server. The grab is in effect until
// dt_lock goes out of scope (i.e., when we return).
// For proper test-and-set, the grab needs to start
// before check_for_live_session() and end after
// advertise_address().
//
dt_lock = new _Tt_desktop_lock( _desktop );
// check for a session already running
switch (status = check_for_live_session()) {
case TT_OK:
case TT_ERR_NOMP:
// Muscle in on dead ttsessions
status = TT_OK;
break;
case TT_ERR_SESSION:
return TT_ERR_SESSION;
default:
_tt_syslog(0, LOG_ERR,
"_Tt_s_session::check_for_live_session(): %s",
_tt_enumname(status));
return TT_ERR_INTERNAL;
}
}
_pid = getpid();
_server_uid = getuid();
_queued_messages = new _Tt_message_list();
_properties = new _Tt_session_prop_list;
// Create an RPC server managing object which will
// invoke the appropiate dispatch function on any RPC
// requests. This object also allocates an RPC program
// number which is then used to compose the session id to
// be advertised to potential clients.
_rpc_server = new _Tt_rpc_server(-1,
TT_RPC_VERSION,
RPC_ANYSOCK,
_auth);
if (! _rpc_server->init(_tt_service_rpc)) {
return(TT_ERR_NOMP);
}
_rpc_program = _rpc_server->program();
_rpc_version = _rpc_server->version();
// initializes our local host object which allows us to
// inquire our host address so we can then advertise it to
// clients.
if (! _tt_global->get_local_host(_host)) {
_tt_syslog(0, LOG_ERR,"get_local_host(): 0");
return(TT_ERR_NOMP);
}
if (parsed_address(_address_string) != TT_OK) {
_tt_syslog(0, LOG_ERR,"parsed_address() != TT_OK");
return(TT_ERR_NOMP);
}
if (_TT_AUTH_ICEAUTH == _auth.auth_level() &&
(status = _auth.generate_auth_cookie()) != TT_OK) {
return status;
}
if ((status = set_id()) == TT_OK) {
// advertise our address according to the type of
// session environment that we are in.
if ((status = advertise_address()) == TT_OK) {
#ifdef OPT_UNIX_SOCKET_RPC
// open a unix domain socket for connection
// requests and set the unix_fd field in the
// _Tt_s_mp object to it so it can be added to
// the list of file descriptors polled.
_u_sock = s_open_unix_socket(local_socket_name());
_tt_s_mp->unix_fd = _u_sock;
#endif // OPT_UNIX_SOCKET_RPC
return(TT_OK);
} else {
return(status);
}
} else {
return(status);
}
}
//
// Used to check whether there is already a live session. Only desktop
// sessions need this check since process-tree sessions are always unique
// since they are based on the process hierarchy.
//
// XXX: If the range of environments were to be extended to more than
// just desktop and process-tree sessions we would need more abstract
// methods for session environments that return whether this check is
// necessary.
//
// Returns:
// TT_OK Found no session
// TT_ERR_SESSION Found a live session (diagnostic emitted)
// TT_ERR_NOMP Found a dead session (diagnostic emitted)
//
Tt_status _Tt_s_session::
check_for_live_session()
{
_Tt_session rsession;
Tt_status status;
if (env() != _TT_ENV_X11) {
return(TT_OK);
}
// try to find the address of an advertised session
if (find_advertised_address(rsession._address_string) == TT_OK) {
// found another server id, check to see that it's
// running.
rsession._desktop = _desktop;
rsession._displayname = _displayname;
status = rsession.client_session_init();
switch (status) {
Tt_status ping_status;
case TT_OK:
switch (ping_status = rsession.ping()) {
case TT_OK:
case TT_ERR_INVALID:
case TT_ERR_NO_MATCH:
case TT_ERR_UNIMP:
_tt_syslog(stderr, LOG_ERR,
catgets(_ttcatd, 2, 6,
"Found another session run"
"ning (host=%s, pid=%d)"),
(char *)(rsession.host()->name()),
rsession._pid);
return(TT_ERR_SESSION);
default:
_tt_syslog(0, LOG_ERR,
"_Tt_session::ping(): %s",
_tt_enumname(ping_status));
return TT_ERR_INTERNAL;
case TT_ERR_NOMP:
break; // and fall through
}
// Fall through
case TT_ERR_NOMP:
{const char *hostname = "";
if (! rsession.host().is_null()) {
hostname = rsession.host()->name();
}
_tt_syslog(stderr, LOG_ERR,
catgets(_ttcatd, 2, 7,
"Can't contact alleged session "
"(host=%s, pid=%d); "
"assuming it crashed..."),
hostname, rsession._pid);
return(TT_ERR_NOMP);}
case TT_ERR_INVALID:
_tt_syslog(stderr, LOG_ERR,
catgets(_ttcatd, 2, 8,
"Can't parse advertised session id;"
" overwriting it with my own..."));
return(TT_ERR_NOMP);
case TT_WRN_NOTFOUND:
case TT_ERR_ACCESS:
case TT_ERR_NO_MATCH:
return(TT_OK);
default:
_tt_syslog(0, LOG_ERR,
"_Tt_session::client_session_init(): %s",
_tt_enumname(status));
return(TT_ERR_INTERNAL);
}
}
return(TT_OK);
}
#if defined(ultrix)
/* strdup - make duplicate of string s */
#include <string.h>
#include <malloc.h>
static char *
strdup(char *s)
{
char *p;
p = (char *)malloc(strlen(s) + 1); /* + 1 for '\0' character */
if (p != NULL)
strcpy(p,s);
return p;
}
#endif
//
// Advertises a session procid so that any clients that come up within
// the appropiate domain will find the session id.
//
Tt_status _Tt_s_session::
advertise_address()
{
_Tt_string s;
_Tt_string prop(TT_XATOM_NAME);
_Tt_string cde_prop(TT_CDE_XATOM_NAME);
_Tt_string xdisp("DISPLAY");
switch(env()) {
case _TT_ENV_X11:
// advertise our address by setting a special property
// on our desktop session.
if (_desktop->set_prop(cde_prop, _address_string) &&
_desktop->set_prop(prop, _address_string)) {
s = xdisp.cat("=").cat(_displayname);
(void)putenv(strdup((char *)s));
return(TT_OK);
}
return(TT_ERR_INTERNAL);
case _TT_ENV_PROCESS_TREE:
// advertise our address by exporting a special
// environment variable.
if (_tt_put_all_env_var (2, _address_string, (char*)cde_prop, (char*)prop) != 2) {
return(TT_ERR_INTERNAL);
}
return(TT_OK);
case _TT_ENV_LAST:
default:
return(TT_ERR_INTERNAL);
}
}
//
// This function is called to notify the session object that a new
// pattern has been registered by some procid. This means that for any
// queued messages, there may now be a procid that is suitable to receive
// the message so this function iterates through all the queued messages
// attempting to deliver the message.
//
// XXX: For efficiency, this method might take an argument which is the
// new pattern and then delivery of the queued messages could be
// restricted to just matching against the new pattern.
//
void _Tt_s_session::
pattern_added()
{
_Tt_message_list_cursor qmsgs;
_Tt_s_message *sm;
/* try to deliver session queued msgs */
qmsgs.reset(_queued_messages);
while (qmsgs.next()) {
sm = (_Tt_s_message *)(*qmsgs).c_pointer();
// set state to "sent"
sm->set_state(TT_SENT);
_Tt_msg_trace trace( **qmsgs, TTDR_SESSION_JOIN );
if (sm->deliver( trace )) {
qmsgs.remove();
} else {
// couldn't successfully deliver so revert
// state to queued.
sm->set_state(TT_QUEUED);
}
}
}
//
// The given procid wishes to join this session. We iterate through the
// procid's patterns and add our session id to them. We also invoke the
// pattern_added method since we may have an opportunity to deliver more
// queued messages.
//
Tt_status _Tt_s_session::
s_join(_Tt_s_procid_ptr &procid)
{
// update session-scoped handler patterns with session id
mod_session_id_in_patterns(procid->patterns(), 1);
procid->set_active(1);
if (procid->is_active()) {
// we've altered the patterns registered so we call
// pattern_added() to attempt delivery of any
// queued messages.
pattern_added();
}
return(TT_OK);
}
//
// For each pattern in patterns that is session-scoped, this method will
// add or delete (depending on add parameter) this session's id to the
// session list for the pattern.
//
void _Tt_s_session::
mod_session_id_in_patterns(_Tt_pattern_list_ptr &patterns, int add)
{
_Tt_pattern_list_cursor pcursor;
int scopes;
pcursor.reset(patterns);
while (pcursor.next()) {
scopes = pcursor->scopes();
if (scopes&(1<<TT_SESSION) ||
scopes&(1<<TT_FILE_IN_SESSION) ||
scopes&(1<<TT_BOTH)) {
if (add) {
pcursor->add_session(address_string());
// set special pattern flag to
// optimize session-scoped pattern
// matching.
pcursor->set_in_session();
} else {
pcursor->del_session(address_string());
// clear special pattern flag to
// optimize session-scoped pattern
// matching.
pcursor->clr_in_session();
}
}
}
}
//
// The given procid wishes to quit this session. We remove our session id
// from the procid's patterns.
//
Tt_status _Tt_s_session::
s_quit(_Tt_s_procid_ptr &procid)
{
// delete session from handler patterns
mod_session_id_in_patterns(procid->patterns(), 0);
return(TT_OK);
}
//
// Adds a message to the queue of session-queued messages.
//
void _Tt_s_session::
queue_message(_Tt_message_ptr &m)
{
if (! m->handler_ptype().len()) {
// can't queue a message with no handler ptype
return;
}
_Tt_message_list_cursor qm;
Tt_state qm_state;
_Tt_string qm_ptype;
// verify that only one message with m's id and handler_ptype
// exists in the queue (in the same state as m)
qm.reset(_queued_messages);
while (qm.next()) {
if (qm->is_equal(m)) {
qm_state = qm->state();
if (qm_state == m->state()) {
qm_ptype = qm->handler_ptype();
if (qm_ptype == m->handler_ptype()){
return;
}
}
}
}
_queued_messages->append(m);
}
_Tt_message_list_ptr & _Tt_s_session::
queued_messages()
{
return(_queued_messages);
}

View File

@@ -0,0 +1,53 @@
/*%% (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_s_session.h /main/3 1995/10/23 11:59:47 rswiston $ */
/*
* mp_s_session.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* This file contains the implementation of the server side of
* the _Tt_session object.
*/
#ifndef MP_S_SESSION_H
#define MP_S_SESSION_H
#include "mp/mp_session.h"
#include "mp_s_session_utils.h"
#include "mp_s_procid_utils.h"
#include "mp_rpc_server_utils.h"
class _Tt_s_session : public _Tt_session {
public:
_Tt_s_session();
virtual ~_Tt_s_session();
Tt_status s_addprop(_Tt_string prop, _Tt_string val);
Tt_status s_getprop(_Tt_string prop, int i,
_Tt_string &value);
Tt_status s_init();
Tt_status s_join(_Tt_s_procid_ptr &procid);
Tt_status s_propcount(_Tt_string prop, int &cnt);
Tt_status s_propname(int i, _Tt_string &prop);
Tt_status s_propnames_count(int &cnt);
Tt_status s_quit(_Tt_s_procid_ptr &procid);
Tt_status s_setprop(_Tt_string prop, _Tt_string val);
void queue_message(_Tt_message_ptr &m);
void pattern_added();
Tt_status check_for_live_session();
private:
Tt_status advertise_address();
void mod_session_id_in_patterns(_Tt_pattern_list_ptr
&patterns,
int add);
void u_rpc_init();
_Tt_message_list_ptr &queued_messages();
_Tt_rpc_server_ptr _rpc_server;
friend class _Tt_s_mp;
};
#endif /* MP_S_SESSION_H */

View File

@@ -0,0 +1,125 @@
//%% (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_s_session_prop.C /main/3 1995/10/23 12:00:00 rswiston $
/*
*
* mp_s_session_prop.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp/mp_global.h"
#include "mp_s_mp.h"
#include "mp/mp_mp.h"
#include "mp_rpc_server.h"
#include "mp_rpc_implement.h"
#include "mp_s_session.h"
#include "mp/mp_session_prop.h"
#include "mp/mp_xdr_functions.h"
Tt_status _Tt_s_session::
s_setprop(_Tt_string prop, _Tt_string val)
{
_Tt_session_prop_list_cursor propc(_properties);
_Tt_string_list_cursor valp;
while (propc.next()) {
if (propc->_name == prop) {
// found the property
valp.reset(propc->_values);
// remove all of the existing values
while (valp.next()) {
valp.remove();
}
// append the new value
propc->_values->append(val);
break;
}
}
if (!propc.is_valid()) {
// we didn't find the property, so add it
_properties->append(_Tt_session_prop_ptr
(new _Tt_session_prop(prop, val)));
}
return TT_OK;
}
Tt_status _Tt_s_session::
s_addprop(_Tt_string prop, _Tt_string val)
{
_Tt_session_prop_list_cursor propc(_properties);
while (propc.next()) {
if (propc->_name == prop) {
// found the property
// append the new value
propc->_values->append(val);
break;
}
}
if (!propc.is_valid()) {
// we didn't find the property, so add it
_properties->append(_Tt_session_prop_ptr
(new _Tt_session_prop(prop, val)));
}
return TT_OK;
}
Tt_status _Tt_s_session::
s_getprop(_Tt_string prop, int i, _Tt_string &value)
{
_Tt_session_prop_list_cursor propc(_properties);
while (propc.next()) {
if (propc->_name == prop) {
// found the property
if (i >= propc->_values->count()) {
return TT_ERR_NUM;
} else {
value = (*propc->_values)[i];
}
break;
}
}
if (!propc.is_valid()) {
// we didn't find the property
return TT_ERR_PROPNAME;
} else {
return TT_OK;
}
}
Tt_status _Tt_s_session::
s_propcount(_Tt_string prop, int &cnt)
{
_Tt_session_prop_list_cursor propc(_properties);
while (propc.next()) {
if (propc->_name == prop) {
// found the property
cnt = propc->_values->count();
return TT_OK;
}
}
// we didn't find the property
return TT_ERR_PROPNAME;
}
Tt_status _Tt_s_session::
s_propname(int i, _Tt_string &prop)
{
if (i >= _properties->count()) {
return TT_ERR_NUM;
}
prop = (*_properties)[i]->_name;
return TT_OK;
}
Tt_status _Tt_s_session::
s_propnames_count(int &cnt)
{
cnt = _properties->count();
return TT_OK;
}

View 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_s_session_utils.C /main/3 1995/10/23 12:00:11 rswiston $
/*
*
* mp_s_session_utils.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* Declaration of auxilliary data structures for the _Tt_s_session class
*/
#include "mp_s_session.h"
implement_ptr_to(_Tt_s_session)

View 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_s_session_utils.h /main/3 1995/10/23 12:00:22 rswiston $ */
/*
*
* mp_s_session_utils.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* Declaration of auxilliary data structures for the _Tt_s_session class
*/
#ifndef MP_S_SESSION_UTILS_H
#define MP_S_SESSION_UTILS_H
#include "mp/mp_session_utils.h"
class _Tt_s_session;
declare_derived_ptr_to(_Tt_s_session,_Tt_session)
#endif /* MP_S_SESSION_UTILS_H */

View File

@@ -0,0 +1,44 @@
//%% (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_s_xdr_functions.C /main/3 1995/10/23 12:00:33 rswiston $
/*
*
* mp_s_xdr_functions.cc
*
* Server-side only xdr functions.
*
* In order that the server has _s_ versions of the routines,
* we use slightly different xdr routines for decoding! This
* is a violation of XDR dogma \(but not really, since the XDR ing
* is only done in the parent _Tt_xxx class; the only difference
* is the constructor that gets called.\)
*
* Copyright (c) 1992 by Sun Microsystems, Inc.
*/
#include "mp_s_xdr_functions.h"
bool_t
tt_s_xdr_add_pattern_args(XDR *xdrs,_Tt_s_add_pattern_args *args)
{
return(args->procid.xdr(xdrs) && args->pattern.xdr(xdrs));
}
bool_t
tt_s_xdr_del_pattern_args(XDR *xdrs,_Tt_s_del_pattern_args *args)
{
return(args->procid.xdr(xdrs) && args->pattern_id.xdr(xdrs));
}
bool_t
tt_s_xdr_update_args(XDR *xdrs, _Tt_s_update_args *args)
{
return( xdr_int(xdrs, (int *)&args->newstate) &&
args->message.xdr(xdrs));
}

View 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_s_xdr_functions.h /main/3 1995/10/23 12:00:44 rswiston $ */
/*
*
* mp_s_xdr_functions.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* This file implements the wrappers needed for calling
* RPC argument XDR routines on the server side.
*/
#ifndef MP_S_XDR_FUNCTIONS_H
#define MP_S_XDR_FUNCTIONS_H
#include <rpc/rpc.h>
#include "api/c/tt_c.h"
#include "mp_s_message_utils.h"
#include "mp_s_pattern_utils.h"
#include "mp_s_procid_utils.h"
struct _Tt_s_add_pattern_args: public _Tt_allocated {
_Tt_s_procid_ptr procid;
_Tt_s_pattern_ptr pattern;
};
struct _Tt_s_del_pattern_args: public _Tt_allocated {
_Tt_s_procid_ptr procid;
_Tt_string pattern_id;
};
struct _Tt_s_update_args: public _Tt_allocated {
_Tt_s_message_ptr message;
Tt_state newstate;
};
bool_t tt_s_xdr_add_pattern_args(XDR *xdrs,
_Tt_s_add_pattern_args *args);
bool_t tt_s_xdr_del_pattern_args(XDR *xdrs,
_Tt_s_del_pattern_args *args);
bool_t tt_s_xdr_update_args(XDR *xdrs,
_Tt_s_update_args *args);
#endif /* MP_XDR_FUNCTIONS_H */

View File

@@ -0,0 +1,229 @@
//%% (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_self_procid.C /main/3 1995/10/23 12:00:55 rswiston $
/*
* @(#)mp_self_procid.cc 1.3 93/07/25
*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
*/
#include <unistd.h>
#include <errno.h>
#include "mp_self_procid.h"
#include "mp_s_mp.h"
#include "mp/mp_session.h"
#include "mp/mp_message.h"
#include "mp/mp_arg.h"
#include "mp_s_pattern.h"
#include "util/tt_global_env.h"
#include "util/tt_host.h"
#include "util/tt_port.h"
#include "util/tt_trace.h"
_Tt_self_procid::_Tt_self_procid()
{
}
_Tt_self_procid::~_Tt_self_procid()
{
}
Tt_status
_Tt_self_procid::init()
{
_id = _tt_s_mp->alloc_procid_key();
_id = _id.cat(" ").cat(_tt_s_mp->initial_session->address_string());
_pid = getpid();
// XXX Probably could just set _version and return at this point
// _Tt_s_procid::init() expects _proc_host_ipaddr to be initialized
if (! _tt_global->get_local_host(_proc_host)) {
return(TT_ERR_NOMP);
}
_proc_host_ipaddr = _proc_host->addr();
return _Tt_s_procid::init();
}
//
// We just go ahead and process the messages when we signal ourself
// that we have new messages.
//
Tt_status
_Tt_self_procid::signal_new_message()
{
// XXX do we need to muck with _TT_PROC_SIGNALLED? I think not.
_Tt_next_message_args args;
Tt_status status = next_message( args );
_Tt_message_list_cursor msgC( args.msgs );
while (status == TT_OK) {
//
// In theory, we should at this point do the things
// that _Tt_c_procid::next_message() and tt_message_receive()
// do: check the queue for file-scoped messages,
// and run pattern callbacks. But ttsession declares
// no ptypes, and we lack the client-side machinery
// for callbacks. So we use our own.
//
msgC.reset();
while (msgC.next()) {
_process_msg( *msgC );
}
status = next_message( args );
}
if (status == TT_WRN_NOTFOUND) {
return TT_OK;
}
return status;
}
Tt_callback_action
_Tt_self_procid::handle_Session_Trace(
const _Tt_message_ptr &msg,
void *proc
)
{
return ((_Tt_self_procid *)proc)->_handle_Session_Trace( msg );
}
Tt_callback_action
_Tt_self_procid::observe_Saved(
const _Tt_message_ptr &msg,
void *proc
)
{
return ((_Tt_self_procid *)proc)->_observe_Saved( msg );
}
_Tt_s_pattern *
_Tt_self_procid::s_pattern_create()
{
_Tt_s_pattern *pat = new _Tt_s_pattern();
pat->set_id(_tt_s_mp->initial_session->address_string());
return pat;
}
//
// This is a very simple callback server-side pattern callback scheme.
// It does not do everything that client-side callbacks do.
//
Tt_status
_Tt_self_procid::_process_msg(
const _Tt_message_ptr &msg
)
{
_Tt_string pat_id = msg->pattern_id();
if (pat_id.len() == 0) {
return TT_OK;
}
_Tt_pattern_list_cursor patC( _patterns );
while (patC.next()) {
if (patC->id() == pat_id) {
if (patC->server_callback != 0) {
if ( (*(patC->server_callback))( msg, this )
== TT_CALLBACK_PROCESSED)
{
break;
}
}
}
}
return TT_OK;
}
Tt_status
_Tt_self_procid::_reply(
const _Tt_message_ptr &msg
)
{
return update_message( msg, TT_HANDLED );
}
Tt_status
_Tt_self_procid::_fail(
const _Tt_message_ptr &msg,
int return_status
)
{
Tt_status status = msg->set_status( return_status );
if (status != TT_OK) {
return status;
}
return update_message( msg, TT_FAILED );
}
Tt_status
_Tt_self_procid::update_message(
const _Tt_message_ptr &msg,
Tt_state new_state
)
{
//
// This is the sort of checking done by
// _Tt_c_procid::update_message().
//
if (msg->message_class() != TT_REQUEST) {
return TT_ERR_CLASS;
}
if (msg->handler().is_null()) {
return TT_ERR_NOTHANDLER;
}
_Tt_procid_ptr me = (_Tt_procid *)this;
if (! me->is_equal( msg->handler() )) {
return TT_ERR_NOTHANDLER;
}
switch (msg->state()) {
case TT_FAILED:
case TT_HANDLED:
return(TT_ERR_INVALID);
default:
break;
}
return _Tt_s_procid::update_message( msg, new_state );
}
Tt_callback_action
_Tt_self_procid::_handle_Session_Trace(
const _Tt_message_ptr &msg
)
{
_Tt_arg_list_ptr args = new _Tt_arg_list( *msg->args() );
_Tt_arg_list_cursor argC( args );
if (! argC.next()) {
_fail( msg, TT_DESKTOP_EPROTO );
return TT_CALLBACK_PROCESSED;
}
_Tt_string script;
Tt_status status = (*argC)->data_string( script );
if (status != TT_OK) {
_fail( msg, (int)status );
return TT_CALLBACK_PROCESSED;
}
if ((script.len() == 0) && (msg->file().len() > 0)) {
script = _tt_network_path_to_local_path(msg->file());
}
if (argC.next()) {
_fail( msg, TT_DESKTOP_ENOTSUP );
return TT_CALLBACK_PROCESSED;
}
if (_tt_putenv( TRACE_SCRIPT, script ) == 0) {
_fail( msg, TT_DESKTOP_ENOMEM );
return TT_CALLBACK_PROCESSED;
}
tt_trace_control( 0 );
tt_trace_control( 1 );
_reply( msg );
return TT_CALLBACK_PROCESSED;
}
Tt_callback_action
_Tt_self_procid::_observe_Saved(
const _Tt_message_ptr &
)
{
if (kill( getpid(), SIGTYPES ) < 0) {
_tt_syslog(0, LOG_ERR, "kill(): %m");
}
return TT_CALLBACK_PROCESSED;
}

View File

@@ -0,0 +1,67 @@
/*%% (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_self_procid.h /main/3 1995/10/23 12:01:07 rswiston $ */
/* -*-C++-*-
*
* @(#)mp_self_procid.h 1.1 93/07/09
*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
*/
#ifndef _MP_SELF_PROCID_H
#define _MP_SELF_PROCID_H
#include "mp_s_procid.h"
#include "mp_s_pattern_utils.h"
class _Tt_self_procid : public _Tt_s_procid {
public:
_Tt_self_procid();
virtual ~_Tt_self_procid();
virtual Tt_status init();
virtual Tt_status signal_new_message();
static Tt_callback_action handle_Session_Trace(
const _Tt_message_ptr &msg,
void *self_proc
);
static Tt_callback_action observe_Saved(
const _Tt_message_ptr &msg,
void *self_proc
);
//
// Server-side equivalent of tt_pattern_create()
//
static _Tt_s_pattern *s_pattern_create();
private:
Tt_status _process_msg(
const _Tt_message_ptr &msg
);
//
// Server-side equivalent of tt_message_reply(), tt_message_fail()
//
Tt_status _reply(
const _Tt_message_ptr &msg
);
Tt_status _fail(
const _Tt_message_ptr &msg,
int status
);
virtual Tt_status update_message(
const _Tt_message_ptr &msg,
Tt_state new_state
);
//
// Custom callbacks for doing things ttsession likes to do
//
Tt_callback_action _handle_Session_Trace(
const _Tt_message_ptr &msg
);
Tt_callback_action _observe_Saved(
const _Tt_message_ptr &msg
);
};
#endif /* _MP_SELF_PROCID_H */

View File

@@ -0,0 +1,749 @@
//%% (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_signature.C /main/4 1998/03/20 14:28:50 mgreess $
/*
* Tool Talk Message Passer (MP) - mp_signature.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* Implementation of the _Tt_signature class representing a signature
* of a method or
* a procedure.
*/
#include <stdlib.h>
#if defined(linux)
# include <g++/minmax.h>
#else
# include <macros.h>
#endif
#include "util/tt_global_env.h"
#include "mp/mp_global.h"
#include "mp/mp_arg.h"
#include "mp/mp_mp.h"
#include "mp_s_mp.h"
#include "mp_signature.h"
#include "mp_ce_attrs.h"
#include "mp/mp_context.h"
#include "util/tt_enumname.h"
#include "util/tt_trace.h"
#include "util/tt_string.h"
/*
* Signatures are used in both otype and ptype descriptions. They are
* composed of a matching component together with a field-setting
* component. The matching component, which is the scope, class, op, and
* args, is matched against a message whereas the field-setting
* component, which is the opnum, ptype, and reliability settings, sets
* fields in the message.
*/
_Tt_signature::
_Tt_signature()
{
_scope = TT_BOTH;
_args = new _Tt_arg_list();
_contexts = new _Tt_context_list;
_message_class = TT_CLASS_UNDEFINED;
_pattern_category = TT_CATEGORY_UNDEFINED;
_reliability = TT_DISCARD;
_opnum = -1;
_op = 0;
_ptid = 0;
_otid = 0;
_super_otid = 0;
_mangled_args = 0;
ce_entry = 0;
_timestamp = 0;
}
_Tt_signature::
_Tt_signature(_Tt_signature_ptr sig)
{
_scope = sig->_scope;
_args = sig->_args;
_mangled_args = sig->_mangled_args;
_message_class = sig->_message_class;
_pattern_category = sig->_pattern_category;
_op = sig->_op;
_reliability = sig->_reliability;
_opnum = sig->_opnum;
_ptid = sig->_ptid;
_otid = sig->_otid;
_super_otid = sig->_super_otid;
_timestamp = sig->_timestamp;
}
bool_t _Tt_signature::
xdr(XDR *xdrs)
{
if (! xdr_int(xdrs, (int *)&_scope)) {
return(0);
}
if (! _args.xdr(xdrs)) {
return(0);
}
if (! xdr_int(xdrs, (int *)&_message_class)) {
return(0);
}
if (! xdr_int(xdrs, (int *)&_pattern_category)) {
return(0);
}
if (! _op.xdr(xdrs)) {
return(0);
}
if (! xdr_int(xdrs, (int *)&_reliability)) {
return(0);
}
if (! xdr_int(xdrs, &_opnum)) {
return(0);
}
if (! _ptid.xdr(xdrs)) {
return(0);
}
if (! _otid.xdr(xdrs)) {
return(0);
}
if (! _super_otid.xdr(xdrs)) {
return(0);
}
if (_tt_global->xdr_version() >= TT_CONTEXTS_XDR_VERSION) {
if (! _contexts.xdr(xdrs)) {
return 0;
}
}
return(1);
}
_Tt_signature::
~_Tt_signature()
{
}
Tt_scope _Tt_signature::
scope() const
{
return(_scope);
}
const _Tt_arg_list_ptr & _Tt_signature::
args() const
{
return(_args);
}
const _Tt_context_list_ptr & _Tt_signature::
contexts() const
{
return(_contexts);
}
Tt_class _Tt_signature::
message_class() const
{
return(_message_class);
}
Tt_category _Tt_signature::
category() const
{
return(_pattern_category);
}
const _Tt_string & _Tt_signature::
op() const
{
return(_op);
}
int _Tt_signature::
opnum() const
{
return(_opnum);
}
Tt_disposition _Tt_signature::
reliability() const
{
return(_reliability);
}
const _Tt_string & _Tt_signature::
ptid() const
{
return(_ptid);
}
const _Tt_string &_Tt_signature::
otid() const
{
return(_otid);
}
_Tt_string _Tt_signature::
super_otid()
{
return(_super_otid);
}
void _Tt_signature::
set_scope(Tt_scope s)
{
_scope = s;
}
void _Tt_signature::
set_message_class(Tt_class mclass)
{
_message_class = mclass;
}
void _Tt_signature::
set_op(_Tt_string op)
{
_op = op;
}
void _Tt_signature::
set_opnum(int num)
{
_opnum = num;
}
void _Tt_signature::
set_pattern_category(Tt_category k)
{
_pattern_category = k;
}
void _Tt_signature::
set_ptid(_Tt_string ptid)
{
_ptid = ptid;
}
void _Tt_signature::
set_otid(_Tt_string otid)
{
_otid = otid;
}
void _Tt_signature::
set_super_otid(_Tt_string super_otid)
{
_super_otid = super_otid;
}
void _Tt_signature::
set_reliability(Tt_disposition r)
{
_reliability = (Tt_disposition)(_reliability | r);
}
void _Tt_signature::
append_arg(_Tt_arg_ptr &arg)
{
_Tt_arg_list_ptr argc;
_args->append(arg);
if (_mangled_args.len() == 0) {
_mangled_args = "_";
}
_mangled_args = _mangled_args.cat(_tt_enumname(arg->mode())).cat(arg->type()).cat("_");
}
void _Tt_signature::
append_context(_Tt_context_ptr &context)
{
_contexts->append_ordered(context);
}
/*
* Matches a signature against a scope, class, op, arglist, and
* contexts. If the match succeeds then the caller determines which
* fields in the signature to use.
*
* trace can be 0 if we are being called merely to do types
* administration instead of message dispatching.
*/
int _Tt_signature::
match(Tt_scope theScope, Tt_class theClass, const _Tt_string &op,
const _Tt_arg_list_ptr &args, const _Tt_string &otype,
const _Tt_context_list_ptr &contexts, const _Tt_msg_trace *trace,
int &was_exact) const
{
int score = 0;
Tt_class mclass;
was_exact = 0;
if (trace != 0) {
*trace << "Tt_message & ";
trace->incr_indent();
if (_otid.len()) {
*trace << "otype " << _otid;
} else {
*trace << "ptype " << _ptid;
}
*trace << " {\n";
switch (_pattern_category) {
case TT_HANDLE_PUSH:
*trace << "handle_push";
break;
case TT_HANDLE_ROTATE:
*trace << "handle_rotate";
break;
case TT_HANDLE:
*trace << "handle";
break;
case TT_OBSERVE:
*trace << "observe";
break;
}
*trace << ": ";
trace->print( _Tt_signature::pretty_print_, this );
trace->decr_indent();
*trace << "} ";
}
_Tt_string reason;
if (_otid.len() > 0 && otype != _otid) {
reason = "otype";
} else if (_otid.len() == 0 && (scope() != theScope)) {
reason = "Tt_scope";
} else if (mclass = message_class(),
mclass != TT_CLASS_UNDEFINED && mclass != theClass) {
reason = "Tt_class";
} else {
score = match(op, args, contexts, reason, was_exact);
}
if (trace != 0) {
*trace << "== " << score << ";";
if (score <= 0) {
*trace << " /* " << reason << "*/";
}
*trace << "\n";
}
return score;
}
int _Tt_signature::
match(
const _Tt_string &op,
const _Tt_arg_list_ptr &args,
const _Tt_context_list_ptr &contexts,
_Tt_string &reason,
int &was_exact
) const
{
was_exact = 0;
if (_op != op) {
reason = "op";
return 0;
}
/* according to the spec if there are no arguments in */
/* the signature then args should be ignored in the */
/* match. (see p.22) */
if (_args->count() == 0) {
if (args.is_null() || (args->count() == 0)) {
was_exact = 1;
}
return 1;
}
/* for each arg in args match arg_kind and type */
/* against corresponding arg in signature. */
if (! args.is_null() && args->count() != _args->count()) {
reason = "args";
return 0;
}
_Tt_arg_list_cursor margc(args);
_Tt_arg_list_cursor argc(_args);
int score = 1;
was_exact = 1;
while (argc.next() && margc.next()) {
int used_wildcard;
int points = argc->match_score( **margc, used_wildcard );
if (used_wildcard) {
was_exact = 0;
}
if (points <= 0) {
reason = "args";
return 0;
}
score += points;
}
if (_contexts->count() == 0) {
return score;
}
/* for each context in contexts match slotname against */
/* corresponding arg in signature. */
_Tt_context_list_cursor mc(contexts);
_Tt_context_list_cursor sc(_contexts);
mc.next();
sc.next();
while (mc.is_valid() && sc.is_valid()) {
int cmpres = mc->slotName().cmp(sc->slotName());
if (cmpres<0) { // target less than signature
// The target has a context slot which is not in
// the signature. If we are matching a message
// for possible delivery, this still could be a
// match, but if we are matching another signature
// for replacement in a tt_type_comp merge,
// we should only replace exact matches.
// Continue on to look for other mismatches,
// but return partial mismatch to caller so it can
// determine what to do.
was_exact = 0;
mc.next();
} else if (cmpres==0) { // target same as signature
// Context in target matches context in sig.
mc.next();
sc.next();
} else { // target greater than signature
// The signature has a context slot which is not
// in the target. This match fails.
was_exact = 0;
reason = "contexts";
return 0;
}
}
if (mc.is_valid() && !sc.is_valid()) {
// Unconsumed context slots in target.
was_exact = 0;
} else if (!mc.is_valid() && sc.is_valid()) {
// Unsatisfied context slots in signature
was_exact = 0;
reason = "contexts";
return 0;
} // else both are invalid, or both are valid. result stands..
return score;
}
int _Tt_signature::
operator==(const _Tt_signature &sig) const
{
if (_otid != sig.otid()) {
return 0;
}
if (category() != sig.category()) {
return 0;
}
int was_exact;
if (0 >= match(sig.scope(), sig.message_class(), sig.op(),
sig.args(), sig.otid(), sig.contexts(), 0, was_exact))
{
return 0;
}
return was_exact;
}
//
// True if the two _Tt_signatures overload the same op in the
// same way (i.e. with the same arguments and contexts)
//
int _Tt_signature::
is_same_method(const _Tt_signature &sig) const
{
int was_exact;
_Tt_string r;
if (match(sig.op(), sig.args(), sig.contexts(), r, was_exact) <= 0) {
return 0;
}
if (! was_exact) {
return 0;
}
return 1;
}
int _Tt_signature::
is_ce_equal(_Tt_signature &sig)
{
_Tt_arg_list_cursor argc;
if (_op != sig._op) {
return(0);
}
if (_otid != sig._otid) {
return(0);
}
Tt_mode md;
if (_mangled_args.len() == 0) {
_mangled_args = "_";
argc.reset(_args);
while (argc.next()) {
md = argc->mode();
_mangled_args = _mangled_args.cat(_tt_enumname(md)).cat(argc->type()).cat("_");
}
}
if (sig._mangled_args.len() == 0) {
sig._mangled_args = "_";
argc.reset(sig._args);
while (argc.next()) {
md = argc->mode();
sig._mangled_args = sig._mangled_args.cat(_tt_enumname(md)).cat(argc->type()).cat("_");
}
}
return(_mangled_args == sig._mangled_args);
}
void _Tt_signature::
print(const _Tt_ostream &os) const
{
_Tt_arg_list_cursor argc;
//
// XXX This is only used for Classing Engine, never for
// tracing, so we can be lazy and write directly to the
// FILE * of the _Tt_ostream.
//
FILE *fs = os.theFILE();
fprintf(fs,"(\n");
fprintf(fs,"\t\t(%s,%s,<",
_tt_ce_attr_string(_TYPE_NAME),
_tt_ce_attr_string(_TT_TOOLTALK_TYPE));
if (_otid.len()) {
_otid.print(fs);
} else {
_ptid.print(fs);
}
fputs("::", fs);
_op.print(fs);
if (0==_mangled_args.len()) {
fputc('_',fs);
} else {
_mangled_args.print(fs);
}
fputs(">)\n", fs);
fprintf(fs,"\t\t(%s,string,<%s>)\n",
_tt_ce_attr_string(_TT_TOOLTALK_TYPE),
_tt_ce_attr_string(_TT_TOOLTALK_SIGNATURE));
fprintf(fs,"\t\t(%s,string,<", _tt_ce_attr_string(_TT_OP));
_op.print(fs);
fputs(">)\n", fs);
fprintf(fs,"\t\t(%s,string,<%s>)\n",
_tt_ce_attr_string(_TT_CATEGORY),
_tt_enumname(_pattern_category));
argc.reset(_args);
int argn=0;
while (argc.next()) {
fprintf(fs,"\t\t(%s%d,string,<%s ",
_tt_ce_attr_string(_TT_ARG), argn,
_tt_enumname(argc->mode()));
argc->type().print(fs);
fputs(" ", fs);
argc->name().print(fs);
fputs(">)\n", fs);
argn++;
}
fprintf(fs,"\t\t(%s,string,<%s>)\n",
(_otid.len()) ? _tt_ce_attr_string(_TT_MSET_SCOPE) :
_tt_ce_attr_string(_TT_SCOPE),
_tt_enumname(_scope));
fprintf(fs,"\t\t(%s,string,<%s>)\n",
_tt_ce_attr_string(_TT_CLASS),
_tt_enumname(_message_class));
switch (_reliability) {
case TT_START+TT_QUEUE:
#ifdef NOT_BACKWARD_COMPATIBLE
fprintf(fs,"\t\t(%s,string,<TT_START+TT_QUEUE>)\n",
_tt_ce_attr_string(_TT_MSET_DISPOSITION));
#else
//
// Version 1.0 can't deal with start+queue, so we
// hide it in the typename, which version 1.0 doesn't
// check.
//
fprintf(fs,"\t\t(%s,string:TT_START+TT_QUEUE,<TT_START>)\n",
_tt_ce_attr_string(_TT_MSET_DISPOSITION));
#endif /*NOT_BACKWARD_COMPATIBLE*/
break;
case TT_QUEUE:
fprintf(fs,"\t\t(%s,string,<TT_QUEUE>)\n",
_tt_ce_attr_string(_TT_MSET_DISPOSITION));
break;
case TT_START:
fprintf(fs,"\t\t(%s,string,<TT_START>)\n",
_tt_ce_attr_string(_TT_MSET_DISPOSITION));
break;
case TT_DISCARD:
default:
fprintf(fs,"\t\t(%s,string,<TT_DISCARD>)\n",
_tt_ce_attr_string(_TT_MSET_DISPOSITION));
break;
}
fprintf(fs,"\t\t(%s,string,<%d>)\n",
_tt_ce_attr_string(_TT_MSET_OPNUM), _opnum);
fprintf(fs,"\t\t(%s,string,<",
_tt_ce_attr_string(_TT_MSET_HANDLER_PTYPE));
_ptid.print(fs);
fputs(">)\n", fs);
if (_otid.len()) {
fprintf(fs,"\t\t(%s,string,<",
_tt_ce_attr_string(_TT_MSET_OTYPE));
_otid.print(fs);
fputs(">)\n", fs);
}
fprintf(fs,"\t)");
}
void _Tt_signature::
pretty_print_(const _Tt_ostream &os, const _Tt_object *obj)
{
((const _Tt_signature *)obj)->pretty_print( os );
}
void _Tt_signature::
pretty_print(const _Tt_ostream &os) const
{
_Tt_arg_list_cursor argc;
int argn;
int is_osig = _otid.len() > 0;
if (! is_osig) {
switch (_scope) {
case TT_FILE: os << "file"; break;
case TT_SESSION: os << "session"; break;
case TT_FILE_IN_SESSION: os << "file_in_session";break;
}
}
os << " " << _op << "(";
argc.reset(_args);
argn = _args->count();
while (argc.next()) {
switch (argc->mode()) {
case TT_IN: os << "in"; break;
case TT_OUT: os << "out"; break;
case TT_INOUT: os << "inout"; break;
}
os << " " << argc->type() << " " << argc->name();
if (--argn) {
os << ", ";
}
}
os << ")";
if (_contexts->count() > 0) {
_Tt_context_list_cursor ctxts(_contexts);
os << " context(";
ctxts.next();
os << ctxts->slotName();
while(ctxts.next()) {
os << ", " << ctxts->slotName();
}
os << ")";
}
if (is_osig) {
os << " => " << _ptid << " ";
switch (_scope) {
case TT_FILE: os << "file"; break;
case TT_SESSION: os << "session"; break;
case TT_FILE_IN_SESSION: os << "file_in_session";break;
}
} else {
if ( (_reliability&TT_START) || (_reliability&TT_QUEUE)
|| (_opnum != -1))
{
// We are psig and have right hand side, so need =>
os << " =>";
}
}
if (_reliability & TT_START) {
os << " start";
}
if (_reliability & TT_QUEUE) {
os << " queue";
}
if (_opnum != -1) {
os << " opnum=" << _opnum;
}
if (is_osig && _super_otid.len()) {
os << " from " << _super_otid;
}
os << ";\n";
}
void _Tt_signature::
pretty_print_(const _Tt_ostream &os, const _Tt_signature_list_ptr &sigs,
Tt_category category, int skip_sigs_with_otid)
{
if (sigs.is_null()) {
return;
}
if (sigs->count()) {
int print_header = 1;
_Tt_signature_list_cursor sigC(sigs);
while (sigC.next()) {
if (sigC->otid().len() && skip_sigs_with_otid) {
continue;
}
if (sigC->category() != category) {
continue;
}
if (print_header) {
print_header = 0;
switch (category) {
case TT_HANDLE:
os << "handle:\n";
break;
case TT_HANDLE_PUSH:
os << "handle_push:\n";
break;
case TT_HANDLE_ROTATE:
os << "handle_rotate:\n";
break;
case TT_OBSERVE:
os << "observe:\n";
break;
}
}
os << "\t";
sigC->pretty_print(os);
}
}
}
int _Tt_signature::
xdr_version_required() const
{
int version = TT_TYPESDB_DEFAULT_XDR_VERSION;
if (_contexts->count() > 0) {
version = max(version, TT_CONTEXTS_XDR_VERSION);
}
switch (_pattern_category) {
case TT_HANDLE_PUSH:
case TT_HANDLE_ROTATE:
version = max(version, TT_PUSH_ROTATE_XDR_VERSION);
break;
}
return version;
}
int _Tt_signature::
xdr_version_required_(const _Tt_signature_list_ptr &sigs)
{
int version = TT_TYPESDB_DEFAULT_XDR_VERSION;
_Tt_signature_list_cursor sigC( sigs );
while (sigC.next()) {
version = max(version, sigC->xdr_version_required());
}
return version;
}

View 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_signature.h /main/3 1995/10/23 12:01:36 rswiston $ */
/*
* Tool Talk Message Passer (MP) - mp_signature.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* Declaration of the _Tt_signature & _Tt_signature_list classes.
*/
#ifndef _MP_SIGNATURE_H
#define _MP_SIGNATURE_H
#include "mp/mp_global.h"
#include "mp/mp_arg_utils.h"
#include "mp_signature_utils.h"
#include "mp/mp_context_utils.h"
#include "mp/mp_trace.h"
/*
* _Tt_signature is used to represent the signature of a method or
* procedure.
*/
class _Tt_signature : public _Tt_object {
public:
_Tt_signature();
_Tt_signature(_Tt_signature_ptr sig);
virtual ~_Tt_signature();
Tt_scope scope() const;
const _Tt_arg_list_ptr &args() const;
const _Tt_context_list_ptr &contexts() const;
Tt_class message_class() const;
Tt_category category() const;
const _Tt_string & op() const;
int opnum() const;
Tt_disposition reliability() const;
const _Tt_string & ptid() const;
/* only relevant for otype signatures */
const _Tt_string & otid() const;
_Tt_string super_otid();
void set_scope(Tt_scope scope);
void set_args(_Tt_arg_list_ptr &args);
void set_message_class(Tt_class mclass);
void set_pattern_category(Tt_category kind);
void set_op(_Tt_string op);
void set_opnum(int opnum);
void set_reliability(Tt_disposition r);
void set_ptid(_Tt_string ptid);
void set_otid(_Tt_string otid);
void set_super_otid(_Tt_string otid);
int match(
Tt_scope s,
Tt_class c,
const _Tt_string &op,
const _Tt_arg_list_ptr &args,
const _Tt_string &otype,
const _Tt_context_list_ptr &contexts,
const _Tt_msg_trace *trace,
int &was_exact
) const;
int match(
const _Tt_string &op,
const _Tt_arg_list_ptr &args,
const _Tt_context_list_ptr &contexts,
_Tt_string &reason,
int &was_exact
) const;
void append_arg(_Tt_arg_ptr &arg);
void append_context(_Tt_context_ptr &c);
void print(const _Tt_ostream &os) const;
void pretty_print(const _Tt_ostream &os) const;
static void pretty_print_(const _Tt_ostream &os,
const _Tt_object *obj);
static void pretty_print_(const _Tt_ostream &os,
const _Tt_signature_list_ptr &sigs,
Tt_category category,
int skip_sigs_with_otid);
bool_t xdr(XDR *xdrs);
int operator==(const _Tt_signature &sig) const;
int is_same_method(const _Tt_signature &sig) const;
int is_ce_equal(_Tt_signature &st);
void *ce_entry;
unsigned int timestamp() const
{ return _timestamp; }
void set_timestamp(unsigned int stamp)
{ _timestamp = stamp; }
int xdr_version_required() const;
static int xdr_version_required_(
const _Tt_signature_list_ptr &sigs);
private:
friend class _Tt_typedb;
_Tt_string _mangled_args;
Tt_scope _scope;
_Tt_arg_list_ptr _args;
_Tt_context_list_ptr _contexts;
Tt_class _message_class;
Tt_category _pattern_category;
_Tt_string _op;
Tt_disposition _reliability;
int _opnum;
_Tt_string _ptid;
_Tt_string _otid;
_Tt_string _super_otid;
unsigned int _timestamp;
};
#endif /* _MP_SIGNATURE_H */

View 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_signature_utils.C /main/3 1995/10/23 12:01:47 rswiston $
/*
*
* mp_signature_utils.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp_signature.h"
_Tt_sigs_by_op::
_Tt_sigs_by_op()
{
}
_Tt_sigs_by_op::
~_Tt_sigs_by_op()
{
}
_Tt_sigs_by_op::
_Tt_sigs_by_op(_Tt_string o)
{
_op = o;
}
_Tt_string
_tt_sigs_by_op_op(_Tt_object_ptr &o)
{
return(((_Tt_sigs_by_op *)o.c_pointer())->op());
}
implement_list_of(_Tt_signature)
implement_list_of(_Tt_sigs_by_op)
implement_table_of(_Tt_sigs_by_op)

View File

@@ -0,0 +1,35 @@
/*%% (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_signature_utils.h /main/3 1995/10/23 12:01:56 rswiston $ */
/*
*
* mp_signature_utils.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#ifndef MP_SIGNATURE_UTILS_H
#define MP_SIGNATURE_UTILS_H
#include <util/tt_object.h>
#include <util/tt_list.h>
#include <util/tt_string.h>
declare_list_of(_Tt_signature)
class _Tt_sigs_by_op : public _Tt_object {
public:
_Tt_sigs_by_op();
~_Tt_sigs_by_op();
_Tt_sigs_by_op(_Tt_string o);
void set_op(_Tt_string o){ _op = o; };
_Tt_string op(){ return _op; };
_Tt_signature_list_ptr sigs;
private:
_Tt_string _op;
};
_Tt_string _tt_sigs_by_op_op(_Tt_object_ptr &o);
declare_list_of(_Tt_sigs_by_op)
declare_table_of(_Tt_sigs_by_op)
#endif /* MP_SIGNATURE_UTILS_H */

2220
cde/lib/tt/slib/mp_typedb.C Normal file

File diff suppressed because it is too large Load Diff

100
cde/lib/tt/slib/mp_typedb.h Normal file
View File

@@ -0,0 +1,100 @@
/*%% (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_typedb.h /main/3 1995/10/23 12:02:24 rswiston $ */
/*
* @(#)mp_typedb.h 1.25 @(#)
* mp_typedb.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#ifndef _MP_TYPEDB_H
#define _MP_TYPEDB_H
#if defined(ultrix)
#include <sys/types.h>
#endif
#include <sys/stat.h>
#include "util/tt_object.h"
#include "mp/mp_global.h"
#include "mp_otype_utils.h"
#include "mp_ptype_utils.h"
#include "mp_signature_utils.h"
#include "mp_typedb_utils.h"
#define TT_NS_NAME "SUN_TOOLTALK_TYPES"
/*
* This is also used by tt_type_comp.
*/
int _tt_map_xdr_dbpaths(_Tt_string &udb, _Tt_string &sdb, _Tt_string &ndb);
typedef enum {
TypedbUser,
TypedbSystem,
TypedbNetwork,
TypedbAll,
TypedbNone
} _Tt_typedbLevel;
class _Tt_typedb : public _Tt_object {
public:
_Tt_typedb(char *ce_dir = (char *)0);
virtual ~_Tt_typedb();
int abort_write();
int begin_write(_Tt_typedbLevel db);
int end_write();
Tt_status write(const _Tt_string &outfile);
Tt_status write(FILE *outfile);
static Tt_status send_saved(const _Tt_string &savedfile);
int remove_otype(_Tt_string otid);
int remove_ptype(_Tt_string ptid);
int insert(_Tt_ptype_ptr &pt);
int insert(_Tt_otype_ptr &ot);
Tt_status init_xdr(const _Tt_string &binary_file);
Tt_status init_xdr(FILE *f);
Tt_status init_xdr(_Tt_typedbLevel db= TypedbAll);
Tt_status init_ce( _Tt_typedbLevel db= TypedbAll);
static Tt_status merge_from(const _Tt_string &xdr_file,
_Tt_typedb_ptr &tdb);
static Tt_status merge_from(FILE *xdr_file,
_Tt_typedb_ptr &tdb,
int &version);
static Tt_status merge_from(XDR *xdrs,
_Tt_typedb_ptr &tdb,
int &version);
static Tt_status ce2xdr();
static _Tt_typedbLevel level( const _Tt_string &level_name );
static const char *level_name( _Tt_typedbLevel db );
static _Tt_string_list *tt_path();
void print(const _Tt_ostream &os) const;
void pretty_print(
const _Tt_ostream &os) const;
int xdr_version_required() const;
bool_t xdr(XDR *xdrs);
_Tt_ptype_table_ptr ptable;
_Tt_otype_table_ptr otable;
_Tt_string user_db;
_Tt_string system_db;
_Tt_string network_db;
_Tt_typedbLevel ceDB2Use;
private:
#ifdef OPT_CLASSING_ENGINE
void *make_ce_entry(_Tt_ptype_ptr &pt);
void *make_ce_entry(_Tt_otype_ptr &ot);
void *make_ce_entry(_Tt_signature_ptr &st);
_Tt_string _ce_dir;
#endif /* OPT_CLASSING_ENGINE */
int write_ce_header(const _Tt_ostream& os) const;
int _flags;
_Tt_string _lock_file;
};
#endif /* _MP_TYPEDB_H */

View 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_typedb_utils.C /main/3 1995/10/23 12:02:35 rswiston $
/*
*
* mp_typedb_utils.cc
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include "mp_typedb.h"
implement_ptr_to(_Tt_typedb)

View 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_typedb_utils.h /main/3 1995/10/23 12:02:50 rswiston $ */
/*
*
* mp_typedb_utils.h
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#ifndef MP_TYPEDB_UTILS_H
#define MP_TYPEDB_UTILS_H
#include <util/tt_object.h>
#include <util/tt_ptr.h>
class _Tt_typedb;
declare_ptr_to(_Tt_typedb)
#endif /* MP_TYPEDB_UTILS_H */

139
cde/lib/tt/slib/simple.mk Normal file
View File

@@ -0,0 +1,139 @@
# %% (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: simple.mk /main/3 1995/10/23 12:02:59 rswiston $
# @(#)simple.mk 1.6 93/09/07
TT_DIR = ..
include $(TT_DIR)/simple-macros.mk
all: libstt.a
LIBSTT_OBJECTS =\
mp_ce_attrs.o \
mp_observer.o \
mp_observer_utils.o \
mp_otype.o \
mp_otype_utils.o \
mp_ptype.o \
mp_ptype_utils.o \
mp_rpc_implement.o \
mp_rpc_server.o \
mp_rpc_server_utils.o \
mp_s_file.o \
mp_s_file_utils.o \
mp_s_message.o \
mp_s_message_utils.o \
mp_s_mp.o \
mp_s_msg_context.o \
mp_s_pat_context.o \
mp_s_pattern.o \
mp_s_pattern_utils.o \
mp_s_procid.o \
mp_s_procid_utils.o \
mp_s_session.o \
mp_s_session_prop.o \
mp_s_session_utils.o \
mp_s_xdr_functions.o \
mp_signature.o \
mp_signature_utils.o \
mp_typedb.o \
mp_typedb_utils.o
libstt.a: $(LIBSTT_OBJECTS)
$(RM) libstt.a; $(AR) libstt.a $(LIBSTT_OBJECTS)
$(RANLIB) libstt.a
mp_ce_attrs.o: mp_ce_attrs.C
$(CCC) $(CCCFLAGS) -o mp_ce_attrs.o -c mp_ce_attrs.C
mp_observer.o: mp_observer.C
$(CCC) $(CCCFLAGS) -o mp_observer.o -c mp_observer.C
mp_observer_utils.o: mp_observer_utils.C
$(CCC) $(CCCFLAGS) -o mp_observer_utils.o -c mp_observer_utils.C
mp_otype.o: mp_otype.C
$(CCC) $(CCCFLAGS) -o mp_otype.o -c mp_otype.C
mp_otype_utils.o: mp_otype_utils.C
$(CCC) $(CCCFLAGS) -o mp_otype_utils.o -c mp_otype_utils.C
mp_ptype.o: mp_ptype.C
$(CCC) $(CCCFLAGS) -o mp_ptype.o -c mp_ptype.C
mp_ptype_utils.o: mp_ptype_utils.C
$(CCC) $(CCCFLAGS) -o mp_ptype_utils.o -c mp_ptype_utils.C
mp_rpc_implement.o: mp_rpc_implement.C
$(CCC) $(CCCFLAGS) -o mp_rpc_implement.o -c mp_rpc_implement.C
mp_rpc_server.o: mp_rpc_server.C
$(CCC) $(CCCFLAGS) -o mp_rpc_server.o -c mp_rpc_server.C
mp_rpc_server_utils.o: mp_rpc_server_utils.C
$(CCC) $(CCCFLAGS) -o mp_rpc_server_utils.o -c mp_rpc_server_utils.C
mp_s_file.o: mp_s_file.C
$(CCC) $(CCCFLAGS) -o mp_s_file.o -c mp_s_file.C
mp_s_file_utils.o: mp_s_file_utils.C
$(CCC) $(CCCFLAGS) -o mp_s_file_utils.o -c mp_s_file_utils.C
mp_s_message.o: mp_s_message.C
$(CCC) $(CCCFLAGS) -o mp_s_message.o -c mp_s_message.C
mp_s_message_utils.o: mp_s_message_utils.C
$(CCC) $(CCCFLAGS) -o mp_s_message_utils.o -c mp_s_message_utils.C
mp_s_mp.o: mp_s_mp.C
$(CCC) $(CCCFLAGS) -o mp_s_mp.o -c mp_s_mp.C
mp_s_msg_context.o: mp_s_msg_context.C
$(CCC) $(CCCFLAGS) -o mp_s_msg_context.o -c mp_s_msg_context.C
mp_s_pat_context.o: mp_s_pat_context.C
$(CCC) $(CCCFLAGS) -o mp_s_pat_context.o -c mp_s_pat_context.C
mp_s_pattern.o: mp_s_pattern.C
$(CCC) $(CCCFLAGS) -o mp_s_pattern.o -c mp_s_pattern.C
mp_s_pattern_utils.o: mp_s_pattern_utils.C
$(CCC) $(CCCFLAGS) -o mp_s_pattern_utils.o -c mp_s_pattern_utils.C
mp_s_procid.o: mp_s_procid.C
$(CCC) $(CCCFLAGS) -o mp_s_procid.o -c mp_s_procid.C
mp_s_procid_utils.o: mp_s_procid_utils.C
$(CCC) $(CCCFLAGS) -o mp_s_procid_utils.o -c mp_s_procid_utils.C
mp_s_session.o: mp_s_session.C
$(CCC) $(CCCFLAGS) -o mp_s_session.o -c mp_s_session.C
mp_s_session_prop.o: mp_s_session_prop.C
$(CCC) $(CCCFLAGS) -o mp_s_session_prop.o -c mp_s_session_prop.C
mp_s_session_utils.o: mp_s_session_utils.C
$(CCC) $(CCCFLAGS) -o mp_s_session_utils.o -c mp_s_session_utils.C
mp_s_xdr_functions.o: mp_s_xdr_functions.C
$(CCC) $(CCCFLAGS) -o mp_s_xdr_functions.o -c mp_s_xdr_functions.C
mp_signature.o: mp_signature.C
$(CCC) $(CCCFLAGS) -o mp_signature.o -c mp_signature.C
mp_signature_utils.o: mp_signature_utils.C
$(CCC) $(CCCFLAGS) -o mp_signature_utils.o -c mp_signature_utils.C
mp_typedb.o: mp_typedb.C
$(CCC) $(CCCFLAGS) -o mp_typedb.o -c mp_typedb.C
mp_typedb_utils.o: mp_typedb_utils.C
$(CCC) $(CCCFLAGS) -o mp_typedb_utils.o -c mp_typedb_utils.C
clean:
$(RM) $(LIBSTT_OBJECTS) libstt.a
install:

View File

@@ -0,0 +1,63 @@
/*%% (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: tt_db_server_consts.h /main/3 1995/10/23 12:03:11 rswiston $ */
/*
* tt_db_server_consts.h - Declares constants that are used by the
* _Tt_db_server_db class that may be useful
* in other parts of the DB server.
*
* Copyright (c) 1992 by Sun Microsystems, Inc.
*
*/
#ifndef _TT_DB_SERVER_CONSTS_H
#define _TT_DB_SERVER_CONSTS_H
#include "db/tt_db_key.h"
#include <limits.h>
#ifndef LONG_BIT
#define LONG_BIT 32
#endif
// The TT_DB_VERSION should be set to the lowest version of ToolTalk
// that includes a DB server that is compatible with the current
// database table formats. Currently, the last change to the table
// formats took place in ToolTalk version 1.1.
#define TT_DB_VERSION "1.1"
#define TT_DB_FILE_TABLE_FILE "file_table"
#define TT_DB_FILE_OBJECT_MAP_FILE "file_object_map"
#define TT_DB_PROPERTY_TABLE_FILE "property_table"
#define TT_DB_ACCESS_TABLE_FILE "access_table"
#define TT_DB_PROPS_CACHE_LEVEL_PROPERTY "_MODIFICATION_DATE"
#define TT_DB_FORWARD_POINTER_PROPERTY "_NEW_OIDKEY"
#define TT_DB_OBJECT_TYPE_PROPERTY "_NODE_TYPE"
#define TT_DB_MESSAGE_PROPERTY "_TT_MSG_%d_%d"
#define TT_DB_MESSAGE_INFO_PROPERTY "_TT_QUEUED_MSGS"
// The ':' at the beginning of the file name is for old client
// compatibility. The old server protocol expects a ':' in all file
// paths to delimit a hostname.
#define TT_DB_FORWARD_POINTER_FILE ":.TT_DB_FORWARD_POINTER_FILE"
const int TT_DB_MAX_KEY_LENGTH = 120;
const int TT_DB_MAX_PROPERTY_NAME_LENGTH = 64;
const int TT_DB_LONG_SIZE = LONG_BIT/8;
const int TT_DB_SHORT_SIZE = 2;
const int TT_DB_FIRST_KEY_OFFSET = 0;
const int TT_DB_SECOND_KEY_OFFSET = TT_DB_KEY_LENGTH;
const int TT_DB_FILE_PATH_OFFSET = TT_DB_KEY_LENGTH;
const int TT_DB_PROPERTY_NAME_OFFSET = TT_DB_KEY_LENGTH;
const int TT_DB_PROPERTY_VALUE_OFFSET = TT_DB_KEY_LENGTH+
TT_DB_MAX_PROPERTY_NAME_LENGTH;
const int TT_DB_ACCESS_USER_OFFSET = TT_DB_KEY_LENGTH;
const int TT_DB_ACCESS_GROUP_OFFSET = TT_DB_KEY_LENGTH+TT_DB_LONG_SIZE;
const int TT_DB_ACCESS_MODE_OFFSET = TT_DB_KEY_LENGTH+2*TT_DB_LONG_SIZE;
#endif /* _TT_DB_SERVER_CONSTS_H */

View File

@@ -0,0 +1,106 @@
//%% (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: tt_isstrerror.C /main/3 1995/10/23 12:03:24 rswiston $
//%% $XConsortium: tt_isstrerror.C /main/3 1995/10/23 12:03:24 rswiston $
//%%
//%% RESTRICTED CONFIDENTIAL INFORMATION:
//%%
//%% The information in this document is subject to special
//%% restrictions in a confidential disclosure agreement between
//%% HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
//%% document outside HP, IBM, Sun, USL, SCO, or Univel without
//%% Sun's specific written approval. This document and all copies
//%% and derivative works thereof must be returned or destroyed at
//%% Sun's request.
//%%
//%% Copyright 1993 Sun Microsystems, Inc. All rights reserved.
//%%
/*
* @(#)tt_isstrerror.C 1.3 94/11/17 SMI
*
* tt_isstrerror.C - interpret iserrno values
*
* Copyright (c) 1994 by Sun Microsystems, Inc.
*/
/*
* _tt_isstrerror() is a extended version of strerror(3) that
* also interprets the ISAM iserrno codes.
* It's in slib because:
* - it shouldn't go in libtt because nobody there calls
* ISAM directly
* - it can't go in libisam without major restructuring of
* the mini_isam build, making it dependent on the libtt
* internationalization code
* - both things that do call ISAM, rpc.ttdbserverd and
* ttdbck, do link with slib.
*/
#include"tt_isstrerror.h"
#include"util/tt_gettext.h"
#include <string.h>
/* use message set 2, TTMSET_SLIB */
const char *
_tt_isstrerror(int an_errno)
{
switch(an_errno) {
case 100:
return catgets(_ttcatd, 2, 14,"duplicate ISAM record");
case 101:
return catgets(_ttcatd, 2, 15,"ISAM file not open");
case 102:
return catgets(_ttcatd, 2, 16,"illegal ISAM argument");
case 103:
return catgets(_ttcatd, 2, 17,"illegal ISAM key descriptor");
case 104:
return catgets(_ttcatd, 2, 18,"too many ISAM files open");
case 105:
return catgets(_ttcatd, 2, 19,"bad ISAM file format");
case 106:
return catgets(_ttcatd, 2, 20,"ISAM non-exclusive access");
case 107:
return catgets(_ttcatd, 2, 21,"ISAM record locked");
case 108:
return catgets(_ttcatd, 2, 22,"ISAM key already exists");
case 109:
return catgets(_ttcatd, 2, 23,"ISAM key is primary key");
case 110:
return catgets(_ttcatd, 2, 24,"end or beginning of ISAM file");
case 111:
return catgets(_ttcatd, 2, 25,"no ISAM record found");
case 112:
return catgets(_ttcatd, 2, 26,"no current ISAM record");
case 113:
return catgets(_ttcatd, 2, 27,"ISAM file locked");
case 114:
return catgets(_ttcatd, 2, 28,"ISAM file name too long");
case 116:
return catgets(_ttcatd, 2, 29,
"ISAM cannot allocate memory");
case 1117:
return catgets(_ttcatd, 2, 30, "ISAM RPC timeout");
case 1118:
return catgets(_ttcatd, 2, 31,
"Broken ISAM TCP/IP connection");
case 1119:
return catgets(_ttcatd, 2, 32,
"Cannot connect to ISAM server");
case 1120:
return catgets(_ttcatd, 2, 33, "Cannot import ISAM data");
case 1121:
return catgets(_ttcatd, 2, 34, "no local SAM daemon");
case 1122:
return catgets(_ttcatd, 2, 35, "ISAM internal fatal error");
case 1123:
return catgets(_ttcatd, 2, 36, "ISAM Locale/LANG mismatch");
default:
// NetISAM can also return system errno values.
return strerror(an_errno);
}
}

View 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: tt_isstrerror.h /main/3 1995/10/23 12:03:35 rswiston $ */
/*
* tt_isstrerror.h
*
* Copyright (c) 1994 by Sun Microsystems, Inc.
*
* This file implements the _Tt_s_mp object which represents the global
* information for the server MP component. There should only be one
* instance of a _Tt_s_mp object in the server.
*/
#ifndef _TT_ISSTRERROR_H
#define _TT_ISSTRERROR_H
extern const char * _tt_isstrerror(int an_iserrno);
#endif /* _TT_ISSSTRERROR_H */