This document specifies version 11 of LysKOM Protocol A. This is edition 11.0 of the specification. It corresponds to version 2.1.0 of lyskomd.
The most up-to-date version if this document can always be found at http://www.lysator.liu.se/lyskom/protocol/.
Copyright © 1995-2003 Lysator ACS.
Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies.Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original.
Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions.
LysKOM is a conferencing system1. Similar systems were QZ-KOM and PortaCOM2. The LysKOM system is copyrighted by Lysator Academic Computing Society and distributed under conditions of the GNU Public License. LysKOM and its documentation is provided "as is" without warranty of any kind.
Anything described here as "unspecified" is liable to change in future protocol versions.
This specification is the work of several people. The main contributors have been Per Cederqvist ceder@lysator.liu.se, David Byers byers@lysator.liu.se, Pär Emanuelsson pell@lysator.liu.se, Thomas Bellman bellman@lysator.liu.se, Lars Aronsson aronsson@lysator.liu.se, Linus Tolke linus@lysator.liu.se and Kent Engström kent@lysator.liu.se.
The LysKOM developers can be reached by email to
lyskom@lysator.liu.se. If you find any errors in this
document, please report them at
http://bugzilla.lysator.liu.se/. Use lyskomd
as the
product, and documentation
as component.
This chapter introduces the concepts used in LysKOM, such as articles, conferences and sessions.
An article is represented as a value of the type Text-Stat
and a
string containing the article contents. An article will usually have one
or more recipients and may be a comment or footnote to other articles.
Each article is kept in the database until it is older than the
nice
value of each of its recipients and it is not marked by any
user.
There is an array of Misc-Info
included in the
Text-Stat
. This array contains information about recipients,
senders, comments and footnotes.
Each article is identified by a number, the global3
article number (the Text-No
). Global numbers are assigned in
ascending order to new articles, and are never reused. If an article
has recipients it will also have a local number for each recipient
(the Local-Text-No
). Local numbers are used in some data
structures to provide more compact storage and to provide an ordering
of articles for a particular recipient. Local numbers are assigned in
ascending order and are never reused for a particular recipient,
though different recipients will have articles with the same local
numbers.
Occasionally it is necessary to map between local and global numbers.
The server call local-to-global
does this.
Conferences hold articles. They are represented in the protocol as a
data type called Conference
. Each conference has a
creator, the person who created the conference, and a
supervisor, a conference whose members can modify the conference.
If the supervisor is a person, the members of that person's mailbox
are supervisors, which in most cases is only that person. Persons are
a special case: in addition to those who are supervisors for a certain
person because of the supervisor
field, the person is always a
supervisor of himself. There is one exception to this special case:
the person cannot use set-supervisor
to change who is his
supervisor.
We have also introduced a type called UConference
(pronounced
micro-conf-stat) which holds a subset of the information contained in
the full Conference
type. Use the UConference
type
whenever possible since it places a much smaller load on the LysKOM
server.
Each conference has a type, which is essentially a collection of
boolean flags. Currently the flags rd-prot
,
letterbox
, secret
, original
,
allow-anonymous
and forbid-secret
are defined.
rd-prot
original
super-conf
instead. This
restriction is not enforced by the server; clients must implement this
functionality. (See Recipients of comments, for a summary of how
a client should select the recipients of a comment.)
letterbox
secret
allow-anonymous
forbid-secret
Persons are represented in the protocol by values of the type
Person
. Associated with persons are statistics, a set of personal
flags and a set of privileges (see Security). Persons are also
associated with a conference that has the same number as the person and
the letterbox
bit set.
Connections to the server are represented as values of the type
Static-Session-Info
, Session-Info-Ident
or
Session-Info
. Sessions have session number that are unique for
each session in the lifetime of the server execution. A single user can
have several sessions running at once. The session is not released until
the network connection is closed; a user can log in and out repeatedly
in a single session.
The Misc-Info
list contains tagged data. The fields are sent in
groups pertaining to a particular type of information: information about
recipient; carbon copy recipient; blank carbon copy recipient;
comment to; footnote to; comment in
and footnote in. The information groups may be sent in any order and
there may be any number of groups. Within each group the elements are
always sent in the order listed below.
recpt
loc-no
recpt
field.
rec-time
sent-by
sent-at
The carbon-copy recipient group is identical to the recipient group above. The difference is how new comments to an article with a recipient or carbon-copy recipient are treated. A comment to an article is sent to all recipients, but not to carbon-copy recipients of the original article. This difference is enforced by the clients.
cc-recpt
loc-no
cc-recpt
field.
rec-time
sent-by
sent-at
The blank carbon-copy recipient group is identical to the carbon-copy recipient group above. The difference is the visibility of the information. A carbon-copy recipient group is visible to anyone that is allowed to fetch both the text status of the involved text and the conference status of the involved conference. (That is, as long as the conference isn't secret everybody is allowed to see the carbon-copy recipient group.)
A BCC recipient group is basically only visible to members and supervisors of the recipient. Persons that have the right to become a member of the recipient can also see it, as can the author of the text (unless the recipient is secret to him). This is enforced by the server.
This type of group was introduced in protocol version 10. When
old-style calls such as get-text-stat-old
are used this will be converted to a CC recipient group by the server
for the benefit of clients that don't understand this group. (This
conversion will of course only be performed when the user is allowed
to se the blank carbon copy.)
bcc-recpt
loc-no
bcc-recpt
field.
rec-time
sent-by
sent-at
comm-to
sent-by
sent-at
footn-to
sent-at
comm-in
footn-in
The aux-item list is used as a generic extension mechanism in the LysKOM server and in protocol A.
Aux-items were introduced in protocol version 10 as a mechanism for extending the conference, text and server information structures without changing the protocol. (There is no need for aux-items on persons - just add an aux-item to the corresponding mailbox.)
The exact structure of an aux item is specified elsewhere
(see Auxiliary Information). The important fields here are the
aux-no
, tag
and data
fields.
The aux-no
field is used to identify an item. The
aux-no
together with a text or conference number uniquely
identifies a particular aux item. Items are numbered from one and up
within each item list. Once assigned, the aux-no
for an item
is never changed. New items are guaranteed to be assigned numbers that
have never been used before within a particular list.
The tag
field identifies the type of aux item. It is used by
the server and by clients to figure out how to interpret the data
field, and by the server to decide if the item needs special
treatment.
The data
field is a simple string. The meaning of the string
is determined by the tag
field, but since it is a string,
clients that have no understanding of the contents can successfully
parse the item anyway (in contrast to items in the misc-info list.)
An aux item that is placed on a text can be inherited. This means
that if a comment or footnote to the text is created, an almost
identical item will be created on the new text. The tag
,
creator
, flags
and data
field will be
inherited unchanged. The aux-no
might be given a different
value. A non-zero inherit-limit
field will be decremented.
The created-at
timestamp will be set to the time when the new
comment or footnote is created.
Inheritance only happens at text creation time. If a comment or
footnote link is added later with add-comment
or
add-footnote
, no items will be inherited. Also, if the link
is removed (via sub-comment
or sub-footnote
), the
inherited items will still be in place.
Inheritance only happens when the inherit
bit is set, and if
inherit-limit
is 0 or greater than 1. See Auxiliary Information, for more information.
Inheritance has no meaning for items placed on the server or on a conference.
It is possible for a predefined aux-item to behave in a way that isn't consistent with the description in this section. The documentation for the specific aux-item should document any deviations.
Predefined Aux-Item types are part of Protocol A, and clients should support all of them. As with other parts of the protocol, changes to these definitions will be made backwards-compatible, if possible.
Creation and deletion of items with a predefined type can cause arbitrarily complex and wondrous behavior in the server. Furthermore, the server may place constraints on the items with regard to content, flags, who can create them, to what objects they can be attached and so forth. The server may also silently enforce specific values for any field of an item, regardless of what the client requests.
All items with tags in the range 1-9999 and 30000 and up are considered
predefined. If a client attempts to create an item with a tag in this
range, but the server has no idea what that tag means, the server will
return an error (illegal-aux-item
).
Some items with tags in the range 10000-19999 are also predefined. They are items that initially were reserved for private use for a specific client, but where it was later discovered that the tag was generally useful. They should ideally have been assigned a number in the 1-9999 range from the beginning, but if they already have a widespread use they can be redefined to be predefined. Such redefinition will always be made in cooperation with the client writer.
See Aux-Item Types, for the complete list of predefined Aux-Item types.
Client-specific items do not cause the server to perform any magic. All the flags (except the delete flag) are left untouched, the data is not validated in any way, and anyone can create any item. If you need more server support than this, your item should be on the predefined list.
All tags in the range 10000-19999 are reserved for clients. Blocks of 100 numbers at a time can be assigned to specific clients. A client should never create items with tags in a range assigned to another client or in an unassigned range. Assigned ranges will never change, except that specific aux-items may be redefined as predefined, as explained in Predefined Aux-Item Types.
Currently, the following ranges are assigned to clients:
If you want a range of numbers, send e-mail to the LysKOM development group, or request it via Bugzilla.
Experimental numbers are free for all. Use 'em any way you want. All numbers in the range 20000-29999 are for experimental use.
If you want a new predefined item type, just document what it does, what the data format looks like and what the server is to do with the item and send this to the LysKOM development group. We'll assign a number to your item and put the documentation in this document.
If you're not sure what you want the data to look like yet, make a note in your documentation that the data format might change. Once you have a data format you're happy with, update the documentation so others may use your item.
If you need serious magic in the server (more than can be specified with the lyskomd configuration file), you'll probably have to write the code yourself, or hope that the development group thinks your idea is so cool we do the job for you.
The idea is not to reject any type of item, unless there's already an item type that does the job just as well. Adding item types should be a much less painful process than adding new calls.
Security in LysKOM is based on two components. Each person has a set
of privileges and each session has a security level. Rights in the
system require both the sufficient privileges and a sufficient
security level. The privileges currently available are wheel
,
admin
, statistic
, create-conf
, create-pers
and change-name
. Security levels range from 0 to 255.
wheel
admin
statistic
create-conf
create-pers
change-name
Persons' memberships in conferences are represented in the protocol as
arrays of Membership
-typed values. This structure contains
information about how and when the membership was created and which
texts have been read in the conference.
There are two kinds of memberships. An active membership indicates that the person is actively participating in the conference, wants to know if there are unread texts and wants to receive messages send to the conference. A passive membership is similar to no membership at all. The person is still a member but will not receive messages sent to the conference and will not be notified when there are new texts. From the user's perspective, passive membership should be like no membership at all, but the server still remembers what the user has read in the conference while he or she was an active member. Since protocol version 10 a bit in the membership type field of the membership structure indicates the type of membership. Previously the server did not support passive memberships, but there was a convention that clients should treat the priority level zero as a passive membership.
The membership record indicates which texts have been read through the
read-ranges
field, which contains a list of ranges of local
text numbers that has been read.
Finding out which articles a person has read in a particular conference requires a few calls. Normally, a client will retrieve a batch of perhaps 50 articles at a time. The outline of the process is as follows:
read-ranges
.
local-to-global
to translate a number of local
numbers to global numbers.
read-texts
from the result.
The process is complicated because of the translation between local
and global text numbers. If the server does not implement the
local-to-global
call, it is possible to use the less
efficient but perfectly serviceable get-map
call
instead.
The data types in protocol A come in two flavors. The first (vanilla) are the simple data types from which the LysKOM (chocolate) data types are built. Simple data types include things like integers and strings while complex data types include things such as conferences and people.
This specification uses a BNF-like grammar to describe the protocol and its data elements.
Data fields have been given names that start with a lower-case letter.
Fundamental data types have names in all-caps (such as INT32
and
ARRAY
).
Derived data types have names that start with an upper-case letter. (If
the type contains more than one word, all words start with an upper-case
letter, like this: Text-Stat
.) The operator ::=
defines
the name to its left.
Comments start with !
(exclamation mark) and alternatives are
separated by a |
(vertical bar.) A ;
(semicolon)
terminates statements in the grammar. In some specifications there are
literal strings. There is to be no whitespace before or after literal
strings unless there is whitespace in the literal itself.
INT32
, INT16
, INT8
and BOOL
are non-negative
integers which must fit in 32, 16, 8 and 1 bits, respectively. They are
transmitted to the server in ASCII-encoded decimal notation.
FLOAT
are floating point numbers. They are represented as if
printed via printf("%g", val);
in C. See 7.19.6.1 The
fprintf function in ISO/IEC 9899:1999 Programming languages -
C for the details. See The %g conversion, if you don't
have the C standard handy.
HOLLERITH
denotes character strings of arbitrary length. They are
transmitted as nHtext
where text is the string and
n is the number of characters in text in decimal
notation. All byte values are allowed in the string itself, including
nulls.
Long live FORTRAN!
The character set used in the strings is not yet specified by Protocol A. In the future, some Unicode encoding will probably be used, but it is not yet decided which one or how the transition will be handled. Bug 99 is about the need for a Unicode roadmap; check that bug for the current state of the plans.
For now, which character set to use is a local policy of each server
installation. There is not yet any way in the protocol to specify the
character set that a certain server uses. Most clients currently
assume that ISO 8859-1 (Latin-1) is used, and the default collate
table of lyskomd also assumes ISO 8859-1. Conference names must
currently use an 8-bit character set encoding where whitespace is
defined as in ASCII, or conference matching won't work.
get-collate-table
contains some more information about
character set issues.
BITSTRING
is a string of bits, commonly used for a set of
boolean-valued flags. Bit strings are denoted as
BITSTRING ( name-1; name-2; name-3; ... )
in this specification. They are transmitted as a sequence of ASCII ones and zeroes in the order the fields are listed.
For instance, given the specification
shape-of-world ::= BITSTRING ( is-flat; is-round; is-2d; is-3d; )
most peoples idea of shape-of-world
would be sent as 0101
(round and three-dimensional.)
ENUMERATION
is an integer constant. It is transmitted as an INT32,
but only fixed values are permitted. Clients should be prepared to
receive numbers outside the enumeration and either handle this
gracefully as an error or use a reasonable default value in place of an
invalid enumeration value.
An enumeration is specified as
ENUMERATION ( name-1=value-1; name-2=value-2; name-3=value-3; ... )
This specification states that name-1 is represented by the integer value-1, name-2 is represented by value-2 and name-3 is represented by value-3.
An enumeration can also be inherited from a SELECTION data type:
Info-type ::= ENUMERATION-OF(Misc-Info)
This means that Info-type is an enumeration, that contains the same keys and values as the SELECTION Misc-Info.
For example, in the following specification, the constant guwal will be
transmitted as the integer 2, ciokwe as the integer 3, and hopi as the
integer 5.
language ::= ENUMERATION ( hakka = 1; guwal = 2; ciokwe = 3; yoruba = 4; hopi = 5; )
ARRAY
is a list of a fixed number of elements of a single type.
The specification for an array is ARRAY type
where
type is the type of the array elements.
Arrays are transmitted as an n { element
element ... }
where n is the number of elements and
each element is an element of the array. A special case is when
the array is empty, in which case the server transmits it as 0 *
.
Note that the client must always transmit empty arrays as 0 {
}
.
In some calls the client can ask the server not to send the array
contents, only its length. In these cases the array is transmitted as
n *
where n is the number of elements in the array.
SELECTION
is tagged data. It consists of an INT32 selector
followed by a tail of an arbitrary type and is specified as
SELECTION ( n=name tail : type; n=name tail : type; ... )
where each n is the selector value, name the selector
name and tail the name of the selector tail and type
its type. name and tail are often very similar, such
as sent-by
and sender
.
When transmitted, the selector is transmitted as an INT32 followed by
the tail belonging to that selector. For instance, given the
specification
description ::= SELECTION ( 1=name the_name : HOLLERITH; 2=age years : INT32; )
two legal messages of the type description
are 1
4HJohn
and 2 18
.
RPC
is a notation used to specify calls to the server. An RPC
specification has the following form:
RPC ( call [n] ( request ) -> ( reply ) ; call [n] ( request ) -> ( reply ) ; )
where each call is the name of a call, n is the call number, request is a single data element sent as a request and reply is a single data element sent in reply from the server.
RPC calls are transmitted as n request where n and request have the same meaning as above. Note that in the client-server dialog a reference number must also be supplied with each request. This reference number is not part of the RPC itself, but is required for communications; see Client-Server Dialog.
Structures are collections of several data items. In the specification
they are written as
( name : type ; name : type ; ... )
where each name is the name of a data field and the corresponding type is its type.
Structures are transmitted as a sequence of their fields.
The client-server dialog consists of two phases, establishing the connection and the LysKOM session itself.
A connection to the server is initiated by connecting to the appropriate
network port6 and
sending a single letter which is used to select a protocol version.
This letter should always be A
7.
The protocol version letter should be
followed by connection information required by that protocol. In
protocol A the connection information is a HOLLERITH
string saying who
the user connecting is followed by a linefeed character.
The format of the string should be username % hostname
.
When the server has accepted the connection it replies with the string
LysKOM
on a single line.
% telnet kom.lysator.liu.se 4894 Trying 130.236.254.151 ... Connected to varg.lysator.liu.se. Escape character is '^]'. A26Hbyers%kajsa.lysator.liu.se LysKOM
Besides the string LysKOM
, the server may respond with
%%LysKOM unsupported protocol.
or %% No connections left.
.
The %%LysKOM unsupported protocol.
reply is sent if the server
does not understand the requested protocol, that is, if the first
character is anything but an A
. The connection will be closed
by the server as soon as this string has been sent.
The %% No connections left.
reply is sent if the server is not
accepting additional connections. This error is transient. The next
connection attempt may succeed. Clients should wait a few seconds before
attempting to make another connection after receiving this error.
The connection will be closed by the server as soon as this string has
been sent.
After connecting (see Connecting to the Server), calls to the
server can be made. Most calls require
the user to log in, but some calls can be made without a log-in. Calls
to the server are made by sending a reference number followed by the
call as specified. The call must be terminated with a linefeed
character (ASCII 0x0A).
server-call ::= ( ref-no : INT32; request : Protocol-Request; )
The client may send several requests without waiting for the replies. However, the server will only buffer a limited amount of replies, so the client must check for pending replies from the server at least each time it sends requests to the server.
At some future point the server will reply with the result of the
request or an error code preceded by an indicator and the reference
number. The replies will be sent in the same order as the
requests8.
server-reply ::= ok-reply | error-reply | protocol-error; ok-reply ::= ( "=" ref-no : INT32; reply-data; ) error-reply ::= ( "%" ref-no : INT32; error-code : INT32; error-status : INT32; ) protocol-error ::= "%% LysKOM protocol error." | "%%Insane token length." | "%%Insane array size."
Our notation is not flexible enough to specify the two-way nature of
the communication. ref-no
in the reply is always the same as
ref-no
in the corresponding request. reply-data
depends on which request was made and is specified together with each
request.
Note that there is no whitespace after the initial indicator in the reply.
Data elements sent from the client to the server are separated by one or more space characters (ASCII 32). An entire call is terminated by a linefeed character (ASCII 10).
Earlier versions of the protocol specified that data elements could be
separated by any number of linefeed (ASCII 10), return (ASCII 13), tab
(ASCII 9) or space (ASCII 32) characters. Servers should be forgiving
and understand requests using the older conventions, but clients must
conform to the current convention of separating data elements with
spaces and terminating all requests with a linefeed character. The
not-implemented
error code will not be returned properly
unless the client follows this requirement.
The server may return two different types of errors. Normal
error-reply
errors are replies to syntactically correct calls
to the server, while protocol-error
are replies to syntactically
incorrect calls. See Protocol Error Messages, for more information
about protocol-error
.
If a call cannot complete successfully, LysKOM will respond with an
error-reply
. The meaning of error-code
and
error-status
varies depending on the request; see Error Codes, and the documentation for each call, for a list of available
error-code
values and what they mean.
A client should be prepared for any error code in response to any
call, no matter if the response makes any sense or not. The value
returned in error-status
was more or less undefined before
protocol version 10. For protocol version 10 or newer, the meaning of
error-status
is defined in this document.
The meaning of error-status
can be modified by any call. In
particular the calls that deal with Misc-Info lists set
error-status
to the index of the misc item that caused the error
(if the error was caused by a misc item.)
Client should handle the error messages listed with each call in a
graceful manner. In addition, the following error types should always
be handled gracefully: temporary-failure
,
internal-error
, feature-disabled
,
not-implemented
, obsolete-call
,
ldb-error
,
out-of-memory
. Client should also be able to handle any
error in any situation without choking completely since bugs might
cause the wrong error message to be sent or new errors might be added
later on.
The server may send asynchronous messages (see Asynchronous Messages) to the client at any time (but not in the middle of a
reply). Two important asynchronous messages are
async-new-text
(see async-new-text) and
async-send-message
(see async-send-message).
Protocol error messages are sent in reply to syntactically incorrect calls to the server. These should never appear in the client-server dialog. If they do, there is probably a bug in the client.
In this section the data types specific to LysKOM are defined. Most of these will probably make very little sense until you know what calls there are. This section does not include the server calls or asynchronous messages, even though these are also data types.
Since the types defined here are all based on the simple types, the definitions are more concise in this section.
The types defined in this section are fairly simple and used in many of the more complex data types.
Time ::= ( seconds : INT32; minutes : INT32; hours : INT32; day : INT32; month : INT32; year : INT32; day-of-week : INT32; day-of-year : INT32; is-dst : BOOL; )
Time
is used to specify times in several data structures. The
fields seconds
, minutes
and hours
give wall clock
time. day
is the day of month and month
is the current
month, starting with zero for January. year
is the number of
years since 1900. day-of-week
is the current weekday, with zero
used for Sunday. day-of-year
is how many days of the year have
passed starting with zero and is-dst
is true when the time
indicated is daylight savings time.
When the server receives a Time
structure from a client it
ignores the day-of-week
and day-of-year
fields.
All times are expressed in the time zone of the server, unless the
set-connection-time-format
request is used.
Conf-No ::= INT16;
This type denotes a conference number.
Text-No ::= INT32; Local-Text-No ::= INT32; Text-List ::= ( first-local-no : Local-Text-No; texts : ARRAY Text-No; )
These three types are used to indicate articles in the LysKOM database.
Text-No
is a global text number and Local-Text-No
a local
text number. Text-List
is used when a mapping from local to
global numbers are required.
Pers-No ::= Conf-No; Session-No ::= INT32;
Pers-No
is used to indicate a person. Session-No
is used
in a few data structures relating to information about active LysKOM
sessions.
Aux-No ::= INT32; Aux-Item ::= ( aux-no : Aux-No; tag : INT32; creator : Pers-No; created-at : Time; flags : Aux-Item-Flags; inherit-limit : INT32; data : HOLLERITH; ) Aux-Item-Input ::= ( tag : INT32; flags : Aux-Item-Flags; inherit-limit : INT32; data : HOLLERITH; ) Aux-Item-Flags ::= BITSTRING ( deleted; inherit; secret; hide-creator; dont-garb; reserved2; reserved3; reserved4; )
Aux-Item-Input contains a subset of the fields of an Aux-Item. It is used when the client wants to send an Aux-Item to the server, and it only contains the elements that the client can affect. The fields in Aux-Item and Aux-Item-Input have the following meaning:
aux-no
modify-system-info
request, and when using that request
the aux-no
is enough to uniquely identify the aux-item.)
This field is not present in Aux-Item-Input
. It is assigned by
the server.
tag
creator
This field is not present in Aux-Item-Input
. It is assigned by
the server.
created-at
This field is not present in Aux-Item-Input
. It is assigned by
the server.
flags
inherit-limit
data
The flags that can be set on an aux-item have the following meaning:
deleted
inherit
secret
hide-creator
dont-garb
Conf-Type ::= BITSTRING ( rd-prot; original; secret; letterbox; ) Extended-Conf-Type ::= BITSTRING ( rd-prot; original; secret; letterbox; allow-anonymous; forbid-secret; reserved2; reserved3; ) Any-Conf-Type ::= Conf-Type | Extended-Conf-Type;
These types are used to specify the type of a conference.
Conf-Type
is used in data types and calls that were created
before version 8.0 of the protocol and has been augmented in
Extended-Conf-Type
. The type Any-Conf-Type
is used when
either is admissible.
The bits have the following meaning (see Conferences, for more info.)
rd-prot
original
secret
letterbox
allow-anonymous
forbid-secret
reserved2
reserved3
Conf-Z-Info ::= ( name : HOLLERITH; type : Conf-Type; conf-no : Conf-No; )
These types are used for the result of some calls that search for conferences based on their names.
Garb-Nice ::= INT32; Conference-Old ::= ( name : HOLLERITH; type : Conf-Type; creation-time : Time; last-written : Time; creator : Pers-No; presentation : Text-No; supervisor : Conf-No; permitted-submitters : Conf-No; super-conf : Conf-No; msg-of-day : Text-No; nice : Garb-Nice; no-of-members : INT16; first-local-no : Local-Text-No; no-of-texts : INT32; ) Conference ::= ( name : HOLLERITH; type : Extended-Conf-Type; creation-time : Time; last-written : Time; creator : Pers-No; presentation : Text-No; supervisor : Conf-No; permitted-submitters : Conf-No; super-conf : Conf-No; msg-of-day : Text-No; nice : Garb-Nice; keep-commented : Garb-Nice; no-of-members : INT16; first-local-no : Local-Text-No; no-of-texts : INT32; expire : Garb-Nice; aux-items : ARRAY Aux-Item; ) UConference ::= ( name : HOLLERITH; type : Extended-Conf-Type; highest-local-no : Local-Text-No; nice : Garb-Nice; )
These three types are used to specify information about a conference.
Garb-Nice
is a quantity used to specify how long articled are
kept in a conference before being removed. Conference
is the full
information about a conference and UConference
is brief
information about a conference.
The fields of Conference
are
name
type
creation-time
last-written
creator
presentation
supervisor
permitted-submitters
super-conf
original
bit is
set, clients should send comments to this conference
(see Recipients of comments). If the permitted-submitters
field rejects a text11, the
server will silently send the text to the super-conf
conference instead. This redirection mechanism is applied repeatedly
until conference that accepts the text is found, or an
implementation-defined limit is reached.
msg-of-day
nice
keep-commented
no-of-members
first-local-no
no-of-texts
expire
aux-items
The fields of UConference
are
name
type
Conference
.
highest-local-no
nice
The result of request number 12, lookup-name, cannot be expressed in the
grammar used in this document. This is as close as it gets:
Conf-List-Archaic ::= ( conf-nos : ARRAY Conf-No; conf-types : ARRAY Conf-Type; ! Sans n; see below )
The two arrays conf-nos
and conf-types
are always the same
size. For some obscure reason the size of the second array is not
actually transmitted. See also the example in lookup-name.
Text-Mapping ::= ( range-begin : Local-Text-No; range-end : Local-Text-No; more-texts-exists : BOOL; block : Local-To-Global-Block; ) Local-To-Global-Block ::= SELECTION ( 0=sparse sparse-block : ARRAY Text-Number-Pair; 1=dense dense-block : Text-List; ) Text-Number-Pair ::= ( local-number : Local-Text-No; global-number : Text-No; )
A Text-Mapping
is used when the client needs to look up which
global Text-No
that corresponds to a Local-Text-No
. The
client uses local-to-global
to ask for information about a few
texts starting a a certain local text number, and the server returns the
information in a Text-Mapping
.
range-begin
Text-Mapping
says anything
about.
range-end
Text-Mapping
tells the client about all existing texts from
range-begin
to (but not including) range-end
.
more-texts-exists
local-to-global-reverse
which
searches backwards, this will instead be true if there are more texts
before this block.
block
0
that indicates that the sparse format
is used, and is followed by an array of Text-Number-Pair
. The
array will always be sorted so that local-number
always
increases.
1
that indicates that the dense format
is used, and is followed by a Text-List
. The Text-List
contains first-local-no
and an array of Text-No
.
The local text number first-local-no
corresponds to the first
Text-No
in the array, first-local-no
+ 1 corresponds to
the second entry in the array, and so on. The array contains a zero to
indicate that a certain local text number doesn't exist.
Info ::= ( version : INT32; conf-pres-conf : Conf-No; pers-pres-conf : Conf-No; motd-conf : Conf-No; kom-news-conf : Conf-No; motd-of-lyskom : Text-No; aux-item-list : ARRAY Aux-Item; ) Info-Old ::= ( version : INT32; conf-pres-conf : Conf-No; pers-pres-conf : Conf-No; motd-conf : Conf-No; kom-news-conf : Conf-No; motd-of-lyskom : Text-No; ) Version-Info ::= ( protocol-version : INT32; server-software : HOLLERITH; software-version : HOLLERITH; ) Static-Server-Info ::= ( boot-time : Time; save-time : Time; db-status : HOLLERITH; existing-texts : INT32; highest-text-no : Text-No; existing-confs : INT32; existing-persons : INT32; highest-conf-no : Conf-No; )
These data types contain information about the LysKOM server. The fields
of Info
and Info-Old
are:
version
10607
is
version 1.6.7 of the server. If greater than 10699 the
get-version-info
should be used instead.
conf-pres-conf
pers-pres-conf
motd-conf
kom-news-conf
motd-of-lyskom
aux-item-list
Info-Old
.) A list of aux-items that belong to
the server.
The fields of Version-Info
are:
protocol-version
server-software
software-version
The Static-Server-Info
contains information about the state of
the server when it started. It contains the following fields:
boot-time
save-time
db-status
clean
(if the
previous invocation of the server was shut down cleanly) or
backup
(which means that some information may have been lost in
the last restart). Clients should be prepared to find other values
here.
existing-texts
get-stats
call with
what
set to texts
.)
highest-text-no
first-unused-text-no
and find-previous-text-no
calls.)
existing-confs
get-stats
call with what
set to
confs
.)
existing-persons
get-stats
call
with what
set to persons
.)
highest-conf-no
first-unused-conf-no
and find-previous-conf-no
calls.)
Person ::= ( username : HOLLERITH; privileges : Priv-Bits; flags : Personal-Flags; last-login : Time; user-area : Text-No; total-time-present : INT32; sessions : INT32; created-lines : INT32; created-bytes : INT32; read-texts : INT32; no-of-text-fetches : INT32; created-persons : INT16; created-confs : INT16; first-created-local-no : INT32; no-of-created-texts : INT32; no-of-marks : INT16; no-of-confs : INT16; ) Personal-Flags ::= BITSTRING ( unread-is-secret; flg2; flg3; flg4; flg5; flg6; flg7; flg8; ) Priv-Bits ::= BITSTRING ( wheel; admin; statistic; create-pers; create-conf; change-name; flg7; flg8; flg9; flg10; flg11; flg12; flg13; flg14; flg15; flg16; )
These types are used to specify information about persons. Person
contains the information about a person, Personal-Flags
contains
flags set by the user and Priv-Bits
contains the person's
privileges (see Security).
The fields of Person
are
username
privileges
flags
last-login
user-area
total-time-present
sessions
created-lines
created-bytes
read-texts
no-of-text-fetches
created-persons
created-confs
first-created-local-no
no-of-created-texts
first-created-local-no
+ no-of-created-texts
- 1.
no-of-marks
no-of-confs
The fields of Personal-Flags
are
unread-is-secret
read-ranges
field of Membership
(and
read-texts
, last-time-read
and last-text-read
fields of Membership-10
and Membership-Old
) when other
persons asks about the information.
flg2
flg3
flg4
flg5
flg6
flg7
flg8
Membership-Type ::= BITSTRING ( invitation; passive; secret; passive-message-invert; reserved2; reserved3; reserved4; reserved5; )
The Membership-Type
type contains flags that modify a membership.
It is passed as part of both Member
and Membership
(and
obsolete versions of those types).
The flags are:
invitation
passive
passive-message-invert
.
secret
passive-message-invert
passive
bit is inverted when checking
for messages (see async-send-message) to this conference. In
other words, messages are blocked if one (but not both) of the bits
passive
and passive-message-invert
are set.
The remaining flags in the Membership-Type
structure are reserved
and should be set to false on all new memberships and retained on all
existing memberships.
Member ::= ( member : Pers-No; added-by : Pers-No; added-at : Time; type : Membership-Type; )
The Member
structure encodes information about a member in a
conference. It is returned by the get-members
call. The
fields of a Member
structure are
member
added-by
added-at
type
The contents of a Member
structure can be cleared (all fields set
to zero) if the person requesting the record has insufficient privileges
to see the contents of the structure.
Read-Range ::= ( first-read : Local-Text-No; last-read : Local-Text-No; ) Membership ::= ( position : INT32; last-time-read : Time; conference : Conf-No; priority : INT8; read-ranges : ARRAY Read-Range; added-by : Pers-No; added-at : Time; type : Membership-Type; ) Membership-Old ::= ( last-time-read : Time; conference : Conf-No; priority : INT8; last-text-read : Local-Text-No; read-texts : ARRAY Local-Text-No; ) Membership-10 ::= ( position : INT32; last-time-read : Time; conference : Conf-No; priority : INT8; last-text-read : Local-Text-No; read-texts : ARRAY Local-Text-No; added-by : Pers-No; added-at : Time; type : Membership-Type; )
The Membership
structure encodes information about a person's
membership in a conference. It is returned by the
query-read-texts
and get-membership
calls.
The Membership-10
and Membership-Old
types are obsolete
variants of the same type, returned by older requests.
Membership-Old
contains less information. The encoding of the
read texts in Membership-10
is very inefficient in the common
case where you have read many texts after the first unread text.
position
last-time-read
unread-is-secret
bit of the Personal-Flags
is set and you don't have enough
privileges to get the info anyhow.
conference
priority
last-text-read
unread-is-secret
is set, unless you have access to
the data anyhow. This field is not available in Membership
,
but you can easily derive the same information from
read-ranges
.
read-texts
last-text-read
that have also been
read. This will be empty if unread-is-secret
is set, unless
you have access to the data anyhow.
read-ranges
unread-is-secret
is set, unless you have access to the data
anyhow.
added-by
added-at
type
A membership record may be cleared by the server (all fields set to zero) if the person requesting the membership has insufficient privileges to see the contents membership, but has sufficient privileges to know about the person.
Mark ::= ( text-no : Text-No; type : INT8; )
This data type hold information about a person's marks on articles.
The fields of Mark
are
text-no
type
Before version eight of protocol A, the meaning of the mark value was unspecified. Work is underway to specify the meaning of certain mark values.
Misc-Info ::= SELECTION ( 0=recpt recipient : Conf-No; 1=cc-recpt cc-recipient : Conf-No; 2=comm-to comment-to : Text-No; 3=comm-in commented-in : Text-No; 4=footn-to footnote-to : Text-No; 5=footn-in footnoted-in : Text-No; 6=loc-no local-no : Local-Text-No; 7=rec-time received-at : Time; 8=sent-by sender : Pers-No; 9=sent-at sent-at : Time; 15=bcc-recpt bcc-recipient : Conf-No; ) Info-Type ::= ENUMERATION-OF(Misc-Info) Text-Stat-Old ::= ( creation-time : Time; author : Pers-No; no-of-lines : INT32; no-of-chars : INT32; no-of-marks : INT16; misc-info : ARRAY Misc-Info; ) Text-Stat ::= ( creation-time : Time; author : Pers-No; no-of-lines : INT32; no-of-chars : INT32; no-of-marks : INT16; misc-info : ARRAY Misc-Info; aux-items : ARRAY Aux-Item; )
These two structures contain information about a single article.
Text-Stat
contains core information about the article and
Misc-Info
contains miscellaneous information related to the
article.
A Text-Stat
consists of the following:
creation-time
author
no-of-lines
no-of-chars
no-of-marks
misc-info
Misc-Info
list for this article.
aux-items
Misc-Info
, when sent to the client, is sent in a particular order
(see The Misc-Info List). The variants Misc-Info
are
(briefly):
recpt
cc-recpt
comm-to
comm-in
footn-to
footn-in
loc-no
recpt
, cc-recpt
or bcc-recpt
.
rec-time
recpt
, cc-recpt
or bcc-recpt
.
sent-by
recpt
, cc-recpt
or bcc-recpt
.
sent-at
recpt
, cc-recpt
or bcc-recpt
.
bcc-recpt
Who-Info-Old ::= ( person : Pers-No; working-conference : Conf-No; what-am-i-doing : HOLLERITH; ) Who-Info ::= ( person : Pers-No; working-conference : Conf-No; session : Session-No; what-am-i-doing : HOLLERITH; username : HOLLERITH; ) Who-Info-Ident ::= ( person : Pers-No; working-conference : Conf-No; session : Session-No; what-am-i-doing : HOLLERITH; username : HOLLERITH; hostname : HOLLERITH; ident-user : HOLLERITH; )
These structures are used to retrieve information on who is currently
using LysKOM. All the requests using these types are obsolete, but
Who-Info
is used by async-i-am-on
(see async-i-am-on).
The fields of Who-Info-Old
are
person
working-conference
what-am-i-doing
The fields of Who-Info
are
person
working-conference
session
what-am-i-doing
username
hostname
and
ident-user
(see below) and information from the client.
The fields of Who-Info-Ident
are
person
working-conference
session
what-am-i-doing
username
hostname
and
ident-user
.
hostname
ident-user
Session-Info ::= ( person : Pers-No; working-conference : Conf-No; session : Session-No; what-am-i-doing : HOLLERITH; username : HOLLERITH; idle-time : INT32; connection-time : Time; ) Session-Info-Ident ::= ( person : Pers-No; working-conference : Conf-No; session : Session-No; what-am-i-doing : HOLLERITH; username : HOLLERITH; hostname : HOLLERITH; ident-user : HOLLERITH; idle-time : INT32; connection-time : Time; ) Static-Session-Info ::= ( username : HOLLERITH; hostname : HOLLERITH; ident-user : HOLLERITH; connection-time : Time; ) Session-Flags ::= BITSTRING ( invisible; user-active-used; user-absent; reserved3; reserved4; reserved5; reserved6; reserved7; ) Dynamic-Session-Info ::= ( session : Session-No; person : Pers-No; working-conference : Conf-No; idle-time : INT32; flags : Session-Flags; what-am-i-doing : HOLLERITH; ) Scheduling-Info ::= ( priority : INT16; weight : INT16; )
These data types give information about a particular LysKOM session. The
types Session-Info
and Session-Info-Ident
have been
superseded by Static-Session-Info
and
Dynamic-Session-Info
. The static session info represents
information about a session that does not change during the lifetime of
the session. Therefore static session infos can be aggressively cached by
the client.
The fields of Session-Info
are
person
working-conference
session
what-am-i-doing
username
Who-Info
above.)
idle-time
user-active
was used by this
session, or since the session was created if
user-active
has not been used yet. See also
user-active-used
below.
connection-time
The fields of Session-Info-Ident
are
person
working-conference
session
what-am-i-doing
username
Who-Info-Ident
above.)
hostname
ident-user
idle-time
user-active
was used by this
session, or since the session was created if
user-active
has not been used yet. See also
user-active-used
below.
connection-time
The fields of Static-Session-Info
are
username
Who-Info-Ident
above.)
hostname
ident-user
connection-time
The bits in Session-Flags
are:
invisible
invisible
flag
set.
user-active-used
user-active
call has been issued by
the session, which in turn means that idle-time
fields of
Dynamic-Session-Info
, Session-Info
and
Session-Info-Ident
are valid. When false, the
idle-time
fields contains the number of seconds since the
session was created.
user-absent
The fields of a Dynamic-Session-Info
are
session
person
working-conference
idle-time
user-active
was used by this
session, or since the session was created if
user-active
has not been used yet. See also
user-active-used
above.
flags
what-am-i-doing
The Scheduling-Info
type determines how the resources are
shared between different sessions12.
See get-scheduling
and set-scheduling
for more
information. It contains these fields:
priority
priority
value will have
priority over other clients. A client with priority
set to 0
can totally starve clients with priority
set to 1, 2 or
anything higher.
weight
weight
value. If one client has a weight of 200 and another of
50, the first client will get roughly four times as much work done
(assuming that the server is the limiting factor).
Stats ::= ( average : FLOAT; ascent-rate : FLOAT; descent-rate : FLOAT; ) Stats-Description ::= ( what : ARRAY HOLLERITH; when : ARRAY INT32; )
The Stats
structure returns information about a measured value.
average
average
is the average value for the measurement period.
If the measurement period is 0, this is instead the current value.
ascent-rate
descent-rate
ascent-rate
would be the average number of issued requests per
second, and the descent-rate
would be the average number of
received replies (or timeouts, errors, or other reasons why the
request is no longer pending).
When calculating the ascent-rate
, only events that cause the
value to increase are considered. Likewise, the descent-rate
only considers events that decrease the value.
Example: if the measurement period is 60 seconds, the value starts at 5, and it is increased by one 90 times and decreased by one 60 times during the measurement period, the value will of course be 35 when the period ends. The ascent rate will be 1.5 per second, and the descent rate 1.0 per second.
If the measurement period is 0, both ascent-rate
and
descent-rate
are set to 0.
The Stats-Description
structure returns information about what
kind of statistical information that the server gathers. It contains
these fields:
what
when
get-stats
is a number of values
collected during various periods of time. This array contains the
periods, measured in seconds. The value 0 means that the current
value is returned. The values are only returned in ascending order,
so if 0 is included it will be the first value. Measured Properties, for more info.
This chapter documents all calls that can be made to the server. All calls are annotated with the protocol version in which they appeared and their current status.
The heading for each call looks something like this:
create-person-old [5] (1) Obsolete (10)
The heading consists of several parts:
create-person-old
[5]
(1)
Obsolete
(10)
The status of a call can be any of:
Experimental
Recommended
Obsolete
A note about the examples: The examples consist of a number of calls and replies. Extra newlines are sometimes inserted in the examples to avoid overly long lines.
login-old [0] (( person : Pers-No; passwd : HOLLERITH )) -> ( );
Log in as a person. This call has been replaced by login
.
undefined-person
person
is not an existing person.
login-disallowed
person
does not have the wheel
bit set.
invalid-password
passwd
is not the correct password for person
. The
error-status
indicates the person number.
logout [1] ( ) -> ( );
Log out from LysKOM.
This call does not disconnect the session; use disconnect
for that.
After issuing a logout
call the client can reconnect as the same
or a different person using the login
call.
For a client that needs to log in as several different users, issuing multiple logout and login requests during one session is faster and places less load on the server than does creating new sessions.
This call never fails.
change-conference [2] ( conference : Conf-No ) -> ( ) ;
Change current conference of a session. This call used to be called pepsi (the name was a very obscure and not very funny joke.)
login-first
undefined-conference
conference
does not exist or is secret.
conference-zero
conference
is zero.
not-member
conference
.
change-name [3] (( conference : Conf-No; new-name : HOLLERITH )) -> ( ) ;
This call changes the name of a conference or a person. To change the name of a conference the session issuing the call must be logged in as a person who either has special privileges or is the supervisor of the conference.
login-first
undefined-conference
conference
does not exist or is secret.
conference-zero
conference
is zero.
permission-denied
change-name
bit is not set or the user
does not have enough access to conference
.
conference-exists
new-name
is already occupied by another conference.
string-too-long
new-name
is too long for a valid conference name.
bad-name
new-name
.
change-what-i-am-doing [4] ( what-am-i-doing : HOLLERITH ) -> ( );
This call tells the server what the logged-in user is doing. The string is usually displayed when a user requests that a client list who is using LysKOM. Clients are encouraged to use this call creatively.
string-too-long
what-am-i-doing
is too long.
create-person-old [5] (( name : HOLLERITH; passwd : HOLLERITH )) -> ( Pers-No );
This call requests that the server create a new person with the name and password given as arguments. To create a person the session may have to be logged in as a person with sufficient privileges, if the server is configured that way.
If the session was not logged in an automatic visible login to the new person will be performed.
The new person will be a member of exactly one conference: the associated mailbox. That membership will have priority 255 and (of course) position 0. All flags of the membership will be 0.
Example:
1 5 24HLysKOM Statistics Daemon 6Hsecret =1 6
This example creates a new person named "LysKOM statistics Daemon" with the password "secret". The server has returned the person number six for the person.
login-first
permission-denied
create-pers
bit set.
conference-exists
name
.
invalid-password
passwd
is not a valid password.
index-out-of-range
error-status
indicates the
person number that should have been created if the limit hadn't been
reached.
get-person-stat-old [6] (( person : Pers-No; mask : INT32 )) -> ( Person );
This call returns information about a person. If the low bit of
mask
is not set, the empty string is returned instead of the
username
field. This call is obsolete and has been replaced
by get-person-stat
.
login-first
undefined-person
person
does not exist.
undefined-conference
person
does not exist or is secret.
conference-zero
person
is zero.
set-priv-bits [7] (( person : Pers-No; privileges : Priv-Bits )) -> ( );
This call sets the privileges of person
to
privileges
. See Security. To successfully issue this call the
session must be logged in as a person with sufficient privileges.
Example:
1 7 6 0010000000000000 =1
This example sets the privileges of person 6 to nothing but
statistic
. This particular set of privileges might be useful
for a person used by a statistics-collecting dæmon.
login-first
undefined-person
person
is not a valid person.
permission-denied
wheel
bit set
and privilege level set to 6 or higher.
set-passwd [8] (( person : Pers-No; old-pwd : HOLLERITH; new-pwd : HOLLERITH )) -> ( );
This call is used to set the password of person
to
new-pwd
. Any person may set it's own password. In addition
persons with sufficient privileges may set other persons' passwords.
The password of the person currently logged in must match
old-pwd
.
Example:
1 8 5 6Hgazonk 7Ha9go8Hz =1
This example sets the password of the LysKOM administrator to "a9go8Hz" provided that the old password was "gazonk".
login-first
undefined-person
person
is not a valid person.
permission-denied
wheel
bit set and
privilege level 7 or higher enabled.
invalid-password
old-pwd
is invalid or new-pwd
is invalid as a password.
query-read-texts-old [9] (( person : Pers-No; conference : Conf-No )) -> ( Membership-Old );
This call is used to find the number of unread texts in a conference.
The data it returns is actually a membership structure which specifies
which texts have been read. It is up to the client to transform the data
to a more usable form. person
is the person being queried
and conference
is the conference in question.
Calling query-read-texts-old
does not require the session to be
logged in.
Example:
1 9 6 1 =1 32 5 11 12 7 93 1 193 1 1 20 133 3 { 135 136 137 }
This example finds the read texts for user 6 in conference 1. The returned data indicates that the user last read conference 1 (the tenth number) on Monday July 12th, 1993 at 11:05:32 (the first nine numbers), that the person has assigned priority 20 to the conference (the eleventh number) and that all articles up to and including local number 133 plus articles 135, 136 and 137 have been read.
undefined-person
person
does not exist, or no access to person.
undefined-conference
conference
does not exist, or is secret.
conference-zero
conference
is zero.
not-member
person
is not a member of conference
.
create-conf-old [10] (( name : HOLLERITH; type : Any-Conf-Type )) -> ( Conf-No );
This call is used to create new conferences. name
is the name of
the new conference and type
is its type. If successful, the call
returns the conference number of the newly created conference.
To use this call the session must have logged in as a user with privileges to create conferences (see Security).
Example:
1 50 8 %1 9 0 1 10 13HInlägg }t mig 00001000 =1 8 1 50 8 =1 13HInlägg }t mig 0000 43 9 17 14 5 96 5 165 1 43 9 17 14 5 96 5 165 1 5 0 5 0 5 0 77 0 1 0
This example creates a new conference named "Inlägg }t mig"13 which accepts all users as members and accepts anonymous articles. The server returns 7 as the new conference number.
login-first
permission-denied
create-conf
bit set.
conference-exists
name
already exists.
bad-name
name
contains invalid characters.
string-to-long
name
is too long to be used as a conference name.
secret-public
type
has the secret
bit set, but
the rd-prot
bit is cleared.
index-out-of-range
error-status
indicates
the conference number that should have been created if the limit
hadn't been reached.
delete-conf [11] ( conf : Conf-No ) -> ( );
This call deletes the conference conf
from the LysKOM
database. Only privileged users and the supervisors of a conference may
delete it. If the conference is a mailbox the corresponding person will
also be deleted.
Example:
1 50 7 =1 4HTest 1001 16 4 19 10 5 96 1 161 1 16 4 19 10 5 96 1 161 1 7 0 7 0 0 0 77 1 1 0 1 11 7 =1 1 50 7 %1 9 0
This example shows the successful deletion of conference number seven.
login-first
undefined-conference
conf
does not exist or is secret.
conference-zero
conf
is zero.
permission-denied
conf
and not enough privileges enabled.
undefined-person
conf
is a mailbox but does not exist as a person (the database
is corrupt.)
lookup-name [12] ( name : HOLLERITH ) -> ( Conf-List-Archaic );
This call returns a list of conferences matching the string name
.
lookup-name has been superseded by lookup-z-name
.
Example:
1 12 3Ha d =1 3 { 217 674 1582 } { 0000 1001 0000 } 2 12 3H::: =2 0 * * 3 76 3Ha d 1 1 =3 3 { 31HAlkohol- (och annan) drogdebatt 0000 217 13HAnna Degerman 1001 674 27HAnarchy discussion (import) 0000 1582 } 4 76 3H::: 1 1 =4 0 *
This example shows two attempts to look up a name. The first example
looks up a d
and finds three matches (the middle, number 674,
is a person). The second example looks up :::
which doesn't
match any conference (or person). Call number 3 and 4 issues the same
lookup using the lookup-z-name
call.
(The return value for call number 3 has been broken into three lines
to fit on the page.)
This call always succeeds.
get-conf-stat-older [13] (( conf-no : Conf-No; mask : INT32 )) -> ( Conference-Old );
This call retrieves the information associated with conference
conf-no
in the LysKOM server. This call should no longer be
used; use get-conf-stat
instead.
The mask
argument determines if the name is returned or not. If
the lowest bit is 1 the name is returned, otherwise the empty string is
returned instead of the name.
undefined-conference
conf-no
does not exist or is secret.
conference-zero
conf-no
is zero.
add-member-old [14] (( conf-no : Conf-No; pers-no : Pers-No; priority : INT8; where : INT16 )) -> ( );
Make the person pers-no
a member of conference conf-no
.
The membership priority is set to priority
and its position in
the membership list is set to where
.
This call can be used to change the priority and position of a conference in the person's membership list if the person is already a member of the conference.
In protocol version 10, setting the priority to zero sets the passive bit in the membership. The actual priority is not changed.
Example:
1 46 119 0 10 0 =1 1 { 49 14 17 13 8 91 5 255 1 119 255 0 0 * } 1 14 1 119 250 0 =1 1 46 119 0 10 0 =1 2 { 52 30 14 11 5 96 2 162 1 1 250 0 0 * 49 14 17 13 8 91 5 255 1 119 255 0 0 * }
This example makes person 119 (me) a member of conference number 1. The priority is set to 250 and the conference is placed first in the membership list. The first and last calls of the example show the membership list for person 119 before and after the call.
login-first
undefined-conference
conf-no
does not exist or is secret.
conference-zero
conf-no
is zero.
undefined-person
pers-no
does not exist
access-denied
conf-no
.
permission-denied
pers-no
is already a member of conference conf-no
,
but the person logged on is not a supervisor and does not have enough
privileges to change the priorities of person pers-no
.
sub-member [15] (( conf-no : Conf-No; pers-no : Pers-No )) -> ( );
Removes the person pers-no
from the membership list of conference
conf-no
and remove the conference from the person's list of
memberships.
Example:
1 46 5 0 100 0 =1 2 { 44 14 19 10 5 96 1 161 1 1 0 0 0 * 49 14 17 13 8 91 5 255 1 5 255 0 0 * } 1 15 1 5 =1 1 46 5 0 100 0 =1 1 { 49 14 17 13 8 91 5 255 1 5 255 0 0 * }
This example shows how person 5 is removed from conference one. The
calls to get-membership-old
demonstrate the effects on the
LysKOM database.
login-first
undefined-conference
conf-no
does not exist or is secret.
conference-zero
conf-no
is zero.
undefined-person
pers-no
does not exist.
not-member
pers-no
is not a member of conference conf-no
.
permission-denied
conf-no
or not supervisor of person
pers-no
and not enough privileges to issue the call anyway.
error-status
contains the conference number.
set-presentation [16] (( conf-no : Conf-No; text-no : Text-No )) -> ( );
This call sets the presentation text of the conference or person
conf-no
to the text text-no
. To remove a presentation, use
a text-no
of zero. This call protects the new presentation from
being deleted automatically and removes such protection from the old
presentation. In lyskomd this is implemented by increasing the mark
count on presentation texts.
Example:
1 50 6 =1 11HDavid Byers 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 0 5 0 5 0 77 1 1 0 1 16 6 1 =1 1 50 6 =1 11HDavid Byers 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 1 5 0 5 0 77 1 1 0
This example shows how the presentation of person 6 is being
changed. To start with, the person had no presentation, as is shown by
the get-conf-stat-old
call. Later, after
set-presentation
has been called, the presentation field has
changed.
login-first
undefined-conference
conf-no
does not exist or is secret.
conference-zero
conf-no
is zero.
permission-denied
conf-no
.
no-such-text
text-no
does not exist or no read permission.
mark-limit
text-no
would cause it to have too many
marks.
set-etc-motd [17] (( conf-no : Conf-No; text-no : Text-No )) -> ( );
This call sets the message of the day on the conference or person
conf-no
to the article text-no
and removes the old
message. To remove an old message without setting a new one, use a
text-no
of zero. This call protects the new message from
automatic deletion and removes such protection from the old message just
as set-presentation
.
Example:
1 50 6 =1 11HDavid Byers 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 0 5 0 5 0 77 1 1 0 1 17 6 1 =1 1 50 6 =1 11HDavid Byers 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 0 5 0 5 1 77 1 1 0
This example shows how text number one is used as the message of the day
for conference six (which happens to be a mailbox.) The
get-conf-stat-old
calls before and after demonstrate the change in
the conference structure.
login-first
undefined-conference
conf-no
does not exist or is secret.
conference-zero
conf-no
is zero.
permission-denied
conf-no
.
mark-limit
text-no
would cause it to have too many
marks.
set-supervisor [18] (( conf-no : Conf-No; admin : Conf-No )) -> ( );
The set-supervisor
call changes the supervisor of an existing
conference. The result is that all members of the conference
admin
become supervisors of the conference conf-no
.
Typically, but not always, admin
will be a mailbox.
Example:
1 50 4 =1 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 0 0 0 0 77 1 1 1 1 18 4 6 =1 1 50 4 =1 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 0 0 77 1 1 1
This example makes the members of conference six supervisors of
conference four (which is usually the "News about LysKOM"
conference). The change in the conference structure is evident from
the get-conf-stat-old
calls before and after the
set-supervisor
call. Note that the original supervisor was not
set. In order to change the supervisor of such a conference, the
session issuing the call must have administration privileges.
login-first
undefined-conference
conf-no
or conference admin
does not exist or
is secret.
conference-zero
conf-no
is zero.
permission-denied
conf-no
.
set-permitted-submitters [19] (( conf-no : Conf-No; perm-sub : Conf-No )) -> ( );
This call grants the right to send articles to the conference
conf-no
to all members of the conference perm-sub
. If
perm-sub
is 0, everybody can send articles to the conference.
(This is the default setting of new conferences and persons.)
When a person tries to submit an article but does not have the right to do so, the server will send the article to the super-conference instead.
Example:
1 50 4 =1 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 0 0 77 1 1 1 1 19 4 1 =1 1 50 4 =1 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 1 0 0 77 1 1 1
This example shows how all members of conference one are given
permission to send articles to conference four. From the beginning,
only members of conference four were permitted to submit articles. The
change is evident from the get-conf-stat-old
calls before and after the set-permitted-submitters
call.
login-first
undefined-conference
conf-no
or conference perm-sub
does not exist
or is secret.
conference-zero
conf-no
is zero.
permission-denied
conf-no
.
set-super-conf [20] (( conf-no : Conf-No; super-conf : Conf-No )) -> ( );
Makes the conference super-conf
the super-conference of the
conference conf-no
. See Conference Status Types, for more
info on what this field is used for.
Example:
1 50 4 =1 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 0 0 77 1 1 1 2 20 4 8 =2 3 50 4 =3 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 8 0 77 1 1 1
This example demonstrates how the super-conference of conference 1 is
set to conference 8. The calls to get-conf-stat-old
demonstrate the
change in the conference structure.
login-first
undefined-conference
conf-no
or conference super-conf
does not exist
or is secret.
conference-zero
conf-no
is zero.
permission-denied
conf-no
.
set-conf-type [21] (( conf-no : Conf-No; type : Any-Conf-Type )) -> ( );
Sets the conference type of conference conf-no
to type
.
Before protocol version 8, type
could only be four bits. Starting
with protocol version 8, either a four-bit Conf-Type
or an
eight-bit Extended-Conf-Type
is allowed.
Example:
1 78 4 =1 17HNyheter om LysKOM 00001000 1 77 1 21 4 00000000 =1 1 78 4 =1 17HNyheter om LysKOM 00000000 1 77
This example shows a user removing the allow-anonymous
bit
from conference four. The get-uconf-stat
call
shows all eight bits of the conference type before and after the
set-conf-type
call.
login-first
undefined-conference
conf-no
does not exist or is secret.
conference-zero
conf-no
is zero.
secret-public
type
has secret
bit but not rd-prot
.
permission-denied
conf-no
.
letterbox
letterbox
flag.
invalid-membership-type
forbid-secret
on a conference with a secret member.)
error-status
is the id of the first person with an incompatible
membership type.
set-garb-nice [22] (( conf-no : Conf-No; nice : Garb-Nice )) -> ( );
Sets the expiration time for articles in conference conf-no
to
nice
days. An article that is older than the maximum expiration
time of each conference it is sent to may be deleted by the LysKOM
server unless it has marks.
Example:
1 78 4 =1 17HNyheter om LysKOM 00000000 1 77 1 22 4 7 =1 1 78 4 =1 17HNyheter om LysKOM 00000000 1 7
This example shows the expiration time of conference four being lowered from 77 to just seven days.
login-first
undefined-conference
conf-no
does not exist or is secret.
conference-zero
conf-no
is zero.
permission-denied
conf-no
.
get-marks [23] ( ) -> ( ARRAY Mark );
This call returns the list of marks the current user has set.
Example:
1 23 =1 3 { 13020 100 13043 95 12213 95 }
In this example, the current user has three marks, one on text 13020 with mark type 100, one on text 13042 with mark type 95 and one on text 12213 with mark type 95. The maximum number of marks may be arbitrarily limited in the LysKOM server.
login-first
mark-text-old [24] (( text : Text-No; mark-type : INT8 )) -> ( );
This call has been replaced by mark-text
and
unmark-text
and should no longer be used.
This call can only set mark-type
to a value in the range 1 to
255 (inclusive). If mark-type
is set to 0 the mark will be
removed.
login-first
no-such-text
text
does not exist.
permission-denied
text
.
undefined-person
too-many-marks
get-text [25] (( text : Text-No; start-char : INT32; end-char : INT32 )) -> ( HOLLERITH );
Retrieve text number text
from the LysKOM database, starting at
position start-char
and ending at position end-char
. The
first character in the text is numbered 0 and the last can be retrieved
using get-text-stat
. It is also permitted to request a character
position beyond the actual end of the text, in which case as much text
as is available will be returned.
Example:
1 25 100 0 32766 =1 25HYawnNothing is happening 2 25 100 5 32766 =2 20HNothing is happening 3 25 100 0 3 =3 4HYawn
In the example,
represents a linefeed.
In this example, text 100 is requested three times, first from position 0 to position 32766, then from position 5 to position 32766 and finally from position 0 to position 4. The first reply contains the entire text, the following two contain only the requested portion.
no-such-text
text
does not exits or no read permission.
This error code will also be used when attempting to fetch texts
without logging in first. (There are some texts that are readable
without logging in: the motd-of-lyskom (see set-motd-of-lyskom),
and texts with the world-readable
aux item set on them.)
text-zero
index-out-of-range
start-char
is larger than the length of the text.
get-text-stat-old [26] ( text-no : Text-No ) -> ( Text-Stat-Old );
Get information about text number text-no
. The text-stat contains
information about the size of the text, its recipients, comments, author
and more.
For compatibility reasons this call will only return the misc-infos 0=recpt, 1=cc-recpt, 2=comm-to, 3=comm-in, 4=footn-to, 5=footn-in, 6=loc-no, 7=rec-time, 8=sent-by and 9=sent-at. Newer misc-infos will either be removed or converted to a similar one. Specifically, 15=bcc-recpt may (at the servers discretion) be converted to 1=cc-recpt or omitted entirely.
Example:
1 26 100 =1 7 35 16 15 6 96 1 196 1 14 1 22 1 7 { 0 7 6 85 0 15 6 1 8 13 9 12 37 16 15 6 96 1 196 1 3 311 }
In this example, text number 100 was created by person 7 at approximately 4:35PM on July 15 1996. Its recipients are conferences 7 and 15, and it was sent to conference 15 by person 13 at 16:37 on the day it was created. The text has a single comment: text 311.
no-such-text
text-no
does not exist, or no read access.
This error code will also be used when attempting to fetch texts
without logging in first. (There are some texts that are readable
without logging in: the motd-of-lyskom (see set-motd-of-lyskom),
and texts with the world-readable
aux item set on them.)
text-zero
mark-as-read [27] (( conference : Conf-No; text : ARRAY Local-Text-No )) -> ( );
Marks text text
in conference number conference
as read
for the current user. This call updates the membership record for the
user.
Example:
1 9 6 7 =1 20 32 11 17 6 96 3 198 1 7 1 240 0 * 1 78 7 =1 13HInlägg }t mig 00001000 241 1 1 27 7 1 { 241 } =1 1 9 6 7 =1 20 32 11 17 6 96 3 198 1 7 1 241 0 *
This example shows person 6 marking local text number 241 in conference
7 as read. In the first query-read-texts-old
call the person
has read local text 240, but nothing higher. The mark-as-read
call is reflected in the second query-read-texts-old
call, where
the user is seen to have read text 241 in conference 7.
To mark a global text number as read it is necessary to translate it
into local text numbers by looking at the misc-info list in the
Text-Stat
and calling mark-as-read
once for each recipient.
There is no need to call mark-as-read
on deleted texts. The
server will automatically mark them as read, sooner or later.
login-first
undefined-conference
conference
does not exist or is secret.
conference-zero
conference
is zero.
not-member
conference
.
no-such-local-text
text
is not a local text number in
conference
. The error argument indicates the index of the invalid
number.
local-text-zero
text
is zero.
create-text-old [28] (( text : HOLLERITH; misc-info : ARRAY Misc-Info )) -> ( Text-No );
Creates a new text with contents from text
and recipients
etc. defined by misc-info
(see The Misc-Info List). In
addition to the result, the server will send an asynchronous message
to all members of any of the recipients of the new text. It is not
defined whether this messages comes before or after the reply to
the create-text message. Clients should be prepared for either
situation.
The text up to the first linefeed is considered to be the subject line. The remaining text is the message body. Although messages with only a subject are valid, clients should avoid letting users create such messages.
The only Misc-Info items valid for this call are recpt
,
cc-recpt
, bcc-recpt
(protocol version 10),
comm-to
and footn-to
.
Example:
1 28 20HExampleMessage body 3 { 0 5 1 112 2 33467 } :16 0 33502 13 16 15 16 6 97 3 196 1 119 1 20 0 5 { 0 5 6 148 1 112 6 3438 2 33467 } =1 33502
In the example,
represents a linefeed.
In this example, person 119 creates a text containing a subject and a one-line body. The recipient of the text is conference five, conference 112 is a CC recipient and the text is a comment to text 33467. The server reply indicates that the new text has been given number 33502. Finally there is an asynchronous message sent to all members of recipient conferences. Note how the message was sent before the reply to the client. The misc-info list in this message has two additional fields, the local numbers of the text in each of its recipient conferences.
login-first
string-too-long
text
is longer than the maximum length of a message.
temporary-failure
no-such-text
not-author
footnote-limit
comment-limit
index-out-of-range
error-status
indicates the text
number that should have been created if the limit hadn't been reached.
access-denied
anonymous-rejected
illegal-misc
delete-text [29] ( text : Text-No ) -> ( );
Deletes the text text
from the LysKOM database, if the person
issuing the command may do so.
Example:
1 29 33467 =1
This simple example shows the deletion of text number 33467.
login-first
no-such-text
text
does not exist or no read access.
not-author
add-recipient [30] (( text-no : Text-No; conf-no : Conf-No; recpt-type : Info-Type )) -> ( );
Adds conf-no
as recipient to text text-no
. If
recpt-type
is 1, then a cc-recpt
(see The Misc-Info List) is created; otherwise a recpt
is created.
Since protocol version 8 this call can also be used to change a
cc-recpt
into a recpt
and vice versa by simply adding
a recipient that already exists.
Since protocol version 10 the recpt-type
parameter is a
Misc-Info
. Only infos recpt
, cc-recpt
and
bcc-recpt
are accepted. In protocol version 9 and earlier this
argument was a BOOL
, that indicated if the recipient should be
a cc-recpt
(when true) or recpt
(when false).
Example:
1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 30 1 5 0 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 3 { 0 5 6 1 9 34 34 17 17 6 97 4 197 1 } 1 30 1 5 1 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 3 { 1 5 6 1 9 34 34 17 17 6 97 4 197 1 }
This example show how conference 5 is added first as a recipient of text 1, then changed to a carbon-copy recipient. The misc-info list reflects these changes.
login-first
undefined-conference
conf-no
does not exist.
conference-zero
conf-no
is zero.
no-such-text
text-no
does not exist.
already-recipient
conf-no
is already a recipient of the same type as
recpt-type
.
illegal-info-type
recpt-type
is not recpt
, cc-recpt
or
bcc-recpt
.
recipient-limit
permission-denied
access-denied
sub-recipient [31] (( text-no : Text-No; conf-no : Conf-No )) -> ( );
Removes conf-no
from the list of recipients of text
text-no
. Recipients may be removed by the author of the text or
by the supervisor of the recipients of the text or by the supervisor of
the author.
Example:
1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 3 { 1 5 6 1 9 34 34 17 17 6 97 4 197 1 } 1 31 1 5 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 31 1 5 %1 30 0
In this example, conference 5 is removed from the recipient list of text number 5. When the call is repeated, the server simply returns an error since conference 5 is not a recipient of the text.
login-first
no-such-text
text-no
does not exist or is secret.
not-recipient
conf-no
is not a recipient of text text-no
.
undefined-conference
conf-no
does not exist or is secret.
conference-zero
conf-no
is zero.
permission-denied
conf-no
and not enough privileges set and enabled.
add-comment [32] (( text-no : Text-No; comment-to : Text-No )) -> ( );
Add a comment link between the text comment-to
and the text
text-no
(text-no
becomes a comment to the text
comment-to
). This call is used to add comment links after a text
has been created. The normal procedure for creating comments is to add a
comm-to
element to the text's misc-info list when the text is
created (see The Misc-Info List).
Example:
1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 { 0 2 6 1 } 1 32 2 1 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 { 3 2 } 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 4 { 0 2 6 1 2 1 9 19 52 18 17 6 97 4 197 1 }
In this example, text number two is added as a comment to text number one. The change is reflected in the Misc-Info List of the texts.
login-first
index-out-of-range
text-no
and comment-to
are identical. The
error-status
is text-no
.
no-such-text
text-no
of comment-to
are undefined.
comment-limit
comment-to
already has the maximum number of comments.
already-comment
text-no
is already a comment of comment-to
.
already-footnote
text-no
is already a footnote of comment-to
,
and a text cannot be both a comment and a footnote to the same text.
sub-comment [33] (( text-no : Text-No; comment-to : Text-No )) -> ( );
This call removes the text text-no
from comment-to
's list
of comments.
Example:
1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 { 3 2 } 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 4 { 0 2 6 1 2 1 9 19 52 18 17 6 97 4 197 1 } 1 33 2 1 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 { 0 2 6 1 }
In this example text 2 is a comment to text 1, as shown by the misc-info
lists of the two texts. The sub-comment
is called. The misc-info
lists are changed to reflect the change.
login-first
no-such-text
text-no
or comment-to
does not exist.
not-comment
text-no
is not a comment to comment-to
.
permission-denied
text-no
or not sender of the
comment and not enough privileges set and enable to complete the call
anyway.
get-map [34] (( conf-no : Conf-No; first-local-no : Local-Text-No; no-of-texts : INT32 )) -> ( Text-List );
This call has been superseded by local-to-global
.
This call retrieves an array mapping local text numbers to global
numbers. It is most often used to get a list of unread texts in a
conference. Clients will usually use the query-read-texts
or
get-membership
calls to find the last local number a user has
read in a particular conference, then use the get-map
call to
retrieve the global numbers of all unread texts in the conference.
The conf-no
parameter specifies which conference to get the map
of. first-local-no
is the local number of the first text returned
by the call. no-of-texts
is the maximum number of text the client
wants.
The result is a list of global text numbers. The first element of the
list is the global number of local number first-local-no
,
specified by the call; the second element is the global number of local
number first-local-no
plus one; and so forth. The list returned
by the server is at most no-of-texts
long, but may be shorter if
the call specifies more texts that there are in the conference.
If first-local-no
is higher than the highest local text number,
the server will return an error.
If first-local-no
is lower than the lowest number that still
exists, the server will set first-local-no
in the returned
Text-List
to the first text that still exists. The size of the
returned array will be decreased by the same amount as
first-local-no
is increased. This may result in an empty array
being returned. (This paragraph applies even when first-local-no
is 0.)
If no texts at all exists in conf-no
the resulting array will be
empty, and first-local-no
will be set to the number the next text
to be created will receive.
Example:
1 34 119 10 5 =1 10 5 { 0 0 466 478 391 } 2 34 119 16 5 =2 16 3 { 481 0 491 } 3 34 119 19 5 %3 16 0 4 34 120 1 5 =4 4 2 { 480 485 } 5 34 120 1 2 =5 4 0 *
This example shows five get-map
calls. The first retrieves the
mappings of local numbers 10 to 15; the second call returns local
numbers 16 to 18. As this example shows the maps are not necessarily
sorted in ascending order, since texts may be added after their
creation, and the maps may contain zeroes anywhere. These represent
texts that have been removed for some reason.
Since the first example returned two leading zeroes we can be certain that at least one text with a local text number lower than 10 still exists. Otherwise the result would have been truncated in the front as it is in examples 4 and 5.
The third exchange in the example shows what happens when
first-local-no
is too large.
The forth and fifth examples shows what happens when an attempt to retrieve a mapping from a conference where the first local text numbers have been deleted. In the example local text numbers 1, 2 and 3 no longer exist, and 4 corresponds to 480, and 5 to 485.
login-first
undefined-conference
conf-no
does not exist or is secret.
conference-zero
conf-no
is zero.
access-denied
conf-no
is read protected.
no-such-local-text
first-local-no
is higher than the highest local text number that
ever has existed in this conference.
get-time [35] ( ) -> ( Time );
This call simply returns the local time according to the server.
Example:
1 35 =1 23 47 19 17 6 97 4 197 1
This example demonstrates the call. According to the server the time is 19:47:23, Thursday July 17, 1997. The result also shows that it is the 197th day of the year, and that daylight savings time is in effect.
This call always succeeds
get-info-old [36] ( ) -> ( Info-Old );
This call returns the Info-Old
structure for the server
(see Info-Old). Clients should call this in order to find
out which conferences are used for presentations and such.
This call has been superseded by get-info
.
This call can be issued without logging in.
Example:
1 36 =1 10900 1 2 3 4 1
In this example, the server version is 1.9, the conference for presentation of new conferences is conference 1, the conference for presentation of new persons is conference 2, the conference for door messages is conference 3, the LysKOM news conference is conference 4 and the login message is text number 1.
This call always succeeds.
add-footnote [37] (( text-no : Text-No; footnote-to: Text-No )) -> ( );
Add a footnote link between the text footnote-to
and the text
text-no
(text-no
becomes a footnote to the text
footnote-to
). This call is used to add footnote links after a text
has been created. Only the author of both texts is allowed to add
the footnote link.
Example:
1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 { 0 2 6 1 } 1 37 2 1 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 { 5 2 } 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 4 { 0 2 6 1 4 1 9 19 52 18 17 6 97 4 197 1 }
In this example, text number two is added as a footnote to text number one. The change is reflected in the Misc-Info List of the texts.
login-first
no-such-text
text-no
or footnote-to
does not exist or is
secret.
index-out-of-range
text-no
and footnote-to
arguments are equal, and the
server does not support texts that are footnotes to themselves.
not-author
footnote-to
.
footnote-limit
footnote-to
already has the maximum number of footnotes.
already-footnote
text-no
is already a footnote to footnote-to
.
already-comment
text-no
is already a comment to footnote-to
, and a
text cannot be both a comment and a footnote to the same text.
sub-footnote [38] (( text-no : Text-No; footnote-to : Text-No )) -> ( );
This call removes the text text-no
from footnote-to
's list
of footnotes. Only the author of a footnote may remove it.
Example:
1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 { 5 2 } 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 4 { 0 2 6 1 4 1 9 19 52 18 17 6 97 4 197 1 } 1 38 2 1 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 { 0 2 6 1 }
In this example text 2 is a footnote to text 1, as shown by the
misc-info lists of the two texts. The sub-footnote
is called.
The misc-info lists are changed to reflect the change.
login-first
no-such-text
text-no
or footnote-to
does not exist or is
secret.
not-footnote
text-no
is not a footnote to footnote-to
.
permission-denied
text-no
and not enough privileges
set and enabled to complete call anyway.
who-is-on-old [39] ( ) -> ( ARRAY Who-Info-Old );
This call is obsolete. Use get-static-session-info
and
who-is-on-dynamic
instead. If the server does not support these
calls, use who-is-on
instead.
The returned list contains all sessions where a person is logged in and the invisible flag of the session is unset.
This call always succeeds.
set-unread [40] (( conf-no : Conf-No; no-of-unread : INT32 )) -> ( );
Only read the last no-of-unread
in the conference conf-no
.
This call modifies the last-text-read
of current person's
membership for the conference. This call is sometimes used to
implement the "only read last N texts" command found in many
clients. Due to possible race conditions14, this call is usually
better implemented using the set-last-read
call
which explicitly sets the last-text-read
field of the
membership.
Example:
1 9 5 6 =1 1 34 21 17 6 97 4 197 1 6 100 0 0 * 1 40 6 0 =1 1 9 5 6 =1 1 34 21 17 6 97 4 197 1 6 100 4 0 *
This example shows that person 5 last read text 0 in conference 6 (and
since 0 is an illegal local text number, that implies that the person
has not read anything in the conference.) After calling
set-unread
and asking to have zero unread texts in conference 6,
this is reflected by the call to query-read-texts-old
.
login-first
undefined-conference
conf-no
does not exist or is secret.
not-member
conf-no
.
set-motd-of-lyskom [41] ( text-no : Text-No ) -> ( );
This call sets the login message of LysKOM. It can only be executed by a
privileged person, with the proper privileges enabled. A somewhat less
convenient way of doing this is to use the set-info
call.
Example:
1 36 =1 10900 1 2 3 4 0 1 41 435 =1 1 36 =1 10900 1 2 3 4 435
This example shows how the login message of LysKOM is set using the
set-motd-of-lyskom call. The results of the get-info
calls
demonstrate the effect.
login-first
permission-denied
no-such-text
text-no
does not exist.
mark-limit
text-no
already has the maximum number of marks.
enable [42] ( level : INT8 ) -> ( );
Sets the security level for the current session to level
.
See Security, for details about security levels. The only levels
that make any sense right now are 0 and 255. This call may be issued
by any person, but without the right privilege bits set, it has no
effect.
Example:
1 41 1 %1 12 0 1 42 255 =1 1 41 1 =1
This example shows how enable
makes a privileged call possible,
in this case a call to set-motd-of-lyskom
.
login-first
sync-kom [43] ( ) -> ( );
This call instructs the LysKOM server to make sure the permanent copy of its database is current. Processing of requests is normally blocked until this call has completed, but the exact details depend on the server implementation. This call is privileged in most implementations.
Example:
1 42 255 =1 1 43 :0 7 :0 7 =1
This example shows how the enable
call is used to enable
all privileges, then the sync-kom
call is used to
save the database. The server responds with two asynchronous messages
signaling that the database is being saved.
login-first
permission-denied
shutdown-kom [44] ( exit-val : INT8 ) -> ( );
This call instructs the server to save all data and shut down.
exit-val
is currently not used. This call is privileged.
Example:
1 42 255 =1 1 44 0 =1 :2 13 5 3
This example shows the shutdown of a server. The asynchronous message sent after the call returns is the result of a session being forced to log out.
login-first
permission-denied
broadcast [45] ( message : HOLLERITH ) -> ( );
This call can been replaced by send-message
. It is a privileged
call.
login-first
string-too-long
message
is too long.
feature-disabled
get-membership-old [46] (( person : Pers-No; first : INT16; no-of-confs : INT16; want-read-texts : BOOL )) -> ( ARRAY Membership-Old );
This call retrieves the membership record for a list of conferences for
a single person. person
is the person whose memberships are to be
retrieved. first
is the first position in the membership list to
retrieve, numbered from 0 and up. no-of-confs
is the number of
membership records to retrieve. If want-read-texts
is 0
the server will not send the contents of the read-texts
array
of the memberships. (The size will be transmitted, but a single
asterisk (*
) will be sent instead of the array itself.)
The server will return a membership list that is shorter than
no-of-confs
if no-of-confs
+ first
is larger than
the number of conferences the person is a member of.
Servers that support protocol version 10 will return a priority of zero if the passive bit in the membership record has been set (either by a set-membership-type or by setting the priority of the conference to zero.)
Example:
1 46 5 0 3 1 =1 2 { 49 14 17 13 8 91 5 255 1 5 255 0 0 * 20 14 22 17 6 97 4 197 1 6 100 2 0 * } 1 46 5 0 1 1 =1 1 { 49 14 17 13 8 91 5 255 1 5 255 0 0 * } 1 46 5 1 4 1 =1 1 { 20 14 22 17 6 97 4 197 1 6 100 2 0 * }
In this example we retrieve the memberships of person 5. The first call asks for three memberships, starting with number 0. Since this person is only a member of two conferences, the list returned only contains two memberships. (An extra newline has been inserted in the result of the first call to make the result more readable.) The next two calls retrieve a single membership each, the first by asking for only one, and the second by asking for four memberships, starting with number 1.
login-first
undefined-person
person
does not exist.
undefined-conference
person
does not exist or is secret.
index-out-of-range
first
is higher than the index of the last conference in the
person's membership list.
bad-bool
want-read-texts
must be either 0
or 1
.
get-created-texts [47] (( person : Pers-No; first : Local-Text-No; no-of-texts : INT32 )) -> ( Text-List );
This call is obsolete; instead you should use map-created-texts
.
This call returns a list of the texts written by a person.
person
is the person whose created texts are to be
retrieved. first
is the first text to
retrieve. no-of-texts
is the number of texts to retrieve.
This call is essentially the same as get-map
, but instead of
returning the texts sent to a single conference, it returns the texts
written by a single person to any conference. The number of texts
written by any one person is contained in the Person record for that
person.
If first
is lower than the first text written by person
that still exists, it will be automatically increased to the first still
existing text written by person
. The get-created-texts
will still attempt to return information about no-of-texts
texts.
(In this regard get-map
and get-created-texts
differ,
since get-map
will never ever return information about a later
text than specified in the arguments to the call.15)
Example:
1 47 5 0 100 =1 1 8 { 1 2 3 4 5 6 7 8 } 2 47 5 4 2 =2 4 2 { 4 5 } 3 47 10 8 8 =3 12 8 { 309 312 324 327 329 339 0 387 }
In this example we have retrieved all texts written by person five. The first call asked for 100 texts, but only 8 were returned, which implies that person number 5 only created a total of 8 texts. We can also see that person 5 wrote all the first 8 texts in the conference system. The second call shows how a part of the map can be retrieved.
The third call asks for eight texts written by person 10, starting with the eighth number. Since the first eleven texts written by that person no longer exists the server instead returns information about eight texts staring from the twelfth text person 10 created. One of the eight texts has been deleted.
login-first
undefined-person
person
does not exist or is secret.
undefined-conference
person
does not exist or is secret.
no-such-local-text
first
is higher than the local text number of the last created
text.
get-members-old [48] (( conf : Conf-No; first : INT16; no-of-members : INT16 )) -> ( ARRAY Pers-No );
This call returns a list of members of the conference conf
.
first
is the first index in the membership to return, numbered
from zero and up. no-of-members
is the maximum number of members
to return.
Example:
1 48 1 0 100 =1 4 { 7 8 9 10 } 1 48 6 0 100 =1 4 { 5 7 9 10 } 1 48 6 2 2 =1 2 { 9 10 }
In this example the client first requests the first 100 members in conference 1. The second request is for the first 100 members of conference 6. The last request is for members 2 and 3 in conference 6. As can be seen from the examples, the returned list is truncated if there are fewer members than requested.
undefined-conference
conf
does not exist or is secret.
index-out-of-range
first
is higher than the number of members in conf
.
get-person-stat [49] ( pers-no : Pers-No ) -> ( Person );
This call returns the person pers-no
. This call does not return
all the information a client usually needs since the name is not
included in the Person data structure. Use get-conf-stat
on the
same number to get additional information about the person.
Example:
1 49 8 =1 44Hbyers@lage.lysator.liu.se 0000010000000000 00000000 44 21 19 18 6 97 5 198 1 0 2 3 0 0 0 0 0 0 1 0 0 2 1 50 8 =1 11HPaul Dekker 1001 8 6 19 18 6 97 5 198 1 8 6 19 18 6 97 5 198 1 8 0 8 0 0 0 77 1 1 0
This simple example shows how person number 8 is retrieved from the
server. The second call shows the get-conf-stat-old
call on the same
ID number.
undefined-person
pers-no
does not exist.
undefined-conference
pers-no
does not exist or is secret.
get-conf-stat-old [50] ( conf-no : Conf-No ) -> ( Conference-Old );
This call retrieves the conference data structure for conference number
conf-no
.
Important note: This call does not return the extra flag bits that were
introduced in protocol version 8. To get this information, use the
get-uconf-stat
call instead. However, clients should be able to
handle Conference-Old
structures with an arbitrary number of flag
bits since we may decide to change the behavior of this call in the
future.
Example:
1 50 1 =1 27HPresentation (av nya) möten 0000 48 11 17 13 8 91 5 255 1 18 34 21 17 6 97 4 197 1 0 0 0 0 0 0 77 0 1 1 1 50 8 =1 11HPaul Dekker 1001 8 6 19 18 6 97 5 198 1 8 6 19 18 6 97 5 198 1 8 0 8 0 0 0 77 1 1 0
This simple example retrieves conferences 1 and 8 from the server. Conference 1 is a regular conference, and conference 8 is a mailbox.
undefined-conference
conf-no
does not exist or is secret.
who-is-on [51] ( ) -> ( ARRAY Who-Info );
This call is obsolete. Please use who-is-on-dynamic
and
get-static-session-info
calls instead.
Nonetheless, servers should support this call since many clients still
use it.
This call should simply return a list of visible sessions (sessions where a person is logged in and the invisible flag is unset). The data structure is described elsewhere (see Who-Info).
This call always succeeds.
get-unread-confs [52] ( pers-no : Pers-No ) -> ( ARRAY Conf-No );
This call returns a list of conferences in which the person
pers-no
may have unread texts. This call will return a result for
any valid pers-no
. To retrieve information about secret persons,
or to get information about unread texts in secret conference, the
session must log on as a person with access to that information.
The result is guaranteed to include all conferences where pers-no
has unread texts. It may also return some extra conferences.
Passive memberships are never returned.
The returned conference numbers will be returned in the same order as they appear on the persons list of memberships.
Example:
1 52 7 =1 2 { 1 6 } 1 52 1 %1 10 0 1 52 1000 %1 10 0
This example shows how a session first retrieves the list of conferences in which person 7 has unread texts. The next request is for the unread conferences of person 1, but that happens to be a conference. The last request is for the unread conferences of person 1000, but that person didn't exist in the test database.
login-first
undefined-person
pers-no
does not exist or is secret.
send-message [53] (( recipient : Conf-No; message : HOLLERITH )) -> ( );
This call sends the message message
to all members of
recipient
using async-send-message
. If
recipient
is 0, the message is sent to all sessions that are
logged in.
The message is sent to all members of recipient
that are
currently logged in, and where the passive
and
passive-message-invert
bits of the Membership-Type
(see Membership-Type) don't prevent the message from being
delivered.
Example:
1 53 4 14HThis is a test =1 1 53 1 14HThis is a test :3 12 1 8 14HThis is a test =1 1 53 0 14HThis is a test :3 12 0 8 14HThis is a test =1 1 53 5 14HThis is a test %1 16 0 1 53 3 14HThis is a test %1 42 0
login-first
string-too-long
message
is too long.
undefined-conference
recipient
does not exist or is secret.
feature-disabled
message-not-sent
get-session-info [54] ( session-no : Session-No ) -> ( Session-Info );
This call is obsolete. It has been replaced by
get-session-info-ident
, which in turn is also obsolete. See
get-session-info-ident
for more information.
login-first
undefined-session
session-no
does not exist.
disconnect [55] ( session-no : Session-No ) -> ( );
This call disconnects the session session-no
from the LysKOM
server. A session can always disconnect itself, even without logging in.
If the session is logged in as user foo it can also disconnect any
session logged in as a person for which foo is the supervisor.
Session number zero is always interpreted as the session making the call, so the easiest way to disconnect the current session is to disconnect session zero.
Example:
1 56 =1 7 1 55 7 =1 :2 13 8 7 Connection closed by foreign host.
In this example the client asks for its own session number, then disconnects itself (disconnection session 0 would have had the same effect.) The asynchronous message sent just before the session is disconnected is the logout message for the user that was logged on in the session. The "Connection closed by foreign host." is not part of the server output. This message was generated by telnet.
login-first
session-no
is not the
session issuing the call.
permission-denied
undefined-session
session-no
does not exist.
who-am-i [56] ( ) -> ( Session-No );
This call simply returns the session number of the session issuing the call.
Example:
1 56 =1 7
In this example the session number of the session issuing the call is seven.
This call always succeeds.
set-user-area [57] (( pers-no : Pers-No; user-area : Text-No )) -> ( );
This call sets the user-area field for the person pers-no
in the
database to the text user-area
. The user area is used to store
client data for a particular person. See The User Area, for more
details.
Example:
1 49 7 =1 25Hdavby@lage.lysator.liu.se 0000010000000000 00000000 6 58 21 19 6 97 6 199 1 0 458 7 3 12 7 12 0 0 3 0 0 4 1 57 7 11 =1 1 49 7 =1 25Hdavby@lage.lysator.liu.se 0000010000000000 00000000 6 58 21 19 6 97 6 199 1 11 458 7 71 2592 7 13 0 0 3 1 0 4
In this example the user area of person 7 is set to text number 11. The original user area was text numbers zero, which means that the person had no user area.
login-first
undefined-person
pers-no
does not exist or is secret.
permission-denied
pers-no
to complete the call.
get-last-text [58] ( before : Time ) -> ( Text-No );
This call returns the number of the last text created before
before
. There is no guarantee that the text is readable by the
person making the request, or that the text even exists.
This call assumes that all texts are written in chronological order, when the time is expressed in the local time zone of the server. That may not always be the case in real life. When daylight savings time reverts to standard time the same time span will occur twice. The clock of the server may also have been adjusted manually from time to time. This protocol specification does not mandate what the server should do in such cases.
If set-connection-time-format
has been used with
use-utc
set to 1, the before
time should be expressed in
UTC. Daylight savings time will not be an issue in that case.
Example:
1 58 49 6 22 19 6 97 6 199 1 =1 11 1 58 49 6 22 18 6 97 6 199 1 =1 8 1 58 49 6 22 1 6 97 6 199 1 =1 0
In this example the text created most recently before 22:06 on July 19, 1997 was text number 11; the text created most recently before 22:06 on July 18 was text number 8; and the text created most recently before 22:06 on July 1st was text number 0, which means that there is no text that old in the database.
login-first
create-anonymous-text-old [59] (( text : HOLLERITH; misc-info : ARRAY Misc-Info )) -> ( Text-No );
Similar to create-text-old
, but the text is created with the
author
field set to zero. Not even the server has a record of
who created the text.
The original intended use for this call was for importing texts from other sources, such as WWW, FTP or Gopher, but some clients include explicit support for sending anonymous texts to a server.
It is only possible to send anonymous texts to a conference with the right flag bit set.
The only Misc-Info items valid for this call in the misc-info
array are recpt
, cc-recpt
, bcc-recpt
(introduced
in protocol version 10), comm-to
and footn-to
.
Example:
1 28 20HExampleMessage body 3 { 0 5 1 112 2 33467 } :16 0 33502 13 16 15 16 6 97 3 196 1 0 1 20 0 5 { 0 5 6 148 1 112 6 3438 2 33467 } =1 33502
In the example,
represents a linefeed.
In this example, person 119 creates a text containing a subject and a one-line body. The recipient of the text is conference five, conference 112 is a CC recipient and the text is a comment to text 33467. The server reply indicates that the new text has been given number 33502. Finally there is an asynchronous message sent to all members of recipient conferences. Note how the message was sent before the reply to the client. The misc-info list in this message has two additional fields, the local numbers of the text in each of its recipient conferences.
login-first
string-too-long
text
is longer than the maximum length of a message.
temporary-failure
no-such-text
not-author
footnote-limit
comment-limit
access-denied
anonymous-rejected
illegal-misc
find-next-text-no [60] ( start : Text-No ) -> ( Text-No );
This call returns the next readable text in the database created after
text start
. start
does not have to be a valid or readable
text number, as shown in the examples.
Example:
1 60 0 =1 2 1 60 2 =1 4
This example shows how to retrieve the first readable text in the LysKOM
database by calling find-next-text-no
with start
set to zero.
In the example, the first text is number 2. The second example gets the
text following number 2, which happens to be text number 4.
login-first
no-such-text
start
.
find-previous-text-no [61] ( start : Text-No ) -> ( Text-No );
This call returns the first readable text in the database created most
recently before start
. start
does not have to be a valid
or readable text number, as shown in the examples.
Example:
1 61 134217727 =1 11 1 61 4 =1 2
This example shows that the last readable text in the database is number 11 (unless by some odd coincidence all text from 11 to text number 134217727 have been deleted.) It also shows that the most recent text before number 4 is text number 2.
login-first
no-such-text
start
.
login [62] (( person : Pers-No; passwd : HOLLERITH; invisible : BOOL )) -> ( );
This call is used to log in. The session is logged in as person number
person
if passwd
is the correct password for that person.
If invisible
is true, the session is invisible: it will not be
returned by who-is-on
and who-is-on-ident
, and the
dynamic session info (see Dynamic-Session-Info)
will have the invisible flag set.
Invisible sessions are primarily used by software agents that do not act on the behalf of real users.
Example:
1 62 7 6Hgazonk 1 =1 1 62 7 6Hgazonk 0 :2 9 7 1 1 62 7 6Hgazonk 0 :2 13 7 1 :2 9 7 1 =1
This example first shows a session log in as person seven with the invisible flag set. Because of this the asynchronous login message is not sent. The second call logs in as person seven again. This time a login message is sent, but not a logout message since the login was invisible. The third example shows a third login as person 7, but this time both the logout and login messages are sent.
undefined-person
person
does not exist.
login-disallowed
person
does not have enough
privileges to override.
invalid-password
passwd
is not the password of person
and the
currently logged in person is not the supervisor of person
and
does not have enough privileges set and enabled to log in anyway.
conference-zero
bad-bool
invisible
must be either 0
or 1
.
who-is-on-ident [63] ( ) -> ( ARRAY Who-Info-Ident );
This call is obsolete. It has been replaced by
who-is-on-dynamic
and get-static-session-info
. It
returns a list of all visible sessions.
This call always succeeds.
get-session-info-ident [64] ( session-no : Session-No ) -> ( Session-Info-Ident );
This call is obsolete. Use who-is-on-dynamic
combined with
get-static-session-info
instead.
login-first
undefined-session
session-no
does not exist.
re-lookup-person [65] ( regexp : HOLLERITH ) -> ( ARRAY Pers-No );
This call is obsolete. It has been replaced by re-z-lookup
.
It returns a list of persons matching the regular expression
regexp
. The regexp syntax used is that of the ed
(1)
Unix utility.
regexp-error
regexp
. Perhaps the pattern is
not a correct regexp.
re-lookup-conf [66] ( regexp : HOLLERITH ) -> ( ARRAY Conf-No );
This call is obsolete. It has been replaced by re-z-lookup
. It
returns a list of conferences matching the regular expression
regexp
. The regexp syntax used is that of the ed
(1) Unix
utility.
regexp-error
regexp
. Perhaps the pattern is
not a correct regexp.
lookup-person [67] ( name : HOLLERITH ) -> ( ARRAY Pers-No );
This call is obsolete. It has been replaced by lookup-z-name
.
This call returns a list of persons with names matching the
contracted name in name
. See Name Expansion, for a
description of the matching process.
This call always succeeds.
lookup-conf [68] ( name : HOLLERITH ) -> ( ARRAY Conf-No );
This call is obsolete. It has been replaced by lookup-z-name
.
This call returns a list of conferences with names matching the
contracted name in name
. See Name Expansion, for a
description of the matching process.
This call always succeeds.
set-client-version [69] (( client-name : HOLLERITH; client-version : HOLLERITH )) -> ( );
This call is used to tell the server which client and which version of
that client is being used. The name of the client is passed in
client-name
and the version in client-version
. The
information sent in this call is made available to other sessions
through the get-client-name
and get-client-version
calls. This call should be used exactly once per session.
The following names are currently registered:
elisp-client | The famous CPU hog.
|
nilkom | C++ experiment
|
tkom | C++ experiment
|
getmail | Postmaster
|
ttykom | The one and second tty client by Linus
|
WinKOM | Windows client
|
JySKom | JSK Web Client
|
Example:
1 56 =1 7 2 69 11Helisp-client 4H0.45 =2 3 70 7 =3 11Helisp-client 4 71 7 =4 4H0.45
In this example the who-am-i
call is used to find the ID of
the current session. Next, set-client-version
is used
to set the name of the client to "elisp-client" and the version to
"0.45". The third call is to get-client-name
, which
returns the string just sent to the server. Finally
get-client-version
is used to retrieve the client version of
session number 7, which is, as expected, the string "0.45".
string-too-long
client-name
or client-version
is too long.
client-is-crazy
error-status
is undefined.
get-client-name [70] ( session : Session-No ) -> ( HOLLERITH );
This call returns the name of the client that owns session number
session
. This client name string returned is the one set by the
client using set-client-version
. If set-client-version
has not been issued in session number session
, the empty string
is returned.
See set-client-version, for an example of this call.
login-first
undefined-session
session
does not exist.
get-client-version [71] ( session : Session-No ) -> ( HOLLERITH );
This call returns the version of the client that owns session number
session
. This client version string returned is the one set by
the client using set-client-version
. If
set-client-version
has not been issued in session number
session
, the empty string is returned.
See set-client-version, for an example of this call.
login-first
undefined-session
session
does not exist.
mark-text [72] (( text : Text-No; mark-type : INT8 )) -> ( );
This call associates the mark mark-type
with the text
text
. The list of marks set by a person can be retrieved using
the get-marks
call.
Currently, servers do not associate any particular meaning to the different types of marks, but that may change in the future. Currently, servers should not delete texts that have marks, except by user request.
Example:
1 23 =1 0 * 2 72 110 230 =2 3 23 =3 1 { 110 230 }
This example shows how a person with no marks set sets mark 230 on text
number 110. The calls to get-marks
show the effect of the call.
login-first
no-such-text
text
does not exists or is secret.
permission-denied
text
.
undefined-person
mark-limit
text
.
unmark-text [73] ( text-no : Text-No ) -> ( );
This call removes any marks the logged-in person has set on the text
text-no
.
Example:
1 23 =1 1 { 110 230 } 2 73 110 =2 3 23 =3 0 *
This example shows how a user with a mark set on text number 110 removes
it using the unmark-text
call.
login-first
undefined-person
not-marked
text-no
was not marked.
re-z-lookup [74] (( regexp : HOLLERITH; want-persons : BOOL; want-confs : BOOL )) -> ( ARRAY Conf-Z-Info );
This call returns a list of those conferences and/or persons matching
the regular expression regexp
. If want-confs
is true, then
the result will include non-mailbox conferences. If
want-persons
is true, then the result will include mailbox
conferences.
See also lookup-z-name, for an alternative way to look up names.
Refer to Name Expansion, for more details on how name lookup works.
Example:
1 74 2H.* 1 1 =1 4 { 15HTest Conference 0000 10 11HDavid Byers 1001 6 21HTrains (-) Discussion 0000 11 4HJohn 1001 9 } 2 74 2H.* 0 1 =2 2 { 15HTest Conference 0000 10 21HTrains (-) Discussion 0000 11 } 3 74 7HT.*[cC] 1 1 =3 2 { 15HTest Conference 0000 10 21HTrains (-) Discussion 0000 11 }
This example shows three calls to re-z-lookup
. The first call
returns all conferences and persons in the entire database, in this case
two conferences and two persons. The second example uses the same
regular expression, but in this case, the call specifies that the
result is only to contain conferences, so the two persons are not
returned. The third example simply returns all names matching the
pattern "T.*[cC]".
regexp-error
regexp
. Perhaps the pattern is
not a correct regexp.
bad-bool
want-persons
and want-confs
must be either 0
or
1
.
get-version-info [75] ( ) -> ( Version-Info );
This call returns information about the server version. The data returned by this call are primarily useful for presenting to the user. A client should not use this call to determine what the server's capabilities are.
Example:
1 75 =1 9 7Hlyskomd 5H1.9.0
This example lets us know that the server is lyskomd, version 1.9.0, which at the time of writing this is the only really usable server.
This call always succeeds.
lookup-z-name [76] (( name : HOLLERITH; want-pers : BOOL; want-confs : BOOL )) -> ( ARRAY Conf-Z-Info );
This call looks up the name name
in the server, and returns a
list of all matching conferences and/or persons. If want-confs
is true, then the result will include conferences that are not
mailboxes. If want-pers
is true, then the result will include
conferences that are mailboxes.
See also re-z-lookup, for an alternative way to look up names.
Refer to Name Expansion, for details on the matching process.
Example:
1 76 0H 1 1 =1 4 { 15HTest Conference 0000 10 11HDavid Byers 1001 6 21HTrains (-) Discussion 0000 11 4HJohn 1001 9 } 2 76 0H 0 1 =1 2 { 15HTest Conference 0000 10 21HTrains (-) Discussion 0000 11 } 3 76 3HT C 1 1 =3 1 { 15HTest Conference 0000 10 }
This example shows three calls to lookup-z-name
. The first call
retrieves all conferences and persons in the server. The second request
looks up the same name as the first, but this time the result is
restricted to conferences. The final request requests all conferences
and persons matching the pattern "T C".
bad-bool
want-pers
and want-confs
must be either 0
or
1
.
set-last-read [77] (( conference : Conf-No; last-read : Local-Text-No )) -> ( );
This call tells the server that the last local text number the person
issuing the call has read in conference conference
is
last-read
. This call is typically used when a user wants to have
a specific number of unread texts in a particular conference.
Example:
1 9 7 6 =1 2 4 22 18 6 97 5 198 1 6 100 6 0 * 2 77 6 3 =2 3 9 7 6 =3 2 4 22 18 6 97 5 198 1 6 100 3 0 *
This example shows how person 7 originally had read everything up to and
including local text number 6 in conference 6. After the call to
set-last-read
, the query-read-texts-old
call reports that
person 7 has read everything up to and including local text number 3.
login-first
undefined-conference
conference
does not exist or is secret.
not-member
conference
.
get-uconf-stat [78] ( conference : Conf-No ) -> ( UConference );
This call returns some information about conference conference
.
The information it returns is sufficient for most uses of conference
information, and this call should be used instead of
get-conf-stat
wherever possible. It uses less
bandwidth and the lyskomd server always keeps all UConference
objects in memory, so this call is significantly faster than
get-conf-stat
.
This is also currently the only way to get all the flag bits of the conference.
Example:
1 50 6 =1 8HTestconf 0000 1 34 21 17 6 97 4 197 1 37 3 22 18 6 97 5 198 1 5 4 5 0 5 0 77 4 1 6 2 78 6 =2 8HTestconf 00001000 6 77 3 50 7 =3 11HDavid Byers 1111 13 4 19 18 6 97 5 198 1 13 4 19 18 6 97 5 198 1 7 0 7 0 0 0 77 1 1 0 4 78 7 =4 11HDavid Byers 11111000 0 77
This example shows the difference between get-conf-stat-old
and
get-uconf-stat
. In the first two examples conference 6 is
retrieved, and in the second two, conference 7, which happens to be a
person, is retrieved. Note the difference in length of the flag field.
undefined-conference
conference
does not exist or is secret.
conference-zero
conference
is zero.
set-info [79] ( info : Info-Old ) -> ( );
This call sets the server information retrieved by
get-info-old
. The version number in the info structure is
ignored (but must be present); all other fields are stored permanently
in the LysKOM database. This is a privileged call.
Example:
1 79 10901 1 2 3 4 1080 =1
This example sets the conference presentation conference to one, the user presentation conference to two, the motd conference to three and the news conference to four. It also sets the login message to text 1080. It also attempts to set the version number to 1.9.1, but that number is silently ignored by the server.
login-first
permission-denied
undefined-conference
info
does not exist.
no-such-text
info
does not exist.
mark-limit
info
already has the maximum number of marks.
text-zero
info
was set to 0. That should mean that there should be no message of the
day, and the current implementation of the server does accept MOTD to be
0.
accept-async [80] ( request-list : ARRAY INT32 ) -> ( );
This call advises the server that the client wants to receive the
asynchronous messages listed in request-list
. The server must
send these messages to the client when applicable, but may also send
other types of messages if it so desires. The list of currently
requested asynchronous messages may be retrieved using the
query-async
call.
Don't forget that message type 12 is personal, group and global text messages. Most users will not want these turned off.
Example:
1 80 2 { 7 9 } =1
This example tells the server that the client wants to receive asynchronous messages when the database is being synched (message 7) and when someone logs in (message 9).
If the client requests a message that the server does not send, the server will reply with an error message saying which message number it does not support. The call will succeed anyway. This mechanism is useful for clients that want new versions of some messages, but need to be compatible with older servers.
unknown-async
request-list
is not the number
of an async message the server knows about. The error-status
indicates the first offending number.
Please note that a bug in lyskomd 1.9.0 prevented the server from
sending this error message (frankly, we simply forgot about it.)
long-array
request-list
was too long. Servers should always accept a
request-list
that contains a lot more asynchronous messages than
the server sends, so that it can deal with newer clients. This error
message should only be returned if the client tries to trigger a buffer
overrun.
query-async [81] ( ) -> ( ARRAY INT32 );
This call queries the server for which asynchronous messages the client is receiving. Note that the client may not be able to turn off all messages returned in this list since the server may consider some messages to be mandatory. Also note that the client may still receive messages that are not listed in the result of this call. Even though those messages are turned off, the server may decide to send them under certain circumstances.
Example:
1 81 =1 7 { 0 5 7 9 11 12 13 }
In this example the client is receiving seven types of asynchronous messages: messages about new articles, changed names, database synching, new logins, rejected connections, personal messages and logouts. This particular set was the default for new connections to lyskomd 1.9 servers. See Asynchronous Messages, for the currently recommended list of asynchronous messages that servers should preselect.
This call always succeeds.
user-active [82] ( ) -> ( );
This call simply notifies the server that the user is active. The server uses the time of the last user-active call to calculate how long a user has been idle.
The client should send this to the server every time the user actively does something LysKOM-related, such as reads a texts, writes on a comment, gives a command, de-iconifies the LysKOM window, et c. However, the call should not be issued more than twice per minute, to avoid excessive network and server load.
This call always succeeds.
who-is-on-dynamic [83] (( want-visible : BOOL; want-invisible : BOOL; active-last : INT32 )) -> ( ARRAY Dynamic-Session-Info );
This call returns a list of information about sessions. Only sessions with the desired visibility and activeness are returned.
If want-visible
is true then information about visible sessions is
returned. If want-invisible
is true then information about
invisible sessions is returned. If they are both true sessions will be
included in the answer regardless of their visibility status.
Sessions where no-one is logged in are considered invisible, and the
invisible
flag is set in the corresponding
Dynamic-Session-Info
that is returned.
If active-last
is zero then the result is a list of all sessions
with the proper visibility. If active-last
is nonzero then only
sessions that have issued an user-active
call within the last
active-last
seconds are included in the list. Sessions that have
never issued an user-active
call are always included (if they
have the proper visibility).
bad-bool
want-visible
and want-invisible
must be either 0
or 1
.
get-static-session-info [84] ( session-no : Session-No ) -> ( Static-Session-Info );
This call returns information about session number session-no
.
The returned information cannot change until the session number is
reused (and that cannot happen until the server is shut down), so
clients are encouraged to cache the information.
login-first
undefined-session
session-no
does not exist.
get-collate-table [85] ( ) -> ( HOLLERITH );
This call returns the collate table being used by the server to match names. If index A and index B in the string are the same character, characters A and B are considered equivalent. An empty collate table indicates that the server considers all characters different.
Currently, the lyskomd server only deals with 8-bit characters. Clients should be prepared for collate tables of any length. Characters whose code are greater than the length of the collate table should be considered to be unique.
This call always succeeds.
create-text [86] (( text : HOLLERITH; misc-info : ARRAY Misc-Info; aux-items : ARRAY Aux-Item-Input )) -> ( Text-No );
Creates a new text with contents from text
and recipients
etc. defined by misc-info
(see The Misc-Info List). In
addition to the result, the server will send an asynchronous message
to all members of any of the recipients of the new text. It is not
defined whether this messages comes before or after the reply to
the create-text message. Clients should be prepared for either
situation.
The text up to the first linefeed is considered to be the subject line. The remaining text is the message body. Although messages with only a subject are valid, clients should avoid letting users create such messages.
The items in aux-items
are attached to the new text.
The only Misc-Info items valid for this call are recpt
,
cc-recpt
, bcc-recpt
(introduced in protocol version 10),
comm-to
and footn-to
.
login-first
string-too-long
text
is longer than the maximum length of a message.
temporary-failure
no-such-text
not-author
footnote-limit
comment-limit
index-out-of-range
error-status
indicates the text
number that should have been created if the limit hadn't been reached.
access-denied
anonymous-rejected
illegal-misc
illegal-aux-item
aux-items
is illegal. The tag might be
out of range, the item not applicable to texts or whatever
aux-item-permission
long-array
create-anonymous-text [87] (( text : HOLLERITH; misc-info : ARRAY Misc-Info; aux-items : ARRAY Aux-Item-Input )) -> ( Text-No );
Similar to create-text
, but the text is created the author
field set to zero. Not even the server has a record of who created the
text.
The original intended use for this call was for importing texts from other sources, such as WWW, FTP or Gopher, but some clients include explicit support for sending anonymous texts to a server.
It is only possible to send anonymous texts to a conference with the right flag bit set.
The only Misc-Info items valid for this call in the misc-info
array are recpt
, cc-recpt
, bcc-recpt
(introduced
in protocol version 10), comm-to
and footn-to
.
login-first
string-too-long
text
is longer than the maximum length of a message.
temporary-failure
no-such-text
not-author
footnote-limit
comment-limit
access-denied
anonymous-rejected
illegal-misc
illegal-aux-item
aux-items
is illegal. The tag might be
out of range, the item not applicable to texts or whatever
aux-item-permission
create-conf [88] (( name : HOLLERITH; type : Any-Conf-Type; aux-items : ARRAY Aux-Item-Input )) -> ( Conf-No );
This call is used to create new conferences. name
is the name of
the new conference and type
is its type. If successful, the call
returns the conference number of the newly created conference. The list
aux-items
contains the aux items to attach to the conference.
To use this call the session must have logged in as a user with privileges to create conferences (see Security).
login-first
permission-denied
create-conf
bit set. May also be an attempt to
create a conference with the letterbox
bit set.
conference-exists
name
already exists.
bad-name
name
contains invalid characters.
string-to-long
name
is too long to be used as a conference name.
secret-public
secret
bit set, but the
rd-prot
bit is cleared.
illegal-aux-item
aux-items
is illegal. The tag might be
out of range, the item not applicable to conferences or whatever
aux-item-permission
index-out-of-range
error-status
indicates
the conference number that should have been created if the limit
hadn't been reached.
create-person [89] (( name : HOLLERITH; passwd : HOLLERITH; flags : Personal-Flags; aux-items : ARRAY Aux-Item-Input )) -> ( Pers-No );
This call requests that the server create a new person with the name and
password given as arguments. To create a person the session must be
logged in as a person with sufficient privileges. The list
aux-items
contains the aux items that are to be attached to the
new person's mailbox conference. The person flags are set to
flags
.
The new person will be a member of exactly one conference: the associated mailbox. That membership will have priority 255 and (of course) position 0. All flags of the membership will be 0.
Unlike call number 5, this call does not do an automatic login.
login-first
permission-denied
create-pers
bit set.
person-exists
name
.
invalid-password
passwd
is not a valid password.
illegal-aux-item
aux-items
is illegal. The tag might be
out of range, the item not applicable to conferences or mailboxes or
whatever.
aux-item-permission
index-out-of-range
error-status
indicates
the person number that should have been created if the limit hadn't
been reached.
get-text-stat [90] ( text-no : Text-No ) -> ( Text-Stat );
Get information about text number text-no
. The text-stat contains
information about the size of the text, its recipients, comments, author
and more.
no-such-text
text-no
does not exist, or no read access.
This error code will also be used when attempting to fetch texts
without logging in first. (There are some texts that are readable
without logging in: the motd-of-lyskom (see set-motd-of-lyskom),
and texts with the world-readable
aux item set on them.)
text-zero
get-conf-stat [91] ( conf-no : Conf-No ) -> ( Conference );
This call retrieves the conference data structure for conference number
conf-no
.
undefined-conference
conf-no
does not exist or is secret.
modify-text-info [92] (( text : Text-No; delete : ARRAY Aux-No; add : ARRAY Aux-Item-Input )) -> ( );
This call deletes the aux-items listed in delete
from the text
text
and then adds the ones listed in add
to the text.
Either list may be empty, and the call is guaranteed to either
completely fail or completely succeed.
login-first
no-such-text
text
does not exist or is secret.
aux-item-permission
delete
, or
not enough permissions to add one or more of the items in add
.
illegal-aux-item
add
is illegal for some reason.
modify-conf-info [93] (( conf : Conf-No; delete : ARRAY Aux-No; add : ARRAY Aux-Item-Input )) -> ( );
This call deleted the aux-items listed in delete
from the
conference conf
and then adds the ones listed in add
to
the conference. Either list may be empty, and the call is guaranteed
to either completely fail or completely succeed.
login-first
undefined-conference
conf
does not exist or is secret.
aux-item-permission
delete
, or
not enough permissions to add one or more of the items in add
.
illegal-aux-item
add
is illegal for some reason.
get-info [94] ( ) -> ( Info );
This call returns the Info
structure for the server
(see Info). Clients should call this in order to find
out which conferences are used for presentations and such.
It can be issued without logging in.
This call always succeeds.
modify-system-info [95] (( items-to-delete : ARRAY Aux-No; items-to-add : ARRAY Aux-Item-Input )) -> ( );
This call modifies the aux-item list of the server information (which
can be retrieved using get-info
.) It only succeeds when issued by
a person with the admin bit set and privileges enabled.
The items in items-to-delete
are removed, and the items in
items-to-add
are added. This call is atomic; either all
deletions or additions succeeded, or none of them is made.
login-first
permission-denied
illegal-aux-item
aux-item-permission
query-predefined-aux-items [96] ( ) -> ( ARRAY INT32 );
Returns the list of aux-items that have specific definitions in the server. These items are the only items within the restricted tag ranges that can be created. The meanings of the various item types are defined in this document; see Aux-Item Types.
This call always succeeds.
set-expire [97] (( conf-no : Conf-No; expire : Garb-Nice )) -> ( );
This call sets the expire
field of the conference conf-no
to expire
. This call can only be issued by the conference's
supervisor or a privileged user.
login-first
undefined-conference
conf-no
does not exist or is secret.
permission-denied
conf-no
and not privileged enough to
complete the call anyway.
query-read-texts-10 [98] (( person : Pers-No; conference : Conf-No )) -> ( Membership-10 );
This call is obsolete. Use query-read-texts
.
This call is used to find the number of unread texts in a conference.
The data it returns is actually a membership structure which specifies
which texts have been read. It is up to the client to transform the data
to a more usable form. person
is the person being queried
and conference
is the conference in question.
Calling query-read-texts-10
does not require the session to be
logged in.
Example:
1 98 6 1 =1 4 32 5 11 12 7 93 1 193 1 1 20 133 3 { 135 136 137 } 5 43 8 3 12 7 93 1 193 1 01000000
This example finds the read texts for user 6 in conference 1. The
returned data indicates that conference 1 is the fifth conference on
the users' membership list (4
; remember that the
position
starts its count at 0), user last read the conference
on Monday July 12th, 1993 at 11:05:32 (32 5 11 12 7 93 1 193
1
), that it is the membership in conference number 1 (1
), that
the person has assigned priority 20 to the conference (20
) and
that all articles up to and including local number 133 (133
)
plus articles 135, 136 and 137 (3 { 135 136 137 }
) have been
read. The membership was added by person 5 (5
) at Monday July
12th, 1993 at 03:08:43 (43 8 3 12 7 93 1 193 1
) and it is
passive (01000000
).
undefined-person
person
does not exist, or no access to person.
undefined-conference
conference
does not exist, or is secret.
conference-zero
conference
is zero.
not-member
person
is not a member of conference
or insufficient
privileges to find out if person
is a member.
get-membership-10 [99] (( person : Pers-No; first : INT16; no-of-confs : INT16; want-read-texts : BOOL )) -> ( ARRAY Membership-10 );
This call is obsolete. Use get-membership
.
This call retrieves the membership record for a list of conferences
for a single person. person
is the person whose memberships are
to be retrieved. first
is the first position in the membership
list to retrieve, numbered from 0 and up. no-of-confs
is the
number of membership records to retrieve. If want-read-texts
is
0
, the server will not send the contents of the
read-texts
array of the memberships. (The size will be
transmitted, but a single asterisk (*
) will be sent instead of
the array itself.)
The server will return a membership list that is shorter than
no-of-confs
if no-of-confs
+ first
is larger than
the number of conferences the person is a member of. Elements of the
member list that the person requesting the list does not have sufficient
privileges to see may be cleared. Cleared elements simply have all
fields set to zero.
Example:
1 99 5 0 3 1 =1 2 { 0 49 14 17 13 8 91 5 255 1 5 255 0 0 * 5 49 14 17 13 8 91 5 255 1 00000000 1 20 14 22 17 6 97 4 197 1 6 100 2 0 * 5 49 14 17 13 8 91 5 255 1 00000000 } 2 99 5 0 1 1 =2 1 { 0 49 14 17 13 8 91 5 255 1 5 255 0 0 * 5 49 14 17 13 8 91 5 255 1 00000000 } 3 99 5 1 4 1 =3 1 { 1 20 14 22 17 6 97 4 197 1 6 100 2 0 * 5 49 14 17 13 8 91 5 255 1 00000000 }
In this example we retrieve the memberships of person 5. The first call asks for three memberships, starting with number 0. Since this person is only a member of two conferences, the list returned only contains two memberships. The next two calls retrieve a single membership each. The first by asking for only one, and the second by asking for four memberships, starting with number 1.
login-first
undefined-person
person
does not exist.
undefined-conference
person
does not exist or is secret.
index-out-of-range
first
is higher than the index of the last conference in the
person's membership list.
bad-bool
want-read-texts
must be either 0
or 1
.
add-member [100] (( conf-no : Conf-No; pers-no : Pers-No; priority : INT8; where : INT16; type : Membership-Type )) -> ( );
Make the person pers-no
a member of conference conf-no
.
The membership priority is set to priority
and its position in
the membership list is set to where
.
The membership flags are set to type
. If the current user is
adding a user he isn't supervisor of, the invitation
bit of
type
is automatically set by the server.
This call can be used to change the priority, position and flags of a conference in the person's membership list if the person is already a member of the conference. The person doing this must either be a supervisor of the affected person, or have sufficient privileges enabled.
Example:
1 99 119 0 10 0 =1 1 { 49 14 17 13 8 91 5 255 1 119 255 0 0 * 119 00001111 } 1 100 1 119 250 0 10000000 =1 1 100 119 119 251 1 00000000 =1 1 99 119 0 10 0 =1 2 { 52 30 14 11 5 96 2 162 1 1 250 0 0 * 119 00000000 49 14 17 13 8 91 5 251 1 119 255 0 0 * 10000000 }
This example makes person 119 (me) a member of conference number 1 and changes the priority and some flags of the preexisting membership in conference 119. The priority is set to 250 and the conference is placed first in the membership list. The first and last calls of the example show the membership list for person 119 before and after the calls.
login-first
undefined-conference
conf-no
does not exist or is secret.
conference-zero
conf-no
is zero.
undefined-person
pers-no
does not exist
access-denied
conf-no
or to change privileges, position or type of a preexisting membership.
permission-denied
pers-no
is already a member of conference conf-no
,
but the person logged on is not a supervisor and does not have enough
privileges to change the priorities of person pers-no
.
get-members [101] (( conf : Conf-No; first : INT16; no-of-members : INT16 )) -> ( ARRAY Member );
This call returns a list of members of the conference conf
.
first
is the first index in the membership to return, numbered
from zero and up. no-of-members
is the maximum number of members
to return.
Some of the elements of the result may be cleared if the person requesting the information does not have sufficient privileges to see the contents. Cleared elements simply have all fields set to zero.
Example:
1 101 1 0 100 =1 4 { 7 7 00000000 8 8 00000000 9 8 00000000 10 10 00000000 } 1 101 6 0 100 =1 4 { 5 5 01000000 7 7 01000000 9 8 10000000 10 10 00000000 } 1 101 6 2 2 =1 2 { 9 8 10000000 10 10 00000000 }
In this example the client first requests the first 100 members in conference 1. The second request is for the first 100 members of conference 6. The last request is for members 2 and 3 in conference 6.
undefined-conference
conf
does not exist or is secret.
index-out-of-range
first
is higher than the number of members in conf
.
set-membership-type [102] (( pers : Pers-No; conf : Conf-No; type : Membership-Type )) -> ( );
This call modifies the type of a membership. The person pers
membership in conference conf
is affected. The server may impose
arbitrary restrictions on how the membership type may be changed.
Typically it will only be possible to clear the invitation
bit.
It is possible that the server will not permit the secret
bit to
be set. Attempting to set a membership type that does not agree with
the server's restrictions will result in an error.
login-first
conference-zero
conf
is zero.
undefined-conference
conf
does not exist or is secret or the person
pers
does not exist or is secret.
permission-denied
pers
.
not-member
pers
is not a member of conference conf
.
invalid-membership-type
type
was not compatible with
restrictions set on the server or on the conference conf
local-to-global [103] (( conf-no : Conf-No; first-local-no : Local-Text-No; no-of-existing-texts : INT32 )) -> ( Text-Mapping );
This call retrieves information that makes it possible to convert
no-of-existing-texts
existing local text numbers starting at
first-local-no
to global text numbers, provided that there are
that many local texts.
The conf-no
parameter specifies which conference to look up local
numbers in. first-local-no
is the first number that the client
is interested in. no-of-existing-texts
is the maximum number of
texts the client wants information about. Legal values for
no-of-existing-texts
are 1-255 (inclusive).
The server will return a sparse or dense Text-Mapping depending on the
how many deleted texts there are after first-local-no
.
The local-to-global-reverse
request can be useful if you
want to traverse the mapping from higher to lower numbers.
Example:
1 103 93 1 5 =1 1 7 1 1 1 6 { 1003 1005 1009 1029 0 1034 } 2 103 93 1 6 =2 1 63 1 0 6 { 1 1003 2 1005 3 1009 4 1029 6 1034 62 1302 } 3 103 93 50 10 =3 50 70 0 0 2 { 62 1302 69 1006 }
The above example shows three calls to local-to-global
. (Extra
newlines have been inserted in the result of the two final calls to make
the result more readable.)
The first call requests information about the first five existing
texts in conference 93. The result contains information about texts
in the range 1-7 (including the lower limit, but not the upper), and
there are more texts. The server uses the dense form of the
Text-Mapping
. As can be seen from the result, they have local
text numbers 1, 2, 3, 4 and 6. The global text number corresponding
to local text number 5 is sent as 0, indicating that it doesn't exist.
In the second call, the client requests the same information, but one
additional text. The result looks dramatically different, since the
next existing text in this example has local text number 62. The
result contains information about texts in the range 1-63 (including
the lower limit, and excluding the upper), and there are more texts.
The server of course uses the sparse form of the Text-Mapping
.
The final call shows what happens when first-local-no
doesn't
exist. The result contains information about texts in the range 50-70
(including the lower limit and excluding the upper); only local text
number 62 and 69 actually exists in that range. 69 is the highest
local text number.
(Note that local text number 69 corresponds to global text number 1006,
which is lower than 1302. Situations like this often occurs when
add-recipient
is used.)
login-first
long-array
no-of-existing-texts
was larger than 255.
conf-zero
conf-no
was set to 0.
local-text-zero
first-local-no
was set to 0.
undef-conf
access-denied
no-such-local-text
first-local-no
is greater than the highest local text number that
ever existed in the conference.
map-created-texts [104] (( author : Pers-No; first-local-no : Local-Text-No; no-of-existing-texts : INT32 )) -> ( Text-Mapping );
Return text numbers for existing texts that author
has written.
Just as each conference has a mapping from local text numbers to global text numbers, each person has a mapping from the N:th text written by him to the global text number. This function can be used to retrieve part of that mapping.
More information and examples may be found in local-to-global.
The map-created-texts-reverse
request can be useful if you
want to traverse the mapping from higher to lower numbers.
login-first
long-array
no-of-existing-texts
was larger than 255.
conf-zero
author
was set to 0.
local-text-zero
first-local-no
was set to 0.
undef-pers
no-such-local-text
first-local-no
is greater than the highest local text number that
ever existed in the conference.
access-denied
set-keep-commented [105] (( conf-no : Conf-No; keep-commented : Garb-Nice )) -> ( );
Sets the keep-commented
field of the conference conf-no
to
keep-commented
. This call can only be issued by a conference's
supervisor or a privileged user.
login-first
undefined-conference
conf-no
does not exist or is secret.
permission-denied
conf-no
and not privileged enough to
complete the call anyway.
set-pers-flags [106] (( pers-no : Pers-No; flags : Personal-Flags )) -> ( );
Set the flags field of person pers-no
to flags
. This call
can only be issued by the person supervisor or a privileged user.
login-first
conference-zero
pers-no
parameter is zero.
undefined-person
permission-denied
query-read-texts [107] (( person : Pers-No; conference : Conf-No; want-read-ranges : BOOL; max-ranges : INT32 )) -> ( Membership );
This call is used to find the number of unread texts in a conference.
The data it returns is actually a membership structure which specifies
which texts have been read. It is up to the client to transform the
data to a more usable form. person
is the person being queried
and conference
is the conference in question.
If want-read-ranges
is 0
, the server will not send the
contents of the read-ranges
array of the memberships. (The
size will be transmitted, but a single asterisk (*
) will be
sent instead of the array itself.) The max-ranges
argument is
ignored in this case.
If want-read-ranges
is 1
, the read-ranges
array
will be returned. If max-ranges
is non-zero, the array will be
truncated to max-ranges
ranges. (It isn't possible to
determine if the array has been truncated, or if the array actually
contained exactly that many ranges.) Setting max-ranges
to
1
gives you enough information to find out the first unread
text.
When you call this request with want-read-ranges
set to
1
, the ranges will expand to include any adjacent texts that
are now deleted. This may not happen if get-membership
is
used to retrieve the information.
Calling query-read-texts
does not require the session to be
logged in.
Example:
1 107 6 1 1 0 =1 4 32 5 11 12 7 93 1 193 1 1 20 2 { 1 133 135 137 } 5 43 8 3 12 7 93 1 193 1 01000000
This example finds the read texts for user 6 in conference 1. The
returned data indicates that conference 1 is the fifth conference on
the users' membership list (4
; remember that the
position
starts its count at 0), user last read the conference
on Monday July 12th, 1993 at 11:05:32 (32 5 11 12 7 93 1 193
1
), that it is the membership in conference number 1 (1
), that
the person has assigned priority 20 to the conference (20
) and
that all texts 1-133 and 135-137 have been read (2 { 1 133 135
137 }
). The membership was added by person 5 (5
) at Monday
July 12th, 1993 at 03:08:43 (43 8 3 12 7 93 1 193 1
) and it is
passive (01000000
).
undefined-person
person
does not exist, or no access to person.
undefined-conference
conference
does not exist, or is secret.
conference-zero
conference
is zero.
not-member
person
is not a member of conference
or insufficient
privileges to find out if person
is a member.
bad-bool
want-read-ranges
must be either 0
or 1
.
get-membership [108] (( person : Pers-No; first : INT16; no-of-confs : INT16; want-read-ranges : BOOL; max-ranges : INT32 )) -> ( ARRAY Membership );
This call retrieves the membership record for a list of conferences
for a single person. person
is the person whose memberships are
to be retrieved. first
is the first position in the membership
list to retrieve, numbered from 0 and up. no-of-confs
is the
number of membership records to retrieve.
If want-read-ranges
is 0
, the server will not send the
contents of the read-texts
array of the memberships. (The
sizes will be transmitted, but a single asterisk (*
) will be
sent instead of the array itself.) The max-ranges
argument is
ignored in this case.
If want-read-ranges
is 1
, the read-ranges
arrays
of the memberships will be returned. If max-ranges
is
non-zero, each array will be truncated to max-ranges
ranges.
(It isn't possible to determine if an array has been truncated, or if
that array actually contained exactly that many ranges.) Unlike
query-read-texts
, the ranges may not expand to include
deleted texts, so it isn't certain that you get enough information
to find the first unread text if you specify a non-zero
max-ranges
argument.
The server will return a membership list that is shorter than
no-of-confs
if no-of-confs
+ first
is larger than
the number of conferences the person is a member of. Elements of the
member list that the person requesting the list does not have sufficient
privileges to see may be cleared. Cleared elements simply have all
fields set to zero.
Example:
1 108 5 0 3 1 0 =1 2 { 0 49 14 17 13 8 91 5 255 1 5 255 0 * 5 49 14 17 13 8 91 5 255 1 00000000 1 20 14 22 17 6 97 4 197 1 6 100 1 { 1 2 } 5 49 14 17 13 8 91 5 255 1 00000000 } 2 108 5 0 1 1 0 =2 1 { 0 49 14 17 13 8 91 5 255 1 5 255 0 * 5 49 14 17 13 8 91 5 255 1 00000000 } 3 108 5 1 4 1 0 =3 1 { 1 20 14 22 17 6 97 4 197 1 6 100 1 { 1 2 } 5 49 14 17 13 8 91 5 255 1 00000000 }
In this example we retrieve the memberships of person 5. The first call asks for three memberships, starting with number 0. Since this person is only a member of two conferences, the list returned only contains two memberships. The next two calls retrieve a single membership each. The first by asking for only one, and the second by asking for four memberships, starting with number 1.
login-first
undefined-person
person
does not exist.
undefined-conference
person
does not exist or is secret.
index-out-of-range
first
is higher than the index of the last conference in the
person's membership list.
bad-bool
want-read-ranges
must be either 0
or 1
.
mark-as-unread [109] (( conference : Conf-No; text : Local-Text-No )) -> ( );
Marks text text
in conference number conference
as not
read for the current user. This call updates the membership record
for the user. It can be used to undo the effect of
mark-as-read
.
Example:
1 9 6 7 =1 20 32 11 17 6 96 3 198 1 7 1 241 0 * 1 78 7 =1 13HInlägg }t mig 00001000 241 1 1 27 7 241 =1 1 9 6 7 =1 20 32 11 17 6 96 3 198 1 7 1 240 0 *
This example shows person 6 marking local text number 241 in
conference 7 as not read. In the first query-read-texts-old
call the person has read local text 241, and nothing higher. The
mark-as-read
call is reflected in the second
query-read-texts-old
call, where the user is seen to have read
text 240 in conference 7, but nothing higher.
To mark a global text number as not read it is necessary to translate
it into local text numbers by looking at the misc-info list in the
Text-Stat
and calling mark-as-read
once for each
recipient.
Attempts to mark a deleted text as unread will appear to succeed, but might have no effect, since the server will automatically mark them as read, sooner or later.
login-first
undefined-conference
conference
does not exist or is secret.
conference-zero
conference
is zero.
not-member
conference
.
no-such-local-text
text
is not, and has never been, a local text number in
conference
. The error argument contains the invalid number.
local-text-zero
text
is zero.
set-read-ranges [110] (( conference : Conf-No; read-ranges : ARRAY Read-Range )) -> ( );
This call tells the server that the person issuing the call has read
exactly those texts specified by read-ranges
in conference
conference
. This call is typically used to migrate a
membership from one person to another. It can also be used instead of
set-unread
or set-last-read
.
The server may automatically extend the ranges with adjacent local text numbers that are deleted.
Example:
1 9 7 6 =1 2 4 22 18 6 97 5 198 1 6 100 6 0 * 2 110 6 3 { 1 20 23 23 25 28 } =2 3 9 7 6 =3 2 4 22 18 6 97 5 198 1 6 100 20 5 { 23 25 26 27 28 }
This example shows how person 7 originally had read everything up to
and including local text number 6 in conference 6. After the call to
set-read-ranges
, the query-read-texts-old
call reports
that person 7 has read the local text numbers 1-20, 23 and 25-28.
login-first
undefined-conference
conference
does not exist or is secret.
conference-zero
conference
is zero.
not-member
conference
.
local-text-zero
read-ranges
contains the number 0.
no-such-local-text
read-ranges
contains a local text number that never has
existed.
long-array
read-ranges
array is too long. error-status
indicates the maximum range allowed.
invalid-range
first-read
field in one of the ranges in
read-ranges
is greater than last-read
. The
error-status
indicates the interval (0 for the first interval,
1 for the second, and so on).
invalid-range-list
first-read
field in one of the ranges in
read-ranges
is not greater than the last-read
field of
the previous range. The error-status
indicates the interval
(0 for the first interval, 1 for the second, and so on).
get-stats-description [111] ( ) -> ( Stats-Description );
Return a list of the supported statistical measurements. This request always succeeds, and always returns the same value for the duration of a session, so a client doesn't need to use it more than once per session.
See Stats-Description, for more info about the data type. See Measured Properties, for more info on what the returned values means.
Example:
1 111 =1 2 { 3HX-a 3HX-b } 4 { 0 60 300 900 }
This call always succeeds.
get-stats [112] ( what : HOLLERITH ) -> ( ARRAY Stats );
Return a list of the statistical measurements of what
. The
number of elements in the result corresponds to the when
field
of the Stats-Description
returned by
get-stats-description
.
See Measured Properties, for more info on the what
argument. See also Stats-Description.
Example:
1 112 7Hclients =1 4 { 20 0 0 19.80 1.2 1.1 18.33 1.2 1.1 16.11 1.2 1.2e-02 }
Assuming that the when
field of get-stats-description
contains the time periods 0, 60, 300 and 900, the above result
indicates that there is currently 20 connected clients. The past
averages for 1, 5 and 15 minutes are 19.8, 18.33 and 16.11 connected
clients.
You can use this call even if you are not logged in.
feature-disabled
undefined-measurement
what
.
access-denied
enable
request, by a receiving a privilege bit, or
in an implementation-defined way.
get-boottime-info [113] ( ) -> ( Static-Server-Info );
Return status information that was current when the server started. This include the time of the last restart. Clients are encouraged to cache the return value of this request, as it will never change while a client is connected.
This call always succeeds
first-unused-conf-no [114] ( ) -> ( Conf-No );
Return first conference number that is not yet used.
This call always succeeds
first-unused-text-no [115] ( ) -> ( Text-No );
Return first text number that is not yet used.
This call always succeeds
find-next-conf-no [116] ( start : Conf-No ) -> ( Conf-No );
This call returns the next conference that you are allowed to see in
the database created after conference start
. start
does
not have to be a valid or readable conference number, as shown in the
examples.
Example:
1 116 0 =1 2 1 116 2 =1 4
This example shows how to retrieve the first readable conference in
the LysKOM database by calling find-next-conf-no
with
start
set to zero. In the example, the first conference is number 2.
The second example gets the conference following number 2, which happens to
be conference number 4.
login-first
undefined-conference
start
.
find-previous-conf-no [117] ( start : Conf-No ) -> ( Conf-No );
This call returns the last accessible conference in the database
created before start
. start
does not have to be a valid
or readable conference number, as shown in the examples.
Example:
1 114 =1 12345 2 117 12345 =2 12330 1 117 12330 =1 12329
This example uses first-unused-conf-no
to find the largest
number that can meaningfully be sent to find-previous-conf-no
.
It then uses the request twice to find that the two conferences with
highest conference numbers that are accessible to the user logged in
is 12329 and 12330.
login-first
undefined-conference
start
.
get-scheduling [118] ( session-no : Session-No ) -> ( Scheduling-Info );
Get the current scheduling information for a session. You can use 0
as session-no
to get information about the current session.
set-scheduling
contains an example.
The first error code in the list below that is applicable will be returned.
login-first
session-no
is
0 or the number of the current session.
undefined-session
set-scheduling [119] (( session-no : Session-No; priority : INT16; weight : INT16 )) -> ( );
This call sets the scheduling priority and weight of the connection.
Scheduling-Info, for more information. You can use 0 as
session-no
to set the info for the current session.
Example:
1 118 0 =1 1 1000 2 119 0 0 1000 %2 58 1 3 119 0 1 2500 %2 59 1500 3 119 0 1 1500 =3
This example uses get-scheduling
to find out the current
scheduling setting (priority 1 and weight 1000). The client then
attempts to get a better priority (0), but is informed that priority 1
is the best priority available to this user (or before logging in).
At request 3 the client attempts to increase the weight to 2500, but
is informed that 1500 is the best weight available. It finally sets
the weight to 1500. This will result in a 50% speedup compared to the
default setting.
The set-scheduling
request makes it possible to implement a
quite complex scheduling machinery in the server. Please note,
however, that a server that only implements priority 0 and weight 1
(and thus treats all sessions equally) is fully compliant with this
specification. The number of priorities and weights that are
available is implementation-defined. They can vary depending on the
privileges of the user that is logged in, and may be affected by the
enable
call.
The first error code in the list below that is applicable will be returned.
weight-zero
weight
.
login-first
session-no
is
0 or the number of the current session.
undefined-session
access-denied
index-out-of-range
priority
argument is numerically too large.
error-status
indicates the numerically largest priority that
the server supports.
priority-denied
error-status
indicates the lowest priority that you have
access to.
weight-denied
error-status
indicates the highest weight
you have access to at the specified priority. The limit may differ at
different priorities.
set-connection-time-format [120] ( use-utc : BOOL ) -> ( );
This call specifies how Time
values are sent over the
protocol. By default, they are sent in the local time zone of the
server. If use-utc
is 1, they will instead be sent using UTC.
This affects both times sent from the server to the client, and from the client to the server.
Please note that there is a race condition. The time contained in any
asynchronous message received after sending a
set-connection-time-format
request and before getting the reply
may have been sent using either the old or the new setting. You
should not trust them.
bad-bool
use-utc
must be either 0
or 1
.
local-to-global-reverse [121] (( conf-no : Conf-No; local-no-ceiling : Local-Text-No; no-of-existing-texts : INT32 )) -> ( Text-Mapping );
This call retrieves information that makes it possible to convert
no-of-existing-texts
existing local text numbers smaller than
local-no-ceiling
to global text numbers, provided that there
are that many local texts smaller than local-no-ceiling
.
In other words, this request is just link local-to-global
,
but it searches backwards in the mapping.
The conf-no
parameter specifies which conference to look up
local numbers in. local-no-ceiling
is the first number that
the client is not interested in. no-of-existing-texts
is the
maximum number of texts the client wants information about. Legal
values for no-of-existing-texts
are 1-255 (inclusive).
The server will return a sparse or dense Text-Mapping depending on the
how many deleted texts there are before local-no-ceiling
.
As a special case, if local-no-ceiling
is 0, information will
be returned about the no-of-existing-texts
highest-numbered
texts.
login-first
long-array
no-of-existing-texts
was larger than 255.
conf-zero
conf-no
was set to 0.
undef-conf
access-denied
map-created-texts-reverse [122] (( author : Pers-No; local-no-ceiling : Local-Text-No; no-of-existing-texts : INT32 )) -> ( Text-Mapping );
Return text numbers for existing texts that author
has written.
This is just like map-created-texts
, but searches in the
other direction. (Compare with local-to-global-reverse
.)
As a special case, if local-no-ceiling
is 0, information will
be returned about the last no-of-existing-texts
texts.
login-first
long-array
no-of-existing-texts
was larger than 255.
conf-zero
author
was set to 0.
undef-pers
access-denied
Asynchronous messages are information messages sent from the server to the client. Most of them are used to inform the client about changes to the database (such as when a new text is created), so that the clients don't have to poll the server for new information. Some have other uses.
The messages with status "O" are included here for historical purposes
only. Servers are not required to handle them, and are encouraged to
reject them if a client uses it as an argument to
accept-async
.
Clients can select which messages to receive by issuing an
accept-async
call. They can find out which
messages are being sent by issuing the query-async
call. Note that the server can send other messages as well. For example, a broadcast message from a person with admin bits set may get through even if the client has not requested broadcast messages.
When a connection is opened some messages are selected by default.
Clients should use the accept-async
call to select which
messages they want. Servers are encouraged to preselect the
async-new-text-old
, async-new-name
,
async-sync-db
, async-leave-conf
, async-login
,
async-rejected-connection
, async-send-message
and
async-logout
messages. These correspond to the useful messages
that were sent prior to the introduction of accept-async
.
An asynchronous message is sent as a colon immediately followed by the
number of message parameters, the message number and the message
parameters. For example, message number 5 could be sent as
:3 5 119 11HDavid Byers 13HDavid C Byers
The parameters of each message are listed in the same format as server calls.
async-new-text-old [0] (( text-no : Text-No; text-stat : Text-Stat-Old ));
This message is sent when a text is created. The text number of the text
is sent in text-no
and the text stat in text-stat
. This
message is sent to all logged-in members of any recipient of the text,
any text it is a comment of, and any text it is a footnote of.
In protocol version 10 this call has been superseded by async-new-text.
async-i-am-off [1] ( person : Pers-No );
This message was sent when person
logged off. It has been
replaced by async-logout
, since this asynchronous message
could not differentiate between sessions if the same person was logged
in more than once.
async-i-am-on-obsolete [2] (( person : Pers-No; conference : Conf-No; what-am-i-doing : HOLLERITH ));
This message was sent when person
changed his
what-i-am-doing
string to what-am-i-doing
or his working
conference to conference
.
It has been replaced by call number 6, async-i-am-on
, since
this asynchronous message could not differentiate between sessions if
the same person was logged in more than once.
async-new-name [5] (( conf-no : Conf-No; old-name : HOLLERITH; new-name : HOLLERITH ));
This message is sent when a person or conference changes names. The
conference whose name is being changed is sent in conf-no
, the
old name in old-name
and the new name in new-name
.
async-i-am-on [6] ( info : Who-Info );
This message is sent when a session's working conference,
what-i-am-doing
string (see change-what-i-am-doing) or
username changes. The new information is sent in info
.
async-sync-db [7] ( );
This message is sent once just before the server blocks to save its database and once just after it blocks. There is no good way to tell the difference between the two cases.
async-leave-conf [8] ( conf-no : Conf-No );
This message is sent to a user when the user's membership in the working
conference is removed for any reason. The conference the user is being
removed from is sent in conf-no
.
Earlier versions of the LysKOM Protocol A specifications stated that this message was only sent if the membership was "revoked forcefully". The exact meaning of that phrasing was never specified. The lyskomd implementation has probably always followed the current version of the specification, which means that this message is sent whatever the reason for the removal is.
Possible reasons include:
sub-member
call.
sub-member
call.
This message is not sent if a membership is transformed from an active to a passive membership.
async-login [9] (( pers-no : Pers-No; session-no : Session-No ));
This message is sent when someone logs in. The identity of the person
logging in is sent in pers-no
, and the session number in
session-no
.
async-broadcast [10] (( sender : Pers-No; message : HOLLERITH ));
This message has been superseded by async-send-message
which
is more flexible. It used to be sent when the administrator
(sender
) broadcasted a string (message
) to all LysKOM
users, but is no longer used.
async-rejected-connection [11] ( );
This message is sent when someone fails to log in because the maximum number of allowed connections has been reached. Some clients may take this as a signal to log out. Administrators should take it as a signal to allow more connections.
async-send-message [12] (( recipient : Conf-No; sender : Pers-No; message : HOLLERITH ));
This message is sent when someone (the sender
) sends a message
string (the message
). The recipient of the message is sent in
recipient
. If it is zero, then the message was sent to all
connections. If it is a conference, then the message is being sent to
all logged-in members of that conference. If it is a mailbox then the
message is personal and is only sent to members of the mailbox
conference.
The passive
and passive-message-invert
bits of the
membership influence if this message is sent. See Membership-Type.
async-logout [13] (( pers-no : Pers-No; session-no : Session-No ));
This message is sent when someone logs out. pers-no
is the person
logging out and session-no
is the session in which the person is
logging out. This message might also be sent when a session disconnects,
even if there is nobody logged on in the session.
async-deleted-text [14] (( text-no : Text-No; text-stat : Text-Stat ));
This message is sent when a text is deleted and the currently
logged-in person is a member of one of the recipients, or a recipient
of any text that is linked to this text via a comment or footnote
link. The text number being deleted is sent in text-no
and the
text stat in text-stat
.
async-new-text [15] (( text-no : Text-No; text-stat : Text-Stat ));
This message indicates that a new text has been created. The text has
number text-no
, and the text stat is text-stat
. The
message is sent to all logged-in members of any recipient of the text,
any text it is a comment of, and any text it is a footnote of.
async-new-recipient [16] (( text-no : Text-No; conf-no : Conf-No; type : Info-Type ));
This message indicates that a new recipient has been added to text
text-no
. The recipient added is conf-no
and the type of
recipient is indicated by type
. This message is sent to all
recipients of the text (of any text that is linked to this text via a
comment or footnote link) that are permitted to know about the new
recipient.
async-sub-recipient [17] (( text-no : Text-No; conf-no : Conf-No; type : Info-Type ));
This message indicates that a recipient has been removed from text
text-no
. The recipient removed is conf-no
and the type
of recipient is indicated by type
. This message is sent to
everybody that were recipients of the text (or any text that is linked
to this text via a comment or footnote link) and that were permitted
to know about the recipient.
async-new-membership [18] (( pers-no : Pers-No; conf-no : Conf-No ));
This message indicates that the membership for pers-no
in
conference conf-no
has been added. This message is currently sent
only to pers-no
, but that may change in the future.
See also async-leave-conf.
async-new-user-area [19] (( pers-no : Pers-No; old-user-area : Text-No; new-user-area : Text-No ));
This message indicates that the user-area of pers-no
has
changed from old-user-area
to new-user-area
. This
message is sent to all supervisors of pers-no
(which of course
includes pers-no
himself).
async-new-presentation [20] (( conf-no : Conf-No; old-presentation : Text-No; new-presentation : Text-No ));
This message indicates that the presentation of conf-no
has
changed from old-presentation
to new-presentation
. This
message is sent to everybody who is allowed to see conf-no
. If
the conference had no presentation, old-presentation
will be
0. Likewise, if the presentation of the conference was removed,
new-presentation
will be 0.
async-new-motd [21] (( conf-no : Conf-No; old-motd : Text-No; new-motd : Text-No ));
This message indicates that the msg-of-day
of conf-no
has changed from old-motd
to new-motd
. This message is
sent to everybody who is allowed to see conf-no
. If the
conference had no message-of-the-day, old-motd
will be 0.
Likewise, if the motd of the conference was removed, new-motd
will be 0.
async-text-aux-changed [22] (( text-no : Text-No; deleted : ARRAY Aux-Item; added : ARRAY Aux-Item ));
This message indicates that the aux-items of text text-no
have
been changed. (This message is not sent when the text is created or
deleted.) deleted
is a list of the deleted items, and
added
is a list of the added items. At least one of the arrays
will be non-empty.
Please note that all items in deleted
will have the
deleted
bit of the flags
field set.
Normal errors are sent in reply to syntactically correct calls to the server. The client should accept any error code in response to any call, even if the error code in question is not listed in the description of the call, and even if the error code in question is not defined in the protocol specification yet.
This table lists the currently defined error codes together with a short explanation. The explanation given below is the default semantics for the error code. It can be updated by the descriptions found for a specific call.
See Client-Server Dialog, for more information about error responses, including the syntax of the error response.
no-error (0)
error-status
is undefined. This should
never happen, but it might.
not-implemented (2)
error-status
is undefined.
obsolete-call (3)
error-status
is
undefined.
invalid-password (4)
string-too-long (5)
error-status
indicates the maximum string length.
login-first (6)
error-status
is
undefined.
login-disallowed (7)
error-status
is undefined.
conference-zero (8)
error-status
is undefined.
undefined-conference (9)
error-status
contains the conference number in question.
undefined-person (10)
error-status
contains the person number in question.
access-denied (11)
error-status
indicates the object to which we didn't have enough permissions to.
permission-denied (12)
error-status
indicated the object
for which permission was lacking, or zero.
not-member (13)
error-status
indicates the conference
in question.
no-such-text (14)
error-status
indicates the text number in question.
text-zero (15)
error-status
is undefined.
no-such-local-text (16)
error-status
indicates the offending
number.
local-text-zero (17)
error-status
is undefined.
bad-name (18)
error-status
is undefined.
index-out-of-range (19)
error-status
is
undefined unless stated otherwise in the call documentation.
conference-exists (20)
error-status
is undefined.
person-exists (21)
error-status
is undefined. This error code is probably not used,
but you never know for sure.
secret-public (22)
secret
bit set and the
rd-prot
bit unset. This is an error since such a conference type
is inconsistent. error-status
is undefined.
letterbox (23)
letterbox
flag of a conference.
error-status
indicates the conference number.
ldb-error (24)
error-status
is an internal code.
illegal-misc (25)
error-status
contains the
index of the illegal item.
illegal-info-type (26)
error-status
is the type.
already-recipient (27)
error-status
contains the recipient that already is.
already-comment (28)
error-status
contains the text number of the text that already is a comment.
already-footnote (29)
error-status
contains the text number of the text that already is a footnote.
not-recipient (30)
error-status
contains the conference number in question.
not-comment (31)
error-status
contains the text number that isn't a comment.
not-footnote (32)
error-status
contains the text number that isn't a footnote.
recipient-limit (33)
error-status
is the text that has the maximum
number of recipients.
comment-limit (34)
error-status
is the text with the maximum number of
comments.
footnote-limit (35)
error-status
is the text with the maximum number of
footnotes.
mark-limit (36)
error-status
is the text with the maximum number of
marks.
not-author (37)
error-status
contains the text number in question.
no-connect (38)
out-of-memory (39)
server-is-crazy (40)
client-is-crazy (41)
set-client-version
more than once.
undefined-session (42)
error-status
contains the offending session number.
regexp-error (43)
error-status
is undefined.
not-marked (44)
error-status
indicates the
text in question.
temporary-failure (45)
error-status
is undefined.
long-array (46)
error-status
is
undefined.
anonymous-rejected (47)
error-status
is undefined.
illegal-aux-item (48)
error-status
contains the index in the aux-item list
where the invalid item appears.
aux-item-permission (49)
error-status
contains the index at
which the item appears in the aux-item list sent to the server.
unknown-async (50)
error-status
contains the message type the server did not
understand.
internal-error (51)
error-status
is undefined.
feature-disabled (52)
error-status
is undefined.
message-not-sent (53)
error-status
is undefined.
invalid-membership-type (54)
error-status
is
undefined unless specifically mentioned in the documentation for a
specific call.
invalid-range (55)
error-status
is undefined.
invalid-range-list (56)
error-status
is undefined.
undefined-measurement (57)
error-status
is undefined.
priority-denied (58)
error-status
indicates the lowest priority that you have
access to.
weight-denied (59)
weight-zero (60)
error-status
is undefined.
bad-bool (61)
BOOL
was given a value that is neither
0
nor 1
.
error-status
is undefined.
Some of the aux-items below (mostly the ones that begin with "mx-") are used by mail importers.
content-type [1] (text)
This item may only be set by the author of a text. The inherit, secret
and hide-owner bits are cleared. Only one content-type item can be
created per creator.
fast-reply [2] (text)
An item of this type will never be inherited, can always be deleted, is
never anonymous and is never secret.
cross-reference [3] (text, conference, letterbox)
The inherit bit is automatically cleared and the item can always be
deleted.
no-comments [4] (text)
This item may only be set by the author. The secret, hide-creator and
inherit bits are automatically cleared.
personal-comment [5] (text)
This item may only be set by the author. The secret, hide-creator and
inherit bits are automatically cleared.
request-confirmation [6] (text)
The hide-creator, secret and inherit bits are automatically cleared.
read-confirm [7] (text)
The hide-creator, secret and inherit bits are automatically cleared.
Once created an item of this type cannot be deleted.
redirect [8] (conference, letterbox)
Data is PROTOCOL:ADDRESS where PROTOCOL is either "E-mail" or "LysKOM", and ADDRESS is either an e-mail address or a LysKOM conference number. Hopefully we'll be able to replace this with a forwarding mechanism later.
This item can only be set by the conference supervisor or in the case of
a mailbox, the person attached to the mailbox. The hide-creator and
secret bits are cleared automatically. Only one redirect can be
specified.
x-face [9] (conference, letterbox, server)
This item can only be set by the conference supervisor or in the case of
a mailbox, the person attached to the mailbox. The hide-creator and
secret bits are cleared automatically.
alternate-name [10] (text, conference, letterbox)
The inherit flag is automatically cleared.
pgp-signature [11] (text)
pgp -sba
in PGP 2.6.2 generates.
The secret, hide-creator and inherit bits are automatically cleared.
Signatures cannot be deleted once they have been created.
pgp-public-key [12] (letterbox)
This item can only be set by the person himself. The hide-creator,
secret and inherit bits are automatically cleared.
e-mail-address [13] (conference, letterbox, server)
The meaning of this aux-item when set on a conference that isn't a mailbox is vague. For a conference that is used as to import a mailing list this should be the email address of the list. For other conferences we haven't really defined a sensible use.
When this aux-item is set on the server it should contain the email address of the administrator (or administrators.)
This aux-item can only be set by the supervisor of a conference or the
server administrator. The creator cannot be hidden.
faq-text [14] (conference, letterbox, server)
This item can only be set by the supervisor or server administrator. The
hide-creator, secret, and inherit bits are automatically cleared.
creating-software [15] (text)
elisp-client 0.47.3
. Setting the creating-software aux-item is
optional.
The data should be the client name, a space, and the client version used
in the set-client-version
call. The server may enforce this
restriction.
mx-author [16] (text)
From
header. This aux-item may be
missing, if the mail address in the From
header consists of just
the addr-spec
(see the next aux-item).
Clients should display this instead of the actual author of the text (which will be an importer ID) even if an mx-from aux-item is not present.
Sample contents: Joe Q. Public
which may come from a From
header containing "Joe Q. Public" <john.q.public@example.com>
.
mx-from [17] (text)
addr-spec
in the mail
standards) extracted from the From
header of an imported
e-mail.
Clients should display this address together with the mx-author
,
preferably inside angles. If mx-author
is not present, this address
should be shown anyway. It can also be used by clients to construct an
address for personal (e-mail) replies to an imported message.
Sample contents: john.q.public@example.com
which may come from a
From
header containing john.q.public@example.com
or
something like "Joe Q. Public" <john.q.public@example.com>
.
mx-reply-to [18] (text)
addr-spec
in the mail
standards) extracted from the Reply-To
header of an imported
e-mail. Clients should use this for constructing replies to imported
messages.
mx-to [19] (text)
To
header.
Multiple mx-to
items may be present when multiple recipients are
specified in the header. Clients should display these items along
with the normal LysKOM recipient headers.
Sample contents: Both john.q.public@example.com
and
"Joe Q. Public" <john.q.public@example.com>
are valid.
mx-cc [20] (text)
mx-to
, but applies to the CC
header rather than
the To
header.
mx-date [21] (text)
Date
header of an imported
email. Its format is "YYYY-MM-DD hh:mm:ss TZ".
YYYY is the year the message was sent, MM is the
month, DD is the day, hh is the hour,
mm is the minute and ss is the second. This
date and time are given in the
timezone where the message was sent. TZ is the timezone the date is
valid for. It must be of the form "+hhmm" or
"-hhmm", where hh is the
number of hours offset from UTC and mm is the number of minutes
offset. Symbolic timezones are not permitted. The timezone specification
is recommended but optional, since it is not always available.
Clients should display this information as the date and time a text was
written, since the imported text will have been created at a later
time. The date and time when the message was imported would then be
displayed elsewhere or not at all.
mx-message-id [22] (text)
Message-ID
header of an imported e-mail, with
whitespace and comments removed. The Message-ID should contain the
surrounding angles.
mx-in-reply-to [23] (text)
Hopefully, this information comes from the In-Reply-To
header
of the imported e-mail, but it could also have been picked from the end
of the References
header line.
If the text really comments more than one other text directly,
it is allowed to attach more than one mx-in-reply-to
items to
it.
mx-misc [24] (text)
Subject
, and including those that are redundantly
stored in other aux-items. The headers are concatenated with "\n". In
other words, this item contains all headers of an imported e-mail as
they appear in the message.
Clients are encouraged to provide a command to display this information.
mx-allow-filter [25] (conference, letterbox)
mx-reject-forward [26] (conference, letterbox)
notify-comments [27] (letterbox)
This item can only be set by the owner of the letterbox. No flags are
forced or cleared.
faq-for-conf [28] (text)
recommended-conf [29] (server)
A few examples might clarify what the data may look like:
1
2 32
3 250 11100000
4 253 01000000 garbage
This is a recommendation only; it is up to the client that creates a new
person to also add him to the conferences that are specified via
recommended-conf
.
allowed-content-type [30] (conference, letterbox, server)
allowed-content-type
glob patterns of that conference.
If the conference doesn't have any allowed-content-type
, the
allowed-content-type
items of the server should be used. If the
server also has no allowed-content-type
aux-items, it should be
interpreted as if a single allowed-content-type
aux-item with the
value 1 text/plain
exists.
If there are allowed-content-type
aux-items with different
priority numbers, it is a hint to the client about which content-type is
most desirable. Content-types that matches a lower priority number are
preferred.
As an example, consider a conference with the following four
allowed-content-type
aux-items:
1 text/plain 2 text/x-kom-basic 2 text/enriched 3 text/*
These aux-items taken together means that text/plain
is
preferred, that text/x-kom-basic
and text/enriched
can be
used if there is a reason why text/plain
is inadequate, and
that any text type (such as text/html
) is acceptable. Other
content types, such as x-kom/user-area
, should not be used.
The server does not currently enforce the above restriction on the
content type of new texts. This mechanism is currently a hint to the
client (or to the author of a new text). This may change in the
future, if experience shows that it is desirable to have the server
enforce the content type.
canonical-name [31] (server)
kom.lysator.liu.se:8300
, kom.lysator.liu.se
. The intent
is that the canonical-name
should be globally unique among all
LysKOM servers. Only a single aux-item of this type can be set on the
server. This aux-item can be used by clients that wish to do certain
things only when connected to a specific server.
mx-list-name [32] (conference)
bug-lyskom@lysator.liu.se
.
send-comments-to [33] (letterbox)
Data is a decimal integer (a conference number) optionally followed by a space character and a decimal number (a recipient type). In the future, additional data may be defined; clients must be prepared to accept and ignore a space and any trailing data that may follow the recipient type. Clients must be prepared to accept items of this type that contain only the conference number.
Comments should be sent to the specified conference number instead of
to the author. The value 0
is special and means that the
comment should not be sent to any special conference, even though that
means that the author of the commented text will never see the
comment. (The value 0
is useful for mail importers and other
similar robots.)
The recipient type is the type of recipient to add. If the recipient
type is missing, clients should either assume recipient type zero
(recpt
) or ask the user. Legal recipient types are 0
for recpt
, 1
for cc-recpt
and 15
for
bcc-recpt
(these are the values used in Info-Type
).
Additional recipient types may be added in the future. Clients should
treat unknown or invalid recipient types as if they were missing
(i.e. treat them as zero or ask the user).
See Recipients of comments, for more information about how the client should select the conferences that a comment should be sent to.
This aux-item can only be set by the supervisor of the person.
world-readable [34] (text)
Only the author of the text can set this item. The data must be the
empty string. The hide-creator, secret, dont-garb and inherit bits
are automatically cleared.
mx-refuse-import [35] (conference, letterbox)
If the data is the string all
, the importer will never add this
conference or letterbox as a recipient.
If the data is the string spam
, the importer will not add this
conference or letterbox as a recipient if the mail is considered to be
spam according to some importer specific criteria (such as the presence
of SpamAssassin flags).
In the future, other alternatives in addition to the above may be defined for this aux-item. An importer should silently ignore unrecognized ones. If more than one aux-item of this type is present, they will be combined in the most restrictive way, i.e. the recipient will not be added if any of the aux-items forbids import.
Clients are encouraged to provide commands to manage aux-items of this
type for conferences and letterboxes.
mx-mime-belongs-to [10100] (text)
mx-mime-part-in [10101] (text)
mx-mime-misc [10102] (text)
Clients are encouraged to provide a command to display this.
mx-envelope-sender [10103] (text)
mx-mime-file-name [10104] (text)
name
parameter on a Content-Type
MIME header line.
Clients are encouraged to use this file name as the default file name when the user chooses to save the text.
See also Some Client-specific Aux-Item Types, for information about some non-standardized aux-item types.
Names in LysKOM can be expanded according to two rules, regexp matching or KOM conventions.
This type of expansion, used by the re-z-lookup
call and
its predecessors simply matches ed
(1) style
regular expressions to names in the database to find the list of
matching names. The matching is case sensitive.
This type of matching is a little more complicated. Patterns consist of
words and parenthesized expressions, and contain implicit wildcards. The
lyskomd
program implements an approximation of theses
conventions. Since lyskomd
is the trendsetter, these semantics
are good enough.
The rules are simple. Any parenthesized expressions are removed from the pattern and the names being checked for matches. Then the words of the pattern are examined from beginning to end, and if every pattern word matches the prefix of the corresponding word in the name, the name matches the pattern.
For example "L D" matches "LysKOM (client, server and protocol) Discussion (and) Ideas", but not "LysKOM Protocol Discussion".
The matching is case insensitive. Character case is converted
according to a collate table in the server. The collate table can be
retrieved from the server with the get-collate-table
call.
The current collate table simply maps ISO 8859-1 uppercase and lowercase letters to equivalents, and also considered braces and suchlike equivalent according to swascii rules.
LysKOM defines a few special content types for texts. They are all
described in this chapter. In addition to these, clients must support
text/plain
, should support text/enriched
and are
encouraged to support text/html
.
Lines are separated by a single linefeed (ASCII 10) character. The linefeed character is used as a line separator, not as a line terminator. In other words, there should be no linefeed after the last line.
This type of content corresponds to the mime type
text/x-kom-basic
. It is raw
text that can be reformatted by the client without ill effects, but
that can be legibly displayed on a text terminal without formatting.
The following rules apply when reformatting:
This content type was previously erroneously called x-kom/basic
, but
as far as we know no client ever created texts that were labeled with
that name. Please use the new name text/x-kom-basic
instead.
Historical note: version 0.46.1 and earlier of the elisp client
created texts labeled with x-kom/text
. Clients may treat that content
type as text/x-kom-basic
for improved interoperability.
This content type indicates that the article contains a user area. See The User Area.
The user area is a regular text that is used to store client-specific information in the server. Most clients use this to store settings a user has made that are specific to a particular server. There are also provisions to store settings that are shared between clients.
The user-area is divided into several sub-blocks. The common
block is
shared by all clients, and its formats and contents are dictated by this
protocol specification. Clients may also create one or more other blocks.
In normal texts, everything up to the first linefeed is considered to be the subject line. The user area is an exception: it does not contain any subject line.
Each block is encoded as a HOLLERITH
string. A table of
contents is also encoded as a HOLLERITH
string and added first
in the user area. There must be at last one space between each
string, and there might be spaces at the beginning and/or end of the
user-area. Thus, a user-area made up of three blocks will contain
four HOLLERITH
-encoded strings, each separated by at least one
space, and maybe with extra spaces at the beginning or end of the
text.
The table of contents consists of one HOLLERITH
-encoded string
for each block in the user-area. Each string contains the name of the
corresponding block. There is at least one space between each string,
and there may be spaces before the first string and after the last
string. Clients must never create two or more blocks with the same
name.
This format ensures that clients can copy or read past other clients' blocks without knowing their structure.
Example:
13H7Hblock-a 1Hb 4Hasdf 5H hjkl
In the above example, there are two blocks: block-a
and
b
. block-a
contains four bytes, asdf
, while
b
contains five bytes: hjkl
(note the leading
space). Below are a few other ways to encode the same user-area:
14H 7Hblock-a 1Hb 4Hasdf 5H hjkl 16H 7Hblock-a 1Hb 4Hasdf 5H hjkl 13H1Hb 7Hblock-a 5H hjkl 4Hasdf
The first two examples embed extra (redundant) spaces, and the last swaps the order of the two blocks.
The following block names have been defined:
common
elisp
WWW-kom
rkom
If you're writing a client that uses the user-area, please let us know what you name your client's block.
This defines the structure of the common block. The common block contains a list of variable settings. Each variable setting consists of a name, some whitespace, and a value. Settings are separated by a linefeed character. The values can be of several different types (such as integers, strings, booleans, lists of stuff) but they are all encoded as HOLLERITHs. The reason for this is to simplify for clients that need to ignore the value, and so it is possible to add new value types without confusing old clients.
The grammar below defines the syntax of the common block.
common-block : settings settings : settings setting | /* empty */ setting : variable ' ' value '\n' variable : [A-Za-z-_0-9]+ value : HOLLERITH
The values contain structure within the HOLLERITH. The following
grammar defines the data types that are currently used. Clients must
be prepared to ignore values that have other data types.
boolean : 1 | 0 integer : -?[0-9]+ string-list : string-list ' ' HOLLERITH | HOLLERITH
Currently the following variables are used, but more may be added, and clients must cope with variables they know nothing of in the common block. (Doing so is easy, as all values are encoded as HOLLERITHs.)
created-texts-are-read
boolean
.
dashed-lines
boolean
.
presence-messages
boolean
.
print-number-of-unread-on-entrance
boolean
.
read-depth-first
boolean
.
reading-puts-comments-in-pointers-last
boolean
.
confirm-multiple-recipients
boolean
.
default-mark
integer
.
language
string-list
.
This contains a list of ISO 639 language codes. ISO 639-2 should be used for languages that have a 2-character language code. For other languages, ISO 639-1 should be used. http://lcweb.loc.gov/standards/iso639-2/langcodes.html contains a list of the current language codes.
The client should configure its user interface to use the first language in the list that it supports. Example: a client that supports English and Swedish would use:
2Hfr 2Hsv 2Hen
2Hen 2Hsv 2Hfr
2Hes 2Hfr
The details of the security model isn't properly documented. Much information can be extracted from various parts of the protocol specification, but there is no complete overview. In time, this chapter may become such an overview. For now, it only defines when a membership is visible.
The various requests that return information about a membership can be grouped into three categories:
These requests fail if the conference is secret and you don't have access to it, even if a membership should be visible to you according to the rules below.
These requests fail if the person is secret and you don't have access to it, even if a membership should be visible to you according to the rules below.
These requests follows the rules below exactly.
The rules for membership visibility are given below. In the explanation, the variables C, P and V are used like this:
The following flags also influences how much V can see:
unread-is-secret
flag of P
secret
flag of P:s membership in C
The following rules determines if a membership is visible to V. The first rule that matches is used.
unread-is-secret
and secret
flags are
ignored.
secret
flag is ignored. The unread-is-secret
flag is honored.
secret
is unset, then the membership is visible. The
unread-is-secret
flag is honored.
The server measures a number of properties, and can return information
about them to a client via the get-stats
request. A server implementation may include experimental
properties, whose name should begin with X-
. All other
properties should be defined in this chapter.
Some of the properties that are suggested here might prove to be too
hard to measure efficiently, or might prove to expose too much
information. In that case, a server may select to not implement them.
Clients must be prepared to receive a feature-disabled
or
undefined-measurement
error if they call get-stats
with a value that wasn't received from
get-stats-description
.
For each measured value, both the levels and the ascent and descent rates are returned. See Stats, for more information.
Ascent and descent rates are always normalized to a number of events per 100 seconds.
run-queue-length
pending-dns
pending-ident
clients
reqs
texts
confs
persons
send-queue-bytes
recv-queue-bytes
This appendix is not really part of the protocol specification, but it contains some information that may be useful for client writers.
Most clients will implement certain commands. This main purpose of this section is to get client writers started on some of these commands, and to answer some questions that seem to come up over and over again.
Each person has a membership list containing the conferences the person
is a member of. Each element is an object of type Membership
. Among
other things it contains the number of the conference, the priority of
the membership, when the person most recently marked a text as read in
the conference, and which texts the person has read.
The list of read texts consists of two parts: a local text number called
last-text-read
and a list of local text numbers called
read-texts
. The person has marked all texts up to and including
last-text-read
as read, and also the texts listed in
read-texts
. All other texts in the conference are unread. Clients
can use either the query-read-texts
or
get-membership
calls to get membership data.
The standard procedure for finding out which texts are unread is the following:
get-unread-confs
for the person.
This returns a list of conferences in which the person may have unread
texts. This call may return conferences that do not contain any unread
texts, but it will never forget to return a conference that does contain
an unread text.
query-read-texts
for each conference returned in
the previous step. This will return the membership data for all the
conferences that may contain unread texts.
get-uconf-stat
for each conference returned in
the first step. The conference status will be needed shortly. Repeat the
following steps for each conference.
last-text-read
field for the
corresponding membership. If the highest existing local text is higher
than last-text-read
, the conference may contain unread texts.
last-text-read
and ending at the highest existing local
number. Every local number in the map that is not read according to the
membership data and that has a mapping to a global number is an unread
text. You might say that you remove the read texts from the map to get
the unread texts.
Take care not to call get-map or get-membership too much since they tend
to be expensive operations. Use get-unread-confs
and
query-read-texts
to minimize the work. Another point to remember
is that the server will send asynchronous messages with information
about new texts. Clients need to listen to these messages.
There are certain conventions that most clients follow, and that users expect. These are not part of the protocol and are subject to change. In particular those conventions that address deficiencies in the protocol will go away when the protocol is updated to correct these deficiencies.
Traditionally the only clients for LysKOM were text-based and only displayed texts exactly as they were stored in the server. Although there are a number of clients now that can wrap lines automatically, texts should still be stored in preformatted style, suitable for display in a monospaced font.
If the client accepts texts from the user and then reformats them, such as a client with an editor with a variable-width font, it should ensure that it follows the following simple rules:
Clients that include editors but do not alter the text before sending it to the server should attempt to ensure that texts confirm to the above conventions.
The same conventions apply to messages sent with the
send-message
call.
This convention is understood by all popular clients. If the first line
is one of a few predefined strings, then this string specifies the type
of text. Currently only the strings "html:" and "enriched:" are
supported, specifying text/html
and text/enriched
respectively.
Starting with protocol version 10, this ugly workaround is obsolete. Use aux-items to specify content type instead.
When a client needs to prompt the user for a conference (or person), it could offer the user several ways of specifying the conference:
lookup-z-name
call.
re-z-lookup
call.
re-z-lookup
call.
It is beyond the scope of this document to specify how the client interacts with the user.
The client should offer the user all the methods of specifying a conference listed above. At the very least, the two first methods should be supported.
When a user writes a comment, the user should have full control over
which conferences and/or letterboxes the comment is sent to. By
default, the recipient list should be all recpt
recipients.
cc-recpt
and bcc-recpt
recipients should not be
included.
Conferences in the recipient list that have the original
bit set, and a non-zero super-conf
, should be replaced by the
super-conf
.
If the author of the commented text isn't a member of any of the new
recipients, the client should check if the author has a
send-comments-to
aux item. If it is 0
, nothing should be
done. Otherwise, send-comments-to
should be a valid conference
number, and that conference should be added as a recpt
recipient. If there is no send-comments-to
aux-item, the user
should be prompted to add the author of the commented text as a
recpt
or cc-recpt
recipient.
If the author of the new comment is not a member of any of the
recipients, the client should check if the author has a
send-comments-to
aux item. If it is 0
nothing should be
done. Otherwise, send-comments-to
should be a valid conference
number, and the user should be prompted to add that conference as a
recpt
or cc-recpt
recipient. If there is no
send-comments-to
, or send-comments-to
is invalid, the user
should be prompted to add his letterbox as a recpt
or
cc-recpt
recipient.
If a recipient is present more than once, all duplicates should be removed.
The ordering of the groups of Misc-Info
items are not defined
by this protocol. However, when creating a new text, clients are
recommended to use this order:
footn-to
items
comm-to
items
recpt
items
cc-recpt
items
bcc-recpt
items
This is the order that the elisp-client normally uses, and users have come to expect that order.
E-mail import has been implemented using various programs since the
first LysKOM server became operational. Protocol version 10 introduces a
lot of aux-items, a large part of which are intended for use by mail
importers to enhance the functionality. As of this moment, there is one
mail importer (komimportmail
) that is designed to take full
advantage of all the new aux-items.
E-mail export has never been used seriously. The first person to design and implement an exporter gets to rewrite this appendix based on his or her experiences.
The main job of the mail importer is to figure out where to deliver mail, how to handle MIME coding and/or structure and how to deal with threading. During this, it creates one or more texts and a lot of aux-items.
Although a mail message contains To
and CC
headers, they
are not really useful when importing as it is the envelope recipients,
not the header recipients, that should be used. To understand this,
consider a mail where the To
header contains a personal mail
address. The mail is received using a tool like procmail
and
forwarded to the LysKOM importer. The envelope address will be correct,
but the To
header will still contain the personal address.
The komimportmail
importer uses addresses like
"number@server", where number is the number of the
recipient and server is the mail domain reserved for the LysKOM
importer. For backwards compatibility with earlier importers, it is
allowed to prepend a "p" before the number. Instead of the number,
komimportmail
can accept a name, as long as the name can be
resolved to exactly one conference or letterbox. Before looking up the
name, any underscore or period is translated into a space.
Care should be taken when a mail is received more than once. This can
happen if a mail is addressed to more than one address. For example,
assume that a mail is sent to john.q.public@example.com
and
sven.svensson@exempel.se
. Two different mail servers handle the
two recipients, but both eventually decide to forward the mail to the
LysKOM importer (but for different conferences). The LysKOM importer
will receive the mail twice, with different envelope recipients.
A solution is to keep a database containing a mapping from
Message-ID
to LysKOM text number for imported messages. If a
message is seen more than once, the message is not imported. Instead,
recipients are added to the existing text.
On the other hand, that will introduce a security hole, where a person
who knows the Message-ID
of an interesting imported mail can add
himself or some open conference as a recipient. Perhaps the importer
should check for matching contents before adding recipients.
The importer needs to be careful not to deliver messages to conferences that do not allow messages, even though the server might not complain.
For mail delivery to work for any conference, the importer has to use a
privileged person, or it will be unable to deliver mail to secret
conferences. A potential problem is that this leaks secret information
from the server. For the time being, the komimportmail
importer
avoids this problem by using an unprivileged person and requiring the
members of secret conferences to invite the importer if they want e-mail
import to work.
The importer should do its best to thread messages. When the importer
sees a new message it needs to look at the In-Reply-To
header to
see what the message is a reply to. If the In-Reply-To
header
does not exist, or if it exists but does not contain a valid Message-ID,
the last valid Message-ID of a References
header may be used
instead.
If the Message-ID of a previously imported e-mail is found, the new text should be made a comment of the replied-to text.
If the Message-ID is of the form defined below (see Message-ID), and it refers to a text exported from this server, the new text should be made a comment of the replied-to text.
This means that the importer will probably have to maintain its own database of imported texts that maps the message ID to the text number in the LysKOM database. There is no other way to find the text number for a particular imported text. Fortunately, this is exactly the same database we need to solve the multiple reception problem described above.
It has been noted that messages on some mailing lists arrive in peculiar order, with replies before the original messages. Perhaps this is due to moderation. A smart importer should be prepared to handle this, by adding a comment link when the original message eventually arrives.
One possible solution is to add a new kind of entry to the Message-ID database, mapping a Message-ID to a list of text numbers that should become comments to the message when it is imported.
An importer should try to handle e-mail messages containing MIME appendices as smart as possible. As the current LysKOM model lacks hierarchical structuring inside articles, appendices should probably be imported as comments or footnotes to the main message.
One would think that it is easy to convert the hierarchical MIME structure to a corresponding LysKOM comment tree. However, this would require creating empty interior nodes to attach some comments to.
Therefore, the komimportmail
importer currently uses a rather
naive algorithm: All leaf parts are found. The first one gets to be the
main text, and the rest are included as comments to it.
Appendices encoded with Base64 or Quoted-Printable should be decoded.
When creating aux-items like mx-author
, text coded using the
method in RFC 2047 should be decoded.
As of this writing, an experimental e-mail exporter exists, but it is a fairly recent creation. The author of this document knows very little about how it works, so this section contains very little information.
A standard for Message-ID creation has been established. The general
format is:
text-no.port.exporter.randomness@server
The different parts are explained below:
canonical-name
aux item defines a unique name for the LysKOM
system that the text was exported from. The server and
port fields are set from it. If no port is specified in the
canonical-name
, the port part is set to the empty string.
This appendix contains some contributed information from client writers about some of the aux-item types that they use. This information may be updated at any time by the client writers. How much the client writer cares about backward compatibility when they make changes to these aux-item types may be beyond the control of the authors of the Protocol A specification.
If any of the aux-item types defined here becomes widely used by different clients, they should probably be standardized and moved to the Aux-Item Types chapter.
elisp-client-read-faq [10000] (letterbox)
Note that aux-items of this type should always be secret since they may contain information about texts of conferences that are not publicly visible.
A few examples might clarify what the data may look like:
459 11215
459 11215 garbage
This aux-item is specific to the elisp client. Other clients are not
required to use or understand this item type.
elisp-client-rejected-recommendation [10001] (letterbox)
Note that aux-items of this type should always be secret since future extensions may contain sensitive data.
A few examples might clarify what the data may look like:
459
459 garbage
This aux-item is specific to the elisp client. Other clients are not required to use or understand this item type.
While useful and stable, this protocol is far from perfect. Here is a short list of things the current developers would like to change in future versions of the protocol. The list is not sorted.
All changes will be made in a backwards compatible way. Clients will still be able to use the old requests.
Misc-Info
array should be
integrated into the Text-Stat
. There should be one array of
recipients, one of texts that comments this text, and so on. This
would make the Misc-Info
type obsolete. (This is
bug 134.)
Text-Stat
. They should probably be separated from the
Text-Stat
; retrieving the Text-Stat
should only indicate
which aux-items that exists. (This is
bug 135.)
One way to fix this is to remove the original
bit and
introduce a followups-to
field in the Conference
.
Doing this in a backwards-compatible way requires some thought...
(This is
bug 136.)
In the future, a new call might be added, so that a client can give
the server explicit permission to reorder the replies. The client
would then have to rely on the ref-no
to match each reply to
the corresponding call. (This is
bug 138.)
For more information about potential future changes, see Bugzilla @ Lysator. The above list is in no way complete.
These new calls have status Experimental.
The following calls have changed status from Recommended or Experimental to Obsolete.
reserved1
bit of
Membership-Type
has been renamed to
passive-message-invert
. See Membership Information. This
affects async-send-message
and send-message
.
get-last-text
, find-next-text-no
and
find-previous-text-no
.
add-recipient
call if you are the supervisor of either the
author, recipient or sender. The check used to be more restrictive.
async-new-text-old
, async-deleted-text
,
async-new-text
, async-new-recipient
and
async-sub-recipient
.
BOOL
argument now return the
error bad-bool
if the argument is anything but 0
or
1
.
These new calls have status Experimental.
Old name | New name
|
5=create-person | 5=create-person-old
|
9=query-read-texts | 9=query-read-texts-old
|
10=create-conf | 10=create-conf-old
|
13=get-conf-stat-old | 13=get-conf-stat-older
|
14=add-member | 14=add-member-old
|
26=get-text-stat | 26=get-text-stat-old
|
28=create-text | 28=create-text-old
|
36=get-info | 36=get-info-old
|
46=get-membership | 46=get-membership-old
|
48=get-members | 48=get-members-old
|
50=get-conf-stat | 50=get-conf-stat-old
|
59=create-anonymous-text | 59=create-anonymous-text-old
|
The following calls have changed status from Recommended or Experimental to Obsolete.
async-
prefix has been added to the name of all asynchronous
messages. In addition, 0=new-text has been renamed to
0=async-new-text-old, and it is now considered obsolete. Clients should
use 80=accept-async to listen to 15=async-new-text instead.
add-member-old
and
get-membership-old
perform magic, translating between priorities
and membership types. The magic is documented with each call.
not-implemented
when
a client attempts to use an unimplemented call. This feature requires
that the client uses linefeed as call terminator.
change-conference
was previously called pepsi
. The
name was changed, but not the functionality.
who-is-on-ident
is now considered obsolete.
get-session-info-ident
is now considered obsolete.
recpt
to cc-recpt
and vice versa.
Conf-Type
and Extended-Conf-Type
.
Conf-Type
and Extended-Conf-Type
.
mx-refuse-import
[35]. See Aux-Item Types.
New types: Read-Range
and Membership
(the old
Membership
was renamed to Membership-10
).
See Membership Information.
Stats
and Stats-Description
. See Statistics.
Static-Server-Info
. See Server Information.
FLOAT
. See Simple Data Types.
Status change: The query-read-texts-10
and
get-membership-10
requests are now obsolete. The
set-keep-commented
request is now recommended.
New calls:
query-read-texts
get-membership
mark-as-unread
set-read-ranges
get-stats-description
get-stats
get-boottime-info
first-unused-conf-no
first-unused-text-no
find-next-conf-no
find-previous-conf-no
get-scheduling
set-scheduling
set-connection-time-format
local-to-global-reverse
map-created-texts-reverse
New error codes: invalid-range
,
invalid-range-list
, priority-denied
,
weight-denied
, weight-zero
,
undefined-measurement
and bad-bool
.
New async messages:
Protocol change: Renamed the reserved1
bit of
Membership-Type
to passive-message-invert
.
See Membership Information. This affects
async-send-message
and send-message
.
The following requests can no longer be used until you have logged in:
get-last-text
, find-next-text-no
and
find-previous-text-no
.
You can now modify the type of a recipient with the
add-recipient
call if you are the supervisor of either the
author, recipient or sender. The check used to be more restrictive.
Aux-item tags 10200-10299 are now reserved for private test use. See Client-Specific Aux-Item Types.
The following asynchronous messages are also sent to recipients of
texts linked to the relevant text via comment or footnote links:
async-new-text-old
, async-deleted-text
,
async-new-text
, async-new-recipient
and
async-sub-recipient
.
Two requests can now return more error codes than they used to:
add-comment
already-comment
and already-footnote
.
add-footnote
already-comment
.
The field later-texts-exists
in Text-Mapping
has been
renamed to more-texts-exists
, as this name is more meaningful
for the new requests local-to-global-reverse
and
map-created-texts-reverse
.
Fixed errors: The description of the error
index-out-of-range
was wrong for
add-footnote
,missing for create-person-old
,
create-person
, create-conf-old
,
create-conf
and create-text-old
, and incomplete
for create-text
.
async-leave-conf
is not sent when the person is deleted,
so don't say that it is.
The documentation for no-of-created-texts in the Person
structure
was wrong. See Person.
The documentation for the privilege bits create-conf
and
create-pers
stated that they are by default on. In fact, they
are by default ignored, but off. See Security.
The example for re-z-lookup
was wrong.
An example for lookup-z-name
was wrong.
Protocol change: Added a new "language" value to the common block of the user area. See The User Area.
New aux-items: world-readable
[34]. See Aux-Item Types.
elisp-client-read-faq
[10000] and
elisp-client-rejected-recommendation
[10001].
See Some Client-specific Aux-Item Types.
Modified aux-item: send-comments-to
[33] may now also
contain an optional recipient type. See Aux-Item Types.
Previously undocumented stuff: The rules for when a membership is visible are now documented. See Membership visibility.
Documented the unread-is-secret
flag of Person
.
See Personal-Flags.
The documentation for get-person-stat-old
was
improved.
The Message-ID of exported texts is now documented. See Message-ID.
A client should offer to add the author as a recipient of a text he is creating if he isn't a member of any of the recipients. See Recipients of comments.
There should be no linefeed after the last line of a text. See LysKOM Content Types. See Reformattable Text (text/x-kom-basic).
Added a recommendation for how groups of Misc-Info
items should
be sorted. See Order of misc-info groups.
Editorial changes: Several spelling errors, typos, et c were fixed.
Distributed with lyskomd 2.0.7.
query-read-texts-10
and get-membership-10
were
wrong. The idle-time
field is only affected by the
user-active
request, not by all activity (see Session Information).
Protocol change: Expanded the documentation of
super-conf
. See Conference Status Types. Simplified the
rules for super-conf
; a setting of 0 no longer means anything.
A new section contains a summary of how a client should decide where
to send a comment, and it contains the new rules. Recipients of comments. Most clients already implemented the new rules; the old
rules were overly complex.
New aux-item: send-comments-to
[33].
Modified aux-item: faq-text
[14] may now be set on a
letterbox.
Previously undocumented stuff: Expanded the documentation of
permitted-submitters
. See set-permitted-submitters.
Clarify that a person is a supervisor of himself, except for the
set-supervisor
call; see Conferences.
Document the change-name
privilege bit; see Security.
Document that last-login
is also updated on logout;
see Person Status Types.
Clarify that the address part of redirect
[8] is a conference
number.
Compatibility info: Mention that the elisp client used to enter
texts as x-kom/text
instead of text/x-kom-basic
.
Administrativia: Updated "Future changes" (see Future changes), and mention that we now use Bugzilla to keep track of bugs and feature requests.
Editorial changes: Added some of Texinfo markup and cross references. Several spelling errors, typos, et c were fixed.
Distributed with lyskomd 2.0.6.
old-pwd
argument
to set-passwd
. The content-type x-kom/basic
was renamed
to text/x-kom-basic
.
Previously undocumented stuff: Documented several previously
undocumented aspects of the protocol: the hello string used during
connection establishment, the items-to-delete
and
items-to-add
arguments of modify-system-info
, the
type
argument of add-member
(including the fact that the
invitation membership flag is automatically set in some
circumstances), that a client can issue many requests at once (and
that the replies are sent back in order).
New stuff: Registered the "rkom" user-area block.
New aux-items: The following predefined aux-items were added:
canonical-name
[31], mx-list-name
[32]
mx-mime-belongs-to
[10100], mx-mime-part-in
[10101],
mx-mime-misc
[10102], mx-envelope-sender
[10103] and
mx-mime-file-name
[10104]. Those aux-items with a number higher
than 10000 were previously documented in this document, but they now
have the status of predefined aux-items.
Editorial changes: Lots of editorial changes needed to publish an
online version on the web at
http://www.lysator.liu.se/lyskom/protocol/. Many minor syntax
errors corrected, and much missing Texinfo markup added. The document
now makes heavy use of Texinfo macros. Due to bugs in the current
version of texinfo.tex
this file cannot currently be typeset
using TeX. (All bugs are reported to the Texinfo maintainers.)
get-membership-old
, get-membership-10
and login
used to
take an argument of type BITSTRING(a-single-field)
. The
type has now been changed to BOOL
instead, to simplify the
description. The encoding of the protocol is unchanged.
The indices are now joined into a single index. More terms have been added to it. Many sections of text were moved around to make it easier to find information. Some non-normative information was moved to appendices. Removed a few non-normative empty sections.
This edition was published on the web; no lyskomd release was imminent
when the edition was finished. Future editions will also be published
on the web; most of them will likely be published at the same time as
a lyskomd release is made. They will continue to be included in the
lyskomd releases.
allowed-content-type
and
recommended-conf
aux-items were added. The
mx-allow-filter
and mx-reject-forward
aux-items are marked
obsolete. Text regarding mail import was improved, based on actual
experience in writing an email importer. Reserved a range of aux-items
for komimportmail. Several minor corrections and clarifications made.
Distributed with lyskomd 2.0.4.
sub-comment
was incorrectly marked obsolete. This has been
corrected. Regexps are case sensitive. The Info-Type enumeration was
introduced in the description of the protocol. (Previous versions of
the protocol had broken definitions of add-recipient
,
async-new-recipient
and async-sub-recipient
.) Distributed
with lyskomd 2.0.1.
sub-comment
call as
obsolete, and stated that regexp lookup was case insensitive. Both
statements were wrong, and has since been fixed.
accept-async
: accept-async
add-comment
: add-comment
add-footnote
: add-footnote
add-member
: add-member
add-member-old
: add-member-old
add-recipient
: add-recipient
Any-Conf-Type
: Conference Types
ARRAY
: Simple Data Types
async-broadcast
: async-broadcast
async-deleted-text
: async-deleted-text
async-i-am-off
: async-i-am-off
async-i-am-on
: async-i-am-on
async-i-am-on-obsolete
: async-i-am-on-obsolete
async-leave-conf
: async-leave-conf
async-login
: async-login
async-logout
: async-logout
async-new-membership
: async-new-membership
async-new-motd
: async-new-motd
async-new-name
: async-new-name
async-new-presentation
: async-new-presentation
async-new-recipient
: async-new-recipient
async-new-text
: async-new-text
async-new-text-old
: async-new-text-old
async-new-user-area
: async-new-user-area
async-rejected-connection
: async-rejected-connection
async-send-message
: async-send-message
async-sub-recipient
: async-sub-recipient
async-sync-db
: async-sync-db
async-text-aux-changed
: async-text-aux-changed
Aux-Item
: Auxiliary Information
Aux-Item-Flags
: Auxiliary Information
Aux-Item-Input
: Auxiliary Information
Aux-No
: Auxiliary Information
BITSTRING
: Simple Data Types
BOOL
: Simple Data Types
broadcast
: broadcast
change-conference
: change-conference
change-name
: change-name
change-what-i-am-doing
: change-what-i-am-doing
Conf-List-Archaic
: Archaic way to list conferences
Conf-No
: Common Types
Conf-Type
: Conference Types
Conf-Z-Info
: Conference Search Results
Conference
: Conference Status Types
Conference-Old
: Conference Status Types
create-anonymous-text
: create-anonymous-text
create-anonymous-text-old
: create-anonymous-text-old
create-conf
: create-conf
create-conf-old
: create-conf-old
create-person
: create-person
create-person-old
: create-person-old
create-text
: create-text
create-text-old
: create-text-old
delete-conf
: delete-conf
delete-text
: delete-text
disconnect
: disconnect
Dynamic-Session-Info
: Session Information
enable
: enable
ENUMERATION
: Simple Data Types
Extended-Conf-Type
: Conference Types
find-next-conf-no
: find-next-conf-no
find-next-text-no
: find-next-text-no
find-previous-conf-no
: find-previous-conf-no
find-previous-text-no
: find-previous-text-no
first-unused-conf-no
: first-unused-conf-no
first-unused-text-no
: first-unused-text-no
FLOAT
: Simple Data Types
Garb-Nice
: Conference Status Types
get-boottime-info
: get-boottime-info
get-client-name
: get-client-name
get-client-version
: get-client-version
get-collate-table
: get-collate-table
get-conf-stat
: get-conf-stat
get-conf-stat-old
: get-conf-stat-old
get-conf-stat-older
: get-conf-stat-older
get-created-texts
: get-created-texts
get-info
: get-info
get-info-old
: get-info-old
get-last-text
: get-last-text
get-map
: get-map
get-marks
: get-marks
get-members
: get-members
get-members-old
: get-members-old
get-membership
: get-membership
get-membership-10
: get-membership-10
get-membership-old
: get-membership-old
get-person-stat
: get-person-stat
get-person-stat-old
: get-person-stat-old
get-scheduling
: get-scheduling
get-session-info
: get-session-info
get-session-info-ident
: get-session-info-ident
get-static-session-info
: get-static-session-info
get-stats
: get-stats
get-stats-description
: get-stats-description
get-text
: get-text
get-text-stat
: get-text-stat
get-text-stat-old
: get-text-stat-old
get-time
: get-time
get-uconf-stat
: get-uconf-stat
get-unread-confs
: get-unread-confs
get-version-info
: get-version-info
HOLLERITH
: Simple Data Types
Info
: Server Information
Info-Old
: Server Information
Info-Type
: Article Information
INT16
: Simple Data Types
INT32
: Simple Data Types
INT8
: Simple Data Types
Local-Text-No
: Common Types
local-to-global
: local-to-global
Local-To-Global-Block
: Mapping Local to Global Text Numbers
local-to-global-reverse
: local-to-global-reverse
login
: login
login-old
: login-old
logout
: logout
lookup-conf
: lookup-conf
lookup-name
: lookup-name
lookup-person
: lookup-person
lookup-z-name
: lookup-z-name
map-created-texts
: map-created-texts
map-created-texts-reverse
: map-created-texts-reverse
Mark
: Article Marks
mark-as-read
: mark-as-read
mark-as-unread
: mark-as-unread
mark-text
: mark-text
mark-text-old
: mark-text-old
Member
: Membership Information
Membership
: Membership Information
Membership-10
: Membership Information
Membership-Old
: Membership Information
Membership-Type
: Membership Information
Misc-Info
: Article Information
modify-conf-info
: modify-conf-info
modify-system-info
: modify-system-info
modify-text-info
: modify-text-info
Pers-No
: Common Types
Person
: Person Status Types
Personal-Flags
: Person Status Types
Priv-Bits
: Person Status Types
query-async
: query-async
query-predefined-aux-items
: query-predefined-aux-items
query-read-texts
: query-read-texts
query-read-texts-10
: query-read-texts-10
query-read-texts-old
: query-read-texts-old
re-lookup-conf
: re-lookup-conf
re-lookup-person
: re-lookup-person
re-z-lookup
: re-z-lookup
Read-Range
: Membership Information
RPC
: Simple Data Types
Scheduling-Info
: Session Information
SELECTION
: Simple Data Types
send-message
: send-message
Session-Flags
: Session Information
Session-Info
: Session Information
Session-Info-Ident
: Session Information
Session-No
: Common Types
set-client-version
: set-client-version
set-conf-type
: set-conf-type
set-connection-time-format
: set-connection-time-format
set-etc-motd
: set-etc-motd
set-expire
: set-expire
set-garb-nice
: set-garb-nice
set-info
: set-info
set-keep-commented
: set-keep-commented
set-last-read
: set-last-read
set-membership-type
: set-membership-type
set-motd-of-lyskom
: set-motd-of-lyskom
set-passwd
: set-passwd
set-permitted-submitters
: set-permitted-submitters
set-pers-flags
: set-pers-flags
set-presentation
: set-presentation
set-priv-bits
: set-priv-bits
set-read-ranges
: set-read-ranges
set-scheduling
: set-scheduling
set-super-conf
: set-super-conf
set-supervisor
: set-supervisor
set-unread
: set-unread
set-user-area
: set-user-area
shutdown-kom
: shutdown-kom
Static-Server-Info
: Server Information
Static-Session-Info
: Session Information
Stats
: Statistics
Stats-Description
: Statistics
sub-comment
: sub-comment
sub-footnote
: sub-footnote
sub-member
: sub-member
sub-recipient
: sub-recipient
sync-kom
: sync-kom
Text-List
: Common Types
Text-Mapping
: Mapping Local to Global Text Numbers
Text-No
: Common Types
Text-Number-Pair
: Mapping Local to Global Text Numbers
Text-Stat
: Article Information
Text-Stat-Old
: Article Information
Time
: Common Types
UConference
: Conference Status Types
unmark-text
: unmark-text
user-active
: user-active
Version-Info
: Server Information
who-am-i
: who-am-i
Who-Info
: Who Information
Who-Info-Ident
: Who Information
Who-Info-Old
: Who Information
who-is-on
: who-is-on
who-is-on-dynamic
: who-is-on-dynamic
who-is-on-ident
: who-is-on-ident
who-is-on-old
: who-is-on-old
Or in modern terms, enabling technology for Computer-Supported Cooperative Work (CSCW).
Also known as "PottaKOM" and "BortaKOM."
The number is not truly global; it is local to a specific LysKOM server.
The LysKOM server is normally configured so that anybody can create new conferences, even if they do not have this privilege.
The LysKOM server is normally configured so that anybody can create new persons, even if they do not have this privilege.
The default port for a LysKOM server is 4894. That port was registered with IANA 2001-06-20.
In the early 1990s there was much discussion about the next generation LysKOM protocol, called "Protocol B", and at one point in time it was believed that "Protocol B" would arrive at the same time as "Emacs 19". "Emacs 19" arrived and was obsoleted by new versions. Meanwhile, it was discovered that "Protocol A" was more extensible that first believed. "Protocol A" will continue to evolve, but it is unlikely that it will ever be superseded by "Protocol B".
Client writers are encouraged to write the clients so that they are prepared for replies that are sent out-of-order. See Future changes, for speculations about how that may benefit the client in the future.
The supervisor
may be a person, in which
case the members of that person's mailbox become supervisors.
permitted-submitters
can be
a person, in which case all persons who are members of the associated
mailbox are allowed to submit articles to the conference.
This is true if the text is created
using create-text
, create-anonymous-text
,
create-anonymous-text-old
or create-text-old
.
Future requests that create texts may have other semantics.
RFC 2782 (DNS SRV) provided
inspiration when the Scheduling-Info
structure was defined.
This conference is a standard Lysator conference. It's all Padrone's fault.
Another client might
create a new text immediately before the server processes this
set-unread
call, so you might end up setting
last-text-read
to something unexpected.
This
difference was not intentional, but it is now too late to change the
semantics of either get-map
or get-created-texts
.
Besides, they are both obsolete calls.