Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
9
cde/lib/tt/Imakefile
Normal file
9
cde/lib/tt/Imakefile
Normal file
@@ -0,0 +1,9 @@
|
||||
XCOMM $TOG: Imakefile /main/7 1998/08/10 18:01:46 mgreess $
|
||||
#define IHaveSubdirs
|
||||
#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CXXDEBUGFLAGS=$(CXXDEBUGFLAGS)'
|
||||
|
||||
SUBDIRS = mini_isam lib slib bin
|
||||
LINTSUBDIRS = mini_isam lib slib bin
|
||||
|
||||
MakeSubdirs($(SUBDIRS))
|
||||
DependSubdirs($(SUBDIRS))
|
||||
777
cde/lib/tt/README
Normal file
777
cde/lib/tt/README
Normal file
@@ -0,0 +1,777 @@
|
||||
/* $TOG: README /main/4 1999/08/30 10:44:07 mgreess $ */
|
||||
1.8 10/27/92
|
||||
Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
|
||||
|
||||
TOOLTALK IMPLEMENTATION OVERVIEW
|
||||
|
||||
|
||||
This document presents a roadmap to understanding the implementation
|
||||
of the main message-passing features of ToolTalk 1.0.1. It does not
|
||||
aim to describe the details of the algorithms used. In order to find
|
||||
these out it is necessary to read the source code as well as the
|
||||
comments. This document should give the reader an overall picture of
|
||||
how all the various objects that implement message-passing fit
|
||||
together as well as familiarity with where to find the code that
|
||||
implements a particular feature. Finally some naming conventions used
|
||||
throughout the code are given.
|
||||
|
||||
|
||||
********** Please update this document as the code is changed **********
|
||||
|
||||
|
||||
|
||||
MEMORY MANAGEMENT
|
||||
|
||||
The only memory management policy used througout the code is
|
||||
reference-counting. This is an automatic sort of memory management
|
||||
since objects are "magically" deleted when there are no longer
|
||||
references to them. This functionality is implemented by way of
|
||||
pointer classes that behave just like normal pointers except that they
|
||||
maintain a reference count in the object they point to. It is
|
||||
important *not* to mix normal pointers with counted pointers.
|
||||
|
||||
MIXING POINTERS
|
||||
|
||||
You should never use a C pointer with refcounted objects (i.e., those
|
||||
inheriting from _Tt_object (actually, from _Tt_new; I have no idea why
|
||||
_Tt_new and _Tt_object are different)). You should always use
|
||||
refcounting pointers ("ptrs") with _Tt_objects. The danger is as
|
||||
follows:
|
||||
|
||||
_Tt_object *evilRef;
|
||||
{
|
||||
evilRef = new _Tt_object;
|
||||
//
|
||||
// refCount is now zero, but evilRef is pointing at our
|
||||
// object!
|
||||
//
|
||||
...
|
||||
_Tt_object_ptr goodRef = evilRef;
|
||||
//
|
||||
// refCount is now 1
|
||||
//
|
||||
...
|
||||
//
|
||||
// goodRef goes out of scope.
|
||||
// goodRef::~_Tt_object_ptr() decrements the refCount
|
||||
// to zero, and deletes our object because the
|
||||
// refCount is now zero.
|
||||
//
|
||||
}
|
||||
int foo = evilRef->dataMember; // core dump
|
||||
|
||||
If you need a static pointer to a _Tt_object, you cannot have a static
|
||||
_Tt_object_ptr, because static C++ instances aren't allowed. But you
|
||||
don't want to have a static _Tt_object *, because then you have to
|
||||
eternally worry about never showing it to a refcounting pointer (which
|
||||
would try to delete it when it was done with it).
|
||||
|
||||
The best thing to do is have a static _Tt_object_ptr *:
|
||||
|
||||
static _Tt_object_ptr *ppGlobalObj;
|
||||
ppGlobalObj = new _Tt_object_ptr;
|
||||
*ppGlobalObj = new _Tt_object;
|
||||
|
||||
Now you can use *ppGlobalObj wherever you would have used your static
|
||||
_Tt_object_ptr. The _Tt_object you allocated is safely refcounted, so
|
||||
you can let refcounting pointers do whatever they want with it.
|
||||
When it's time to clean up, you just
|
||||
|
||||
delete ppGlobalObj;
|
||||
|
||||
This is a call to ppGlobalObj->~_Tt_object_ptr(), which decrements the
|
||||
refcount of your object, and *optionally* deletes it if the refcount
|
||||
is zero. This way, you don't delete your object out from under anyone
|
||||
who still has a reference to it.
|
||||
|
||||
REFCOUNTING INSIDE CONSTRUCTORS
|
||||
|
||||
Inside a constructor, never assign the 'this' pointer of a refcounted
|
||||
object to an automatic refcounting pointer. Inside the constructor,
|
||||
the refcount is still zero. Assigning 'this' into a refcounting
|
||||
pointer will increment the refcount to 1. But before the constructor
|
||||
returns, the automatic refcounting pointer on the stack will be
|
||||
destructed. The destructor will decrement the object's refcount back
|
||||
to zero, and therefore delete the object -- before the constructor
|
||||
even returns!
|
||||
|
||||
_Tt_foo::_Tt_foo()
|
||||
{
|
||||
// On entry, _Tt_foo::_refcount_ == 0
|
||||
_Tt_foo_ptr evilRef = this;
|
||||
// Now, _Tt_foo::_refcount_ == 1
|
||||
...
|
||||
// On exit, evilRef->~_Tt_foo_ptr() will be called.
|
||||
// It will decrement the refcount to zero, and
|
||||
// then delete this object under construction!
|
||||
}
|
||||
|
||||
Also, be sure not to pass the 'this' pointer to any routine that might
|
||||
hold a temporary reference to the object while the routine runs.
|
||||
(Here, "hold a temporary reference to" means "increment the refcount
|
||||
and then decrement it".) If you must pass the 'this' pointer anywhere
|
||||
from within the constructor, cast it to const first so that the
|
||||
compiler will protect you from any routine with an intention of
|
||||
modifying its refcount. If you absolutely must pass the 'this'
|
||||
pointer to a routine that might only temporarily reference it, then
|
||||
manually increment the refcount before doing so, and then manually
|
||||
decrement the refcount before returning from the constructor
|
||||
|
||||
CYCLICAL REFERENCES
|
||||
|
||||
Avoid creating data structures that permit cyclical references.
|
||||
A single reference cycle can cause a massive memory leak.
|
||||
|
||||
COMMENT CONVENTIONS
|
||||
|
||||
Throughout the code, any comments preceded by XXX: denote notes to the
|
||||
reader of problems or suggestions for the code they describe.
|
||||
|
||||
|
||||
|
||||
DESCRIPTION OF OBJECT CLASSES
|
||||
|
||||
This section presents all the object classes used to implement the
|
||||
message-passing portion of ToolTalk along with a brief description of
|
||||
what each class represents and in which files it can be found. Before
|
||||
describing the classes we need to mention some important naming
|
||||
conventions as well as some general comments about client/server
|
||||
conventions.
|
||||
|
||||
Many of the object classes described below have client-side and
|
||||
server-side implementations. For example, a client-side version of a
|
||||
ToolTalk message has methods to send the message to the server. On the
|
||||
server-side there is a corresponding _Tt_message that processes the
|
||||
new message. In the 1.0 version of ToolTalk, these methods were
|
||||
roughly coded as:
|
||||
|
||||
void _Tt_some_object::
|
||||
sample_method(...)
|
||||
{
|
||||
if (_tt_mp->in_server()) {
|
||||
... do server-specific actions ...
|
||||
} else {
|
||||
... do client-specific actions ...
|
||||
}
|
||||
}
|
||||
|
||||
where the "in_server" method for the _Tt_mp class returns 1 if the
|
||||
environment is in server mode (which is true if the method is
|
||||
executing on behalf of ttsession). The problem with this scheme is
|
||||
that the library was excessively big because the code to implement the
|
||||
server, ttsession, was contained in the library even though it wasn't
|
||||
needed for the clients.
|
||||
|
||||
Because of this, the 1.0.1 version split up this method in one of two
|
||||
ways. The first method is to create two subclasses of the object. One
|
||||
of the subclasses, named with a "_c_" infix, represents the
|
||||
client-side state and methods for the object. The other subclass,
|
||||
named with a "_s_" infix, represents the server-side state and methods
|
||||
for the object. Each of these subclasses then contains the
|
||||
corresponding method which now doesn't need the conditional test. The
|
||||
example above then becomes:
|
||||
|
||||
void _Tt_c_some_object::
|
||||
sample_method(...)
|
||||
{
|
||||
... do client-specific actions ...
|
||||
}
|
||||
|
||||
|
||||
void _Tt_s_some_object::
|
||||
sample_method(...)
|
||||
{
|
||||
... do server-specific actions ...
|
||||
}
|
||||
|
||||
The other mechanism is to still have one object class but name the
|
||||
object with a "c_" prefix for the client-specific method, and an "s_"
|
||||
prefix for the server-specific method.
|
||||
|
||||
In the 4/93 version of ToolTalk, more classes were split up so that
|
||||
no references to server-only classes would appear in client code.
|
||||
As part of this, the client-to-server XDR methods were slightly
|
||||
changed. You will see (in mp_rpc_implement.C) that apparently
|
||||
the server uses a XDR function to decode the arguments of some
|
||||
RPCs which is different from the encoding XDR function. This
|
||||
seemingly violates the central dogma of XDR, but it really isn't
|
||||
as bad as it looks. What is happpening is that we have class
|
||||
hierarchies like:
|
||||
|
||||
_Tt_pattern
|
||||
|
|
||||
------------------
|
||||
| |
|
||||
_Tt_s_pattern _Tt_c_pattern
|
||||
|
||||
Only _Tt_pattern has an XDR method -- that is, the data that appears
|
||||
on the wire is only the common data. A client would create a _Tt_c_pattern
|
||||
and XDR it out; the server then XDR's it in as a _Tt_s_pattern, but
|
||||
the _Tt_pattern::XDR routine does all the work and the only difference
|
||||
is the virtual function table (and any private _Tt_s_pattern data,
|
||||
which would be initialized by the _Tt_s_pattern constructor.)
|
||||
|
||||
|
||||
The following classes are related to the main message-passing
|
||||
functionality in ToolTalk. Details on what methods they implement and
|
||||
precise algorithms are in the source code along with the comments
|
||||
throughout the code.
|
||||
|
||||
|
||||
Class: _Tt_arg
|
||||
File: tt/lib/mp/mp_arg.C (client/server methods)
|
||||
tt/lib/mp/mp_s_arg.C (server-only methods)
|
||||
|
||||
This class represents an argument to a message or pattern. Its methods
|
||||
implement matching arguments with other arguments and constructing and
|
||||
updating arguments.
|
||||
|
||||
|
||||
Class: _Tt_auth
|
||||
File: tt/lib/mp/mp_auth.C (client/server methods)
|
||||
tt/lib/mp/mp_auth_functions.C (utility functions copied from libICE)
|
||||
|
||||
This class maintains the authorization level being used by the server
|
||||
(cookie, des, unix, none). In the case of the cookie authorization
|
||||
scheme, this class also is responsible for generating the cookie and
|
||||
writing it to and reading it from the authority file.
|
||||
|
||||
Class: _Tt_desktop
|
||||
File: tt/lib/mp/mp_desktop.C
|
||||
|
||||
This class represents "desktop" sessions. Currently this means X11
|
||||
server sessions but the methods reflect an interface that is largely
|
||||
independent of X11. As a result, all X11-dependent code is isolated in
|
||||
this one module.
|
||||
|
||||
|
||||
Class: _Tt_c_message (subclass of _Tt_message)
|
||||
File: tt/lib/mp/mp_c_message.C
|
||||
|
||||
This class represents client-only view of ToolTalk messages. It
|
||||
contains methods for sending messages to the ttsession server.
|
||||
|
||||
|
||||
Class: _Tt_c_procid (subclass of _Tt_procid)
|
||||
File: tt/lib/mp/mp_c_procid.C
|
||||
|
||||
This class implements client-only methods needed to reply to messages
|
||||
and to retrieve new messages for the ToolTalk client represented by
|
||||
this class.
|
||||
|
||||
|
||||
Class: _Tt_file
|
||||
File: tt/lib/mp/mp_file.C (server/client methods)
|
||||
tt/lib/mp/mp_s_file.C (server-only methods)
|
||||
|
||||
This class represents file objects. The functionality implemented is
|
||||
for querying for specs contained in the file, joining and quitting
|
||||
file scopes, and queuing and de-queueing messages on file objects.
|
||||
|
||||
|
||||
Class: _Tt_message
|
||||
File: tt/lib/mp/mp_message.C
|
||||
|
||||
This class represents a ToolTalk message. This class represents
|
||||
methods that are common to both clients and ttsession. Its subclasses,
|
||||
_Tt_s_message and _Tt_c_message described below implement methods
|
||||
specific to client manipulation and server manipulation respectively.
|
||||
The code is structured so that _Tt_message objects contain the methods
|
||||
to do delivery to other clients.
|
||||
|
||||
|
||||
Class: _Tt_mp
|
||||
File: tt/lib/mp/mp_mp.C
|
||||
|
||||
This class represents the global state needed by the message-passing
|
||||
objects. In particular, this object contains many object caches that
|
||||
are needed by the system as well as holds references to some important
|
||||
objects such as the default session object.
|
||||
|
||||
|
||||
Class: _Tt_node
|
||||
File: tt/lib/mp/mp_node.C
|
||||
|
||||
This class represents a ToolTalk spec. Its methods create/destroy
|
||||
specs in a database and add properties to an existing spec.
|
||||
|
||||
|
||||
Class: _Tt_observer
|
||||
File: tt/lib/mp/mp_observer.C
|
||||
|
||||
This class is a very simple class that basically just stores some
|
||||
message fields that can change for static observers of a message. It
|
||||
is used only by the _Tt_s_message class. This class is mainly used as
|
||||
to hold the information necessary to honor static observer "promises"
|
||||
for message disposition processing.
|
||||
|
||||
|
||||
Class: _Tt_otype
|
||||
File: tt/lib/mp/mp_otype.C
|
||||
|
||||
This class implements methods needed to deal with otype definitions.
|
||||
In general the operations needed are for setting and returning the
|
||||
observer, inherited, and handler signatures for this otype definition
|
||||
as well as printing out the otype definition which, in addition to
|
||||
debugging, is used to print out the definition for storage under the
|
||||
Classing Engine and also for dumping out compiled type databases in
|
||||
source format.
|
||||
|
||||
|
||||
Class: _Tt_pattern
|
||||
File: tt/lib/mp/mp_pattern.C (server/client methods)
|
||||
tt/lib/mp/mp_s_pattern.C (server-only methods)
|
||||
|
||||
This class represents a ToolTalk pattern. Client-side methods
|
||||
implement adding/deleting fields to the pattern and
|
||||
registering/unregistering the pattern by invoking the proper rpc
|
||||
routines on the server. Server-side methods implement the appropiate
|
||||
actions for registering/unregistering patterns as well as matching
|
||||
patterns to messages.
|
||||
|
||||
|
||||
Class: _Tt_procid
|
||||
File: tt/lib/mp/mp_procid.C
|
||||
|
||||
This class represents a ToolTalk client. It represents all of the
|
||||
methods and data necessary for sending a message to a ToolTalk client.
|
||||
Its subclasses, _Tt_s_procid and _Tt_c_procid, implement the needed
|
||||
server-only and client-only methods.
|
||||
|
||||
|
||||
Class: _Tt_ptype
|
||||
File: tt/lib/mp/mp_ptype.C
|
||||
|
||||
This class implements methods needed to deal with ptype definitions
|
||||
and with starting new instances of ptypes which is functionality
|
||||
needed to implement the start disposition options for ToolTalk
|
||||
messages. Also, as with _Tt_otype objects, printing methods are also
|
||||
defined that are used for storage in type databases and dumping out
|
||||
ptype definitions in source format.
|
||||
|
||||
|
||||
Class: _Tt_rpc_client
|
||||
File: tt/lib/mp/mp_rpc_client.C
|
||||
|
||||
This class represents a client rpc connection. The methods implemented
|
||||
are basically wrappers around the rpc interfaces with the important
|
||||
difference that the api to this object is the same regardless of
|
||||
whether tli rpc or non-tli rpc is used. The methods for this object
|
||||
are ifdefed to use tli rpc or not.
|
||||
|
||||
|
||||
Class: _Tt_rpc_server
|
||||
File: tt/lib/mp/mp_rpc_server.C
|
||||
|
||||
This class represents an rpc server. The methods implemented are
|
||||
wrappers around the rpc server interfaces with the difference that
|
||||
both tli and non-tli rpc is supported by ifdefing the implementation
|
||||
code for the methods to select which rpc interface to use.
|
||||
|
||||
|
||||
Class: _Tt_s_message (subclass of _Tt_message)
|
||||
File: tt/lib/mp/mp_s_message.C
|
||||
|
||||
This class represents a ToolTalk message with some specialized methods
|
||||
that are specific to server-side manipulation of messages. In
|
||||
particular this class implements methods to dispatch a message (ie.
|
||||
match the message against static patterns), and deliver the message to
|
||||
ToolTalk clients with patterns that match it. There are also methods
|
||||
to implement the reliability for messages that don't match any active
|
||||
client's patterns.
|
||||
|
||||
|
||||
Class: _Tt_s_mp
|
||||
File: tt/lib/mp/mp_s_mp.C
|
||||
|
||||
This class represents the global server-only state needed by the
|
||||
message-passing objects. It contains object caches that are relevant
|
||||
to the server module as well as the ptypes and otypes that were read
|
||||
in from the type database.
|
||||
|
||||
|
||||
Class: _Tt_s_procid (subclass of _Tt_procid)
|
||||
File: tt/lib/mp/mp_s_procid.C
|
||||
|
||||
This class implements server-only methods needed to send messages to
|
||||
ToolTalk clients and also methods which process replies to previously
|
||||
sent messages.
|
||||
|
||||
|
||||
Class: _Tt_session
|
||||
File: tt/lib/mp/mp_session.C (server/client methods)
|
||||
tt/lib/mp/mp_s_session.C (server-only methods)
|
||||
|
||||
This class represents a ToolTalk session. It has methods that apply in
|
||||
client-side and server-side environments. The main functionality
|
||||
required is establishing ToolTalk sessions, advertising the addressing
|
||||
information to contact the session, and methods for connecting to a
|
||||
session given its addressing information and auto-starting a session
|
||||
if necessary.
|
||||
|
||||
|
||||
Class: _Tt_signature
|
||||
File: tt/lib/mp/mp_signature.C
|
||||
|
||||
This class represents a ToolTalk signature which can be either an
|
||||
otype or ptype signature. The main methods for this object allow one
|
||||
to create a signature, match the signature against an operation name
|
||||
and a list of arguments, and match the signature against relevant
|
||||
message fields.
|
||||
|
||||
|
||||
Class: _Tt_stream_socket
|
||||
File: tt/lib/mp/mp_stream_socket.C
|
||||
|
||||
This class represents a stream connection. Its methods are ifdefed
|
||||
depending on whether TCP sockets are to be used or TLI streams.
|
||||
|
||||
|
||||
Class: _Tt_typedb
|
||||
File: tt/lib/mp/mp_typedb.C
|
||||
|
||||
This class represents the ToolTalk type database. It has methods for
|
||||
reading and writing the database in either a native xdr format or to
|
||||
the Classing Engine. Important Note: since the typedb on disk is
|
||||
a table_ptr and not just a table, it's possible to have a null
|
||||
table and a non-null _ptr, which if xdr-decoded will crash the
|
||||
_Tt_object_table xdr method, because the default constructor
|
||||
for that class tries to decode a null table.
|
||||
|
||||
|
||||
Class: _Tt_global
|
||||
File: tt/lib/util/tt_global_env.C
|
||||
|
||||
This class is where any global information that is not specific to
|
||||
message-passing is kept. In particular any global flags or caches are
|
||||
kept in this object. This class also keeps the number representing the
|
||||
current xdr version to be used by all xdr methods.
|
||||
|
||||
|
||||
Class: _Tt_host
|
||||
File: tt/lib/util/tt_host.C
|
||||
|
||||
This class packages up methods for mapping host addresses to host
|
||||
names and viceversa.
|
||||
|
||||
|
||||
Class: _Tt_xdr_version
|
||||
File: tt/lib/util/tt_xdr_version.C
|
||||
|
||||
This class provides a mechanism for temporarily setting the default
|
||||
xdr version. It sets the version to a given number in the constructor
|
||||
and then resets the default to the previous value in the destructor.
|
||||
|
||||
|
||||
Class: _Tt_new_ptr
|
||||
File: tt/lib/util/tt_new_ptr.C
|
||||
|
||||
Generic version of a pointer class. This implements the
|
||||
reference-counting machinery. See declare_ptr_to and implement_ptr_to
|
||||
in tt/lib/util/tt_ptr.h to see how a specialized pointer class is
|
||||
derived from this generic class.
|
||||
|
||||
|
||||
Class: _Tt_object_list
|
||||
File: tt/lib/util/tt_object_list.C
|
||||
|
||||
Generic version of a list class. See declare_list_of and
|
||||
implement_list_of in tt/lib/util/tt_list.h to see how a specialized
|
||||
list class is derived from the generic one.
|
||||
|
||||
|
||||
Class: _Tt_object_table
|
||||
File: tt/lib/util/tt_object_table.C
|
||||
|
||||
Generic version of a table class. See declare_table_of and
|
||||
implement_table_of in tt/lib/util/tt_table.h to see how a specialized
|
||||
list class is derived from the generic one. Important note: unfortunately
|
||||
you can crash this method by trying to de-xdr on online db because
|
||||
the default constructor for that class tries to decode a null table.
|
||||
|
||||
|
||||
FINDING ONE'S WAY AROUND
|
||||
|
||||
The rich functionality offered by ToolTalk is implemented partly in
|
||||
the client library, partly in the server (which itself is implemented
|
||||
by objects contained in a server library). Thus it isn't always
|
||||
trivial to find which code implements a certain feature. A good
|
||||
heuristic to use is to decide whether the particular feature is likely
|
||||
to be implemented on the client side or server side. If it is likely a
|
||||
client-side feature then it is accessible through one of the tooltalk
|
||||
api calls. These are all implemented in the tt/lib/api/c directory
|
||||
where the files are named api_<noun> where <noun> is the name of the
|
||||
entity being operated on by the api call. For example,
|
||||
tt_pattern_create can be found in "api_pattern.C". The api calls that
|
||||
don't operate on a particular entity are found in "api_mp.C". For
|
||||
example, tt_open and tt_fd can be found there.
|
||||
|
||||
Once the code for the api is located, the way the feature is
|
||||
implemented can be traced through the code. Occasionally the api call
|
||||
may interact with the server-side code. This is usually in the form of
|
||||
an api call such as:
|
||||
|
||||
...
|
||||
rstatus = call(TT_RPC_JOIN_SESSION,
|
||||
(xdrproc_t)tt_xdr_procid,
|
||||
(char *)&procid,
|
||||
(xdrproc_t)xdr_int,
|
||||
(char *)&status);
|
||||
...
|
||||
|
||||
|
||||
This will cause an rpc stub to be invoked which then invokes the
|
||||
appropiate methods on the server side. All the rpc stubs are
|
||||
implemented in tt/lib/mp/mp_rpc_implement.C. Furthermore, the naming
|
||||
scheme for these stubs is to add an underscore to the front of the
|
||||
enum used to make the call on the client side and then turn all the
|
||||
letters into lower case. In the example above, one would then look for
|
||||
the "_tt_rpc_join_session" function in tt/lib/mp/mp_rpc_implement.C.
|
||||
|
||||
The details of how the call is mapped to this rpc stub and what
|
||||
processing goes on before the rpc stub is invoked can be found in the
|
||||
_tt_service_rpc function which does the actual rpc dispatching.
|
||||
|
||||
Since most of the functionality is initiated by an api call (the
|
||||
exception being the initializiation of the server itself), this
|
||||
strategy usually succeeds in finding the code one is looking for.
|
||||
|
||||
|
||||
We now list some guides into the code implementing some of the major
|
||||
features in ToolTalk. For each piece of functionality some important
|
||||
methods and/or files are listed which represent the main code that
|
||||
implements the given functionality. Looking at the code for the given
|
||||
methods and their associated comments should give a good idea as to
|
||||
how the functionality is implemented.
|
||||
|
||||
|
||||
********** Please add to this list **********
|
||||
|
||||
- RPC REQUEST HANDLING
|
||||
|
||||
(client) _Tt_session::call - single method that all other methods use
|
||||
when they want to invoke an rpc call.
|
||||
|
||||
(server) tt/lib/mp/mp_rpc_implement.C contains all of the rpc stubs
|
||||
that get invoked on the server side in response to an rpc request from
|
||||
a client. The dispatch function in this file "_tt_service_rpc" does
|
||||
the actual dispatching of the rpc request (_tt_service_rpc is actually
|
||||
invoked by the rpc function svc_getreqset which is called from
|
||||
_Tt_s_mp::main_loop by calling _Tt_rpc_server::run).
|
||||
|
||||
Looking at the various rpc stubs in mp_rpc_implement.C is an
|
||||
excellent way of navigating the code to find out how each particular
|
||||
rpc call is used. In particular, a good strategy for finding out how
|
||||
an api call is implemented is by looking at the definition of the api
|
||||
call and tracing through the code until _Tt_session::call invocations
|
||||
are found. Using the rpc procedure number passed into the
|
||||
_Tt_session::call method one can then look in mp_rpc_implement.C to
|
||||
see what happens on the server side.
|
||||
|
||||
|
||||
- NULL MESSAGE SENDING/RECEIVING LOOP
|
||||
|
||||
This loop consists of a client sending a request message to ttsession
|
||||
when no patterns match the message. The message gets failed and
|
||||
returned to the sender. Understanding the code involved in this loop
|
||||
means that one understands the basic low-level mechanism by which the
|
||||
messages sent to and received from ttsession. The major methods
|
||||
involved here are:
|
||||
|
||||
(client) _Tt_c_message::dispatch - send message to ttsession
|
||||
(server) _Tt_s_message::dispatch - match message with static patterns.
|
||||
(server) _Tt_s_message::deliver - match message with dynamic patterns.
|
||||
(server) _Tt_s_procid::add_message - add a message to procid's message
|
||||
queue.
|
||||
(server) _Tt_s_procid::signal_new_message - signal a procid that it has
|
||||
a new message.
|
||||
(client) _Tt_c_procid::next_message - get next message from ttsession
|
||||
(server) _Tt_s_procid::next_message - return next message from ttsession
|
||||
|
||||
|
||||
- DISPATCHING AND DELIVERING A MESSAGE
|
||||
|
||||
(server) _Tt_s_message::dispatch
|
||||
(server) _Tt_s_message::deliver
|
||||
|
||||
|
||||
|
||||
- STARTING A NEW PTYPE
|
||||
|
||||
(server) _Tt_s_message::handle_no_recipients
|
||||
(server) _Tt_s_message::change_state
|
||||
(server) _Tt_ptype::start
|
||||
|
||||
|
||||
- PROCESSING THE REPLY TO A MESSAGE
|
||||
|
||||
(client) _Tt_c_procid::update_msg
|
||||
(server) _Tt_s_procid::update_msg
|
||||
(server) _Tt_message::update_msg
|
||||
(server) _Tt_s_message::change_state
|
||||
|
||||
|
||||
- HONORING START AND QUEUE RELIABILITY OPTIONS
|
||||
|
||||
_Tt_s_message::deliver
|
||||
_Tt_s_message::handle_no_recipients
|
||||
|
||||
For file-scope messages, queueing is actually handled on the client
|
||||
side. For more details look in:
|
||||
|
||||
_Tt_c_message::c_dispatch
|
||||
_Tt_file::q_message
|
||||
_Tt_file::dq_message
|
||||
_Tt_file::c_join
|
||||
|
||||
|
||||
- READING IN CLASSING ENGINE DATABASES
|
||||
|
||||
_Tt_typedb::init_ce
|
||||
|
||||
- ADDING/MERGING NEW TYPES TO A TYPE DATABASE
|
||||
|
||||
_Tt_typedb::begin_write
|
||||
_Tt_typedb::end_write
|
||||
_Tt_typedb::insert_ptype
|
||||
_Tt_typedb::insert_otype
|
||||
|
||||
|
||||
- DECLARING A PTYPE
|
||||
|
||||
_tt_rpc_declare_ptype
|
||||
_Tt_s_procid::declare_ptype
|
||||
|
||||
|
||||
- DETECTING PTYPE LAUNCH FAILURE
|
||||
|
||||
sig_handler (in tt/bin/ttsession/mp_server.C)
|
||||
notify_launch_failure (in tt/bin/ttsession/mp_server.C)
|
||||
_Tt_ptype::launch_failed
|
||||
|
||||
|
||||
- AUTO-STARTING A SESSION
|
||||
|
||||
tt_open (tt/lib/api/c/api_mp.C)
|
||||
_Tt_mp::init
|
||||
_Tt_session::init
|
||||
_Tt_session::c_init
|
||||
|
||||
|
||||
- ESTABLISHING RPC CONNECTION TO THE SERVER
|
||||
|
||||
_Tt_session::client_session_init - client-side processing
|
||||
_Tt_s_mp::main_loop - unix and network rpc connection
|
||||
_Tt_session::u_rpc_init - unix socket rpc connection
|
||||
|
||||
|
||||
- XDR/RPC VERSIONING SCHEME
|
||||
|
||||
_tt_service_rpc (tt/lib/mp/mp_rpc_implement.C)
|
||||
_Tt_xdr_version (tt/lib/util/tt_xdr_version)
|
||||
_Tt_global::set_xdr_version (tt/lib/util/tt_global_env.C)
|
||||
_Tt_global::xdr_version (tt/lib/util/tt_global_env.C)
|
||||
|
||||
|
||||
- TRACE/DEBUG/ERROR OUTPUT
|
||||
|
||||
For trace output in ttsession and in slib, use the _Tt_trace
|
||||
class.
|
||||
|
||||
For debug output in the old dm code, do it according to the
|
||||
$TT_DM_DEBUG level. No other module has a similar debug output
|
||||
facility.
|
||||
|
||||
When an error is detected in the client library and a Tt_status
|
||||
other than TT_ERR_INTERNAL is going to be passed up through
|
||||
the API to diagnose it, then the client library should not
|
||||
emit any message anywhere. That's the job of the application using
|
||||
libtt.
|
||||
|
||||
_tt_syslog( 0, LOG_ERR, ) should be used in the client library when:
|
||||
- a TT_ERR_INTERNAL (bug) arises and we want to diagnose what happened;
|
||||
- a partial failure of an API call occurs, but the API call is still
|
||||
considered to have succeeded. For example, when tt_message_send()
|
||||
for a file-scoped message cannot contact one of the interested
|
||||
sessions.
|
||||
|
||||
The daemons (ttsession and dbserver) should pass either 0 or stderr
|
||||
to _tt_syslog(), depending on whether they are in daemon mode or not.
|
||||
|
||||
In CDE, certain parts (tt_type_comp, ttrm et al.) of ToolTalk are
|
||||
likely to be run from tools that have stderr aimed at /dev/null.
|
||||
These parts of ToolTalk should never write to stderr directly, nor
|
||||
call perror(), nc_perror(), t_error(), etc. Instead, they should pass
|
||||
stderr to _tt_syslog(), and use strerror() (or %m), nc_strerror(),
|
||||
t_strerror(), etc. _tt_syslog() will prefix, route, suppress, and
|
||||
multiplex the output appropriately. For example, in CDE we will
|
||||
probably multiplex our error output onto ~/.dt/errorlog. For
|
||||
suppression, _tt_syslog() obeys _tt_global->silent.
|
||||
|
||||
No output should include un-internationalized English. The output
|
||||
should include only ToolTalk-ese and catgets() strings. (ToolTalk-ese
|
||||
can be C/C++ use of the ToolTalk API, or the ToolTalk types language.)
|
||||
All modules that call catgets() should include "util/tt_gettext.h", so
|
||||
that they are really calling _tt_catgets() instead of the one in
|
||||
/usr/lib. This lets us map catgets() to something else on platforms
|
||||
where it is not supported.
|
||||
|
||||
It is OK to write normal output to stdout.
|
||||
|
||||
ASSIGNING NEW CATGETS MESSAGE IDS
|
||||
|
||||
When you code up a new call to catgets(), choose your message set out
|
||||
of util/tt_gettext.h, and use -1 as the message id. Then follow this
|
||||
procedure to update the message catalog:
|
||||
|
||||
0. Make sure your source file(s) is(are) checked in; ttgenmsg will
|
||||
refuse to work on checked-out files.
|
||||
0a. Make sure /home/tooltalk/tools/bin is in your PATH
|
||||
1. Check out SUNW_TOOLTALK.msg and SUNW_TOOLTALK.sets
|
||||
2. Run "make msgs" from the top of the tree.
|
||||
2a. Run msgfix which will sort and clean up "msgs" into "msgs.fixed"
|
||||
3. Check in SUNW_TOOLTALK.sets (which now has been updated).
|
||||
4. Copy "msgs.fixed" to SUNW_TOOLTALK.msg and check it in.
|
||||
5. Check in your updated source files.
|
||||
|
||||
Note to source customers: ttgenmsg depends on genmsg, an internal
|
||||
SunSoft tool, and so ttgenmsg is not included in the ToolTalk source
|
||||
distribution. If you add any new catgets() messages, you will have to
|
||||
manually assign message ids and update the message catalog.
|
||||
|
||||
Note to ToolTalk developers: ttgenmsg and genmsg are in
|
||||
/home/tooltalk/tools/bin.
|
||||
|
||||
THREADING ISSUES
|
||||
|
||||
- Locking granularity:
|
||||
ToolTalk API calls acquire a global lock which they hold as long
|
||||
as they are doing operations that can't block. The original
|
||||
intention was to drop the locks around RPC calls and re-acquire
|
||||
them immediately after returning from such calls. This proved to
|
||||
be unworkable because it resulted in crashes in the RPC library.
|
||||
As of the time of this writing, locks are held around RPC calls,
|
||||
which introduces the danger of a blocking call causing a deadlock
|
||||
in the entire TT library, since only one thread is actually
|
||||
manipulating TT structures at any particular time in a process.
|
||||
|
||||
- ttsession threading
|
||||
Currently ttsession only uses a thread for registering as a client
|
||||
of itself. This is an atomic operation and its success or failure
|
||||
doesn't have a significant effect on ttsession's ability to serve
|
||||
client processes. ttsession tracing won't work until the
|
||||
thread completes successfully.
|
||||
|
||||
- ALL thread-specific storage should be from malloc calls, NEVER local
|
||||
storage. Also, all storage obtained from tt_malloc-type calls is
|
||||
thread-specific.
|
||||
|
||||
- Calling tt_message_receive and receiving the same message simultaneously
|
||||
in different threads causes the message object to be updated from under
|
||||
the calling code. This happens, for instance, when one thread has a
|
||||
handle pattern registered and another has an observe pattern registered,
|
||||
and they both match the same message. The biggest danger here is
|
||||
if one thread deletes a message while another thread is accessing
|
||||
data from the message. It is up to the client program to regulate
|
||||
access to TT message data.
|
||||
1474
cde/lib/tt/SUNW_TOOLTALK.msg
Normal file
1474
cde/lib/tt/SUNW_TOOLTALK.msg
Normal file
File diff suppressed because it is too large
Load Diff
11
cde/lib/tt/SUNW_TOOLTALK.sets
Normal file
11
cde/lib/tt/SUNW_TOOLTALK.sets
Normal file
@@ -0,0 +1,11 @@
|
||||
1 29
|
||||
2 36
|
||||
3 20
|
||||
4 40
|
||||
5 7
|
||||
6 26
|
||||
7 11
|
||||
8 14
|
||||
9 3
|
||||
10 903
|
||||
11 55
|
||||
10
cde/lib/tt/bin/Imakefile
Normal file
10
cde/lib/tt/bin/Imakefile
Normal file
@@ -0,0 +1,10 @@
|
||||
XCOMM $TOG: Imakefile /main/8 1999/08/30 14:33:22 mgreess $
|
||||
#define IHaveSubdirs
|
||||
#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CXXDEBUGFLAGS=$(CXXDEBUGFLAGS)'
|
||||
|
||||
SUBDIRS = dbck shell scripts tt_type_comp \
|
||||
ttauth ttdbserverd ttsession tttar tttrace
|
||||
|
||||
MakeSubdirs($(SUBDIRS))
|
||||
DependSubdirs($(SUBDIRS))
|
||||
LintSubdirs($(SUBDIRS))
|
||||
38
cde/lib/tt/bin/dbck/Imakefile
Normal file
38
cde/lib/tt/bin/dbck/Imakefile
Normal file
@@ -0,0 +1,38 @@
|
||||
XCOMM $XConsortium: Imakefile /main/14 1996/05/08 09:27:35 drk $
|
||||
|
||||
#define CplusplusSource YES
|
||||
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
|
||||
EXTRA_LOAD_FLAGS = ExtraLoadFlags $(UNSHARED_CXXLIB)
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#include "../../tooltalk.tmpl"
|
||||
|
||||
DEFINES =
|
||||
INCLUDES = -I. -I../../slib -I../../lib -I../../mini_isam
|
||||
|
||||
DEPLIBS = ../../slib/libstt.a TtClientDepLibs ../../mini_isam/libisam.a
|
||||
LOCAL_LIBRARIES = ../../slib/libstt.a TtClientLibs ../../mini_isam/libisam.a
|
||||
SYS_LIBRARIES =
|
||||
|
||||
#ifdef TtClientExtraLibs
|
||||
EXTRA_LIBRARIES = TtClientExtraLibs
|
||||
#endif
|
||||
|
||||
|
||||
SRCS = binkey.C binkey_utils.C common.C \
|
||||
options.C options_tt.C prop.C \
|
||||
prop_utils.C spec.C spec_repair.C \
|
||||
spec_utils.C ttdbck.C
|
||||
|
||||
OBJS = binkey.o binkey_utils.o common.o \
|
||||
options.o options_tt.o prop.o \
|
||||
prop_utils.o spec.o spec_repair.o \
|
||||
spec_utils.o ttdbck.o
|
||||
|
||||
|
||||
NormalCplusplusObjectRule()
|
||||
|
||||
ComplexCplusplusProgramTarget(ttdbck)
|
||||
|
||||
SpecialCplusplusObjectRule(options,options,$(TT_VERSION_DEFINE))
|
||||
11
cde/lib/tt/bin/dbck/admindefines
Normal file
11
cde/lib/tt/bin/dbck/admindefines
Normal file
@@ -0,0 +1,11 @@
|
||||
XCOMM $XConsortium: admindefines /main/2 1996/05/07 19:15:52 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
|
||||
110
cde/lib/tt/bin/dbck/binkey.C
Normal file
110
cde/lib/tt/bin/dbck/binkey.C
Normal file
@@ -0,0 +1,110 @@
|
||||
//%% (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: binkey.C /main/3 1995/10/20 16:24:54 rswiston $
|
||||
/*
|
||||
*
|
||||
* binkey.cc
|
||||
*
|
||||
* Copyright (c) 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "util/tt_string.h"
|
||||
#include "db/tt_db_key_utils.h"
|
||||
#include "binkey.h"
|
||||
#include <memory.h>
|
||||
|
||||
static unsigned char sixteen_zeroes[OID_KEY_LENGTH] = {
|
||||
0,0,0,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0};
|
||||
static unsigned char sixteen_foxes[OID_KEY_LENGTH] = {
|
||||
255,255,255,255,
|
||||
255,255,255,255,
|
||||
255,255,255,255,
|
||||
255,255,255,255};
|
||||
|
||||
Binkey Binkey::smallest(sixteen_zeroes);
|
||||
Binkey Binkey::largest(sixteen_foxes);
|
||||
|
||||
static int binkey_compare(const unsigned char *a, const unsigned char *b);
|
||||
|
||||
Binkey::
|
||||
Binkey()
|
||||
{
|
||||
memset((char *)_binkey, 0, sizeof(_binkey));
|
||||
_key = (_Tt_db_key *)0;
|
||||
}
|
||||
|
||||
Binkey::
|
||||
Binkey(const unsigned char *k)
|
||||
{
|
||||
_Tt_string bks(k, sizeof(_binkey));
|
||||
memcpy((char *)_binkey, k, sizeof(_binkey));
|
||||
_key = new _Tt_db_key(bks);
|
||||
}
|
||||
|
||||
Binkey & Binkey::
|
||||
operator=(const Binkey &k)
|
||||
{
|
||||
memcpy((char *)_binkey, (char *)k._binkey, sizeof(_binkey));
|
||||
_key = new _Tt_db_key(k);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Binkey & Binkey::
|
||||
operator=(const unsigned char *k)
|
||||
{
|
||||
_Tt_string bks(k, sizeof(_binkey));
|
||||
memcpy((char *)_binkey, k, sizeof(_binkey));
|
||||
_key = new _Tt_db_key(bks);
|
||||
return *this;
|
||||
}
|
||||
|
||||
int
|
||||
operator==(const Binkey &a, const _Tt_db_key &b)
|
||||
{
|
||||
return b==*a._key;
|
||||
}
|
||||
|
||||
int
|
||||
operator==(const Binkey &a, const Binkey &b)
|
||||
{
|
||||
return binkey_compare(a._binkey,b._binkey)==0;
|
||||
}
|
||||
int
|
||||
operator<(const Binkey &a, const Binkey &b)
|
||||
{
|
||||
return binkey_compare(a._binkey,b._binkey)<0;
|
||||
}
|
||||
int
|
||||
operator>(const Binkey &a, const Binkey &b)
|
||||
{
|
||||
return binkey_compare(a._binkey,b._binkey)>0;
|
||||
}
|
||||
|
||||
static int
|
||||
binkey_compare(const unsigned char *pa, const unsigned char *pb)
|
||||
{
|
||||
// No libc routines seem to guarantee to handle unsigned chars!
|
||||
int i = OID_KEY_LENGTH;
|
||||
while (i--) {
|
||||
if (*pa>*pb) return 1;
|
||||
if (*pa++<*pb++) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Binkey::
|
||||
print(FILE* f) const
|
||||
{
|
||||
if (_key.is_null()) {
|
||||
fprintf(f,"(null key)");
|
||||
} else {
|
||||
_key->print(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
59
cde/lib/tt/bin/dbck/binkey.h
Normal file
59
cde/lib/tt/bin/dbck/binkey.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*%% (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: binkey.h /main/3 1995/10/20 16:25:01 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* binkey.h
|
||||
*
|
||||
* Simple class for manipulating 16-byte keys.
|
||||
* This class simply encapsulates the storage and (lexical) comparison
|
||||
* of 16-byte binary keys. Generally, _Tt_db_key is the class to
|
||||
* use to hold and manipulate keys; only code which depends on the
|
||||
* lexical ordering of keys (which should only be the inspect-and-
|
||||
* repair tools) should use this class.
|
||||
*
|
||||
* Copyright (c) 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _BINKEY_H
|
||||
#define _BINKEY_H
|
||||
|
||||
#include "tt_const.h"
|
||||
#include "util/tt_object.h"
|
||||
#include "util/tt_string.h"
|
||||
#include "db/tt_db_key.h"
|
||||
#include "db/tt_db_key_utils.h"
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
|
||||
class Binkey : public _Tt_object {
|
||||
private:
|
||||
unsigned char _binkey[OID_KEY_LENGTH];
|
||||
_Tt_db_key_ptr _key;
|
||||
public:
|
||||
static Binkey smallest;
|
||||
static Binkey largest;
|
||||
Binkey();
|
||||
Binkey(const unsigned char *);
|
||||
~Binkey() {};
|
||||
operator _Tt_string() const {return _key->string();};
|
||||
operator char*() const {return (char *)_binkey;};
|
||||
_Tt_db_key_ptr key() const {return _key;};
|
||||
friend int operator==(const Binkey &a, const Binkey &b);
|
||||
friend int operator!=(const Binkey &a, const Binkey &b) {
|
||||
return !(a==b);};
|
||||
friend int operator==(const Binkey &a, const _Tt_db_key &b);
|
||||
friend int operator!=(const Binkey &a, const _Tt_db_key &b) {
|
||||
return !(a==b);};
|
||||
friend int operator<(const Binkey &a, const Binkey &b);
|
||||
friend int operator>(const Binkey &a, const Binkey &b);
|
||||
Binkey &operator=(const Binkey &k);
|
||||
Binkey &operator=(const unsigned char *);
|
||||
virtual void print(FILE *f = stdout) const;
|
||||
};
|
||||
|
||||
declare_list_of(Binkey)
|
||||
|
||||
#endif /* _BINKEY_H */
|
||||
15
cde/lib/tt/bin/dbck/binkey_utils.C
Normal file
15
cde/lib/tt/bin/dbck/binkey_utils.C
Normal file
@@ -0,0 +1,15 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: binkey_utils.C /main/3 1995/10/20 16:25:10 rswiston $
|
||||
/*
|
||||
*
|
||||
* binkey_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "binkey.h"
|
||||
|
||||
implement_list_of(Binkey)
|
||||
50
cde/lib/tt/bin/dbck/common.C
Normal file
50
cde/lib/tt/bin/dbck/common.C
Normal file
@@ -0,0 +1,50 @@
|
||||
//%% (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: common.C /main/3 1995/10/20 16:25:17 rswiston $
|
||||
/*
|
||||
*
|
||||
* common.cc
|
||||
*
|
||||
* Some utility routines common to all inspect-and-repair tools (but
|
||||
* not part of any class.)
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "dbck.h"
|
||||
|
||||
static int
|
||||
do_a_directory(_Tt_string path, int (*fn)(_Tt_string))
|
||||
{
|
||||
_Tt_string suffix("TT_DB/");
|
||||
|
||||
if (path.right(1)!="/") {
|
||||
path = path.cat("/");
|
||||
}
|
||||
|
||||
if (path.right(suffix.len())!=suffix) {
|
||||
path = path.cat(suffix);
|
||||
}
|
||||
|
||||
return (*fn)(path);
|
||||
}
|
||||
|
||||
int
|
||||
do_directories(const _Tt_string_list_ptr &dirs, int (*fn)(_Tt_string))
|
||||
{
|
||||
int failcount = 0;
|
||||
_Tt_string_list_cursor c(dirs);
|
||||
|
||||
if (dirs->is_empty()) {
|
||||
failcount = !do_a_directory(".",fn);
|
||||
} else {
|
||||
while(c.next()) {
|
||||
failcount += !do_a_directory(*c,fn);
|
||||
}
|
||||
}
|
||||
return failcount;
|
||||
}
|
||||
|
||||
|
||||
30
cde/lib/tt/bin/dbck/dbck.h
Normal file
30
cde/lib/tt/bin/dbck/dbck.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*%% (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: dbck.h /main/3 1995/10/20 16:25:24 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* dbck.h
|
||||
*
|
||||
* standard/global defines common to all inspect and repair tools
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#ifndef _DBCK_H
|
||||
#define _DBCK_H
|
||||
#include "options.h"
|
||||
|
||||
extern char *progname; // from argv[0]
|
||||
extern FILE *tstream; // for calling print() methods in dbx
|
||||
|
||||
extern int do_directories(const _Tt_string_list_ptr &dirs,
|
||||
int (*fn)(_Tt_string));
|
||||
|
||||
#if !defined(_TT_NODEBUG)
|
||||
#define DBCK_DEBUG(n) (opts->debug_level()>=(n))
|
||||
#else
|
||||
#define DBCK_DEBUG(n) 0
|
||||
#endif
|
||||
|
||||
#endif /* _DBCK_H */
|
||||
183
cde/lib/tt/bin/dbck/options.C
Normal file
183
cde/lib/tt/bin/dbck/options.C
Normal file
@@ -0,0 +1,183 @@
|
||||
//%% (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: options.C /main/4 1998/03/20 14:26:44 mgreess $
|
||||
/*
|
||||
*
|
||||
* options.cc
|
||||
*
|
||||
* Common option handling routines
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "util/copyright.h"
|
||||
#if defined(linux) || defined(sgi)
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include "dbck.h"
|
||||
#include "options.h"
|
||||
#include "util/tt_iostream.h"
|
||||
#include "util/tt_gettext.h"
|
||||
|
||||
Dbck_options::
|
||||
Dbck_options()
|
||||
{
|
||||
_dbdirectories = new _Tt_string_list;
|
||||
_sel_filename_p = 0;
|
||||
_sel_filename = (char *) 0;
|
||||
_sel_objid_p = 0;
|
||||
_sel_objid_key = (_Tt_db_key *) 0;
|
||||
_sel_type_p = 0;
|
||||
_sel_type = (char *) 0;
|
||||
_diag_badform_p = 0;
|
||||
_diag_exist_p = 0;
|
||||
_disp_id_p = 0;
|
||||
_disp_mand_p = 0;
|
||||
_disp_prop_p = 0;
|
||||
_repair_netisam_p = 0;
|
||||
_repair_type_p = 0;
|
||||
_repair_type = (char *) 0;
|
||||
_repair_delete_p = 0;
|
||||
_debug_level = 0;
|
||||
}
|
||||
|
||||
int Dbck_options::
|
||||
set_opts(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
char *opts = optstring();
|
||||
|
||||
while (-1 != (c = getopt(argc,(char **)argv,opts))) {
|
||||
if (!set_option(c, optarg)) {
|
||||
//print help
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
_dbdirectories = new _Tt_string_list;
|
||||
for (; optind<argc; ++optind) {
|
||||
_Tt_string s(argv[optind]);
|
||||
_dbdirectories->append(s);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int Dbck_options::
|
||||
set_common_option(int optchar, const char *optval)
|
||||
{
|
||||
switch (optchar) {
|
||||
case '?':
|
||||
case 'h': // treat h as illegal, forces Usage: msg
|
||||
return 0;
|
||||
case 'v':
|
||||
_TT_PRINT_VERSIONS(progname)
|
||||
exit(0);
|
||||
case 'd':
|
||||
_debug_level = atoi(optval);
|
||||
break;
|
||||
case 'f':
|
||||
_sel_filename_p = 1;
|
||||
_sel_filename = optval;
|
||||
break;
|
||||
case 'k':
|
||||
_sel_objid_p = 1;
|
||||
_sel_objid_key = new _Tt_db_key(_Tt_string(optval));
|
||||
break;
|
||||
case 't':
|
||||
_sel_type_p = 1;
|
||||
_sel_type = optval;
|
||||
break;
|
||||
case 'b':
|
||||
_diag_badform_p = 1;
|
||||
break;
|
||||
case 'x':
|
||||
_diag_exist_p = 1;
|
||||
break;
|
||||
case 'i':
|
||||
_disp_id_p = 1;
|
||||
break;
|
||||
case 'm':
|
||||
_disp_mand_p = 1;
|
||||
break;
|
||||
case 'p':
|
||||
_disp_prop_p = 1;
|
||||
break;
|
||||
case 'I':
|
||||
_repair_netisam_p = 1;
|
||||
break;
|
||||
case 'T':
|
||||
_repair_type_p = 1;
|
||||
_repair_type = optval;
|
||||
break;
|
||||
case 'Z':
|
||||
_repair_delete_p = 1;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Dbck_options::
|
||||
print(FILE *f) const
|
||||
{
|
||||
fprintf(f,"%s <\n",type_string());
|
||||
fprintf(f,"\nDirectories:\n");
|
||||
dbdirectories()->print(_tt_string_print,f);
|
||||
fprintf(f,"\n");
|
||||
|
||||
if (_sel_filename_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 7, "Select by filename: %s\n"),
|
||||
(char *)_sel_filename);
|
||||
}
|
||||
if (_sel_objid_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 8, "Select by objid key:"));
|
||||
_sel_objid_key->print(f);
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
if (_sel_type_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 9, "Select by type: %s\n"),
|
||||
(char *)_sel_type);
|
||||
}
|
||||
if (_diag_badform_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 10,
|
||||
"Diagnose badly formed entities\n"));
|
||||
}
|
||||
if (_diag_exist_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 11, "Diagnose references to "
|
||||
"non-existent entities\n"));
|
||||
}
|
||||
if (_disp_id_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 12, "Display ids\n"));
|
||||
}
|
||||
if (_disp_mand_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 13, "Display mandatory data\n"));
|
||||
}
|
||||
if (_disp_prop_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 14,
|
||||
"Display properties and values data\n"));
|
||||
}
|
||||
if (_repair_netisam_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 15,
|
||||
"Invoke NetISAM isrepair() function before "
|
||||
"inspecting\n"));
|
||||
}
|
||||
if (_repair_type_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 16,
|
||||
"Repair by setting to type: %s\n"),
|
||||
(char *)_repair_type);
|
||||
}
|
||||
if (_repair_delete_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 17, "Repair by deleting\n"));
|
||||
}
|
||||
fprintf(f,catgets(_ttcatd, 6, 18, "Debugging printout level %d\n"),
|
||||
_debug_level);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
118
cde/lib/tt/bin/dbck/options.h
Normal file
118
cde/lib/tt/bin/dbck/options.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: options.h /main/3 1995/10/20 16:25:40 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* options.h
|
||||
*
|
||||
* Class definitions for classes to parse and hold options from
|
||||
* the command lines.
|
||||
*
|
||||
* Part of the ToolTalk/Link Service data base inspect and repair tool.
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _OPTIONS_H
|
||||
#define _OPTIONS_H
|
||||
#include "util/tt_string.h"
|
||||
#include "binkey.h"
|
||||
|
||||
// Options common to both ttdbck and lsdbck
|
||||
|
||||
class Dbck_options : public _Tt_object {
|
||||
|
||||
public:
|
||||
Dbck_options();
|
||||
int set_opts(int argc, char **argv);
|
||||
|
||||
const _Tt_string_list_ptr &dbdirectories() const {
|
||||
return _dbdirectories;};
|
||||
|
||||
// Selection options
|
||||
|
||||
virtual int selecting_p() const{
|
||||
return _sel_filename_p | _sel_objid_p | _sel_type_p;
|
||||
}
|
||||
int sel_filename_p()const{return _sel_filename_p;};
|
||||
const _Tt_string &sel_filename() const{return _sel_filename;};
|
||||
int sel_objid_p() const{return _sel_objid_p;};
|
||||
_Tt_db_key_ptr sel_objid_key() const{return _sel_objid_key;};
|
||||
int sel_type_p() const{return _sel_type_p;};
|
||||
const _Tt_string &sel_type() const{return _sel_type;};
|
||||
|
||||
// Diagnosis options
|
||||
|
||||
virtual int diagnosing_p() const{
|
||||
return _diag_badform_p | _diag_exist_p;
|
||||
};
|
||||
int diag_badform_p()const{return _diag_badform_p;};
|
||||
int diag_exist_p() {return _diag_exist_p;};
|
||||
|
||||
// Display options
|
||||
|
||||
virtual int displaying_p() const{
|
||||
return _disp_id_p | _disp_mand_p | _disp_prop_p;
|
||||
};
|
||||
int disp_id_p() const{return _disp_id_p;};
|
||||
int disp_mand_p() const{return _disp_mand_p;};
|
||||
int disp_prop_p() const{return _disp_prop_p;};
|
||||
|
||||
// Repair options
|
||||
|
||||
// Note repair_netisam_p is not included in repairing_p since
|
||||
// netisam repair occurs *before* inspection, instead of after.
|
||||
|
||||
virtual int repairing_p() const{
|
||||
return _repair_type_p | _repair_delete_p;
|
||||
};
|
||||
int repair_netisam_p() const{return _repair_netisam_p;};
|
||||
int repair_type_p() const{return _repair_type_p;};
|
||||
const _Tt_string &repair_type() const{return _repair_type;};
|
||||
int repair_delete_p() const{return _repair_delete_p;};
|
||||
int debug_level() const{return _debug_level;};
|
||||
|
||||
virtual char * type_string() const {
|
||||
return "Dbck_options";
|
||||
};
|
||||
virtual void print(FILE *f = stdout) const;
|
||||
|
||||
protected:
|
||||
_Tt_string_list_ptr _dbdirectories;
|
||||
|
||||
// Selection options
|
||||
|
||||
int _sel_filename_p;
|
||||
_Tt_string _sel_filename; // shell wildcard pattern
|
||||
int _sel_objid_p;
|
||||
_Tt_db_key_ptr _sel_objid_key;
|
||||
int _sel_type_p;
|
||||
_Tt_string _sel_type; // shell wildcard pattern
|
||||
|
||||
// Diagnosis options
|
||||
|
||||
int _diag_badform_p;
|
||||
int _diag_exist_p;
|
||||
|
||||
// Display options
|
||||
|
||||
int _disp_id_p;
|
||||
int _disp_mand_p;
|
||||
int _disp_prop_p;
|
||||
|
||||
// Repair options
|
||||
|
||||
int _repair_netisam_p;
|
||||
int _repair_type_p;
|
||||
_Tt_string _repair_type;
|
||||
int _repair_delete_p;
|
||||
|
||||
int _debug_level;
|
||||
virtual char * optstring()=0;
|
||||
virtual int set_option(int optchar, const char *optval)=0;
|
||||
int set_common_option(int optchar,
|
||||
const char *optval);
|
||||
};
|
||||
#endif
|
||||
66
cde/lib/tt/bin/dbck/options_tt.C
Normal file
66
cde/lib/tt/bin/dbck/options_tt.C
Normal file
@@ -0,0 +1,66 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: options_tt.C /main/3 1995/10/20 16:25:48 rswiston $
|
||||
/*
|
||||
*
|
||||
* options_tt.cc
|
||||
*
|
||||
* ttdbck option handling routines
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "dbck.h"
|
||||
#include "options_tt.h"
|
||||
#include "util/tt_gettext.h"
|
||||
|
||||
Dbck_specoptions::
|
||||
Dbck_specoptions()
|
||||
{
|
||||
_repair_filename_p = 0;
|
||||
_repair_filename = (char *)0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the getopt valid-options string
|
||||
*/
|
||||
char * Dbck_specoptions::
|
||||
optstring()
|
||||
{
|
||||
return "vhf:k:t:bximpaIF:T:Zd:";
|
||||
}
|
||||
|
||||
int Dbck_specoptions::
|
||||
set_option(int optchar, const char *optval)
|
||||
{
|
||||
switch (optchar) {
|
||||
case 'a':
|
||||
_disp_id_p = _disp_mand_p = _disp_prop_p = 1;
|
||||
break;
|
||||
case 'F':
|
||||
_repair_filename_p = 1;
|
||||
_repair_filename = optval;
|
||||
break;
|
||||
default:
|
||||
return set_common_option(optchar, optval);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void Dbck_specoptions::
|
||||
print(FILE *f) const
|
||||
{
|
||||
Dbck_options::print(f);
|
||||
if (_repair_filename_p) {
|
||||
fprintf(f,catgets(_ttcatd, 6, 19,
|
||||
"Repair by setting to file: %s\n"),
|
||||
(char *)_repair_filename);
|
||||
}
|
||||
fprintf(f,">\n");
|
||||
}
|
||||
59
cde/lib/tt/bin/dbck/options_tt.h
Normal file
59
cde/lib/tt/bin/dbck/options_tt.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*%% (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: options_tt.h /main/3 1995/10/20 16:25:55 rswiston $ */
|
||||
/* -*-C++-*-
|
||||
*
|
||||
* options_tt.h
|
||||
*
|
||||
* Class definitions for classes to parse and hold options from
|
||||
* the command lines.
|
||||
*
|
||||
* Part of the ToolTalk/Link Service data base inspect and repair tool.
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _OPTIONS_TT_H
|
||||
#define _OPTIONS_TT_H
|
||||
#include "util/tt_string.h"
|
||||
#include "options.h"
|
||||
|
||||
// options unique to ttdbck
|
||||
|
||||
class Dbck_specoptions : public Dbck_options {
|
||||
|
||||
public:
|
||||
Dbck_specoptions();
|
||||
|
||||
// Repair options
|
||||
|
||||
virtual int repairing_p() const{
|
||||
return Dbck_options::repairing_p() |
|
||||
_repair_filename_p;
|
||||
};
|
||||
int repair_filename_p() const{
|
||||
return _repair_filename_p;
|
||||
};
|
||||
const _Tt_string &repair_filename() const{
|
||||
return _repair_filename;
|
||||
};
|
||||
|
||||
virtual char * type_string() const{
|
||||
return "Dbck_specoptions";
|
||||
};
|
||||
virtual void print(FILE *f = stdout) const;
|
||||
|
||||
protected:
|
||||
|
||||
// Repair options
|
||||
|
||||
int _repair_filename_p;
|
||||
_Tt_string _repair_filename;
|
||||
|
||||
virtual char * optstring();
|
||||
virtual int set_option(int optchar, const char *optval);
|
||||
};
|
||||
|
||||
#endif
|
||||
47
cde/lib/tt/bin/dbck/prop.C
Normal file
47
cde/lib/tt/bin/dbck/prop.C
Normal file
@@ -0,0 +1,47 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: prop.C /main/3 1995/10/20 16:26:03 rswiston $
|
||||
/*
|
||||
*
|
||||
* prop.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#if defined(ultrix)
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include "prop.h"
|
||||
#include "ttdbck.h"
|
||||
|
||||
// A Prop just holds the name and its list of values.
|
||||
// We probably have 600 classes that do this by now.
|
||||
|
||||
Prop::
|
||||
Prop(_Tt_string propname)
|
||||
{
|
||||
_name = propname;
|
||||
_values = new _Tt_string_list();
|
||||
}
|
||||
|
||||
void Prop::
|
||||
print(FILE *f) const
|
||||
{
|
||||
fprintf(f,"Prop<");
|
||||
_name->print(f);
|
||||
fprintf(f,"=<");
|
||||
_values->print(_tt_string_print,f);
|
||||
fprintf(f,">>\n");
|
||||
}
|
||||
|
||||
_Tt_string
|
||||
_tt_prop_name(_Tt_object_ptr &o)
|
||||
{
|
||||
return(((Prop *)o.c_pointer())->name());
|
||||
}
|
||||
47
cde/lib/tt/bin/dbck/prop.h
Normal file
47
cde/lib/tt/bin/dbck/prop.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: prop.h /main/3 1995/10/20 16:26:11 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* prop.h
|
||||
*
|
||||
* Part of the inspect&repair tools.
|
||||
*
|
||||
* accumulates, prints, rewrites(?) data for a spec or link.
|
||||
* This is for the sole use of dbck, so much less information
|
||||
* hiding is done than the usual TT class definition style:
|
||||
* in particular, data members are simply made public,
|
||||
* instead of defining access functions.
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _PROP_H
|
||||
#define _PROP_H
|
||||
|
||||
#include "util/tt_object.h"
|
||||
#include "util/tt_list.h"
|
||||
#include "util/tt_table.h"
|
||||
#include "util/tt_string.h"
|
||||
|
||||
declare_list_of(Prop)
|
||||
declare_table_of(Prop)
|
||||
|
||||
class Prop : public _Tt_object {
|
||||
public:
|
||||
Prop(){};
|
||||
Prop(_Tt_string propname);
|
||||
~Prop() {};
|
||||
virtual void print(FILE * f) const;
|
||||
_Tt_string &name() { /* key access for table package */
|
||||
return _name;
|
||||
}
|
||||
_Tt_string _name;
|
||||
_Tt_string_list_ptr _values;
|
||||
};
|
||||
|
||||
_Tt_string _tt_prop_name(_Tt_object_ptr &o);
|
||||
|
||||
#endif /* _SPEC_H */
|
||||
18
cde/lib/tt/bin/dbck/prop_utils.C
Normal file
18
cde/lib/tt/bin/dbck/prop_utils.C
Normal file
@@ -0,0 +1,18 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: prop_utils.C /main/3 1995/10/20 16:26:19 rswiston $
|
||||
/*
|
||||
*
|
||||
* prop_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "prop.h"
|
||||
|
||||
implement_list_of(Prop)
|
||||
|
||||
implement_table_of(Prop)
|
||||
|
||||
297
cde/lib/tt/bin/dbck/spec.C
Normal file
297
cde/lib/tt/bin/dbck/spec.C
Normal file
@@ -0,0 +1,297 @@
|
||||
//%% (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: spec.C /main/3 1995/10/20 16:26:34 rswiston $
|
||||
/*
|
||||
*
|
||||
* spec.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(ultrix)
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include "spec.h"
|
||||
#include "options_tt.h"
|
||||
#include "util/tt_gettext.h"
|
||||
#include "ttdbck.h"
|
||||
#include "tt_db_server_consts.h"
|
||||
|
||||
#if !defined(OPT_STRERROR)
|
||||
// No strerror(), fake it
|
||||
char *
|
||||
strerror(int e)
|
||||
{
|
||||
return ((e<sys_nerr) ? sys_errlist[e] : "unknown");
|
||||
}
|
||||
#endif
|
||||
|
||||
Spec::
|
||||
Spec()
|
||||
{
|
||||
key = (Binkey *) 0;
|
||||
filename = "";
|
||||
type = "";
|
||||
is_filespec = 0;
|
||||
props = new Prop_table(_tt_prop_name);
|
||||
propnames = new _Tt_string_list;
|
||||
}
|
||||
|
||||
void Spec::
|
||||
add_prop_and_value(_Tt_string propname, _Tt_string value)
|
||||
{
|
||||
// the reason we need to keep the list of names in
|
||||
// propnames is that we want to preserve the order in
|
||||
// which they were encountered, so that adding them
|
||||
// back in goes smoothly. A tt_table method that
|
||||
// returned a sorted list of keys would be nice, but
|
||||
// right now I don't have time... RFM 1/10/91
|
||||
|
||||
Prop_ptr sp = props->lookup(propname);
|
||||
|
||||
if (sp.is_null()) {
|
||||
sp = new Prop(propname);
|
||||
props->insert(sp);
|
||||
propnames->append(propname);
|
||||
}
|
||||
|
||||
sp->_values->append(value);
|
||||
}
|
||||
|
||||
void Spec::
|
||||
print(FILE *f) const
|
||||
{
|
||||
print_key(f);
|
||||
print_mand(f);
|
||||
print_props(f);
|
||||
}
|
||||
void Spec::
|
||||
print_key(FILE *f) const
|
||||
{
|
||||
fprintf(f,
|
||||
"-----------\n"
|
||||
"objkey: ");
|
||||
key->print(f);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
void Spec::
|
||||
print_mand(FILE *f) const
|
||||
{
|
||||
if (is_filespec) {
|
||||
fprintf(f, "file: %s\n", (char *)filename);
|
||||
} else {
|
||||
fprintf(f,
|
||||
"type: %s\nfile: %s\n",
|
||||
(char *)type, (char *)filename);
|
||||
}
|
||||
}
|
||||
|
||||
void Spec::
|
||||
print_props(FILE *f) const
|
||||
{
|
||||
_Tt_string_list_cursor c;
|
||||
Prop_ptr sp;
|
||||
_Tt_string_list_cursor v;
|
||||
int i;
|
||||
|
||||
c.reset(propnames);
|
||||
while(c.next()) {
|
||||
sp = props->lookup(*c);
|
||||
v.reset(sp->_values);
|
||||
i = 0;
|
||||
while(v.next()) {
|
||||
fprintf(f,
|
||||
"prop %32s[%2d] = ",
|
||||
(char *)sp->_name, i++);
|
||||
v->print(f);
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Called when all info for a spec has been accumulated; see if the
|
||||
// spec is selected under the current selection options, diagnose
|
||||
// according to diagnostic options, print according to printing
|
||||
// options.
|
||||
//
|
||||
void Spec::
|
||||
process_spec()
|
||||
{
|
||||
// Possible things to go wrong. Done as a bitmap not so much
|
||||
// to save space, but to make the determination whether any
|
||||
// bad things were found easy, by seeing if bad_flags is nonzero.
|
||||
|
||||
int bad_flags = 0;
|
||||
const int BAD_NOFILE = 1;
|
||||
const int BAD_NOTYPE = 2;
|
||||
const int BAD_MULTITYPE = 4;
|
||||
const int BAD_FILE_STAT = 8;
|
||||
const int BAD_TYPE = 0x10;
|
||||
const int BAD_TYPED_FILESPEC = 0x20;
|
||||
|
||||
int save_errno = 0;
|
||||
|
||||
Prop_ptr sp;
|
||||
_Tt_otype_ptr ot;
|
||||
_Tt_string_list_ptr type_list;
|
||||
|
||||
// All the props have been accumulated, now we can pick out
|
||||
// the type if it's there.
|
||||
|
||||
sp = props->lookup(_Tt_string(TT_DB_OBJECT_TYPE_PROPERTY));
|
||||
if (!sp.is_null()) {
|
||||
type_list = sp->_values;
|
||||
} else {
|
||||
type_list = new _Tt_string_list;
|
||||
}
|
||||
|
||||
if (type_list->count()==1) {
|
||||
type = type_list->top();
|
||||
} else {
|
||||
type = "";
|
||||
}
|
||||
|
||||
_Tt_string filehostname, filelocalpath;
|
||||
filelocalpath = filename.split(':',filehostname);
|
||||
|
||||
if (opts->selecting_p()) {
|
||||
if (opts->sel_filename_p()) {
|
||||
if (!filelocalpath.sh_match(opts->sel_filename())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->sel_type_p()) {
|
||||
if (!type.sh_match(opts->sel_type())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->sel_objid_p()) {
|
||||
if (*key != *opts->sel_objid_key()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->diagnosing_p()) {
|
||||
if (opts->diag_badform_p()) {
|
||||
if (filename=="") {
|
||||
bad_flags |= BAD_NOFILE;
|
||||
}
|
||||
switch (type_list->count()) {
|
||||
case 0:
|
||||
// It's OK if docoids have no type.
|
||||
if (!is_filespec) {
|
||||
bad_flags |= BAD_NOTYPE;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
ot = (*tdb_ptr)->otable->lookup(type);
|
||||
if (ot.is_null()) {
|
||||
bad_flags |= BAD_TYPE;
|
||||
} else if (is_filespec) {
|
||||
// docoids should not have a type,
|
||||
// it's an error if they do, even
|
||||
// if it's a valid type
|
||||
bad_flags |= BAD_TYPED_FILESPEC;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bad_flags |= BAD_MULTITYPE;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->diag_exist_p() && filename!="") {
|
||||
struct stat statbuf;
|
||||
|
||||
// HACK: ought to check that filehostname is
|
||||
// same as localhost, but that's expensive
|
||||
// due to aliases, possibly domain-qualified
|
||||
// names, etc.
|
||||
if (-1==stat((char *)filelocalpath,&statbuf)) {
|
||||
save_errno = errno;
|
||||
bad_flags |= BAD_FILE_STAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the spec has a forward pointer, then it's OK for
|
||||
// it to be missing information...
|
||||
sp = props->lookup(_Tt_string(TT_DB_FORWARD_POINTER_PROPERTY));
|
||||
if (!sp.is_null()) {
|
||||
bad_flags = 0;
|
||||
}
|
||||
|
||||
// a spec is eligible for display or repair only if it passes all
|
||||
// selection options (if not, we returned earlier) and if either the
|
||||
// spec is bad somehow, or we aren't diagnosing in which case we
|
||||
// always display or repair all selected specs.
|
||||
|
||||
if (bad_flags || !opts->diagnosing_p()) {
|
||||
if (opts->displaying_p() || bad_flags) {
|
||||
print_key(stdout);
|
||||
}
|
||||
|
||||
if (opts->disp_mand_p()) {
|
||||
print_mand(stdout);
|
||||
}
|
||||
|
||||
if (opts->disp_prop_p()) {
|
||||
print_props(stdout);
|
||||
}
|
||||
|
||||
// if we are diagnosing, now is the time to print the
|
||||
// diagnostics. Note that bad_flags will be zero if
|
||||
// we aren't diagnosing, but we still must fall all
|
||||
// way through and put the spec on the repair list.
|
||||
|
||||
if ((bad_flags & BAD_NOFILE)!=0) {
|
||||
printf(catgets(_ttcatd, 6, 20,
|
||||
"Error: no file for spec.\n"));
|
||||
}
|
||||
if ((bad_flags & BAD_NOTYPE)!=0) {
|
||||
printf(catgets(_ttcatd, 6, 21,
|
||||
"Error: no type for spec.\n"));
|
||||
}
|
||||
if ((bad_flags & BAD_TYPE)!=0) {
|
||||
printf(catgets(_ttcatd, 6, 22,"Error: \"%s\" is not "
|
||||
"an installed otype.\n"),
|
||||
type.operator const char *());
|
||||
}
|
||||
if ((bad_flags & BAD_MULTITYPE)!=0) {
|
||||
printf(catgets(_ttcatd, 6, 23,"Error: spec has multiple "
|
||||
"values for type property.\n"));
|
||||
}
|
||||
if ((bad_flags & BAD_FILE_STAT)!=0) {
|
||||
printf(catgets(_ttcatd, 6, 24,"Error: "));
|
||||
printf("%s: %s", (char *)filename, strerror(save_errno));
|
||||
}
|
||||
|
||||
if ((bad_flags & BAD_TYPED_FILESPEC)!=0) {
|
||||
printf(catgets(_ttcatd, 6, 26,"Error: "));
|
||||
printf("%s: internal spec for file has an otype.\n",
|
||||
(char *)filename);
|
||||
}
|
||||
|
||||
// put the spec on the list for later processing, unless
|
||||
// it is a filespec, which cannot be repaired (hope we
|
||||
// never get a bad filespec!)
|
||||
|
||||
if (!is_filespec && opts->repairing_p()) {
|
||||
specs_to_repair->append(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
53
cde/lib/tt/bin/dbck/spec.h
Normal file
53
cde/lib/tt/bin/dbck/spec.h
Normal 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: spec.h /main/3 1995/10/20 16:26:43 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* spec.h
|
||||
*
|
||||
* Part of the spec inspect&repair tool.
|
||||
*
|
||||
* accumulates, prints, rewrites(?) data for a spec.
|
||||
* This is for the sole use of ttdbck, so much less information
|
||||
* hiding is done than the usual TT class definition style:
|
||||
* in particular, data members are simply made public,
|
||||
* instead of defining access functions.
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _SPEC_H
|
||||
#define _SPEC_H
|
||||
|
||||
#include "util/tt_object.h"
|
||||
#include "util/tt_list.h"
|
||||
#include "util/tt_string.h"
|
||||
#include "binkey.h"
|
||||
#include "prop.h"
|
||||
|
||||
declare_list_of(Spec)
|
||||
|
||||
class Spec : public _Tt_object {
|
||||
public:
|
||||
Spec();
|
||||
~Spec() {};
|
||||
Binkey_ptr key;
|
||||
_Tt_string type;
|
||||
_Tt_string filename;
|
||||
int is_filespec;
|
||||
virtual void print(FILE * f) const;
|
||||
void process_spec();
|
||||
void print_key(FILE * f) const;
|
||||
void print_mand(FILE * f) const;
|
||||
void print_props(FILE * f) const;
|
||||
void add_prop_and_value(_Tt_string propname,
|
||||
_Tt_string value);
|
||||
void repair_spec();
|
||||
private:
|
||||
Prop_table_ptr props;
|
||||
_Tt_string_list_ptr propnames;
|
||||
};
|
||||
|
||||
#endif /* _SPEC_H */
|
||||
225
cde/lib/tt/bin/dbck/spec_repair.C
Normal file
225
cde/lib/tt/bin/dbck/spec_repair.C
Normal file
@@ -0,0 +1,225 @@
|
||||
//%% (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: spec_repair.C /main/3 1995/10/20 16:26:51 rswiston $
|
||||
/*
|
||||
*
|
||||
* spec_repair.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#if defined(ultrix)
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if defined(_AIX)
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include "spec.h"
|
||||
#include "options_tt.h"
|
||||
#include "ttdbck.h"
|
||||
#include "db/tt_db_object.h"
|
||||
#include "db/tt_db_object_utils.h"
|
||||
#include "db/tt_db_key.h"
|
||||
#include "db/tt_db_object.h"
|
||||
#include "db/tt_db_results.h"
|
||||
#include "db/tt_db_access.h"
|
||||
#include "tt_db_server_consts.h"
|
||||
|
||||
#define MKERR(msg, err) fprintf(stderr, \
|
||||
"ttdbck: error %s spec: %s\n", \
|
||||
msg, \
|
||||
tt_status_message(err))
|
||||
|
||||
const char* MP_TYPE_PROP = "_NODE_TYPE";
|
||||
|
||||
void Spec::
|
||||
repair_spec()
|
||||
{
|
||||
|
||||
// by this point all the information about the spec is collected
|
||||
// in the Spec instance. We make any requested changes to
|
||||
// the Spec instance, then completely replace the
|
||||
// info on disk with the info from the Spec instance.
|
||||
|
||||
if (opts->repair_type_p()) {
|
||||
type = opts->repair_type();
|
||||
}
|
||||
|
||||
if (opts->repair_filename_p()) {
|
||||
filename = opts->repair_filename();
|
||||
}
|
||||
|
||||
_Tt_db_object_ptr oldobj = new _Tt_db_object();
|
||||
switch(oldobj->getDBResults()) {
|
||||
case TT_DB_OK:
|
||||
break;
|
||||
default:
|
||||
MKERR("creating", TT_ERR_INTERNAL);
|
||||
return;
|
||||
}
|
||||
|
||||
_Tt_string objid = oldobj->create(filename, key->key()->string());
|
||||
switch(oldobj->getDBResults()) {
|
||||
case TT_DB_OK:
|
||||
break;
|
||||
default:
|
||||
MKERR("creating", TT_ERR_INTERNAL);
|
||||
return;
|
||||
}
|
||||
|
||||
_Tt_db_access_ptr access = oldobj->getAccess();
|
||||
switch(oldobj->getDBResults()) {
|
||||
case TT_DB_OK:
|
||||
break;
|
||||
default:
|
||||
MKERR("creating", TT_ERR_INTERNAL);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(oldobj->remove()) {
|
||||
case TT_DB_OK:
|
||||
case TT_DB_ERR_NO_SUCH_OBJECT:
|
||||
case TT_DB_ERR_NO_SUCH_PROPERTY:
|
||||
case TT_DB_WRN_FORWARD_POINTER:
|
||||
break;
|
||||
case TT_DB_ERR_ACCESS_DENIED:
|
||||
MKERR("destroying", TT_ERR_ACCESS);
|
||||
return;
|
||||
default:
|
||||
MKERR("destroying", TT_ERR_DBAVAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (opts->repair_delete_p()) {
|
||||
// don't recreate the spec.
|
||||
} else {
|
||||
|
||||
// Should ensure we are running under a particular namespace
|
||||
// for this? Like an override namespace to force into the
|
||||
// db under repair?
|
||||
|
||||
_Tt_db_object_ptr newobj = new _Tt_db_object();
|
||||
switch(newobj->getDBResults()) {
|
||||
case TT_DB_OK:
|
||||
break;
|
||||
default:
|
||||
MKERR("creating", TT_ERR_INTERNAL);
|
||||
return;
|
||||
}
|
||||
|
||||
_Tt_string newobjid = newobj->create(filename,
|
||||
key->key()->string());
|
||||
switch(newobj->getDBResults()) {
|
||||
case TT_DB_OK:
|
||||
break;
|
||||
default:
|
||||
MKERR("creating", TT_ERR_INTERNAL);
|
||||
return;
|
||||
}
|
||||
|
||||
newobj->setType(type);
|
||||
newobj->setAccess(access);
|
||||
|
||||
// Re-create the properties
|
||||
|
||||
_Tt_string_list_cursor c;
|
||||
Prop_ptr sp;
|
||||
_Tt_string_list_cursor v;
|
||||
_Tt_db_property_ptr dbprop = new _Tt_db_property();
|
||||
uid_t euid;
|
||||
gid_t group;
|
||||
mode_t mode;
|
||||
int owner_written = 0;
|
||||
int group_written = 0;
|
||||
int mode_written = 0;
|
||||
|
||||
c.reset(propnames);
|
||||
while(c.next()) {
|
||||
sp = props->lookup(*c);
|
||||
v.reset(sp->_values);
|
||||
if (!v.next()) {
|
||||
// No values for the property. This is
|
||||
// theoretically impossible -- delete the
|
||||
// property.
|
||||
} else if (sp->_name == TT_DB_OBJECT_TYPE_PROPERTY) {
|
||||
// this is the special prop that holds the
|
||||
// type name. Don't try to set it by that name.
|
||||
} else {
|
||||
|
||||
if (sp->_name ==
|
||||
TT_OBJECT_OWNER_PROPERTY) {
|
||||
|
||||
// This is the special user field
|
||||
// Note that the access info is
|
||||
// already written out above.
|
||||
// Re-write it here anyway, in
|
||||
// case it was corrupt in the
|
||||
// old DB.
|
||||
|
||||
memcpy((char *)&euid,
|
||||
(char *)(*v), sizeof(uid_t));
|
||||
owner_written = 1;
|
||||
}
|
||||
else if (sp->_name ==
|
||||
TT_OBJECT_GROUP_PROPERTY) {
|
||||
|
||||
// This is the special group field
|
||||
// See note for owner field above
|
||||
|
||||
memcpy((char *)&group,
|
||||
(char *)(*v), sizeof(gid_t));
|
||||
group_written = 1;
|
||||
}
|
||||
else if (sp->_name ==
|
||||
TT_OBJECT_MODE_PROPERTY) {
|
||||
|
||||
// This is the special mode field
|
||||
// See note for owner field above
|
||||
|
||||
memcpy((char *)&mode,
|
||||
(char *)(*v), sizeof(mode_t));
|
||||
mode_written = 1;
|
||||
}
|
||||
else {
|
||||
|
||||
// Ordinary property -- create
|
||||
// a new _Tt_db_property record
|
||||
|
||||
dbprop->name = sp->_name;
|
||||
dbprop->values->push(*v);
|
||||
|
||||
while(v.next()) {
|
||||
|
||||
// Add any remaining values
|
||||
|
||||
dbprop->values->push(*v);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
newobj->addProperty(dbprop);
|
||||
}
|
||||
|
||||
if (owner_written && group_written && mode_written) {
|
||||
|
||||
// We have complete access info from the old prop
|
||||
// list, so we may as well use it.
|
||||
|
||||
access->user = euid;
|
||||
access->group = group;
|
||||
access->mode = mode;
|
||||
newobj->setAccess(access);
|
||||
}
|
||||
|
||||
// There\'s not much we can do if this call doesn\'t work
|
||||
|
||||
newobj->write();
|
||||
}
|
||||
}
|
||||
15
cde/lib/tt/bin/dbck/spec_utils.C
Normal file
15
cde/lib/tt/bin/dbck/spec_utils.C
Normal file
@@ -0,0 +1,15 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: spec_utils.C /main/3 1995/10/20 16:27:00 rswiston $
|
||||
/*
|
||||
*
|
||||
* spec_utils.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "spec.h"
|
||||
|
||||
implement_list_of(Spec)
|
||||
615
cde/lib/tt/bin/dbck/ttdbck.C
Normal file
615
cde/lib/tt/bin/dbck/ttdbck.C
Normal file
@@ -0,0 +1,615 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: ttdbck.C /main/3 1995/10/20 16:34:00 rswiston $
|
||||
/*
|
||||
*
|
||||
* ttdbck.cc
|
||||
* @(#)ttdbck.C 1.31 93/09/07
|
||||
*
|
||||
* ToolTalk 1.0 spec data base inspect and repair tool
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <isam.h>
|
||||
#include <locale.h>
|
||||
#include <memory.h>
|
||||
#include "util/tt_port.h"
|
||||
#include "util/tt_gettext.h"
|
||||
#include "util/tt_global_env.h"
|
||||
#include "ttdbck.h"
|
||||
#include "dbck.h"
|
||||
#include "options_tt.h"
|
||||
#include "binkey.h"
|
||||
#include "spec.h"
|
||||
#include "util/copyright.h"
|
||||
#include "dm/dm_recfmts.h"
|
||||
#include "mp/mp_mp.h"
|
||||
#include "mp_s_mp.h"
|
||||
#include "tt_db_server_consts.h"
|
||||
#include "tt_isstrerror.h"
|
||||
|
||||
TT_INSERT_COPYRIGHT
|
||||
|
||||
#ifdef OPT_PATCH
|
||||
static char PatchID[] = "Patch Id: 100626_03.";
|
||||
static int Patch_ID100626_03;
|
||||
#endif
|
||||
|
||||
char *progname; // from argv[0]
|
||||
Dbck_specoptions *opts;
|
||||
_Tt_typedb_ptr *tdb_ptr;
|
||||
FILE *tstream; // for calling print() methods in dbx
|
||||
|
||||
// Global variables controlling state of main merge loop.
|
||||
|
||||
Table_oid_prop oid_prop_record;
|
||||
Table_oid_access oid_access_record;
|
||||
Table_oid_container oid_container_record;
|
||||
Table_docoid_path docoid_path_record;
|
||||
|
||||
struct keydesc docoid_path_keydesc;
|
||||
|
||||
int oid_prop_fd, oid_access_fd, oid_container_fd, docoid_path_fd;
|
||||
|
||||
Binkey this_min_key;
|
||||
Binkey oid_prop_key;
|
||||
Binkey oid_access_key;
|
||||
Binkey oid_container_key;
|
||||
Binkey last_min_key;
|
||||
|
||||
int oid_access_inspected;
|
||||
int oid_container_inspected;
|
||||
|
||||
_Tt_string oid_prop_value;
|
||||
_Tt_string oid_prop_name;
|
||||
|
||||
_Tt_string oid_prop_rootname;
|
||||
_Tt_string oid_access_rootname;
|
||||
_Tt_string oid_container_rootname;
|
||||
_Tt_string docoid_path_rootname;
|
||||
|
||||
Spec_list_ptr specs_to_repair;
|
||||
|
||||
|
||||
// TOC
|
||||
|
||||
int main(int argc, char **argv);
|
||||
int process_directory(_Tt_string dirname);
|
||||
void process_spec(Spec_ptr s);
|
||||
void advance_oid_prop();
|
||||
void advance_oid_container();
|
||||
void advance_oid_access();
|
||||
void closeall();
|
||||
Binkey compute_min_key(Binkey a, Binkey b, Binkey c);
|
||||
void inspect_docoid_path(Spec_ptr p);
|
||||
void pisamerr(const char *func, const char *name);
|
||||
void check_if_file(Spec_ptr p);
|
||||
|
||||
// isam.h does not include function headers at all!!
|
||||
|
||||
extern "C" {
|
||||
int isaddindex(int, struct keydesc*);
|
||||
int isbuild(char*, int, struct keydesc*, int);
|
||||
int isclose(int);
|
||||
int iscntl(int, int, char*);
|
||||
int isdelrec(int, long);
|
||||
int iserase(char*);
|
||||
int isopen(char*, int);
|
||||
int isread(int, char*, int);
|
||||
int isrepair(const char *, int);
|
||||
int isrewrec(int, int, char*);
|
||||
int isstart(int, struct keydesc*, int, char*, int);
|
||||
int iswrite(int, char*);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int status;
|
||||
|
||||
tstream = stderr;
|
||||
opts = new Dbck_specoptions;
|
||||
progname = argv[0];
|
||||
setlocale( LC_ALL, "" );
|
||||
|
||||
if (!opts->set_opts(argc, argv))
|
||||
{
|
||||
fprintf(stderr, catgets(_ttcatd, 6, 2,
|
||||
"Usage:\n"
|
||||
"ttdbck [-f file] [-k objkey] [-t type] [-bx] \n"
|
||||
"[-impa] [-IZ] [-F newfilename] [-T newtype] [mountpoints]\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (DBCK_DEBUG(1)) {
|
||||
opts->print(stderr);
|
||||
}
|
||||
|
||||
if (opts->repairing_p() &&
|
||||
!opts->selecting_p() &&
|
||||
!opts->diagnosing_p()) {
|
||||
fprintf(stderr,
|
||||
catgets(_ttcatd, 6, 3,
|
||||
"ttdbck: you must specify a selection "
|
||||
"[-fkt] option or a diagnosis [-bx] option\n"
|
||||
"if a repair [-FTZ] option is specified\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (opts->diag_badform_p()) {
|
||||
// We have to initialize just enough of the ttsession
|
||||
// server state to make the _Tt_typedb class work.
|
||||
// XXX: really the _Tt_typedb class should be independent
|
||||
// of the server.
|
||||
_tt_global = new _Tt_global;
|
||||
_tt_s_mp = new _Tt_s_mp;
|
||||
_tt_mp = (_Tt_mp *)new _Tt_s_mp;
|
||||
tdb_ptr = new _Tt_typedb_ptr;
|
||||
(*tdb_ptr) = new _Tt_typedb;
|
||||
|
||||
Tt_status err;
|
||||
// Load the xdr types database
|
||||
err = (*tdb_ptr)->init_xdr();
|
||||
if (err == TT_ERR_NO_MATCH) {
|
||||
fprintf(stderr, "ttdbck: %s\n",
|
||||
catgets(_ttcatd, 6, 4,
|
||||
"Version mismatch in compiled types"));
|
||||
exit (1);
|
||||
} else if (err != TT_OK) {
|
||||
fprintf(stderr, "ttdbck: %s\n",
|
||||
catgets(_ttcatd, 6, 5,
|
||||
"Cannot read types in database"));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
status = do_directories(opts->dbdirectories(),process_directory);
|
||||
|
||||
// Normally UNIX programs don't make noise if nothing is wrong, but
|
||||
// in the case of ttdbck it's unlikely the admin running it is
|
||||
// familiar with it, and it's only being run if the database is
|
||||
// suspected of damage already. So we print a reassuring message
|
||||
// if there are no errors. If there are errors, there has
|
||||
// already been output.
|
||||
|
||||
if (status==0) {
|
||||
fprintf(stderr,
|
||||
catgets(_ttcatd, 6, 25,
|
||||
"ttdbck: no errors found.\n"));
|
||||
}
|
||||
|
||||
exit(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Main guts of ttdbck. Called once for each directory named on the
|
||||
* command line. Returns 1 if the directory was processed without
|
||||
* detecting any errors, else 0.
|
||||
*/
|
||||
int
|
||||
process_directory(_Tt_string dirname)
|
||||
{
|
||||
struct keydesc oid_prop_keydesc;
|
||||
struct keydesc oid_access_keydesc;
|
||||
struct keydesc oid_container_keydesc;
|
||||
|
||||
Spec_ptr this_spec;
|
||||
|
||||
// Initialize for main loop.
|
||||
|
||||
specs_to_repair = new Spec_list;
|
||||
|
||||
oid_prop_rootname = dirname.cat(TT_DB_PROPERTY_TABLE_FILE);
|
||||
oid_prop_keydesc.k_flags = ISDUPS;
|
||||
oid_prop_keydesc.k_nparts = 2;
|
||||
oid_prop_keydesc.k_part[0].kp_start =
|
||||
offsetof(Table_oid_prop,objkey);
|
||||
oid_prop_keydesc.k_part[0].kp_leng =
|
||||
sizeof(oid_prop_record.objkey);
|
||||
oid_prop_keydesc.k_part[0].kp_type = BINTYPE;
|
||||
oid_prop_keydesc.k_part[1].kp_start =
|
||||
offsetof(Table_oid_prop,propname);
|
||||
oid_prop_keydesc.k_part[1].kp_leng =
|
||||
sizeof(oid_prop_record.propname);
|
||||
oid_prop_keydesc.k_part[1].kp_type = CHARTYPE;
|
||||
|
||||
oid_access_rootname = dirname.cat(TT_DB_ACCESS_TABLE_FILE);
|
||||
oid_access_keydesc.k_flags = ISNODUPS;
|
||||
oid_access_keydesc.k_nparts = 1;
|
||||
oid_access_keydesc.k_part[0].kp_start =
|
||||
offsetof(Table_oid_access,objkey);
|
||||
oid_access_keydesc.k_part[0].kp_leng =
|
||||
sizeof(oid_access_record.objkey);
|
||||
oid_access_keydesc.k_part[0].kp_type = BINTYPE;
|
||||
|
||||
oid_container_rootname = dirname.cat(TT_DB_FILE_OBJECT_MAP_FILE);
|
||||
oid_container_keydesc.k_flags = ISNODUPS;
|
||||
oid_container_keydesc.k_nparts = 1;
|
||||
oid_container_keydesc.k_part[0].kp_start =
|
||||
offsetof(Table_oid_container,objkey);
|
||||
oid_container_keydesc.k_part[0].kp_leng =
|
||||
sizeof(oid_container_record.objkey);
|
||||
oid_container_keydesc.k_part[0].kp_type = BINTYPE;
|
||||
|
||||
docoid_path_rootname = dirname.cat(TT_DB_FILE_TABLE_FILE);
|
||||
docoid_path_keydesc.k_flags = ISNODUPS;
|
||||
docoid_path_keydesc.k_nparts = 1;
|
||||
docoid_path_keydesc.k_part[0].kp_start =
|
||||
offsetof(Table_docoid_path, dockey);
|
||||
docoid_path_keydesc.k_part[0].kp_leng =
|
||||
sizeof(docoid_path_record.dockey);
|
||||
docoid_path_keydesc.k_part[0].kp_type = BINTYPE;
|
||||
|
||||
last_min_key = Binkey::smallest;
|
||||
|
||||
oid_prop_fd = -1;
|
||||
oid_access_fd = -1;
|
||||
oid_container_fd = -1;
|
||||
docoid_path_fd = -1;
|
||||
|
||||
if (opts->repair_netisam_p()) {
|
||||
if (-1==isrepair(oid_prop_rootname, 1)) {
|
||||
pisamerr("isrepair", oid_prop_rootname);
|
||||
return 0;
|
||||
}
|
||||
if (-1==isrepair(oid_access_rootname, 1)) {
|
||||
pisamerr("isrepair", oid_access_rootname);
|
||||
return 0;
|
||||
}
|
||||
if (-1==isrepair(oid_container_rootname, 1)) {
|
||||
pisamerr("isrepair", oid_container_rootname);
|
||||
return 0;
|
||||
}
|
||||
if (-1==isrepair(docoid_path_rootname, 1)) {
|
||||
pisamerr("isrepair", docoid_path_rootname);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
oid_prop_fd = isopen(oid_prop_rootname, ISVARLEN+ISINPUT+ISMANULOCK);
|
||||
if (oid_prop_fd==-1) {
|
||||
pisamerr("isopen",oid_prop_rootname);
|
||||
closeall();
|
||||
return 0;
|
||||
}
|
||||
oid_access_fd = isopen(oid_access_rootname,
|
||||
ISVARLEN+ISINPUT+ISMANULOCK);
|
||||
if (oid_access_fd==-1) {
|
||||
pisamerr("isopen",oid_access_rootname);
|
||||
closeall();
|
||||
return 0;
|
||||
}
|
||||
oid_container_fd = isopen(oid_container_rootname,
|
||||
ISVARLEN+ISINPUT+ISMANULOCK);
|
||||
if (oid_container_fd==-1) {
|
||||
pisamerr("isopen",oid_container_rootname);
|
||||
closeall();
|
||||
return 0;
|
||||
}
|
||||
docoid_path_fd = isopen(docoid_path_rootname,
|
||||
ISVARLEN+ISINPUT+ISMANULOCK);
|
||||
if (docoid_path_fd==-1) {
|
||||
pisamerr("isopen",docoid_path_rootname);
|
||||
closeall();
|
||||
return 0;
|
||||
}
|
||||
if (-1==isstart(oid_prop_fd, &oid_prop_keydesc,
|
||||
0,
|
||||
(char *)&oid_prop_record,
|
||||
ISFIRST)) {
|
||||
pisamerr("isstart",oid_prop_rootname);
|
||||
closeall();
|
||||
return 0;
|
||||
}
|
||||
if (-1==isstart(oid_access_fd, &oid_access_keydesc,
|
||||
0,
|
||||
(char *)&oid_access_record,
|
||||
ISFIRST)) {
|
||||
pisamerr("isstart", oid_access_rootname);
|
||||
closeall();
|
||||
return 0;
|
||||
}
|
||||
if (-1==isstart(oid_container_fd, &oid_container_keydesc,
|
||||
0,
|
||||
(char *)&oid_container_record,
|
||||
ISFIRST)){
|
||||
pisamerr("isstart", oid_container_rootname);
|
||||
closeall();
|
||||
return 0;
|
||||
}
|
||||
if (-1==isstart(docoid_path_fd, &docoid_path_keydesc,
|
||||
0,
|
||||
(char *)&docoid_path_record,
|
||||
ISFIRST)){
|
||||
pisamerr("isstart", docoid_path_rootname);
|
||||
closeall();
|
||||
return 0;
|
||||
}
|
||||
|
||||
advance_oid_prop();
|
||||
advance_oid_access();
|
||||
advance_oid_container();
|
||||
this_min_key = compute_min_key(oid_prop_key,
|
||||
oid_access_key,
|
||||
oid_container_key);
|
||||
while (this_min_key<Binkey::largest) {
|
||||
if (last_min_key<this_min_key) {
|
||||
// At this point, we have read all
|
||||
// information about the previous spec.
|
||||
// Analyze it, list it if called for,
|
||||
// queue it for later repair if called
|
||||
// for.
|
||||
|
||||
process_spec(this_spec);
|
||||
|
||||
// Complain about any missing required props
|
||||
// in previous spec, and reset the required property
|
||||
// list.
|
||||
|
||||
// start accumulating a new spec
|
||||
|
||||
this_spec = new Spec;
|
||||
this_spec->key =
|
||||
new Binkey((unsigned char *)(char *)this_min_key);
|
||||
check_if_file(this_spec);
|
||||
|
||||
if (oid_access_key>this_min_key) {
|
||||
// mark spec as no access rec
|
||||
}
|
||||
|
||||
if (oid_container_key>this_min_key) {
|
||||
// mark spec as no container rec
|
||||
}
|
||||
}
|
||||
|
||||
if (!oid_container_inspected &&
|
||||
oid_container_key==this_min_key) {
|
||||
oid_container_inspected = 1;
|
||||
inspect_docoid_path(this_spec);
|
||||
}
|
||||
|
||||
if (oid_prop_key==this_min_key) {
|
||||
|
||||
// Accumulate property
|
||||
|
||||
this_spec->add_prop_and_value(oid_prop_name,
|
||||
oid_prop_value);
|
||||
}
|
||||
|
||||
// Advance to next records.
|
||||
|
||||
if (oid_prop_key==this_min_key) {
|
||||
advance_oid_prop();
|
||||
} else {
|
||||
if (oid_container_key==this_min_key) {
|
||||
advance_oid_container();
|
||||
}
|
||||
if (oid_access_key==this_min_key) {
|
||||
advance_oid_access();
|
||||
}
|
||||
}
|
||||
last_min_key = this_min_key;
|
||||
this_min_key = compute_min_key(oid_prop_key,
|
||||
oid_access_key,
|
||||
oid_container_key);
|
||||
}
|
||||
// And remember to process the last spec.
|
||||
|
||||
process_spec(this_spec);
|
||||
|
||||
closeall();
|
||||
|
||||
if (opts->repairing_p()) {
|
||||
Spec_list_cursor c(specs_to_repair);
|
||||
while(c.next()) {
|
||||
c->repair_spec();
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// the advance_*() routines try to read the next record in the table;
|
||||
// when eof is hit, they set the record key to the largest possible
|
||||
// key. This makes all the merge comparisons work right.
|
||||
|
||||
void
|
||||
advance_oid_prop()
|
||||
{
|
||||
if (-1==isread(oid_prop_fd, (char *)&oid_prop_record, ISNEXT)) {
|
||||
switch (iserrno) {
|
||||
case EENDFILE:
|
||||
break;
|
||||
default:
|
||||
pisamerr("isread", oid_prop_rootname);
|
||||
break;
|
||||
}
|
||||
oid_prop_key = Binkey::largest;
|
||||
} else {
|
||||
int l;
|
||||
oid_prop_key = oid_prop_record.objkey;
|
||||
l = sizeof(oid_prop_record.propname);
|
||||
if (oid_prop_record.propname[l-1]==NULL_CHAR) {
|
||||
// strip nulls
|
||||
l = strlen(oid_prop_record.propname);
|
||||
}
|
||||
oid_prop_name.set((unsigned char *)oid_prop_record.propname,l);
|
||||
oid_prop_value.set((unsigned char *)oid_prop_record.propval,
|
||||
isreclen-offsetof(Table_oid_prop,propval));
|
||||
}
|
||||
}
|
||||
void
|
||||
advance_oid_access()
|
||||
{
|
||||
if (-1==isread(oid_access_fd, (char *)&oid_access_record, ISNEXT)) {
|
||||
switch (iserrno) {
|
||||
case EENDFILE:
|
||||
break;
|
||||
default:
|
||||
pisamerr("isread", oid_access_rootname);
|
||||
break;
|
||||
}
|
||||
oid_access_key = Binkey::largest;
|
||||
} else {
|
||||
oid_access_key = oid_access_record.objkey;
|
||||
}
|
||||
oid_access_inspected = 0;
|
||||
}
|
||||
void
|
||||
advance_oid_container()
|
||||
{
|
||||
if (-1==isread(oid_container_fd,
|
||||
(char *)&oid_container_record, ISNEXT)) {
|
||||
switch (iserrno) {
|
||||
case EENDFILE:
|
||||
break;
|
||||
default:
|
||||
pisamerr("isread", oid_container_rootname);
|
||||
break;
|
||||
}
|
||||
oid_container_key = Binkey::largest;
|
||||
} else {
|
||||
oid_container_key = oid_container_record.objkey;
|
||||
}
|
||||
oid_container_inspected = 0;
|
||||
}
|
||||
|
||||
void
|
||||
closeall()
|
||||
{
|
||||
if (oid_container_fd!=-1) isclose(oid_container_fd);
|
||||
if (oid_access_fd!=-1) isclose(oid_access_fd);
|
||||
if (oid_prop_fd!=-1) isclose(oid_prop_fd);
|
||||
if (docoid_path_fd!=-1) isclose(docoid_path_fd);
|
||||
}
|
||||
|
||||
// compute_min_key finds the least key
|
||||
|
||||
Binkey
|
||||
compute_min_key(Binkey a, Binkey b, Binkey c)
|
||||
{
|
||||
Binkey result = a;
|
||||
if (b<result) result = b;
|
||||
if (c<result) result = c;
|
||||
return result;
|
||||
}
|
||||
|
||||
// process spec is called when the next key is encountered, or at
|
||||
// end of file. The spec data accumulated in spec s is inspected,
|
||||
// printed, and/or queued for later repair.
|
||||
|
||||
void
|
||||
process_spec(Spec_ptr s)
|
||||
{
|
||||
// The first time through the loop there is no accumulated spec
|
||||
// so s will be null.
|
||||
|
||||
if (!s.is_null()) {
|
||||
s->process_spec();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// inspect_docoid_path retrieves the docoid_path record for the current
|
||||
// spec and fills the file name into this_spec.
|
||||
|
||||
void
|
||||
inspect_docoid_path(Spec_ptr this_spec)
|
||||
{
|
||||
memset((char *)&docoid_path_record, 0, sizeof(docoid_path_record));
|
||||
memcpy(docoid_path_record.dockey, oid_container_record.dockey,
|
||||
sizeof(docoid_path_record.dockey));
|
||||
|
||||
if (-1==isread(docoid_path_fd, (char *)&docoid_path_record, ISEQUAL)) {
|
||||
switch (iserrno) {
|
||||
case ENOREC:
|
||||
// oid doesn't have a file!
|
||||
this_spec->filename = "";
|
||||
return;
|
||||
default:
|
||||
pisamerr("isread", oid_container_rootname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (docoid_path_record.filepath[MAX_KEY_LEN-1] == '\0') {
|
||||
// strip padding.
|
||||
this_spec->filename = (char *)docoid_path_record.filepath;
|
||||
} else {
|
||||
this_spec->filename.set((unsigned char *)
|
||||
docoid_path_record.filepath,
|
||||
isreclen-offsetof(Table_docoid_path,
|
||||
filepath));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print ISAM error message. Some error codes (well, one)
|
||||
* are special cased to give more "helpful" messages.
|
||||
*/
|
||||
|
||||
void
|
||||
pisamerr(const char *func, const char *name)
|
||||
{
|
||||
const char *msg = _tt_isstrerror(iserrno);
|
||||
if (msg) {
|
||||
fprintf(stderr,"ttdbck: %s(\"%s\"): %s\n", func, name,
|
||||
msg);
|
||||
} else {
|
||||
fprintf(stderr,"ttdbck: %s(\"%s\"): %d\n", func, name,
|
||||
iserrno);
|
||||
}
|
||||
switch (iserrno) {
|
||||
case EBADFILE:
|
||||
fprintf(stderr,
|
||||
catgets(_ttcatd, 6, 6,
|
||||
"ttdbck: try 'ttdbck -I'.\n"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
check_if_file(Spec_ptr this_spec)
|
||||
{
|
||||
memset((char *)&docoid_path_record, '\0', sizeof(docoid_path_record));
|
||||
memcpy((char *)docoid_path_record.dockey,
|
||||
(char *)(*this_spec->key), OID_KEY_LENGTH);
|
||||
|
||||
if (-1==isread(docoid_path_fd, (char *)&docoid_path_record, ISEQUAL)) {
|
||||
switch (iserrno) {
|
||||
case ENOREC:
|
||||
break;
|
||||
default:
|
||||
pisamerr("isread", oid_container_rootname);
|
||||
break;
|
||||
}
|
||||
this_spec->is_filespec = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// This is the docoid for a file. Set the filename in the spec
|
||||
// so the -f option will select the docoid for the file as well.
|
||||
|
||||
this_spec->is_filespec = 1;
|
||||
|
||||
if (docoid_path_record.filepath[MAX_KEY_LEN-1] == '\0') {
|
||||
// strip padding.
|
||||
this_spec->filename = (char *)docoid_path_record.filepath;
|
||||
} else {
|
||||
this_spec->filename.set((unsigned char *)
|
||||
docoid_path_record.filepath,
|
||||
isreclen-offsetof(Table_docoid_path,
|
||||
filepath));
|
||||
}
|
||||
}
|
||||
27
cde/lib/tt/bin/dbck/ttdbck.h
Normal file
27
cde/lib/tt/bin/dbck/ttdbck.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: ttdbck.h /main/3 1995/10/20 16:34:12 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* ttdbck.h
|
||||
*
|
||||
* ToolTalk 1.0 spec data base inspect and repair tool global declarations
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TTDBCK_H
|
||||
#define _TTDBCK_H
|
||||
|
||||
#include "spec.h"
|
||||
#include "options_tt.h"
|
||||
#include "mp_typedb.h"
|
||||
|
||||
extern char *progname; // from argv[0]
|
||||
extern Spec_list_ptr specs_to_repair;
|
||||
extern _Tt_typedb_ptr *tdb_ptr;
|
||||
extern Dbck_specoptions *opts;
|
||||
|
||||
#endif /* _TTDBCK_H */
|
||||
11
cde/lib/tt/bin/scripts/Imakefile
Normal file
11
cde/lib/tt/bin/scripts/Imakefile
Normal file
@@ -0,0 +1,11 @@
|
||||
XCOMM $XConsortium: Imakefile /main/4 1996/04/21 19:11:31 drk $
|
||||
|
||||
#include "../../tooltalk.tmpl"
|
||||
|
||||
/* Any shell scripts shipped as part of ToolTalk are collected here. */
|
||||
|
||||
PROGRAMS = ttce2xdr
|
||||
|
||||
all:: $(PROGRAMS)
|
||||
|
||||
CppScriptTarget(ttce2xdr,ttce2xdr.cpp,$(TT_VERSION_DEFINE),)
|
||||
252
cde/lib/tt/bin/scripts/ttce2xdr.cpp
Normal file
252
cde/lib/tt/bin/scripts/ttce2xdr.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
XCOMM! /bin/sh
|
||||
XCOMM $XConsortium: ttce2xdr.cpp /main/4 1996/04/21 19:11:34 drk $
|
||||
XCOMM (c) Copyright 1996 Digital Equipment Corporation.
|
||||
XCOMM (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
XCOMM (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
XCOMM (c) Copyright 1992-1994,1996 Sun Microsystems, Inc.
|
||||
XCOMM (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
XCOMM (c) Copyright 1996 FUJITSU LIMITED.
|
||||
XCOMM (c) Copyright 1996 Hitachi.
|
||||
XCOMM
|
||||
XCOMM ttce2xdr - Convert ToolTalk Classing Engine tables to XDR types database
|
||||
|
||||
XCOMM
|
||||
XCOMM usage
|
||||
XCOMM
|
||||
usage() {
|
||||
echo "$1: convert ToolTalk CE tables to XDR types database"
|
||||
echo "Usage: $1 [-xn][-d user|system]"
|
||||
echo " $1 [-xn]-d network [<OPENWINHOME1> [<OPENWINHOME2>]]"
|
||||
echo " $1 [-h]"
|
||||
echo " $1 [-v]"
|
||||
echo " -d <db> database to read (default: all) and "
|
||||
echo " write (default: user)"
|
||||
echo " -n echo commands instead of executing them"
|
||||
echo " -h help"
|
||||
echo " -v version"
|
||||
echo " -x debug mode (pass 'set -x' to /bin/sh)"
|
||||
echo " <OPENWINHOME1> OWv3 installation to read from"
|
||||
echo " <OPENWINHOME2> OWv3 installation to write to"
|
||||
}
|
||||
|
||||
XCOMM
|
||||
XCOMM version
|
||||
XCOMM
|
||||
version() {
|
||||
echo TT_VERSION_STRING
|
||||
}
|
||||
|
||||
XCOMM
|
||||
XCOMM cleanup - Call me before exiting
|
||||
XCOMM
|
||||
cleanup() {
|
||||
rm -f /tmp/ttce2xdr.types.$$ /tmp/ttce2xdr.types.$$.deps /tmp/ttce2xdr.ceascii.$$
|
||||
}
|
||||
|
||||
XCOMM
|
||||
XCOMM nullit - create null ~/.tt/xdr.types so auto convert won't be run
|
||||
XCOMM next time
|
||||
XCOMM
|
||||
nullit() {
|
||||
test -d $HOME/.tt || mkdir $HOME/.tt
|
||||
touch $HOME/.tt/types.xdr
|
||||
}
|
||||
|
||||
XCOMM
|
||||
XCOMM Main
|
||||
XCOMM
|
||||
trap cleanup 0 1 2 3 15
|
||||
|
||||
cmd=`basename $0`
|
||||
|
||||
dryrun=
|
||||
database=
|
||||
ow1=
|
||||
ow2=
|
||||
|
||||
XCOMM
|
||||
XCOMM Parse command line
|
||||
XCOMM
|
||||
args=$*
|
||||
while getopts hxnvrfd: option
|
||||
do
|
||||
case $option in
|
||||
h | \?) usage $cmd; exit 1;;
|
||||
x) set -x;;
|
||||
v) version $cmd; exit 1;;
|
||||
n) dryrun=1;;
|
||||
d) database=$OPTARG;;
|
||||
esac
|
||||
done
|
||||
|
||||
XCOMM
|
||||
XCOMM Discard args processed by getopts
|
||||
XCOMM
|
||||
shift `expr $OPTIND - 1`
|
||||
|
||||
XCOMM
|
||||
XCOMM Process mandatory args
|
||||
XCOMM
|
||||
if [ $# -gt 0 ]; then
|
||||
ow1=$1
|
||||
shift
|
||||
if [ $# -gt 0 ]; then
|
||||
ow2=$1
|
||||
shift
|
||||
fi
|
||||
fi
|
||||
|
||||
XCOMM
|
||||
XCOMM Check for extraneous args
|
||||
XCOMM
|
||||
if [ $# -gt 0 ]; then
|
||||
usage $cmd
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "`set | grep TTHOME`" ]; then
|
||||
echo "\$TTHOME is set. $cmd does not support \$TTHOME."
|
||||
echo "Unset it and rerun $cmd, or run tt_type_comp(1) by hand."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $database ]; then
|
||||
case $database in
|
||||
user | system | network)
|
||||
;;
|
||||
*) echo "$cmd: bogus database: $database";
|
||||
usage $cmd; exit 1;;
|
||||
esac
|
||||
dbopt="-d $database"
|
||||
else
|
||||
database="user"
|
||||
fi
|
||||
|
||||
XCOMM if we are doing user (perhaps automatic) conversion. make
|
||||
XCOMM sure there is some conversion to do, otherwise we can bail out
|
||||
XCOMM early.
|
||||
|
||||
if [ "$database" = "user" ]; then
|
||||
if [ ! -f $HOME/.cetables/cetables ]; then
|
||||
XCOMM user doesn't even have a cetables, nothing to do
|
||||
nullit
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ce_db_build user -to_ascii /tmp/ttce2xdr.ceascii.$$
|
||||
|
||||
if egrep -s "NS_NAME=SUN_TOOLTALK_TYPES" /tmp/ttce2xdr.ceascii.$$ ; then
|
||||
:
|
||||
else
|
||||
XCOMM user has cetables, but no ToolTalk types
|
||||
nullit
|
||||
exit 0
|
||||
fi
|
||||
|
||||
XCOMM Now, we know the user has a cetables with ToolTalk types. Now
|
||||
XCOMM check for a possible malformed cetables with no ToolTalk name
|
||||
XCOMM space definition.
|
||||
|
||||
if egrep -s '^NS_ATTR=$' /tmp/ttce2xdr.ceascii.$$ ; then
|
||||
|
||||
XCOMM The cetables exists, and has ToolTalk types, but
|
||||
XCOMM since the basic definitions in the network CE database
|
||||
XCOMM may be gone, we need to add them back in. Eventually
|
||||
XCOMM in a future release we should remove all ToolTalk info
|
||||
XCOMM from user's cetables.
|
||||
|
||||
ed /tmp/ttce2xdr.ceascii.$$ >/dev/null <<- 'EOF'
|
||||
/^NS_ATTR=$/d
|
||||
i
|
||||
NS_ATTR=((NS_MANAGER,string,<$CEPATH/tns_mgr.so>)
|
||||
)
|
||||
.
|
||||
/^NS_ENTRIES=/a
|
||||
(TYPE_NAME,string,<SUN_TOOLTALK::attrs>)
|
||||
(TYPE_NAME,string,<attr>)
|
||||
(TT_OP,string,<attr>)
|
||||
(TT_ARG,string,<attr>)
|
||||
(TT_SCOPE,string,<attr>)
|
||||
(TT_SCOPE,string,<attr>)
|
||||
(TT_DISPOSITION,string,<attr>)
|
||||
(TT_MSET_DISPOSITION,string,<attr>)
|
||||
(TT_MSET_OPNUM,string,<attr>)
|
||||
(TT_OPNUM,string,<attr>)
|
||||
(TT_MSET_HANDLER_PTYPE,string,<attr>)
|
||||
(TT_HANDLER_PTYPE,string,<attr>)
|
||||
(TT_MSET_OTYPE,string,<attr>)
|
||||
(TT_OTYPE,string,<attr>)
|
||||
(TT_PARENT,string,<attr>)
|
||||
(TT_OUT,string,<attr>)
|
||||
(TT_IN,string,<attr>)
|
||||
(TT_INOUT,string,<attr>)
|
||||
(TT_SESSION,string,<attr>)
|
||||
(TT_FILE,string,<attr>)
|
||||
(TT_BOTH,string,<attr>)
|
||||
(TT_FILE_IN_SESSION,string,<attr>)
|
||||
(TT_DISCARD,string,<attr>)
|
||||
(TT_QUEUE,string,<attr>)
|
||||
(TT_START,string,<attr>)
|
||||
(TT_CATEGORY,string,<attr>)
|
||||
(TT_OBSERVE,string,<attr>)
|
||||
(TT_HANDLE,string,<attr>)
|
||||
(TT_CLASS,string,<attr>)
|
||||
(TT_REQUEST,string,<attr>)
|
||||
(TT_NOTICE,string,<attr>)
|
||||
(SUN_TOOLTALK_TYPE,string,<attr>)
|
||||
(SUN_TOOLTALK_PTYPE,string,<attr>)
|
||||
(SUN_TOOLTALK_OTYPE,string,<attr>)
|
||||
(SUN_TOOLTALK_SIGNATURE,string,<attr>)
|
||||
.
|
||||
w
|
||||
q
|
||||
EOF
|
||||
ce_db_build user -from_ascii /tmp/ttce2xdr.ceascii.$$
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ $dryrun ]; then
|
||||
if [ $ow1 ]; then
|
||||
echo "OPENWINHOME=$ow1; export OPENWINHOME"
|
||||
fi
|
||||
echo "tt_type_comp -Eps $dbopt > /tmp/ttce2xdr.types.$$"
|
||||
if [ $ow2 ]; then
|
||||
echo "OPENWINHOME=$ow2; export OPENWINHOME"
|
||||
fi
|
||||
echo "tt_type_comp -Ms $dbopt /tmp/ttce2xdr.types.$$"
|
||||
else
|
||||
if [ $ow1 ]; then
|
||||
OPENWINHOME=$ow1
|
||||
export OPENWINHOME
|
||||
fi
|
||||
rm -f /tmp/ttce2xdr.types.$$
|
||||
if tt_type_comp -Eps $dbopt > /tmp/ttce2xdr.types.$$; then :; else
|
||||
XCOMM Conversion failed for some reason. If we're working on a
|
||||
XCOMM user database, we're probably doing an automatic conversion.
|
||||
XCOMM and there's no point in continuing to retry this every time.
|
||||
XCOMM Just touch the .tt/types.xdr file so auto conversion won't
|
||||
XCOMM keep getting run.
|
||||
|
||||
case $database in
|
||||
user)
|
||||
nullit
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
echo $cmd: could not read ToolTalk types from Classing Engine database.
|
||||
echo $cmd: there may not be any ToolTalk types in this database.
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ $ow2 ]; then
|
||||
OPENWINHOME=$ow2
|
||||
export OPENWINHOME
|
||||
fi
|
||||
if tt_type_comp -Ms $dbopt /tmp/ttce2xdr.types.$$; then :; else
|
||||
echo $cmd: could not compile types into XDR database.
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
49
cde/lib/tt/bin/shell/Imakefile
Normal file
49
cde/lib/tt/bin/shell/Imakefile
Normal file
@@ -0,0 +1,49 @@
|
||||
XCOMM $XConsortium: Imakefile /main/10 1996/05/08 09:27:50 drk $
|
||||
|
||||
#define CplusplusSource YES
|
||||
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
|
||||
EXTRA_LOAD_FLAGS = ExtraLoadFlags $(UNSHARED_CXXLIB)
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#include "../../tooltalk.tmpl"
|
||||
|
||||
DEFINES =
|
||||
INCLUDES = -I. -I../../lib
|
||||
|
||||
DEPLIBS = TtClientDepLibs
|
||||
LOCAL_LIBRARIES = TtClientLibs
|
||||
SYS_LIBRARIES =
|
||||
|
||||
#ifdef TtClientExtraLibs
|
||||
EXTRA_LIBRARIES = TtClientExtraLibs
|
||||
#endif
|
||||
|
||||
PROG1 = ttmv
|
||||
SRCS1 = ttmv.C mover.C
|
||||
OBJS1 = ttmv.o mover.o
|
||||
|
||||
PROG2 = ttrm
|
||||
SRCS2 = ttrm.C remover.C
|
||||
OBJS2 = ttrm.o remover.o
|
||||
|
||||
PROG3 = ttcp
|
||||
SRCS3 = ttcp.C copier.C
|
||||
OBJS3 = ttcp.o copier.o
|
||||
|
||||
PROG4 = ttrmdir
|
||||
SRCS4 = $(SRCS2)
|
||||
OBJS4 = $(OBJS2)
|
||||
|
||||
PROGRAMS = $(PROG1) $(PROG2) $(PROG3) $(PROG4)
|
||||
|
||||
NormalCplusplusObjectRule()
|
||||
|
||||
ComplexCplusplusProgramTarget_1($(PROG1),$(LOCAL_LIBRARIES),/**/)
|
||||
ComplexCplusplusProgramTarget_2($(PROG2),$(LOCAL_LIBRARIES),/**/)
|
||||
ComplexCplusplusProgramTarget_3($(PROG3),$(LOCAL_LIBRARIES),/**/)
|
||||
ComplexCplusplusProgramTarget_4($(PROG4),$(LOCAL_LIBRARIES),/**/)
|
||||
|
||||
SpecialCplusplusObjectRule(remover,remover,$(TT_VERSION_DEFINE))
|
||||
SpecialCplusplusObjectRule(mover,mover,$(TT_VERSION_DEFINE))
|
||||
SpecialCplusplusObjectRule(copier,copier,$(TT_VERSION_DEFINE))
|
||||
11
cde/lib/tt/bin/shell/admindefines
Normal file
11
cde/lib/tt/bin/shell/admindefines
Normal file
@@ -0,0 +1,11 @@
|
||||
XCOMM $XConsortium: admindefines /main/2 1996/05/07 19:16:10 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
|
||||
452
cde/lib/tt/bin/shell/copier.C
Normal file
452
cde/lib/tt/bin/shell/copier.C
Normal file
@@ -0,0 +1,452 @@
|
||||
//%% (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: copier.C /main/3 1995/10/20 16:35:57 rswiston $
|
||||
/*
|
||||
* copier.cc - Link Service/ToolTalk wrapper for cp(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tt_options.h"
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/param.h>
|
||||
#include <errno.h>
|
||||
#include "api/c/tt_c.h"
|
||||
#include "util/tt_path.h"
|
||||
#include "util/tt_gettext.h"
|
||||
#include "util/copyright.h"
|
||||
#include "copier.h"
|
||||
|
||||
/*
|
||||
* External variables
|
||||
*/
|
||||
extern char *_tt_get_realpath(char *, char *);
|
||||
|
||||
/*
|
||||
* copier::copier()
|
||||
*/
|
||||
copier::
|
||||
copier( char *arg0 )
|
||||
{
|
||||
if (arg0 != NULL) {
|
||||
char *base = strrchr( arg0, '/' );
|
||||
if (base == NULL) {
|
||||
base = arg0;
|
||||
} else {
|
||||
base++; /* Don't want the '/' */
|
||||
}
|
||||
_prog_name = base;
|
||||
_process_name = _prog_name;
|
||||
}
|
||||
_args = new _Tt_string_list();
|
||||
_from_paths = new _Tt_string_list();
|
||||
_should_cp = TRUE;
|
||||
_recurse = FALSE;
|
||||
_preserve = FALSE;
|
||||
_clonedir_mode = FALSE;
|
||||
_tt_opened = FALSE;
|
||||
}
|
||||
|
||||
copier::
|
||||
~copier()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* copier::do_cp() - Use system() to invoke cp(1), and return its exit status.
|
||||
* We can just use _args, since we never get here when our one
|
||||
* cp-incompatible option (-L) has been given.
|
||||
*/
|
||||
int copier::
|
||||
do_cp()
|
||||
{
|
||||
_Tt_string cmd( "cp" );
|
||||
_Tt_string_list_cursor arg_cursor( _args );
|
||||
|
||||
while (arg_cursor.next()) {
|
||||
cmd = cmd.cat( " " ).cat( *arg_cursor );
|
||||
}
|
||||
//printf( "Invoking: %s\n", (char *)cmd );
|
||||
int sys_status = system( (char *)cmd );
|
||||
if (WIFEXITED(sys_status)) {
|
||||
return WEXITSTATUS(sys_status);
|
||||
} else {
|
||||
fprintf( stderr,
|
||||
"%s: system(\"%s\"): %d\n",
|
||||
(char *)_process_name, (char *)cmd, sys_status );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* copier::do_ttcp() - Use tttar(1) to copy the objects of the _from_paths.
|
||||
*
|
||||
* Algorithm:
|
||||
*
|
||||
* if (_clonedir_mode) {
|
||||
* cd _from_path; tttar cfhL - . | (cd ../_to_path; tttar xfLp? -)
|
||||
* } else {
|
||||
* if (_to_path_is_dir) {
|
||||
* tttar cfhL - _from_paths | (cd _to_path ; tttar xfLp? - )
|
||||
* } else {
|
||||
* tttar cfhL - _from_path | tttar xfLp? - -rename from to
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
Tt_status copier::
|
||||
do_ttcp()
|
||||
{
|
||||
_Tt_string cmd;
|
||||
_Tt_string_list_cursor from_path_cursor( _from_paths );
|
||||
Tt_status err;
|
||||
|
||||
if (_clonedir_mode) {
|
||||
#ifdef DO_TTTAR_AFTER_CP
|
||||
if (mkdir( (char *)_to_path, S_IRWXU ) != 0) {
|
||||
return TT_ERR_PATH;
|
||||
}
|
||||
#endif
|
||||
cmd = cmd.cat( "cd " ).cat( _from_paths->top()).cat( " ; ");
|
||||
}
|
||||
cmd = cmd.cat( "tttar cfhL -" );
|
||||
while (from_path_cursor.next()) {
|
||||
_Tt_string from_path = *from_path_cursor;
|
||||
if (! this->can_cp( from_path )) {
|
||||
/*
|
||||
* Don't tttar any paths we know that cp(1) will
|
||||
* reject. We do this for clonedir mode, too, so
|
||||
* we can return if the cloning shouldn't be done.
|
||||
*/
|
||||
from_path_cursor.remove();
|
||||
} else {
|
||||
/*
|
||||
* tt_file_destroy() any path that cp(1) will delete
|
||||
*/
|
||||
_Tt_string path2zap = _to_path;
|
||||
if (_to_path_is_dir) {
|
||||
/*
|
||||
* cp(1) will overwrite any entry in _to_path
|
||||
* that has the same name as a _from_path.
|
||||
*/
|
||||
_Tt_string dir, base;
|
||||
base = from_path.rsplit( '/', dir );
|
||||
path2zap = _to_path.cat( "/" ).cat( base );
|
||||
}
|
||||
err = tt_file_destroy( (char *)path2zap );
|
||||
if (err > TT_WRN_LAST) {
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 8, 12,
|
||||
"%s: Could not remove "
|
||||
"ToolTalk objects of %s "
|
||||
"because %s\n"),
|
||||
(char *)_process_name,
|
||||
(char *)path2zap,
|
||||
tt_status_message(err) );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_from_paths->count() <= 0) {
|
||||
return TT_OK;
|
||||
}
|
||||
if (_clonedir_mode) {
|
||||
/*
|
||||
* In clonedir mode, we just tttar up everything in
|
||||
* the directory we're cloning.
|
||||
*/
|
||||
cmd = cmd.cat( " ." );
|
||||
} else {
|
||||
from_path_cursor.reset();
|
||||
while (from_path_cursor.next()) {
|
||||
cmd = cmd.cat( " " ).cat( *from_path_cursor );
|
||||
}
|
||||
}
|
||||
cmd = cmd.cat( " |" );
|
||||
if (_to_path_is_dir) {
|
||||
cmd = cmd.cat( " ( cd " );
|
||||
if (_clonedir_mode) {
|
||||
char realpath_buf[ MAXPATHLEN ];
|
||||
|
||||
/*
|
||||
* If we're in _clonedir_mode, then we'll be
|
||||
* cd'ing down into _from_path, and so we want
|
||||
* a realpath of _to_path to cd over to,
|
||||
* because if _from_path is a symlink then
|
||||
* in _from_path "../_to_path" is _not_ _to_path.
|
||||
*/
|
||||
char *real_to_path = _tt_get_realpath( (char *)_to_path,
|
||||
realpath_buf );
|
||||
if (real_to_path == NULL) {
|
||||
fprintf( stderr, "%s: %s: %s\n",
|
||||
(char *)_process_name,
|
||||
(char *)_to_path, strerror(errno) );
|
||||
return TT_ERR_PATH;
|
||||
}
|
||||
cmd = cmd.cat( real_to_path );
|
||||
} else {
|
||||
cmd = cmd.cat( _to_path );
|
||||
}
|
||||
cmd = cmd.cat( " ;" );
|
||||
}
|
||||
cmd = cmd.cat( " tttar xfL" );
|
||||
if (_preserve) {
|
||||
cmd = cmd.cat( "p" );
|
||||
}
|
||||
cmd = cmd.cat( " -" );
|
||||
/*
|
||||
* Use the hack we built into tttar(1) to rename paths
|
||||
* as they're extracted. Rename each _from_path to _to_path.
|
||||
*/
|
||||
from_path_cursor.reset();
|
||||
while (from_path_cursor.next()) {
|
||||
_Tt_string from_path = *from_path_cursor;
|
||||
cmd = cmd.cat( " -rename " ).cat( from_path )
|
||||
.cat( " " ).cat( _to_path );
|
||||
/*
|
||||
* If the copy is to be made in a subdirectory of _to_path,
|
||||
* make tttar maps _from_path to the appropriate
|
||||
* subdirectory of _to_path as it extracts.
|
||||
*/
|
||||
if ((_to_path_is_dir) && (! _clonedir_mode)) {
|
||||
_Tt_string dir_name;
|
||||
cmd = cmd.cat( "/" )
|
||||
.cat( from_path.rsplit( '/', dir_name ));
|
||||
}
|
||||
}
|
||||
if (_to_path_is_dir) {
|
||||
cmd = cmd.cat( " )" );
|
||||
}
|
||||
//printf( "Invoking: %s\n", (char *)cmd );
|
||||
int sys_status = system( (char *)cmd );
|
||||
#ifdef DO_TTTAR_AFTER_CP
|
||||
if (_clonedir_mode) {
|
||||
/*
|
||||
* remove the target directory, so that cp(1) won't
|
||||
* see it and make _from_path a subdirectory of it.
|
||||
*/
|
||||
if (rmdir( (char *)_to_path ) != 0) {
|
||||
fprintf( stderr, "%s: rmdir(\"%s\"): %s\n",
|
||||
(char *)_process_name, (char *)_to_path,
|
||||
strerror(errno) );
|
||||
return TT_ERR_PATH;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (WIFEXITED(sys_status)) {
|
||||
if (WEXITSTATUS(sys_status) == 0) {
|
||||
return TT_OK;
|
||||
} else {
|
||||
return TT_ERR_INTERNAL;
|
||||
}
|
||||
} else {
|
||||
fprintf( stderr,
|
||||
"%s: system(\"%s\"): %d\n",
|
||||
(char *)_process_name, sys_status );
|
||||
return TT_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
} /* do_ttcp() */
|
||||
|
||||
/*
|
||||
* copier::can_cp() - Can we copy this path to _to_path?
|
||||
*
|
||||
* TO_DO: can_cp() can be as tricky as you like.
|
||||
*/
|
||||
bool_t copier::
|
||||
can_cp( _Tt_string from_path )
|
||||
{
|
||||
struct stat stat_buf;
|
||||
|
||||
if (stat( (char *)from_path, &stat_buf) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
if (S_ISDIR(stat_buf.st_mode) && (! _recurse)) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* copier::open_tt()
|
||||
*/
|
||||
Tt_status copier::
|
||||
open_tt()
|
||||
{
|
||||
char *process_id = tt_open();
|
||||
Tt_status err = tt_ptr_error( process_id );
|
||||
if (err == TT_OK) {
|
||||
_process_id = process_id;
|
||||
_tt_opened = TRUE;
|
||||
} else if (err > TT_WRN_LAST) {
|
||||
fprintf( stderr,
|
||||
"%s: tt_open(): %s\n",
|
||||
(char *)_process_name, tt_status_message( err ) );
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* copier::close_tt()
|
||||
*/
|
||||
Tt_status copier::
|
||||
close_tt()
|
||||
{
|
||||
if (! _tt_opened) {
|
||||
return TT_OK;
|
||||
}
|
||||
Tt_status err = tt_close();
|
||||
if (err > TT_WRN_LAST) {
|
||||
fprintf( stderr,
|
||||
"%s: tt_close(): %s\n",
|
||||
(char *)_process_name, tt_status_message( err ) );
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* copier::parse_args()
|
||||
*/
|
||||
void copier::
|
||||
parse_args( int argc, char **argv )
|
||||
{
|
||||
for ( int arg_num = 1; arg_num < argc; arg_num++ ) {
|
||||
_Tt_string arg( argv[arg_num] );
|
||||
_args->append( arg );
|
||||
if (arg[0] == '-') {
|
||||
this->_parse_arg( (char *)arg );
|
||||
} else {
|
||||
if (arg_num == argc - 1) {
|
||||
_to_path = arg;
|
||||
} else {
|
||||
_from_paths->append( arg );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((_to_path.len() <= 0) || (_from_paths->count() <= 0)) {
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
if (_from_paths->count() > 1) {
|
||||
/*
|
||||
* If multiple things to move, the place we're moving them to
|
||||
* must be a directory.
|
||||
*/
|
||||
struct stat stat_buf;
|
||||
|
||||
if (stat( (char *)_to_path, &stat_buf) != 0) {
|
||||
fprintf( stderr, "%s: %s: ", (char *)_process_name,
|
||||
(char *)_to_path );
|
||||
perror(NULL);
|
||||
exit(2);
|
||||
}
|
||||
if (! S_ISDIR(stat_buf.st_mode)) {
|
||||
fprintf( stderr, "%s: %s: %s\n",
|
||||
(char *)_process_name, (char *)_to_path,
|
||||
strerror(ENOTDIR) );
|
||||
this->usage();
|
||||
exit(2);
|
||||
}
|
||||
_to_path_is_dir = TRUE;
|
||||
} else {
|
||||
struct stat stat_buf;
|
||||
|
||||
_to_path_is_dir = FALSE;
|
||||
if (stat( (char *)_to_path, &stat_buf) == 0) {
|
||||
_to_path_is_dir = S_ISDIR(stat_buf.st_mode);
|
||||
} else {
|
||||
/*
|
||||
* If you "cp -r dir1 dir2" and dir2 doesn't
|
||||
* exist, cp(1) creates it and copies dir1's
|
||||
* contents into it. What we need to do in this
|
||||
* case is to
|
||||
* 1. mkdir( dir2 ), [so we can cd there]
|
||||
* 2. (cd dir1; tttar cf - .) | (cd dir2; tttar xf -)
|
||||
* 3. rmdir( dir2 ) [so cp(1) will do right thing]
|
||||
*/
|
||||
_Tt_string from_path = _from_paths->top();
|
||||
if ( (_from_paths->count() == 1)
|
||||
&& (stat( (char *)from_path, &stat_buf) == 0)
|
||||
&& S_ISDIR(stat_buf.st_mode))
|
||||
{
|
||||
_clonedir_mode = TRUE;
|
||||
_to_path_is_dir = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* parse_args() */
|
||||
|
||||
/*
|
||||
* copier::_parse_arg() - Parse an option
|
||||
*
|
||||
* If you add any options not supported by cp(1) and still expect
|
||||
* it to be system()'d, fix ::do_cp() to pass cp(1) the right args.
|
||||
*/
|
||||
void copier::
|
||||
_parse_arg( char *arg )
|
||||
{
|
||||
if (arg == NULL) {
|
||||
return;
|
||||
}
|
||||
int n = -1;
|
||||
while (arg[++n] != '\0') {
|
||||
switch (arg[n]) {
|
||||
case '-':
|
||||
if (n != 0) {
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
this->usage();
|
||||
exit(1);
|
||||
break;
|
||||
case 'L':
|
||||
_should_cp = FALSE;
|
||||
break;
|
||||
case 'p':
|
||||
_preserve = TRUE;
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
_recurse = TRUE;
|
||||
break;
|
||||
case 'v':
|
||||
_TT_PRINT_VERSIONS((char *)_prog_name)
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} /* _parse_arg() */
|
||||
|
||||
/*
|
||||
* copier::usage()
|
||||
*/
|
||||
void copier::
|
||||
usage(FILE *fs) const
|
||||
{
|
||||
fprintf( fs,
|
||||
catgets(_ttcatd, 8, 13,
|
||||
"Usage: %s [-pL] file1 file2\n"
|
||||
" %s [-prRL] path1 [path2 ...] dir\n"
|
||||
" %s -v\n"
|
||||
" %s -h\n"),
|
||||
(char *)_prog_name, (char *)_prog_name, (char *)_prog_name,
|
||||
(char *)_prog_name );
|
||||
fprintf( fs,
|
||||
catgets(_ttcatd, 8, 14,
|
||||
"\t-L do not perform a cp(1)\n"
|
||||
"\t-v print the version number and quit\n"
|
||||
"\t-h print this message\n" ));
|
||||
}
|
||||
51
cde/lib/tt/bin/shell/copier.h
Normal file
51
cde/lib/tt/bin/shell/copier.h
Normal 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: copier.h /main/3 1995/10/20 16:36:05 rswiston $ */
|
||||
/*
|
||||
* copier.h - Interface to copier, an LS/TT-aware cp(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _COPIER_H
|
||||
#define _COPIER_H
|
||||
|
||||
#include <api/c/tt_c.h>
|
||||
#include <util/tt_string.h>
|
||||
|
||||
class copier : public _Tt_object {
|
||||
public:
|
||||
copier( char *arg0 );
|
||||
virtual ~copier();
|
||||
|
||||
int do_cp();
|
||||
Tt_status do_ttcp();
|
||||
bool_t can_cp( _Tt_string from_path );
|
||||
Tt_status open_tt();
|
||||
Tt_status close_tt();
|
||||
void parse_args( int argc, char **argv );
|
||||
void usage( FILE *fs = stderr ) const;
|
||||
bool_t should_cp() { return _should_cp; }
|
||||
bool_t tt_opened() { return _tt_opened; }
|
||||
|
||||
private:
|
||||
void _parse_arg( char *arg );
|
||||
|
||||
_Tt_string _process_name;
|
||||
_Tt_string _prog_name;
|
||||
_Tt_string _process_id;
|
||||
_Tt_string_list_ptr _args;
|
||||
bool_t _should_cp;
|
||||
bool_t _recurse;
|
||||
bool_t _preserve;
|
||||
bool_t _tt_opened;
|
||||
_Tt_string_list_ptr _from_paths;
|
||||
_Tt_string _to_path;
|
||||
bool_t _to_path_is_dir;
|
||||
bool_t _clonedir_mode; /* see parse_args() */
|
||||
};
|
||||
|
||||
#endif /* _COPIER_H */
|
||||
368
cde/lib/tt/bin/shell/mover.C
Normal file
368
cde/lib/tt/bin/shell/mover.C
Normal file
@@ -0,0 +1,368 @@
|
||||
//%% (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: mover.C /main/4 1995/10/20 16:36:15 rswiston $
|
||||
/*
|
||||
* mover.cc - Link Service/ToolTalk wrapper for mv(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tt_options.h"
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#ifdef __osf__
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#if !defined(USL) && !defined(__uxp__)
|
||||
#include <osfcn.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#if defined(ultrix)
|
||||
#include <sys/inode.h>
|
||||
#define S_ISLNK(m) (((m)&IFMT) == IFLNK)
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#if defined(OPT_BUG_USL) || defined(OPT_BUG_UXP)
|
||||
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
#include <sys/wait.h>
|
||||
#include "api/c/tt_c.h"
|
||||
#include "util/tt_gettext.h"
|
||||
#include "util/copyright.h"
|
||||
#include "mover.h"
|
||||
|
||||
/*
|
||||
* External variables
|
||||
*/
|
||||
|
||||
/*
|
||||
* mover::mover()
|
||||
*/
|
||||
mover::
|
||||
mover( char *arg0 )
|
||||
{
|
||||
if (arg0 != NULL) {
|
||||
char *base = strrchr( arg0, '/' );
|
||||
if (base == NULL) {
|
||||
base = arg0;
|
||||
} else {
|
||||
base++; // Don't want the '/'
|
||||
}
|
||||
_prog_name = base;
|
||||
_process_name = _prog_name;
|
||||
}
|
||||
_args = new _Tt_string_list();
|
||||
_from_paths = new _Tt_string_list();
|
||||
_should_mv = TRUE;
|
||||
_force = FALSE;
|
||||
_tt_opened = FALSE;
|
||||
}
|
||||
|
||||
mover::
|
||||
~mover()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* mover::do_mv() - Use system() to invoke mv(1), and return its exit status.
|
||||
* We can just use _args, since we never get here when our one
|
||||
* mv-incompatible option (-L) has been given.
|
||||
*/
|
||||
int mover::
|
||||
do_mv()
|
||||
{
|
||||
_Tt_string cmd( "mv" );
|
||||
_Tt_string_list_cursor arg_cursor( _args );
|
||||
|
||||
while (arg_cursor.next()) {
|
||||
cmd = cmd.cat( " " ).cat( *arg_cursor );
|
||||
}
|
||||
//printf( "Invoking: %s\n", (char *)cmd );
|
||||
int sys_status = system( (char *)cmd );
|
||||
if (WIFEXITED(sys_status)) {
|
||||
return WEXITSTATUS(sys_status);
|
||||
} else {
|
||||
if (! _force) {
|
||||
fprintf(stderr, "%s: system(\"%s\"): %d\n",
|
||||
(char *)_process_name, (char *)cmd, sys_status);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mover::do_ttmv() - Use tt_file_move() on the things to move.
|
||||
*/
|
||||
Tt_status mover::
|
||||
do_ttmv()
|
||||
{
|
||||
Tt_status worst_err = TT_OK;
|
||||
Tt_status err;
|
||||
_Tt_string full_to_path;
|
||||
bool_t abort = FALSE;
|
||||
bool_t are_more;
|
||||
|
||||
full_to_path = _to_path;
|
||||
_Tt_string_list_cursor from_path_cursor( _from_paths );
|
||||
/*
|
||||
* call to next() must be first, so that are_more will be valid
|
||||
* if we abort. Why does the next() method wrap around?
|
||||
*/
|
||||
while ((are_more = from_path_cursor.next()) && (! abort)) {
|
||||
if (! this->can_mv( *from_path_cursor )) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* tt_file_destroy() any path that mv(1) will delete
|
||||
*/
|
||||
if (_to_path_is_dir) {
|
||||
full_to_path = _to_path.cat("/").
|
||||
cat(*from_path_cursor);
|
||||
}
|
||||
/*
|
||||
* mv(1) will overwrite any entry in _to_path that
|
||||
* has the same name as a _from_path.
|
||||
*/
|
||||
err = tt_file_destroy( (char *)full_to_path );
|
||||
if ((err > TT_WRN_LAST) && (! _force)) {
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 8, 2,
|
||||
"%s: Could not remove "
|
||||
"ToolTalk objects of %s "
|
||||
"because %s\n"),
|
||||
(char *)_process_name,
|
||||
(char *)full_to_path,
|
||||
tt_status_message(err) );
|
||||
}
|
||||
err = tt_file_move( (char *)*from_path_cursor,
|
||||
(char *)full_to_path );
|
||||
if (err > TT_WRN_LAST) {
|
||||
worst_err = err;
|
||||
if (! _force) {
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 8, 3,
|
||||
"%s: Could not move ToolTalk "
|
||||
"objects of \"%s\" to \"%s\" "
|
||||
"because %s\n"),
|
||||
(char *)_process_name,
|
||||
(char *)*from_path_cursor,
|
||||
(char *)full_to_path,
|
||||
tt_status_message( err ));
|
||||
}
|
||||
switch (err) {
|
||||
case TT_ERR_DBAVAIL:
|
||||
case TT_ERR_PATH:
|
||||
break;
|
||||
case TT_ERR_NOMP:
|
||||
case TT_ERR_DBEXIST:
|
||||
default:
|
||||
abort = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (are_more && (! _force)) {
|
||||
from_path_cursor.prev();
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 8, 4,
|
||||
"%s: Will not attempt to move the ToolTalk "
|
||||
"objects of:\n"),
|
||||
(char *)_process_name );
|
||||
while (from_path_cursor.next()) {
|
||||
fprintf( stderr, "\t%s\n", (char *)*from_path_cursor );
|
||||
}
|
||||
}
|
||||
/*
|
||||
* TO_DO: This should be uncommented if you think that warning them
|
||||
* about hygiene is more important than obeying the -f flag.
|
||||
*
|
||||
if ((worst_err > TT_WRN_LAST) && _should_mv && _force) {
|
||||
fprintf( stderr, "%s: The ToolTalk objects of some files were "
|
||||
"not moved.\nSince you've told us to move the files "
|
||||
"anyway, you will need to\nuse %s -L to move "
|
||||
"the ToolTalk objects of the problem files.\n",
|
||||
(char *)_process_name, (char *)_prog_name );
|
||||
}
|
||||
*/
|
||||
return worst_err;
|
||||
|
||||
} /* do_ttmv() */
|
||||
|
||||
/*
|
||||
* mover::can_mv() - Can we move this path to _to_path?
|
||||
*
|
||||
* TO_DO: Judging by mv.c, can_mv() can be as tricky as you like.
|
||||
* I'll count on tt_file_move() to Do The Right Thing.
|
||||
*/
|
||||
bool_t mover::
|
||||
can_mv( _Tt_string from_path )
|
||||
{
|
||||
struct stat lstat_buf;
|
||||
if (lstat( (char *)from_path, &lstat_buf) == 0) {
|
||||
if (S_ISLNK(lstat_buf.st_mode)) {
|
||||
/*
|
||||
* Don't tt_file_move() a symlink, or TT will
|
||||
* tt_file_move() the linked file.
|
||||
*/
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* If we're trying to mv a file that doesn't exist,
|
||||
* let's not tt_file_move() the associated pathname.
|
||||
* But if we're trying to ttmv -L a file that doesn't
|
||||
* exist, we should probably tt_file_move() it anyway.
|
||||
*/
|
||||
if (_should_mv) {
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mover::open_tt()
|
||||
*/
|
||||
Tt_status mover::
|
||||
open_tt()
|
||||
{
|
||||
char *process_id = tt_open();
|
||||
Tt_status err = tt_ptr_error( process_id );
|
||||
if (err == TT_OK) {
|
||||
_process_id = process_id;
|
||||
_tt_opened = TRUE;
|
||||
} else if (err > TT_WRN_LAST) {
|
||||
fprintf( stderr,
|
||||
"%s: tt_open(): %s\n",
|
||||
(char *)_process_name, tt_status_message(err) );
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* mover::close_tt()
|
||||
*/
|
||||
Tt_status mover::
|
||||
close_tt()
|
||||
{
|
||||
if (! _tt_opened) {
|
||||
return TT_OK;
|
||||
}
|
||||
Tt_status err = tt_close();
|
||||
if (err > TT_WRN_LAST) {
|
||||
fprintf( stderr,
|
||||
"%s: tt_close(): %s\n",
|
||||
(char *)_process_name, tt_status_message(err) );
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* mover::parse_args()
|
||||
*/
|
||||
void mover::
|
||||
parse_args( int argc, char **argv )
|
||||
{
|
||||
bool_t no_more_options = FALSE;
|
||||
|
||||
for ( int arg_num = 1; arg_num < argc; arg_num++ ) {
|
||||
_Tt_string arg( argv[arg_num] );
|
||||
_args->append( arg );
|
||||
if ((arg[0] == '-') && (! no_more_options)) {
|
||||
if (arg[1] == '\0') {
|
||||
/*
|
||||
* The bare option "-" means take the
|
||||
* subsequent arguments to be pathnames.
|
||||
*/
|
||||
no_more_options = TRUE;
|
||||
} else {
|
||||
for (int n = 1; n < arg.len(); n++) {
|
||||
switch (arg[n]) {
|
||||
case 'f':
|
||||
_force = TRUE;
|
||||
break;
|
||||
case 'L':
|
||||
_should_mv = FALSE;
|
||||
break;
|
||||
case 'v':
|
||||
_TT_PRINT_VERSIONS((char *)_prog_name)
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (arg_num == argc - 1) {
|
||||
_to_path = arg;
|
||||
} else {
|
||||
_from_paths->append( arg );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((_to_path.len() <= 0) || (_from_paths->count() <= 0)) {
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
if (_from_paths->count() > 1) {
|
||||
/*
|
||||
* If multiple things to move, the place we're moving them to
|
||||
* must be a directory.
|
||||
*/
|
||||
struct stat stat_buf;
|
||||
|
||||
if (stat( (char *)_to_path, &stat_buf) != 0) {
|
||||
fprintf( stderr, "%s: \"%s\": ", (char *)_process_name,
|
||||
(char *)_to_path );
|
||||
perror(NULL);
|
||||
exit(2);
|
||||
}
|
||||
if (! S_ISDIR(stat_buf.st_mode)) {
|
||||
fprintf( stderr, "%s: \"%s\": %s\n",
|
||||
(char *)_process_name, (char *)_to_path,
|
||||
strerror(ENOTDIR) );
|
||||
this->usage();
|
||||
exit(2);
|
||||
}
|
||||
_to_path_is_dir = TRUE;
|
||||
} else {
|
||||
struct stat stat_buf;
|
||||
|
||||
_to_path_is_dir = FALSE;
|
||||
if (stat( (char *)_to_path, &stat_buf) == 0) {
|
||||
_to_path_is_dir = S_ISDIR(stat_buf.st_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mover::usage()
|
||||
*/
|
||||
void mover::
|
||||
usage(FILE *fs) const
|
||||
{
|
||||
fprintf( fs,
|
||||
catgets(_ttcatd, 8, 5,
|
||||
"Usage: %s [-] [-fL] path1 path2\n"
|
||||
" %s [-] [-fL] path1 [path2 ...] dir\n"
|
||||
" %s -v\n"
|
||||
" %s -h\n"),
|
||||
(char *)_prog_name, (char *)_prog_name, (char *)_prog_name,
|
||||
(char *)_prog_name );
|
||||
fprintf( fs,
|
||||
catgets(_ttcatd, 8, 6,
|
||||
"\t-L do not perform a mv(1)\n"
|
||||
"\t-v print the version number and quit\n"
|
||||
"\t-h print this message\n" ));
|
||||
}
|
||||
48
cde/lib/tt/bin/shell/mover.h
Normal file
48
cde/lib/tt/bin/shell/mover.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*%% (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: mover.h /main/3 1995/10/20 16:36:24 rswiston $ */
|
||||
/*
|
||||
* mover.h - Interface to mover, an LS/TT-aware mv(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MOVER_H
|
||||
#define _MOVER_H
|
||||
|
||||
#include <api/c/tt_c.h>
|
||||
#include <util/tt_string.h>
|
||||
|
||||
class mover : public _Tt_object {
|
||||
public:
|
||||
mover( char *arg0 );
|
||||
virtual ~mover();
|
||||
|
||||
int do_mv();
|
||||
Tt_status do_ttmv();
|
||||
bool_t can_mv( _Tt_string from_path );
|
||||
Tt_status open_tt();
|
||||
Tt_status close_tt();
|
||||
void parse_args( int argc, char **argv );
|
||||
void usage( FILE *fs = stderr ) const;
|
||||
bool_t should_mv() { return _should_mv; }
|
||||
bool_t force() { return _force; }
|
||||
bool_t tt_opened() { return _tt_opened; }
|
||||
|
||||
private:
|
||||
_Tt_string _process_name;
|
||||
_Tt_string _prog_name;
|
||||
_Tt_string _process_id;
|
||||
_Tt_string_list_ptr _args;
|
||||
bool_t _should_mv;
|
||||
bool_t _force;
|
||||
bool_t _tt_opened;
|
||||
_Tt_string_list_ptr _from_paths;
|
||||
_Tt_string _to_path;
|
||||
bool_t _to_path_is_dir;
|
||||
};
|
||||
|
||||
#endif /* _MOVER_H */
|
||||
371
cde/lib/tt/bin/shell/rcopier.C
Normal file
371
cde/lib/tt/bin/shell/rcopier.C
Normal file
@@ -0,0 +1,371 @@
|
||||
//%% (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: rcopier.C /main/3 1995/10/20 16:36:32 rswiston $
|
||||
/*
|
||||
* rcopier.cc - Link Service/ToolTalk wrapper for rcp(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tt_options.h"
|
||||
#include <string.h>
|
||||
#ifdef __osf__
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#ifndef USL
|
||||
#include <osfcn.h>
|
||||
#endif
|
||||
#endif
|
||||
#if defined(OPT_BUG_SUNOS_4)
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
#include <api/c/tt_c.h>
|
||||
#include <util/tt_path.h>
|
||||
#include <util/tt_enumname.h>
|
||||
#include <util/copyright.h>
|
||||
#include "rcopier.h"
|
||||
|
||||
/*
|
||||
* External variables
|
||||
*/
|
||||
|
||||
implement_list_of(rpath)
|
||||
|
||||
/*
|
||||
* rpath::rpath()
|
||||
*/
|
||||
rpath::
|
||||
rpath()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* rpath::~rpath()
|
||||
*/
|
||||
rpath::
|
||||
~rpath()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* rpath::rpath()
|
||||
*/
|
||||
rpath::
|
||||
rpath( _Tt_string)
|
||||
{
|
||||
/*
|
||||
* host:path
|
||||
* user@host:path
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* rcopier::rcopier()
|
||||
*/
|
||||
rcopier::
|
||||
rcopier( char *arg0 )
|
||||
{
|
||||
if (arg0 != NULL) {
|
||||
char *base = strrchr( arg0, '/' );
|
||||
if (base == NULL) {
|
||||
base = arg0;
|
||||
} else {
|
||||
base++; /* Don't want the '/' */
|
||||
}
|
||||
_prog_name = base;
|
||||
_process_name = _prog_name;
|
||||
}
|
||||
_args = new _Tt_string_list();
|
||||
_from_paths = new rpath_list();
|
||||
_should_rcp = TRUE;
|
||||
_recurse = FALSE;
|
||||
_preserve = FALSE;
|
||||
_tt_opened = FALSE;
|
||||
}
|
||||
|
||||
rcopier::
|
||||
~rcopier()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* rcopier::do_rcp() - Use system() to invoke rcp(1), and return its exit status.
|
||||
* We can just use _args, since we never get here when our one
|
||||
* rcp-incompatible option (-L) has been given.
|
||||
*/
|
||||
int rcopier::
|
||||
do_rcp()
|
||||
{
|
||||
_Tt_string cmd( "rcp" );
|
||||
_Tt_string_list_cursor arg_cursor( _args );
|
||||
|
||||
while (arg_cursor.next()) {
|
||||
cmd = cmd.cat( " " ).cat( *arg_cursor );
|
||||
}
|
||||
printf( "Invoking: %s\n", (char *)cmd );
|
||||
int sys_status = system( (char *)cmd );
|
||||
if (WIFEXITED(sys_status)) {
|
||||
return WEXITSTATUS(sys_status);
|
||||
} else {
|
||||
fprintf( stderr,
|
||||
"%s: I invoked rcp(1), but system() returned "
|
||||
"%d, which is not an exit status!\n",
|
||||
(char *)_process_name, sys_status );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* rcopier::do_ttrcp() - Use tttar(1) to copy the objects of the _from_paths.
|
||||
*
|
||||
* Algorithm:
|
||||
*
|
||||
* [rsh fromhost -l user] tttar cfhL - frompath |
|
||||
* [rsh tohost -l user] tttar xfL - -rename frompath topath
|
||||
*
|
||||
* TO_DO: this won't work if topath is a directory. If it's a
|
||||
* remote directory, how do we find this out?
|
||||
* }
|
||||
*/
|
||||
Tt_status rcopier::
|
||||
do_ttrcp()
|
||||
{
|
||||
rpath_list_cursor from_path_cursor( _from_paths );
|
||||
|
||||
/*
|
||||
* TO_DO: tt_file_destroy() any paths that rcp(1) will delete
|
||||
*/
|
||||
while (from_path_cursor.next()) {
|
||||
_Tt_string cmd;
|
||||
rpath_ptr rp = *from_path_cursor;
|
||||
|
||||
if (rp->host().len() >= 0) {
|
||||
cmd = cmd.cat( "rsh ").cat( rp->host()).cat( " -l ")
|
||||
.cat( _username ).cat( " " );
|
||||
}
|
||||
cmd = cmd.cat( "tttar cfhL - " ).cat( rp->path()).cat(" | ");
|
||||
if (_to_path->host().len() >= 0) {
|
||||
cmd = cmd.cat( "rsh ").cat( _to_path->host())
|
||||
.cat( " -l ").cat( _username ).cat( " " );
|
||||
}
|
||||
cmd = cmd.cat( "tttar xfL" );
|
||||
if (_preserve) {
|
||||
cmd = cmd.cat( "p" );
|
||||
}
|
||||
cmd = cmd.cat( " - -rename " ).cat( rp->path())
|
||||
.cat( _to_path->path());
|
||||
printf( "Invoking: %s\n", (char *)cmd );
|
||||
int sys_status = system( (char *)cmd );
|
||||
if (WIFEXITED(sys_status)) {
|
||||
if (WEXITSTATUS(sys_status) != 0) {
|
||||
return TT_ERR_INTERNAL;
|
||||
}
|
||||
} else {
|
||||
fprintf( stderr,
|
||||
"%s: invoked tttar(1), but system() returned "
|
||||
"%d, which is not an exit status!\n",
|
||||
(char *)_process_name, sys_status );
|
||||
return TT_ERR_INTERNAL;
|
||||
}
|
||||
}
|
||||
return TT_OK;
|
||||
|
||||
} /* do_ttrcp() */
|
||||
|
||||
/*
|
||||
* rcopier::open_tt()
|
||||
*/
|
||||
Tt_status rcopier::
|
||||
open_tt()
|
||||
{
|
||||
char *process_id = tt_open();
|
||||
Tt_status err = tt_ptr_error( process_id );
|
||||
if (err == TT_OK) {
|
||||
_process_id = process_id;
|
||||
_tt_opened = TRUE;
|
||||
} else if (err > TT_WRN_LAST) {
|
||||
fprintf( stderr,
|
||||
"%s: Could not initialize ToolTalk because %s\n",
|
||||
(char *)_process_name,
|
||||
#ifndef TT_STATUS_MSG_TO_DO
|
||||
_tt_enumname( (Tt_status)err )
|
||||
#else
|
||||
tt_status_message( err )
|
||||
#endif
|
||||
);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* rcopier::close_tt()
|
||||
*/
|
||||
Tt_status rcopier::
|
||||
close_tt()
|
||||
{
|
||||
if (! _tt_opened) {
|
||||
return TT_OK;
|
||||
}
|
||||
Tt_status err = tt_close();
|
||||
if (err > TT_WRN_LAST) {
|
||||
fprintf( stderr,
|
||||
"%s: Could not close ToolTalk because %s\n",
|
||||
(char *)_process_name,
|
||||
#ifndef TT_STATUS_MSG_TO_DO
|
||||
_tt_enumname( (Tt_status)err )
|
||||
#else
|
||||
tt_status_message( err )
|
||||
#endif
|
||||
);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* rcopier::parse_args()
|
||||
*/
|
||||
void rcopier::
|
||||
parse_args( int argc, char **argv )
|
||||
{
|
||||
for ( int arg_num = 1; arg_num < argc; arg_num++ ) {
|
||||
_Tt_string arg( argv[arg_num] );
|
||||
_args->append( arg );
|
||||
if (arg[0] == '-') {
|
||||
this->_parse_arg( (char *)arg );
|
||||
} else {
|
||||
if (arg_num == argc - 1) {
|
||||
_to_path = new rpath( arg );
|
||||
} else {
|
||||
rpath_ptr rp = new rpath( arg );
|
||||
_from_paths->append( rp );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_to_path->path().len() <= 0) {
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
if (_from_paths->count() <= 0) {
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
if (_from_paths->count() > 1) {
|
||||
/*
|
||||
* If multiple things to move, the place we're
|
||||
* moving them to must be a directory.
|
||||
*/
|
||||
if (_to_path->host().len() <= 0) {
|
||||
/*
|
||||
* to_path is local. Yay!
|
||||
*/
|
||||
struct stat stat_buf;
|
||||
|
||||
if (stat( (char *)_to_path->path(), &stat_buf) != 0) {
|
||||
fprintf( stderr, "%s: %s: ",
|
||||
(char *)_process_name,
|
||||
(char *)_to_path->path() );
|
||||
perror(NULL);
|
||||
exit(2);
|
||||
}
|
||||
if (! S_ISDIR(stat_buf.st_mode)) {
|
||||
fprintf( stderr, "%s: %s is not a directory\n",
|
||||
(char *)_process_name,
|
||||
(char *)_to_path->path() );
|
||||
this->usage();
|
||||
exit(2);
|
||||
}
|
||||
_to_path_is_dir = TRUE;
|
||||
} else {
|
||||
/*
|
||||
* TO_DO: figure out if remote path is dir or not
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
if (_to_path->host().len() <= 0) {
|
||||
struct stat stat_buf;
|
||||
|
||||
_to_path_is_dir = FALSE;
|
||||
if (stat( (char *)_to_path->path(), &stat_buf) == 0) {
|
||||
_to_path_is_dir = S_ISDIR(stat_buf.st_mode);
|
||||
}
|
||||
/*
|
||||
* I don't think rcp has a clonedir mode. (see ttcp)
|
||||
else {
|
||||
_Tt_string from_path = _from_paths->top();
|
||||
if ( (_from_paths->count() == 1)
|
||||
&& (stat( (char *)from_path, &stat_buf) == 0)
|
||||
&& S_ISDIR(stat_buf.st_mode))
|
||||
{
|
||||
_clonedir_mode = TRUE;
|
||||
_to_path_is_dir = TRUE;
|
||||
}
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* TO_DO: figure out if remote path is dir or not
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
} /* parse_args() */
|
||||
|
||||
/*
|
||||
* rcopier::_parse_arg() - Parse an option
|
||||
*/
|
||||
void rcopier::
|
||||
_parse_arg( char *arg )
|
||||
{
|
||||
if (arg == NULL) {
|
||||
return;
|
||||
}
|
||||
int n = -1;
|
||||
while (arg[++n] != '\0') {
|
||||
switch (arg[n]) {
|
||||
case '-':
|
||||
if (n != 0) {
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
_should_rcp = FALSE;
|
||||
break;
|
||||
case 'p':
|
||||
_preserve = TRUE;
|
||||
break;
|
||||
case 'r':
|
||||
_recurse = TRUE;
|
||||
break;
|
||||
case 'v':
|
||||
_TT_PRINT_VERSIONS((char *)_prog_name)
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} /* _parse_arg() */
|
||||
|
||||
/*
|
||||
* rcopier::usage()
|
||||
*/
|
||||
void rcopier::
|
||||
usage(FILE *fs) const
|
||||
{
|
||||
fprintf( fs,
|
||||
"Usage: %s [-pL] file1 file2\n"
|
||||
" %s [-prL] path1 [path2 ...] dir\n"
|
||||
" %s -v\n"
|
||||
" %s -h\n",
|
||||
(char *)_prog_name, (char *)_prog_name, (char *)_prog_name,
|
||||
(char *)_prog_name );
|
||||
fprintf( fs, "\t-L do not perform a rcp(1)\n" );
|
||||
fprintf( fs, "\t-v print the version number and quit\n" );
|
||||
fprintf( fs, "\t-h[elp] print this message\n" );
|
||||
}
|
||||
65
cde/lib/tt/bin/shell/rcopier.h
Normal file
65
cde/lib/tt/bin/shell/rcopier.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: rcopier.h /main/3 1995/10/20 16:36:39 rswiston $ */
|
||||
/*
|
||||
* rcopier.h - Interface to rcopier, an LS/TT-aware rcp(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _RCOPIER_H
|
||||
#define _RCOPIER_H
|
||||
|
||||
#include <api/c/tt_c.h>
|
||||
#include <util/tt_string.h>
|
||||
|
||||
class rpath : public _Tt_object {
|
||||
public:
|
||||
rpath();
|
||||
rpath( _Tt_string r_path );
|
||||
virtual ~rpath();
|
||||
_Tt_string host() { return _host; }
|
||||
_Tt_string path() { return _path; }
|
||||
|
||||
private:
|
||||
_Tt_string _host;
|
||||
_Tt_string _path;
|
||||
};
|
||||
|
||||
declare_list_of(rpath)
|
||||
|
||||
class rcopier : public _Tt_object {
|
||||
public:
|
||||
rcopier( char *arg0 );
|
||||
virtual ~rcopier();
|
||||
|
||||
int do_rcp();
|
||||
Tt_status do_ttrcp();
|
||||
Tt_status open_tt();
|
||||
Tt_status close_tt();
|
||||
void parse_args( int argc, char **argv );
|
||||
void usage( FILE *fs = stderr ) const;
|
||||
bool_t should_rcp() { return _should_rcp; }
|
||||
bool_t tt_opened() { return _tt_opened; }
|
||||
|
||||
private:
|
||||
void _parse_arg( char *arg );
|
||||
|
||||
_Tt_string _process_name;
|
||||
_Tt_string _prog_name;
|
||||
_Tt_string _process_id;
|
||||
_Tt_string_list_ptr _args;
|
||||
bool_t _should_rcp;
|
||||
bool_t _tt_opened;
|
||||
_Tt_string _username;
|
||||
bool_t _preserve;
|
||||
bool_t _recurse;
|
||||
rpath_list_ptr _from_paths;
|
||||
rpath_ptr _to_path;
|
||||
bool_t _to_path_is_dir;
|
||||
};
|
||||
|
||||
#endif /* _RCOPIER_H */
|
||||
376
cde/lib/tt/bin/shell/remover.C
Normal file
376
cde/lib/tt/bin/shell/remover.C
Normal file
@@ -0,0 +1,376 @@
|
||||
//%% (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: remover.C /main/5 1999/10/14 18:37:42 mgreess $
|
||||
/*
|
||||
* remover.cc - ToolTalk wrapper for rm(1) and rmdir(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tt_options.h"
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#ifdef __osf__
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#if !defined(USL) && !defined(__uxp__)
|
||||
#include <osfcn.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#if defined(ultrix)
|
||||
#include <sys/inode.h>
|
||||
#define S_ISLNK(m) (((m)&IFMT) == IFLNK)
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#if defined(OPT_BUG_USL) || defined(OPT_BUG_UXP)
|
||||
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
#include <sys/wait.h>
|
||||
#include "api/c/tt_c.h"
|
||||
#include "util/tt_path.h"
|
||||
#include "util/tt_gettext.h"
|
||||
#include "util/copyright.h"
|
||||
#include "remover.h"
|
||||
|
||||
/*
|
||||
* External variables
|
||||
*/
|
||||
|
||||
/*
|
||||
* remover::remover()
|
||||
*/
|
||||
remover::
|
||||
remover( char *arg0 )
|
||||
{
|
||||
if (arg0 != NULL) {
|
||||
char *base = strrchr( arg0, '/' );
|
||||
if (base == NULL) {
|
||||
base = arg0;
|
||||
} else {
|
||||
base++;
|
||||
}
|
||||
_prog_name = base;
|
||||
_process_name = _prog_name;
|
||||
}
|
||||
_am_rmdir = (_prog_name == "ttrmdir");
|
||||
_args = new _Tt_string_list();
|
||||
_paths = new _Tt_string_list();
|
||||
_should_rm = TRUE;
|
||||
_force = FALSE;
|
||||
_recurse = FALSE;
|
||||
_tt_opened = FALSE;
|
||||
}
|
||||
|
||||
remover::
|
||||
~remover()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* remover::do_rm() - Invoke rm[dir](1), and return its exit status.
|
||||
* We can just use _args, since we never get here when our one
|
||||
* incompatible option (-L) has been given.
|
||||
*/
|
||||
int remover::
|
||||
do_rm()
|
||||
{
|
||||
_Tt_string cmd;
|
||||
_Tt_string_list_cursor arg_cursor( _args );
|
||||
|
||||
if (_am_rmdir) {
|
||||
cmd = "rmdir";
|
||||
} else {
|
||||
cmd = "rm";
|
||||
}
|
||||
while (arg_cursor.next()) {
|
||||
cmd = cmd.cat( " " ).cat( *arg_cursor );
|
||||
}
|
||||
//printf( "Invoking: %s\n", (char *)cmd );
|
||||
int sys_status = system( (char *)cmd );
|
||||
if (WIFEXITED(sys_status)) {
|
||||
return WEXITSTATUS(sys_status);
|
||||
} else {
|
||||
fprintf( stderr,
|
||||
"%s: system(\"%s\"): %d\n",
|
||||
(char *)_process_name, (char *)cmd, sys_status );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remover::do_ttrm() - Use tt_file_destroy() on the paths to destroy.
|
||||
*/
|
||||
Tt_status remover::
|
||||
do_ttrm()
|
||||
{
|
||||
return this->_ttrm_paths( _paths );
|
||||
}
|
||||
|
||||
/*
|
||||
* remover::ttrm_path() - tt_file_destroy() this path.
|
||||
*/
|
||||
Tt_status remover::
|
||||
_ttrm_paths( _Tt_string_list_ptr paths )
|
||||
{
|
||||
Tt_status worst_err = TT_OK;
|
||||
Tt_status err;
|
||||
bool_t abort = FALSE;
|
||||
|
||||
while ((! paths->is_empty()) && (! abort)) {
|
||||
_Tt_string path = paths->top();
|
||||
_Tt_string_list_ptr children;
|
||||
|
||||
paths->pop();
|
||||
if (! this->can_rm( path )) {
|
||||
continue;
|
||||
}
|
||||
if (_recurse) {
|
||||
_Tt_string_list_ptr children = _tt_dir_entries(path,
|
||||
FALSE);
|
||||
err = this->_ttrm_paths( children );
|
||||
if (err > TT_WRN_LAST) {
|
||||
switch (err) {
|
||||
case TT_ERR_DBAVAIL:
|
||||
case TT_ERR_PATH:
|
||||
break;
|
||||
case TT_ERR_NOMP:
|
||||
case TT_ERR_DBEXIST:
|
||||
default:
|
||||
abort = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (! abort) {
|
||||
err = tt_file_destroy( (char *)path );
|
||||
if (err > TT_WRN_LAST) {
|
||||
worst_err = err;
|
||||
if (! _force) {
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 8, 7,
|
||||
"%s: Could not remove "
|
||||
"ToolTalk objects of "
|
||||
"%s because %s\n"),
|
||||
(char *)_process_name,
|
||||
(char *)path,
|
||||
tt_status_message(err) );
|
||||
}
|
||||
switch (err) {
|
||||
case TT_ERR_DBAVAIL:
|
||||
case TT_ERR_PATH:
|
||||
break;
|
||||
case TT_ERR_NOMP:
|
||||
case TT_ERR_DBEXIST:
|
||||
default:
|
||||
abort = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return worst_err;
|
||||
|
||||
} /* ttrm_paths() */
|
||||
|
||||
/*
|
||||
* remover::can_rm() - Can we remove this path?
|
||||
*
|
||||
* TO_DO: For now I'll count on tt_file_destroy() not to let me
|
||||
* destroy the specs in files I can't remove.
|
||||
*/
|
||||
bool_t remover::
|
||||
can_rm( _Tt_string path )
|
||||
{
|
||||
if (_am_rmdir) {
|
||||
} else {
|
||||
if (! _recurse) {
|
||||
struct stat lstat_buf;
|
||||
|
||||
if (lstat( (char *)path, &lstat_buf) == 0) {
|
||||
if (S_ISDIR(lstat_buf.st_mode)) {
|
||||
/*
|
||||
* rm(1) without the -r flag
|
||||
* won't remove directories,
|
||||
* but tt_file_destroy() will,
|
||||
* so we make sure not to ask
|
||||
* it to.
|
||||
*/
|
||||
if (! _force) {
|
||||
fprintf( stderr, "%s: %s: %s\n",
|
||||
(char *)_prog_name,
|
||||
(char *)path,
|
||||
strerror(EISDIR) );
|
||||
}
|
||||
return FALSE;
|
||||
} else if (S_ISLNK(lstat_buf.st_mode)) {
|
||||
/*
|
||||
* Don't tt_file_destroy() a symlink,
|
||||
* or TT will tt_file_destroy() the
|
||||
* linked file.
|
||||
*/
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* remover::open_tt()
|
||||
*/
|
||||
Tt_status remover::
|
||||
open_tt()
|
||||
{
|
||||
char *process_id = tt_open();
|
||||
Tt_status err = tt_ptr_error( process_id );
|
||||
if (err == TT_OK) {
|
||||
_process_id = process_id;
|
||||
_tt_opened = TRUE;
|
||||
} else if (err > TT_WRN_LAST) {
|
||||
fprintf( stderr,
|
||||
"%s: tt_open(): %s\n",
|
||||
(char *)_process_name, tt_status_message(err) );
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* remover::close_tt()
|
||||
*/
|
||||
Tt_status remover::
|
||||
close_tt()
|
||||
{
|
||||
if (! _tt_opened) {
|
||||
return TT_OK;
|
||||
}
|
||||
Tt_status err = tt_close();
|
||||
if (err > TT_WRN_LAST) {
|
||||
fprintf( stderr,
|
||||
"%s: tt_close(): %s\n",
|
||||
(char *)_process_name, tt_status_message(err) );
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* remover::parse_args()
|
||||
*/
|
||||
void remover::
|
||||
parse_args( int argc, char **argv )
|
||||
{
|
||||
bool_t no_more_options = FALSE;
|
||||
|
||||
for ( int arg_num = 1; arg_num < argc; arg_num++ ) {
|
||||
_Tt_string arg( argv[arg_num] );
|
||||
_args->append( arg );
|
||||
if (_am_rmdir) {
|
||||
if (arg[0] == '-') {
|
||||
this->_parse_arg( (char *)arg );
|
||||
} else {
|
||||
_paths->append( arg );
|
||||
}
|
||||
} else {
|
||||
if ((arg[0] != '-') || no_more_options) {
|
||||
_paths->append( arg );
|
||||
} else {
|
||||
if (arg[1] == '\0') {
|
||||
/*
|
||||
* The bare option "-" means take the
|
||||
* subsequent arguments to be paths.
|
||||
*/
|
||||
no_more_options = TRUE;
|
||||
} else {
|
||||
this->_parse_arg( (char *)arg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_paths->count() <= 0) {
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remover::_parse_arg() - Parse an option
|
||||
*/
|
||||
void remover::
|
||||
_parse_arg( char *arg )
|
||||
{
|
||||
if (arg == NULL) {
|
||||
return;
|
||||
}
|
||||
int n = -1;
|
||||
while (arg[++n] != '\0') {
|
||||
switch (arg[n]) {
|
||||
case '-':
|
||||
if (n != 0) {
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
if (_am_rmdir) {
|
||||
this->usage();
|
||||
exit(1);
|
||||
} else {
|
||||
_force = TRUE;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
if (_am_rmdir) {
|
||||
this->usage();
|
||||
exit(1);
|
||||
} else {
|
||||
_recurse = TRUE;
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
_should_rm = FALSE;
|
||||
break;
|
||||
case 'v':
|
||||
_TT_PRINT_VERSIONS((char *)_prog_name)
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
this->usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remover::usage()
|
||||
*/
|
||||
void remover::
|
||||
usage(FILE *fs) const
|
||||
{
|
||||
fprintf( fs,
|
||||
catgets(_ttcatd, 8, 8,
|
||||
"Usage: %s [-] [-%s] %s ...\n"
|
||||
" %s -v\n"
|
||||
" %s -h\n"),
|
||||
(char *)_prog_name,
|
||||
(_am_rmdir ? "L" : "fLrR"),
|
||||
(_am_rmdir ? catgets(_ttcatd, 8, 9, "file")
|
||||
: catgets(_ttcatd, 8, 10, "dir") ),
|
||||
(char *)_prog_name, (char *)_prog_name );
|
||||
fprintf( fs,
|
||||
catgets(_ttcatd, 8, 11,
|
||||
"\t-L do not perform a %s(1)\n"
|
||||
"\t-v print the version number and quit\n"
|
||||
"\t-h[elp] print this message\n" ),
|
||||
(_am_rmdir ? "rmdir" : "rm"));
|
||||
}
|
||||
51
cde/lib/tt/bin/shell/remover.h
Normal file
51
cde/lib/tt/bin/shell/remover.h
Normal 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: remover.h /main/3 1995/10/20 16:36:57 rswiston $ */
|
||||
/*
|
||||
* remover.h - Interface to remover, an LS/TT-aware rm(1) and rmdir(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _REMOVER_H
|
||||
#define _REMOVER_H
|
||||
|
||||
#include <api/c/tt_c.h>
|
||||
#include <util/tt_string.h>
|
||||
|
||||
class remover : public _Tt_object {
|
||||
public:
|
||||
remover( char *arg0 );
|
||||
virtual ~remover();
|
||||
|
||||
int do_rm();
|
||||
Tt_status do_ttrm();
|
||||
bool_t can_rm( _Tt_string path );
|
||||
Tt_status open_tt();
|
||||
Tt_status close_tt();
|
||||
void parse_args( int argc, char **argv );
|
||||
void usage( FILE *fs = stderr ) const;
|
||||
bool_t should_rm() { return _should_rm; }
|
||||
bool_t force() { return _force; }
|
||||
bool_t tt_opened() { return _tt_opened; }
|
||||
|
||||
private:
|
||||
Tt_status _ttrm_paths( _Tt_string_list_ptr paths );
|
||||
void _parse_arg( char *arg );
|
||||
|
||||
_Tt_string _process_name;
|
||||
_Tt_string _prog_name;
|
||||
_Tt_string _process_id;
|
||||
_Tt_string_list_ptr _args;
|
||||
bool_t _should_rm;
|
||||
bool_t _force;
|
||||
bool_t _recurse;
|
||||
bool_t _am_rmdir;
|
||||
bool_t _tt_opened;
|
||||
_Tt_string_list_ptr _paths;
|
||||
};
|
||||
|
||||
#endif /* _REMOVER_H */
|
||||
56
cde/lib/tt/bin/shell/ttcp.C
Normal file
56
cde/lib/tt/bin/shell/ttcp.C
Normal file
@@ -0,0 +1,56 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: ttcp.C /main/3 1995/10/20 16:37:11 rswiston $
|
||||
/* @(#)ttcp.C 1.12 93/07/30
|
||||
* ttcp.cc - Link Service/ToolTalk wrapper for cp(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
#include <util/copyright.h>
|
||||
#include <tt_options.h>
|
||||
#include "copier.h"
|
||||
|
||||
TT_INSERT_COPYRIGHT
|
||||
|
||||
#ifdef OPT_PATCH
|
||||
static char PatchID[] = "Patch Id: 100626_03.";
|
||||
static int Patch_ID100626_03;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* main()
|
||||
*/
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Tt_status tterr = TT_OK;
|
||||
copier *ttcp = new copier( argv[0] );
|
||||
|
||||
setlocale( LC_ALL, "" );
|
||||
ttcp->parse_args( argc, argv );
|
||||
|
||||
if (ttcp->should_cp()) {
|
||||
int err = ttcp->do_cp();
|
||||
if (err != 0) {
|
||||
exit( err );
|
||||
}
|
||||
}
|
||||
|
||||
tterr = ttcp->open_tt();
|
||||
if (ttcp->tt_opened()) {
|
||||
tterr = ttcp->do_ttcp();
|
||||
}
|
||||
(void)ttcp->close_tt();
|
||||
|
||||
if (tterr > TT_WRN_LAST) {
|
||||
exit(1);
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
62
cde/lib/tt/bin/shell/ttmv.C
Normal file
62
cde/lib/tt/bin/shell/ttmv.C
Normal file
@@ -0,0 +1,62 @@
|
||||
//%% (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: ttmv.C /main/3 1995/10/20 16:37:18 rswiston $
|
||||
/* @(#)ttmv.C 1.13 93/07/30
|
||||
* ttmv.cc - Link Service/ToolTalk wrapper for mv(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
#include <util/copyright.h>
|
||||
#include "mover.h"
|
||||
|
||||
TT_INSERT_COPYRIGHT
|
||||
|
||||
#ifdef OPT_PATCH
|
||||
static char PatchID[] = "Patch Id: 100626_03.";
|
||||
static int Patch_ID100626_03;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* main()
|
||||
*/
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Tt_status tterr = TT_OK;
|
||||
mover *ttmv = new mover( argv[0] );
|
||||
|
||||
setlocale( LC_ALL , "" );
|
||||
ttmv->parse_args( argc, argv );
|
||||
tterr = ttmv->open_tt();
|
||||
|
||||
if (ttmv->tt_opened()) {
|
||||
tterr = ttmv->do_ttmv();
|
||||
}
|
||||
if ( ttmv->should_mv()
|
||||
/*
|
||||
* I take the -f option pretty seriously, so I'll move
|
||||
* the actual files even though the ttmv failed.
|
||||
*/
|
||||
&& ((tterr <= TT_WRN_LAST) || ttmv->force()))
|
||||
{
|
||||
int err = ttmv->do_mv();
|
||||
if (err != 0) {
|
||||
(void)ttmv->close_tt();
|
||||
exit( err );
|
||||
}
|
||||
}
|
||||
|
||||
(void)ttmv->close_tt();
|
||||
|
||||
if ((tterr > TT_WRN_LAST) && (! ttmv->force())) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
50
cde/lib/tt/bin/shell/ttrcp.C
Normal file
50
cde/lib/tt/bin/shell/ttrcp.C
Normal file
@@ -0,0 +1,50 @@
|
||||
//%% (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: ttrcp.C /main/3 1995/10/20 16:37:27 rswiston $
|
||||
/*
|
||||
* ttrcp.cc - Link Service/ToolTalk wrapper for rcp(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
#include <util/copyright.h>
|
||||
#include "rcopier.h"
|
||||
|
||||
TT_INSERT_COPYRIGHT
|
||||
|
||||
/*
|
||||
* main()
|
||||
*/
|
||||
void
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Tt_status tterr = TT_OK;
|
||||
rcopier *ttrcp = new rcopier( argv[0] );
|
||||
|
||||
setlocale( LC_ALL, "" );
|
||||
ttrcp->parse_args( argc, argv );
|
||||
|
||||
if (ttrcp->should_rcp()) {
|
||||
int err = ttrcp->do_rcp();
|
||||
if (err != 0) {
|
||||
exit( err );
|
||||
}
|
||||
}
|
||||
|
||||
tterr = ttrcp->open_tt();
|
||||
if (ttrcp->tt_opened()) {
|
||||
tterr = ttrcp->do_ttrcp();
|
||||
}
|
||||
(void)ttrcp->close_tt();
|
||||
|
||||
if (tterr > TT_WRN_LAST) {
|
||||
exit(1);
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
63
cde/lib/tt/bin/shell/ttrm.C
Normal file
63
cde/lib/tt/bin/shell/ttrm.C
Normal 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: ttrm.C /main/3 1995/10/20 16:37:34 rswiston $
|
||||
/* @(#)ttrm.C 1.12 93/07/30
|
||||
* ttrm.cc - Link Service/ToolTalk wrapper for rm(1).
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
#include <util/copyright.h>
|
||||
#include <tt_options.h>
|
||||
#include "remover.h"
|
||||
|
||||
/*
|
||||
* External variables
|
||||
*/
|
||||
|
||||
TT_INSERT_COPYRIGHT
|
||||
|
||||
#ifdef OPT_PATCH
|
||||
static char PatchID[] = "Patch Id: 100626_03.";
|
||||
static int Patch_ID100626_03;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* main()
|
||||
*/
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Tt_status tterr = TT_OK;
|
||||
remover *ttrm = new remover( argv[0] );
|
||||
|
||||
setlocale( LC_ALL, "" );
|
||||
ttrm->parse_args( argc, argv );
|
||||
tterr = ttrm->open_tt();
|
||||
|
||||
if (ttrm->tt_opened()) {
|
||||
tterr = ttrm->do_ttrm();
|
||||
}
|
||||
if ( ttrm->should_rm()
|
||||
&& ((tterr <= TT_WRN_LAST) || ttrm->force()))
|
||||
{
|
||||
int err = ttrm->do_rm();
|
||||
if (err != 0) {
|
||||
(void)ttrm->close_tt();
|
||||
exit( err );
|
||||
}
|
||||
}
|
||||
|
||||
(void)ttrm->close_tt();
|
||||
|
||||
if ((tterr > TT_WRN_LAST) && (! ttrm->force())) {
|
||||
exit(1);
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
37
cde/lib/tt/bin/tt_type_comp/Imakefile
Normal file
37
cde/lib/tt/bin/tt_type_comp/Imakefile
Normal file
@@ -0,0 +1,37 @@
|
||||
XCOMM $XConsortium: Imakefile /main/14 1996/05/08 09:28:02 drk $
|
||||
|
||||
#define CplusplusSource YES
|
||||
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
|
||||
EXTRA_LOAD_FLAGS = ExtraLoadFlags $(UNSHARED_CXXLIB)
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#include "../../tooltalk.tmpl"
|
||||
|
||||
DEFINES =
|
||||
INCLUDES = -I../../lib -I../../slib
|
||||
|
||||
DEPLIBS = ../../slib/libstt.a TtClientDepLibs
|
||||
LOCAL_LIBRARIES = ../../slib/libstt.a TtClientLibs
|
||||
SYS_LIBRARIES =
|
||||
|
||||
#ifdef TtClientExtraLibs
|
||||
EXTRA_LIBRARIES = TtClientExtraLibs
|
||||
#endif
|
||||
|
||||
SRCS = mp_type_comp.C mp_types_table.C \
|
||||
frozen.mp_types_lex.C frozen.mp_types_gram.C
|
||||
|
||||
OBJS = mp_type_comp.o mp_types_table.o \
|
||||
frozen.mp_types_lex.o frozen.mp_types_gram.o
|
||||
|
||||
NormalCplusplusObjectRule()
|
||||
|
||||
ComplexCplusplusProgramTarget(tt_type_comp)
|
||||
|
||||
SpecialCplusplusObjectRule(mp_type_comp,mp_type_comp,$(TT_VERSION_DEFINE))
|
||||
|
||||
frozen.mp_types_lex.o: mp_types_gram.h
|
||||
|
||||
LinkFile(mp_types_gram.h,frozen.mp_types_gram.h)
|
||||
|
||||
11
cde/lib/tt/bin/tt_type_comp/admindefines
Normal file
11
cde/lib/tt/bin/tt_type_comp/admindefines
Normal file
@@ -0,0 +1,11 @@
|
||||
XCOMM $XConsortium: admindefines /main/2 1996/05/07 19:16:29 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
|
||||
1115
cde/lib/tt/bin/tt_type_comp/frozen.mp_types_gram.C
Normal file
1115
cde/lib/tt/bin/tt_type_comp/frozen.mp_types_gram.C
Normal file
File diff suppressed because it is too large
Load Diff
46
cde/lib/tt/bin/tt_type_comp/frozen.mp_types_gram.h
Normal file
46
cde/lib/tt/bin/tt_type_comp/frozen.mp_types_gram.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* $XConsortium: frozen.mp_types_gram.h /main/3 1995/10/20 16:38:17 rswiston $ */
|
||||
|
||||
typedef union
|
||||
#ifdef __cplusplus
|
||||
YYSTYPE
|
||||
#endif
|
||||
{
|
||||
int num;
|
||||
char *str;
|
||||
} YYSTYPE;
|
||||
extern YYSTYPE yylval;
|
||||
# define PER_FILE 257
|
||||
# define PER_SESSION 258
|
||||
# define START 259
|
||||
# define FILE_SCOPE 260
|
||||
# define SESSION_SCOPE 261
|
||||
# define FILE_IN_SESSION 262
|
||||
# define REQUEST 263
|
||||
# define NOTIFICATION 264
|
||||
# define VOID_ARGS 265
|
||||
# define QUEUE 266
|
||||
# define OPNUM 267
|
||||
# define IN 268
|
||||
# define OUT 269
|
||||
# define INOUT 270
|
||||
# define OTYPE 271
|
||||
# define INHERIT 272
|
||||
# define FROM 273
|
||||
# define PTYPE 274
|
||||
# define OBSERVE 275
|
||||
# define HANDLE 276
|
||||
# define HANDLE_PUSH 277
|
||||
# define HANDLE_ROTATE 278
|
||||
# define COLON 279
|
||||
# define SEMICOLON 280
|
||||
# define LCURL 281
|
||||
# define RCURL 282
|
||||
# define INFER 283
|
||||
# define LPAREN 284
|
||||
# define RPAREN 285
|
||||
# define COMMA 286
|
||||
# define EQUAL 287
|
||||
# define CONTEXT 288
|
||||
# define TT_IDENTIFIER 289
|
||||
# define TT_STRING 290
|
||||
# define TT_NUMBER 291
|
||||
1274
cde/lib/tt/bin/tt_type_comp/frozen.mp_types_lex.C
Normal file
1274
cde/lib/tt/bin/tt_type_comp/frozen.mp_types_lex.C
Normal file
File diff suppressed because it is too large
Load Diff
719
cde/lib/tt/bin/tt_type_comp/mp_type_comp.C
Normal file
719
cde/lib/tt/bin/tt_type_comp/mp_type_comp.C
Normal file
@@ -0,0 +1,719 @@
|
||||
//%% (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_type_comp.C /main/4 1999/10/14 18:37:58 mgreess $
|
||||
/*
|
||||
*
|
||||
* mp_type_comp.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* ToolTalk type compiler. Performs syntax and semantics checks on
|
||||
* type input file and then writes out the type table in xdr format
|
||||
* or in Classing Engine format.
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined(sgi)
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#if defined(USL) || defined(__uxp__)
|
||||
#include "tt_options.h"
|
||||
#if defined(OPT_BUG_USL) || defined(OPT_BUG_UXP)
|
||||
extern "C" int getopt(int, char *const *, const char *);
|
||||
#endif
|
||||
#endif
|
||||
#include "mp/mp_global.h"
|
||||
#include "mp/mp_mp.h"
|
||||
#include "mp_otype.h"
|
||||
#include "mp_ptype.h"
|
||||
#include "mp_types_table.h"
|
||||
#include "mp_typedb.h"
|
||||
#include "util/copyright.h"
|
||||
#include "util/tt_global_env.h"
|
||||
#include "util/tt_xdr_version.h"
|
||||
#include "util/tt_port.h"
|
||||
#include "util/tt_gettext.h"
|
||||
|
||||
#define _TT_DBCLIENT_SIDE
|
||||
#include "db/db_server.h"
|
||||
|
||||
#if defined(ultrix)
|
||||
extern "C" void xdrstdio_create(XDR *, FILE *, enum xdr_op);
|
||||
#endif
|
||||
|
||||
typedef void (*cmd_fn)();
|
||||
|
||||
TT_INSERT_COPYRIGHT
|
||||
|
||||
#ifdef OPT_PATCH
|
||||
static char PatchID[] = "Patch Id: 100626_03.";
|
||||
static int Patch_ID100626_03;
|
||||
#endif
|
||||
|
||||
_Tt_string ifile;
|
||||
_Tt_typedbLevel cedb = TypedbNone;
|
||||
_Tt_string ofile;
|
||||
_Tt_string_list_ptr cargs;
|
||||
int option_xdr = 1;
|
||||
int option_remap_ptypes = 1;
|
||||
_Tt_string cpp_options("");
|
||||
|
||||
void
|
||||
print_usage_and_exit()
|
||||
{
|
||||
_tt_syslog(stderr, LOG_ERR, "%s",
|
||||
catgets(_ttcatd, 4, 2,
|
||||
"Usage:\n"
|
||||
"tt_type_comp [-s] [-d db] [-mM] source_file\n"
|
||||
"tt_type_comp [-s] [-d db] -r type ...\n"
|
||||
"-M merge source types into specified database, not updating existing types\n"
|
||||
"-m merge, but update existing types. Default.\n"
|
||||
"-r remove source types from the specified database\n"
|
||||
"-d db database to operate on. One of: user, system, or network. Default: user\n"
|
||||
"-G perform garbage collection on the ToolTalk database server.\n"
|
||||
"\n"
|
||||
"tt_type_comp [-sE] -p|O|P [-d db]\n"
|
||||
"tt_type_comp [-s] -p|O|P compiled_file\n"
|
||||
"-O enumerate on stdout the names of all otypes read\n"
|
||||
"-P enumerate on stdout the names of all ptypes read\n"
|
||||
"-p pretty-print on stdout all the ToolTalk types read\n"
|
||||
"-E use the Classing Engine database(s) instead of the XDR database(s)\n"
|
||||
"-d db database to read from. One of: user, system, or network. Default: all\n"
|
||||
"\n"
|
||||
"tt_type_comp [-s] -x [-o compiled_file] source_file\n"
|
||||
"-x compile types from source_file (or stdin, if file is \"-\")\n"
|
||||
"-o write compiled types to compiled_file (or stdout, if file is \"-\")\n"
|
||||
" Default: source_file.xdr, or \"types.xdr\" if source is stdin\n"
|
||||
"\n"
|
||||
"tt_type_comp [-hv]\n"
|
||||
"-v print out version number\n"
|
||||
"-h print out this message\n"
|
||||
"-s do not print out any status messages.\n"
|
||||
"\n"
|
||||
"These cpp options will be passed through:\n"
|
||||
" -undef -Dname -Idirectory -Uname -Ydirectory"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
read_types(_Tt_string file, _Tt_typedb_ptr &db)
|
||||
{
|
||||
_Tt_parse_status result;
|
||||
_Tt_types_table *table;
|
||||
if (file == "-") {
|
||||
table = new _Tt_types_table(stdin, result);
|
||||
} else {
|
||||
table = new _Tt_types_table(file, result);
|
||||
}
|
||||
|
||||
if (result == _TT_PARSE_OK) {
|
||||
db = new _Tt_typedb();
|
||||
|
||||
if (table->check_semantics() != _TT_PARSE_OK) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 3,
|
||||
"Semantic error in types file"));
|
||||
exit(2);
|
||||
}
|
||||
db->ptable = table->ptypes();
|
||||
db->otable = table->otypes();
|
||||
} else {
|
||||
_Tt_string msg = catgets(_ttcatd, 4, 4,
|
||||
"Not a valid ToolTalk types file" );
|
||||
if (file.len() > 0) {
|
||||
msg = msg.cat( ": " ).cat( file );
|
||||
}
|
||||
_tt_syslog(stderr, LOG_ERR, msg);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
f_ce_print()
|
||||
{
|
||||
_Tt_typedb_ptr db;
|
||||
|
||||
db = new _Tt_typedb();
|
||||
if (db->init_ce(cedb) != TT_OK) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 5,
|
||||
"Cannot read any ToolTalk types "
|
||||
"from Classing Engine database"));
|
||||
exit(3);
|
||||
}
|
||||
db->pretty_print(stdout);
|
||||
}
|
||||
|
||||
void
|
||||
merge(int overwrite)
|
||||
{
|
||||
|
||||
int status_ok = 1;
|
||||
int exists;
|
||||
_Tt_typedb_ptr db;
|
||||
_Tt_ptype_table_cursor db_ptypes;
|
||||
_Tt_otype_table_cursor db_otypes;
|
||||
_Tt_typedb_ptr xdb;
|
||||
_Tt_ptype_ptr pt;
|
||||
_Tt_otype_ptr ot;
|
||||
Tt_status st = TT_OK;
|
||||
|
||||
if (cedb == TypedbNone) {
|
||||
cedb = TypedbUser;
|
||||
}
|
||||
|
||||
if (! option_xdr) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 6,
|
||||
"Merging Classing Engine tables is no "
|
||||
"longer supported"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
xdb = new _Tt_typedb();
|
||||
read_types(ifile, db);
|
||||
|
||||
if ((st=xdb->init_xdr(cedb)) != TT_OK) {
|
||||
// if TT_ERR_DBEXIST is returned from init_ce
|
||||
// we continue with the merge. It just means
|
||||
// we're starting up in an environment where
|
||||
// no tooltalk namespaces exist in any of the
|
||||
// Classing Engine databases.
|
||||
if (st != TT_ERR_DBEXIST) {
|
||||
if (st == TT_ERR_NO_MATCH) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 7,
|
||||
"Cannot read types in %s data"
|
||||
"base - version mismatch"),
|
||||
_Tt_typedb::level_name(cedb));
|
||||
} else {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 8,
|
||||
"Cannot read types in %s data"
|
||||
"base"),
|
||||
_Tt_typedb::level_name(cedb));
|
||||
}
|
||||
/*
|
||||
* The most common way for this to fail seems to be
|
||||
* to not have OPENWINHOME set. Suggest this
|
||||
* to the user.
|
||||
*/
|
||||
if (0==getenv("OPENWINHOME")) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 9,
|
||||
"$OPENWINHOME not set"));
|
||||
}
|
||||
exit(3);
|
||||
}
|
||||
}
|
||||
|
||||
if (! xdb->begin_write(cedb)) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 10,
|
||||
"Cannot initialize %s database for writing"),
|
||||
_Tt_typedb::level_name(cedb));
|
||||
exit(3);
|
||||
}
|
||||
|
||||
db_otypes.reset(db->otable);
|
||||
while (db_otypes.next()) {
|
||||
ot = xdb->otable->lookup(db_otypes->otid());
|
||||
exists = (! ot.is_null());
|
||||
if (exists) {
|
||||
if (! overwrite) {
|
||||
continue;
|
||||
}
|
||||
if (! xdb->remove_otype(db_otypes->otid())) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 11,
|
||||
"Could not remove old "
|
||||
"definition for %s"),
|
||||
(char *)db_otypes->otid());
|
||||
xdb->abort_write();
|
||||
exit(3);
|
||||
}
|
||||
}
|
||||
if (! _tt_global->silent) {
|
||||
printf( "%s %s...\n",
|
||||
(exists)
|
||||
? catgets(_ttcatd, 4, 12, "Overwriting")
|
||||
: catgets(_ttcatd, 4, 13, "Writing"),
|
||||
(char *)db_otypes->otid());
|
||||
}
|
||||
if (! xdb->insert(*db_otypes)) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 14, "Could not add "
|
||||
"new definition for %s"),
|
||||
(char *)db_otypes->otid());
|
||||
xdb->abort_write();
|
||||
exit(3);
|
||||
}
|
||||
}
|
||||
|
||||
db_ptypes.reset(db->ptable);
|
||||
while (db_ptypes.next()) {
|
||||
pt = xdb->ptable->lookup(db_ptypes->ptid());
|
||||
exists = (! pt.is_null());
|
||||
if (exists) {
|
||||
if (! overwrite) {
|
||||
continue;
|
||||
}
|
||||
if (! xdb->remove_ptype(db_ptypes->ptid())) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 15,
|
||||
"Could not remove old "
|
||||
"definition for %s"),
|
||||
(char *)db_ptypes->ptid());
|
||||
xdb->abort_write();
|
||||
}
|
||||
}
|
||||
if (! _tt_global->silent) {
|
||||
printf("%s %s...\n",
|
||||
(exists)
|
||||
? catgets(_ttcatd, 4, 16, "Overwriting")
|
||||
: catgets(_ttcatd, 4, 17, "Writing"),
|
||||
(char *)db_ptypes->ptid());
|
||||
}
|
||||
if (! xdb->insert(*db_ptypes)) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 18, "Could not add "
|
||||
"new definition for %s"),
|
||||
(char *)db_ptypes->ptid());
|
||||
xdb->abort_write();
|
||||
}
|
||||
}
|
||||
|
||||
if (! xdb->end_write()) {
|
||||
// diagnostic emitted by ::end_write()
|
||||
exit(3);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
f_merge_overwrite()
|
||||
{
|
||||
merge(1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
f_merge_no_overwrite()
|
||||
{
|
||||
merge(0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
f_list_types(int otypes)
|
||||
{
|
||||
_Tt_typedb_ptr db;
|
||||
Tt_status status;
|
||||
int checkOW = 0;
|
||||
|
||||
if (cedb == TypedbNone) {
|
||||
cedb = TypedbAll;
|
||||
}
|
||||
db = new _Tt_typedb();
|
||||
if (option_xdr) {
|
||||
if (ifile.len() > 0) {
|
||||
if (ifile == "-") {
|
||||
status = db->init_xdr( stdin );
|
||||
} else {
|
||||
status = db->init_xdr( ifile );
|
||||
}
|
||||
} else {
|
||||
status = db->init_xdr( cedb );
|
||||
}
|
||||
} else {
|
||||
status = db->init_ce( cedb );
|
||||
}
|
||||
if (status != TT_OK) {
|
||||
if (status == TT_ERR_NO_MATCH) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 19, "Version mismatch "
|
||||
"in compiled types"));
|
||||
} else {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 20, "Cannot read types "
|
||||
"in database"));
|
||||
}
|
||||
//
|
||||
// The most common way for this to fail seems to be
|
||||
// to not have OPENWINHOME set. Suggest this
|
||||
// to the user.
|
||||
//
|
||||
if (0==getenv("OPENWINHOME")) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 21,
|
||||
"$OPENWINHOME not set"));
|
||||
}
|
||||
exit(3);
|
||||
}
|
||||
if (otypes) {
|
||||
_Tt_otype_table_cursor db_otypes;
|
||||
db_otypes.reset(db->otable);
|
||||
while (db_otypes.next()) {
|
||||
printf("%s\n", (char *)db_otypes->otid());
|
||||
}
|
||||
} else {
|
||||
_Tt_ptype_table_cursor db_ptypes;
|
||||
db_ptypes.reset(db->ptable);
|
||||
while (db_ptypes.next()) {
|
||||
printf("%s\n", (char *)db_ptypes->ptid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
f_list_ptypes()
|
||||
{
|
||||
f_list_types( 0 );
|
||||
}
|
||||
|
||||
void
|
||||
f_list_otypes()
|
||||
{
|
||||
f_list_types( 1 );
|
||||
}
|
||||
|
||||
void
|
||||
f_remove_types()
|
||||
{
|
||||
_Tt_string_list_cursor argc;
|
||||
_Tt_typedb_ptr db;
|
||||
_Tt_otype_ptr ot;
|
||||
_Tt_ptype_ptr pt;
|
||||
int db_changed = 0;
|
||||
Tt_status err;
|
||||
|
||||
if (cedb == TypedbNone) {
|
||||
cedb = TypedbUser;
|
||||
}
|
||||
db = new _Tt_typedb();
|
||||
if ((option_xdr && (err = db->init_xdr(cedb)) != TT_OK) ||
|
||||
(!option_xdr && (err = db->init_ce(cedb)) != TT_OK)) {
|
||||
if (err == TT_ERR_NO_MATCH) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 22,
|
||||
"Cannot read types in %s data"
|
||||
"base - version mismatch"),
|
||||
_Tt_typedb::level_name(cedb));
|
||||
} else {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 23,
|
||||
"Cannot read types in %s database"),
|
||||
_Tt_typedb::level_name(cedb));
|
||||
}
|
||||
/*
|
||||
* The most common way for this to fail seems to be
|
||||
* to not have OPENWINHOME set. Suggest this
|
||||
* to the user.
|
||||
*/
|
||||
if (0==getenv("OPENWINHOME")) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 24,
|
||||
"$OPENWINHOME not set"));
|
||||
}
|
||||
exit(3);
|
||||
}
|
||||
|
||||
if (! db->begin_write(cedb)) {
|
||||
// diagnostic emitted
|
||||
exit(3);
|
||||
}
|
||||
|
||||
argc.reset(cargs);
|
||||
while (argc.next()) {
|
||||
pt = db->ptable->lookup(*argc);
|
||||
if (pt.is_null()) {
|
||||
ot = db->otable->lookup(*argc);
|
||||
if (! ot.is_null()) {
|
||||
if (! _tt_global->silent) {
|
||||
printf(catgets(_ttcatd, 4, 25,
|
||||
"Removing otype %s\n"),
|
||||
(char *)(*argc));
|
||||
}
|
||||
db_changed = 1;
|
||||
db->remove_otype(*argc);
|
||||
}
|
||||
} else {
|
||||
if (! _tt_global->silent) {
|
||||
printf(catgets(_ttcatd, 4, 26,
|
||||
"Removing ptype %s\n"),
|
||||
(char *)(*argc));
|
||||
}
|
||||
db->remove_ptype(*argc);
|
||||
db_changed = 1;
|
||||
}
|
||||
}
|
||||
if (db_changed ) {
|
||||
// write out changes
|
||||
if (! db->end_write()) {
|
||||
exit(3);
|
||||
}
|
||||
} else {
|
||||
db->abort_write();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
f_xdr_file()
|
||||
{
|
||||
_Tt_typedb_ptr db;
|
||||
|
||||
if (ofile.len() == 0) {
|
||||
if (ifile == "-") {
|
||||
ofile = "types.xdr";
|
||||
} else {
|
||||
ofile = ifile.cat(".xdr");
|
||||
}
|
||||
}
|
||||
read_types(ifile, db);
|
||||
|
||||
Tt_status status;
|
||||
if (ofile == "-") {
|
||||
status = db->write( stdout );
|
||||
} else {
|
||||
status = db->write( ofile );
|
||||
}
|
||||
if (status != TT_OK) {
|
||||
exit( 3 );
|
||||
}
|
||||
if (ofile != "-") {
|
||||
_Tt_typedb::send_saved( ofile );
|
||||
printf(catgets(_ttcatd, 4, 27, "output written to %s\n"),
|
||||
(char *)ofile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
f_xdr_print()
|
||||
{
|
||||
_Tt_typedb_ptr db;
|
||||
Tt_status status;
|
||||
|
||||
db = new _Tt_typedb();
|
||||
if (ifile.len() != 0) {
|
||||
if (ifile == "-") {
|
||||
status = db->init_xdr( stdin );
|
||||
} else {
|
||||
status = db->init_xdr( ifile );
|
||||
}
|
||||
} else {
|
||||
if (cedb == TypedbNone) {
|
||||
cedb = TypedbAll;
|
||||
}
|
||||
status = db->init_xdr(cedb);
|
||||
}
|
||||
if (status != TT_OK) {
|
||||
// diagnostic emitted
|
||||
exit(3);
|
||||
}
|
||||
if (!db.is_null()) {
|
||||
db->pretty_print(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// This sends messages to the 'default' ToolTalk files.
|
||||
// This forces an attempt to contact the sessions registered for
|
||||
// each file, if they are dead, then a deleteSession() is sent
|
||||
// to clear out (garbage collect) the information for that dead
|
||||
// session. Dead sessions can occur in the dbserver if the system
|
||||
// that had registered died without un-registering with dbserver
|
||||
// for a file.
|
||||
//
|
||||
void
|
||||
f_garbage_collect()
|
||||
{
|
||||
_Tt_db_client dbClient;
|
||||
_Tt_string sessionId;
|
||||
|
||||
if (dbClient.getConnectionResults() == TT_DB_OK) {
|
||||
|
||||
_Tt_string_list *sessions;
|
||||
sessions = dbClient.get_all_sessions();
|
||||
|
||||
if (sessions != NULL && sessions->count() > 0) {
|
||||
|
||||
// Delete the list of sessions that are dead.
|
||||
do {
|
||||
Tt_status ttstatus;
|
||||
|
||||
sessionId = sessions->top();
|
||||
if ((ttstatus
|
||||
= tt_default_session_set(sessionId))
|
||||
!= TT_OK) {
|
||||
dbClient.delete_session(sessionId);
|
||||
}
|
||||
sessions->pop();
|
||||
} while(sessions->count() > 0);
|
||||
}
|
||||
dbClient.garbage_collect_in_server();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
process_args(int argc, char **argv)
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
int c;
|
||||
int args_left;
|
||||
cmd_fn fn;
|
||||
int fn_set = 0;
|
||||
|
||||
// default function is to merge types
|
||||
fn = f_merge_overwrite;
|
||||
|
||||
// Need to parse out the cpp options specially because they
|
||||
// don't work with getopt
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i][0] == '-' &&
|
||||
(argv[i][1] == 'u' || argv[i][1] == 'D' ||
|
||||
argv[i][1] == 'I' || argv[i][1] == 'U' ||
|
||||
argv[i][1] == 'Y')) {
|
||||
if (argv[i][1] == 'u' &&
|
||||
strcmp(argv[i], "-undef") != 0) {
|
||||
print_usage_and_exit();
|
||||
}
|
||||
cpp_options = cpp_options.cat(argv[i]).cat(" ");
|
||||
// getopt stops processing on an empty string, so
|
||||
// need a fake option for below
|
||||
argv[i] = "-Y";
|
||||
}
|
||||
}
|
||||
int need_file = 1;
|
||||
int only_one_input = 0;
|
||||
while ((c = getopt(argc, argv, "XEGOPsd:hmMo:prvxY")) != -1) {
|
||||
switch (c) {
|
||||
case 'X':
|
||||
option_xdr = 1;
|
||||
break;
|
||||
case 'E':
|
||||
option_xdr = 0;
|
||||
break;
|
||||
case 'O':
|
||||
fn_set++;
|
||||
fn = f_list_otypes;
|
||||
need_file = 0;
|
||||
only_one_input = 1;
|
||||
break;
|
||||
case 'P':
|
||||
fn_set++;
|
||||
fn = f_list_ptypes;
|
||||
need_file = 0;
|
||||
only_one_input = 1;
|
||||
break;
|
||||
case 's':
|
||||
_tt_global->silent = 1;
|
||||
break;
|
||||
case 'd':
|
||||
cedb = _Tt_typedb::level( optarg );
|
||||
if (cedb == TypedbNone) {
|
||||
_tt_syslog( stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 28,
|
||||
"Invalid database: %s"),
|
||||
optarg );
|
||||
print_usage_and_exit();
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
print_usage_and_exit();
|
||||
break;
|
||||
case 'm':
|
||||
fn_set++;
|
||||
fn = f_merge_overwrite;
|
||||
break;
|
||||
case 'M':
|
||||
fn_set++;
|
||||
fn = f_merge_no_overwrite;
|
||||
break;
|
||||
case 'o':
|
||||
ofile = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
fn_set++;
|
||||
need_file = 0;
|
||||
only_one_input = 1;
|
||||
if (option_xdr) {
|
||||
fn = f_xdr_print;
|
||||
} else {
|
||||
fn = f_ce_print;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
fn_set++;
|
||||
fn = f_remove_types;
|
||||
break;
|
||||
case 'v':
|
||||
_TT_PRINT_VERSIONS((char *)_tt_global->progname)
|
||||
exit(0);
|
||||
case 'x':
|
||||
fn_set++;
|
||||
fn = f_xdr_file;
|
||||
break;
|
||||
case 'Y':
|
||||
// A cpp option was handled, ignore this
|
||||
break;
|
||||
case 'G':
|
||||
// Garbage collect.
|
||||
need_file = 0;
|
||||
fn = f_garbage_collect;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
print_usage_and_exit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fn_set > 1) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 29,
|
||||
"Specify only one of the options "
|
||||
"-O -P -m -M -p -r -x"));
|
||||
print_usage_and_exit();
|
||||
}
|
||||
//
|
||||
// Extra args are always either a filename or types to remove
|
||||
//
|
||||
ifile = argv[optind];
|
||||
if (ifile.len() == 0) {
|
||||
if (need_file) {
|
||||
print_usage_and_exit();
|
||||
}
|
||||
} else {
|
||||
if (only_one_input && (cedb != TypedbNone)) {
|
||||
print_usage_and_exit();
|
||||
}
|
||||
}
|
||||
if ((ofile.len() > 0) && (fn != f_xdr_file)) {
|
||||
print_usage_and_exit();
|
||||
}
|
||||
args_left = optind;
|
||||
cargs = new _Tt_string_list();
|
||||
while (argv[args_left]) {
|
||||
cargs->append(_Tt_string(argv[args_left++]));
|
||||
}
|
||||
(*fn)();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
_tt_global = new _Tt_global();
|
||||
_tt_global->progname = argv[0];
|
||||
setlocale( LC_ALL, "" );
|
||||
_tt_openlog( _tt_global->progname, LOG_NOWAIT, 0 );
|
||||
process_args(argc, argv);
|
||||
return((int) 0);
|
||||
}
|
||||
418
cde/lib/tt/bin/tt_type_comp/mp_types_gram.y
Normal file
418
cde/lib/tt/bin/tt_type_comp/mp_types_gram.y
Normal file
@@ -0,0 +1,418 @@
|
||||
/*%% (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_types_gram.y /main/3 1995/10/20 16:38:43 rswiston $ */
|
||||
%{
|
||||
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include "mp/mp_arg.h"
|
||||
#include "mp_otype.h"
|
||||
#include "mp_ptype.h"
|
||||
#include "mp_signature.h"
|
||||
#include "mp_types_table.h"
|
||||
|
||||
extern int yyleng;
|
||||
extern char yytext[];
|
||||
|
||||
%}
|
||||
|
||||
%start types
|
||||
|
||||
%union {
|
||||
int num;
|
||||
char *str;
|
||||
}
|
||||
|
||||
%type <str> prop_id value string_lit
|
||||
|
||||
/* reserved tokens: ptype => PTYPE, ... */
|
||||
|
||||
%token <str> PER_FILE PER_SESSION START FILE_SCOPE SESSION_SCOPE
|
||||
FILE_IN_SESSION REQUEST NOTIFICATION
|
||||
VOID_ARGS
|
||||
%token <num> QUEUE OPNUM
|
||||
%token IN OUT INOUT OTYPE INHERIT FROM PTYPE
|
||||
OBSERVE HANDLE HANDLE_PUSH HANDLE_ROTATE
|
||||
COLON SEMICOLON LCURL RCURL INFER LPAREN RPAREN COMMA EQUAL CONTEXT
|
||||
|
||||
/* variable tokens */
|
||||
|
||||
%token <str> TT_IDENTIFIER TT_STRING TT_NUMBER
|
||||
|
||||
%%
|
||||
|
||||
/* Grammar rules for otype & ptype definition languages */
|
||||
|
||||
types : type
|
||||
| types type
|
||||
;
|
||||
|
||||
type : otype
|
||||
| ptype
|
||||
;
|
||||
|
||||
/* OTYPE grammar rules */
|
||||
|
||||
/*
|
||||
* This is the grammar definition:
|
||||
*
|
||||
* otype ::= obj_header '{' objbody* '}' [';']
|
||||
*
|
||||
* obj_header ::= 'otype' otid [':' otid+]
|
||||
*
|
||||
* objbody ::= 'observe:' osignature* | 'handle:' osignature*
|
||||
*
|
||||
* osignature ::= op args [cxtdcl] '=>' rhs ';'
|
||||
*
|
||||
* rhs ::= ptid [scope] ['start'] ['queue'] ['opnum=' number]
|
||||
* [inherit] | inherit
|
||||
*
|
||||
* inherit ::= 'from' otid
|
||||
*/
|
||||
|
||||
otype : header LCURL otype_body_list RCURL opt_del
|
||||
{
|
||||
insert_otype(tmp_otype);
|
||||
tmp_otype = new _Tt_otype();
|
||||
}
|
||||
;
|
||||
|
||||
header : OTYPE otid { tmp_otype->set_otid(tmp_otid); }
|
||||
inheritance_opt
|
||||
{
|
||||
tmp_otype->set_ancestors(tmp_otidl);
|
||||
tmp_otidl = new _Tt_string_list();
|
||||
}
|
||||
;
|
||||
|
||||
otid : TT_IDENTIFIER
|
||||
{
|
||||
tmp_otid = yytext;
|
||||
}
|
||||
;
|
||||
|
||||
inheritance_opt : /* empty */
|
||||
| COLON otid_list
|
||||
;
|
||||
|
||||
otid_list : otid
|
||||
{
|
||||
tmp_otidl->append(tmp_otid);
|
||||
}
|
||||
| otid_list otid
|
||||
{
|
||||
tmp_otidl->append(tmp_otid);
|
||||
}
|
||||
;
|
||||
|
||||
otype_body_list : /* empty */
|
||||
| otype_body_list otype_body
|
||||
;
|
||||
|
||||
otype_body : otype_observe
|
||||
| otype_handle
|
||||
| otype_handle_push
|
||||
| otype_handle_rotate
|
||||
;
|
||||
|
||||
otype_observe : OBSERVE COLON osig_list
|
||||
{
|
||||
tmp_otype->append_osigs(tmp_sigl);
|
||||
tmp_sigl = new _Tt_signature_list();
|
||||
}
|
||||
;
|
||||
|
||||
otype_handle : HANDLE COLON osig_list
|
||||
{
|
||||
tmp_otype->append_hsigs(tmp_sigl, TT_HANDLE);
|
||||
tmp_sigl = new _Tt_signature_list();
|
||||
}
|
||||
;
|
||||
|
||||
otype_handle_push: HANDLE_PUSH COLON osig_list
|
||||
{
|
||||
tmp_otype->append_hsigs(tmp_sigl, TT_HANDLE_PUSH);
|
||||
tmp_sigl = new _Tt_signature_list();
|
||||
}
|
||||
;
|
||||
|
||||
otype_handle_rotate: HANDLE_ROTATE COLON osig_list
|
||||
{
|
||||
tmp_otype->append_hsigs(tmp_sigl, TT_HANDLE_ROTATE);
|
||||
tmp_sigl = new _Tt_signature_list();
|
||||
}
|
||||
;
|
||||
|
||||
osig_list : /* empty */
|
||||
| osig_list osig
|
||||
;
|
||||
|
||||
osig : op args cntxt_opt INFER rhs SEMICOLON
|
||||
{
|
||||
tmp_sig->set_otid(tmp_otype->otid());
|
||||
tmp_sig->set_super_otid(tmp_otid);
|
||||
append_sig(tmp_sig);
|
||||
tmp_sig = new _Tt_signature();
|
||||
}
|
||||
;
|
||||
|
||||
rhs : ptid { tmp_sig->set_ptid(yytext); }
|
||||
scope_opt start_opt queue_opt opnum_opt
|
||||
inherit_opt
|
||||
| inherit
|
||||
;
|
||||
|
||||
inherit_opt : /* empty */
|
||||
| inherit
|
||||
;
|
||||
|
||||
inherit : FROM otid
|
||||
{
|
||||
tmp_sig->set_super_otid(tmp_otid);
|
||||
}
|
||||
;
|
||||
|
||||
/* PTYPE grammar rules */
|
||||
|
||||
/*
|
||||
* The grammar definition:
|
||||
*
|
||||
* ptype ::= 'ptype' ptid '{' property* ptype_body* '}' [';']
|
||||
*
|
||||
* property ::= property_id value ';'
|
||||
*
|
||||
* ptype_body ::= 'observe:' psignature* | 'handle:' psignature*
|
||||
*
|
||||
* ptype_body ::= 'handle_push:' psignature* | 'handle_rotate:' psignature*
|
||||
*
|
||||
* property_id ::= 'per_file' | 'per_session' | 'start'
|
||||
*
|
||||
* value ::= string | number
|
||||
*
|
||||
* psignature ::= [scope] op args [cxtdcl] ['=>' ['start'] ['queue']
|
||||
* ['opnum=' number]] ';'
|
||||
*
|
||||
* scope ::= 'file' | 'session' | 'file_in_session'
|
||||
*
|
||||
* args ::= '(' argspec {, argspec}* ')' | '(void)' | '()'
|
||||
*
|
||||
* cxtdcl ::= 'context' '(' identifier {, identifer }* ')'
|
||||
*
|
||||
* argspec ::= mode type name
|
||||
*
|
||||
* mode ::= 'in' | 'out' | 'inout'
|
||||
*/
|
||||
|
||||
ptype : PTYPE ptid { tmp_ptype->set_ptid(yytext); }
|
||||
LCURL prop_list ptype_body_list RCURL opt_del
|
||||
{
|
||||
insert_ptype(tmp_ptype);
|
||||
tmp_ptype = new _Tt_ptype();
|
||||
}
|
||||
;
|
||||
|
||||
ptid : TT_IDENTIFIER
|
||||
;
|
||||
|
||||
prop_list : /* empty */
|
||||
| prop_list prop
|
||||
;
|
||||
|
||||
prop : prop_id value SEMICOLON
|
||||
{
|
||||
tmp_ptype->appendprop(tmp_propname, tmp_propvalue);
|
||||
tmp_propname = tmp_propvalue = 0;
|
||||
}
|
||||
;
|
||||
|
||||
ptype_body_list : /* empty */
|
||||
| ptype_body_list ptype_body
|
||||
;
|
||||
|
||||
ptype_body : observe
|
||||
| handle
|
||||
| handle_push
|
||||
| handle_rotate
|
||||
;
|
||||
|
||||
prop_id : PER_FILE
|
||||
{ set_tmp_propname(_Tt_string((const unsigned char *)yytext, yyleng)); }
|
||||
| PER_SESSION
|
||||
{ set_tmp_propname(_Tt_string((const unsigned char *)yytext, yyleng));}
|
||||
| START
|
||||
{ set_tmp_propname(_Tt_string((const unsigned char *)yytext,yyleng)); }
|
||||
;
|
||||
|
||||
/* Rule 10 */
|
||||
|
||||
string_lit : TT_STRING
|
||||
{
|
||||
tmp_propvalue.set((const unsigned char *)yytext+1,
|
||||
yyleng - 2);
|
||||
}
|
||||
| string_lit TT_STRING
|
||||
{
|
||||
_Tt_string stringfrag;
|
||||
stringfrag.set((const unsigned char *)yytext+1,
|
||||
yyleng - 2);
|
||||
tmp_propvalue = tmp_propvalue.cat(stringfrag);
|
||||
}
|
||||
;
|
||||
|
||||
value : string_lit
|
||||
| TT_NUMBER
|
||||
{
|
||||
tmp_propvalue = yytext;
|
||||
}
|
||||
;
|
||||
|
||||
observe : OBSERVE COLON psig_list
|
||||
{
|
||||
tmp_ptype->append_osigs(tmp_sigl);
|
||||
tmp_sigl = new _Tt_signature_list();
|
||||
}
|
||||
;
|
||||
|
||||
handle : HANDLE COLON psig_list
|
||||
{
|
||||
tmp_ptype->append_hsigs(tmp_sigl, TT_HANDLE);
|
||||
tmp_sigl = new _Tt_signature_list();
|
||||
}
|
||||
;
|
||||
|
||||
handle_push : HANDLE_PUSH COLON psig_list
|
||||
{
|
||||
tmp_ptype->append_hsigs(tmp_sigl, TT_HANDLE_PUSH);
|
||||
tmp_sigl = new _Tt_signature_list();
|
||||
}
|
||||
;
|
||||
|
||||
handle_rotate : HANDLE_ROTATE COLON psig_list
|
||||
{
|
||||
tmp_ptype->append_hsigs(tmp_sigl, TT_HANDLE_ROTATE);
|
||||
tmp_sigl = new _Tt_signature_list();
|
||||
}
|
||||
;
|
||||
|
||||
opt_del : /* empty */
|
||||
| SEMICOLON
|
||||
;
|
||||
|
||||
psig_list : /* empty */
|
||||
| psig_list psig
|
||||
;
|
||||
|
||||
/* Rule 20 */
|
||||
|
||||
psig : scope_opt op args cntxt_opt infer_opt SEMICOLON
|
||||
{
|
||||
tmp_sig->set_ptid(tmp_ptype->ptid());
|
||||
append_sig(tmp_sig);
|
||||
tmp_sig = new _Tt_signature();
|
||||
}
|
||||
;
|
||||
|
||||
scope_opt : /* empty */
|
||||
| FILE_SCOPE {
|
||||
tmp_sig->set_scope(TT_FILE);
|
||||
}
|
||||
| SESSION_SCOPE {
|
||||
tmp_sig->set_scope(TT_SESSION);
|
||||
}
|
||||
| FILE_IN_SESSION {
|
||||
tmp_sig->set_scope(TT_FILE_IN_SESSION);
|
||||
}
|
||||
;
|
||||
|
||||
op : TT_IDENTIFIER
|
||||
{
|
||||
tmp_sig->set_op(yytext);
|
||||
}
|
||||
;
|
||||
|
||||
args : LPAREN args_aux RPAREN
|
||||
;
|
||||
|
||||
args_aux : /* empty */
|
||||
| VOID_ARGS
|
||||
/*
|
||||
{
|
||||
tmp_sig->append_arg(new _Tt_arg(yytext));
|
||||
}
|
||||
*/
|
||||
| argspecs
|
||||
;
|
||||
|
||||
/* Rule 31 */
|
||||
|
||||
argspecs : argspecs COMMA argspec
|
||||
| argspec
|
||||
;
|
||||
|
||||
argspec : mode type name
|
||||
{
|
||||
tmp_sig->append_arg(tmp_arg);
|
||||
tmp_arg = new _Tt_arg();
|
||||
}
|
||||
;
|
||||
|
||||
mode : IN { tmp_arg->set_mode(TT_IN); }
|
||||
| OUT { tmp_arg->set_mode(TT_OUT); }
|
||||
| INOUT { tmp_arg->set_mode(TT_INOUT); }
|
||||
;
|
||||
|
||||
type : TT_IDENTIFIER
|
||||
{
|
||||
_Tt_string tmptext(yytext);
|
||||
tmp_arg->set_type(tmptext);
|
||||
}
|
||||
;
|
||||
|
||||
name : TT_IDENTIFIER
|
||||
{
|
||||
_Tt_string tmptext(yytext);
|
||||
tmp_arg->set_name(tmptext);
|
||||
}
|
||||
;
|
||||
|
||||
cntxt_opt : /* empty */
|
||||
| CONTEXT LPAREN cntxt_list RPAREN
|
||||
;
|
||||
|
||||
cntxt_list : cntxt_list COMMA cntxt
|
||||
| cntxt
|
||||
;
|
||||
|
||||
cntxt : TT_IDENTIFIER
|
||||
{
|
||||
_Tt_context_ptr tmpcntxt = new _Tt_context;
|
||||
tmpcntxt->setName(yytext);
|
||||
tmp_sig->append_context(tmpcntxt);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
infer_opt : /* empty */
|
||||
| INFER start_opt queue_opt opnum_opt
|
||||
;
|
||||
|
||||
start_opt : /* empty */
|
||||
| START { tmp_sig->set_reliability(TT_START); }
|
||||
;
|
||||
|
||||
queue_opt : /* empty */
|
||||
| QUEUE { tmp_sig->set_reliability(TT_QUEUE); }
|
||||
;
|
||||
|
||||
/* Rule 41 */
|
||||
|
||||
opnum_opt : /* empty */
|
||||
| OPNUM EQUAL TT_NUMBER { tmp_sig->set_opnum(atoi(yytext)); }
|
||||
;
|
||||
|
||||
%%
|
||||
65
cde/lib/tt/bin/tt_type_comp/mp_types_lex.l
Normal file
65
cde/lib/tt/bin/tt_type_comp/mp_types_lex.l
Normal file
@@ -0,0 +1,65 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_types_lex.l /main/3 1995/10/20 16:38:50 rswiston $ */
|
||||
%{
|
||||
#include <stdlib.h>
|
||||
#include "mp_types_gram.h"
|
||||
#include "mp_types_table.h"
|
||||
extern "C" {
|
||||
int input(void);
|
||||
void output(int);
|
||||
void unput(int);
|
||||
}
|
||||
static void skip_c_comments(void);
|
||||
static void skip_cplusplus_comments(void);
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
"/*" skip_c_comments();
|
||||
"//" skip_cplusplus_comments();
|
||||
otype { return OTYPE; }
|
||||
inherit { return INHERIT; }
|
||||
from { return FROM; }
|
||||
ptype { return PTYPE; }
|
||||
per_file { return PER_FILE; }
|
||||
per_session { return PER_SESSION; }
|
||||
start { return START; }
|
||||
observe { return OBSERVE; }
|
||||
handle { return HANDLE; }
|
||||
handle_push { return HANDLE_PUSH; }
|
||||
handle_rotate { return HANDLE_ROTATE; }
|
||||
file { return FILE_SCOPE; }
|
||||
session { return SESSION_SCOPE; }
|
||||
file_in_session { return FILE_IN_SESSION; }
|
||||
request { return REQUEST; }
|
||||
notification { return NOTIFICATION; }
|
||||
void { return VOID_ARGS; }
|
||||
in { return IN; }
|
||||
out { return OUT; }
|
||||
inout { return INOUT; }
|
||||
queue { return QUEUE; }
|
||||
opnum { return OPNUM; }
|
||||
context { return CONTEXT; }
|
||||
":" { return COLON; }
|
||||
";" { return SEMICOLON; }
|
||||
"{" { return LCURL; }
|
||||
"}" { return RCURL; }
|
||||
"=>" { return INFER; }
|
||||
"(" { return LPAREN; }
|
||||
")" { return RPAREN; }
|
||||
"," { return COMMA; }
|
||||
"=" { return EQUAL; }
|
||||
|
||||
[a-zA-Z][-_a-zA-Z0-9]* { return TT_IDENTIFIER; }
|
||||
\"[^"]*\" { return TT_STRING; }
|
||||
[0-9]+ { return TT_NUMBER; }
|
||||
|
||||
[ \t\n] ;
|
||||
|
||||
%%
|
||||
|
||||
|
||||
|
||||
730
cde/lib/tt/bin/tt_type_comp/mp_types_table.C
Normal file
730
cde/lib/tt/bin/tt_type_comp/mp_types_table.C
Normal file
@@ -0,0 +1,730 @@
|
||||
//%% (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_types_table.C /main/3 1995/10/20 16:38:58 rswiston $
|
||||
/*
|
||||
* Tool Talk Message Passer (PM) - mp_types_table.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file contains the definition for the class _Tt_types_table which implements a
|
||||
* hash table of otype and ptype descriptors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tt_options.h"
|
||||
#include "mp/mp_arg.h"
|
||||
#include "mp_types_table.h"
|
||||
#include "util/tt_global_env.h"
|
||||
#include "util/tt_iostream.h"
|
||||
#include "util/tt_port.h"
|
||||
#include "util/tt_gettext.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(OPT_BUG_UW_2) || defined(OPT_BUG_UXP)
|
||||
extern "C" {
|
||||
#ifndef __uxp__
|
||||
int putenv(char *);
|
||||
#endif
|
||||
FILE *popen(const char *, const char *);
|
||||
FILE *fdopen(int, const char *);
|
||||
int pclose(FILE *);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define TT_TYPE_TABLE_BUCKETS 19
|
||||
|
||||
static int use_cpp;
|
||||
static int cppline(const char *line);
|
||||
static void docppline(const char *line, int &lineno, _Tt_string &fname);
|
||||
|
||||
/*
|
||||
* Parse the type descriptions in file stream 'infs', and construct the hash
|
||||
* table of otypes and ptypes.
|
||||
*/
|
||||
|
||||
_Tt_types_table::
|
||||
_Tt_types_table(FILE *infs, _Tt_parse_status& result)
|
||||
{
|
||||
ptable = new _Tt_ptype_table(_tt_ptype_ptid,TT_TYPE_TABLE_BUCKETS);
|
||||
ptc.reset(ptable);
|
||||
otable = new _Tt_otype_table(_tt_otype_otid, TT_TYPE_TABLE_BUCKETS);
|
||||
otc.reset(otable);
|
||||
tmp_otype = new _Tt_otype();
|
||||
tmp_ptype = new _Tt_ptype();
|
||||
tmp_otidl = new _Tt_string_list();
|
||||
tmp_sigl = new _Tt_signature_list();
|
||||
tmp_sig = new _Tt_signature();
|
||||
tmp_arg = new _Tt_arg();
|
||||
tmp_propname = tmp_propvalue = 0;
|
||||
yyin = infs;
|
||||
result = parse_yyin();
|
||||
}
|
||||
|
||||
/*
|
||||
* _Tt_types_table - parse the type descriptions in the file 'path', and
|
||||
* construct the hash table of in-memory otype and ptype descriptors.
|
||||
*/
|
||||
_Tt_types_table::
|
||||
_Tt_types_table(_Tt_string path, _Tt_parse_status& result)
|
||||
{
|
||||
ptable = new _Tt_ptype_table(_tt_ptype_ptid,TT_TYPE_TABLE_BUCKETS);
|
||||
ptc.reset(ptable);
|
||||
otable = new _Tt_otype_table(_tt_otype_otid,TT_TYPE_TABLE_BUCKETS);
|
||||
otc.reset(otable);
|
||||
tmp_otype = new _Tt_otype();
|
||||
tmp_ptype = new _Tt_ptype();
|
||||
tmp_otidl = new _Tt_string_list();
|
||||
tmp_sigl = new _Tt_signature_list();
|
||||
tmp_sig = new _Tt_signature();
|
||||
tmp_arg = new _Tt_arg();
|
||||
tmp_propname = tmp_propvalue = 0;
|
||||
has_contexts = 0;
|
||||
result = parse_path(path);
|
||||
}
|
||||
|
||||
_Tt_otype_table_ptr & _Tt_types_table::
|
||||
otypes()
|
||||
{
|
||||
return otable;
|
||||
}
|
||||
|
||||
_Tt_ptype_table_ptr & _Tt_types_table::
|
||||
ptypes()
|
||||
{
|
||||
return ptable;
|
||||
}
|
||||
|
||||
_Tt_parse_status _Tt_types_table::
|
||||
parse_path(_Tt_string path)
|
||||
{
|
||||
int fd;
|
||||
// If cpp cannot be found, don\'t use it.
|
||||
// This may cause trouble, but it\'s the best thing to try.
|
||||
// A warning will be issued if cpp is not around.
|
||||
use_cpp = (-1 != access(OPT_CPP_PATH,X_OK));
|
||||
|
||||
_file_name = path;
|
||||
if ((fd = open(path, O_RDONLY)) == -1) {
|
||||
_tt_syslog( stderr, LOG_ERR, "%s: %m",
|
||||
path.operator const char *());
|
||||
return _TT_PARSE_ERROR;
|
||||
} else {
|
||||
if (use_cpp) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
if (use_cpp) {
|
||||
_Tt_string deps =_file_name.cat(".deps");
|
||||
unlink((char *)deps);
|
||||
deps = _Tt_string("SUNPRO_DEPENDENCIES=").cat(deps).cat(" ");
|
||||
putenv((char *)deps);
|
||||
char command[MAXPATHLEN+32];
|
||||
sprintf(command,
|
||||
OPT_CPP_PATH " " OPT_CPP_OPTIONS " %s %s",
|
||||
(char *)cpp_options,
|
||||
(char *)_file_name);
|
||||
yyin = popen(command, "r");/* open cpp stream for reading */
|
||||
if (!yyin) {
|
||||
_tt_syslog(stderr, LOG_ERR, "popen(\"%s\"): %m",
|
||||
command );
|
||||
return _TT_PARSE_ERROR;
|
||||
}
|
||||
} else {
|
||||
_tt_syslog(stderr, LOG_WARNING,
|
||||
catgets(_ttcatd, 4, 30,
|
||||
"no preprocessing done because: %s: %s"),
|
||||
OPT_CPP_PATH, strerror(ENOENT));
|
||||
yyin = fdopen(fd,"r");
|
||||
}
|
||||
|
||||
return parse_yyin();
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the file stream that yyin points to
|
||||
*/
|
||||
|
||||
_Tt_parse_status _Tt_types_table::
|
||||
parse_yyin()
|
||||
{
|
||||
_yylineno = -1;
|
||||
int errorp = yyparse();
|
||||
if ((use_cpp && pclose(yyin) != 0) ||
|
||||
(!use_cpp && fclose(yyin) != 0))
|
||||
{
|
||||
return _TT_PARSE_ERROR;
|
||||
}
|
||||
yyin = 0;
|
||||
if (errorp) {
|
||||
reset();
|
||||
return _TT_PARSE_ERROR;
|
||||
} else {
|
||||
return _TT_PARSE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check_semantics - checks otypes and ptypes
|
||||
* If no error found, returns _TT_PARSE_OK, otherwise returns _TT_PARSE_ERROR.
|
||||
*/
|
||||
|
||||
_Tt_parse_status _Tt_types_table::
|
||||
check_semantics()
|
||||
{
|
||||
_Tt_parse_status oresult, presult;
|
||||
|
||||
oresult = check_otypes();
|
||||
presult = check_ptypes();
|
||||
if (oresult == _TT_PARSE_ERROR || presult == _TT_PARSE_ERROR) {
|
||||
return _TT_PARSE_ERROR;
|
||||
} else {
|
||||
return _TT_PARSE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check each otype
|
||||
*/
|
||||
_Tt_parse_status _Tt_types_table::
|
||||
check_otypes()
|
||||
{
|
||||
_Tt_otype_table_cursor otypec(otable);
|
||||
_Tt_parse_status result = _TT_PARSE_OK;
|
||||
|
||||
while (otypec.next()) {
|
||||
if (check_otype(*otypec) == _TT_PARSE_ERROR) {
|
||||
result = _TT_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks an otype:
|
||||
* - Ptypes referenced in otypes are defined.
|
||||
* - Every inherited signature exists in the parent
|
||||
* - The inheritance hierarchy is acyclic.
|
||||
*/
|
||||
_Tt_parse_status _Tt_types_table::
|
||||
check_otype(_Tt_otype_ptr otype)
|
||||
{
|
||||
_Tt_ptype_ptr ptype;
|
||||
_Tt_string ptid;
|
||||
_Tt_parse_status result = _TT_PARSE_OK;
|
||||
_Tt_otype_ptr anc_otype;
|
||||
_Tt_string super;
|
||||
|
||||
if (otype->visitp < 0) {
|
||||
// already processed
|
||||
return _TT_PARSE_OK;
|
||||
}
|
||||
if (otype->visitp > 0) {
|
||||
// this otype is in progress, we have detected a loop
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 31,
|
||||
"otype inheritance cycle involving %s"),
|
||||
(char *) otype->otid());
|
||||
return _TT_PARSE_ERROR;
|
||||
}
|
||||
otype->visitp = 1; // in progress
|
||||
// Check all of the parents of this otype
|
||||
_Tt_string_list_cursor anc_name(otype->_ancestors);
|
||||
while (anc_name.next()) {
|
||||
anc_otype = otable->lookup(*anc_name);
|
||||
if (anc_otype.is_null()) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 32, "ancestor %s of "
|
||||
"otype %s does not exist"),
|
||||
(char *)(*anc_name), (char *)otype->otid());
|
||||
result = _TT_PARSE_ERROR;
|
||||
} else {
|
||||
if (check_otype(anc_otype) == _TT_PARSE_ERROR) {
|
||||
result = _TT_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check the signatures
|
||||
_Tt_signature_list_cursor s1(otype->_osigs);
|
||||
int handles = 0;
|
||||
while (1) {
|
||||
// step through the observer and handler signatures
|
||||
if (! s1.next()) {
|
||||
if (! handles) {
|
||||
s1.reset(otype->_hsigs);
|
||||
handles = 1;
|
||||
if (! s1.next()) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ptid = s1->ptid();
|
||||
if (ptid.len() != 0) {
|
||||
// a normal signature (not purely inherited)
|
||||
ptype = ptable->lookup(ptid);
|
||||
if (ptype.is_null()) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 33,
|
||||
"ptype %s does not exist, "
|
||||
"but was named as implementor"
|
||||
"by otype %s"),
|
||||
(char *)ptid,
|
||||
(char *)otype->otid());
|
||||
s1->print(stdout);
|
||||
result = _TT_PARSE_ERROR;
|
||||
} else {
|
||||
if (handles) {
|
||||
ptype->append_hsig(*s1, s1->category());
|
||||
} else {
|
||||
ptype->append_osig(*s1);
|
||||
}
|
||||
}
|
||||
}
|
||||
super = s1->super_otid();
|
||||
if (super.len() != 0) {
|
||||
// Check inheritance of this signature from parent
|
||||
anc_name.reset(otype->_ancestors);
|
||||
while (anc_name.next()) {
|
||||
if (*anc_name == super) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (anc_name.is_valid()) {
|
||||
// super otype is one of our parents
|
||||
// now look in the parent for a matching sig
|
||||
if (check_super_sig(otype, *s1, super, handles)
|
||||
== _TT_PARSE_ERROR) {
|
||||
result = _TT_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (handles) {
|
||||
/* Handlers with same sigs but different ptypes */
|
||||
_Tt_signature_list_cursor s2(s1);
|
||||
while (s2.next()) {
|
||||
if (s1->is_same_method(*s2)) {
|
||||
if (ptid == s2->ptid()) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 34, "multiple handlers defined in otype %s"),
|
||||
(char *)otype->_otid);
|
||||
s1->print(stdout);
|
||||
s2->print(stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
otype->visitp = -1; // signifies completed
|
||||
return(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the given signature exists in the supertype
|
||||
*/
|
||||
_Tt_parse_status _Tt_types_table::
|
||||
check_super_sig(_Tt_otype_ptr otype, _Tt_signature_ptr sig, _Tt_string super,
|
||||
int handles)
|
||||
{
|
||||
_Tt_otype_ptr super_otype = otable->lookup(super);
|
||||
if (super_otype.is_null()) {
|
||||
// the otype doesn't exist, nothing to check
|
||||
return _TT_PARSE_ERROR;
|
||||
}
|
||||
_Tt_signature_list_cursor super_sigc;
|
||||
if (handles) {
|
||||
super_sigc.reset(super_otype->_hsigs);
|
||||
} else {
|
||||
super_sigc.reset(super_otype->_osigs);
|
||||
}
|
||||
while (super_sigc.next()) {
|
||||
if (sig->is_same_method(*super_sigc)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! super_sigc.is_valid()) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 35, "inherited signature in "
|
||||
"otype %s does not exist in parent"),
|
||||
(char *)otype->otid());
|
||||
sig->print(stdout);
|
||||
return _TT_PARSE_ERROR;
|
||||
}
|
||||
if (sig->ptid().len() == 0) {
|
||||
// pure inheritance
|
||||
_Tt_signature_ptr super_sig = *super_sigc;
|
||||
_Tt_string super_ptid = super_sig->ptid();
|
||||
_Tt_ptype_ptr super_ptype = ptable->lookup(super_ptid);
|
||||
if (super_ptype.is_null()) {
|
||||
// super ptype doesn't exist
|
||||
return _TT_PARSE_ERROR;
|
||||
}
|
||||
// replace the fields of the signature with the super sig
|
||||
sig->set_scope(super_sig->scope());
|
||||
sig->set_message_class(super_sig->message_class());
|
||||
sig->set_op(super_sig->op());
|
||||
sig->set_reliability(super_sig->reliability());
|
||||
sig->set_opnum(super_sig->opnum());
|
||||
sig->set_ptid(super_sig->ptid());
|
||||
// create a duplicated of the parent signature and
|
||||
// replace the otid
|
||||
_Tt_signature_ptr new_sig(new _Tt_signature(super_sig));
|
||||
new_sig->set_otid(otype->otid());
|
||||
new_sig->set_super_otid(super);
|
||||
// install this signature on the super ptype
|
||||
if (handles) {
|
||||
super_ptype->append_hsig(new_sig, new_sig->category());
|
||||
} else {
|
||||
super_ptype->append_osig(new_sig);
|
||||
}
|
||||
}
|
||||
return _TT_PARSE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks ptypes:
|
||||
* - Each ptype handler function has a unique signature.
|
||||
*/
|
||||
_Tt_parse_status _Tt_types_table::
|
||||
check_ptypes()
|
||||
{
|
||||
_Tt_parse_status result = _TT_PARSE_OK;
|
||||
|
||||
_Tt_ptype_table_cursor ptc1(ptable);
|
||||
while (ptc1.next()) {
|
||||
/* check for duplicated signatures */
|
||||
if (ptc1->check_semantics()) {
|
||||
result = _TT_PARSE_ERROR;
|
||||
}
|
||||
/* check for unique handler signatures between ptypes */
|
||||
_Tt_ptype_table_cursor ptc2(ptc1);
|
||||
while (ptc2.next()) {
|
||||
_Tt_signature_list_cursor s1(ptc1->hsigs());
|
||||
while (s1.next()) {
|
||||
_Tt_signature_list_cursor s2(ptc2->hsigs());
|
||||
while (s2.next()) {
|
||||
if (**s1 == **s2) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 36, "two ptypes, %s and %s, with the same handler"),
|
||||
(char *)ptc1->ptid(),
|
||||
(char *)ptc2->ptid());
|
||||
s1->pretty_print(stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* check_cycle - check for a cyclic inheritance hierarchy. Also check
|
||||
* for uniquely defined inherited method (i.e., an inherited method M
|
||||
* cannot be from more than one ancestors whose all have M identically
|
||||
* defined); only give WARNING because user specifically indicates which
|
||||
* ancestor the inherited method comes from. Probably needs to add a
|
||||
* flag for controlling the printing of the warning.
|
||||
*/
|
||||
_Tt_parse_status _Tt_types_table::
|
||||
check_cycle(_Tt_otype_ptr otype, _Tt_otype **path, int top)
|
||||
{
|
||||
_Tt_parse_status result = _TT_PARSE_OK;
|
||||
otype->visitp = 1;
|
||||
path[top++] = otype.c_pointer();
|
||||
_Tt_string_list_cursor anc_name(otype->_ancestors);
|
||||
while (anc_name.next()) { /* depth-first traversal */
|
||||
_Tt_otype_ptr anc_otype = otable->lookup(*anc_name);
|
||||
if (anc_otype.is_null()) {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 37, "ancestor %s of "
|
||||
"otype %s does not exist"),
|
||||
(char *)(*anc_name), (char *)otype->otid());
|
||||
result = _TT_PARSE_ERROR;
|
||||
} else {
|
||||
for (int i = 0; i <= top-1; i++) {
|
||||
if (path[i] == anc_otype.c_pointer()) {
|
||||
fprintf(stderr,
|
||||
catgets(_ttcatd, 4, 38, "cyclic otype inheritance hierarchy -\n {"));
|
||||
for (int j = i; j <= top-1; j++) {
|
||||
fprintf(stderr," %s", (char *) path[j]->otid());
|
||||
}
|
||||
fprintf(stderr," %s }\n",
|
||||
(char *) anc_otype->otid());
|
||||
result = _TT_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
if (!anc_otype->visitp) {
|
||||
result = (_Tt_parse_status)
|
||||
(result +
|
||||
check_cycle(anc_otype, path, top));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
insert_otype(_Tt_otype_ptr &type)
|
||||
{
|
||||
if (otable->lookup(type->otid()).is_null()) {
|
||||
otable->insert(type);
|
||||
} else {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 39,
|
||||
"duplicated definitions of otype %s"),
|
||||
(char *)type->otid());
|
||||
}
|
||||
}
|
||||
|
||||
_Tt_otype_ptr _Tt_types_table::
|
||||
lookup_otype(_Tt_string otid) const
|
||||
{
|
||||
return otable->lookup(otid);
|
||||
}
|
||||
|
||||
int _Tt_types_table::
|
||||
next_otype(_Tt_otype_ptr &o)
|
||||
{
|
||||
if (otc.next()) {
|
||||
o = *otc;
|
||||
return(1);
|
||||
} else {
|
||||
otc.reset(otable);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
reset_otype_cursor()
|
||||
{
|
||||
otc.reset(otable);
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
insert_ptype(_Tt_ptype_ptr &type)
|
||||
{
|
||||
if (ptable->lookup(type->ptid()).is_null()) {
|
||||
ptable->insert(type);
|
||||
} else {
|
||||
_tt_syslog(stderr, LOG_ERR,
|
||||
catgets(_ttcatd, 4, 40,
|
||||
"duplicated definitions of ptype %s"),
|
||||
(char *)type->ptid());
|
||||
}
|
||||
}
|
||||
|
||||
_Tt_ptype_ptr _Tt_types_table::
|
||||
lookup_ptype(_Tt_string ptid) const
|
||||
{
|
||||
return ptable->lookup(ptid);
|
||||
}
|
||||
|
||||
int _Tt_types_table::
|
||||
next_ptype(_Tt_ptype_ptr &p)
|
||||
{
|
||||
if (ptc.next()) {
|
||||
p = *ptc;
|
||||
return(1);
|
||||
} else {
|
||||
ptc.reset(ptable);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
reset_ptype_cursor()
|
||||
{
|
||||
ptc.reset(ptable);
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
print(FILE *fs) const
|
||||
{
|
||||
otable->print(_tt_otype_print, fs);
|
||||
ptable->print(_tt_ptype_print, fs);
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
reset()
|
||||
{
|
||||
|
||||
ptable = new _Tt_ptype_table(_tt_ptype_ptid,TT_TYPE_TABLE_BUCKETS);
|
||||
ptc.reset(ptable);
|
||||
otable = new _Tt_otype_table(_tt_otype_otid,TT_TYPE_TABLE_BUCKETS);
|
||||
otc.reset(otable);
|
||||
reset_tmps();
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
reset_tmps()
|
||||
{
|
||||
tmp_otype = new _Tt_otype();
|
||||
tmp_ptype = new _Tt_ptype();
|
||||
tmp_sigl = new _Tt_signature_list();
|
||||
tmp_sig = new _Tt_signature();
|
||||
tmp_arg = new _Tt_arg();
|
||||
tmp_propname = 0;
|
||||
tmp_propvalue = 0;
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
set_tmp_propname(_Tt_string name)
|
||||
{
|
||||
tmp_propname = name;
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
append_sig(_Tt_signature_ptr &sig)
|
||||
{
|
||||
tmp_sigl->append(sig);
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
yyerror(const char *s)
|
||||
{
|
||||
if (_file_name.len() > 0) {
|
||||
fprintf(stderr,"\"%s\", line %d: %s\n",
|
||||
(char *)_file_name,
|
||||
_yylineno, s);
|
||||
} else {
|
||||
fprintf(stderr,"\"%s\", line %d: %s\n",
|
||||
"<standard input>",
|
||||
_yylineno, s);
|
||||
}
|
||||
}
|
||||
|
||||
int _Tt_types_table::
|
||||
input()
|
||||
{
|
||||
int c;
|
||||
// very first line is a special case. Pretend it was preceded by`
|
||||
// a newline.
|
||||
|
||||
if (_yylineno == -1) {
|
||||
c = '\n';
|
||||
_yylineno = 0;
|
||||
} else {
|
||||
c = getc(yyin);
|
||||
}
|
||||
while (c == '\n') {
|
||||
_yylineno++;
|
||||
c = getc(yyin);
|
||||
while (c == '#') {
|
||||
char buf[MAXPATHLEN+100];
|
||||
// Apparently fgets can't be used because ungetc is
|
||||
int i;
|
||||
for (i=0;i<sizeof(buf)-1;i++){
|
||||
buf[i] = getc(yyin);
|
||||
if (buf[i] == '\n') break;
|
||||
}
|
||||
buf[i] = 0;
|
||||
docppline(buf, _yylineno, _file_name);
|
||||
// cpp line directives are invisible
|
||||
c = getc(yyin);
|
||||
}
|
||||
}
|
||||
return (c == EOF) ? 0 : c;
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
unput(int c)
|
||||
{
|
||||
if (c == '\n') {
|
||||
_yylineno--;
|
||||
}
|
||||
ungetc(c, yyin);
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
output(int /* c */)
|
||||
{
|
||||
/* putc(c, yyout); do nothing */
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
skip_c_comments()
|
||||
{
|
||||
int c;
|
||||
|
||||
for (;;) {
|
||||
while ((c=input())!='*') {
|
||||
;
|
||||
}
|
||||
if ((c=input())!='/') {
|
||||
unput(c);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _Tt_types_table::
|
||||
skip_cplusplus_comments()
|
||||
{
|
||||
int c;
|
||||
int savelineno;
|
||||
|
||||
// input() never returns a newline because it has # line
|
||||
// processing imbedded in it, which eats the newlines.
|
||||
// so we tell when input() has gone past a newline by watching
|
||||
// for _yylineno to change.
|
||||
|
||||
savelineno = _yylineno;
|
||||
while(savelineno==_yylineno) {
|
||||
c = input();
|
||||
}
|
||||
unput(c);
|
||||
}
|
||||
|
||||
|
||||
int _Tt_types_table::
|
||||
yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
docppline(const char *line, int &lineno, _Tt_string &fname)
|
||||
{
|
||||
char *file;
|
||||
int num;
|
||||
char *p;
|
||||
|
||||
while (isspace(*line)) {
|
||||
line++;
|
||||
}
|
||||
num = atoi(line);
|
||||
while (isdigit(*line)) {
|
||||
line++;
|
||||
}
|
||||
while (isspace(*line)) {
|
||||
line++;
|
||||
}
|
||||
if (*line != '"') {
|
||||
fname = "<Unknown, preprocessor error.>";
|
||||
}
|
||||
line++;
|
||||
file = (char *)malloc(strlen(line) + 1);
|
||||
p = file;
|
||||
while (*line && *line != '"') {
|
||||
*p++ = *line++;
|
||||
}
|
||||
*p++ = 0;
|
||||
if (*line == 0) {
|
||||
fname = "<Unknown, preprocessor error.>";
|
||||
} else {
|
||||
fname = file;
|
||||
}
|
||||
free(file);
|
||||
lineno = num;
|
||||
}
|
||||
118
cde/lib/tt/bin/tt_type_comp/mp_types_table.h
Normal file
118
cde/lib/tt/bin/tt_type_comp/mp_types_table.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: mp_types_table.h /main/3 1995/10/20 16:39:07 rswiston $ */
|
||||
/*
|
||||
* Tool Talk Message Passer (PM) - mp_types_table.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* This file contains the declaration for the class _TT_types_table which implements
|
||||
* a hash table of otype and ptype descriptors.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TT_MP_TYPES_TABLE_H
|
||||
#define _TT_MP_TYPES_TABLE_H
|
||||
#include "util/tt_object.h"
|
||||
#include "mp/mp_global.h"
|
||||
#include "mp_otype_utils.h"
|
||||
#include "mp_otype.h"
|
||||
#include "mp_ptype.h"
|
||||
#include "mp_ptype_utils.h"
|
||||
#include "mp_signature.h"
|
||||
#include "mp_signature_utils.h"
|
||||
#include "mp/mp_context.h"
|
||||
#include "util/tt_list.h"
|
||||
#include "util/tt_string.h"
|
||||
#include "util/tt_table.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* Hack for JLE systems */
|
||||
|
||||
#ifdef input
|
||||
#undef input
|
||||
#endif
|
||||
#ifdef output
|
||||
#undef output
|
||||
#endif
|
||||
|
||||
/* Hack for flex */
|
||||
#ifdef FLEX_SCANNER
|
||||
#ifdef yywrap
|
||||
#undef yywrap
|
||||
#endif
|
||||
#endif /* FLEX_SCANNER */
|
||||
|
||||
enum _Tt_parse_status {
|
||||
_TT_PARSE_OK,
|
||||
_TT_PARSE_ERROR
|
||||
};
|
||||
|
||||
extern _Tt_string cpp_options;
|
||||
|
||||
class _Tt_types_table : public _Tt_object {
|
||||
public:
|
||||
_Tt_types_table(FILE *infs, _Tt_parse_status &result);
|
||||
_Tt_types_table(_Tt_string types_def_path, _Tt_parse_status &result);
|
||||
_Tt_parse_status parse_path(_Tt_string path);
|
||||
_Tt_parse_status parse_yyin();
|
||||
_Tt_parse_status check_semantics();
|
||||
_Tt_otype_table_ptr &otypes();
|
||||
_Tt_otype_ptr lookup_otype(_Tt_string otid) const;
|
||||
int next_otype(_Tt_otype_ptr &o);
|
||||
void reset_otype_cursor();
|
||||
_Tt_ptype_table_ptr &ptypes();
|
||||
_Tt_ptype_ptr lookup_ptype(_Tt_string ptid) const;
|
||||
int next_ptype(_Tt_ptype_ptr &p);
|
||||
void reset_ptype_cursor();
|
||||
virtual void print(FILE *fs = stdout) const;
|
||||
int has_contexts;
|
||||
private:
|
||||
void insert_otype(_Tt_otype_ptr &otype);
|
||||
void insert_ptype(_Tt_ptype_ptr &ptype);
|
||||
void reset();
|
||||
void reset_tmps();
|
||||
void append_sig(_Tt_signature_ptr &sig);
|
||||
void set_tmp_propname(_Tt_string name);
|
||||
_Tt_parse_status check_cycle(_Tt_otype_ptr otype, _Tt_otype **path,
|
||||
int top);
|
||||
_Tt_parse_status check_otypes();
|
||||
_Tt_parse_status check_ptypes();
|
||||
_Tt_parse_status check_otype(_Tt_otype_ptr otype);
|
||||
_Tt_parse_status check_super_sig(_Tt_otype_ptr otype,
|
||||
_Tt_signature_ptr sig,
|
||||
_Tt_string super,
|
||||
int handles);
|
||||
int yyparse(void);
|
||||
void yyerror(const char *s);
|
||||
int yylex(void);
|
||||
int yylook();
|
||||
int yyback(int *p, int m);
|
||||
int input();
|
||||
void unput(int c);
|
||||
void output(int c);
|
||||
int yywrap(void);
|
||||
void skip_c_comments(void);
|
||||
void skip_cplusplus_comments(void);
|
||||
|
||||
_Tt_ptype_table_ptr ptable;
|
||||
_Tt_ptype_table_cursor ptc;
|
||||
_Tt_otype_table_ptr otable;
|
||||
_Tt_otype_table_cursor otc;
|
||||
FILE *yyin;
|
||||
_Tt_string _file_name;
|
||||
int _yylineno;
|
||||
_Tt_otype_ptr tmp_otype;
|
||||
_Tt_ptype_ptr tmp_ptype;
|
||||
_Tt_string_list_ptr tmp_otidl;
|
||||
_Tt_string tmp_otid;
|
||||
_Tt_signature_list_ptr tmp_sigl;
|
||||
_Tt_signature_ptr tmp_sig;
|
||||
_Tt_arg_ptr tmp_arg;
|
||||
_Tt_string tmp_propname;
|
||||
_Tt_string tmp_propvalue;
|
||||
};
|
||||
|
||||
#endif /* _TT_MP_TYPES_TABLE_H */
|
||||
22
cde/lib/tt/bin/ttauth/Imakefile
Normal file
22
cde/lib/tt/bin/ttauth/Imakefile
Normal file
@@ -0,0 +1,22 @@
|
||||
XCOMM $TOG: Imakefile /main/1 1999/08/30 10:44:56 mgreess $
|
||||
|
||||
#include <Threads.tmpl>
|
||||
#include "../../tooltalk.tmpl"
|
||||
|
||||
DEFINES =
|
||||
CONN_DEFINES = ConnectionFlags
|
||||
INCLUDES = -I. -I../../slib -I../../lib
|
||||
|
||||
DEPLIBS = TtClientDepLibs
|
||||
LOCAL_LIBRARIES = TtClientLibs
|
||||
SYS_LIBRARIES =
|
||||
#ifdef TtClientExtraLibs
|
||||
EXTRA_LIBRARIES = TtClientExtraLibs
|
||||
#endif
|
||||
|
||||
SRCS = ttauth.c process.c
|
||||
OBJS = ttauth.o process.o
|
||||
|
||||
ComplexProgramTarget(ttauth)
|
||||
|
||||
SpecialCObjectRule(process,$(ICONFIGFILES),$(SIGNAL_DEFINES))
|
||||
1557
cde/lib/tt/bin/ttauth/process.c
Normal file
1557
cde/lib/tt/bin/ttauth/process.c
Normal file
File diff suppressed because it is too large
Load Diff
163
cde/lib/tt/bin/ttauth/ttauth.c
Normal file
163
cde/lib/tt/bin/ttauth/ttauth.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* $TOG: ttauth.c /main/1 1999/08/30 10:46:20 mgreess $
|
||||
*
|
||||
* xauth - manipulate authorization file
|
||||
*
|
||||
*
|
||||
Copyright 1989, 1998 The Open Group
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
* *
|
||||
* Original Author of "xauth" : Jim Fulton, MIT X Consortium
|
||||
* Modified into "iceauth" : Ralph Mor, X Consortium
|
||||
* Modified into "ttauth" : Mitch Greess, Solutions Atlantic
|
||||
*/
|
||||
|
||||
#include "ttauth.h"
|
||||
#include "api/c/tt_c.h"
|
||||
|
||||
|
||||
/*
|
||||
* global data
|
||||
*/
|
||||
char *ProgramName; /* argv[0], set at top of main() */
|
||||
int verbose = -1; /* print certain messages */
|
||||
Bool ignore_locks = False; /* for error recovery */
|
||||
Bool break_locks = False; /* for error recovery */
|
||||
|
||||
/*
|
||||
* local data
|
||||
*/
|
||||
|
||||
static char *authfilename = NULL; /* filename of cookie file */
|
||||
static char *defcmds[] = { "source", "-", NULL }; /* default command */
|
||||
static int ndefcmds = 2;
|
||||
static char *defsource = "(stdin)";
|
||||
|
||||
/*
|
||||
* utility routines
|
||||
*/
|
||||
static void usage ()
|
||||
{
|
||||
static char *prefixmsg[] = {
|
||||
"",
|
||||
"where options include:",
|
||||
" -f authfilename name of authority file to use",
|
||||
" -v turn on extra messages",
|
||||
" -q turn off extra messages",
|
||||
" -i ignore locks on authority file",
|
||||
" -b break locks on authority file",
|
||||
"",
|
||||
"and commands have the following syntax:",
|
||||
"",
|
||||
NULL };
|
||||
static char *suffixmsg[] = {
|
||||
"A dash may be used with the \"merge\" and \"source\" to read from the",
|
||||
"standard input. Commands beginning with \"n\" use numeric format.",
|
||||
"",
|
||||
NULL };
|
||||
char **msg;
|
||||
|
||||
fprintf (stderr, "usage: %s [-options ...] [command arg ...]\n",
|
||||
ProgramName);
|
||||
for (msg = prefixmsg; *msg; msg++) {
|
||||
fprintf (stderr, "%s\n", *msg);
|
||||
}
|
||||
print_help (stderr, NULL, " "); /* match prefix indentation */
|
||||
fprintf (stderr, "\n");
|
||||
for (msg = suffixmsg; *msg; msg++) {
|
||||
fprintf (stderr, "%s\n", *msg);
|
||||
}
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The main routine - parses command line and calls action procedures
|
||||
*/
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i;
|
||||
char *sourcename = defsource;
|
||||
char **arglist = defcmds;
|
||||
int nargs = ndefcmds;
|
||||
int status;
|
||||
|
||||
ProgramName = argv[0];
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
char *arg = argv[i];
|
||||
|
||||
if (arg[0] == '-') {
|
||||
char *flag;
|
||||
|
||||
for (flag = (arg + 1); *flag; flag++) {
|
||||
switch (*flag) {
|
||||
case 'f': /* -f authfilename */
|
||||
if (++i >= argc) usage ();
|
||||
authfilename = argv[i];
|
||||
continue;
|
||||
case 'v': /* -v */
|
||||
verbose = 1;
|
||||
continue;
|
||||
case 'q': /* -q */
|
||||
verbose = 0;
|
||||
continue;
|
||||
case 'b': /* -b */
|
||||
break_locks = True;
|
||||
continue;
|
||||
case 'i': /* -i */
|
||||
ignore_locks = True;
|
||||
continue;
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sourcename = "(argv)";
|
||||
nargs = argc - i;
|
||||
arglist = argv + i;
|
||||
if (verbose == -1) verbose = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose == -1) { /* set default, don't junk stdout */
|
||||
verbose = (isatty(fileno(stdout)) != 0);
|
||||
}
|
||||
|
||||
if (!authfilename) {
|
||||
authfilename = tt_AuthFileName (); /* static name, do not free */
|
||||
if (!authfilename) {
|
||||
fprintf (stderr,
|
||||
"%s: unable to generate an authority file name\n",
|
||||
ProgramName);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
if (auth_initialize (authfilename) != 0) {
|
||||
/* error message printed in auth_initialize */
|
||||
exit (1);
|
||||
}
|
||||
|
||||
status = process_command (sourcename, 1, nargs, arglist);
|
||||
|
||||
(void) auth_finalize ();
|
||||
exit ((status != 0) ? 1 : 0);
|
||||
}
|
||||
43
cde/lib/tt/bin/ttauth/ttauth.h
Normal file
43
cde/lib/tt/bin/ttauth/ttauth.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* $TOG: ttauth.h /main/1 1999/08/30 10:47:04 mgreess $
|
||||
*
|
||||
*
|
||||
Copyright 1989, 1998 The Open Group
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
* *
|
||||
* Author: Jim Fulton, MIT X Consortium
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <X11/Xfuncs.h>
|
||||
|
||||
#ifndef True
|
||||
typedef int Bool;
|
||||
#define False 0
|
||||
#define True 1
|
||||
#endif
|
||||
|
||||
extern char *ProgramName;
|
||||
|
||||
extern char *malloc(), *realloc();
|
||||
int process_command(), auth_initialize(), auth_finalize();
|
||||
extern int print_help();
|
||||
extern int verbose;
|
||||
extern Bool ignore_locks;
|
||||
extern Bool break_locks;
|
||||
216
cde/lib/tt/bin/ttauth/ttauth.man
Normal file
216
cde/lib/tt/bin/ttauth/ttauth.man
Normal file
@@ -0,0 +1,216 @@
|
||||
.\" $TOG: ttauth.man /main/3 1999/10/12 13:33:52 mgreess $
|
||||
.\" Copyright 1993, 1998 The Open Group
|
||||
.\"
|
||||
.\" All Rights Reserved.
|
||||
.\"
|
||||
.\" The above copyright notice and this permission notice shall be included
|
||||
.\" in all copies or substantial portions of the Software.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
.\" OTHER DEALINGS IN THE SOFTWARE.
|
||||
.\"
|
||||
.\" Except as contained in this notice, the name of The Open Group shall
|
||||
.\" not be used in advertising or otherwise to promote the sale, use or
|
||||
.\" other dealings in this Software without prior written authorization
|
||||
.\" from The Open Group.
|
||||
.TH TTAUTH 1 "Release 2.1.30" "CDE"
|
||||
.SH NAME
|
||||
ttauth \- ToolTalk authority file utility
|
||||
.SH SYNOPSIS
|
||||
.B ttauth
|
||||
[ \fB\-f\fP \fIauthfile\fP ] [ \fB\-vqib\fP ] [ \fIcommand arg ...\fP ]
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The \fIttauth\fP program is used to edit and display the authorization
|
||||
information used in connecting to ToolTalk. This program is usually
|
||||
used to extract authorization records from one machine and merge them in on
|
||||
another (as is the case when using remote logins or granting access to
|
||||
other users). Commands (described below) may be entered interactively,
|
||||
on the \fIttauth\fP command line, or in scripts. Note that this program
|
||||
does \fBnot\fP contact the ToolTalk server, \fIttsession\fP.
|
||||
Normally \fIttauth\fP is not used to create the authority file entry in
|
||||
the first place; \fIttsession\fP does that.
|
||||
.SH OPTIONS
|
||||
The following options may be used with \fIttauth\fP. They may be given
|
||||
individually (e.g., \fI\-q \-i\|\fP) or may combined (e.g., \fI\-qi\|\fP).
|
||||
.TP 8
|
||||
.B "\-f \fIauthfile\fP"
|
||||
This option specifies the name of the authority file to use. By default,
|
||||
\fIttauth\fP will use the file specified by the TTAUTHORITY environment variable
|
||||
or \fI\.TTauthority\fP in the user's home directory.
|
||||
.TP 8
|
||||
.B \-q
|
||||
This option indicates that \fIttauth\fP should operate quietly and not print
|
||||
unsolicited status messages. This is the default if an \fIttauth\fP command is
|
||||
is given on the command line or if the standard output is not directed to a
|
||||
terminal.
|
||||
.TP 8
|
||||
.B \-v
|
||||
This option indicates that \fIttauth\fP should operate verbosely and print
|
||||
status messages indicating the results of various operations (e.g., how many
|
||||
records have been read in or written out). This is the default if \fIttauth\fP
|
||||
is reading commands from its standard input and its standard output is
|
||||
directed to a terminal.
|
||||
.TP 8
|
||||
.B \-i
|
||||
This option indicates that \fIttauth\fP should ignore any authority file
|
||||
locks. Normally, \fIttauth\fP will refuse to read or edit any authority files
|
||||
that have been locked by other programs (usually \fIttsession\fP or another
|
||||
\fIttauth\fP).
|
||||
.TP 8
|
||||
.B \-b
|
||||
This option indicates that \fIttauth\fP should attempt to break any authority
|
||||
file locks before proceeding. Use this option only to clean up stale locks.
|
||||
.SH COMMANDS
|
||||
The following commands may be used to manipulate authority files:
|
||||
.TP 8
|
||||
.B "add \fIprotoname protodata netid authname authdata"
|
||||
An authorization entry for the indicated ToolTalk session using the given
|
||||
protocol name (\fIprotoname\fP), protocol data (\fIprotodata\fP), ToolTalk
|
||||
session id (\fInetid\fP), authentication name (\fIauthname\fP), and
|
||||
authentication data (\fIauthdata\fP) is added to the authorization file.
|
||||
The protocol name should always be the string \fITT\fP. The protocol data
|
||||
should always be the empty string \fI""\fP. The ToolTalk session id is
|
||||
formatted string consisting of the ttsession program number, the ttsession
|
||||
authorization level, the IP address of the host running ttsession, and the
|
||||
RPC version number of the ttsession. See the section
|
||||
\fITTSESSION IDENTIFIERS\fP below for information on constructing ToolTalk
|
||||
session id's for the authority file.
|
||||
The authentication name should always be the string
|
||||
\fIMIT-MAGIC-COOKIE-1\fP. The authentication data is specified as
|
||||
an even-lengthed string of hexadecimal digits, each pair representing
|
||||
one octet. The first digit of each pair gives the most significant 4 bits
|
||||
of the octet, and the second digit of the pair gives the least significant 4
|
||||
bits. For example, a 32 character hexkey would represent a 128-bit value.
|
||||
|
||||
.TP 8
|
||||
.B "[n]extract \fIfilename <protoname=$> <protodata=$> <netid=$> <authname=$>\fP"
|
||||
Authorization entries which match the specified fields are written to the
|
||||
indicated file. If the \fInextract\fP command is used, the entries are written
|
||||
in a numeric format suitable for non-binary transmission (such as secure
|
||||
electronic mail). The extracted entries can be read back in using the
|
||||
\fImerge\fP and \fInmerge\fP commands. If the filename consists of
|
||||
just a single dash, the entries will be written to the standard output.
|
||||
.TP 8
|
||||
.B "[n]list \fR\fI<protoname=$> <protodata=$> <netid=$> <authname=$>\fP"
|
||||
Authorization entries which match the specified fields (or all if nothing
|
||||
is specified) are printed on the standard output. If the \fInlist\fP
|
||||
command is used, entries will be shown in the numeric format used by
|
||||
the \fInextract\fP command; otherwise, they are shown in a textual format.
|
||||
Key data is always displayed in the hexadecimal format given in the
|
||||
description of the \fIadd\fP command.
|
||||
.TP 8
|
||||
.B "[n]merge \fR[\fIfilename1 <filename2> <filename3>\fP...]"
|
||||
Authorization entries are read from the specified files and are merged into
|
||||
the authorization database, superceding any matching existing entries. If
|
||||
the \fInmerge\fP command is used, the numeric format given in the description
|
||||
of the \fIextract\fP command is used. If a filename consists of just a single
|
||||
dash, the standard input will be read if it hasn't been read before.
|
||||
.TP 8
|
||||
.B "remove \fI<protoname=$> <protodata=$> <netid=$> <authname=$>\fR"
|
||||
Authorization entries which match the specified fields are removed from the
|
||||
authority file.
|
||||
.TP 8
|
||||
.B "source \fIfilename"
|
||||
The specified file is treated as a script containing \fIttauth\fP commands
|
||||
to execute. Blank lines and lines beginning with a sharp sign (#) are
|
||||
ignored. A single dash may be used to indicate the standard input, if it
|
||||
hasn't already been read.
|
||||
.TP 8
|
||||
.B "info"
|
||||
Information describing the authorization file, whether or not any changes
|
||||
have been made, and from where \fIttauth\fP commands are being read
|
||||
is printed on the standard output.
|
||||
.TP 8
|
||||
.B "exit"
|
||||
If any modifications have been made, the authority file is written out (if
|
||||
allowed), and the program exits. An end of file is treated as an implicit
|
||||
\fIexit\fP command.
|
||||
.TP 8
|
||||
.B "quit"
|
||||
The program exits, ignoring any modifications. This may also be accomplished
|
||||
by pressing the interrupt character.
|
||||
.TP 8
|
||||
.B "help [\fIstring\fP]"
|
||||
A description of all commands that begin with the given string (or all
|
||||
commands if no string is given) is printed on the standard output.
|
||||
.TP 8
|
||||
.B "?"
|
||||
A short list of the valid commands is printed on the standard output.
|
||||
.SH "TTSESSION IDENTIFIERS"
|
||||
The ToolTalk session identifiers (\fInetid\fP) in the authority file and
|
||||
used by the \fIadd\fP, \fI[n]extract\fP, \fI[n]list\fP, and \fIremove\fP
|
||||
commands are derived from the TT_SESSION identifier constructed by
|
||||
ttsession at startup. Ttsession rendezvous with clients by writing the
|
||||
TT_SESSION identifier as a property on the root window or as an environment
|
||||
variable in the client's environment (see ttsession -c). In addition,
|
||||
ttsession creates an entry in the user's authority file. The authority
|
||||
file entry has a \fInetid\fP component which is derived from the TT_SESSION
|
||||
identifier.
|
||||
.PP
|
||||
The TT_SESSION identifier is composed of the following elements:
|
||||
.sp
|
||||
.nf
|
||||
e.g.: TT_SESSION(STRING) = "01 1433 1342177279 1 1 2002 130.105.9.22 4"
|
||||
<Dummy Number> = 01
|
||||
<ttsession Process Id> = 1433
|
||||
<ttsession Program Number> = 1342177279
|
||||
<DummyNumber> = 1
|
||||
<ttsession Authorization Level> = 1
|
||||
<ttsession UID> = 2002
|
||||
<Host IP Address> = 130.105.9.22
|
||||
<RPC Version Number> = 4
|
||||
.fi
|
||||
.PP
|
||||
The ToolTalk session identifiers (\fInetid\fP) in the authority file are
|
||||
composed of the <\fIttsession Program Number\fP>,
|
||||
<\fIttsession Authorization Level\fP>,
|
||||
<\fIHost IP Address\fP>, and
|
||||
<\fIRPC Version Number\fP> fields of the TT_SESSION identifier as follows:
|
||||
.sp
|
||||
.nf
|
||||
e.g: 1342177279/1/130.105.9.22/4
|
||||
.fi
|
||||
.SH EXAMPLE
|
||||
.PP
|
||||
The most common use for \fIttauth\fP is to extract the entry for the
|
||||
current ttsession, copy it to another machine, and merge it into the
|
||||
user's authority file on the remote machine:
|
||||
.sp
|
||||
.nf
|
||||
% xprop -root | grep TT_SESSION
|
||||
TT_SESSION(STRING) = "01 1433 1342177279 1 1 2002 130.105.9.22 4"
|
||||
_SUN_TT_SESSION(STRING) = "01 1433 1342177279 1 1 2002 130.105.9.22 4"
|
||||
% ttauth extract \- netid=1342177279/1/130.105.9.22/4 | rsh otherhost ttauth merge \-
|
||||
.fi
|
||||
.SH ENVIRONMENT
|
||||
This \fIttauth\fP program uses the following environment variables:
|
||||
.TP 8
|
||||
.B TTAUTHORITY
|
||||
to get the name of the authority file to use if the \fI\-f\fP option isn't
|
||||
used.
|
||||
.TP 8
|
||||
.B HOME
|
||||
to get the user's home directory if TTAUTHORITY isn't defined.
|
||||
.SH FILES
|
||||
.TP 8
|
||||
.I $HOME/.TTauthority
|
||||
default authority file if TTAUTHORITY isn't defined.
|
||||
.SH BUGS
|
||||
.PP
|
||||
Users that have unsecure networks should take care to use encrypted
|
||||
file transfer mechanisms to copy authorization entries between machines.
|
||||
Similarly, the \fIMIT-MAGIC-COOKIE-1\fP protocol is not very useful in
|
||||
unsecure environments. Sites that are interested in additional security
|
||||
may need to use encrypted authorization mechanisms such as Kerberos.
|
||||
.PP
|
||||
Spaces are currently not allowed in the protocol name. Quoting could be
|
||||
added for the truly perverse.
|
||||
.SH AUTHORS
|
||||
Jim Fulton, MIT X Consortium, and
|
||||
Mitchell Greess, Solutions Atlantic
|
||||
65
cde/lib/tt/bin/ttdbserverd/Imakefile
Normal file
65
cde/lib/tt/bin/ttdbserverd/Imakefile
Normal file
@@ -0,0 +1,65 @@
|
||||
XCOMM $XConsortium: Imakefile /main/15 1996/09/30 13:50:43 drk $
|
||||
|
||||
#define CplusplusSource YES
|
||||
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
|
||||
EXTRA_LOAD_FLAGS = ExtraLoadFlags $(UNSHARED_CXXLIB)
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#include "../../tooltalk.tmpl"
|
||||
|
||||
DEFINES =
|
||||
INCLUDES = -I. -I../../slib -I../../lib -I../../mini_isam
|
||||
|
||||
DEPLIBS = ../../slib/libstt.a TtClientDepLibs ../../mini_isam/libisam.a
|
||||
LOCAL_LIBRARIES = ../../slib/libstt.a TtClientLibs ../../mini_isam/libisam.a
|
||||
SYS_LIBRARIES =
|
||||
|
||||
#ifdef TtClientExtraLibs
|
||||
EXTRA_LIBRARIES = TtClientExtraLibs
|
||||
#endif
|
||||
|
||||
|
||||
SRCS = \
|
||||
db_server_functions.C \
|
||||
db_server_svc.C \
|
||||
dm_access_cache.C \
|
||||
dm_server.C \
|
||||
tt_db_message_info_utils.C \
|
||||
tt_db_msg_q_lock.C \
|
||||
tt_db_msg_q_lock_entry_utils.C \
|
||||
tt_db_partition_global_map_ref.C \
|
||||
tt_db_partition_redirection_map.C \
|
||||
tt_db_server_db.C \
|
||||
tt_db_server_db_utils.C \
|
||||
tt_isam_file.C \
|
||||
tt_isam_file_utils.C \
|
||||
tt_isam_key_descriptor.C \
|
||||
tt_isam_key_descriptor_utils.C \
|
||||
tt_isam_record.C \
|
||||
tt_isam_record_utils.C
|
||||
|
||||
OBJS = \
|
||||
db_server_functions.o \
|
||||
db_server_svc.o \
|
||||
dm_access_cache.o \
|
||||
dm_server.o \
|
||||
tt_db_message_info_utils.o \
|
||||
tt_db_msg_q_lock.o \
|
||||
tt_db_msg_q_lock_entry_utils.o \
|
||||
tt_db_partition_global_map_ref.o \
|
||||
tt_db_partition_redirection_map.o \
|
||||
tt_db_server_db.o \
|
||||
tt_db_server_db_utils.o \
|
||||
tt_isam_file.o \
|
||||
tt_isam_file_utils.o \
|
||||
tt_isam_key_descriptor.o \
|
||||
tt_isam_key_descriptor_utils.o \
|
||||
tt_isam_record.o \
|
||||
tt_isam_record_utils.o
|
||||
|
||||
NormalCplusplusObjectRule()
|
||||
|
||||
ComplexCplusplusProgramTarget(rpc.ttdbserver)
|
||||
|
||||
SpecialCplusplusObjectRule(db_server_svc,db_server_svc,$(TT_VERSION_DEFINE))
|
||||
6
cde/lib/tt/bin/ttdbserverd/Mapfile
Normal file
6
cde/lib/tt/bin/ttdbserverd/Mapfile
Normal file
@@ -0,0 +1,6 @@
|
||||
# %% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
# %% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
# %% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
# %% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
# %% $XConsortium: Mapfile /main/3 1995/10/20 16:39:55 rswiston $
|
||||
text=LOAD ?RXO;
|
||||
11
cde/lib/tt/bin/ttdbserverd/admindefines
Normal file
11
cde/lib/tt/bin/ttdbserverd/admindefines
Normal file
@@ -0,0 +1,11 @@
|
||||
XCOMM $XConsortium: admindefines /main/2 1996/05/07 19:16:51 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
|
||||
2762
cde/lib/tt/bin/ttdbserverd/db_server_functions.C
Normal file
2762
cde/lib/tt/bin/ttdbserverd/db_server_functions.C
Normal file
File diff suppressed because it is too large
Load Diff
47
cde/lib/tt/bin/ttdbserverd/db_server_globals.h
Normal file
47
cde/lib/tt/bin/ttdbserverd/db_server_globals.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: db_server_globals.h /main/6 1996/05/07 13:51:43 drk $ */
|
||||
/*
|
||||
* db_server_globals.h - Declares the global variables that were defined
|
||||
* in the old DB server and needed by the new DB
|
||||
* server.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DB_SERVER_GLOBALS_H
|
||||
#define _DB_SERVER_GLOBALS_H
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#if defined(OPT_GARBAGE_THREADS)
|
||||
#include <synch.h>
|
||||
#endif // OPT_GARBAGE_THREADS
|
||||
|
||||
extern uid_t _tt_uid;
|
||||
extern gid_t _tt_gid;
|
||||
extern gid_t _tt_gidlist [NGROUPS_MAX];
|
||||
extern int _tt_gidlen;
|
||||
extern int _tt_auth_level;
|
||||
|
||||
#if defined(OPT_GARBAGE_THREADS)
|
||||
extern mutex_t rpc_client_busy; /* Used to sync calls with the RPC clients.*/
|
||||
extern mutex_t garbage_run_in_process;
|
||||
|
||||
#define LOCK_RPC() mutex_lock(&rpc_client_busy);
|
||||
#define UNLOCK_RPC() mutex_unlock(&rpc_client_busy);
|
||||
|
||||
#else /* Else if ! defined(OPT_GARBAGE_THREADS) */
|
||||
|
||||
#define LOCK_RPC() /*EMPTY*/
|
||||
#define UNLOCK_RPC() /*EMPTY*/
|
||||
|
||||
extern int _tt_garbage_id;
|
||||
extern char **global_argv;
|
||||
extern char **global_envp;
|
||||
#endif /* OPT_GARBAGE_THREADS */
|
||||
|
||||
#endif /* _DB_SERVER_GLOBALS_H */
|
||||
1527
cde/lib/tt/bin/ttdbserverd/db_server_svc.C
Normal file
1527
cde/lib/tt/bin/ttdbserverd/db_server_svc.C
Normal file
File diff suppressed because it is too large
Load Diff
512
cde/lib/tt/bin/ttdbserverd/dm_access_cache.C
Normal file
512
cde/lib/tt/bin/ttdbserverd/dm_access_cache.C
Normal file
@@ -0,0 +1,512 @@
|
||||
//%% (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: dm_access_cache.C /main/3 1995/10/20 16:40:39 rswiston $
|
||||
/*
|
||||
* Tool Talk Database Manager - dm_access_cache.h
|
||||
*
|
||||
* Copyright (c) 1989 Sun Microsystems, Inc.
|
||||
*
|
||||
* This file contains class implementation for the oid access info cache.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_access_cache.h"
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include <isam.h>
|
||||
|
||||
implement_ptr_to(_Tt_oid_access)
|
||||
implement_ptr_to(_Tt_oid_access_elem)
|
||||
implement_ptr_to(_Tt_oid_access_queue)
|
||||
implement_ptr_to(_Tt_link_access)
|
||||
implement_ptr_to(_Tt_link_access_elem)
|
||||
implement_ptr_to(_Tt_link_access_queue)
|
||||
|
||||
static char _tt_access_record[ISMAXRECLEN];
|
||||
|
||||
/*
|
||||
* class _Tt_oid_access
|
||||
*/
|
||||
|
||||
_Tt_oid_access::_Tt_oid_access(char *ku)
|
||||
{
|
||||
memcpy(_key, ku, OID_KEY_LENGTH);
|
||||
memcpy((char *)&_user, ku + OID_KEY_LENGTH, sizeof(uid_t));
|
||||
memcpy((char *)&_group, ku + OID_KEY_LENGTH + sizeof(uid_t),
|
||||
sizeof(gid_t));
|
||||
memcpy((char *)&_mode,
|
||||
ku + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
|
||||
sizeof(mode_t));
|
||||
}
|
||||
|
||||
_Tt_oid_access::_Tt_oid_access(const char *key, uid_t user, gid_t group,
|
||||
mode_t mode)
|
||||
{
|
||||
memcpy(_key, key, OID_KEY_LENGTH);
|
||||
_user = user;
|
||||
_group = group;
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
_Tt_oid_access::~_Tt_oid_access()
|
||||
{
|
||||
}
|
||||
|
||||
char *
|
||||
_Tt_oid_access::rec()
|
||||
{
|
||||
memcpy(_tt_access_record, _key, OID_KEY_LENGTH);
|
||||
memcpy(_tt_access_record + OID_KEY_LENGTH, (char *)&_user,
|
||||
sizeof(uid_t));
|
||||
memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t),
|
||||
(char *)&_group, sizeof(gid_t));
|
||||
memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
|
||||
(char *)&_mode, sizeof(mode_t));
|
||||
return _tt_access_record;
|
||||
}
|
||||
|
||||
void
|
||||
_Tt_oid_access::print(FILE *fs) const
|
||||
{
|
||||
fprintf(fs, "oid-access entry: ");
|
||||
fprintf(fs, "key - <%d, %d, %d, %d>, user = %d\n",
|
||||
*((short *) ((char *)_key)),
|
||||
*((int *) ((char *)_key + 4)), *((int *) ((char *)_key + 8)),
|
||||
*((int *) ((char *)_key + 12)), _user);
|
||||
}
|
||||
|
||||
/*
|
||||
* class _Tt_oid_access_elem
|
||||
*/
|
||||
|
||||
_Tt_oid_access_elem::_Tt_oid_access_elem(_Tt_oid_access_ptr oa,
|
||||
_Tt_oid_access_elem_ptr next)
|
||||
{
|
||||
_oa = oa;
|
||||
_next = next;
|
||||
}
|
||||
|
||||
void
|
||||
_Tt_oid_access_elem::print(FILE *fs) const
|
||||
{
|
||||
_oa->print(fs);
|
||||
}
|
||||
|
||||
/*
|
||||
* class _Tt_oid_access_queue
|
||||
*/
|
||||
|
||||
_Tt_oid_access_queue::_Tt_oid_access_queue()
|
||||
{
|
||||
_head = _tail = 0;
|
||||
_len = 0;
|
||||
for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
|
||||
_table[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_Tt_oid_access_queue::~_Tt_oid_access_queue()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
_Tt_oid_access_queue::enqueue(_Tt_oid_access_ptr oa)
|
||||
{
|
||||
if (_len == DM_MAX_ACCESS_ELEMS) {
|
||||
dequeue();
|
||||
}
|
||||
/* put the new element on the LRU list */
|
||||
_Tt_oid_access_elem_ptr oae = new _Tt_oid_access_elem(oa, _head);
|
||||
if (_head.is_null()) {
|
||||
_tail = oae;
|
||||
}
|
||||
_head = oae;
|
||||
/* put the new element in the lookup table */
|
||||
int bucket = hash(oa->key());
|
||||
_table[bucket] = new _Tt_oid_access_elem(oa, _table[bucket]);
|
||||
_len++;
|
||||
}
|
||||
|
||||
_Tt_oid_access_ptr
|
||||
_Tt_oid_access_queue::lookup(const char *key)
|
||||
{
|
||||
if (!key) { /* erroneous condition, read by record number needs key */
|
||||
return 0;
|
||||
}
|
||||
int bucket_no = hash(key);
|
||||
_Tt_oid_access_elem_ptr e = _table[bucket_no];
|
||||
while (!e.is_null()) {
|
||||
_Tt_oid_access_ptr oa = e->oa();
|
||||
if (memcmp(oa->key(), key, OID_KEY_LENGTH) == 0) {
|
||||
return oa;
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* remove - remove the oid access element from both the LRU list and the lookup
|
||||
* table. Does not delete the element.
|
||||
*/
|
||||
|
||||
void
|
||||
_Tt_oid_access_queue::remove(_Tt_oid_access_ptr oa)
|
||||
{
|
||||
/* remove from the LRU list */
|
||||
_Tt_oid_access_elem_ptr prev = 0;
|
||||
_Tt_oid_access_elem_ptr cur = _head;
|
||||
while (!cur.is_null()) {
|
||||
if (cur->oa().is_eq(oa)) {
|
||||
if (prev.is_null()) {
|
||||
_head = _head->next();
|
||||
} else {
|
||||
prev->set_next(cur->next());
|
||||
}
|
||||
if (cur.is_eq(_tail)) {
|
||||
_tail = prev;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
prev = cur;
|
||||
cur = cur->next();
|
||||
}
|
||||
}
|
||||
/* remove from the lookup table */
|
||||
int bucket = hash(oa->key());
|
||||
prev = 0;
|
||||
cur = _table[bucket];
|
||||
while (!cur.is_null()) {
|
||||
if (cur->oa().is_eq(oa)) {
|
||||
if (prev.is_null()) {
|
||||
_table[bucket] = _table[bucket]->next();
|
||||
} else {
|
||||
prev->set_next(cur->next());
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
prev = cur;
|
||||
cur = cur->next();
|
||||
}
|
||||
}
|
||||
--_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* promote - promote the oid access element to the front of the LRU list.
|
||||
*/
|
||||
|
||||
void
|
||||
_Tt_oid_access_queue::promote(_Tt_oid_access_ptr oa)
|
||||
{
|
||||
if (_head->oa().is_eq(oa)) {
|
||||
return;
|
||||
}
|
||||
/* remove from the LRU list */
|
||||
_Tt_oid_access_elem_ptr prev = _head;
|
||||
_Tt_oid_access_elem_ptr cur = prev->next();
|
||||
while (!cur.is_null()) {
|
||||
if (cur->oa().is_eq(oa)) {
|
||||
prev->set_next(cur->next());
|
||||
if (cur.is_eq(_tail)) {
|
||||
_tail = prev;
|
||||
}
|
||||
cur->set_next(_head);
|
||||
_head = cur;
|
||||
break;
|
||||
} else {
|
||||
prev = cur;
|
||||
cur = cur->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the LRU element from the LRU list and lookup table and deletes it.
|
||||
*/
|
||||
|
||||
void
|
||||
_Tt_oid_access_queue::dequeue()
|
||||
{
|
||||
if (!_tail.is_null()) {
|
||||
remove(_tail->oa());
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_Tt_oid_access_queue::hash(const char *key)
|
||||
{
|
||||
int hash_value = 0;
|
||||
for (int i = 0; i < OID_KEY_LENGTH; i++) {
|
||||
hash_value += key[i] & 0177; /* ignore sign */
|
||||
}
|
||||
hash_value = abs(hash_value);
|
||||
return (hash_value % DM_OID_ACCESS_BUCKETS);
|
||||
}
|
||||
|
||||
void
|
||||
_Tt_oid_access_queue::print(FILE *fs) const
|
||||
{
|
||||
fprintf(fs, "\nOID-ACCESS QUEUE list (len = %d):\n", _len);
|
||||
_Tt_oid_access_elem_ptr e = _head;
|
||||
while (!e.is_null()) {
|
||||
e->print(fs);
|
||||
e = e->next();
|
||||
}
|
||||
fprintf(fs, "OID-ACCESS QUEUE table:\n");
|
||||
for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
|
||||
e = _table[i];
|
||||
if (!e.is_null()) {
|
||||
fprintf(fs, "bucket %d:\n", i);
|
||||
while (!e.is_null()) {
|
||||
e->print(fs);
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(fs, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* class _Tt_link_access
|
||||
*/
|
||||
|
||||
_Tt_link_access::_Tt_link_access(char *kp)
|
||||
{
|
||||
memcpy(_key, kp, OID_KEY_LENGTH);
|
||||
memcpy((char *)&_user, kp + OID_KEY_LENGTH, sizeof(uid_t));
|
||||
memcpy((char *)&_group, kp + OID_KEY_LENGTH + sizeof(uid_t),
|
||||
sizeof(gid_t));
|
||||
memcpy((char *)&_mode,
|
||||
kp + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
|
||||
sizeof(mode_t));
|
||||
}
|
||||
|
||||
_Tt_link_access::_Tt_link_access(const char *key, uid_t user, gid_t group,
|
||||
mode_t mode)
|
||||
{
|
||||
memcpy(_key, key, OID_KEY_LENGTH);
|
||||
_user = user;
|
||||
_group = group;
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
_Tt_link_access::~_Tt_link_access()
|
||||
{
|
||||
}
|
||||
|
||||
char *
|
||||
_Tt_link_access::rec()
|
||||
{
|
||||
memcpy(_tt_access_record, _key, OID_KEY_LENGTH);
|
||||
memcpy(_tt_access_record + OID_KEY_LENGTH, (char *)&_user,
|
||||
sizeof(uid_t));
|
||||
memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t),
|
||||
(char *)&_group, sizeof(gid_t));
|
||||
memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
|
||||
(char *)&_mode, sizeof(mode_t));
|
||||
return _tt_access_record;
|
||||
}
|
||||
|
||||
void
|
||||
_Tt_link_access::print(FILE *fs) const
|
||||
{
|
||||
fprintf(fs, "link-access entry: ");
|
||||
fprintf(fs, "key - <%d, %d, %d, %d>, user = %d\n",
|
||||
*((short *) ((char *)_key)),
|
||||
*((int *) ((char *)_key + 4)), *((int *) ((char *)_key + 8)),
|
||||
*((int *) ((char *)_key + 12)), _user);
|
||||
}
|
||||
|
||||
/*
|
||||
* class _Tt_link_access_elem
|
||||
*/
|
||||
|
||||
_Tt_link_access_elem::_Tt_link_access_elem(_Tt_link_access_ptr oa,
|
||||
_Tt_link_access_elem_ptr next)
|
||||
{
|
||||
_oa = oa;
|
||||
_next = next;
|
||||
}
|
||||
|
||||
void
|
||||
_Tt_link_access_elem::print(FILE *fs) const
|
||||
{
|
||||
_oa->print(fs);
|
||||
}
|
||||
|
||||
/*
|
||||
* class _Tt_link_access_queue
|
||||
*/
|
||||
|
||||
_Tt_link_access_queue::_Tt_link_access_queue()
|
||||
{
|
||||
_head = _tail = 0;
|
||||
_len = 0;
|
||||
for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
|
||||
_table[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_Tt_link_access_queue::~_Tt_link_access_queue()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
_Tt_link_access_queue::enqueue(_Tt_link_access_ptr oa)
|
||||
{
|
||||
if (_len == DM_MAX_ACCESS_ELEMS) {
|
||||
dequeue();
|
||||
}
|
||||
/* put the new element on the LRU list */
|
||||
_Tt_link_access_elem_ptr oae = new _Tt_link_access_elem(oa, _head);
|
||||
if (_head.is_null()) {
|
||||
_tail = oae;
|
||||
}
|
||||
_head = oae;
|
||||
/* put the new element in the lookup table */
|
||||
int bucket = hash(oa->key());
|
||||
_table[bucket] = new _Tt_link_access_elem(oa, _table[bucket]);
|
||||
_len++;
|
||||
}
|
||||
|
||||
_Tt_link_access_ptr
|
||||
_Tt_link_access_queue::lookup(const char *key)
|
||||
{
|
||||
if (!key) { /* erroneous condition, read by record number needs key */
|
||||
return 0;
|
||||
}
|
||||
_Tt_link_access_elem_ptr e = _table[hash(key)];
|
||||
while (!e.is_null()) {
|
||||
_Tt_link_access_ptr oa = e->oa();
|
||||
if (memcmp(oa->key(), key, OID_KEY_LENGTH) == 0) {
|
||||
return oa;
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* remove - remove the oid access element from both the LRU list and the lookup
|
||||
* table. Does not delete the element.
|
||||
*/
|
||||
|
||||
void
|
||||
_Tt_link_access_queue::remove(_Tt_link_access_ptr oa)
|
||||
{
|
||||
/* remove from the LRU list */
|
||||
_Tt_link_access_elem_ptr prev = 0;
|
||||
_Tt_link_access_elem_ptr cur = _head;
|
||||
while (!cur.is_null()) {
|
||||
if (cur->oa().is_eq(oa)) {
|
||||
if (prev.is_null()) {
|
||||
_head = _head->next();
|
||||
} else {
|
||||
prev->set_next(cur->next());
|
||||
}
|
||||
if (cur.is_eq(_tail)) {
|
||||
_tail = prev;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
prev = cur;
|
||||
cur = cur->next();
|
||||
}
|
||||
}
|
||||
/* remove from the lookup table */
|
||||
int bucket = hash(oa->key());
|
||||
prev = 0;
|
||||
cur = _table[bucket];
|
||||
while (!cur.is_null()) {
|
||||
if (cur->oa().is_eq(oa)) {
|
||||
if (prev.is_null()) {
|
||||
_table[bucket] = _table[bucket]->next();
|
||||
} else {
|
||||
prev->set_next(cur->next());
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
prev = cur;
|
||||
cur = cur->next();
|
||||
}
|
||||
}
|
||||
--_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* promote - promote the oid access element to the front of the LRU list.
|
||||
*/
|
||||
|
||||
void
|
||||
_Tt_link_access_queue::promote(_Tt_link_access_ptr oa)
|
||||
{
|
||||
if (_head->oa().is_eq(oa)) {
|
||||
return;
|
||||
}
|
||||
/* remove from the LRU list */
|
||||
_Tt_link_access_elem_ptr prev = _head;
|
||||
_Tt_link_access_elem_ptr cur = prev->next();
|
||||
while (!cur.is_null()) {
|
||||
if (cur->oa().is_eq(oa)) {
|
||||
prev->set_next(cur->next());
|
||||
if (cur.is_eq(_tail)) {
|
||||
_tail = prev;
|
||||
}
|
||||
cur->set_next(_head);
|
||||
_head = cur;
|
||||
break;
|
||||
} else {
|
||||
prev = cur;
|
||||
cur = cur->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the LRU element from the LRU list and lookup table and deletes it.
|
||||
*/
|
||||
|
||||
void
|
||||
_Tt_link_access_queue::dequeue()
|
||||
{
|
||||
if (!_tail.is_null()) {
|
||||
remove(_tail->oa());
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_Tt_link_access_queue::hash(const char *key)
|
||||
{
|
||||
int hash_value = 0;
|
||||
for (int i = 0; i < OID_KEY_LENGTH; i++) {
|
||||
hash_value += key[i] & 0177; /* ignore sign */
|
||||
}
|
||||
hash_value = abs(hash_value);
|
||||
return (hash_value % DM_OID_ACCESS_BUCKETS);
|
||||
}
|
||||
|
||||
void
|
||||
_Tt_link_access_queue::print(FILE *fs) const
|
||||
{
|
||||
fprintf(fs, "\nLINK-ACCESS QUEUE list (len = %d):\n", _len);
|
||||
_Tt_link_access_elem_ptr e = _head;
|
||||
while (!e.is_null()) {
|
||||
e->print(fs);
|
||||
e = e->next();
|
||||
}
|
||||
fprintf(fs, "LINK-ACCESS QUEUE table:\n");
|
||||
for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
|
||||
e = _table[i];
|
||||
if (!e.is_null()) {
|
||||
fprintf(fs, "bucket %d:\n", i);
|
||||
while (!e.is_null()) {
|
||||
e->print(fs);
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(fs, "\n");
|
||||
}
|
||||
191
cde/lib/tt/bin/ttdbserverd/dm_access_cache.h
Normal file
191
cde/lib/tt/bin/ttdbserverd/dm_access_cache.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/*%% (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: dm_access_cache.h /main/3 1995/10/20 16:40:47 rswiston $ */
|
||||
/*
|
||||
* Tool Talk Database Manager - dm_access_cache.h
|
||||
*
|
||||
* Copyright (c) 1989 Sun Microsystems, Inc.
|
||||
*
|
||||
* This file contains class declarations for the oid access info cache.
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(_DM_ACCESS_CACHE_H)
|
||||
#define _DM_ACCESS_CACHE_H
|
||||
|
||||
#include <util/tt_object.h>
|
||||
#include <util/tt_string.h>
|
||||
#include <tt_const.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <limits.h>
|
||||
#if !defined(NGROUPS)
|
||||
#define NGROUPS NGROUPS_MAX
|
||||
#endif
|
||||
|
||||
#define DM_OID_ACCESS_BUCKETS 97
|
||||
#define DM_MAX_ACCESS_ELEMS (5 * DM_OID_ACCESS_BUCKETS)
|
||||
|
||||
/*
|
||||
* OID keys' access info cache
|
||||
*/
|
||||
|
||||
class _Tt_oid_access : public _Tt_object {
|
||||
public:
|
||||
_Tt_oid_access() {}
|
||||
_Tt_oid_access(const char *key, uid_t user, gid_t group, mode_t mode);
|
||||
_Tt_oid_access(char *ku);
|
||||
~_Tt_oid_access();
|
||||
const char *key() const { return _key; }
|
||||
uid_t user() const { return _user; }
|
||||
gid_t group() const { return _group; }
|
||||
mode_t mode() const { return _mode; }
|
||||
void set_user(uid_t user) { _user = user; }
|
||||
void set_group(gid_t group) { _group = group; }
|
||||
void set_mode(mode_t mode) { _mode = mode; }
|
||||
int reclen() const { return OID_KEY_LENGTH +
|
||||
sizeof(uid_t) + sizeof(gid_t) +
|
||||
sizeof(mode_t); }
|
||||
char *rec();
|
||||
void print(FILE *fs = stdout) const;
|
||||
private:
|
||||
char _key[OID_KEY_LENGTH];
|
||||
uid_t _user;
|
||||
gid_t _group;
|
||||
mode_t _mode;
|
||||
};
|
||||
|
||||
declare_ptr_to(_Tt_oid_access)
|
||||
|
||||
class _Tt_oid_access_elem;
|
||||
declare_ptr_to(_Tt_oid_access_elem)
|
||||
|
||||
class _Tt_oid_access_elem : public _Tt_object {
|
||||
public:
|
||||
_Tt_oid_access_elem() {}
|
||||
_Tt_oid_access_elem(_Tt_oid_access_ptr oa, _Tt_oid_access_elem_ptr next);
|
||||
_Tt_oid_access_ptr oa() { return _oa; }
|
||||
_Tt_oid_access_elem_ptr next() { return _next; }
|
||||
void set_next(_Tt_oid_access_elem_ptr next)
|
||||
{ _next = next; }
|
||||
void print(FILE *fs = stdout) const;
|
||||
private:
|
||||
_Tt_oid_access_ptr _oa;
|
||||
_Tt_oid_access_elem_ptr _next;
|
||||
};
|
||||
|
||||
class _Tt_oid_access_queue : public _Tt_object {
|
||||
public:
|
||||
_Tt_oid_access_queue();
|
||||
~_Tt_oid_access_queue();
|
||||
void enqueue(_Tt_oid_access_ptr oa);
|
||||
_Tt_oid_access_ptr lookup(const char *key);
|
||||
void remove(_Tt_oid_access_ptr oa);
|
||||
void promote(_Tt_oid_access_ptr oa);
|
||||
void print(FILE *fs = stdout) const;
|
||||
private:
|
||||
void dequeue();
|
||||
int hash(const char *key);
|
||||
|
||||
_Tt_oid_access_elem_ptr _head;
|
||||
_Tt_oid_access_elem_ptr _tail;
|
||||
int _len;
|
||||
_Tt_oid_access_elem_ptr _table[DM_OID_ACCESS_BUCKETS];
|
||||
};
|
||||
|
||||
declare_ptr_to(_Tt_oid_access_queue)
|
||||
|
||||
|
||||
/*
|
||||
* LINK keys' access info cache
|
||||
*/
|
||||
|
||||
class _Tt_link_access : public _Tt_object {
|
||||
public:
|
||||
_Tt_link_access() {}
|
||||
_Tt_link_access(const char *key, uid_t user, gid_t group, mode_t mode);
|
||||
_Tt_link_access(char *ku);
|
||||
~_Tt_link_access();
|
||||
const char *key() const { return _key; }
|
||||
uid_t user() const { return _user; }
|
||||
gid_t group() const { return _group; }
|
||||
mode_t mode() const { return _mode; }
|
||||
void set_user(uid_t user) { _user = user; }
|
||||
void set_group(gid_t group) { _group = group; }
|
||||
void set_mode(mode_t mode) { _mode = mode; }
|
||||
int reclen() const { return OID_KEY_LENGTH +
|
||||
sizeof(uid_t) + sizeof(gid_t) +
|
||||
sizeof(mode_t); }
|
||||
char *rec();
|
||||
void print(FILE *fs = stdout) const;
|
||||
private:
|
||||
char _key[OID_KEY_LENGTH];
|
||||
uid_t _user;
|
||||
gid_t _group;
|
||||
mode_t _mode;
|
||||
};
|
||||
|
||||
declare_ptr_to(_Tt_link_access)
|
||||
|
||||
class _Tt_link_access_elem;
|
||||
declare_ptr_to(_Tt_link_access_elem)
|
||||
|
||||
class _Tt_link_access_elem : public _Tt_object {
|
||||
public:
|
||||
_Tt_link_access_elem() {}
|
||||
_Tt_link_access_elem(_Tt_link_access_ptr oa, _Tt_link_access_elem_ptr next);
|
||||
_Tt_link_access_ptr oa() { return _oa; }
|
||||
_Tt_link_access_elem_ptr next() { return _next; }
|
||||
void set_next(_Tt_link_access_elem_ptr next)
|
||||
{ _next = next; }
|
||||
void print(FILE *fs = stdout) const;
|
||||
private:
|
||||
_Tt_link_access_ptr _oa;
|
||||
_Tt_link_access_elem_ptr _next;
|
||||
};
|
||||
|
||||
class _Tt_link_access_queue : public _Tt_object {
|
||||
public:
|
||||
_Tt_link_access_queue();
|
||||
~_Tt_link_access_queue();
|
||||
void enqueue(_Tt_link_access_ptr oa);
|
||||
_Tt_link_access_ptr lookup(const char *key);
|
||||
void remove(_Tt_link_access_ptr oa);
|
||||
void promote(_Tt_link_access_ptr oa);
|
||||
void print(FILE *fs = stdout) const;
|
||||
private:
|
||||
void dequeue();
|
||||
int hash(const char *key);
|
||||
|
||||
_Tt_link_access_elem_ptr _head;
|
||||
_Tt_link_access_elem_ptr _tail;
|
||||
int _len;
|
||||
_Tt_link_access_elem_ptr _table[DM_OID_ACCESS_BUCKETS];
|
||||
};
|
||||
|
||||
declare_ptr_to(_Tt_link_access_queue)
|
||||
|
||||
// Here follow a bunch of common declarations for dbserver components.
|
||||
// They really should have their own file. (dbserver_commmon.h?)
|
||||
// They got stuck in dm_access_cache since they have do do with
|
||||
// internal dbserver caching (but for fd's.)
|
||||
#define _TT_MAX_ISFD 128
|
||||
|
||||
/* structure containing info open ISAM files: full path and opener's uids */
|
||||
struct _Tt_db_info {
|
||||
_Tt_string db_path;
|
||||
uid_t opener_uid;
|
||||
int open_mode; // mode file was opened with
|
||||
int client_has_open; // 1 iff we think somebodys using it
|
||||
int server_has_open; // 1 iff we opened it
|
||||
int reftime; // "time" of last reference for LRU
|
||||
};
|
||||
|
||||
int cached_isopen(const char *filepath, int mode);
|
||||
int cached_isclose(int isfd);
|
||||
void isgarbage_collect();
|
||||
|
||||
|
||||
#endif /* _DM_ACCESS_CACHE_H */
|
||||
2267
cde/lib/tt/bin/ttdbserverd/dm_server.C
Normal file
2267
cde/lib/tt/bin/ttdbserverd/dm_server.C
Normal file
File diff suppressed because it is too large
Load Diff
79
cde/lib/tt/bin/ttdbserverd/tt_db_message_info.h
Normal file
79
cde/lib/tt/bin/ttdbserverd/tt_db_message_info.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*%% (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_message_info.h /main/3 1995/10/20 16:41:14 rswiston $ */
|
||||
/* @(#)tt_db_message_info.h 1.8 93/09/07
|
||||
* tt_db_message_info.h - Used to create a database record that stores
|
||||
* queued message info in a way that is reasonable
|
||||
* for the new DB server and compatible with the
|
||||
* old DB server.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TT_DB_MESSAGE_INFO_H
|
||||
#define _TT_DB_MESSAGE_INFO_H
|
||||
|
||||
#include "util/tt_object.h"
|
||||
#include "util/tt_string.h"
|
||||
#include "util/tt_xdr_version.h"
|
||||
|
||||
class _Tt_db_message_info : public _Tt_object {
|
||||
public:
|
||||
_Tt_db_message_info () {}
|
||||
~_Tt_db_message_info () {}
|
||||
|
||||
int messageID;
|
||||
int numParts;
|
||||
int messageSize;
|
||||
_Tt_string_list_ptr ptypes;
|
||||
|
||||
bool_t xdr (XDR *xdrs)
|
||||
{
|
||||
int dummy_int = 0;
|
||||
_Tt_string dummy_string = "";
|
||||
bool_t results;
|
||||
_Tt_xdr_version xvers(1);
|
||||
|
||||
results = xdr_int(xdrs, &dummy_int);
|
||||
|
||||
if (results) {
|
||||
results = xdr_int(xdrs, &messageID);
|
||||
}
|
||||
|
||||
if (results) {
|
||||
results = xdr_int(xdrs, &numParts);
|
||||
}
|
||||
|
||||
if (results) {
|
||||
results = xdr_int(xdrs, &messageSize);
|
||||
}
|
||||
|
||||
if (results) {
|
||||
int count = (ptypes.is_null() ? 0 : ptypes->count());
|
||||
results = xdr_int(xdrs, &count);
|
||||
|
||||
for (int i=0; results && (i < count); i++) {
|
||||
results = xdr_int(xdrs, &dummy_int);
|
||||
}
|
||||
}
|
||||
|
||||
if (results) {
|
||||
results = ptypes.xdr(xdrs);
|
||||
}
|
||||
|
||||
if (results) {
|
||||
results = xdr_int(xdrs, &dummy_int);
|
||||
}
|
||||
|
||||
if (results) {
|
||||
results = dummy_string.xdr(xdrs);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _TT_DB_MESSAGE_INFO_H */
|
||||
14
cde/lib/tt/bin/ttdbserverd/tt_db_message_info_utils.C
Normal file
14
cde/lib/tt/bin/ttdbserverd/tt_db_message_info_utils.C
Normal file
@@ -0,0 +1,14 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: tt_db_message_info_utils.C /main/3 1995/10/20 16:41:22 rswiston $
|
||||
/*
|
||||
* tt_db_message_info.cc - Defines the _Tt_db_message_info utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "tt_db_message_info_utils.h"
|
||||
|
||||
implement_ptr_to(_Tt_db_message_info)
|
||||
19
cde/lib/tt/bin/ttdbserverd/tt_db_message_info_utils.h
Normal file
19
cde/lib/tt/bin/ttdbserverd/tt_db_message_info_utils.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: tt_db_message_info_utils.h /main/3 1995/10/20 16:41:33 rswiston $ */
|
||||
/*
|
||||
* tt_db_message_info_utils.h - Declare the _Tt_db_message_info utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_DB_MESSAGE_INFO_UTILS_H
|
||||
#define _TT_DB_MESSAGE_INFO_UTILS_H
|
||||
|
||||
#include "tt_db_message_info.h"
|
||||
|
||||
declare_ptr_to(_Tt_db_message_info)
|
||||
|
||||
#endif // _TT_DB_MESSAGE_INFO_UTILS_H
|
||||
92
cde/lib/tt/bin/ttdbserverd/tt_db_msg_q_lock.C
Normal file
92
cde/lib/tt/bin/ttdbserverd/tt_db_msg_q_lock.C
Normal file
@@ -0,0 +1,92 @@
|
||||
//%% (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_msg_q_lock.C /main/3 1995/10/20 16:41:41 rswiston $
|
||||
/*
|
||||
* tt_db_msg_q_lock.cc - Defines a class for managing the locking and unlocking
|
||||
* the message queue for a particular file.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "tt_db_msg_q_lock.h"
|
||||
#include "tt_db_msg_q_lock_entry_utils.h"
|
||||
|
||||
_Tt_db_msg_q_lock_entry_list_ptr*
|
||||
_Tt_db_msg_q_lock::locks = (_Tt_db_msg_q_lock_entry_list_ptr *)NULL;
|
||||
|
||||
_Tt_db_msg_q_lock::_Tt_db_msg_q_lock ()
|
||||
{
|
||||
if (!locks) {
|
||||
locks = new _Tt_db_msg_q_lock_entry_list_ptr;
|
||||
*locks = new _Tt_db_msg_q_lock_entry_list;
|
||||
}
|
||||
}
|
||||
|
||||
_Tt_db_msg_q_lock::~_Tt_db_msg_q_lock ()
|
||||
{
|
||||
}
|
||||
|
||||
bool_t _Tt_db_msg_q_lock::testAndSetLock (const _Tt_string &client_id,
|
||||
const _Tt_string &file_key)
|
||||
{
|
||||
bool_t found = FALSE;
|
||||
bool_t results = FALSE;
|
||||
|
||||
_Tt_db_msg_q_lock_entry_list_cursor locks_cursor(*locks);
|
||||
while (locks_cursor.next()) {
|
||||
if ((locks_cursor->clientID == client_id) &&
|
||||
(locks_cursor->fileKey == file_key)) {
|
||||
found = TRUE;
|
||||
results = TRUE;
|
||||
break;
|
||||
}
|
||||
else if (locks_cursor->fileKey == file_key) {
|
||||
found = TRUE;
|
||||
results = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
_Tt_db_msg_q_lock_entry_ptr lock = new _Tt_db_msg_q_lock_entry;
|
||||
lock->clientID = (char *)client_id;
|
||||
lock->fileKey = (char *)file_key;
|
||||
(*locks)->append(lock);
|
||||
|
||||
results = TRUE;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
void _Tt_db_msg_q_lock::unsetLock (const _Tt_string &client_id,
|
||||
const _Tt_string &file_key)
|
||||
{
|
||||
_Tt_db_msg_q_lock_entry_list_cursor locks_cursor(*locks);
|
||||
while (locks_cursor.next()) {
|
||||
if ((locks_cursor->clientID == client_id) &&
|
||||
(locks_cursor->fileKey == file_key)) {
|
||||
locks_cursor.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool_t _Tt_db_msg_q_lock::checkLock (const _Tt_string &client_id,
|
||||
const _Tt_string &file_key)
|
||||
{
|
||||
bool_t found = FALSE;
|
||||
|
||||
_Tt_db_msg_q_lock_entry_list_cursor locks_cursor(*locks);
|
||||
while (locks_cursor.next()) {
|
||||
if ((locks_cursor->clientID == client_id) &&
|
||||
(locks_cursor->fileKey == file_key)) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
41
cde/lib/tt/bin/ttdbserverd/tt_db_msg_q_lock.h
Normal file
41
cde/lib/tt/bin/ttdbserverd/tt_db_msg_q_lock.h
Normal 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. */
|
||||
/*%% $XConsortium: tt_db_msg_q_lock.h /main/3 1995/10/20 16:41:50 rswiston $ */
|
||||
/*
|
||||
* tt_db_msg_q_lock.h - Defines a class for managing the locking and unlocking
|
||||
* the message queue for a particular file.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_DB_MSG_Q_LOCK_H
|
||||
#define _TT_DB_MSG_Q_LOCK_H
|
||||
|
||||
#include "util/tt_new.h"
|
||||
#include "util/tt_string.h"
|
||||
#include "tt_db_msg_q_lock_entry_utils.h"
|
||||
|
||||
class _Tt_db_msg_q_lock : public _Tt_allocated {
|
||||
public:
|
||||
_Tt_db_msg_q_lock ();
|
||||
~_Tt_db_msg_q_lock ();
|
||||
|
||||
bool_t testAndSetLock (const _Tt_string &client_id,
|
||||
const _Tt_string &file_key);
|
||||
void unsetLock (const _Tt_string &client_id,
|
||||
const _Tt_string &file_key);
|
||||
bool_t checkLock (const _Tt_string &client_id,
|
||||
const _Tt_string &file_key);
|
||||
|
||||
void unsetAllLocks ()
|
||||
{
|
||||
(*locks)->flush();
|
||||
}
|
||||
|
||||
private:
|
||||
static _Tt_db_msg_q_lock_entry_list_ptr *locks;
|
||||
};
|
||||
|
||||
#endif /* _TT_DB_MSG_Q_LOCK_H */
|
||||
28
cde/lib/tt/bin/ttdbserverd/tt_db_msg_q_lock_entry.h
Normal file
28
cde/lib/tt/bin/ttdbserverd/tt_db_msg_q_lock_entry.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: tt_db_msg_q_lock_entry.h /main/3 1995/10/20 16:41:58 rswiston $ */
|
||||
/*
|
||||
* tt_db_msg_q_lock_entry.h - Defines a class for holding lock information in the
|
||||
* locks list in the tt_db_msg_q_lock class.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_DB_MSG_Q_LOCK_ENTRY_H
|
||||
#define _TT_DB_MSG_Q_LOCK_ENTRY_H
|
||||
|
||||
#include "util/tt_object.h"
|
||||
#include "util/tt_string.h"
|
||||
|
||||
class _Tt_db_msg_q_lock_entry : public _Tt_object {
|
||||
public:
|
||||
_Tt_db_msg_q_lock_entry () {}
|
||||
~_Tt_db_msg_q_lock_entry () {}
|
||||
|
||||
_Tt_string clientID;
|
||||
_Tt_string fileKey;
|
||||
};
|
||||
|
||||
#endif /* _TT_DB_MSG_Q_LOCK_ENTRY_H */
|
||||
15
cde/lib/tt/bin/ttdbserverd/tt_db_msg_q_lock_entry_utils.C
Normal file
15
cde/lib/tt/bin/ttdbserverd/tt_db_msg_q_lock_entry_utils.C
Normal file
@@ -0,0 +1,15 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: tt_db_msg_q_lock_entry_utils.C /main/3 1995/10/20 16:42:08 rswiston $
|
||||
/*
|
||||
* tt_db_msg_q_lock_entry_utils.cc - Defines the _Tt_db_msg_q_lock_entry
|
||||
* utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "tt_db_msg_q_lock_entry_utils.h"
|
||||
|
||||
implement_list_of(_Tt_db_msg_q_lock_entry)
|
||||
21
cde/lib/tt/bin/ttdbserverd/tt_db_msg_q_lock_entry_utils.h
Normal file
21
cde/lib/tt/bin/ttdbserverd/tt_db_msg_q_lock_entry_utils.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: tt_db_msg_q_lock_entry_utils.h /main/3 1995/10/20 16:42:16 rswiston $ */
|
||||
/*
|
||||
* tt_db_msg_q_lock_entry_utils.h - Declares the _Tt_db_msg_q_lock_entry class
|
||||
* utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_DB_MSG_Q_LOCK_ENTRY_UTILS_H
|
||||
#define _TT_DB_MSG_Q_LOCK_ENTRY_UTILS_H
|
||||
|
||||
#include "util/tt_list.h"
|
||||
#include "tt_db_msg_q_lock_entry.h"
|
||||
|
||||
declare_list_of(_Tt_db_msg_q_lock_entry)
|
||||
|
||||
#endif // _TT_DB_MSG_Q_LOCK_ENTRY_UTILS_H
|
||||
267
cde/lib/tt/bin/ttdbserverd/tt_db_partition_global_map_ref.C
Normal file
267
cde/lib/tt/bin/ttdbserverd/tt_db_partition_global_map_ref.C
Normal file
@@ -0,0 +1,267 @@
|
||||
//%% (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_partition_global_map_ref.C /main/3 1995/10/20 16:42:23 rswiston $
|
||||
/*
|
||||
* tt_db_partition_global_map_ref.cc - Define the TT DB server partition
|
||||
* global map ref class.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include "util/tt_port.h"
|
||||
#include "util/tt_gettext.h"
|
||||
#include "tt_isam_file_utils.h"
|
||||
#include "tt_isam_record_utils.h"
|
||||
#include "tt_db_partition_redirection_map.h"
|
||||
#include "tt_db_partition_global_map_ref.h"
|
||||
#include "tt_db_server_consts.h"
|
||||
|
||||
extern _Tt_db_partition_redirection_map *db_pr_map;
|
||||
extern FILE *errstr;
|
||||
|
||||
_Tt_db_server_db_table_ptr*
|
||||
_Tt_db_partition_global_map_ref::dbPartitionMap = (_Tt_db_server_db_table_ptr *)
|
||||
NULL;
|
||||
|
||||
_Tt_db_partition_global_map_ref::_Tt_db_partition_global_map_ref ()
|
||||
{
|
||||
if (!dbPartitionMap) {
|
||||
dbPartitionMap = new _Tt_db_server_db_table_ptr;
|
||||
*dbPartitionMap = new _Tt_db_server_db_table ((_Tt_object_table_keyfn)
|
||||
&dbPartitionMapKey);
|
||||
}
|
||||
}
|
||||
|
||||
_Tt_db_partition_global_map_ref::~_Tt_db_partition_global_map_ref ()
|
||||
{
|
||||
// The static table is freed up when the application dies.
|
||||
}
|
||||
|
||||
void _Tt_db_partition_global_map_ref::addDB (_Tt_db_server_db_ptr &db)
|
||||
{
|
||||
(*dbPartitionMap)->insert(db);
|
||||
}
|
||||
|
||||
void _Tt_db_partition_global_map_ref::removeDB (const _Tt_string &partition)
|
||||
{
|
||||
(*dbPartitionMap)->remove(partition);
|
||||
}
|
||||
|
||||
_Tt_db_server_db_ptr
|
||||
_Tt_db_partition_global_map_ref::getDB (const _Tt_string &partition)
|
||||
{
|
||||
_Tt_string real_partition = db_pr_map->findEntry(partition);
|
||||
if (real_partition.is_null() || !real_partition.len()) {
|
||||
real_partition = partition;
|
||||
}
|
||||
|
||||
_Tt_db_server_db_ptr db_ptr = (*dbPartitionMap)->lookup(real_partition);
|
||||
if (db_ptr.is_null()) {
|
||||
if (!checkForOldDB(real_partition)) {
|
||||
db_ptr = new _Tt_db_server_db(real_partition);
|
||||
|
||||
_Tt_db_results results = db_ptr->getDBResults();
|
||||
if (results != TT_DB_OK) {
|
||||
_tt_syslog(errstr, LOG_ERR,
|
||||
"_Tt_db_server_db(\"%s\"): %d (%s)",
|
||||
(char *)real_partition, results,
|
||||
(char *)db_ptr->getLastFileAccessed());
|
||||
db_ptr = (_Tt_db_server_db *)NULL;
|
||||
}
|
||||
else {
|
||||
addDB(db_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return db_ptr;
|
||||
}
|
||||
|
||||
_Tt_string
|
||||
_Tt_db_partition_global_map_ref::dbPartitionMapKey (_Tt_object_ptr &db)
|
||||
{
|
||||
return (((_Tt_db_server_db *)db.c_pointer())->getPartition());
|
||||
}
|
||||
|
||||
bool_t
|
||||
_Tt_db_partition_global_map_ref::checkForOldDB(const _Tt_string &partition)
|
||||
{
|
||||
if (checkForOldDBTable(partition, "docoid_path", TT_DB_FILE_TABLE_FILE)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (checkForOldDBTable(partition,
|
||||
"oid_container",
|
||||
TT_DB_FILE_OBJECT_MAP_FILE)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (checkForOldDBTable(partition, "oid_prop", TT_DB_PROPERTY_TABLE_FILE)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (checkForOldDBTable(partition, "oid_access", TT_DB_ACCESS_TABLE_FILE)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool_t _Tt_db_partition_global_map_ref
|
||||
::checkForOldDBTable (const _Tt_string &partition,
|
||||
const _Tt_string &old_file,
|
||||
const _Tt_string &new_file)
|
||||
{
|
||||
static bool_t old_db_diagnostic = FALSE;
|
||||
|
||||
_Tt_string base_dir = (char *)partition;
|
||||
if (base_dir[base_dir.len()-1] != '/') {
|
||||
base_dir = base_dir.cat("/");
|
||||
}
|
||||
base_dir = base_dir.cat("TT_DB/");
|
||||
|
||||
_Tt_string old_db_file(base_dir);
|
||||
old_db_file = old_db_file.cat(old_file);
|
||||
|
||||
_Tt_string new_db_file(base_dir);
|
||||
new_db_file = new_db_file.cat(new_file);
|
||||
|
||||
_Tt_string old_db_index(old_db_file);
|
||||
old_db_index = old_db_index.cat(".ind");
|
||||
|
||||
_Tt_string new_db_index(new_db_file);
|
||||
new_db_index = new_db_index.cat(".ind");
|
||||
|
||||
struct stat stat_buf;
|
||||
int temp_errno = 0;
|
||||
|
||||
// If there is no new DB and there is an old DB...
|
||||
if (stat((char *)new_db_index, &stat_buf) &&
|
||||
((temp_errno = errno) == ENOENT) &&
|
||||
!stat((char *)old_db_index, &stat_buf)) {
|
||||
if (new_file == TT_DB_ACCESS_TABLE_FILE) {
|
||||
_Tt_isam_file_ptr old_db_table =
|
||||
new _Tt_isam_file(old_db_file, ISFIXLEN+ISINOUT+ISEXCLLOCK);
|
||||
_Tt_isam_file_ptr access_table;
|
||||
|
||||
int results = old_db_table->getErrorStatus();
|
||||
|
||||
if (!results) {
|
||||
_Tt_isam_key_descriptor_ptr access_key = new _Tt_isam_key_descriptor;
|
||||
access_key->addKeyPart(0, TT_DB_KEY_LENGTH, BINTYPE);
|
||||
|
||||
access_table =
|
||||
new _Tt_isam_file(new_db_file,
|
||||
TT_DB_KEY_LENGTH+3*TT_DB_LONG_SIZE,
|
||||
TT_DB_KEY_LENGTH+3*TT_DB_LONG_SIZE,
|
||||
access_key,
|
||||
ISFIXLEN+ISINOUT+ISEXCLLOCK);
|
||||
results = access_table->getErrorStatus();
|
||||
|
||||
if (!results) {
|
||||
results = access_table->writeMagicString(_Tt_string(TT_DB_VERSION));
|
||||
}
|
||||
}
|
||||
|
||||
if (!results) {
|
||||
_Tt_isam_record_ptr new_record = access_table->getEmptyRecord();
|
||||
_Tt_isam_record_ptr record;
|
||||
|
||||
while (!results) {
|
||||
record = old_db_table->readRecord(ISNEXT);
|
||||
results = old_db_table->getErrorStatus();
|
||||
|
||||
if (!results) {
|
||||
memset((char *)new_record->getRecord(),
|
||||
'\0',
|
||||
new_record->getLength());
|
||||
|
||||
memcpy((char *)new_record->getRecord(),
|
||||
(char *)record->getRecord(),
|
||||
TT_DB_KEY_LENGTH);
|
||||
|
||||
short n_user = *(short *)
|
||||
((char *)record->getRecord()+TT_DB_KEY_LENGTH);
|
||||
long user = (long)ntohs(n_user);
|
||||
u_long nl_user = htonl(user);
|
||||
memcpy((char *)new_record->getRecord()+TT_DB_ACCESS_USER_OFFSET,
|
||||
(char *)&nl_user,
|
||||
TT_DB_LONG_SIZE);
|
||||
|
||||
short n_group = *(short *)
|
||||
((char *)record->getRecord()+
|
||||
TT_DB_KEY_LENGTH+TT_DB_SHORT_SIZE);
|
||||
long group = (long)ntohs(n_group);
|
||||
u_long nl_group = htonl(group);
|
||||
memcpy((char *)new_record->getRecord()+TT_DB_ACCESS_GROUP_OFFSET,
|
||||
(char *)&nl_group,
|
||||
TT_DB_LONG_SIZE);
|
||||
|
||||
short n_mode = *(short *)
|
||||
((char *)record->getRecord()+
|
||||
TT_DB_KEY_LENGTH+2*TT_DB_SHORT_SIZE);
|
||||
long mode = (long)ntohs(n_mode);
|
||||
u_long nl_mode = htonl(mode);
|
||||
memcpy((char *)new_record->getRecord()+TT_DB_ACCESS_MODE_OFFSET,
|
||||
(char *)&nl_mode,
|
||||
TT_DB_LONG_SIZE);
|
||||
|
||||
results = access_table->writeRecord(new_record);
|
||||
}
|
||||
}
|
||||
|
||||
if (results == EENDFILE) {
|
||||
results = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!results) {
|
||||
(void)iserase((char *)old_db_file);
|
||||
}
|
||||
|
||||
if (results) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isrename((char *)old_db_file, (char *)new_db_file)) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
_Tt_isam_file_ptr new_db_table =
|
||||
new _Tt_isam_file(new_db_file, ISFIXLEN+ISINOUT+ISEXCLLOCK);
|
||||
int results = new_db_table->getErrorStatus();
|
||||
|
||||
if (results) {
|
||||
new_db_table = new _Tt_isam_file(new_db_file,
|
||||
ISVARLEN+ISINOUT+ISEXCLLOCK);
|
||||
results = new_db_table->getErrorStatus();
|
||||
}
|
||||
|
||||
if (!results) {
|
||||
(void)new_db_table->writeMagicString(TT_DB_VERSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (temp_errno && (temp_errno != ENOENT)) {
|
||||
return TRUE;
|
||||
}
|
||||
else if (!stat((char *)old_db_index, &stat_buf)) {
|
||||
if (old_db_diagnostic == FALSE) {
|
||||
_tt_syslog(errstr, LOG_ERR,
|
||||
catgets(_ttcatd, 5, 5,
|
||||
"Any data written using an old (<= 1.0.2) "
|
||||
"rpc.ttdbserverd after using a new (>= 1.1) "
|
||||
"rpc.ttdbserverd will be ignored"));
|
||||
old_db_diagnostic = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
44
cde/lib/tt/bin/ttdbserverd/tt_db_partition_global_map_ref.h
Normal file
44
cde/lib/tt/bin/ttdbserverd/tt_db_partition_global_map_ref.h
Normal 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: tt_db_partition_global_map_ref.h /main/3 1995/10/20 16:42:31 rswiston $ */
|
||||
/*
|
||||
* tt_db_partition_global_map_ref.h - Declare the TT DB server partition
|
||||
* global map ref class. This class contains
|
||||
* a global map that provides a partition to
|
||||
* DB server DB mapping. This way only one set
|
||||
* of ISAM file connections is made per partition
|
||||
* on a particular machine.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_DB_PARTITION_GLOBAL_MAP_REF_H
|
||||
#define _TT_DB_PARTITION_GLOBAL_MAP_REF_H
|
||||
|
||||
#include "util/tt_new.h"
|
||||
#include "util/tt_string.h"
|
||||
#include "tt_db_server_db_utils.h"
|
||||
|
||||
class _Tt_db_partition_global_map_ref : public _Tt_allocated {
|
||||
public:
|
||||
_Tt_db_partition_global_map_ref ();
|
||||
~_Tt_db_partition_global_map_ref ();
|
||||
|
||||
void addDB (_Tt_db_server_db_ptr &db);
|
||||
void removeDB (const _Tt_string &partition);
|
||||
_Tt_db_server_db_ptr getDB (const _Tt_string &partition);
|
||||
|
||||
static _Tt_string dbPartitionMapKey (_Tt_object_ptr &db);
|
||||
|
||||
private:
|
||||
static _Tt_db_server_db_table_ptr *dbPartitionMap;
|
||||
|
||||
bool_t checkForOldDB (const _Tt_string&);
|
||||
bool_t checkForOldDBTable (const _Tt_string&,
|
||||
const _Tt_string&,
|
||||
const _Tt_string&);
|
||||
};
|
||||
|
||||
#endif // _TT_DB_PARTITION_GLOBAL_MAP_REF_H
|
||||
51
cde/lib/tt/bin/ttdbserverd/tt_db_partition_redirection_map.C
Normal file
51
cde/lib/tt/bin/ttdbserverd/tt_db_partition_redirection_map.C
Normal 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: tt_db_partition_redirection_map.C /main/3 1995/10/20 16:42:41 rswiston $
|
||||
/*
|
||||
* Tool Talk Utility - tt_partition_redirection_map.cc
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Defines a partition redirection map. A global version
|
||||
* of this object is in declared db_server_svc.cc.
|
||||
*/
|
||||
|
||||
#include "tt_db_partition_redirection_map.h"
|
||||
#include "util/tt_string_map.h"
|
||||
#include "util/tt_map_entry.h"
|
||||
#include "util/tt_path.h"
|
||||
|
||||
const char *pr_map_file = "partition_map";
|
||||
const char *pr_map_env = "_SUN_TT_PARTITION_MAP";
|
||||
const char *pr_cde_map_env = "TT_PARTITION_MAP";
|
||||
|
||||
_Tt_db_partition_redirection_map::
|
||||
_Tt_db_partition_redirection_map ()
|
||||
{
|
||||
map = new _Tt_string_map((_Tt_object_table_keyfn)
|
||||
&_Tt_map_entry::getPathAddress);
|
||||
}
|
||||
|
||||
_Tt_db_partition_redirection_map::
|
||||
~_Tt_db_partition_redirection_map ()
|
||||
{
|
||||
}
|
||||
|
||||
_Tt_string _Tt_db_partition_redirection_map::
|
||||
findEntry(const _Tt_string &address)
|
||||
{
|
||||
return map->findEntry(address);
|
||||
}
|
||||
|
||||
void _Tt_db_partition_redirection_map::refresh ()
|
||||
{
|
||||
// give preference to the cde named setting
|
||||
const char* pr_map_env_to_use = (getenv(pr_cde_map_env) ? pr_cde_map_env : pr_map_env);
|
||||
|
||||
_Tt_string path = _tt_user_path (pr_map_file, pr_map_env_to_use, TRUE);
|
||||
if (path.len()) {
|
||||
map->loadFile(path);
|
||||
}
|
||||
}
|
||||
31
cde/lib/tt/bin/ttdbserverd/tt_db_partition_redirection_map.h
Normal file
31
cde/lib/tt/bin/ttdbserverd/tt_db_partition_redirection_map.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*%% (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_partition_redirection_map.h /main/3 1995/10/20 16:42:49 rswiston $ */
|
||||
/*
|
||||
* Tool Talk Utility - tt_partition_redirection_map.h
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
* Declares a partition redirection map. A global version
|
||||
* of this object is declared in db_server_svc.cc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_PARTITION_REDIRECTION_MAP_H
|
||||
#define _TT_PARTITION_REDIRECTION_MAP_H
|
||||
|
||||
#include "util/tt_new.h"
|
||||
#include "util/tt_string_map_utils.h"
|
||||
|
||||
class _Tt_db_partition_redirection_map : public _Tt_allocated {
|
||||
public:
|
||||
_Tt_db_partition_redirection_map ();
|
||||
~_Tt_db_partition_redirection_map ();
|
||||
void refresh ();
|
||||
_Tt_string findEntry(const _Tt_string &address);
|
||||
private:
|
||||
_Tt_string_map_ptr map;
|
||||
};
|
||||
|
||||
#endif /* _TT_PARTITION_REDIRECTION_MAP_H */
|
||||
1905
cde/lib/tt/bin/ttdbserverd/tt_db_server_db.C
Normal file
1905
cde/lib/tt/bin/ttdbserverd/tt_db_server_db.C
Normal file
File diff suppressed because it is too large
Load Diff
300
cde/lib/tt/bin/ttdbserverd/tt_db_server_db.h
Normal file
300
cde/lib/tt/bin/ttdbserverd/tt_db_server_db.h
Normal file
@@ -0,0 +1,300 @@
|
||||
/*%% (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_db.h /main/3 1995/10/20 16:43:06 rswiston $ */
|
||||
/*
|
||||
* tt_db_server_db.h - Defines the TT DB server database. This class
|
||||
* represents the actual data model currently being
|
||||
* used to store ToolTalk databse information.
|
||||
*
|
||||
* The actual database schema is the following:
|
||||
*
|
||||
* Table Fields Length Description
|
||||
* ----- ------ ------ -----------
|
||||
* File Table Contains the names of all
|
||||
* the that have properties
|
||||
* or objects in the db.
|
||||
*
|
||||
* File Key TT_DB_KEY_LENGTH Unique key that is used
|
||||
* to search (16 bytes) for
|
||||
* a file's properties and
|
||||
* objects in the other
|
||||
* tables.
|
||||
*
|
||||
* File Name Variable up to The name of the file.
|
||||
* MAXPATHLEN (256)
|
||||
*
|
||||
* Table Fields Length Description
|
||||
* ----- ------ ------ -----------
|
||||
* File-object Contains all of the
|
||||
* Map mappings of file keys to
|
||||
* the keys of the objects
|
||||
* in the file.
|
||||
*
|
||||
* Object Key TT_DB_KEY_LENGTH Unique key of an object
|
||||
* in a file.
|
||||
*
|
||||
* File Key TT_DB_KEY_LENGTH Unique key of a file.
|
||||
*
|
||||
* Table Fields Length Description
|
||||
* ----- ------ ------ -----------
|
||||
* Property Contains all of the
|
||||
* Table properties corresponding
|
||||
* to files and objects in
|
||||
* the db.
|
||||
*
|
||||
* Key TT_DB_KEY_LENGTH Unique key of an object
|
||||
* or a file.
|
||||
*
|
||||
* Property Name TT_DB_PROP_NAME_LENGTH The name of a file or
|
||||
* object property.
|
||||
*
|
||||
* Property Variable up to The value of the property.
|
||||
* ISMAXRECLEN.
|
||||
*
|
||||
* Table Fields Length Description
|
||||
* ----- ------ ------ -----------
|
||||
* Access Table Contains the access
|
||||
* privileges of all the
|
||||
* files and objects in
|
||||
* the db.
|
||||
*
|
||||
* Key TT_DB_KEY_LENGTH Unique key of an object
|
||||
* or a file.
|
||||
*
|
||||
* User ID XDR_LONG_SIZE The user ID of the owner
|
||||
* of the object or file.
|
||||
*
|
||||
* Group ID XDR_LONG_SIZE The group ID of the
|
||||
* object or file.
|
||||
*
|
||||
* Mode XDR_LONG_SIZE The access mode of the
|
||||
* object or file.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_DB_SERVER_DB_H
|
||||
#define _TT_DB_SERVER_DB_H
|
||||
|
||||
#include "util/tt_object.h"
|
||||
#include "util/tt_string.h"
|
||||
#include "tt_isam_file_utils.h"
|
||||
#include "db/tt_db_access_utils.h"
|
||||
#include "db/tt_db_key_utils.h"
|
||||
#include "db/tt_db_property_utils.h"
|
||||
#include "db/tt_db_results.h"
|
||||
|
||||
class _Tt_db_server_db : public _Tt_object {
|
||||
public:
|
||||
_Tt_db_server_db ();
|
||||
_Tt_db_server_db (const _Tt_string&);
|
||||
~_Tt_db_server_db ();
|
||||
|
||||
// Returns the partition this DB object is connected to
|
||||
_Tt_string getPartition () const
|
||||
{
|
||||
_Tt_string partition = (char *)dbPartition;
|
||||
return partition;
|
||||
}
|
||||
|
||||
// Creates a file in the TT DB and sets the access permissions of the
|
||||
// file.
|
||||
_Tt_db_results createFile (const _Tt_string &file,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
// Creates an object in the TT DB. If the file is not in the database,
|
||||
// the file will be created using the "file_access" argument to specify
|
||||
// its access permission. If no file is specified, this is a special
|
||||
// object being created just to hold a forward pointer.
|
||||
_Tt_db_results createObject (const _Tt_string &file,
|
||||
const _Tt_string &objid,
|
||||
const _Tt_db_access_ptr &object_access,
|
||||
const _Tt_db_access_ptr &file_access);
|
||||
|
||||
_Tt_db_results removeFile (const _Tt_string &file,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results removeObject (const _Tt_string &objid,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results moveFile (const _Tt_string &file,
|
||||
const _Tt_string &new_file,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results setFileProperty (const _Tt_string &file,
|
||||
const _Tt_db_property_ptr &property,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results setFileProperties (const _Tt_string &file,
|
||||
const _Tt_db_property_list_ptr &properties,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results addFileProperty (const _Tt_string &file,
|
||||
const _Tt_db_property_ptr &property,
|
||||
bool_t unique,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results deleteFileProperty (const _Tt_string &file,
|
||||
const _Tt_db_property_ptr &property,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results deleteFileProperties (const _Tt_string &file,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results getFileProperty (const _Tt_string &file,
|
||||
const _Tt_string &name,
|
||||
const _Tt_db_access_ptr &access,
|
||||
_Tt_db_property_ptr &property);
|
||||
|
||||
_Tt_db_results getFileProperties (const _Tt_string &file,
|
||||
const _Tt_db_access_ptr &access,
|
||||
_Tt_db_property_list_ptr &properties);
|
||||
|
||||
_Tt_db_results getFileObjects (const _Tt_string &file,
|
||||
const _Tt_db_access_ptr &access,
|
||||
_Tt_string_list_ptr &objids);
|
||||
|
||||
_Tt_db_results deleteFileObjects (const _Tt_string &file,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results setFileFile (const _Tt_string &file,
|
||||
const _Tt_string &new_file,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
// If the specified file is a directory, this returns all of the
|
||||
// file names stored in the database that are in the directory.
|
||||
// The file itself is also in the return list.
|
||||
_Tt_db_results getFileChildren (const _Tt_string &file,
|
||||
_Tt_string_list_ptr &children);
|
||||
|
||||
_Tt_db_results setFileAccess (const _Tt_string &file,
|
||||
const _Tt_db_access_ptr &new_access,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results getFileAccess (const _Tt_string &file,
|
||||
const _Tt_db_access_ptr &access,
|
||||
_Tt_db_access_ptr ¤t_access);
|
||||
|
||||
_Tt_db_results setObjectProperty (const _Tt_string &objid,
|
||||
const _Tt_db_property_ptr &property,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results
|
||||
setObjectProperties (const _Tt_string &objid,
|
||||
const _Tt_db_property_list_ptr &properties,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results addObjectProperty (const _Tt_string &objid,
|
||||
const _Tt_db_property_ptr &property,
|
||||
bool_t unique,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results deleteObjectProperty (const _Tt_string &objid,
|
||||
const _Tt_db_property_ptr &property,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results deleteObjectProperties (const _Tt_string &objid,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results getObjectProperty (const _Tt_string &objid,
|
||||
const _Tt_string &name,
|
||||
const _Tt_db_access_ptr &access,
|
||||
_Tt_db_property_ptr &property);
|
||||
|
||||
_Tt_db_results
|
||||
getObjectProperties (const _Tt_string &objid,
|
||||
const _Tt_db_access_ptr &access,
|
||||
_Tt_db_property_list_ptr &properties);
|
||||
|
||||
// Used to facilitate moving an object to a new file on the same
|
||||
// partition. The file specified must be on the partition this DB
|
||||
// server object is connected to. If the file is not in the database,
|
||||
// it will be created with the access permissions of the object.
|
||||
_Tt_db_results setObjectFile (const _Tt_string &objid,
|
||||
const _Tt_string &file,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results getObjectFile (const _Tt_string &objid,
|
||||
const _Tt_db_access_ptr &access,
|
||||
_Tt_string &file);
|
||||
|
||||
_Tt_db_results setObjectAccess (const _Tt_string &objid,
|
||||
const _Tt_db_access_ptr &new_access,
|
||||
const _Tt_db_access_ptr &access);
|
||||
|
||||
_Tt_db_results getObjectAccess (const _Tt_string &objid,
|
||||
const _Tt_db_access_ptr &access,
|
||||
_Tt_db_access_ptr ¤t_access);
|
||||
|
||||
_Tt_db_results getDBResults () const
|
||||
{
|
||||
return dbResults;
|
||||
}
|
||||
|
||||
const _Tt_string &getLastFileAccessed () const
|
||||
{
|
||||
return dbLastFileAccessed;
|
||||
}
|
||||
|
||||
private:
|
||||
_Tt_isam_key_descriptor_ptr fileTableFileKey;
|
||||
_Tt_isam_key_descriptor_ptr fileTableFilePathKey;
|
||||
_Tt_isam_file_ptr fileTable;
|
||||
|
||||
_Tt_isam_key_descriptor_ptr fileObjectMapFileKey;
|
||||
_Tt_isam_key_descriptor_ptr fileObjectMapObjectKey;
|
||||
_Tt_isam_file_ptr fileObjectMap;
|
||||
|
||||
_Tt_isam_key_descriptor_ptr propertyTablePropertyKey;
|
||||
_Tt_isam_file_ptr propertyTable;
|
||||
|
||||
_Tt_isam_key_descriptor_ptr accessTableKey;
|
||||
_Tt_isam_file_ptr accessTable;
|
||||
|
||||
_Tt_string dbHostname;
|
||||
_Tt_string dbPartition;
|
||||
_Tt_db_results dbResults;
|
||||
_Tt_string dbLastFileAccessed;
|
||||
|
||||
void connectToDB (const _Tt_string &partition);
|
||||
|
||||
_Tt_db_results verifyObjectAccess (const _Tt_string&,
|
||||
const _Tt_db_access_ptr&,
|
||||
bool_t=FALSE,
|
||||
bool_t=FALSE);
|
||||
_Tt_db_results verifyUserOnlyObjectAccess (const _Tt_string&,
|
||||
const _Tt_db_access_ptr&);
|
||||
_Tt_db_results verifyAccess (const _Tt_string&,
|
||||
const _Tt_db_access_ptr&,
|
||||
bool_t=FALSE,
|
||||
bool_t=FALSE);
|
||||
_Tt_db_results getFileKey (const _Tt_string&, _Tt_string&);
|
||||
_Tt_string getObjectKey (const _Tt_string&);
|
||||
|
||||
_Tt_db_results setProperty (const _Tt_string&, const _Tt_db_property_ptr&);
|
||||
_Tt_db_results setProperties (const _Tt_string&,
|
||||
const _Tt_db_property_list_ptr&);
|
||||
_Tt_db_results addProperty (const _Tt_string&,
|
||||
const _Tt_db_property_ptr&,
|
||||
bool_t);
|
||||
_Tt_db_results deleteProperty (const _Tt_string&,
|
||||
const _Tt_db_property_ptr&);
|
||||
_Tt_db_results deleteProperties (const _Tt_string&,
|
||||
bool_t=FALSE);
|
||||
_Tt_db_results getProperty (const _Tt_string&,
|
||||
const _Tt_string&,
|
||||
_Tt_db_property_ptr&);
|
||||
_Tt_db_results getProperties (const _Tt_string&,
|
||||
_Tt_db_property_list_ptr&);
|
||||
_Tt_db_results setAccess (const _Tt_string&, const _Tt_db_access_ptr&);
|
||||
_Tt_db_results getAccess (const _Tt_string&, _Tt_db_access_ptr&);
|
||||
_Tt_db_results getFile (const _Tt_string&, _Tt_string&);
|
||||
|
||||
_Tt_db_results addPropertyValue (const _Tt_string&,
|
||||
const _Tt_string&,
|
||||
const _Tt_string&);
|
||||
};
|
||||
|
||||
#endif /* _TT_DB_SERVER_DB_H */
|
||||
15
cde/lib/tt/bin/ttdbserverd/tt_db_server_db_utils.C
Normal file
15
cde/lib/tt/bin/ttdbserverd/tt_db_server_db_utils.C
Normal file
@@ -0,0 +1,15 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: tt_db_server_db_utils.C /main/3 1995/10/20 16:43:15 rswiston $
|
||||
/*
|
||||
* tt_db_server_db_utils.cc - Defines the _Tt_db_server_db utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "tt_db_server_db_utils.h"
|
||||
|
||||
implement_list_of(_Tt_db_server_db)
|
||||
implement_table_of(_Tt_db_server_db)
|
||||
22
cde/lib/tt/bin/ttdbserverd/tt_db_server_db_utils.h
Normal file
22
cde/lib/tt/bin/ttdbserverd/tt_db_server_db_utils.h
Normal 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: tt_db_server_db_utils.h /main/3 1995/10/20 16:43:23 rswiston $ */
|
||||
/*
|
||||
* tt_db_server_db_utils.h - Declare the _Tt_db_server_db utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_DB_SERVER_DB_UTILS_H
|
||||
#define _TT_DB_SERVER_DB_UTILS_H
|
||||
|
||||
#include "util/tt_list.h"
|
||||
#include "util/tt_table.h"
|
||||
#include "tt_db_server_db.h"
|
||||
|
||||
declare_list_of(_Tt_db_server_db)
|
||||
declare_table_of(_Tt_db_server_db)
|
||||
|
||||
#endif // _TT_DB_SERVER_DB_UTILS_H
|
||||
41
cde/lib/tt/bin/ttdbserverd/tt_isam.h
Normal file
41
cde/lib/tt/bin/ttdbserverd/tt_isam.h
Normal 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. */
|
||||
/*%% $XConsortium: tt_isam.h /main/3 1995/10/20 16:43:31 rswiston $ */
|
||||
/*
|
||||
* @(#)tt_isam.h 1.9 95/04/10
|
||||
*
|
||||
* TT version of the NetISAM isam.h file.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_ISAM_H
|
||||
#define _TT_ISAM_H
|
||||
|
||||
#include <isam.h>
|
||||
|
||||
extern "C" { int isaddindex(int, keydesc*); }
|
||||
extern "C" { int isbuild(const char*, int, keydesc*, int); }
|
||||
extern "C" { int isclose(int); }
|
||||
extern "C" { int iscntl(int, int, ...); }
|
||||
extern "C" { int isdelcurr(int); }
|
||||
extern "C" { int isdelrec(int, long); }
|
||||
extern "C" { int iserase(const char*); }
|
||||
extern "C" { int isfsync(int); }
|
||||
extern "C" { int isindexinfo(int, keydesc *, int); }
|
||||
extern "C" { int isopen(const char*, int); }
|
||||
extern "C" { int isread(int, char*, int); }
|
||||
extern "C" { int isrename(char*, char*); }
|
||||
extern "C" { int isrewcurr(int, char*); }
|
||||
extern "C" { int isrewrec(int, long, char*); }
|
||||
extern "C" { int isstart(int, keydesc*, int, char*, int); }
|
||||
extern "C" { int iswrite(int, char*); }
|
||||
extern "C" { int islock(int); }
|
||||
extern "C" { int isunlock(int); }
|
||||
extern "C" { int isgarbage(char *); }
|
||||
extern "C" { int isgetcurpos(int isfd, int *len, char **buf); }
|
||||
extern "C" { int issetcurpos(int isfd, char *buf); }
|
||||
|
||||
#endif /* _TT_ISAM_H */
|
||||
378
cde/lib/tt/bin/ttdbserverd/tt_isam_file.C
Normal file
378
cde/lib/tt/bin/ttdbserverd/tt_isam_file.C
Normal file
@@ -0,0 +1,378 @@
|
||||
//%% (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_isam_file.C /main/3 1995/10/20 16:43:39 rswiston $
|
||||
/*
|
||||
* tt_isam_file.cc - Defines the TT ISAM file class. This class simplifies
|
||||
* opening, closing, reading and writing an ISAM file.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "tt_isam_file.h"
|
||||
#include "util/tt_port.h"
|
||||
#include "dm_access_cache.h"
|
||||
|
||||
extern FILE *errstr;
|
||||
|
||||
bool_t _Tt_isam_file::isamFatalErrorHandlerSet = FALSE;
|
||||
|
||||
_Tt_isam_file::_Tt_isam_file (const _Tt_string &file, int mode)
|
||||
{
|
||||
setTtISAMFileDefaults();
|
||||
fileName = file;
|
||||
fileMode = mode;
|
||||
|
||||
if ((fileDescriptor = cached_isopen(file, mode)) != -1) {
|
||||
getISAMFileInfo();
|
||||
}
|
||||
else {
|
||||
getStatusInfo();
|
||||
}
|
||||
}
|
||||
|
||||
_Tt_isam_file
|
||||
::_Tt_isam_file (const _Tt_string &file,
|
||||
int max_record_length,
|
||||
int min_record_length,
|
||||
_Tt_isam_key_descriptor_ptr primary_key_descriptor,
|
||||
int mode)
|
||||
{
|
||||
setTtISAMFileDefaults();
|
||||
fileName = file;
|
||||
fileMode = mode;
|
||||
|
||||
if ((fileDescriptor = cached_isopen(file, mode)) == -1) {
|
||||
newFlag = TRUE;
|
||||
isreclen = min_record_length;
|
||||
fileDescriptor = isbuild(file,
|
||||
max_record_length,
|
||||
primary_key_descriptor->getKeyDescriptor(),
|
||||
mode);
|
||||
}
|
||||
|
||||
if (fileDescriptor != -1) {
|
||||
getISAMFileInfo();
|
||||
}
|
||||
else {
|
||||
errorStatus = iserrno;
|
||||
currentRecordLength = -1;
|
||||
currentRecordNumber = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void _Tt_isam_file::setTtISAMFileDefaults ()
|
||||
{
|
||||
eraseFlag = FALSE;
|
||||
fileName = (char *)NULL;
|
||||
fileMode = 0;
|
||||
keyDescriptorList = new _Tt_isam_key_descriptor_list;
|
||||
newFlag = FALSE;
|
||||
|
||||
if (!isamFatalErrorHandlerSet) {
|
||||
isamFatalErrorHandlerSet = TRUE;
|
||||
(void)iscntl(ALLISFD, ISCNTL_FATAL, &_Tt_isam_file::isamFatalErrorHandler);
|
||||
}
|
||||
|
||||
iserrno = 0;
|
||||
}
|
||||
|
||||
_Tt_isam_file::~_Tt_isam_file ()
|
||||
{
|
||||
if (eraseFlag) {
|
||||
(void)iserase(fileName);
|
||||
}
|
||||
else {
|
||||
(void)cached_isclose(fileDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
void _Tt_isam_file::setErase (bool_t flag)
|
||||
{
|
||||
eraseFlag = flag;
|
||||
}
|
||||
|
||||
int _Tt_isam_file::sync ()
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
(void)isfsync(fileDescriptor);
|
||||
|
||||
errorStatus = iserrno;
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// islock and isunlock are not supported by mini-isam
|
||||
//
|
||||
//int _Tt_isam_file::lock ()
|
||||
//{
|
||||
// iserrno = 0;
|
||||
//
|
||||
// (void)islock(fileDescriptor);
|
||||
//
|
||||
// errorStatus = iserrno;
|
||||
// return errorStatus;
|
||||
//}
|
||||
//
|
||||
//int _Tt_isam_file::unlock ()
|
||||
//{
|
||||
// iserrno = 0;
|
||||
//
|
||||
// (void)isunlock(fileDescriptor);
|
||||
//
|
||||
// errorStatus = iserrno;
|
||||
// return errorStatus;
|
||||
//}
|
||||
|
||||
int _Tt_isam_file::rename (const _Tt_string &new_file)
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
int results = isrename(fileName, new_file);
|
||||
|
||||
errorStatus = iserrno;
|
||||
if (!results) {
|
||||
fileName = new_file;
|
||||
newFlag = FALSE;
|
||||
|
||||
if ((fileDescriptor = cached_isopen(new_file, fileMode)) != -1) {
|
||||
getISAMFileInfo();
|
||||
}
|
||||
else {
|
||||
getStatusInfo();
|
||||
}
|
||||
}
|
||||
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
int _Tt_isam_file::addIndex (_Tt_isam_key_descriptor_ptr key_descriptor)
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
int results = isaddindex(fileDescriptor, key_descriptor->getKeyDescriptor());
|
||||
|
||||
errorStatus = iserrno;
|
||||
if (!results) {
|
||||
getISAMFileInfo();
|
||||
}
|
||||
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
_Tt_isam_record_ptr _Tt_isam_file::getEmptyRecord ()
|
||||
{
|
||||
return (new _Tt_isam_record(keyDescriptorList,
|
||||
maxRecordLength,
|
||||
minRecordLength));
|
||||
}
|
||||
|
||||
int _Tt_isam_file
|
||||
::findStartRecord (const _Tt_isam_key_descriptor_ptr &key_descriptor,
|
||||
int length,
|
||||
const _Tt_isam_record_ptr &record,
|
||||
int mode)
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
(void)isstart(fileDescriptor,
|
||||
key_descriptor->getKeyDescriptor(),
|
||||
length,
|
||||
(char *)record->getRecord(),
|
||||
mode);
|
||||
|
||||
getStatusInfo();
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
_Tt_isam_record_ptr _Tt_isam_file::readRecord (int mode)
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
_Tt_isam_record_ptr record = (_Tt_isam_record *)NULL;
|
||||
_Tt_string record_buffer(maxRecordLength);
|
||||
int results = isread(fileDescriptor,
|
||||
(char *)record_buffer,
|
||||
mode);
|
||||
|
||||
getStatusInfo();
|
||||
if (!results) {
|
||||
record = getFullRecord(record_buffer);
|
||||
}
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
int _Tt_isam_file::readRecord (int mode,
|
||||
const _Tt_isam_record_ptr &record)
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
int results = isread(fileDescriptor, (char *)record->getRecord(), mode);
|
||||
|
||||
getStatusInfo();
|
||||
if (!results) {
|
||||
record->setLength(currentRecordLength);
|
||||
}
|
||||
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
int _Tt_isam_file::updateCurrentRecord (const _Tt_isam_record_ptr &record)
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
isreclen = record->getLength();
|
||||
(void)isrewcurr(fileDescriptor, (char *)record->getRecord());
|
||||
|
||||
getStatusInfo();
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
int
|
||||
_Tt_isam_file::updateRecord (long recnum, const _Tt_isam_record_ptr &record)
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
isreclen = record->getLength();
|
||||
(void)isrewrec(fileDescriptor, recnum, (char *)record->getRecord());
|
||||
|
||||
getStatusInfo();
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
int _Tt_isam_file::writeRecord (const _Tt_isam_record_ptr &record)
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
isreclen = record->getLength();
|
||||
(void)iswrite(fileDescriptor, (char *)record->getRecord());
|
||||
|
||||
getStatusInfo();
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
int _Tt_isam_file::deleteCurrentRecord ()
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
(void)isdelcurr(fileDescriptor);
|
||||
|
||||
getStatusInfo();
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
int _Tt_isam_file::deleteRecord (long recnum)
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
(void)isdelrec(fileDescriptor, recnum);
|
||||
|
||||
getStatusInfo();
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
int _Tt_isam_file::writeMagicString (const _Tt_string &magic_string)
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
(void)iscntl(fileDescriptor,
|
||||
ISCNTL_APPLMAGIC_WRITE,
|
||||
(char *)magic_string);
|
||||
|
||||
errorStatus = iserrno;
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
_Tt_string _Tt_isam_file::readMagicString ()
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
_Tt_string magic_string_bytes(ISAPPLMAGICLEN);
|
||||
memset((char *)magic_string_bytes, '\0', ISAPPLMAGICLEN);
|
||||
|
||||
(void)iscntl(fileDescriptor,
|
||||
ISCNTL_APPLMAGIC_READ,
|
||||
(char *)magic_string_bytes);
|
||||
|
||||
errorStatus = iserrno;
|
||||
|
||||
_Tt_string magic_string = (char *)magic_string_bytes;
|
||||
return magic_string;
|
||||
}
|
||||
|
||||
int _Tt_isam_file::setFatalErrorHandler (FatalErrorHandlerFunction function)
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
(void)iscntl(fileDescriptor, ISCNTL_FATAL, function);
|
||||
|
||||
errorStatus = iserrno;
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
_Tt_isam_record_ptr
|
||||
_Tt_isam_file::getFullRecord (const _Tt_string &record_buffer)
|
||||
{
|
||||
_Tt_isam_record_ptr record_ptr = new _Tt_isam_record(keyDescriptorList,
|
||||
maxRecordLength,
|
||||
minRecordLength);
|
||||
record_ptr->setBytes(0, currentRecordLength, record_buffer);
|
||||
record_ptr->setLength(currentRecordLength);
|
||||
|
||||
return record_ptr;
|
||||
}
|
||||
|
||||
void _Tt_isam_file::getISAMFileInfo ()
|
||||
{
|
||||
iserrno = 0;
|
||||
|
||||
struct dictinfo file_info;
|
||||
struct keydesc key_descriptor;
|
||||
short num_keys;
|
||||
int results = isindexinfo(fileDescriptor,
|
||||
(keydesc *)&file_info,
|
||||
0);
|
||||
|
||||
getStatusInfo();
|
||||
if (!results) {
|
||||
keyDescriptorList->flush();
|
||||
|
||||
// If the file has var length records, the MSB is set in the di_nkeys
|
||||
// field. This guarantees to turn the bit off...
|
||||
num_keys = file_info.di_nkeys & ~DICTVARLENBIT;
|
||||
|
||||
if (num_keys == 1) {
|
||||
(void)isindexinfo(fileDescriptor, &key_descriptor, 1);
|
||||
if (key_descriptor.k_nparts == 0) {
|
||||
num_keys = 0;
|
||||
}
|
||||
else {
|
||||
num_keys = 1;
|
||||
}
|
||||
}
|
||||
|
||||
maxRecordLength = file_info.di_recsize;
|
||||
minRecordLength = isreclen;
|
||||
|
||||
for (int i=1; i <= num_keys; i++) {
|
||||
isindexinfo(fileDescriptor, &key_descriptor, i);
|
||||
|
||||
_Tt_isam_key_descriptor_ptr key_descriptor_ptr =
|
||||
new _Tt_isam_key_descriptor;
|
||||
key_descriptor_ptr->keyDescriptor = key_descriptor;
|
||||
|
||||
keyDescriptorList->append(key_descriptor_ptr);
|
||||
}
|
||||
|
||||
errorStatus = iserrno;
|
||||
}
|
||||
}
|
||||
|
||||
int _Tt_isam_file::isamFatalErrorHandler (char *msg)
|
||||
{
|
||||
_tt_syslog(errstr, LOG_ERR, "NetISAM: %s", msg);
|
||||
return 1;
|
||||
}
|
||||
122
cde/lib/tt/bin/ttdbserverd/tt_isam_file.h
Normal file
122
cde/lib/tt/bin/ttdbserverd/tt_isam_file.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*%% (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_isam_file.h /main/3 1995/10/20 16:43:47 rswiston $ */
|
||||
/*
|
||||
* tt_isam_file.h - Defines the TT ISAM file class. This class simplifies
|
||||
* opening, closing, reading and writing an ISAM file.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_ISAM_FILE_H
|
||||
#define _TT_ISAM_FILE_H
|
||||
|
||||
#include "util/tt_object.h"
|
||||
#include "tt_isam.h"
|
||||
#include "tt_isam_key_descriptor_utils.h"
|
||||
#include "tt_isam_record_utils.h"
|
||||
|
||||
typedef int (*FatalErrorHandlerFunction) (char *);
|
||||
|
||||
class _Tt_isam_file : public _Tt_object {
|
||||
public:
|
||||
// Dummy constructor needed to make _tt_isam_file_utils.cc happy
|
||||
_Tt_isam_file () {}
|
||||
|
||||
// Real constructors
|
||||
_Tt_isam_file (const _Tt_string &file, int mode);
|
||||
_Tt_isam_file (const _Tt_string &file,
|
||||
int max_record_length,
|
||||
int min_record_length,
|
||||
_Tt_isam_key_descriptor_ptr primary_key_descriptor,
|
||||
int mode);
|
||||
~_Tt_isam_file ();
|
||||
|
||||
void setErase (bool_t);
|
||||
int sync ();
|
||||
|
||||
//
|
||||
// islock and isunlock are not supported by mini-isam
|
||||
//
|
||||
// int lock ();
|
||||
// int unlock ();
|
||||
|
||||
int rename (const _Tt_string&);
|
||||
|
||||
int addIndex (_Tt_isam_key_descriptor_ptr);
|
||||
_Tt_isam_record_ptr getEmptyRecord ();
|
||||
|
||||
int findStartRecord (const _Tt_isam_key_descriptor_ptr &key_descriptor,
|
||||
int length,
|
||||
const _Tt_isam_record_ptr &record,
|
||||
int mode);
|
||||
|
||||
_Tt_isam_record_ptr readRecord (int mode);
|
||||
int readRecord (int mode, const _Tt_isam_record_ptr&);
|
||||
int updateCurrentRecord (const _Tt_isam_record_ptr&);
|
||||
int updateRecord (long recnum, const _Tt_isam_record_ptr&);
|
||||
int writeRecord (const _Tt_isam_record_ptr&);
|
||||
int deleteCurrentRecord ();
|
||||
int deleteRecord (long recnum);
|
||||
|
||||
int writeMagicString (const _Tt_string&);
|
||||
_Tt_string readMagicString ();
|
||||
|
||||
int setFatalErrorHandler (FatalErrorHandlerFunction);
|
||||
|
||||
long getLastRecordNumber () const
|
||||
{
|
||||
return currentRecordNumber;
|
||||
}
|
||||
|
||||
int getFileDescriptor () const
|
||||
{
|
||||
return fileDescriptor;
|
||||
}
|
||||
|
||||
const _Tt_string &getName () const
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
|
||||
int getErrorStatus () const
|
||||
{
|
||||
return errorStatus;
|
||||
}
|
||||
|
||||
bool_t isNew () const
|
||||
{
|
||||
return newFlag;
|
||||
}
|
||||
|
||||
private:
|
||||
int currentRecordLength;
|
||||
long currentRecordNumber;
|
||||
bool_t eraseFlag;
|
||||
int errorStatus;
|
||||
int fileDescriptor;
|
||||
_Tt_string fileName;
|
||||
int fileMode;
|
||||
_Tt_isam_key_descriptor_list_ptr keyDescriptorList;
|
||||
int maxRecordLength;
|
||||
int minRecordLength;
|
||||
bool_t newFlag;
|
||||
|
||||
void setTtISAMFileDefaults ();
|
||||
_Tt_isam_record_ptr getFullRecord (const _Tt_string&);
|
||||
void getISAMFileInfo ();
|
||||
|
||||
void getStatusInfo ()
|
||||
{
|
||||
currentRecordLength = isreclen;
|
||||
currentRecordNumber = isrecnum;
|
||||
errorStatus = iserrno;
|
||||
}
|
||||
|
||||
static bool_t isamFatalErrorHandlerSet;
|
||||
static int isamFatalErrorHandler (char *message);
|
||||
};
|
||||
|
||||
#endif /* _TT_ISAM_FILE_H */
|
||||
15
cde/lib/tt/bin/ttdbserverd/tt_isam_file_utils.C
Normal file
15
cde/lib/tt/bin/ttdbserverd/tt_isam_file_utils.C
Normal file
@@ -0,0 +1,15 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: tt_isam_file_utils.C /main/3 1995/10/20 16:43:55 rswiston $
|
||||
/*
|
||||
* tt_isam_file_utils.cc - Defines the _Tt_isam_file class
|
||||
* utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "tt_isam_file_utils.h"
|
||||
|
||||
implement_ptr_to(_Tt_isam_file)
|
||||
20
cde/lib/tt/bin/ttdbserverd/tt_isam_file_utils.h
Normal file
20
cde/lib/tt/bin/ttdbserverd/tt_isam_file_utils.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: tt_isam_file_utils.h /main/3 1995/10/20 16:44:05 rswiston $ */
|
||||
/*
|
||||
* tt_isam_file_utils.h - Declares the _Tt_isam_file class
|
||||
* utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_ISAM_FILE_UTILS_H
|
||||
#define _TT_ISAM_FILE_UTILS_H
|
||||
|
||||
#include "tt_isam_file.h"
|
||||
|
||||
declare_ptr_to(_Tt_isam_file)
|
||||
|
||||
#endif // _TT_ISAM_FILE_UTILS_H
|
||||
85
cde/lib/tt/bin/ttdbserverd/tt_isam_key_descriptor.C
Normal file
85
cde/lib/tt/bin/ttdbserverd/tt_isam_key_descriptor.C
Normal file
@@ -0,0 +1,85 @@
|
||||
//%% (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_isam_key_descriptor.C /main/3 1995/10/20 16:44:18 rswiston $
|
||||
/*
|
||||
* tt_isam_key_descriptor.cc - Defines the TT ISAM key descriptor class.
|
||||
* This class is used to hold the information required
|
||||
* to create a NetISAM key descriptor. It also makes
|
||||
* it very easy to construct the descriptor.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "tt_isam_key_descriptor.h"
|
||||
|
||||
_Tt_isam_key_descriptor::_Tt_isam_key_descriptor ()
|
||||
{
|
||||
keyDescriptor.k_flags = 0;
|
||||
keyDescriptor.k_nparts = 0;
|
||||
}
|
||||
|
||||
_Tt_isam_key_descriptor::~_Tt_isam_key_descriptor ()
|
||||
{
|
||||
}
|
||||
|
||||
short _Tt_isam_key_descriptor::addKeyPart (short start, short length, short type)
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
if (keyDescriptor.k_nparts < NPARTS-1) {
|
||||
index = keyDescriptor.k_nparts;
|
||||
|
||||
keyDescriptor.k_part [index].kp_start = start;
|
||||
keyDescriptor.k_part [index].kp_leng = length;
|
||||
keyDescriptor.k_part [index].kp_type = type;
|
||||
|
||||
keyDescriptor.k_nparts++;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
short _Tt_isam_key_descriptor::setKeyPart (short index,
|
||||
short start,
|
||||
short length,
|
||||
short type)
|
||||
{
|
||||
short error = 0;
|
||||
|
||||
if ((index > -1) && (index < keyDescriptor.k_nparts)) {
|
||||
keyDescriptor.k_part [index].kp_start = start;
|
||||
keyDescriptor.k_part [index].kp_leng = length;
|
||||
keyDescriptor.k_part [index].kp_type = type;
|
||||
}
|
||||
else {
|
||||
error = -1;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
short _Tt_isam_key_descriptor::getKeyPart (short index,
|
||||
short &start,
|
||||
short &length,
|
||||
short &type) const
|
||||
{
|
||||
short error = 0;
|
||||
|
||||
if ((index > -1) && (index < keyDescriptor.k_nparts)) {
|
||||
|
||||
|
||||
start = keyDescriptor.k_part [index].kp_start;
|
||||
length = keyDescriptor.k_part [index].kp_leng;
|
||||
type = keyDescriptor.k_part [index].kp_type;
|
||||
}
|
||||
else {
|
||||
start = -1;
|
||||
length = -1;
|
||||
type = -1;
|
||||
error = -1;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
82
cde/lib/tt/bin/ttdbserverd/tt_isam_key_descriptor.h
Normal file
82
cde/lib/tt/bin/ttdbserverd/tt_isam_key_descriptor.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*%% (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_isam_key_descriptor.h /main/3 1995/10/20 16:44:29 rswiston $ */
|
||||
/*
|
||||
* tt_isam_key_descriptor.h - Defines the TT ISAM key descriptor class.
|
||||
* This class is used to hold the information required
|
||||
* to create a NetISAM key descriptor. It also makes
|
||||
* it very easy to construct the descriptor.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_ISAM_KEY_DESCRIPTOR_H
|
||||
#define _TT_ISAM_KEY_DESCRIPTOR_H
|
||||
|
||||
#include "util/tt_object.h"
|
||||
#include "tt_isam.h"
|
||||
|
||||
class _Tt_isam_key_descriptor : public _Tt_object {
|
||||
public:
|
||||
_Tt_isam_key_descriptor ();
|
||||
~_Tt_isam_key_descriptor ();
|
||||
|
||||
void setCompress (bool_t flag)
|
||||
{
|
||||
if (flag) {
|
||||
keyDescriptor.k_flags |= COMPRESS;
|
||||
}
|
||||
else {
|
||||
keyDescriptor.k_flags &= (short) (0xFFFF - COMPRESS);
|
||||
}
|
||||
}
|
||||
|
||||
bool_t isCompressSet ()
|
||||
{
|
||||
return ((keyDescriptor.k_flags & COMPRESS) ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
void setDuplicates (bool_t flag)
|
||||
{
|
||||
if (flag) {
|
||||
keyDescriptor.k_flags &= (short) (0xFFFF - ISNODUPS);
|
||||
keyDescriptor.k_flags |= ISDUPS;
|
||||
}
|
||||
else {
|
||||
keyDescriptor.k_flags &= (short) (0xFFFF - ISDUPS);
|
||||
keyDescriptor.k_flags |= ISNODUPS;
|
||||
}
|
||||
}
|
||||
|
||||
bool_t isDuplicatesSet ()
|
||||
{
|
||||
return ((keyDescriptor.k_flags & ISDUPS) ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
short addKeyPart (short start, short length, short type);
|
||||
short setKeyPart (short index, short start, short length, short type);
|
||||
|
||||
short getKeyPart (short index,
|
||||
short &start,
|
||||
short &length,
|
||||
short &type) const;
|
||||
|
||||
short getNumberOfParts () const
|
||||
{
|
||||
return keyDescriptor.k_nparts;
|
||||
}
|
||||
|
||||
private:
|
||||
struct keydesc keyDescriptor;
|
||||
|
||||
keydesc *getKeyDescriptor ()
|
||||
{
|
||||
return &keyDescriptor;
|
||||
}
|
||||
|
||||
friend class _Tt_isam_file;
|
||||
};
|
||||
|
||||
#endif /* _TT_ISAM_KEY_DESCRIPTOR_H */
|
||||
15
cde/lib/tt/bin/ttdbserverd/tt_isam_key_descriptor_utils.C
Normal file
15
cde/lib/tt/bin/ttdbserverd/tt_isam_key_descriptor_utils.C
Normal file
@@ -0,0 +1,15 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: tt_isam_key_descriptor_utils.C /main/3 1995/10/20 16:44:40 rswiston $
|
||||
/*
|
||||
* tt_isam_key_descriptor_utils.cc - Defines the _Tt_isam_key_descriptor class
|
||||
* utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "tt_isam_key_descriptor_utils.h"
|
||||
|
||||
implement_list_of(_Tt_isam_key_descriptor)
|
||||
21
cde/lib/tt/bin/ttdbserverd/tt_isam_key_descriptor_utils.h
Normal file
21
cde/lib/tt/bin/ttdbserverd/tt_isam_key_descriptor_utils.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: tt_isam_key_descriptor_utils.h /main/3 1995/10/20 16:44:48 rswiston $ */
|
||||
/*
|
||||
* tt_isam_key_descriptor_utils.h - Declares the _Tt_isam_key_descriptor class
|
||||
* utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_ISAM_KEY_DESCRIPTOR_UTILS_H
|
||||
#define _TT_ISAM_KEY_DESCRIPTOR_UTILS_H
|
||||
|
||||
#include "util/tt_list.h"
|
||||
#include "tt_isam_key_descriptor.h"
|
||||
|
||||
declare_list_of(_Tt_isam_key_descriptor)
|
||||
|
||||
#endif // _TT_ISAM_KEY_DESCRIPTOR_UTILS_H
|
||||
128
cde/lib/tt/bin/ttdbserverd/tt_isam_record.C
Normal file
128
cde/lib/tt/bin/ttdbserverd/tt_isam_record.C
Normal file
@@ -0,0 +1,128 @@
|
||||
//%% (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_isam_record.C /main/3 1995/10/20 16:44:57 rswiston $
|
||||
/*
|
||||
* tt_isam_record.cc - Defines the TT ISAM record class.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "tt_isam_record.h"
|
||||
|
||||
_Tt_isam_record::
|
||||
_Tt_isam_record (const _Tt_isam_key_descriptor_list_ptr &key_descriptor_list,
|
||||
int max_record_length,
|
||||
int min_record_length)
|
||||
{
|
||||
_Tt_string new_buffer(max_record_length);
|
||||
memset((char *)new_buffer, '\0', max_record_length);
|
||||
|
||||
buffer = new_buffer;
|
||||
keyDescriptorList = key_descriptor_list;
|
||||
currentLength = min_record_length;
|
||||
maxLength = max_record_length;
|
||||
minLength = min_record_length;
|
||||
}
|
||||
|
||||
_Tt_isam_record::~_Tt_isam_record ()
|
||||
{
|
||||
}
|
||||
|
||||
int _Tt_isam_record::getNumberOfKeys () const
|
||||
{
|
||||
return keyDescriptorList->count();
|
||||
}
|
||||
|
||||
_Tt_isam_key_descriptor_ptr _Tt_isam_record::getKeyDescriptor (int index) const
|
||||
{
|
||||
_Tt_isam_key_descriptor_ptr descriptor_ptr = (_Tt_isam_key_descriptor *)NULL;
|
||||
|
||||
if ((index > -1) && (index < keyDescriptorList->count())) {
|
||||
descriptor_ptr = (*keyDescriptorList) [index];
|
||||
}
|
||||
|
||||
return descriptor_ptr;
|
||||
}
|
||||
|
||||
_Tt_string _Tt_isam_record::getKeyPartValue (int index, int part) const
|
||||
{
|
||||
_Tt_string value;
|
||||
|
||||
short key_part_start;
|
||||
short key_part_length;
|
||||
short key_part_type;
|
||||
|
||||
if ((index > -1) && (index < keyDescriptorList->count())) {
|
||||
_Tt_isam_key_descriptor_ptr descriptor_ptr = (*keyDescriptorList) [index];
|
||||
|
||||
if ((part > -1) && (part < descriptor_ptr->getNumberOfParts())) {
|
||||
descriptor_ptr->getKeyPart(part,
|
||||
key_part_start,
|
||||
key_part_length,
|
||||
key_part_type);
|
||||
|
||||
_Tt_string key_part(key_part_length);
|
||||
(void)memcpy((char *)key_part,
|
||||
(char *)buffer+key_part_start,
|
||||
key_part_length);
|
||||
value = key_part;
|
||||
}
|
||||
else {
|
||||
_Tt_string null_string((char *)NULL);
|
||||
value = null_string;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_Tt_string null_string((char *)NULL);
|
||||
value = null_string;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void _Tt_isam_record::setKeyPartValue (int index,
|
||||
int part,
|
||||
const _Tt_string &value)
|
||||
{
|
||||
short key_part_start;
|
||||
short key_part_length;
|
||||
short key_part_type;
|
||||
|
||||
if ((index > -1) && (index < keyDescriptorList->count())) {
|
||||
_Tt_isam_key_descriptor_ptr descriptor_ptr = (*keyDescriptorList) [index];
|
||||
|
||||
descriptor_ptr->getKeyPart(part,
|
||||
key_part_start,
|
||||
key_part_length,
|
||||
key_part_type);
|
||||
|
||||
int length = ((value.len() < key_part_length) ?
|
||||
value.len() : key_part_length);
|
||||
(void)memcpy((char *)buffer+key_part_start, (char *)value, length);
|
||||
}
|
||||
}
|
||||
|
||||
_Tt_string _Tt_isam_record::getBytes (int start, int length) const
|
||||
{
|
||||
if (length < 1) {
|
||||
length = currentLength - start;
|
||||
}
|
||||
|
||||
_Tt_string value(length);
|
||||
(void)memcpy((char *)value, (char *)buffer+start, length);
|
||||
return value;
|
||||
}
|
||||
|
||||
void _Tt_isam_record::setBytes (int start, const _Tt_string &value)
|
||||
{
|
||||
(void)memcpy((char *)buffer+start, (char *)value, value.len());
|
||||
}
|
||||
|
||||
void _Tt_isam_record::setBytes (int start,
|
||||
int length,
|
||||
const _Tt_string &value)
|
||||
{
|
||||
(void)memcpy((char *)buffer+start, (char *)value, length);
|
||||
}
|
||||
75
cde/lib/tt/bin/ttdbserverd/tt_isam_record.h
Normal file
75
cde/lib/tt/bin/ttdbserverd/tt_isam_record.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*%% (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_isam_record.h /main/3 1995/10/20 16:45:07 rswiston $ */
|
||||
/*
|
||||
* tt_isam_record.h - Defines the TT ISAM record class. This class simplifies
|
||||
* putting data in a record. To get an empty record ready
|
||||
* to be filled with data, call the _Tt_isam_file::getEmptyRecord.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_ISAM_RECORD_H
|
||||
#define _TT_ISAM_RECORD_H
|
||||
|
||||
#include "util/tt_object.h"
|
||||
#include "util/tt_string.h"
|
||||
#include "tt_isam_key_descriptor_utils.h"
|
||||
|
||||
class _Tt_isam_record : public _Tt_object {
|
||||
public:
|
||||
// Dummy constructor needed to make tt_isam_record_utils.cc happy
|
||||
_Tt_isam_record () {}
|
||||
|
||||
// Real constructor
|
||||
_Tt_isam_record (const _Tt_isam_key_descriptor_list_ptr &key_descriptor_list,
|
||||
int max_record_length,
|
||||
int min_record_length);
|
||||
~_Tt_isam_record ();
|
||||
|
||||
int getNumberOfKeys () const;
|
||||
_Tt_isam_key_descriptor_ptr getKeyDescriptor (int) const;
|
||||
|
||||
_Tt_string getKeyPartValue (int, int) const;
|
||||
void setKeyPartValue (int, int, const _Tt_string&);
|
||||
|
||||
_Tt_string getBytes (int, int) const;
|
||||
void setBytes (int, const _Tt_string&);
|
||||
void setBytes (int, int, const _Tt_string&);
|
||||
|
||||
void setLength (int length)
|
||||
{
|
||||
currentLength = length;
|
||||
}
|
||||
|
||||
int getLength () const
|
||||
{
|
||||
return currentLength;
|
||||
}
|
||||
|
||||
int getMaxLength () const
|
||||
{
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
int getMinLength () const
|
||||
{
|
||||
return minLength;
|
||||
}
|
||||
|
||||
const _Tt_string &getRecord () const
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private:
|
||||
_Tt_string buffer;
|
||||
_Tt_isam_key_descriptor_list_ptr keyDescriptorList;
|
||||
int currentLength;
|
||||
int maxLength;
|
||||
int minLength;
|
||||
};
|
||||
|
||||
#endif /* _TT_ISAM_RECORD_H */
|
||||
15
cde/lib/tt/bin/ttdbserverd/tt_isam_record_utils.C
Normal file
15
cde/lib/tt/bin/ttdbserverd/tt_isam_record_utils.C
Normal file
@@ -0,0 +1,15 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: tt_isam_record_utils.C /main/3 1995/10/20 16:45:16 rswiston $
|
||||
/*
|
||||
* tt_isam_record_utils.cc - Defines the _Tt_isam_record class
|
||||
* utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "tt_isam_record_utils.h"
|
||||
|
||||
implement_list_of(_Tt_isam_record)
|
||||
21
cde/lib/tt/bin/ttdbserverd/tt_isam_record_utils.h
Normal file
21
cde/lib/tt/bin/ttdbserverd/tt_isam_record_utils.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
|
||||
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
|
||||
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
|
||||
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
|
||||
/*%% $XConsortium: tt_isam_record_utils.h /main/3 1995/10/20 16:45:28 rswiston $ */
|
||||
/*
|
||||
* tt_isam_record_utils.h - Declares the _Tt_isam_record class
|
||||
* utilities.
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _TT_ISAM_RECORD_UTILS_H
|
||||
#define _TT_ISAM_RECORD_UTILS_H
|
||||
|
||||
#include "util/tt_list.h"
|
||||
#include "tt_isam_record.h"
|
||||
|
||||
declare_list_of(_Tt_isam_record)
|
||||
|
||||
#endif // _TT_ISAM_RECORD_UTILS_H
|
||||
30
cde/lib/tt/bin/ttsession/Imakefile
Normal file
30
cde/lib/tt/bin/ttsession/Imakefile
Normal file
@@ -0,0 +1,30 @@
|
||||
XCOMM $XConsortium: Imakefile /main/15 1996/10/09 14:02:13 drk $
|
||||
|
||||
#define CplusplusSource YES
|
||||
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
|
||||
EXTRA_LOAD_FLAGS = ExtraLoadFlags $(UNSHARED_CXXLIB)
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#include "../../tooltalk.tmpl"
|
||||
|
||||
DEFINES =
|
||||
INCLUDES = -I. -I../../slib -I../../lib
|
||||
|
||||
DEPLIBS = ../../slib/libstt.a TtClientDepLibs
|
||||
LOCAL_LIBRARIES = ../../slib/libstt.a TtClientLibs
|
||||
SYS_LIBRARIES =
|
||||
|
||||
#ifdef TtClientExtraLibs
|
||||
EXTRA_LIBRARIES = TtClientExtraLibs
|
||||
#endif
|
||||
|
||||
SRCS = mp_server.C
|
||||
|
||||
OBJS = mp_server.o
|
||||
|
||||
NormalCplusplusObjectRule()
|
||||
|
||||
ComplexCplusplusProgramTarget(ttsession)
|
||||
|
||||
SpecialCplusplusObjectRule(mp_server,mp_server,$(TT_VERSION_DEFINE))
|
||||
6
cde/lib/tt/bin/ttsession/Mapfile
Normal file
6
cde/lib/tt/bin/ttsession/Mapfile
Normal file
@@ -0,0 +1,6 @@
|
||||
# %% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
# %% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
# %% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
# %% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
# %% $XConsortium: Mapfile /main/3 1995/10/20 16:46:19 rswiston $
|
||||
text=LOAD ?RXO;
|
||||
11
cde/lib/tt/bin/ttsession/admindefines
Normal file
11
cde/lib/tt/bin/ttsession/admindefines
Normal file
@@ -0,0 +1,11 @@
|
||||
XCOMM $XConsortium: admindefines /main/2 1996/05/07 19:17:11 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
|
||||
931
cde/lib/tt/bin/ttsession/mp_server.C
Normal file
931
cde/lib/tt/bin/ttsession/mp_server.C
Normal file
@@ -0,0 +1,931 @@
|
||||
//%% (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_server.C /main/10 1999/10/14 18:38:32 mgreess $
|
||||
/*
|
||||
* @(#)mp_server.C 1.119 95/09/26
|
||||
*
|
||||
* Copyright (c) 1992 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include "tt_options.h"
|
||||
#include "mp_s_global.h"
|
||||
#include "mp/mp_mp.h"
|
||||
#include "mp_s_mp.h"
|
||||
#include "mp_ptype.h"
|
||||
#include "mp_s_session.h"
|
||||
#include "mp_typedb.h"
|
||||
#include "util/copyright.h"
|
||||
#include "util/tt_enumname.h"
|
||||
#include "util/tt_global_env.h"
|
||||
#include "util/tt_port.h"
|
||||
#include "util/tt_gettext.h"
|
||||
#include "db/db_server.h"
|
||||
#include <locale.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define MAXARGS 256
|
||||
#define MAXPIDS 256
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
#if defined(sgi)
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
TT_INSERT_COPYRIGHT
|
||||
|
||||
#ifdef OPT_PATCH
|
||||
static char PatchID[] = "Patch Id: 100626_03.";
|
||||
static int Patch_ID100626_03;
|
||||
#endif
|
||||
|
||||
extern char **environ;
|
||||
|
||||
// flag set by the signal handler function whenever we receive a
|
||||
// signal that the types database changed.
|
||||
int signal_types_changed = 0;
|
||||
int signal_toggle_trace = 0;
|
||||
|
||||
// option_classing_engine determines whether we use the Classing Engine
|
||||
// to read the ptype/otype database. It's starting value determines the
|
||||
// default.
|
||||
int option_classing_engine = 0;
|
||||
|
||||
// if equal to 1 then this option means that non process-tree
|
||||
// ttsessions will fork a child and exit when the child ttsession is
|
||||
// ready to service clients.
|
||||
int background_mode = 1;
|
||||
|
||||
// this is a special case of a process-tree session that forks a child
|
||||
// ttsession (rather than forking a root process) and then prints out
|
||||
// the child ttsession session id when it is ready to service clients.
|
||||
int print_sessid = 0;
|
||||
|
||||
// the level of authorization we are to use. one of: "unix", "none",
|
||||
// or "des". The default is "none".
|
||||
char *option_auth_level = (char *)0;
|
||||
|
||||
// Whether to maximize the fd limit.
|
||||
int option_maximize_procids = 0;
|
||||
|
||||
// the pid of the root process that gets forked in a process-tree
|
||||
// session, or of the child ttsession
|
||||
pid_t forked_pid = (pid_t)-1;
|
||||
|
||||
void sig_handler(int sig);
|
||||
|
||||
#ifdef OPT_XTHREADS
|
||||
static void init_self();
|
||||
#endif
|
||||
|
||||
// buffer used to write out the session id of a child ttsession when the
|
||||
// special print_sessid option is turned on.
|
||||
char session_buf[255];
|
||||
|
||||
// pipe used by print_sessid to communicate the session id from
|
||||
// the child ttsession to the parent ttsession.
|
||||
int ds_fds[2];
|
||||
|
||||
// Sink for ttsession error output. If 0, output goes to syslog.
|
||||
FILE *errstr = stderr;
|
||||
pid_t child_waited_for;
|
||||
|
||||
//
|
||||
// failed_procs is used to record any forked processes that have
|
||||
// exited. Essentially it is a circular list of pids. Because it is
|
||||
// typically updated inside a signal handler, it cannot use
|
||||
// dynamically allocated memory so it is implemented as a fixed-size
|
||||
// array of pids with two pointers into the array: _tt_s_mp->fin is an
|
||||
// index into the first unset slot in the array. When a child process
|
||||
// exits it's pid is recorded in this slot and the _tt_s_mp->fin index
|
||||
// is incremented. The other index records the last "processed" slot.
|
||||
// It is the last slot that was processed by the notify_start_failure
|
||||
// routine that processes this list of pids. Whenever _tt_s_mp->fin is
|
||||
// not equal to _tt_s_mp->fout then new pids were added to the list
|
||||
// and need to be processed by notify_start_failure. Note that the
|
||||
// indexes wrap around to 0 when they reach MAXPIDS. This means that
|
||||
// if more than MAXPIDS processes are entered into failed_procs before
|
||||
// they are consumed by notify_start_failure then some of the failed
|
||||
// processes won't get handled properly. This event was considered
|
||||
// unlikely but if it starts to happen then a larger value of MAXPIDS
|
||||
// should be chosen.
|
||||
//
|
||||
// (see notify_start_failure, sig_handler, _Tt_s_mp::main_loop, and
|
||||
// _Tt_s_mp::_Tt_s_mp)
|
||||
pid_t failed_procs[MAXPIDS];
|
||||
|
||||
//
|
||||
// Returns diagnosed child exit status, or -1 if we are not convinced
|
||||
// the child exited.
|
||||
//
|
||||
int
|
||||
child_exit_status(pid_t child, _Tt_wait_status status)
|
||||
{
|
||||
if (WIFEXITED(status)) {
|
||||
return WEXITSTATUS(status);
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 2,
|
||||
"child (%d) exited due to signal %d%s" ),
|
||||
child, WTERMSIG(status),
|
||||
WCOREDUMP(status) ?
|
||||
catgets( _ttcatd, 3, 3,
|
||||
" (core dumped)" )
|
||||
: "" );
|
||||
return 1;
|
||||
} else {
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 4,
|
||||
"child (%d) neither exited nor "
|
||||
"was signaled!" ),
|
||||
child );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void install_signal_handler();
|
||||
void notify_start_failure();
|
||||
int init_types();
|
||||
void print_usage_and_exit();
|
||||
char *cmd = (char *)0;
|
||||
char *cargv[MAXARGS];
|
||||
int c;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
int maxfds;
|
||||
Tt_status status;
|
||||
_Tt_wait_status ch_status;
|
||||
int i;
|
||||
|
||||
//
|
||||
// Initialize all the global objects needed.
|
||||
//
|
||||
_tt_global = new _Tt_global();
|
||||
_tt_s_mp = new _Tt_s_mp;
|
||||
_tt_mp = (_Tt_mp *)_tt_s_mp;
|
||||
_tt_s_mp->exit_main_loop = 1;
|
||||
|
||||
//
|
||||
// parse command-line options
|
||||
//
|
||||
|
||||
// used by other objects when they need to print out error
|
||||
// messages to the user.
|
||||
_tt_global->progname = argv[0];
|
||||
setlocale( LC_ALL, "" );
|
||||
_tt_openlog( _tt_global->progname, LOG_PID | LOG_CONS | LOG_NOWAIT,
|
||||
LOG_DAEMON );
|
||||
|
||||
// needed by the getopt call
|
||||
opterr = 0;
|
||||
while ((c = getopt(argc, argv, "A:pa:htvcd:sSXEN")) != -1) {
|
||||
switch (c) {
|
||||
case 'A':
|
||||
// set maximum number of undelivered messages
|
||||
// in ttsession.
|
||||
_tt_s_mp->max_active_messages = atoi(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
// set authorization level
|
||||
option_auth_level = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
// don't fork and exit (which is the default).
|
||||
background_mode = 0;
|
||||
break;
|
||||
case 's':
|
||||
// don't print out any status messages
|
||||
_tt_global->silent = 1;
|
||||
break;
|
||||
case 'v':
|
||||
// print versions and exit
|
||||
_TT_PRINT_VERSIONS((char *)_tt_global->progname)
|
||||
exit(0);
|
||||
case 'c':
|
||||
// process-tree session. Parse the rest of the
|
||||
// command-line arguments as arguments to the
|
||||
// process-tree program. This means that -c
|
||||
// should always be the last ttsession option
|
||||
// used.
|
||||
|
||||
// set up the server session to be a
|
||||
// process-tree session.
|
||||
_tt_mp->initial_session->set_env(_TT_ENV_PROCESS_TREE,
|
||||
(char *)0);
|
||||
// set up buffer of arguments to pass to the
|
||||
// program we're going to fork as the root of
|
||||
// the process-tree
|
||||
for (i=0;argv[optind] && i < MAXARGS; i++, optind++) {
|
||||
cargv[i] = argv[optind];
|
||||
}
|
||||
if (i==MAXARGS) {
|
||||
errno = E2BIG;
|
||||
_tt_syslog( errstr, LOG_ERR, "%m" );
|
||||
exit(1);
|
||||
}
|
||||
cargv[i] = '\0';
|
||||
|
||||
// if no program given then use $SHELL
|
||||
if (! cargv[0]) {
|
||||
cargv[0] = getenv("SHELL");
|
||||
cargv[1] = '\0';
|
||||
}
|
||||
cmd = cargv[0];
|
||||
background_mode = 0;
|
||||
// exit out of command-processing here
|
||||
// (otherwise, getopt will want to reparse the
|
||||
// arguments!)
|
||||
goto endopt;
|
||||
case 'd':
|
||||
// set up an X tooltalk session to the given X
|
||||
// display.
|
||||
if (getenv("DISPLAY") == 0) {
|
||||
_tt_putenv( "DISPLAY", optarg );
|
||||
}
|
||||
_tt_mp->initial_session->set_env(_TT_ENV_X11, optarg);
|
||||
break;
|
||||
case 't':
|
||||
// turn message tracing on.
|
||||
tt_trace_control( 1 );
|
||||
break;
|
||||
case 'p':
|
||||
// set up a process-tree session but rather
|
||||
// than fork a program as the root of the
|
||||
// process-tree, just set up the tooltalk
|
||||
// session and then print out the session id
|
||||
// to stdout. Programs can then manually set
|
||||
// the _TT_SESSION or _SUN_TT_SESSION environment variable to
|
||||
// this value to communicate.
|
||||
_tt_mp->initial_session->set_env(_TT_ENV_PROCESS_TREE,
|
||||
(char *)0);
|
||||
cmd = (char *)0;
|
||||
print_sessid = 1;
|
||||
break;
|
||||
#ifdef OPT_CLASSING_ENGINE
|
||||
case 'E':
|
||||
// turn on use of Classing Engine
|
||||
option_classing_engine = 1;
|
||||
break;
|
||||
#endif
|
||||
case 'X':
|
||||
option_classing_engine = 0;
|
||||
break;
|
||||
case 'N':
|
||||
option_maximize_procids = 1;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
// error or help request.
|
||||
print_usage_and_exit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
endopt:
|
||||
|
||||
if (option_maximize_procids && (_tt_zoomdtablesize() != 0)) {
|
||||
_tt_syslog( errstr, LOG_WARNING,
|
||||
catgets( _ttcatd, 3, 5,
|
||||
"cannot maximize clients because %m"));
|
||||
}
|
||||
// sanity check
|
||||
if (_tt_mp->initial_session->env() == _TT_ENV_LAST) {
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 6,
|
||||
"No scope to manage. Use -c, -p, "
|
||||
"-d, or set $DISPLAY." ));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//
|
||||
// set authorization level to either the command-line option,
|
||||
// the value of $TOOLTALK_AUTH_LEVEL or the default.
|
||||
//
|
||||
if (option_auth_level == (char *)0) {
|
||||
option_auth_level = getenv("TOOLTALK_AUTH_LEVEL");
|
||||
}
|
||||
if (option_auth_level == (char *)0) {
|
||||
_tt_mp->initial_session->set_auth_level(_TT_AUTH_ICEAUTH);
|
||||
} else if (!strcmp(option_auth_level, "unix")) {
|
||||
_tt_mp->initial_session->set_auth_level(_TT_AUTH_UNIX);
|
||||
_tt_s_mp->unix_cred_chk_flag = 1;
|
||||
} else if (!strcmp(option_auth_level, "cookie")) {
|
||||
_tt_mp->initial_session->set_auth_level(_TT_AUTH_ICEAUTH);
|
||||
} else if (!strcmp(option_auth_level,"des")) {
|
||||
_tt_mp->initial_session->set_auth_level(_TT_AUTH_DES);
|
||||
} else if (!strcmp(option_auth_level,"none")) {
|
||||
_tt_mp->initial_session->set_auth_level(_TT_AUTH_NONE);
|
||||
} else {
|
||||
print_usage_and_exit();
|
||||
}
|
||||
|
||||
// check for conflicting options being set.
|
||||
if (background_mode && ! print_sessid &&
|
||||
_tt_mp->initial_session->env() == _TT_ENV_PROCESS_TREE) {
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 7,
|
||||
"Cannot use -S option with -c" ));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
install_signal_handler();
|
||||
|
||||
// set up a pipe which will be used by the child ttsession to
|
||||
// communicate it's session id to the parent ttsession which
|
||||
// will then print that out and then exit. (see SIGTERM case
|
||||
// in sig_handler below).
|
||||
if (print_sessid) {
|
||||
pipe(ds_fds);
|
||||
}
|
||||
|
||||
if (!background_mode || (forked_pid=fork())==0) {
|
||||
// We are here if and only if we are a ttsession process
|
||||
// that will manage a session.
|
||||
|
||||
// set ourselves to be the process group leader
|
||||
// so that our parent's signals won't propagate
|
||||
// down to us.
|
||||
if (!background_mode) {
|
||||
setpgid(0,0);
|
||||
}
|
||||
|
||||
// re-install signal handler
|
||||
install_signal_handler();
|
||||
|
||||
// Call the s_init method for _tt_mp. This will
|
||||
// cause the initial server session to be initiated
|
||||
// (ie. setup for rpc servicing and advertising our
|
||||
// address to tooltalk clients).
|
||||
status = _tt_s_mp->s_init();
|
||||
|
||||
// now we check startup status, if we found another
|
||||
// session running then we return status=2. For other
|
||||
// errors we return status=1. (See auto-start code in
|
||||
// mp_session.cc in _Tt_session::init)
|
||||
switch (status) {
|
||||
case TT_OK:
|
||||
// rpc servicing has been initiated. Now we
|
||||
// can continue the initialization process.
|
||||
// This process is done this way because we
|
||||
// want to set up rpc servicing as soon as
|
||||
// possible so that clients can begin
|
||||
// contacting ttsession (they won't get
|
||||
// replies back until we're done with
|
||||
// initialization but that's ok).
|
||||
|
||||
if (print_sessid) {
|
||||
// write our session id to a pipe that
|
||||
// was set up by our parent.
|
||||
|
||||
sprintf(session_buf,"%s\n",
|
||||
(char *)(_tt_mp->initial_session->address_string()));
|
||||
write(ds_fds[1], session_buf, 255);
|
||||
}
|
||||
|
||||
// initialize ptypes/otypes
|
||||
if (! init_types()) {
|
||||
// init_types() has emitted diagnostic
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// if we are running as a child ttsession then
|
||||
// we're now at a point where we're ready to
|
||||
// start servicing clients so kill off our
|
||||
// parent.
|
||||
if (background_mode) {
|
||||
// now were ready to accept requests so
|
||||
// kill the parent app.
|
||||
kill(getppid(), SIGTERM);
|
||||
}
|
||||
break;
|
||||
case TT_ERR_SESSION:
|
||||
// couldn't initialize because there's already
|
||||
// a ttsession running in our session scope.
|
||||
exit(2);
|
||||
case TT_ERR_NOMP:
|
||||
exit(1);
|
||||
break;
|
||||
default:
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
"_Tt_s_session::s_init(): %d (%s)!",
|
||||
status, _tt_enumname(status));
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
|
||||
// We're running as a parent ttsession, and we will
|
||||
// not be managing a ToolTalk session. Wait for our
|
||||
// child ttsession to either exit or kill us off with
|
||||
// a SIGTERM indicating it's ready.
|
||||
|
||||
if (waitpid(forked_pid, &ch_status, 0) < 0) {
|
||||
//
|
||||
// Our signal handler should have called exit()!
|
||||
//
|
||||
_tt_syslog( errstr, LOG_ERR, "wait(): %m" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// if the wait returns then child ttsession must have
|
||||
// died abnormally. Return the status returned by the
|
||||
// child process.
|
||||
|
||||
if (WIFEXITED(ch_status)) {
|
||||
// An exit status==2 is returned if the child
|
||||
// ttsession already found a session that is
|
||||
// active so we avoid printing out an error
|
||||
// message in this case.
|
||||
int exitStatus = WEXITSTATUS(ch_status);
|
||||
if (exitStatus != 2) {
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 8,
|
||||
"child ttsession exited"
|
||||
" with status %d" ),
|
||||
exitStatus );
|
||||
}
|
||||
exit(exitStatus);
|
||||
} else if (WIFSIGNALED(ch_status)) {
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 9,
|
||||
"child ttsession exited due "
|
||||
"to signal %d%s" ),
|
||||
WTERMSIG(ch_status),
|
||||
WCOREDUMP(ch_status) ?
|
||||
catgets( _ttcatd, 3, 10,
|
||||
" (core dumped)" )
|
||||
: "" );
|
||||
exit(1);
|
||||
} else {
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 11,
|
||||
"child ttsession neither "
|
||||
"exited nor was signaled!" ));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// if we're in a process-tree session then fork the requested
|
||||
// root process (contained in "cmd"). This process will then
|
||||
// be monitored by the signal handler such that if it exits
|
||||
// then the signal handler will also abort the tooltalk
|
||||
// session.
|
||||
//
|
||||
|
||||
if (cmd != (char *)0 &&
|
||||
_tt_mp->initial_session->env() == _TT_ENV_PROCESS_TREE) {
|
||||
int i;
|
||||
switch(forked_pid = fork()) {
|
||||
case -1:
|
||||
_tt_syslog( errstr, LOG_ERR, "fork(): %m" );
|
||||
exit(1);
|
||||
case 0:
|
||||
maxfds = _tt_getdtablesize();
|
||||
for (i = 3; i < maxfds; i++) {
|
||||
close(i);
|
||||
}
|
||||
_tt_restoredtablesize();
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
execvp(cmd,
|
||||
cargv);
|
||||
_tt_syslog( errstr, LOG_ERR, "execvp(): %m" );
|
||||
exit(1);
|
||||
break;
|
||||
default:
|
||||
#if !defined(OPT_BSD_WAIT)
|
||||
child_waited_for = waitpid(-1, 0, WNOHANG);
|
||||
#else
|
||||
child_waited_for = wait3(&ch_status, WNOHANG, 0);
|
||||
#endif
|
||||
if (child_waited_for < 0) {
|
||||
_tt_syslog( errstr, LOG_ERR, "waitpid(): %m" );
|
||||
if (errno == ECHILD) {
|
||||
exit(1);
|
||||
}
|
||||
} else if (child_waited_for == forked_pid) {
|
||||
//
|
||||
// XXX This really cannot happen here,
|
||||
// because we handle SIGCHLD, so this
|
||||
// all happens in sig_handler()
|
||||
//
|
||||
int xstat = child_exit_status(
|
||||
child_waited_for, ch_status );
|
||||
if (xstat >= 0) {
|
||||
exit( xstat );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((! background_mode) && (print_sessid)) {
|
||||
printf("%s\n",
|
||||
(char *)_tt_mp->initial_session->address_string());
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
#ifdef OPT_XTHREADS
|
||||
// Set the global lock. This basically locks out the init_self
|
||||
// thread until it is given permission to proceed. Locks are
|
||||
// given up just before RPC calls and upon thread exits.
|
||||
// Only this initial call should use mutex_lock as opposed
|
||||
// to _tt_global->grab_mutex, because here we do not want
|
||||
// to wait on the condition variable here.
|
||||
|
||||
_tt_global->grab_mutex();
|
||||
|
||||
// Initialize as a client of ourself. Ignore failure.
|
||||
|
||||
xthread_fork((void *(*)(void *)) init_self, NULL);
|
||||
#else
|
||||
_tt_s_mp->init_self();
|
||||
#endif
|
||||
|
||||
//
|
||||
// main service loop. We basically check for any programs we
|
||||
// forked exiting, check for flags set by the signal handler
|
||||
// (_tt_s_mp->exit_main_loop means exit out of rpc servicing,
|
||||
// signal_types_changed means we got a signal to re-read the
|
||||
// types database). If no signal flags were set or programs
|
||||
// exited, then we just invoke the _Tt_s_mp::main_loop method
|
||||
// to service rpc requests.
|
||||
//
|
||||
if (background_mode) {
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 12, "starting" ));
|
||||
// We are in daemon mode, so error output goes to syslog.
|
||||
errstr = 0;
|
||||
}
|
||||
while (1) {
|
||||
_tt_s_mp->exit_main_loop = 0;
|
||||
if (_tt_s_mp->fout != _tt_s_mp->fin) {
|
||||
notify_start_failure();
|
||||
}
|
||||
_tt_s_mp->main_loop();
|
||||
if (_tt_s_mp->xfd == -2) {
|
||||
// X server exited
|
||||
break;
|
||||
}
|
||||
//
|
||||
// exit from main_loop method is the result of
|
||||
// a signal (see sig_handler below)
|
||||
//
|
||||
if (signal_types_changed) {
|
||||
if (init_types()) {
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 13,
|
||||
"have re-read types"));
|
||||
} else {
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 14,
|
||||
"error in types; "
|
||||
"keeping old types" ));
|
||||
}
|
||||
signal_types_changed = 0;
|
||||
}
|
||||
if (signal_toggle_trace) {
|
||||
int was_on = tt_trace_control( -1 );
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
"tt_trace_control( %d )", !was_on );
|
||||
signal_toggle_trace = 0;
|
||||
}
|
||||
if (_tt_s_mp->fout != _tt_s_mp->fin) {
|
||||
notify_start_failure();
|
||||
}
|
||||
}
|
||||
delete _tt_mp;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef OPT_XTHREADS
|
||||
static void init_self()
|
||||
{
|
||||
_tt_s_mp->init_self();
|
||||
xthread_exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// This routine is called whenever _tt_s_mp->fin is not equal to
|
||||
// _tt_s_mp->fout (see comment for failed_procs above). This condition
|
||||
// signals that an asynchronous signal from the system came in telling us
|
||||
// that a child process exited. What we need to do is search the list of
|
||||
// ptypes for ptypes that are in the process of launching (see
|
||||
// _Tt_ptype::launch). If we find one whose start pid matches one of the
|
||||
// pids in the failed_procs array then we invoke the
|
||||
// _Tt_ptype::launch_failed method to arrange for the _Tt_ptype object to
|
||||
// handle this condition. The reason that this launch failure is special
|
||||
// is that a ptype that is in the process of being launched may not have
|
||||
// gotten far enough to launch a process that connects with ttsession so
|
||||
// the only mechanism we have to detect the failure is that the process
|
||||
// exited. What this means is that a process in a ptype's start string
|
||||
// cannot exit until it either connects with ttsession and replies to its
|
||||
// start message or until a process it launches does so.
|
||||
//
|
||||
void notify_start_failure()
|
||||
{
|
||||
// one of the starting ptypes failed to start.
|
||||
// Find which one it was and fail all the
|
||||
// messages waiting for it.
|
||||
// XXX: there should be better data-structure
|
||||
// support so we wouldn't have to iterate
|
||||
// through all the ptypes.
|
||||
_Tt_ptype_table_cursor ptypes;
|
||||
int ptype_found;
|
||||
|
||||
while (_tt_s_mp->fout != _tt_s_mp->fin) {
|
||||
ptypes.reset(_tt_s_mp->ptable);
|
||||
ptype_found = 0;
|
||||
while (!ptype_found && ptypes.next()) {
|
||||
if (failed_procs[_tt_s_mp->fout]==ptypes->start_pid()) {
|
||||
if (ptypes->launching()) {
|
||||
ptypes->launch_failed();
|
||||
ptype_found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
_tt_s_mp->fout++;
|
||||
if (_tt_s_mp->fout == MAXPIDS) {
|
||||
_tt_s_mp->fout = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Install sig_handler as the handler for all the signals it handles.
|
||||
//
|
||||
void
|
||||
install_signal_handler()
|
||||
{
|
||||
_Tt_string err = "_tt_sigset(SIG";
|
||||
if (_tt_sigset(SIGHUP, &sig_handler) == 0) {
|
||||
_tt_syslog( errstr, LOG_WARNING, err.cat("HUP)"));
|
||||
}
|
||||
if (_tt_sigset(SIGTERM, &sig_handler) == 0) {
|
||||
_tt_syslog( errstr, LOG_WARNING, err.cat("TERM)") );
|
||||
}
|
||||
if (_tt_sigset(SIGINT, &sig_handler) == 0) {
|
||||
_tt_syslog( errstr, LOG_WARNING, err.cat("INT)") );
|
||||
}
|
||||
if (_tt_sigset(SIGUSR1, &sig_handler) == 0) {
|
||||
_tt_syslog( errstr, LOG_WARNING, err.cat("USR1)") );
|
||||
}
|
||||
if (_tt_sigset(SIGUSR2, &sig_handler) == 0) {
|
||||
_tt_syslog( errstr, LOG_WARNING, err.cat("USR2)") );
|
||||
}
|
||||
if (_tt_sigset(SIGCHLD, &sig_handler) == 0) {
|
||||
_tt_syslog( errstr, LOG_WARNING, err.cat("CHLD)") );
|
||||
}
|
||||
if (_tt_sigset(SIGPIPE, &sig_handler) == 0) {
|
||||
_tt_syslog( errstr, LOG_WARNING, err.cat("PIPE)") );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Reads in the ptype/otype database from the XDR (or CE) database.
|
||||
// Once the types are read in from the database the types are installed
|
||||
// via the appropiate _Tt_s_mp methods install_ptable and install_otable.
|
||||
// Keep a pointer to the _Tt_typedb structure so we can merge in
|
||||
// more types later on via tt_session_types_load.
|
||||
//
|
||||
int
|
||||
init_types()
|
||||
{
|
||||
Tt_status err;
|
||||
|
||||
#ifdef OPT_CLASSING_ENGINE
|
||||
_Tt_typedb::ce2xdr();
|
||||
#endif
|
||||
_tt_s_mp->tdb = new _Tt_typedb();
|
||||
if (option_classing_engine) {
|
||||
err = _tt_s_mp->tdb->init_ce();
|
||||
if (err != TT_OK) {
|
||||
if (0==getenv("OPENWINHOME")) {
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 15,
|
||||
"$OPENWINHOME not set"));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
err = _tt_s_mp->tdb->init_xdr();
|
||||
switch (err) {
|
||||
case TT_OK:
|
||||
case TT_ERR_NO_MATCH:
|
||||
case TT_ERR_DBCONSIST:
|
||||
case TT_ERR_PATH:
|
||||
break;
|
||||
default:
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
"_Tt_typedb::init_xdr(): %s",
|
||||
_tt_enumname(err));
|
||||
}
|
||||
if (err != TT_OK) {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
_tt_s_mp->install_ptable(_tt_s_mp->tdb->ptable);
|
||||
_tt_s_mp->install_otable(_tt_s_mp->tdb->otable);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Prints out a usage string and exits.
|
||||
//
|
||||
void
|
||||
print_usage_and_exit()
|
||||
{
|
||||
_tt_syslog( errstr, LOG_ERR, "%s%s%s%s%s",
|
||||
catgets( _ttcatd, 3, 16,
|
||||
"\nUsage: ttsession [-a cookie|unix|des][-d display][-spStvhNX" ),
|
||||
#if defined(OPT_CLASSING_ENGINE)
|
||||
"E",
|
||||
#else
|
||||
"",
|
||||
#endif
|
||||
catgets( _ttcatd, 3, 17,
|
||||
"][-c command]\n"
|
||||
" -c [command] start a process tree session, and run command in it.\n"
|
||||
" Subsequent options are passed to command. Default: $SHELL\n"
|
||||
" -p start a process tree session, and print its id\n"
|
||||
" -d display start an X session on display\n"
|
||||
"\n"
|
||||
" -a cookie|unix|des set server authentication level\n"
|
||||
" -s silent. Don't print out any warnings\n"
|
||||
" -S don't fork into the background\n"
|
||||
" -N maximize the number of clients allowed\n"
|
||||
" -t turn on message tracing\n"
|
||||
" -X use XDR databases for static types (default)\n" ),
|
||||
#if defined(OPT_CLASSING_ENGINE)
|
||||
catgets( _ttcatd, 3, 18,
|
||||
" -E use Classing Engine for static types\n" ),
|
||||
#else
|
||||
"",
|
||||
#endif
|
||||
catgets( _ttcatd, 3, 19,
|
||||
"\n"
|
||||
" -v print out version number\n"
|
||||
" -h print out this message\n"
|
||||
"\n"
|
||||
"Signal interface:\n"
|
||||
" kill -USR1 ttsession_pid toggle message tracing\n"
|
||||
" kill -USR2 ttsession_pid re-read static types" ) );
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Global signal handler for ttsession. All signals are handled by this
|
||||
// function (ie. no signal handlers should be defined in any other files)
|
||||
//
|
||||
void
|
||||
sig_handler(int sig)
|
||||
{
|
||||
int intrs = 100;
|
||||
pid_t child_pid;
|
||||
_Tt_wait_status status;
|
||||
|
||||
switch (sig) {
|
||||
case SIGPIPE:
|
||||
// usually the result of a write on a broken tcp
|
||||
// socket. Default action is to ignore it.
|
||||
break;
|
||||
case SIGHUP:
|
||||
break;
|
||||
case SIGCHLD:
|
||||
// a child process has exited. If the process that
|
||||
// exited is the root process of a process-tree
|
||||
// session then we exit. Otherwise, it is possibly a
|
||||
// ptype that we launched so we record its pid in the
|
||||
// failed_procs list (see comment above for
|
||||
// failed_procs).
|
||||
#if !defined(OPT_BSD_WAIT)
|
||||
// XXX: the sysv code should do the same loop as
|
||||
// below.
|
||||
child_pid = waitpid(-1, &status, WNOHANG);
|
||||
#else
|
||||
// we do an asynchronous wait on the child to get its
|
||||
// pid. However the wait3 call can be interrupted and
|
||||
// return an EINTR so we keep trying for a bounded
|
||||
// amount of time.
|
||||
while (((child_pid = wait3(&status, WNOHANG, 0)) == -1)
|
||||
&& errno == EINTR) {
|
||||
if (! intrs--) {
|
||||
_tt_syslog( errstr, LOG_ERR, "wait3(): %m" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // OPT_BSD_WAIT
|
||||
|
||||
// check for the child pid being the root process of a
|
||||
// process-tree id and exit if it is. Otherwise record
|
||||
// the pid in the failed_procs list and set
|
||||
// _tt_s_mp->exit_main_loop to 1 to signal the main
|
||||
// event loop to break out of rpc servicing to handle
|
||||
// this condition.
|
||||
if (child_pid > 0) {
|
||||
int status2exit = child_exit_status(child_pid, status);
|
||||
int isdead = status2exit >= 0;
|
||||
if (isdead) {
|
||||
if (child_pid == forked_pid) {
|
||||
// calling free in a sig handler is a no-no
|
||||
// delete _tt_mp;
|
||||
exit(status2exit);
|
||||
|
||||
}
|
||||
else
|
||||
#ifdef OPT_XTHREADS
|
||||
if(child_pid !=
|
||||
_tt_s_mp->garbage_collector_pid)
|
||||
#endif
|
||||
{
|
||||
failed_procs[_tt_s_mp->fin] = child_pid;
|
||||
_tt_s_mp->fin++;
|
||||
if (_tt_s_mp->fin == MAXPIDS) {
|
||||
_tt_s_mp->fin = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
_tt_s_mp->exit_main_loop = 1;
|
||||
return;
|
||||
}
|
||||
_tt_syslog( errstr, LOG_WARNING, "waitpid(): %m");
|
||||
break;
|
||||
case SIGTERM:
|
||||
// this signal is sent by a forked ttsession when it
|
||||
// is ready to start servicing clients. It is our
|
||||
// signal to exit. For the special case of a "dialin"
|
||||
// session we print out the child session's id.
|
||||
if ((background_mode) && (forked_pid > 0)) {
|
||||
if (print_sessid) {
|
||||
read(ds_fds[0], session_buf, 255);
|
||||
printf("%s", session_buf);
|
||||
}
|
||||
// this is the signal from the forked
|
||||
// ttsession that we should exit.
|
||||
|
||||
exit(0);
|
||||
}
|
||||
// The child ttsession falls through to clean itself up
|
||||
case SIGINT:
|
||||
_tt_syslog( errstr, LOG_ERR,
|
||||
catgets( _ttcatd, 3, 20, "exiting" ));
|
||||
|
||||
// if this is a process tree system, let our kid know
|
||||
// it's time to depart. It's important to allow the
|
||||
// process tree root process to exit beforehand so
|
||||
// that the controlling terminal will get properly
|
||||
// reassigned. Otherwise, the SIGINT will cause the
|
||||
// entire process hierarchy that has the same
|
||||
// controlling terminal to exit (so for example your
|
||||
// shelltool window would die because ttsession was
|
||||
// killed in process-tree mode).
|
||||
|
||||
if (forked_pid > 0
|
||||
&& 0 == kill(forked_pid, SIGINT)) {
|
||||
|
||||
// Wait for a decent interval to give him a chance
|
||||
// to clean up
|
||||
|
||||
int i;
|
||||
for (i=0; i<10; i++) {
|
||||
sleep(1);
|
||||
if (forked_pid ==
|
||||
waitpid(forked_pid, 0, WNOHANG)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i==10) {
|
||||
// Won't go away, eh? Time to get tough.
|
||||
if (0 == kill(forked_pid, SIGKILL)) {
|
||||
waitpid(forked_pid, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
// calling free in a sig handler is a no-no
|
||||
// delete _tt_mp;
|
||||
exit(1);
|
||||
break;
|
||||
case SIGUSR1:
|
||||
// signal to toggle message tracing
|
||||
signal_toggle_trace = 1;
|
||||
break;
|
||||
case SIGTYPES:
|
||||
// signal to reread types database
|
||||
_tt_s_mp->exit_main_loop = 1;
|
||||
signal_types_changed = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
45
cde/lib/tt/bin/tttar/Imakefile
Normal file
45
cde/lib/tt/bin/tttar/Imakefile
Normal file
@@ -0,0 +1,45 @@
|
||||
XCOMM $XConsortium: Imakefile /main/11 1996/05/08 09:28:48 drk $
|
||||
|
||||
#define CplusplusSource YES
|
||||
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
|
||||
EXTRA_LOAD_FLAGS = ExtraLoadFlags $(UNSHARED_CXXLIB)
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#include "../../tooltalk.tmpl"
|
||||
|
||||
DEFINES =
|
||||
INCLUDES = -I. -I../../lib
|
||||
|
||||
DEPLIBS = ../../slib/libstt.a TtClientDepLibs ../../mini_isam/libisam.a
|
||||
LOCAL_LIBRARIES = ../../slib/libstt.a TtClientLibs ../../mini_isam/libisam.a
|
||||
SYS_LIBRARIES =
|
||||
|
||||
#ifdef TtClientExtraLibs
|
||||
EXTRA_LIBRARIES = TtClientExtraLibs
|
||||
#endif
|
||||
|
||||
|
||||
SRCS = \
|
||||
tttar.C \
|
||||
archiver.C \
|
||||
tttar_utils.C \
|
||||
tttar_api.C \
|
||||
tttar_spec.C \
|
||||
tttar_file_utils.C \
|
||||
tttar_string_map.C
|
||||
|
||||
OBJS = \
|
||||
tttar.o \
|
||||
archiver.o \
|
||||
tttar_utils.o \
|
||||
tttar_api.o \
|
||||
tttar_spec.o \
|
||||
tttar_file_utils.o \
|
||||
tttar_string_map.o
|
||||
|
||||
NormalCplusplusObjectRule()
|
||||
|
||||
ComplexCplusplusProgramTarget(tttar)
|
||||
|
||||
SpecialCplusplusObjectRule(archiver,archiver,$(TT_VERSION_DEFINE))
|
||||
11
cde/lib/tt/bin/tttar/admindefines
Normal file
11
cde/lib/tt/bin/tttar/admindefines
Normal file
@@ -0,0 +1,11 @@
|
||||
XCOMM $XConsortium: admindefines /main/2 1996/05/07 19:18:56 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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user