OIF - Object Interchange Format spec
------------------------------------


	The OIF protocol is intended to be as extensible and simple as
possible. OIF consists of two levels, level one deals solely with the
definition of single objects, and level two specifies the protocol used
to transfer objects between MUDs. Level one OIF can also be used to
implement object storage and retrieval.


OIF Level 1 - object definition
-------------------------------

	An object encoded in OIF consists of an object beginning header,
a list of object attributes, and an object ending trailer. EG:

object
 /* attribute list */
endobj

	Individual attributes are stored in printable ascii characters,
each ended with a newline. The attribute is preceeded with a type-specifier
which can be any number of characters of any type except spaces. Following
the type-specifier is the attribute name, also variable-length, ended with
an equals sign '='. The attribute name may NOT contain a slash '/' character
under any circumstances. The remainder of the line after the equals sign is the
attribute data, and is undefined, except that it cannot contain newlines
in it. There is no length limit specified on attribute lines, though it
is acceptable for an implementation to impose one. An attribute looks like:

str name=Jerry Cornelius

	Where "str" is the attribute's data type, "name" is the attribute's
name, and "Jerry Cornelius" is the attributes data. Note that the ending
newline is NOT part of the attribute data. Attribute names must be all alpha
or numeric characters, with case-sensitivity preserved. Attribute types
must also be all alpha or numeric characters, with case-sensitivity
preserved.

	Each named attribute in an OIF object must be unique, IE: there
may be only one "name" attribute in an object, regardless of its type. There
is no specified limit to the number of attributes an object may have,
though a given implementation may impose limits. Since it would be
possible to create an OIF-compliant object that would use all the memory
available on a given machine, implementations should consider checking
for number and size of attributes in some manner. An example OIF object
would look like the following:

object
str name=Jerry Cornelius
obj owner=726@someMUD
str desc=You see a snobby-looking object, gazing aloofly back at you.
cmd peer=@emote "peers down his nose at $1"
endobj

	Object-IDs are encoded in one of 2 forms: local and fully-qualified.
Locally-named objects are represented with just a string of numbers that
represents the integer ID of the object, EG:
81263
	Fully-qualified object-IDs are locally named IDs followed by an
'@' character and the name of the object's home MUD. The name of the home
MUD MUST be a single alphanumeric string with no spaces, tabs, newlines,
etc. The combined length of an object-ID is limited in an implementation
dependent manner, but all OIF implementations are expected to correctly
handle at least 64-character object-IDs. MUD names should be restricted
to 20 characters, maximum.


Discussion of OIF Level 1:
--------------------------

	One important and obvious aspect of OIF-encoded objects is that
there is no encoding of the object's ID in the object itself. This is a
design decision that has advantages and disadvantages, but the advantages
outweigh the disadvantages significantly, as they allow a higher level of
object portability by not hardcoding the object ID into the object. There
is still the issue of hardcoded object IDs in lists that an object may
contain, but within an individual MUD leaving the object ID out of the
object makes it somewhat easier to clone objects within a local MUD.

	Another important consideration in OIF level 1 was the decision
to make attributes unique. It would be quite feasible to permit having
several attributes with different types share the same name, to permit
MUDs to have a variety of different operators tied to a name. This is
not ruled out of future versions, but is not permitted in OIF 1.0 because
it only serves to further complicate the code that figures out what to
do when an objects "ofail" attribute (for example) is invoked. In the
initial 1.0 case, there will be only one "ofail" attribute per object,
so once it is invoked, figuring out what to do is a matter of examining
the type. If there are not only multiple types, but multiple attributes,
the decision criteria become more messy. This is open to change.

	To allow some room for eventual future growth of the protocol,
note the specification that attribute names cannot contain a slash
character. This is to support eventual further encoding information that
may someday be required in attributes - possible uses encompass mode
bits, permissions, etc. IE:

str foo/readonly=This is a readonly string

	Note that at present there is no existing code that uses this
capability, nor is there server support for it. It's simply there in
case it is someday needed.


OIF Level 2 - object transport
------------------------------

	When a server desires to communicate with another, it opens
a connection to the other server in a mode that will cause a timeout
if the connection hangs for a significant time. If the connection
hangs, the entire transaction is considered to be a failure. Further,
at any point during the transaction, either server may sever the
connection, which results in a transaction failure.

	The level 2 OIF transport is even more general purpose, and
consists of 3 parts: (each will be discussed in detail)

Introduction -	The servers establish a connection and identify
	themselves to eachother's satisfaction.
Exchange -	The calling server server exchanges a sequence of
	operations it desires to have executed on the remote server.
	These operations are stored in internal memory on the remote
	server and are not executed immediately, until the entire
	transaction is completed and agreed upon. There is no specified
	limit to the number of sub-commands that may be ordered in
	th transaction, but either side can sever the transaction
	in the middle, if it desires.
Sign-Off -	The calling server notifies the called server that
	it is done. This indicates to the called server that it should
	now "commit" the transaction. The called server may then do
	any amount of checking on the commands sent, and determine
	if it is willing to accept the commands. If it is, it performs
	the requested operations and sends the calling server an OK,
	otherwise it sends an error code, and an optional line of
	error text that may explain more about why the transaction
	failed.


Introduction:
-------------

	When the calling server contacts the server it desires to do
business, it connects to a predefined address (it must know it from
internal data) and subaddress, and sends a message in the form of:

UnterMUD mymudname mymudversion mypassword

	followed by a newline. The "UnterMUD" string is always the same,
and "mymudname" is the name of the calling MUD, "mymudversion" is a
string consisting of a numeric value, and an optional '.' and another
numeric value (EG: "1.3") encoding the version of the software. The
last value "mypassword" occupies the rest of the line and is the password
of the local MUD, encrypted with the password of the MUD that is being
called.
	At this point the called MUD may check the port-of-origin,
password, version, and may optionally sever the connection without any
further explanation at all. If the called MUD is satisfied, it will
reply to the calling MUD with an identical line, except where its
password is the inverse. The calling MUD may opt to disconnect. 
	If neither MUD has disconnected, the introduction is over.


Exchange:
---------

	The calling MUD now sends a sequence of requests to to the called
MUD. At any point the called MUD can simply drop the connection. If the
called MUD does not drop connection, it will read a sequence of requests
until it gets an "ENDTRANS" message. The length of requests is limited to
1024 bytes. Some of the requests are as follows:

OBJECT objectid
	The OBJECT transaction request indicates that the called server
	should read a Level 1 OIF encoded object and store it in temporary
	memory on a transaction list. The object is NOT entered into the
	permanent database at this point, but is saved until the signoff.
	The read object should have the given ID.

LINKTO toobjectid fromobjectid
	The LINKTO request indicates that the called server should check
	permissions to see if an entrance can be linked from toobjectid
	from fromobjectid. The actual request should be stored for
	execution during the signoff. Actual use of the fromobjectid
	is not necessary, but it is included in case it is useful.

ADDTO newobjectid oldobjectid
	Add the new object to the given old object. This is how object
	movement is implemented. First the object and its contents
	are sent across, then finally an order to link it into the
	destination's contents list.

ENDTRANS
	The transaction list is completed. It should now be validated
	and if it is all valid, executed.


Sign-Off:
---------

	The sign-off phase is pretty straightforward. The called server
has completed executing (or failed to validate and execute) the transaction
and now returns a message to the caller, and shuts down the connection.
The returned message is in the form of a single line, no longer than
1024 bytes, consisting of a single return code, and a leftover string that
occupies the rest of the line. The return code is separated with a single
space, and no interpretation is performed on the remainder of the line.
The possible returned messages are as follows:

OK
	The transaction succeeded and all is well.

ERR
	There is an unspecified error message.

EPERM
	Permission denied.


Discussion of OIF Level 2:
--------------------------

	The main issues in developing the level 2 OIF protocol was to make
it as simple as possible, and to prevent the servers from blocking. The
commit protocol actually admits the possibility of objects becoming
duplicated through a network error. This is life. To make the best use
of buffering inherent in TCP/IP, there is no attempt to validate each
part of the transaction as it is sent - a simple stream of commands is
sent, and if the whole stream is OK, it is executed. The protocol is
designed to make it as easy as possible to add new commands, and the
inclusion of a version number is intended to help with this.

mjr. '91