\input texinfo @c -*-texinfo-*- @c @c FIXME: Explain how the garb works with nice and keep-commented @c @c %**start of header @setfilename protocol-a.info @settitle LysKOM Protocol A @setchapternewpage odd @c @afourpaper @set PROTOEDITION 10.4 @set PROTOVER 10 @set VERSION 1.0.4 @c @holl{l, s} is used to construct Hollerith strings. The main @c reason to use this macro is to help the spell checker. @macro holl {l, s} \l\H\s\ @end macro @c @c Define a few strings that contains characters from ISO Latin-1. @c @iftex @c ispell-ignore @set IAM Inl@"a{}gg @}t mig @set Pell P@"ar Emanuelsson @set Kent Kent Eng@-str@"om@penalty-10000 @set presconf @holl{27,Presentation (av nya) m@"oten} @c ispell-end-ignore @end iftex @ifnottex @c ispell-ignore @set IAM Inlägg @}t mig @set Pell Pär Emanuelsson @set Kent Kent Engström @set presconf @holl{27,Presentation (av nya) möten} @c ispell-end-ignore @end ifnottex @c @c Index setup @c @c Index for asynchronous messages. @defcodeindex am @c Merge all indices. @syncodeindex am fn @syncodeindex tp fn @c @c Special markup for this document. @c @c Indicate something that shouldn't be spell-checked @macro badspell{s} \s\ @end macro @c @req{login} is used for protocol requests. @macro req {n} @code{\n\} @end macro @c @reqlink{login} is used for protocol requests, that should be linked. @ifhtml @macro reqlink {n} @code{@ref{\n\}} @end macro @end ifhtml @ifnothtml @macro reqlink {n} @code{\n\} (@pxref{\n\}) @end macro @end ifnothtml @c @reqdlink{login}...@linkhere{} is used for protocol requests, that @c should be linked, where the link should occur a few words after the @c request itself. @ifhtml @c HTML version: make the word a link. @macro reqdlink {n} @code{@ref{\n\}} @unmacro linkhere @macro linkhere @end macro @end macro @end ifhtml @ifnothtml @ifnottex @c Info version: create @linkhere as a macro that contains a reference. @macro reqdlink {n} @code{\n\} @unmacro linkhere @macro linkhere (@pxref{\n\}) @end macro @end macro @end ifnottex @iftex @c TeX version: this produces output similar to the Info version. @c ispell-ignore @tex \gdef\reqdlink#1{% \code{#1}% \gdef\linkhere{ (\pxref{#1})}% } @end tex @c ispell-end-ignore @end iftex @end ifnothtml @c @aux{mx-allow-filter} is used for aux-item names. @macro aux {n} @code{\n\} @end macro @c @async{async-login} is used for async names. @macro async {n} @code{\n\} @end macro @c @asynclink{async-login} is used for async names, that should be linked. @ifhtml @macro asynclink {n} @code{@ref{\n\}} @end macro @end ifhtml @ifnothtml @macro asynclink {n} @code{\n\} (@pxref{\n\}) @end macro @end ifnothtml @c @asyncdlink{async-login}...@linkhere{} is used for async messages, @c that should be linked, where the link should occur a few words after @c the async name itself. @ifhtml @c HTML version: make the word a link. @macro asyncdlink {n} @code{@ref{\n\}} @unmacro linkhere @macro linkhere @end macro @end macro @end ifhtml @ifnothtml @ifnottex @c Info version: create @linkhere as a macro that contains a reference. @macro asyncdlink {n} @code{\n\} @unmacro linkhere @macro linkhere (@pxref{\n\}) @end macro @end macro @end ifnottex @iftex @c TeX version: this produces output similar to the Info version. @c ispell-ignore @tex \gdef\asyncdlink#1{% \code{#1}% \gdef\linkhere{ (\pxref{#1})}% } @end tex @c ispell-end-ignore @end iftex @end ifnothtml @c @type{Conference} is used for LysKOM types. @macro type {n} @code{\n\} @end macro @c @lt{Conference} is used for linked types. The link is only present @c when it is unobtrusive. It should only be used inside @c @example...@end example. @ifhtml @macro lt {n} @ref{\n\} @end macro @end ifhtml @ifnothtml @macro lt {n} \n\ @end macro @end ifnothtml @c @priv{wheel} is used for privilege bits. @macro priv {n} @code{\n\} @end macro @c @conftype{rd-prot} is used for conference type bits. @macro conftype {n} @code{\n\} @end macro @c @misc{bcc-recpt} is used for misc-info names. @macro misc {n} @code{\n\} @end macro @c @rarg{passwd} is used to reference arguments of requests. This is @c *only* used in the nodes that defines the requests. @macro rarg {n} @code{\n\} @end macro @c @aarg{text-no} is used to reference arguments of asynchronous @c messages. This is *only* used in the nodes that defines the @c relevant asynchronous message. @macro aarg {n} @code{\n\} @end macro @c @errorcode{no-such-text} is used to mark error codes. @macro errorcode {n} @code{\n\} @end macro @c @field{ident-user} is used to mark fields of struct types. @macro field {n} @code{\n\} @end macro @c @reqexample is used immediately before Protocol-A example @c fragments. @macro reqexample @need 2000 @i{Example:} @end macro @c @c Define strings that can be encoded as macros instead of with @set. @c @macro daemon @badspell{d@ae{}mon} @end macro @c %**end of header @ifinfo This is the LysKOM Protocol A specification, edition @value{PROTOEDITION}. It specifies version @value{PROTOVER} of the protocol. It corresponds to version @value{VERSION} of lyskomd. Copyright @copyright{} 1995-2000 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. @ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries a copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore 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. @end ifinfo @c FIXME: What does this do? @c ispell-ignore @iftex @parindent 0pt @font@tensltt=cmsltt10 @tex \global\def\rett#1{{\let\t\sltt\tt #1}} \global\def\sltt#1{{\fam\ttfam\tensltt\let\t\rett #1}} \global\let\t\sltt @end tex @end iftex @c ispell-end-ignore @titlepage @title{LysKOM Protocol A} @subtitle{Protocol version @value{PROTOVER}} @subtitle{Edition @value{PROTOEDITION}} @subtitle{(lyskomd @value{VERSION})} @author by the LysKOM Developers @page @c ispell-ignore @vskip 0pt plus 1filll @c ispell-end-ignore Copyright @copyright{} 1995-2000 Lysator ACS Permission is granted to make and distribute verbatim copies of this document 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. @end titlepage @ifnothtml @contents @end ifnothtml @dircategory LysKOM @direntry * Protocol A: (protocol-a). The LysKOM Protocol A specification. @end direntry @c ispell-ignore @ifhtml @html Lysator LysKOM
@end html @end ifhtml @c ispell-end-ignore @node Top @top LysKOM Protocol A This document specifies version @value{PROTOVER} of LysKOM Protocol A. This is edition @value{PROTOEDITION} of the specification. It corresponds to version @value{VERSION} of lyskomd. The most up-to-date version if this document can always be found at @uref{http://www.lysator.liu.se/lyskom/protocol/}. @menu * Preface:: What is LysKOM? Who wrote this document? * Concepts:: Articles, conferences, aux-items, @dots{} * Fundamentals:: The building blocks of Protocol A. * LysKOM Data Types:: Domain-specific data types used in Protocol A. * Protocol Requests:: Each request explained in depth. * Asynchronous Messages:: Unsolicited information from the server. * Error Codes:: All error codes with explanations. * Aux-Item Types:: All predefined aux-item types. * Name Expansion:: Looking up the name of a conference or person. * LysKOM Content Types:: Predefined content types for articles. * The User Area:: Store client-specific settings in the server. * Writing Clients:: A few tips for client writers. * Importing and Exporting E-Mail:: A few thoughts on e-mail integration. * Future changes:: The protocol is not yet perfect. * Protocol Version History:: The protocol was even less perfect before. * Document Edition History:: Changes in this document. * Index:: Index of protocol elements. @end menu @ifnottex @node Preface @chapter Preface @end ifnottex LysKOM is a conferencing system@footnote{Or in modern terms, enabling technology for Computer-Supported Cooperative Work (CSCW).}. Similar systems were QZ-KOM and PortaCOM@footnote{Also known as ``PottaKOM'' and ``BortaKOM.''}. 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 @email{ceder@@lysator.liu.se}, David Byers @email{byers@@lysator.liu.se}, @value{Pell} @email{pell@@lysator.liu.se}, Thomas Bellman @email{bellman@@lysator.liu.se}, Lars Aronsson @email{aronsson@@lysator.liu.se}, Linus Tolke @email{linus@@lysator.liu.se} and @value{Kent} @email{kent@@lysator.liu.se}. The LysKOM developers can be reached by email to @email{lyskom@@lysator.liu.se}. @node Concepts @chapter Concepts used in LysKOM This chapter introduces the concepts used in LysKOM, such as articles, conferences and sessions. @menu * Articles:: Reading and writing articles is what LysKOM is about. * Conferences:: Articles are organized in conferences. * Persons and Sessions:: Persons log on to the LysKOM system. * The Misc-Info List:: How articles are organized in comment chains and in conferences. * The Aux-Item List:: A generic extension mechanism. * Security:: Some persons have more privileges than others. * Membership and Reading:: You don't have to read anything twice. @end menu @node Articles @section Articles An article is represented as a value of the type @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 @field{nice} value of each of its recipients and it is not marked by any user. There is an array of @type{Misc-Info} included in the @type{Text-Stat}. This array contains information about recipients, senders, comments and footnotes. Each article is identified by a number, the global@footnote{The number is not truly global; it is local to a specific LysKOM server.} article number (the @type{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 @type{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 @reqdlink{local-to-global} does this@linkhere{}. @node Conferences @section Conferences Conferences hold articles. They are represented in the protocol as a data type called @type{Conference}. Each conference has a @dfn{creator}, the person who created the conference, and a @dfn{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. We have also introduced a type called @type{UConference} (pronounced micro-conf-stat) which holds a subset of the information contained in the full @type{Conference} type. Use the @type{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 @conftype{rd-prot}, @conftype{letterbox}, @conftype{secret}, @conftype{original}, @conftype{allow-anonymous} and @conftype{forbid-secret} are defined. @table @conftype @item rd-prot The conference is protected from reading by non-members. Persons become members by having one of the existing members or supervisors add him or her to the conference. This restriction is enforced by the server. @item original Conferences of this type are intended for original articles only. Comments are to be redirected to the super-conference instead. This restriction is currently not enforced by the server; clients must implement this functionality. @item letterbox Conferences of this type are connected to persons. Letters to a person are sent to the mailbox and the name of the mailbox is synchronized with the person name. It is currently not possible to explicitly set or clear this flag on a conference. @item secret Conferences of this type are secret. The server will not divulge any information about the existence of the conference to persons who are not members or supervisors of the conference. If a mailbox is made secret, that person cannot log in using the person name, but must specify a person number instead. @item allow-anonymous Conferences of this type accept anonymous articles. Other conferences will reject anonymous articles. @item forbid-secret Conferences of this type do not allow secret members. If a conference is changed to this type, preexisting secret members remain secret. @end table @node Persons and Sessions @section Persons and Sessions Persons are represented in the protocol by values of the type @type{Person}. Associated with persons are statistics, a set of personal flags and a set of privileges (@pxref{Security}). Persons are also associated with a conference that has the same number as the person and the @conftype{letterbox} bit set. Connections to the server are represented as values of the type @type{Static-Session-Info}, @type{Session-Info-Ident} or @type{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. @node The Misc-Info List @section The Misc-Info List The @type{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. @subsection Recipient @table @misc @item recpt Starts a recipient group. It contains the conference number of a recipient of the article. @item loc-no Always present within a recipient group. It contains the local text number of the article in the conference specified by the preceding @misc{recpt} field. @item rec-time If the recipient is a person, this element is added by the server when the recipient marks the article as read. It contains the time when the text was read. @item sent-by Present when the recipient was added by a person other than the author (after the article was created.) It contains the person number of the person who added the recipient. @item sent-at Present when the recipient was added after the article was created. It contains the time when the recipient was added. @end table @subsection Carbon Copy (CC) Recipient 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. @table @misc @item cc-recpt Starts a carbon-copy recipient group. It contains the conference number of a carbon-copy recipient of the article. @item loc-no Always present in a CC recipient group. It contains the local text number of the article in the conference specified by the most recent @misc{cc-recpt} field. @item rec-time Present after the CC recipient has read the article. It contains the time when the article was read. Since only persons can read articles this will only be seen if the CC recipient is a person. @item sent-by Present when a CC recipient was added by a person other than the author after the article had been created. It contains the person number of the person who added the CC recipient. @item sent-at Present when a CC recipient was added after the article had been created. It is the time when the CC recipient was added. @end table @subsection Blank Carbon Copy (BCC) Recipient 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 @reqlink{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.) @table @misc @item bcc-recpt Starts a blank carbon-copy recipient group. It contains the conference number of a blank carbon-copy recipient of the article. @item loc-no Always present in a BCC recipient group. It contains the local text number of the article in the conference specified by the most recent @misc{bcc-recpt} field. @item rec-time Present after the BCC recipient has read the article. It contains the time when the article was read. Since only persons can read articles this will only be seen if the BCC recipient is a person. @item sent-by Present when a BCC recipient was added by a person other than the author after the article had been created. It contains the person number of the person who added the BCC recipient. @item sent-at Present when a BCC recipient was added after the article had been created. It is the time when the BCC recipient was added. @end table @subsection Comment To @table @misc @item comm-to Always present when the article is a comment to another article. @item sent-by Present when the article was added as a comment by a person other than the author, after the article had been created. It contains the person number of the person who added the article as a comment. @item sent-at Present when the article was added as a comment after the article had been created. It contains the time when it was added as a comment. @end table @subsection Footnote To @table @misc @item footn-to Always present when the article is a footnote to another article. @item sent-at Present when the article was added as a footnote after the article had been created. It contains the time when it was added as a footnote. @end table @subsection Comment in @table @misc @item comm-in Present when there are comments to this article. It contains the article number which is a comment to this article. @end table @subsection Footnote in @table @misc @item footn-in Present when there are footnotes to this article. It contains the article number which is a footnote to this article. @end table @node The Aux-Item List @section The Aux-Item List The aux-item list is used as a generic extension mechanism in the LysKOM server and in protocol A. @menu * About Aux-Items:: An introduction to aux-items. * Predefined Aux-Item Types:: Predefined aux-items are part of the protocol. * Client-Specific Aux-Item Types:: Clients can allocate aux-items for their private use. * Experimental Aux-Item Types:: A block of aux-items are reserved for experimental use. * Defining New Aux-Item Types:: Creating new aux-item types is easy. @end menu @node About Aux-Items @subsection About Aux-Items Aux-items were introduced in protocol version 10 as a mechanism for extending the conference, text and server information structures without changing the protocol. Persons were excluded since nobody could figure out a case where setting an aux-item on the mailbox wasn't as good as setting it on the person (another reason was that I was fed up writing aux-item code by the time they were working on texts and conferences.) The exact structure of an aux item is specified elsewhere (@pxref{Auxiliary Information}). The important fields here are the @field{aux-no}, @field{tag} and @field{data} fields. The @field{aux-no} field is used to identify an item. The @field{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 @field{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 @field{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 @field{data} field is a simple string. The meaning of the string is determined by the @field{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.) @node Predefined Aux-Item Types @subsection Predefined Aux-Item Types 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 (@errorcode{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. @xref{Aux-Item Types}, for the complete list of predefined Aux-Item types. @node Client-Specific Aux-Item Types @subsection Client-Specific 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 @ref{Predefined Aux-Item Types}. Currently, the following ranges are assigned to clients: @itemize @bullet @item 10000-10099: The Elisp Client @item 10100-10199: komimportmail @end itemize If you want a range of numbers, send e-mail to the LysKOM development group. @node Experimental Aux-Item Types @subsection Experimental Aux-Item Types Experimental numbers are free for all. Use @badspell{'em} any way you want. All numbers in the range 20000-29999 are for experimental use. @node Defining New Aux-Item Types @subsection Defining New Aux-Item Types 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. @node Security @section Security 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 @priv{wheel}, @priv{admin}, @priv{statistic}, @priv{create-conf}, @priv{create-pers} and @priv{change-name}. Security levels range from 0 to 255. @table @priv @item wheel @emph{Normally not assigned} @table @asis @item Level 0 Person may always log in, even when LysKOM is crowded. @item Level 6 Person may set Priv-Bits for all persons. @item Level 7 Person may set password for all persons. @item Level 8 Person acts as supervisor for everything. @item Level 10 Person can read all articles. @end table @item admin @emph{Normally not assigned} @table @asis @item Level 1 Shut down the server@* Set motd-of-kom@* Read last-login @item Level 2 Read status of secret conferences and persons@* Read the protected parts of person and conference statuses@* Read the entire text status, even when there are secret recipients @item Level 3 Change everybody's names @item Level 4 Add/remove members@* Add/remove recipients to articles @item Level 5 Set super-conference@* Remove articles @item Level 6 Set administrator @end table @item statistic @emph{Normally not assigned} @table @asis @item Level 2 Read the statistics portions of persons, even if protected @end table @item create-conf @emph{Normally assigned} @table @asis @item Level 0 Create conferences @end table @item create-pers @emph{Normally assigned} @table @asis @item Level 0 Create persons @end table @end table @node Membership and Reading @section Membership and Reading Persons' memberships in conferences are represented in the protocol as arrays of @type{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 @field{last-text-read} and @field{read-texts} fields. All texts with local numbers up to @field{last-text-read} have been read. In addition, all texts with local numbers contained in the @field{read-texts} array have 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: @enumerate @item Fetch the membership to get the @field{last-text-read} @item Use @reqlink{local-to-global} to translate a number of local numbers to global numbers. @item Remove the global numbers corresponding to local numbers contained in @field{read-texts} from the result. @item Get and translate more texts as needed. @end enumerate The process is complicated because of the translation between local and global text numbers. If the server does not implement the @reqdlink{local-to-global} call@linkhere{}, it is possible to use the less efficient but perfectly serviceable @reqdlink{get-map} call instead@linkhere{}. @node Fundamentals @chapter Fundamentals of Protocol A 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. @menu * Notation:: The grammar used in this document. * Simple Data Types:: BOOL, INT32, ARRAY, @dots{} * Connecting to the Server:: The initial handshake. * Client-Server Dialog:: Requests, replies, asynchronous messages. * Protocol Error Messages:: How the server reacts to syntax errors. @end menu @node Notation @section Notation 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 @type{INT32} and @type{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: @type{Text-Stat}.) The operator @code{::=} defines the name to its left. Comments start with @code{!} (exclamation mark) and alternatives are separated by a @code{|} (vertical bar.) A @code{;} (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. @node Simple Data Types @section Simple Data Types @anchor{INT32} @anchor{INT16} @anchor{INT8} @anchor{BOOL} @subsection Integers @tindex INT32 @tindex INT16 @tindex INT8 @tindex BOOL @type{INT32}, @type{INT16}, @type{INT8} and @type{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. @anchor{HOLLERITH} @subsection Strings @tindex HOLLERITH @type{HOLLERITH} denotes character strings of arbitrary length. They are transmitted as @code{@var{n}H@var{text}} where @var{text} is the string and @var{n} is the number of characters in @var{text} in decimal notation. All byte values are allowed in the string itself, including nulls. Long live FORTRAN! @anchor{BITSTRING} @subsection Bit Strings @tindex BITSTRING @type{BITSTRING} is a string of bits, commonly used for a set of boolean-valued flags. Bit strings are denoted as @example BITSTRING ( name-1; name-2; name-3; @dots{} ) @end example 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 @example shape-of-world ::= BITSTRING ( is-flat; is-round; is-2d; is-3d; ) @end example most peoples idea of @code{shape-of-world} would be sent as @code{0101} (round and three-dimensional.) @anchor{ENUMERATION} @subsection Enumerations @tindex ENUMERATION @type{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 @example ENUMERATION ( name-1=value-1; name-2=value-2; name-3=value-3; @dots{} ) @end example 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 datatype: @example Info-type ::= ENUMERATION-OF(Misc-Info) @end example 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. @example language ::= ENUMERATION ( hakka = 1; guwal = 2; ciokwe = 3; yoruba = 4; hopi = 5; ) @end example @anchor{ARRAY} @subsection Arrays @tindex ARRAY @type{ARRAY} is a list of a fixed number of elements of a single type. The specification for an array is @code{ARRAY @var{type}} where @var{type} is the type of the array elements. Arrays are transmitted as an @code{@var{n} @{ @var{element} @var{element} @dots{} @}} where @var{n} is the number of elements and each @var{element} is an element of the array. A special case is when the array is empty, in which case the server transmits it as @code{0 *}. Note that the client must always transmit empty arrays as @code{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 @code{@var{n} *} where @var{n} is the number of elements in the array. @anchor{SELECTION} @subsection Selection @tindex SELECTION @type{SELECTION} is tagged data. It consists of an INT32 selector followed by a tail of an arbitrary type and is specified as @example SELECTION ( @var{n}=@var{name} @var{tail} : @var{type}; @var{n}=@var{name} @var{tail} : @var{type}; @dots{} ) @end example where each @var{n} is the selector value, @var{name} the selector name and @var{tail} the name of the selector tail and @var{type} its type. @var{name} and @var{tail} are often very similar, such as @samp{sent-by} and @samp{sender}. When transmitted, the selector is transmitted as an INT32 followed by the tail belonging to that selector. For instance, given the specification @example description ::= SELECTION ( 1=name the_name : HOLLERITH; 2=age years : INT32; ) @end example two legal messages of the type @code{description} are @samp{1 @holl{4,John}} and @samp{2 18}. @anchor{RPC} @subsection RPC @tindex RPC @type{RPC} is a notation used to specify calls to the server. An RPC specification has the following form: @example RPC ( @var{call} [@var{n}] ( @var{request} ) -> ( @var{reply} ) ; @var{call} [@var{n}] ( @var{request} ) -> ( @var{reply} ) ; ) @end example where each @var{call} is the name of a call, @var{n} is the call number, @var{request} is a single data element sent as a request and @var{reply} is a single data element sent in reply from the server. RPC calls are transmitted as @var{n} @var{request} where @var{n} and @var{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 @ref{Client-Server Dialog}. @subsection Structure Structures are collections of several data items. In the specification they are written as @example ( @var{name} : @var{type} ; @var{name} : @var{type} ; @dots{} ) @end example where each @var{name} is the name of a data field and the corresponding @var{type} is its type. Structures are transmitted as a sequence of their fields. @node Connecting to the Server @section Connecting to the Server 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 port@footnote{The default port for a LysKOM server is 4894.} and sending a single letter which is used to select a protocol version. This letter should always be @samp{A}@footnote{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''.}. The protocol version letter should be followed by connection information required by that protocol. In protocol A the connection information is a @type{HOLLERITH} string saying who the user connecting is followed by a newline character. The format of the string should be @samp{@var{username} % @var{hostname}}. When the server has accepted the connection it replies with the string @code{LysKOM} on a single line. @example % telnet kom.lysator.liu.se 4894 Trying 130.236.254.151 ... Connected to varg.lysator.liu.se. @c This comment matches the bracket on the next line: [ Escape character is '^]'. A@holl{26,byers%kajsa.lysator.liu.se} LysKOM @end example Besides the string @samp{LysKOM}, the server may respond with @samp{%%LysKOM unsupported protocol.} or @samp{%% No connections left.}. The @samp{%%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 @samp{A}. The connection will be closed by the server as soon as this string has been sent. The @samp{%% 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. @node Client-Server Dialog @section Client-Server Dialog After connecting (@pxref{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 @emph{must} be terminated with a linefeed character (ASCII 0x0A). @example server-call ::= ( ref-no : INT32; request : Protocol-Request; ) @end example 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 requests@footnote{Client writers are encouraged to write the clients so that they are prepared for replies that are sent out-of-order. @xref{Future changes}, for speculations about how that may benefit the client in the future.}. @example 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." @end example Our notation is not flexible enough to specify the two-way nature of the communication. @field{ref-no} in the reply is always the same as @field{ref-no} in the corresponding request. @field{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 @errorcode{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 @code{error-reply} errors are replies to syntactically correct calls to the server, while @code{protocol-error} are replies to syntactically incorrect calls. @xref{Protocol Error Messages}, for more information about @code{protocol-error}. If a call cannot complete successfully, LysKOM will respond with an @code{error-reply}. The meaning of @field{error-code} and @field{error-status} varies depending on the request; see @ref{Error Codes}, and the documentation for each call, for a list of available @field{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 @field{error-status} was more or less undefined before protocol version 10. For protocol version 10, the meaning of @field{error-status} is defined in this document. The meaning of @field{error-status} can be modified by any call. In particular the calls that deal with Misc-Info lists set @field{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: @errorcode{temporary-failure}, @errorcode{internal-error}, @errorcode{feature-disabled}, @errorcode{not-implemented}, @errorcode{obsolete-call}, @errorcode{ldb-error}, @errorcode{feature-disabled}, @errorcode{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 (@pxref{Asynchronous Messages}) to the client at any time (but not in the middle of a reply). Two important asynchronous messages are @async{async-new-text} (@pxref{async-new-text}) and @async{async-send-message} (@pxref{async-send-message}). @node Protocol Error Messages @section Protocol Error Messages 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. @table @asis @item "%% LysKOM protocol error." The client has sent a request that does not comply with protocol A. The server will attempt to recover from this error, but additional calls may be silently lost, and the server may send replies that the client does not expect, and in some cases recovery may not be possible. This error is also returned when the client sends an array that is longer than the maximum allowed by the server. @item "%%Insane token length." The client has sent a single token that is insanely long. Typically this means that the client has sent several kilobytes worth of digits, or something similar. This is never returned for long strings. The server will automatically disconnect a client who sends a token with an insane length. @item "%%Insane array size." The client has send an array with a negative length. The server is not easily fooled. The server will automatically disconnect a client who sends an array with an insane length. @end table @node LysKOM Data Types @chapter LysKOM Data Types 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. @menu * Common Types:: Simple types used over and over again. * Auxiliary Information:: Aux-items and related types. * Conference Types:: A few flags for conferences. * Conference Search Results:: Name lookup returns these types. * Conference Status Types:: Information about a conference. * Archaic way to list conferences:: Archaic name lookup result type. * Mapping Local to Global Text Numbers:: The Text-Mapping type. * Server Information:: Information about an installation. * Person Status Types:: Information about a person. * Membership Information:: Persons are members of conferences. * Article Marks:: Persons can mark articles. * Article Information:: Information about an article. * Who Information:: Old-style info about logged-on users. * Session Information:: New-style info about logged-on users. @end menu @node Common Types @section Common Types The types defined in this section are fairly simple and used in many of the more complex data types. @anchor{Time} @subsection Time @tindex Time @example Time ::= ( seconds : @lt{INT32}; minutes : @lt{INT32}; hours : @lt{INT32}; day : @lt{INT32}; month : @lt{INT32}; year : @lt{INT32}; day-of-week : @lt{INT32}; day-of-year : @lt{INT32}; is-dst : @lt{BOOL}; ) @end example @type{Time} is used to specify times in several data structures. The fields @field{seconds}, @field{minutes} and @field{hours} give wall clock time. @field{day} is the day of month and @field{month} is the current month, starting with zero for January. @field{year} is the number of years since 1900. @field{day-of-week} is the current weekday, with zero used for Sunday. @field{day-of-year} is how many days of the year have passed starting with zero and @field{is-dst} is true when the time indicated is daylight savings time. When the server receives a @type{Time} structure from a client it ignores the @field{day-of-week} and @field{day-of-year} fields. All times are expressed in the time zone of the server. @anchor{Conf-No} @subsection Conference Numbers @tindex Conf-No @example Conf-No ::= @lt{INT16}; @end example This type denotes a conference number. @need 1511 @anchor{Text-No} @anchor{Local-Text-No} @anchor{Text-List} @subsection Text Numbers @tindex Text-No @tindex Local-Text-No @tindex Text-List @example Text-No ::= @lt{INT32}; Local-Text-No ::= @lt{INT32}; Text-List ::= ( first-local-no : @lt{Local-Text-No}; texts : @lt{ARRAY} @lt{Text-No}; ) @end example These three types are used to indicate articles in the LysKOM database. @type{Text-No} is a global text number and @type{Local-Text-No} a local text number. @type{Text-List} is used when a mapping from local to global numbers are required. @anchor{Pers-No} @anchor{Session-No} @subsection Person and Session Numbers @tindex Pers-No @tindex Session-No @example Pers-No ::= @lt{Conf-No}; Session-No ::= @lt{INT32}; @end example @type{Pers-No} is used to indicate a person. @type{Session-No} is used in a few data structures relating to information about active LysKOM sessions. @node Auxiliary Information @section Auxiliary Information @anchor{Aux-No} @anchor{Aux-Item} @anchor{Aux-Item-Input} @anchor{Aux-Item-Flags} @tindex Aux-No @tindex Aux-Item @tindex Aux-Item-Input @tindex Aux-Item-Flags @example Aux-No ::= @lt{INT32}; Aux-Item ::= ( aux-no : @lt{Aux-No}; tag : @lt{INT32}; creator : @lt{Pers-No}; created-at : @lt{Time}; flags : @lt{Aux-Item-Flags}; inherit-limit : @lt{INT32}; data : @lt{HOLLERITH}; ) Aux-Item-Input ::= ( tag : @lt{INT32}; flags : @lt{Aux-Item-Flags}; inherit-limit : @lt{INT32}; data : @lt{HOLLERITH}; ) @need 2200 Aux-Item-Flags ::= BITSTRING ( deleted; inherit; secret; hide-creator; dont-garb; reserved2; reserved3; reserved4; ) @end example 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: @table @field @item aux-no The number of the item within the list where it is found. This number together with a conference or text number uniquely identifies a particular aux-item. (There is also a global list of Aux-Items for the server. That list is manipulated via the @reqdlink{modify-system-info} request@linkhere{}, and when using that request the @field{aux-no} is enough to uniquely identify the aux-item.) This field is not present in @type{Aux-Item-Input}. It is assigned by the server. @item tag The item tag. The tag determines what the data means. @item creator The person who created the item, or zero if the item was created anonymously or if the owner is being withheld. This field is not present in @type{Aux-Item-Input}. It is assigned by the server. @item created-at The time when the item was created. This field is not present in @type{Aux-Item-Input}. It is assigned by the server. @item flags The item flags (see below). @item inherit-limit Determines how many times (how deep) an item may be inherited. If zero, the item is inherited an unlimited number of times. If nonzero it is @emph{one more} than the number of additional times the item may be inherited. Thus, 1 means that inheritance will be blocked and 2 means that the item will be inherited only to the next level. @item data The item data. @end table The flags that can be set on an aux-item have the following meaning: @table @field @item deleted The item has been deleted, and should not be used for anything. @item inherit The item will be inherited (if the inherit-limit field allows it.) @item secret The item will not be revealed to anyone but the item's creator and supervisors of the creator. @item hide-creator The item creator will be withheld from everyone but the item's creator and supervisors of the creator. @item dont-garb The object the item is set on will not be garbage-collected. @end table @node Conference Types @section Conference Types @anchor{Conf-Type} @anchor{Extended-Conf-Type} @anchor{Any-Conf-Type} @tindex Conf-Type @tindex Extended-Conf-Type @tindex Any-Conf-Type @example 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 ::= @lt{Conf-Type} | @lt{Extended-Conf-Type}; @end example These types are used to specify the type of a conference. @type{Conf-Type} is used in data types and calls that were created before version 8.0 of the protocol and has been augmented in @type{Extended-Conf-Type}. The type @type{Any-Conf-Type} is used when either is admissible. The bits have the following meaning (@pxref{Conferences}, for more info.) @table @conftype @item rd-prot If unset anyone can add themselves as members to the conference. @item original If set, comments are not allowed in the conference. @item secret If set the conference is secret. It's existence will only be revealed to members and supervisors. @item letterbox Set if the conference is a person's mailbox. @item allow-anonymous Set if anonymous articles are allowed in the conference. @item forbid-secret If set, secret members cannot be added to the conference. @itemx reserved2 @itemx reserved3 Reserved for future use. The values of these bits should be never be modified or used by clients who do not know their meaning. When a new conference is created these should always be set to zero. @end table @node Conference Search Results @section Conference Search Results @anchor{Conf-Z-Info} @tindex Conf-Z-Info @example Conf-Z-Info ::= ( name : @lt{HOLLERITH}; type : @lt{Conf-Type}; conf-no : @lt{Conf-No}; ) @end example These types are used for the result of some calls that search for conferences based on their names. @node Conference Status Types @section Conference Status Types @anchor{Garb-Nice} @anchor{Conference-Old} @tindex Garb-Nice @tindex Conference-Old @tindex Conference @tindex UConference @example Garb-Nice ::= @lt{INT32}; Conference-Old ::= ( name : @lt{HOLLERITH}; type : @lt{Conf-Type}; creation-time : @lt{Time}; last-written : @lt{Time}; creator : @lt{Pers-No}; presentation : @lt{Text-No}; supervisor : @lt{Conf-No}; permitted-submitters : @lt{Conf-No}; super-conf : @lt{Conf-No}; msg-of-day : @lt{Text-No}; nice : @lt{Garb-Nice}; no-of-members : @lt{INT16}; first-local-no : @lt{Local-Text-No}; no-of-texts : @lt{INT32}; ) @anchor{Conference} Conference ::= ( name : @lt{HOLLERITH}; type : @lt{Extended-Conf-Type}; creation-time : @lt{Time}; last-written : @lt{Time}; creator : @lt{Pers-No}; presentation : @lt{Text-No}; supervisor : @lt{Conf-No}; permitted-submitters : @lt{Conf-No}; super-conf : @lt{Conf-No}; msg-of-day : @lt{Text-No}; nice : @lt{Garb-Nice}; keep-commented : @lt{Garb-Nice}; no-of-members : @lt{INT16}; first-local-no : @lt{Local-Text-No}; no-of-texts : @lt{INT32}; expire : @lt{Garb-Nice}; aux-items : @lt{ARRAY} @lt{Aux-Item}; ) @anchor{UConference} UConference ::= ( name : @lt{HOLLERITH}; type : @lt{Extended-Conf-Type}; highest-local-no : @lt{Local-Text-No}; nice : @lt{Garb-Nice}; ) @end example These three types are used to specify information about a conference. @type{Garb-Nice} is a quantity used to specify how long articled are kept in a conference before being removed. @type{Conference} is the full information about a conference and @type{UConference} is brief information about a conference. The fields of @type{Conference} are @table @field @item name The name of this conference. @item type The type of the conference. @item creation-time The date and time when the conference was created. @item last-written The date when something was last written in the conference. @item creator The person who created the conference. @item presentation The article containing the conference presentation or zero if the conference has no presentation. @item supervisor The conference@footnote{The @field{supervisor} may be a person, in which case the members of that person's mailbox become supervisors.} who supervises this conference. @item permitted-submitters The conference whose members@footnote{@field{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.} may submit articles to the conference, or zero if anyone may do so. @item super-conf The conference that receives comments if this conference does not accept them. Zero means the author of the comment in question. @item msg-of-day The conference notice, if any. @item nice The number of days an article should be kept before being removed from the conference. @item keep-commented A text that has comments no older than this number of days will not be removed from the conference. @item no-of-members The number of members of this conference. @item first-local-no The local number of the oldest existing article in the conference. @item no-of-texts The number of articles in the conference. @item expire This field will be used to control when a conference expires. It is not used at the moment, and should be set to zero for future compatibility. @item aux-items The conference's aux item list. @end table The fields of @type{UConference} are @table @field @item name The name of this conference. @item type The conference type. Note that this is an extended conference type, unlike the type field of @type{Conference}. @item highest-local-no The local number of the newest article in the conference. @item nice The number of days an article should be kept before being removed from the conference. @end table @node Archaic way to list conferences @section Archaic way to list conferences @anchor{Conf-List-Archaic} 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: @tindex Conf-List-Archaic @example Conf-List-Archaic ::= ( conf-nos : @lt{ARRAY} @lt{Conf-No}; conf-types : @lt{ARRAY} @lt{Conf-Type}; ! Sans @var{n}; see below ) @end example The two arrays @field{conf-nos} and @field{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 @ref{lookup-name}. @node Mapping Local to Global Text Numbers @section Mapping Local to Global Text Numbers @anchor{Text-Mapping} @tindex Text-Mapping @tindex Local-To-Global-Block @tindex Text-Number-Pair @example Text-Mapping ::= ( range-begin : @lt{Local-Text-No}; range-end : @lt{Local-Text-No}; later-texts-exists : @lt{BOOL}; block : @lt{Local-To-Global-Block}; ) @anchor{Local-To-Global-Block} Local-To-Global-Block ::= SELECTION ( 0=sparse sparse-block : @lt{ARRAY} @lt{Text-Number-Pair}; 1=dense dense-block : @lt{Text-List}; ) @anchor{Text-Number-Pair} Text-Number-Pair ::= ( local-number : @lt{Local-Text-No}; global-number : @lt{Text-No}; ) @end example A @type{Text-Mapping} is used when the client needs to look up which global @type{Text-No} that corresponds to a @type{Local-Text-No}. The client uses @reqlink{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 @type{Text-Mapping}. @table @field @item range-begin The first local text number that the client asked about. @item range-end The first local text number that the reply doesn't say anything about. This @type{Text-Mapping} tells the client about all existing texts from @field{range-begin} to (but not including) @field{range-end}. @item later-texts-exists This is true if there are more texts in the conference after this block. @item block The block can be sent i two formats. The server is free to choose which format to use as it pleases; clients must be prepared for any of them. @itemize @bullet @item The @dfn{sparse} format is useful when many local text number no longer exists. It starts with a @code{0} that indicates that the sparse format is used, and is followed by an array of @type{Text-Number-Pair}. The array will always be sorted so that @field{local-number} always increases. @item The @dfn{dense} format is good when most of the local text numbers exist. It starts with a @code{1} that indicates that the dense format is used, and is followed by a @type{Text-List}. The @type{Text-List} contains @field{first-local-no} and an array of @type{Text-No}. The local text number @field{first-local-no} corresponds to the first @type{Text-No} in the array, @field{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. @end itemize @end table @node Server Information @section Server Information @anchor{Info} @tindex Info @tindex Info-Old @tindex Version-Info @example Info ::= ( version : @lt{INT32}; conf-pres-conf : @lt{Conf-No}; pers-pres-conf : @lt{Conf-No}; motd-conf : @lt{Conf-No}; kom-news-conf : @lt{Conf-No}; motd-of-lyskom : @lt{Text-No}; aux-item-list : @lt{ARRAY} @lt{Aux-Item}; ) @anchor{Info-Old} Info-Old ::= ( version : @lt{INT32}; conf-pres-conf : @lt{Conf-No}; pers-pres-conf : @lt{Conf-No}; motd-conf : @lt{Conf-No}; kom-news-conf : @lt{Conf-No}; motd-of-lyskom : @lt{Text-No}; ) @anchor{Version-Info} Version-Info ::= ( protocol-version : @lt{INT32}; server-software : @lt{HOLLERITH}; software-version : @lt{HOLLERITH}; ) @end example These data types contain information about the LysKOM server. The fields of @type{Info} and @type{Info-Old} are @table @field @item version The server version encoded as a number @var{@badspell{aa}}@var{@badspell{bb}}@var{@badspell{cc}} where @var{@badspell{aa}} is the major version number, @var{@badspell{bb}} the minor number and @var{@badspell{cc}} the secondary minor version. For instance, @code{10607} is version 1.6.7 of the server. If greater than 10699 the @reqlink{get-version-info} should be used instead. @item conf-pres-conf The conference that contains conference presentations. @item pers-pres-conf The conference that contains person presentations. @item motd-conf The conference that contains conference and person notices. @item kom-news-conf The conference that contains news about LysKOM. @item motd-of-lyskom The number of an article to display when LysKOM is entered or zero if there is none. @item aux-item-list (Not present in @type{Info-Old}.) A list of aux-items that belong to the server. @end table The fields of @type{Version-Info} are: @table @field @item protocol-version The version of protocol A the server is using. This may be used to ascertain which calls are available. @item server-software Human-readable name of the server software. @item software-version Human-readable name of the server software version. @end table @node Person Status Types @section Person Status Types @anchor{Person} @tindex Person @tindex Personal-Flags @tindex Priv-Bits @example Person ::= ( username : @lt{HOLLERITH}; privileges : @lt{Priv-Bits}; flags : @lt{Personal-Flags}; last-login : @lt{Time}; user-area : @lt{Text-No}; total-time-present : @lt{INT32}; sessions : @lt{INT32}; created-lines : @lt{INT32}; created-bytes : @lt{INT32}; read-texts : @lt{INT32}; no-of-text-fetches : @lt{INT32}; created-persons : @lt{INT16}; created-confs : @lt{INT16}; first-created-local-no : @lt{INT32}; no-of-created-texts : @lt{INT32}; no-of-marks : @lt{INT16}; no-of-confs : @lt{INT16}; ) @anchor{Personal-Flags} Personal-Flags ::= BITSTRING ( unread-is-secret; flg2; flg3; flg4; flg5; flg6; flg7; flg8; ) @anchor{Priv-Bits} Priv-Bits ::= BITSTRING ( wheel; admin; statistic; create-pers; create-conf; change-name; flg7; flg8; flg9; flg10; flg11; flg12; flg13; flg14; flg15; flg16; ) @end example These types are used to specify information about persons. @type{Person} contains the information about a person, @type{Personal-Flags} contains flags set by the user and @type{Priv-Bits} contains the person's privileges. The fields of @type{Person} are @table @field @item username The name of the user. @c FIXME: this is wrong/needs explanation/should be renamed. @item privileges The privileges of the person. @item flags Flags set by the user. @item last-login The time when the person last logged on. @item user-area The text number of the person's user area or zero if the person has no user area. @item total-time-present The number of seconds the person has been using LysKOM. @item sessions The number of sessions the person has initiated. @item created-lines The number of lines of articles the person has written. @item created-bytes The number of characters the person has written. @item read-texts The number of articles the person has read. @item no-of-text-fetches The number of texts the person has retrieved from the server. @item created-persons The number of other persons this person has created. @item created-confs This holds the number of conferences created by the person. @item first-created-local-no The local number of the earliest existing article written by the person. The local number applies to a local-to-global mapping containing all articles written by the person. @item no-of-created-texts This holds the number of articles written by the person. @item no-of-marks The number of marked texts this person has. @item no-of-confs The number of conferences the person is a member of. @end table @node Membership Information @section Membership Information @anchor{Membership-Type} @tindex Membership-Type @example Membership-Type ::= BITSTRING ( invitation; passive; secret; reserved1; reserved2; reserved3; reserved4; reserved5; ) @end example The @type{Membership-Type} type contains flags that modify a membership. It is passed as part of both @type{Member} and @type{Membership}. The flags are: @table @field @item invitation The member has been invited, but has not yet accepted membership. Clients should set this flag when adding other users as members. The server may force this flag to be set when adding another person as a member of a conference. @item passive The member is not actively participating in the conference. Passive members do not receive group messages and should not be displayed as active members by clients. @item secret The member does not wish to disclose the membership. Secret memberships and members are cleared before being returned to a person who is not a supervisor of the member or has sufficient privileges enabled. @end table The remaining flags in the @type{Membership-Type} structure are reserved and should be set to false on all new memberships and retained on all existing memberships. @anchor{Member} @tindex Member @example Member ::= ( member : @lt{Pers-No}; added-by : @lt{Pers-No}; added-at : @lt{Time}; type : @lt{Membership-Type}; ) @end example The @type{Member} structure encodes information about a member in a conference. It is returned by the @reqdlink{get-members} call@linkhere{}. The fields of a @type{Member} structure are @table @field @item member The person who is a member of the conference. @item added-by The person who created the membership. This field is zero only if the membership was created before protocol version 10 was introduced. @item added-at The time when the membership was created. This field is meaningless if added-by is zero. @item type Flags modifying the membership. @end table The contents of a @type{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. @anchor{Membership-Old} @tindex Membership-Old @tindex Membership @example Membership-Old ::= ( last-time-read : @lt{Time}; conference : @lt{Conf-No}; priority : @lt{INT8}; last-text-read : @lt{Local-Text-No}; read-texts : @lt{ARRAY} @lt{Local-Text-No}; ) @anchor{Membership} Membership ::= ( position : @lt{INT32}; last-time-read : @lt{Time}; conference : @lt{Conf-No}; priority : @lt{INT8}; last-text-read : @lt{Local-Text-No}; read-texts : @lt{ARRAY} @lt{Local-Text-No}; added-by : @lt{Pers-No}; added-at : @lt{Time}; type : @lt{Membership-Type}; ) @end example The @type{Membership} structure encodes information about a person's membership in a conference. It is returned by the @reqlink{query-read-texts} and @reqdlink{get-membership} calls@linkhere{}. @table @field @item position The position of this membership in the membership list. @item last-time-read The time when the person last read anything from the conference. @item conference The conference this membership data pertains to. @item priority The priority the person has assigned to the conference. The higher the number, the higher the priority. In the past, priority zero indicated a passive membership. This usage is now obsolete. @item last-text-read The local number of last text read in the conference. @item read-texts Additional texts beyond @field{last-text-read} that have also been read. @item added-by The person who created the membership. This field is zero if the membership was created before protocol version 10 was introduced. @item added-at The time when the membership was created. This field is meaningless if added-by is zero. @item type Flags modifying the membership. @end table 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. @node Article Marks @section Article Marks @anchor{Mark} @tindex Mark @example Mark ::= ( text-no : @lt{Text-No}; type : @lt{INT8}; ) @end example This data type hold information about a person's marks on articles. The fields of @type{Mark} are @table @field @item text-no The text number marked. @item type The mark value. @end table 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. @node Article Information @section Article Information @anchor{Misc-Info} @tindex Misc-Info @tindex Text-Stat-Old @tindex Text-Stat @tindex Info-Type @example Misc-Info ::= SELECTION ( 0=recpt recipient : @lt{Conf-No}; 1=cc-recpt cc-recipient : @lt{Conf-No}; 2=comm-to comment-to : @lt{Text-No}; 3=comm-in commented-in : @lt{Text-No}; 4=footn-to footnote-to : @lt{Text-No}; 5=footn-in footnoted-in : @lt{Text-No}; 6=loc-no local-no : @lt{Local-Text-No}; 7=rec-time received-at : @lt{Time}; 8=sent-by sender : @lt{Pers-No}; 9=sent-at sent-at : @lt{Time}; 15=bcc-recpt bcc-recipient : @lt{Conf-No}; ) @anchor{Info-Type} Info-Type ::= ENUMERATION-OF(@lt{Misc-Info}) @anchor{Text-Stat-Old} Text-Stat-Old ::= ( creation-time : @lt{Time}; author : @lt{Pers-No}; no-of-lines : @lt{INT32}; no-of-chars : @lt{INT32}; no-of-marks : @lt{INT16}; misc-info : @lt{ARRAY} @lt{Misc-Info}; ) @anchor{Text-Stat} Text-Stat ::= ( creation-time : @lt{Time}; author : @lt{Pers-No}; no-of-lines : @lt{INT32}; no-of-chars : @lt{INT32}; no-of-marks : @lt{INT16}; misc-info : @lt{ARRAY} @lt{Misc-Info}; aux-items : @lt{ARRAY} @lt{Aux-Item}; ) @end example These two structures contain information about a single article. @type{Text-Stat} contains core information about the article and @type{Misc-Info} contains miscellaneous information related to the article. A @type{Text-Stat} consists of the following: @table @field @item creation-time The time when the article was created. @item author The author of the article. @item no-of-lines The number of lines in the article. @item no-of-chars The number of characters in the article. @item no-of-marks The number of marks added to this article by persons. @item misc-info The @type{Misc-Info} list for this article. @item aux-items The list of aux items for this article. @end table @type{Misc-Info}, when sent to the client, is sent in a particular order (@pxref{The Misc-Info List}). The variants @type{Misc-Info} are (briefly): @table @misc @item recpt Used to specify recipients of the article. @item cc-recpt Specifies recipients who have received a copy of the article but who will not receive comments. @item comm-to Specifies an article this article is a comment to. @item comm-in Specifies an article in which there are comments to this article. @item footn-to Specifies an article this article is a footnote to. @item footn-in Specifies an article to which this article is a footnote. @item loc-no Specifies the local text number of this article in the conference specified by @misc{recpt} or @misc{cc-recpt}. @item rec-time Specifies the time when this article was received by the conference specified by @misc{recpt} or @misc{cc-recpt}. @item sent-by Specifies who sent this article to the conference specified by @misc{recpt} or @misc{cc-recpt}. @item sent-at Specifies when the article was sent to the conference specified by @misc{recpt} or @misc{cc-recpt}. @item bcc-recpt Specifies a blind carbon copy recipient. This item is only accepted by protocol version 10 servers and is only sent in responses and messages introduced in protocol version 10 or later. @end table @node Who Information @section Who Information @anchor{Who-Info-Old} @anchor{Who-Info} @anchor{Who-Info-Ident} @tindex Who-Info-Old @tindex Who-Info @tindex Who-Info-Ident @example Who-Info-Old ::= ( person : @lt{Pers-No}; working-conference : @lt{Conf-No}; what-am-i-doing : @lt{HOLLERITH}; ) Who-Info ::= ( person : @lt{Pers-No}; working-conference : @lt{Conf-No}; session : @lt{Session-No}; what-am-i-doing : @lt{HOLLERITH}; username : @lt{HOLLERITH}; ) Who-Info-Ident ::= ( person : @lt{Pers-No}; working-conference : @lt{Conf-No}; session : @lt{Session-No}; what-am-i-doing : @lt{HOLLERITH}; username : @lt{HOLLERITH}; hostname : @lt{HOLLERITH}; ident-user : @lt{HOLLERITH}; ) @end example These structures are used to retrieve information on who is currently using LysKOM. All the requests using these types are obsolete, but @type{Who-Info} is used by @async{async-i-am-on} (@pxref{async-i-am-on}). The fields of @type{Who-Info-Old} are @table @field @item person The person the information is about. @item working-conference The conference the person is currently in. @item what-am-i-doing A client-supplied string saying what the person is doing. @end table The fields of @type{Who-Info} are @table @field @item person The person the information is about. @item working-conference The conference the person is currently in. @item session The person's session number. @item what-am-i-doing A client-supplied string saying what the person is doing. @item username The name of the ``real'' user constructed from @field{hostname} and @field{ident-user} (see below) and information from the client. @c FIXME: define the format @end table The fields of @type{Who-Info-Ident} are @table @field @item person The person the information is about. @item working-conference The conference the person is currently in. @item session The person's session number. @item what-am-i-doing A client-supplied string saying what the person is doing. @item username The name of the ``real'' user constructed from @field{hostname} and @field{ident-user}. @c FIXME: define the format @item hostname The host the connection originated at. @item ident-user The user name according to the Ident @daemon{} at the user's machine or ``unknown'' if Ident was not used. @end table @node Session Information @section Session Information @anchor{Session-Info} @anchor{Session-Info-Ident} @tindex Session-Info @tindex Session-Info-Ident @tindex Static-Session-Info @tindex Session-Flags @tindex Dynamic-Session-Info @example Session-Info ::= ( person : @lt{Pers-No}; working-conference : @lt{Conf-No}; session : @lt{Session-No}; what-am-i-doing : @lt{HOLLERITH}; username : @lt{HOLLERITH}; idle-time : @lt{INT32}; connection-time : @lt{Time}; ) Session-Info-Ident ::= ( person : @lt{Pers-No}; working-conference : @lt{Conf-No}; session : @lt{Session-No}; what-am-i-doing : @lt{HOLLERITH}; username : @lt{HOLLERITH}; hostname : @lt{HOLLERITH}; ident-user : @lt{HOLLERITH}; idle-time : @lt{INT32}; connection-time : @lt{Time}; ) @anchor{Static-Session-Info} Static-Session-Info ::= ( username : @lt{HOLLERITH}; hostname : @lt{HOLLERITH}; ident-user : @lt{HOLLERITH}; connection-time : @lt{Time}; ) @anchor{Session-Flags} Session-Flags ::= BITSTRING ( invisible; user-active-used; user-absent; reserved3; reserved4; reserved5; reserved6; reserved7; ) @anchor{Dynamic-Session-Info} Dynamic-Session-Info ::= ( session : @lt{Session-No}; person : @lt{Pers-No}; working-conference : @lt{Conf-No}; idle-time : @lt{INT32}; flags : @lt{Session-Flags}; what-am-i-doing : @lt{HOLLERITH}; ) @end example These data types give information about a particular LysKOM session. The types @type{Session-Info} and @type{Session-Info-Ident} have been superseded by @type{Static-Session-Info} and @type{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 @type{Session-Info} are @table @field @item person The person using this session. @item working-conference The conference the session is currently in. @item session The number of this session. @item what-am-i-doing A client-supplied string saying what the person is currently doing. @item username The name of the ``real'' user (see @type{Who-Info} above.) @item idle-time @c FIXME: should this be user-active-call? The number of seconds since the last server call. @item connection-time The time when the connection was initiated. This is not the same as the amount of time the person has been on. @end table The fields of @type{Session-Info-Ident} are @table @field @item person The person using this session. @item working-conference The conference the session is currently in. @item session The number of this session. @item what-am-i-doing A client-supplied string saying what the person is currently doing. @item username The name of the ``real'' user (see @type{Who-Info-Ident} above.) @item hostname The host the connection originated at. @item ident-user The user name according to the Ident @daemon{} at the user's machine or ``unknown'' if Ident was not used. @item idle-time The number of seconds since the last server call. @item connection-time The time when the connection was initiated. This is not the same as the amount of time the person has been on. @end table The fields of @type{Static-Session-Info} are @table @field @item username The name of the ``real'' user (see @type{Who-Info-Ident} above.) @item hostname The host the connection originated at. @item ident-user The user name according to the Ident @daemon{} at the user's machine or ``unknown'' if Ident was not used. @item connection-time The time when the connection was initiated. This is not the same as the amount of time the person has been on. @end table The bits in @type{Session-Flags} are: @table @field @item invisible When true, the user requested an invisible session (@pxref{login}). Sessions where no-one is logged in also have the @field{invisible} flag set. @item user-active-used When true, the @reqdlink{user-active} call@linkhere{} has been issued by the session, which in turn means that @field{idle-time} field in the @type{Dynamic-Session-Info} is valid. @item user-absent This flag is currently not used. @end table The fields of a @type{Dynamic-Session-Info} are @table @field @item session The session number of the session. @item person The person currently logged on, or zero if the session has not yet logged on. @item working-conference The conference the session is currently in. @item idle-time The number of seconds that have passed since the last time @reqlink{user-active} was called in the session. @item flags The dynamic session flags (see above.) @item what-am-i-doing What the client is doing. This string is set by the client. @end table @node Protocol Requests @chapter Protocol Requests 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. @menu * Protocol Notation:: The notation used when describing the requests and their replies. * login-old:: O Log in to LysKOM. Call 62 is preferred (0) * logout:: r Log out. Call 62 to log in again (1) * change-conference:: r Change current conference (2) * change-name:: r Change name of a conference or person (3) * change-what-i-am-doing:: r Change what-am-i-doing in who information (4) * create-person-old:: O Create a person (5) * get-person-stat-old:: O Get person information. Use call 49 (6) * set-priv-bits:: r Set privileges of a person (7) * set-passwd:: r Set password of a person (8) * query-read-texts-old:: O Get info on what is read (9) * create-conf-old:: O Create a conference (10) * delete-conf:: r Delete a conference (11) * lookup-name:: O Look up a name. Replaced by call 76 (12) * get-conf-stat-older:: O Get conference information. Use call 50 (13) * add-member-old:: O Add a member to a conference (14) * sub-member:: r Remove a member from a conference (15) * set-presentation:: r Set the presentation of a conference (16) * set-etc-motd:: r Set conference notice (17) * set-supervisor:: r Set supervisor of a conference (18) * set-permitted-submitters:: r Set permitted submitters of a conference (19) * set-super-conf:: r Set super-conference of a conference (20) * set-conf-type:: r Set the type of a conference (21) * set-garb-nice:: r Set garb-nice of a conference (22) * get-marks:: r Get marks for a person (23) * mark-text-old:: O Mark a text. Replaced by calls 72 and 73 (24) * get-text:: r Get an article or part of an article (25) * get-text-stat-old:: O Get text status information (26) * mark-as-read:: r Mark an article as read in a conference (27) * create-text-old:: O Create an article (28) * delete-text:: r Delete an article (29) * add-recipient:: r Add a recipient to an article (30) * sub-recipient:: r Remove a recipient from an article (31) * add-comment:: r Add a comment to an article (32) * sub-comment:: r Remove a comment from an article (33) * get-map:: O Map local text nos to global. Use 103 (34) * get-time:: r Get the current time (35) * get-info-old:: O Get server information (36) * add-footnote:: r Add an article as a footnote to another (37) * sub-footnote:: r Remove a footnote from an article (38) * who-is-on-old:: O Get active sessions. Replaced by call 63 (39) * set-unread:: r Set number of unread in a conference (40) * set-motd-of-lyskom:: r Set LysKOM message of the day (41) * enable:: r Set security level (42) * sync-kom:: r Save the database (43) * shutdown-kom:: r Shut LysKOM down (44) * broadcast:: O Broadcast a message. Replaced by call 53 (45) * get-membership-old:: O Get membership for a person. Use call 99 (46) * get-created-texts:: O Get texts created by a user. Use 104 (47) * get-members-old:: O Get members of a conference. Use 101 (48) * get-person-stat:: r Get status information for a person (49) * get-conf-stat-old:: O Get status information for a conference (50) * who-is-on:: O Get current sessions. Use call 63 (51) * get-unread-confs:: r Get conferences with unread articles (52) * send-message:: r Send a personal message (53) * get-session-info:: O Get session information. Use call 64 (54) * disconnect:: r Disconnect a session (55) * who-am-i:: r Get current session number (56) * set-user-area:: r Set a person's user area (57) * get-last-text:: r Get text created before a certain time (58) * create-anonymous-text-old:: O Create an anonymous text (59) * find-next-text-no:: r Get next text number (60) * find-previous-text-no:: r Get previous text number (61) * login:: r Log in to LysKOM (62) * who-is-on-ident:: r Get current sessions (63) * get-session-info-ident:: r Get session information (64) * re-lookup-person:: O Look up a person based on name (65) * re-lookup-conf:: O Look up a conference based on name (66) * lookup-person:: O Find persons matching abbreviated name (67) * lookup-conf:: O Find conference matching abbrev'd name (68) * set-client-version:: r Set the name and version the client (69) * get-client-name:: r Get the name of the client (70) * get-client-version:: r Get the version of the client (71) * mark-text:: r Mark a text (72) * unmark-text:: r Unmark a text (73) * re-z-lookup:: r Lookup for conferences and persons (74) * get-version-info:: r Get protocol version of server (75) * lookup-z-name:: r Look up an abbreviated name (76) * set-last-read:: r Set text last read in a conference (77) * get-uconf-stat:: r Get abbreviated conference status (78) * set-info:: r Set server information (79) * accept-async:: r Select asynchronous messages to receive (80) * query-async:: r Ask server which async messages are sent (81) * user-active:: r Tell the server that the user is active (82) * who-is-on-dynamic:: r Get a list of active users (83) * get-static-session-info:: r Get static information about a session (84) * get-collate-table:: r Get the current collate table (85) * create-text:: r Create a text (86) * create-anonymous-text:: r Create an anonymous text (87) * create-conf:: r Create a conference (88) * create-person:: r Create a person (89) * get-text-stat:: r Get text status information (90) * get-conf-stat:: r Get conference status information (91) * modify-text-info:: r Add or delete text aux items (92) * modify-conf-info:: r Add or delete conference aux items (93) * get-info:: r Get server information (94) * modify-system-info:: r Add or delete system aux items (95) * query-predefined-aux-items:: r Get list of aux-items the server knows (96) * set-expire:: e Set the expire field of a conference (97) * query-read-texts:: r Get info on what is read (98) * get-membership:: r Get membership for a person (99) * add-member:: r Add a member to a conference (100) * get-members:: r Get members of a conference (101) * set-membership-type:: r Modify the type of conference (102) * local-to-global:: r Map local text numbers to global ones (103) * map-created-texts:: r Map texts created by a person to global (104) * set-keep-commented:: e Set how new comments protect old texts (105) * set-pers-flags:: r Set personal flags (106) @end menu @ifnottex @node Protocol Notation @section Protocol Notation @end ifnottex The heading for each call looks something like this: @display create-person-old [5] (1) Obsolete (10) @end display The heading consists of several parts: @table @asis @item The name: @samp{create-person-old} This is the name of the call. The name is not considered part of the protocol. It may change in future versions of this document. Since the name is never sent over the network it doesn't matter that much. @item The call number: @samp{[5]} The call number is what really matters, since it is sent over the network. It will never change. @item Introduced: @samp{(1)} The protocol version when the call was first implemented. Some calls added more functionality in a later protocol version. The description for those calls describes such changes. @item The status: @samp{Obsolete} The status of the call (see below). @item Made obsolete: @samp{(10)} This figure is only present for some obsolete calls, and it states in which protocol version the call was obsoleted. @end table The status of a call can be any of: @table @samp @item Experimental The call is experimental. No client should rely on the existence of this call. Experimental calls that are useful will usually become recommended in future versions. @item Recommended The call is a standard call. Clients are recommended to use these calls rather than experimental or obsolete ones. Servers are required to implement all recommended calls. @item Obsolete The call should no longer be used by clients. Servers should implement these, or they will be incompatible with old client versions. @emph{Please note:} the documentation for the obsolete calls may be incomplete. Many of them perform compatibility magic to ensure that they never return anything that old clients don't expect. This compatibility magic is often documented, but we may have forgotten to document it in some places. @end table @i{A note about the examples:} The examples consist of a number of calls and replies. @iftex Calls are set in a normal typewriter font. Replies are set in a slanted typewriter font. @end iftex Extra newlines are sometimes inserted in the examples to avoid overly long lines. @node login-old @section login-old [0] (1) Obsolete @findex login-old @example login-old [0] (( person : @lt{Pers-No}; passwd : @lt{HOLLERITH} )) -> ( ); @end example Log in as a person. This call has been replaced by @reqlink{login}. @subheading Error codes @table @errorcode @item undefined-person @rarg{person} is not an existing person. @item login-disallowed Logins are not allowed and @rarg{person} does not have the @priv{wheel} bit set. @item invalid-password @rarg{passwd} is not the correct password for @rarg{person}. The @field{error-status} indicates the person number. @end table @node logout @section logout [1] (1) Recommended @findex logout @example logout [1] ( ) -> ( ); @end example Log out from LysKOM. This call does not disconnect the session; use @reqdlink{disconnect} for that@linkhere{}. After issuing a @req{logout} call the client can reconnect as the same or a different person using the @reqdlink{login} call@linkhere{}. 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. @subheading Error codes This call never fails. @node change-conference @section change-conference [2] (1) Recommended @findex change-conference @example change-conference [2] ( conference : @lt{Conf-No} ) -> ( ) ; @end example Change current conference of a session. This call used to be called pepsi (the name was a very obscure and not very funny joke.) @subheading Error codes @table @errorcode @item login-first The session is not logged in yet. @item undefined-conference Conference @rarg{conference} does not exist or is secret. @item conference-zero @rarg{conference} is zero. @item not-member The user currently logged in is not a member of @rarg{conference}. @end table @node change-name @section change-name [3] (1) Recommended @findex change-name @example change-name [3] (( conference : @lt{Conf-No}; new-name : @lt{HOLLERITH} )) -> ( ) ; @end example 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. @subheading Error codes @table @errorcode @item login-first The session is not logged in yet. @item undefined-conference Conference @rarg{conference} does not exist or is secret. @item conference-zero @rarg{conference} is zero. @item permission-denied Permission denied. The @priv{change-name} bit is not set or the user does not have enough access to @rarg{conference}. @item conference-exists @rarg{new-name} is already occupied by another conference. @item string-too-long @rarg{new-name} is too long for a valid conference name. @item bad-name There are invalid characters in @rarg{new-name}. @end table @node change-what-i-am-doing @section change-what-i-am-doing [4] (1) Recommended @findex change-what-i-am-doing @example change-what-i-am-doing [4] ( what-am-i-doing : @lt{HOLLERITH} ) -> ( ); @end example 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. @subheading Error codes @table @errorcode @item string-too-long @rarg{what-am-i-doing} is too long. @end table @node create-person-old @section create-person-old [5] (1) Obsolete (10) @findex create-person-old @example create-person-old [5] (( name : @lt{HOLLERITH}; passwd : @lt{HOLLERITH} )) -> ( @lt{Pers-No} ); @end example 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. @reqexample @example 1 5 @holl{24,LysKOM} Statistics Daemon @holl{6,secret} @t{=1 6} @end example 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. @subheading Error codes @table @errorcode @item login-first The session is not logged in and the server does not allow person creation before logging in. @item permission-denied The server does not allow anyone to create person and the person currently logged on does not have the @priv{create-pers} bit set. @item conference-exists There is already a conference named @rarg{name}. @item invalid-password The string @rarg{passwd} is not a valid password. @end table @node get-person-stat-old @section get-person-stat-old [6] (1) Obsolete @findex get-person-stat-old @example get-person-stat-old [6] (( person : @lt{Pers-No}; mask : @lt{INT32} )) -> ( @lt{Person} ); @end example This call returns information about a person. If the low bit of @rarg{mask} is not set, then the name is not returned. This call is obsolete and has been replaced by @reqlink{get-person-stat}. @subheading Error codes @table @errorcode @item login-first This call can't be executed without logging in first. @item undefined-person Person @rarg{person} does not exist. @item undefined-conference Conference @rarg{person} does not exist or is secret. @item conference-zero @rarg{person} is zero. @end table @node set-priv-bits @section set-priv-bits [7] (1) Recommended @findex set-priv-bits @example set-priv-bits [7] (( person : @lt{Pers-No}; privileges : @lt{Priv-Bits} )) -> ( ); @end example This call sets the privileges of @rarg{person} to @rarg{privileges}. @xref{Security}. To successfully issue this call the session must be logged in as a person with sufficient privileges. @reqexample @example 1 7 6 0010000000000000 @t{=1} @end example This example sets the privileges of person 6 to nothing but @priv{statistic}. This particular set of privileges might be useful for a person used by a statistics-collecting @daemon{}. @subheading Error codes @table @errorcode @item login-first This call can't be executed without logging in first. @item undefined-person @rarg{person} is not a valid person. @item permission-denied The person currently logged in does not have the @priv{wheel} bit set and privilege level set to 6 or higher. @end table @node set-passwd @section set-passwd [8] (1) Recommended @findex set-passwd @example set-passwd [8] (( person : @lt{Pers-No}; old-pwd : @lt{HOLLERITH}; new-pwd : @lt{HOLLERITH} )) -> ( ); @end example This call is used to set the password of @rarg{person} to @rarg{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 @rarg{old-pwd}. @reqexample @example 1 8 5 @holl{6,gazonk} @holl{7,a9go8Hz} @t{=1} @end example This example sets the password of the LysKOM administrator to ``a9go8Hz'' provided that the old password was ``gazonk''. @subheading Error codes @table @errorcode @item login-first This call cannot be executed without logging in. @item undefined-person @rarg{person} is not a valid person. @item permission-denied Attempt to change password of another person without being the supervisor of that person and without the @priv{wheel} bit set and privilege level 7 or higher enabled. @item invalid-password @rarg{old-pwd} is invalid or @rarg{new-pwd} is invalid as a password. @end table @node query-read-texts-old @section query-read-texts-old [9] (1) Obsolete (10) @findex query-read-texts-old @example query-read-texts-old [9] (( person : @lt{Pers-No}; conference : @lt{Conf-No} )) -> ( @lt{Membership-Old} ); @end example 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. @rarg{person} is the person being queried and @rarg{conference} is the conference in question. Calling @req{query-read-texts-old} does not require the session to be logged in. @reqexample @example 1 9 6 1 @t{=1 32 5 11 12 7 93 1 193 1 1 20 133 3 @{ 135 136 137 @}} @end example 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. @subheading Error codes @table @errorcode @item undefined-person @rarg{person} does not exist, or no access to person. @item undefined-conference Conference @rarg{conference} does not exist, or is secret. @item conference-zero @rarg{conference} is zero. @item not-member @rarg{person} is not a member of @rarg{conference}. @end table @node create-conf-old @section create-conf-old [10] (1) Obsolete (10) @findex create-conf-old @example create-conf-old [10] (( name : @lt{HOLLERITH}; type : @lt{Any-Conf-Type} )) -> ( @lt{Conf-No} ); @end example This call is used to create new conferences. @rarg{name} is the name of the new conference and @rarg{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 (@pxref{Security}). @reqexample @example 1 50 8 @t{%1 9 0} 1 10 @holl{13,@value{IAM}} 00001000 @t{=1 8} 1 50 8 @t{=1 @holl{13,@value{IAM}} 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} @end example This example creates a new conference named ``@value{IAM}''@footnote{This conference is a standard Lysator conference. It's all Padrone's fault.} which accepts all users as members and accepts anonymous articles. The server returns 7 as the new conference number. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied The server does not allow anyone to create a conference and user does not have the @req{create-conf} bit set. @item conference-exists A conference named @rarg{name} already exists. @item bad-name @rarg{name} contains invalid characters. @item string-to-long @rarg{name} is too long to be used as a conference name. @item secret-public The conference type @rarg{type} has the @conftype{secret} bit set, but the @conftype{rd-prot} bit is cleared. @end table @node delete-conf @section delete-conf [11] (1) Recommended @findex delete-conf @example delete-conf [11] ( conf : @lt{Conf-No} ) -> ( ); @end example This call deletes the conference @rarg{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. @reqexample @example 1 50 7 @t{=1 @holl{4,Test} 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 @t{=1} 1 50 7 @t{%1 9 0} @end example This example shows the successful deletion of conference number seven. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference @rarg{conf} does not exist or is secret. @item conference-zero @rarg{conf} is zero. @item permission-denied Not supervisor of @rarg{conf} and not enough privileges enabled. @item undefined-person @rarg{conf} is a mailbox but does not exist as a person (the database is corrupt.) @end table @node lookup-name @section lookup-name [12] (1) Obsolete @findex lookup-name @example lookup-name [12] ( name : @lt{HOLLERITH} ) -> ( @lt{Conf-List-Archaic} ); @end example This call returns a list of conferences matching the string @rarg{name}. lookup-name has been superseded by @reqlink{lookup-z-name}. @c ispell-ignore @reqexample @example 1 12 @holl{3,a d} @t{=1 3 @{ 217 674 1582 @} @{ 0000 1001 0000 @}} 2 12 @holl{3,:::} @t{=2 0 * *} 3 76 @holl{3,a d} 1 1 @t{=3 3 @{ @holl{31,Alkohol- (och annan) drogdebatt} 0000 217 @holl{13,Anna Degerman} 1001 674 @holl{27,Anarchy discussion (import)} 0000 1582 @}} 4 76 @holl{3,:::} 1 1 @t{=4 0 *} @end example @c ispell-end-ignore This example shows two attempts to look up a name. The first example looks up @samp{a d} and finds three matches (the middle, number 674, is a person). The second example looks up @samp{:::} which doesn't match any conference (or person). Call number 3 and 4 issues the same lookup using the @reqdlink{lookup-z-name} call@linkhere{}. (The return value for call number 3 has been broken into three lines to fit on the page.) @subheading Error codes This call always succeeds. @node get-conf-stat-older @section get-conf-stat-older [13] (1) Obsolete @findex get-conf-stat-older @example get-conf-stat-older [13] (( conf-no : @lt{Conf-No}; mask : @lt{INT32} )) -> ( @lt{Conference-Old} ); @end example This call retrieves the information associated with conference @rarg{conf-no} in the LysKOM server. This call should no longer be used; use @reqdlink{get-conf-stat} instead@linkhere{}. The @rarg{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. @subheading Error codes @table @errorcode @item undefined-conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @end table @node add-member-old @section add-member-old [14] (1) Obsolete (10) @findex add-member-old @example add-member-old [14] (( conf-no : @lt{Conf-No}; pers-no : @lt{Pers-No}; priority : @lt{INT8}; where : @lt{INT16} )) -> ( ); @end example Make the person @rarg{pers-no} a member of conference @rarg{conf-no}. The membership priority is set to @rarg{priority} and its position in the membership list is set to @rarg{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. @reqexample @example 1 46 119 0 10 0 @t{=1 1 @{ 49 14 17 13 8 91 5 255 1 119 255 0 0 * @}} 1 14 1 119 250 0 @t{=1} 1 46 119 0 10 0 @t{=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 * @}} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item undefined-person Person @rarg{pers-no} does not exist @item access-denied Not enough permissions or privileges to add members to conference @rarg{conf-no}. @item permission-denied Person @rarg{pers-no} is already a member of conference @rarg{conf-no}, but the person logged on is not a supervisor and does not have enough privileges to change the priorities of person @rarg{pers-no}. @end table @node sub-member @section sub-member [15] (1) Recommended @findex sub-member @example sub-member [15] (( conf-no : @lt{Conf-No}; pers-no : @lt{Pers-No} )) -> ( ); @end example Removes the person @rarg{pers-no} from the membership list of conference @rarg{conf-no} and remove the conference from the person's list of memberships. @reqexample @example 1 46 5 0 100 0 @t{=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 @t{=1} 1 46 5 0 100 0 @t{=1 1 @{ 49 14 17 13 8 91 5 255 1 5 255 0 0 * @}} @end example This example shows how person 5 is removed from conference one. The calls to get-membership demonstrate the effects on the LysKOM database. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item undefined-person Person @rarg{pers-no} does not exist. @item not-member Person @rarg{pers-no} is not a member of conference @rarg{conf-no}. @item permission-denied Not supervisor of conference @rarg{conf-no} or not supervisor of person @rarg{pers-no} and not enough privileges to issue the call anyway. @end table @node set-presentation @section set-presentation [16] (1) Recommended @findex set-presentation @example set-presentation [16] (( conf-no : @lt{Conf-No}; text-no : @lt{Text-No} )) -> ( ); @end example This call sets the presentation text of the conference or person @rarg{conf-no} to the text @rarg{text-no}. To remove a presentation, use a @rarg{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. @reqexample @example 1 50 6 @t{=1 @holl{11,David 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 @t{=1} 1 50 6 @t{=1 @holl{11,David 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} @end example 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 @reqdlink{get-conf-stat-old} call@linkhere{}. Later, after @req{set-presentation} has been called, the presentation field has changed. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions to change presentation of conference @rarg{conf-no}. @item no-such-text Text @rarg{text-no} does not exist or no read permission. @item mark-limit Adding a mark to text @rarg{text-no} would cause it to have too many marks. @end table @node set-etc-motd @section set-etc-motd [17] (1) Recommended @findex set-etc-motd @example set-etc-motd [17] (( conf-no : @lt{Conf-No}; text-no : @lt{Text-No} )) -> ( ); @end example This call sets the message of the day on the conference or person @rarg{conf-no} to the article @rarg{text-no} and removes the old message. To remove an old message without setting a new one, use a @rarg{text-no} of zero. This call protects the new message from automatic deletion and removes such protection from the old message just as @reqlink{set-presentation}. @reqexample @example 1 50 6 @t{=1 @holl{11,David 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 @t{=1} 1 50 6 @t{=1 @holl{11,David 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} @end example 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 @req{get-conf-stat-old} calls before and after demonstrate the change in the conference structure. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions to set the MOTD of conference @rarg{conf-no}. @item mark-limit Adding a mark to text @rarg{text-no} would cause it to have too many marks. @end table @node set-supervisor @section set-supervisor [18] (1) Recommended @findex set-supervisor @example set-supervisor [18] (( conf-no : @lt{Conf-No}; admin : @lt{Conf-No} )) -> ( ); @end example The @req{set-supervisor} call changes the supervisor of an existing conference. The result is that all members of the conference @rarg{admin} become supervisors of the conference @rarg{conf-no}. Typically, but not always, @rarg{admin} will be a mailbox. @reqexample @example 1 50 4 @t{=1 @holl{17,Nyheter 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 @t{=1} 1 50 4 @t{=1 @holl{17,Nyheter 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} @end example 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 @reqdlink{get-conf-stat-old} calls@linkhere{} before and after the @req{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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} or conference @rarg{admin} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions or privileges to change the supervisor of conference @rarg{conf-no}. @end table @node set-permitted-submitters @section set-permitted-submitters [19] (1) Recommended @findex set-permitted-submitters @example set-permitted-submitters [19] (( conf-no : @lt{Conf-No}; perm-sub : @lt{Conf-No} )) -> ( ); @end example This call grants the right to send articles to the conference @rarg{conf-no} to all members of the conference @rarg{perm-sub}. The right to submit articles is per default only granted to the members of the conference. When a person tries to submit an article but does not have the right to do so, the client is expected to send the article to the super-conference instead. @reqexample @example 1 50 4 @t{=1 @holl{17,Nyheter 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 @t{=1} 1 50 4 @t{=1 @holl{17,Nyheter 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} @end example 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 @reqdlink{get-conf-stat-old} calls@linkhere{} before and after the @req{set-permitted-submitters} call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} or conference @rarg{perm-sub} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions to change the permitted submitters of conference @rarg{conf-no}. @end table @node set-super-conf @section set-super-conf [20] (1) Recommended @findex set-super-conf @example set-super-conf [20] (( conf-no : @lt{Conf-No}; super-conf : @lt{Conf-No} )) -> ( ); @end example Makes the conference @rarg{super-conf} the super-conference of the conference @rarg{conf-no}. When an article is submitted to a conference that does not accept it, it is sent to the super-conference instead. @reqexample @example 1 50 4 @t{=1 @holl{17,Nyheter 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 @t{=2} 3 50 4 @t{=3 @holl{17,Nyheter 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} @end example This example demonstrates how the super-conference of conference 1 is set to conference 8. The calls to @reqlink{get-conf-stat-old} demonstrate the change in the conference structure. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} or conference @rarg{super-conf} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions to change super-conference of conference @rarg{conf-no}. @end table @node set-conf-type @section set-conf-type [21] (1) Recommended @findex set-conf-type @example set-conf-type [21] (( conf-no : @lt{Conf-No}; type : @lt{Any-Conf-Type} )) -> ( ); @end example Sets the conference type of conference @rarg{conf-no} to @rarg{type}. Before protocol version 8, @rarg{type} could only be four bits. Starting with protocol version 8, either a four-bit @type{Conf-Type} or an eight-bit @type{Extended-Conf-Type} is allowed. @reqexample @example 1 78 4 @t{=1 @holl{17,Nyheter om LysKOM} 00001000 1 77} 1 21 4 00000000 @t{=1} 1 78 4 @t{=1 @holl{17,Nyheter om LysKOM} 00000000 1 77} @end example This example shows a user removing the @conftype{allow-anonymous} bit from conference four. The @reqdlink{get-uconf-stat} call@linkhere{} shows all eight bits of the conference type before and after the @req{set-conf-type} call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item secret-public @rarg{type} has @conftype{secret} bit but not @conftype{rd-prot}. @item permission-denied Not enough permissions or privileges to change the conference type of conference @rarg{conf-no}. @item letterbox Attempt to change the @conftype{letterbox} flag. @item invalid-membership-type Attempt to change to a conference type that is not compatible with one of more members of the conference (for example, attempting to set @conftype{forbid-secret} on a conference with a secret member.) @field{error-status} is the id of the first person with an incompatible membership type. @end table @node set-garb-nice @section set-garb-nice [22] (1) Recommended @findex set-garb-nice @example set-garb-nice [22] (( conf-no : @lt{Conf-No}; nice : @lt{Garb-Nice} )) -> ( ); @end example Sets the expiration time for articles in conference @rarg{conf-no} to @rarg{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. @reqexample @example 1 78 4 @t{=1 @holl{17,Nyheter om LysKOM} 00000000 1 77} 1 22 4 7 @t{=1} 1 78 4 @t{=1 @holl{17,Nyheter om LysKOM} 00000000 1 7} @end example This example shows the expiration time of conference four being lowered from 77 to just seven days. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions to change the expiration time for conference @rarg{conf-no}. @end table @node get-marks @section get-marks [23] (1) Recommended @findex get-marks @example get-marks [23] ( ) -> ( @lt{ARRAY} @lt{Mark} ); @end example This call returns the list of marks the current user has set. @reqexample @example 1 23 @t{=1 3 @{ 13020 100 13043 95 12213 95 @}} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @end table @node mark-text-old @section mark-text-old [24] (1) Obsolete @findex mark-text-old @example mark-text-old [24] (( text : @lt{Text-No}; mark-type : @lt{INT8} )) -> ( ); @end example This call has been replaced by @reqlink{mark-text} and @reqlink{unmark-text} and should no longer be used. This call can only set @rarg{mark-type} to a value in the range 1 to 255 (inclusive). If @rarg{mark-type} is set to 0 the mark will be removed. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text} does not exist. @item permission-denied No read permission on text @rarg{text}. @item undefined-person The person currently logged in does not exist (can't happen error.) @item too-many-marks Marking the text would cause the person doing the marking to have too many marks, or cause the text to have too many marks. @end table @node get-text @section get-text [25] (1) Recommended @findex get-text @example get-text [25] (( text : @lt{Text-No}; start-char : @lt{INT32}; end-char : @lt{INT32} )) -> ( @lt{HOLLERITH} ); @end example Retrieve text number @rarg{text} from the LysKOM database, starting at position @rarg{start-char} and ending at position @rarg{end-char}. The first character in the text is numbered 0 and the last can be retrieved using @reqlink{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. @reqexample @example 1 25 100 0 32766 @t{=1 @holl{25,Yawn@badspell{^J}Nothing is happening}} 2 25 100 5 32766 @t{=2 @holl{20,Nothing is happening}} 3 25 100 0 3 @t{=3 @holl{4,Yawn}} @end example 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. @subheading Error codes @table @errorcode @item no-such-text The text @rarg{text} does not exits or no read permission. This error code will also be used when attempting to fetch any text except the motd-of-lyskom text without logging in first. @item text-zero Attempt to retrieve text number 0. @item index-out-of-range @rarg{start-char} is larger than the length of the text. @end table @node get-text-stat-old @section get-text-stat-old [26] (1) Obsolete (10) @findex get-text-stat-old @example get-text-stat-old [26] ( text-no : @lt{Text-No} ) -> ( @lt{Text-Stat-Old} ); @end example Get information about text number @rarg{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. @reqexample @example 1 26 100 @t{=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 @}} @end example 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. @subheading Error codes @table @errorcode @item no-such-text The text @rarg{text-no} does not exist, or no read access. This error code will also be used when attempting to fetch any text except the motd-of-lyskom text without logging in first. @item text-zero Attempt to retrieve text number 0. @end table @node mark-as-read @section mark-as-read [27] (1) Recommended @findex mark-as-read @example mark-as-read [27] (( conference : @lt{Conf-No}; text : @lt{ARRAY} @lt{Local-Text-No} )) -> ( ); @end example Marks text @rarg{text} in conference number @rarg{conference} as read for the current user. This call updates the membership record for the user. @reqexample @example 1 9 6 7 @t{=1 20 32 11 17 6 96 3 198 1 7 1 240 0 *} 1 78 7 @t{=1 @holl{13,@value{IAM}} 00001000 241 1} 1 27 7 1 @{ 241 @} @t{=1} 1 9 6 7 @t{=1 20 32 11 17 6 96 3 198 1 7 1 241 0 *} @end example This example shows person 6 marking local text number 241 in conference 7 as read. In the first query-read-texts call the person has read local text 240, but nothing higher. The mark-as-read call is reflected in the second query-read-texts 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conference} does not exist or is secret. @item conference-zero @rarg{conference} is zero. @item not-member The person logged on is not a member of conference @rarg{conference}. @item no-such-local-text One of the numbers in @rarg{text} is not a local text number in @rarg{conference}. The error argument indicates the index of the invalid number. @item local-text-zero One of the numbers in @rarg{text} is zero. @end table @node create-text-old @section create-text-old [28] (1) Obsolete (10) @findex create-text-old @example create-text-old [28] (( text : @lt{HOLLERITH}; misc-info : @lt{ARRAY} @lt{Misc-Info} )) -> ( @lt{Text-No} ); @end example Creates a new text with contents from @rarg{text} and recipients etc. defined by @rarg{misc-info} (@pxref{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 line feed 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 @misc{recpt}, @misc{cc-recpt}, @misc{bcc-recpt} (protocol version 10), @misc{comm-to} and @misc{footn-to}. @reqexample @example 1 28 @holl{20,Example\nMessage body} 3 @{ 0 5 1 112 2 33467 @} @t{:16 0 33502 13 16 15 16 6 97 3 196 1 119 1 20 0} @t{ 5 @{ 0 5 6 148 1 112 6 3438 2 33467 @} } @t{=1 33502} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{text} is longer than the maximum length of a message. @item temporary-failure The text could not be created at the moment. @item no-such-text Attempt to comment or footnote a non-existent or secret text. @item not-author Attempt to footnote a text authored by someone else. @item footnote-limit Attempt to footnote a text with the maximum number of footnotes already set. @item comment-limit Attempt to comment a text with the maximum number of comments already set. @item access-denied Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. @item anonymous-rejected Attempt to send an anonymous text to a conference that does not accept anonymous texts. @item illegal-misc Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list. @end table @node delete-text @section delete-text [29] (1) Recommended @findex delete-text @example delete-text [29] ( text : @lt{Text-No} ) -> ( ); @end example Deletes the text @rarg{text} from the LysKOM database, if the person issuing the command may do so. @reqexample @example 1 29 33467 @t{=1} @end example This simple example shows the deletion of text number 33467. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text} does not exist or no read access. @item not-author The person logged in is not the text author or supervisor of the text author. @end table @node add-recipient @section add-recipient [30] (1) Recommended @findex add-recipient @example add-recipient [30] (( text-no : @lt{Text-No}; conf-no : @lt{Conf-No}; recpt-type : @lt{Info-Type} )) -> ( ); @end example Adds @rarg{conf-no} as recipient to text @rarg{text-no}. If @rarg{recpt-type} is 1, then a @misc{cc-recpt} (@pxref{The Misc-Info List}) is created; otherwise a @misc{recpt} is created. Since protocol version 8 this call can also be used to change a @misc{cc-recpt} into a @misc{recpt} and vice versa by simply adding a recipient that already exists. Since protocol version 10 the @rarg{recpt-type} parameter is a @type{Misc-Info}. Only infos @misc{recpt}, @misc{cc-recpt} and @misc{bcc-recpt} are accepted. In protocol version 9 and earlier this argument was a @type{BOOL}, that indicated if the recipient should be a @misc{cc-recpt} (when true) or @misc{recpt} (when false). @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 30 1 5 0 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1} @t{ 3 @{ 0 5 6 1 9 34 34 17 17 6 97 4 197 1 @}} 1 30 1 5 1 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1} @t{ 3 @{ 1 5 6 1 9 34 34 17 17 6 97 4 197 1 @}} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conf-no} does not exist. @item conference-zero @rarg{conf-no} is zero. @item no-such-text The text @rarg{text-no} does not exist. @item already-recipient The conference @rarg{conf-no} is already a recipient of the same type as @rarg{recpt-type}. @item illegal-info-type @rarg{recpt-type} is not @misc{recpt}, @misc{cc-recpt} or @misc{bcc-recpt}. @item recipient-limit The text already has the maximum number of recipients. @item permission-denied Attempt to change recipient types of a recipient, but not the author of the text or supervisor of the recipient. @item access-denied Attempt to add a conference as recipient that the person logged on does not have permission to add texts to. The client may have to chase the super conf chain. @end table @node sub-recipient @section sub-recipient [31] (1) Recommended @findex sub-recipient @example sub-recipient [31] (( text-no : @lt{Text-No}; conf-no : @lt{Conf-No} )) -> ( ); @end example Removes @rarg{conf-no} from the list of recipients of text @rarg{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. @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1} @t{ 3 @{ 1 5 6 1 9 34 34 17 17 6 97 4 197 1 @}} 1 31 1 5 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 31 1 5 @t{%1 30 0} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text-no} does not exist or is secret. @item not-recipient The conference @rarg{conf-no} is not a recipient of text @rarg{text-no}. @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not supervisor of text author or conference, and not sender of text to @rarg{conf-no} and not enough privileges set and enabled. @end table @node add-comment @section add-comment [32] (1) Recommended @findex add-comment @example add-comment [32] (( text-no : @lt{Text-No}; comment-to : @lt{Text-No} )) -> ( ); @end example Add a comment link between the text @rarg{comment-to} and the text @rarg{text-no} (@rarg{text-no} becomes a comment to the text @rarg{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 @misc{comm-to} element to the text's misc-info list when the text is created (@pxref{The Misc-Info List}). @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 @{ 0 2 6 1 @}} 1 32 2 1 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 @{ 3 2 @}} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1} @t{ 4 @{ 0 2 6 1 2 1 9 19 52 18 17 6 97 4 197 1 @}} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item index-out-of-range The texts @rarg{text-no} and @rarg{comment-to} are identical. The @field{error-status} is @rarg{text-no}. @item no-such-text The text @rarg{text-no} of @rarg{comment-to} are undefined. @item comment-limit The text @rarg{comment-to} already has the maximum number of comments. @end table @node sub-comment @section sub-comment [33] (1) Recommended @findex sub-comment @example sub-comment [33] (( text-no : @lt{Text-No}; comment-to : @lt{Text-No} )) -> ( ); @end example This call removes the text @rarg{text-no} from @rarg{comment-to}'s list of comments. @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 @{ 3 2 @}} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1} @t{ 4 @{ 0 2 6 1 2 1 9 19 52 18 17 6 97 4 197 1 @}} 1 33 2 1 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 @{ 0 2 6 1 @}} @end example In this example text 2 is a comment to text 1, as shown by the misc-info lists of the two texts. The @req{sub-comment} is called. The misc-info lists are changed to reflect the change. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text One of the texts @rarg{text-no} or @rarg{comment-to} does not exist. @item not-comment The text @rarg{text-no} is not a comment to @rarg{comment-to}. @item permission-denied Not supervisor of author of @rarg{text-no} or not sender of the comment and not enough privileges set and enable to complete the call anyway. @end table @node get-map @section get-map [34] (1) Obsolete (10) @findex get-map @example get-map [34] (( conf-no : @lt{Conf-No}; first-local-no : @lt{Local-Text-No}; no-of-texts : @lt{INT32} )) -> ( @lt{Text-List} ); @end example This call has been superseded by @reqlink{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 @reqlink{query-read-texts} or @reqlink{get-membership} calls to find the last local number a user has read in a particular conference, then use the @req{get-map} call to retrieve the global numbers of all unread texts in the conference. The @rarg{conf-no} parameter specifies which conference to get the map of. @rarg{first-local-no} is the local number of the first text returned by the call. @rarg{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 @rarg{first-local-no}, specified by the call; the second element is the global number of local number @rarg{first-local-no} plus one; and so forth. The list returned by the server is at most @rarg{no-of-texts} long, but may be shorter if the call specifies more texts that there are in the conference. If @rarg{first-local-no} is higher than the highest local text number, the server will return an error. If @rarg{first-local-no} is lower than the lowest number that still exists, the server will set @rarg{first-local-no} in the returned @type{Text-List} to the first text that still exists. The size of the returned array will be decreased by the same amount as @rarg{first-local-no} is increased. This may result in an empty array being returned. (This paragraph applies even when @rarg{first-local-no} is 0.) If no texts at all exists in @rarg{conf-no} the resulting array will be empty, and @rarg{first-local-no} will be set to the number the next text to be created will receive. @reqexample @example 1 34 119 10 5 @t{=1 10 5 @{ 0 0 466 478 391 @}} 2 34 119 16 5 @t{=2 16 3 @{ 481 0 491 @}} 3 34 119 19 5 @t{%3 16 0} 4 34 120 1 5 @t{=4 4 2 @{ 480 485 @}} 5 34 120 1 2 @t{=5 4 0 *} @end example This example shows five @req{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 @rarg{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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item access-denied Conference @rarg{conf-no} is read protected. @item no-such-local-text @rarg{first-local-no} is higher than the highest local text number that ever has existed in this conference. @end table @node get-time @section get-time [35] (1) Recommended @findex get-time @example get-time [35] ( ) -> ( @lt{Time} ); @end example This call simply returns the local time according to the server. @reqexample @example 1 35 @t{=1 23 47 19 17 6 97 4 197 1} @end example 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. @subheading Error codes This call always succeeds @node get-info-old @section get-info-old [36] (1) Obsolete (10) @findex get-info-old @example get-info-old [36] ( ) -> ( @lt{Info-Old} ); @end example This call returns the @type{Info-Old} structure for the server (@pxref{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 @reqlink{get-info}. This call can be issued without logging in. @reqexample @example 1 36 @t{=1 10900 1 2 3 4 1} @end example 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. @subheading Error codes This call always succeeds. @node add-footnote @section add-footnote [37] (1) Recommended @findex add-footnote @example add-footnote [37] (( text-no : @lt{Text-No}; footnote-to: @lt{Text-No} )) -> ( ); @end example Add a footnote link between the text @rarg{footnote-to} and the text @rarg{text-no} (@rarg{text-no} becomes a footnote to the text @rarg{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. @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 @{ 0 2 6 1 @}} 1 37 2 1 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 @{ 5 2 @}} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1} @t{ 4 @{ 0 2 6 1 4 1 9 19 52 18 17 6 97 4 197 1 @}} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text-no} or @rarg{footnote-to} does not exist or is secret. @item index-out-of-range Maximum number of texts in database already. @item not-author Not author of @rarg{footnote-to}. @item footnote-limit Text @rarg{footnote-to} already has the maximum number of footnotes. @item already-footnote Text @rarg{text-no} is already a footnote to @rarg{footnote-to}. @end table @node sub-footnote @section sub-footnote [38] (1) Recommended @findex sub-footnote @example sub-footnote [38] (( text-no : @lt{Text-No}; footnote-to : @lt{Text-No} )) -> ( ); @end example This call removes the text @rarg{text-no} from @rarg{footnote-to}'s list of footnotes. Only the author of a footnote may remove it. @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 @{ 5 2 @}} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1} @t{ 4 @{ 0 2 6 1 4 1 9 19 52 18 17 6 97 4 197 1 @}} 1 38 2 1 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 @{ 0 2 6 1 @}} @end example In this example text 2 is a footnote to text 1, as shown by the misc-info lists of the two texts. The @req{sub-footnote} is called. The misc-info lists are changed to reflect the change. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text-no} or @rarg{footnote-to} does not exist or is secret. @item not-footnote The text @rarg{text-no} is not a footnote to @rarg{footnote-to}. @item permission-denied Not supervisor of the author of @rarg{text-no} and not enough privileges set and enabled to complete call anyway. @end table @node who-is-on-old @section who-is-on-old [39] (1) Obsolete @findex who-is-on-old @example who-is-on-old [39] ( ) -> ( @lt{ARRAY} @lt{Who-Info-Old} ); @end example This call is obsolete. Use @reqlink{get-static-session-info} and @reqlink{who-is-on-dynamic} instead. If the server does not support these calls, use @reqlink{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. @subheading Error codes This call always succeeds. @node set-unread @section set-unread [40] (1) Recommended @findex set-unread @example set-unread [40] (( conf-no : @lt{Conf-No}; no-of-unread : @lt{INT32} )) -> ( ); @end example Only read the last @rarg{no-of-unread} in the conference @rarg{conf-no}. This call modifies the @field{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 conditions@footnote{Another client might create a new text immediately before the server processes this @req{set-unread} call, so you might end up setting @field{last-text-read} to something unexpected.}, this call is usually better implemented using the @reqdlink{set-last-read} call@linkhere{} which explicitly sets the @field{last-text-read} field of the membership. @reqexample @example 1 9 5 6 @t{=1 1 34 21 17 6 97 4 197 1 6 100 0 0 *} 1 40 6 0 @t{=1} 1 9 5 6 @t{=1 1 34 21 17 6 97 4 197 1 6 100 4 0 *} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @item not-member Not a member of conference @rarg{conf-no}. @end table @node set-motd-of-lyskom @section set-motd-of-lyskom [41] (1) Recommended @findex set-motd-of-lyskom @example set-motd-of-lyskom [41] ( text-no : @lt{Text-No} ) -> ( ); @end example 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 @reqdlink{set-info} call@linkhere{}. @reqexample @example 1 36 @t{=1 10900 1 2 3 4 0} 1 41 435 @t{=1} 1 36 @t{=1 10900 1 2 3 4 435} @end example This example shows how the login message of LysKOM is set using the set-motd-of-lyskom call. The results of the @req{get-info} calls demonstrate the effect. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied Administrator bit not set or privilege level not enabled. @item no-such-text The text @rarg{text-no} does not exist. @item mark-limit The text @rarg{text-no} already has the maximum number of marks. @end table @node enable @section enable [42] (1) Recommended @findex enable @example enable [42] ( level : @lt{INT8} ) -> ( ); @end example Sets the security level for the current session to @rarg{level}. @xref{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. @reqexample @example 1 41 1 @t{%1 12 0} 1 42 255 @t{=1} 1 41 1 @t{=1} @end example This example shows how @req{enable} makes a privileged call possible, in this case a call to @reqlink{set-motd-of-lyskom}. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @end table @node sync-kom @section sync-kom [43] (1) Recommended @findex sync-kom @example sync-kom [43] ( ) -> ( ); @end example 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. @reqexample @example 1 42 255 @t{=1} 1 43 @t{:0 7} @t{:0 7} @t{=1} @end example This example shows how the @reqdlink{enable} call is used to enable all privileges@linkhere{}, then the @req{sync-kom} call is used to save the database. The server responds with two asynchronous messages signaling that the database is being saved. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied Administrator bit not set or privileges not enabled. @end table @node shutdown-kom @section shutdown-kom [44] (1) Recommended @findex shutdown-kom @example shutdown-kom [44] ( exit-val : @lt{INT8} ) -> ( ); @end example This call instructs the server to save all data and shut down. @rarg{exit-val} is currently not used. This call is privileged. @reqexample @example 1 42 255 @t{=1} 1 44 0 @t{=1} @t{:2 13 5 3} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied Administrator bit not set or privileges not enabled. @end table @node broadcast @section broadcast [45] (1) Obsolete @findex broadcast @example broadcast [45] ( message : @lt{HOLLERITH} ) -> ( ); @end example This call can been replaced by @reqlink{send-message}. It is a privileged call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{message} is too long. @item feature-disabled Messages have been disabled. @end table @node get-membership-old @section get-membership-old [46] (1) Obsolete (10) @findex get-membership-old @example get-membership-old [46] (( person : @lt{Pers-No}; first : @lt{INT16}; no-of-confs : @lt{INT16}; want-read-texts : @lt{BOOL} )) -> ( @lt{ARRAY} @lt{Membership-Old} ); @end example This call retrieves the membership record for a list of conferences for a single person. @rarg{person} is the person whose memberships are to be retrieved. @rarg{first} is the first position in the membership list to retrieve, numbered from 0 and up. @rarg{no-of-confs} is the number of membership records to retrieve. If @rarg{want-read-texts} is @samp{0} the server will not send the contents of the @field{read-texts} array of the memberships. (The size will be transmitted, but a single asterisk (@samp{*}) will be sent instead of the array itself.) The server will return a membership list that is shorter than @rarg{no-of-confs} if @rarg{no-of-confs} + @rarg{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.) @reqexample @example 1 46 5 0 3 1 @t{=1 2 @{ 49 14 17 13 8 91 5 255 1 5 255 0 0 * } @t{ 20 14 22 17 6 97 4 197 1 6 100 2 0 * @}} 1 46 5 0 1 1 @t{=1 1 @{ 49 14 17 13 8 91 5 255 1 5 255 0 0 * @}} 1 46 5 1 4 1 @t{=1 1 @{ 20 14 22 17 6 97 4 197 1 6 100 2 0 * @}} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person The person @rarg{person} does not exist. @item undefined-conference The conference @rarg{person} does not exist or is secret. @item index-out-of-range @rarg{first} is higher than the index of the first conference in the person's membership list. @end table @node get-created-texts @section get-created-texts [47] (1) Obsolete (10) @findex get-created-texts @example get-created-texts [47] (( person : @lt{Pers-No}; first : @lt{Local-Text-No}; no-of-texts : @lt{INT32} )) -> ( @lt{Text-List} ); @end example This call is obsolete; instead you should use @reqlink{map-created-texts}. This call returns a list of the texts written by a person. @rarg{person} is the person whose created texts are to be retrieved. @rarg{first} is the first text to retrieve. @rarg{no-of-texts} is the number of texts to retrieve. This call is essentially the same as @reqlink{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 @rarg{first} is lower than the first text written by @rarg{person} that still exists, it will be automatically increased to the first still existing text written by @rarg{person}. The @req{get-created-texts} will still attempt to return information about @rarg{no-of-texts} texts. (In this regard @req{get-map} and @req{get-created-texts} differ, since @req{get-map} will never ever return information about a later text than specified in the arguments to the call.@footnote{This difference was not intentional, but it is now too late to change the semantics of either @req{get-map} or @req{get-created-texts}. Besides, they are both obsolete calls.}) @reqexample @example 1 47 5 0 100 @t{=1 1 8 @{ 1 2 3 4 5 6 7 8 @}} 2 47 5 4 2 @t{=2 4 2 @{ 4 5 @}} 3 47 10 8 8 @t{=3 12 8 @{ 309 312 324 327 329 339 0 387 @}} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person The person @rarg{person} does not exist or is secret. @item undefined-conference The conference @rarg{person} does not exist or is secret. @item no-such-local-text @rarg{first} is higher than the local text number of the last created text. @end table @node get-members-old @section get-members-old [48] (1) Obsolete (10) @findex get-members-old @example get-members-old [48] (( conf : @lt{Conf-No}; first : @lt{INT16}; no-of-members : @lt{INT16} )) -> ( @lt{ARRAY} @lt{Pers-No} ); @end example This call returns a list of members of the conference @rarg{conf}. @rarg{first} is the first index in the membership to return, numbered from zero and up. @rarg{no-of-members} is the maximum number of members to return. @reqexample @example 1 48 1 0 100 @t{=1 4 @{ 7 8 9 10 @}} 1 48 6 0 100 @t{=1 4 @{ 5 7 9 10 @}} 1 48 6 2 2 @t{=1 2 @{ 9 10 @}} @end example 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. @subheading Error codes @table @errorcode @item undefined-conference The conference @rarg{conf} does not exist or is secret. @item index-out-of-range @rarg{first} is higher than the number of members in @rarg{conf}. @end table @node get-person-stat @section get-person-stat [49] (1) Recommended @findex get-person-stat @example get-person-stat [49] ( pers-no : @lt{Pers-No} ) -> ( @lt{Person} ); @end example This call returns the person @rarg{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 @reqlink{get-conf-stat} on the same number to get additional information about the person. @reqexample @example 1 49 8 @t{=1 @holl{44,byers@@lage.lysator.liu.se} 0000010000000000 00000000} @t{ 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 @t{=1 @holl{11,Paul Dekker} 1001 8 6 19 18 6 97 5 198 1} @t{ 8 6 19 18 6 97 5 198 1 8 0 8 0 0 0 77 1 1 0} @end example This simple example shows how person number 8 is retrieved from the server. The second call shows the @req{get-conf-stat-old} call on the same ID number. @subheading Error codes @table @errorcode @item undefined-person The person @rarg{pers-no} does not exist. @item undefined-conference The conference @rarg{pers-no} does not exist or is secret. @end table @node get-conf-stat-old @section get-conf-stat-old [50] (1) Obsolete (10) @findex get-conf-stat-old @example get-conf-stat-old [50] ( conf-no : @lt{Conf-No} ) -> ( @lt{Conference-Old} ); @end example This call retrieves the conference data structure for conference number @rarg{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 @req{get-uconf-stat} call instead. However, clients should be able to handle @type{Conference-Old} structures with an arbitrary number of flag bits since we may decide to change the behavior of this call in the future. @reqexample @example 1 50 1 @t{=1 @value{presconf} 0000 48 11 17 13 8 91 5 255} @t{ 1 18 34 21 17 6 97 4 197 1 0 0 0 0 0 0 77 0 1 1} 1 50 8 @t{=1 @holl{11,Paul Dekker} 1001 8 6 19 18 6 97 5 198 1} @t{ 8 6 19 18 6 97 5 198 1 8 0 8 0 0 0 77 1 1 0} @end example This simple example retrieves conferences 1 and 8 from the server. Conference 1 is a regular conference, and conference 8 is a mailbox. @subheading Error codes @table @errorcode @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @end table @node who-is-on @section who-is-on [51] (1) Obsolete (9) @findex who-is-on @example who-is-on [51] ( ) -> ( @lt{ARRAY} @lt{Who-Info} ); @end example This call is obsolete. Please use @reqlink{who-is-on-dynamic} and @reqdlink{get-static-session-info} calls instead@linkhere{}. 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 (@pxref{Who-Info}). @subheading Error codes This call always succeeds. @node get-unread-confs @section get-unread-confs [52] (1) Recommended @findex get-unread-confs @example get-unread-confs [52] ( pers-no : @lt{Pers-No} ) -> ( @lt{ARRAY} @lt{Conf-No} ); @end example This call returns a list of conferences in which the person @rarg{pers-no} may have unread texts. This call will return a result for any valid @rarg{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 @rarg{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. @reqexample @example 1 52 7 @t{=1 2 @{ 1 6 @}} 1 52 1 @t{%1 10 0} 1 52 1000 @t{%1 10 0} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person Person @rarg{pers-no} does not exist or is secret. @end table @node send-message @section send-message [53] (1) Recommended @findex send-message @example send-message [53] (( recipient : @lt{Conf-No}; message : @lt{HOLLERITH} )) -> ( ); @end example This call sends the message @rarg{message} to all members of @rarg{recipient} that are currently logged in. If @rarg{recipient} is 0, the message is sent to all sessions that are logged in. @reqexample @example 1 53 4 @holl{14,This is a test} @t{=1} 1 53 1 @holl{14,This is a test} @t{:3 12 1 8 @holl{14,This is a test}} @t{=1} 1 53 0 @holl{14,This is a test} @t{:3 12 0 8 @holl{14,This is a test}} @t{=1} 1 53 5 @holl{14,This is a test} @t{%1 16 0} 1 53 3 @holl{14,This is a test} @t{%1 42 0} @end example @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{message} is too long. @item undefined-conference Conference @rarg{recipient} does not exist or is secret. @item feature-disabled The message feature has been disabled in the server. @item message-not-sent The message was not sent for some other reason. Perhaps the recipient is not accepting messages or there are no viable recipients for a group message. @end table @node get-session-info @section get-session-info [54] (1) Obsolete @findex get-session-info @example get-session-info [54] ( session-no : @lt{Session-No} ) -> ( @lt{Session-Info} ); @end example This call is obsolete. It has been replaced by @reqlink{get-session-info-ident}, which in turn is also obsolete. See @req{get-session-info-ident} for more information. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-session The session @rarg{session-no} does not exist. @end table @node disconnect @section disconnect [55] (1) Recommended @findex disconnect @example disconnect [55] ( session-no : @lt{Session-No} ) -> ( ); @end example This call disconnects the session @rarg{session-no} from the LysKOM server. A session can always disconnect itself, even without logging in. If the session is logged in as user @i{foo} it can also disconnect any session logged in as a person for which @i{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. @reqexample @example 1 56 @t{=1 7} 1 55 7 @t{=1} @t{:2 13 8 7} @t{Connection closed by foreign host.} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call if @rarg{session-no} is not the session issuing the call. @item permission-denied Attempt to disconnect another session and not supervisor of person logged in and not enough privileges set and enabled to complete the call anyway. @item undefined-session The session @rarg{session-no} does not exist. @end table @node who-am-i @section who-am-i [56] (1) Recommended @findex who-am-i @example who-am-i [56] ( ) -> ( @lt{Session-No} ); @end example This call simply returns the session number of the session issuing the call. @reqexample @example 1 56 @t{=1 7} @end example In this example the session number of the session issuing the call is seven. @subheading Error codes This call always succeeds. @node set-user-area @section set-user-area [57] (2) Recommended @findex set-user-area @example set-user-area [57] (( pers-no : @lt{Pers-No}; user-area : @lt{Text-No} )) -> ( ); @end example This call sets the user-area field for the person @rarg{pers-no} in the database to the text @rarg{user-area}. The user area is used to store client data for a particular person. @xref{The User Area}, for more details. @reqexample @example 1 49 7 @t{=1 @holl{25,davby@@lage.lysator.liu.se} 0000010000000000 00000000} @t{ 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 @t{=1} 1 49 7 @t{=1 @holl{25,davby@@lage.lysator.liu.se} 0000010000000000 00000000} @t{ 6 58 21 19 6 97 6 199 1 11 458 7 71 2592 7 13 0 0 3 1 0 4} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person The person @rarg{pers-no} does not exist or is secret. @item permission-denied Not enough access to person @rarg{pers-no} to complete the call. @end table @node get-last-text @section get-last-text [58] (3) Recommended @findex get-last-text @example get-last-text [58] ( before : @lt{Time} ) -> ( @lt{Text-No} ); @end example This call returns the number of the last text created before @rarg{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. @reqexample @example 1 58 49 6 22 19 6 97 6 199 1 @t{=1 11} 1 58 49 6 22 18 6 97 6 199 1 @t{=1 8} 1 58 49 6 22 1 6 97 6 199 1 @t{=1 0} @end example 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. @subheading Error codes This call never fails. @node create-anonymous-text-old @section create-anonymous-text-old [59] (3) Obsolete (10) @findex create-anonymous-text-old @example create-anonymous-text-old [59] (( text : @lt{HOLLERITH}; misc-info : @lt{ARRAY} @lt{Misc-Info} )) -> ( @lt{Text-No} ); @end example Similar to @reqlink{create-text-old}, but the text is created with the @field{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 @rarg{misc-info} array are @misc{recpt}, @misc{cc-recpt}, @misc{bcc-recpt} (introduced in protocol version 10), @misc{comm-to} and @misc{footn-to}. @reqexample @example 1 28 @holl{20,Example\nMessage body} 3 @{ 0 5 1 112 2 33467 @} @t{:16 0 33502 13 16 15 16 6 97 3 196 1 0 1 20 0} @t{ 5 @{ 0 5 6 148 1 112 6 3438 2 33467 @} } @t{=1 33502} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{text} is longer than the maximum length of a message. @item temporary-failure The text could not be created at the moment. @item no-such-text Attempt to comment or footnote a non-existent or secret text. @item not-author Attempt to footnote a text authored by someone else. @item footnote-limit Attempt to footnote a text with the maximum number of footnotes already set. @item comment-limit Attempt to comment a text with the maximum number of comments already set. @item access-denied Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. @item anonymous-rejected Attempt to send an anonymous text to a conference that does not accept anonymous texts. @item illegal-misc Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list. @end table @node find-next-text-no @section find-next-text-no [60] (3) Recommended @findex find-next-text-no @example find-next-text-no [60] ( start : @lt{Text-No} ) -> ( @lt{Text-No} ); @end example This call returns the next readable text in the database created after text @rarg{start}. @rarg{start} does not have to be a valid or readable text number, as shown in the examples. @reqexample @example 1 60 0 @t{=1 2} 1 60 2 @t{=1 4} @end example This example shows how to retrieve the first readable text in the LysKOM database by calling @req{find-next-text-no} with @rarg{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. @subheading Error codes @table @errorcode @item no-such-text There is no text following text @rarg{start}. @end table @node find-previous-text-no @section find-previous-text-no [61] (3) Recommended @findex find-previous-text-no @example find-previous-text-no [61] ( start : @lt{Text-No} ) -> ( @lt{Text-No} ); @end example This call returns the first readable text in the database created most recently before @rarg{start}. @rarg{start} does not have to be a valid or readable text number, as shown in the examples. @reqexample @example 1 61 134217727 @t{=1 11} 1 61 4 @t{=1 2} @end example 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. @subheading Error codes @table @errorcode @item no-such-text There is no text preceding text @rarg{start}. @end table @node login @section login [62] (4) Recommended @findex login @example login [62] (( person : @lt{Pers-No}; passwd : @lt{HOLLERITH}; invisible : @lt{BOOL} )) -> ( ); @end example This call is used to log in. The session is logged in as person number @rarg{person} if @rarg{passwd} is the correct password for that person. If @rarg{invisible} is true, the session is invisible: it will not be returned by @reqlink{who-is-on} and @reqlink{who-is-on-ident}, and the dynamic session info (@pxref{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. @reqexample @example 1 62 7 @holl{6,gazonk} 1 @t{=1} 1 62 7 @holl{6,gazonk} 0 @t{:2 9 7 1} 1 62 7 @holl{6,gazonk} 0 @t{:2 13 7 1} @t{:2 9 7 1} @t{=1} @end example 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. @subheading Error codes @table @errorcode @item undefined-person The person @rarg{person} does not exist. @item login-disallowed Logins have been disabled and person @rarg{person} does not have enough privileges to override. @item invalid-password The password @rarg{passwd} is not the password of @rarg{person} and the currently logged in person is not the supervisor of @rarg{person} and does not have enough privileges set and enabled to log in anyway. @item conference-zero Attempt to log in as person number 0. @end table @node who-is-on-ident @section who-is-on-ident [63] (4) Obsolete (9) @findex who-is-on-ident @example who-is-on-ident [63] ( ) -> ( @lt{ARRAY} @lt{Who-Info-Ident} ); @end example This call is obsolete. It has been replaced by @reqlink{who-is-on-dynamic} and @reqlink{get-static-session-info}. It returns a list of all visible sessions. @subheading Error codes This call always succeeds. @node get-session-info-ident @section get-session-info-ident [64] (4) Obsolete (9) @findex get-session-info-ident @example get-session-info-ident [64] ( session-no : @lt{Session-No} ) -> ( @lt{Session-Info-Ident} ); @end example This call is obsolete. Use @reqlink{who-is-on-dynamic} combined with @reqlink{get-static-session-info} instead. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-session The session @rarg{session-no} does not exist. @end table @node re-lookup-person @section re-lookup-person [65] (5) Obsolete @findex re-lookup-person @example re-lookup-person [65] ( regexp : @lt{HOLLERITH} ) -> ( @lt{ARRAY} @lt{Pers-No} ); @end example This call is obsolete. It has been replaced by @reqlink{re-z-lookup}. It returns a list of persons matching the regular expression @rarg{regexp}. The regexp syntax used is that of the @command{ed}(1) Unix utility. @subheading Error codes @table @errorcode @item regexp-error Error compiling the regexp @rarg{regexp}. Perhaps the pattern is not a correct regexp. @end table @node re-lookup-conf @section re-lookup-conf [66] (5) Obsolete @findex re-lookup-conf @example re-lookup-conf [66] ( regexp : @lt{HOLLERITH} ) -> ( @lt{ARRAY} @lt{Conf-No} ); @end example This call is obsolete. It has been replaced by @reqlink{re-z-lookup}. It returns a list of conferences matching the regular expression @rarg{regexp}. The regexp syntax used is that of the @command{ed}(1) Unix utility. @subheading Error codes @table @errorcode @item regexp-error Error compiling the regexp @rarg{regexp}. Perhaps the pattern is not a correct regexp. @end table @node lookup-person @section lookup-person [67] (6) Obsolete @findex lookup-person @example lookup-person [67] ( name : @lt{HOLLERITH} ) -> ( @lt{ARRAY} @lt{Pers-No} ); @end example This call is obsolete. It has been replaced by @reqlink{lookup-z-name}. This call returns a list of persons with names matching the contracted name in @rarg{name}. @xref{Name Expansion}, for a description of the matching process. @subheading Error codes This call always succeeds. @node lookup-conf @section lookup-conf [68] (6) Obsolete @findex lookup-conf @example lookup-conf [68] ( name : @lt{HOLLERITH} ) -> ( @lt{ARRAY} @lt{Conf-No} ); @end example This call is obsolete. It has been replaced by @reqlink{lookup-z-name}. This call returns a list of conferences with names matching the contracted name in @rarg{name}. @xref{Name Expansion}, for a description of the matching process. @subheading Error codes This call always succeeds. @node set-client-version @section set-client-version [69] (6) Recommended @findex set-client-version @example set-client-version [69] (( client-name : @lt{HOLLERITH}; client-version : @lt{HOLLERITH} )) -> ( ); @end example 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 @rarg{client-name} and the version in @rarg{client-version}. The information sent in this call is made available to other sessions through the @reqlink{get-client-name} and @reqdlink{get-client-version} calls@linkhere{}. This call should be used exactly once per session. The following names are currently registered: @multitable @columnfractions .3 .7 @item elisp-client @tab The famous CPU hog. @item nilkom @tab C++ experiment @item tkom @tab C++ experiment @item getmail @tab Postmaster @item ttykom @tab The one and second tty client by Linus @item WinKOM @tab Windows client @item JySKom @tab JSK Web Client @end multitable @reqexample @example 1 56 @t{=1 7} 2 69 @holl{11,elisp-client} @holl{4,0.45} @t{=2} 3 70 7 @t{=3 @holl{11,elisp-client}} 4 71 7 @t{=4 @holl{4,0.45}} @end example In this example the @reqdlink{who-am-i} call is used to find the ID of the current session@linkhere{}. Next, @req{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 @reqdlink{get-client-name}, which returns the string just sent to the server@linkhere{}. Finally @reqlink{get-client-version} is used to retrieve the client version of session number 7, which is, as expected, the string ``0.45''. @subheading Error codes @table @errorcode @item string-too-long The string @rarg{client-name} or @rarg{client-version} is too long. @item client-is-crazy The client attempted to use this call more than once. The @field{error-status} is undefined. @end table @node get-client-name @section get-client-name [70] (6) Recommended @findex get-client-name @example get-client-name [70] ( session : @lt{Session-No} ) -> ( @lt{HOLLERITH} ); @end example This call returns the name of the client that owns session number @rarg{session}. This client name string returned is the one set by the client using @reqlink{set-client-version}. If @req{set-client-version} has not been issued in session number @rarg{session}, the empty string is returned. @xref{set-client-version}, for an example of this call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-session The session @rarg{session} does not exist. @end table @node get-client-version @section get-client-version [71] (6) Recommended @findex get-client-version @example get-client-version [71] ( session : @lt{Session-No} ) -> ( @lt{HOLLERITH} ); @end example This call returns the version of the client that owns session number @rarg{session}. This client version string returned is the one set by the client using @reqlink{set-client-version}. If @req{set-client-version} has not been issued in session number @rarg{session}, the empty string is returned. @xref{set-client-version}, for an example of this call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-session The session @rarg{session} does not exist. @end table @node mark-text @section mark-text [72] (4) Recommended @findex mark-text @example mark-text [72] (( text : @lt{Text-No}; mark-type : @lt{INT8} )) -> ( ); @end example This call associates the mark @rarg{mark-type} with the text @rarg{text}. The list of marks set by a person can be retrieved using the @reqdlink{get-marks} call@linkhere{}. 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. @reqexample @example 1 23 @t{=1 0 *} 2 72 110 230 @t{=2} 3 23 @t{=3 1 @{ 110 230 @}} @end example This example shows how a person with no marks set sets mark 230 on text number 110. The calls to @reqlink{get-marks} show the effect of the call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text} does not exists or is secret. @item permission-denied No read access to text @rarg{text}. @item undefined-person The person currently logged in does not exist (can't happen error.) @item mark-limit Already the maximum number of marks on text @rarg{text}. @end table @node unmark-text @section unmark-text [73] (6) Recommended @findex unmark-text @example unmark-text [73] ( text-no : @lt{Text-No} ) -> ( ); @end example This call removes any marks the logged-in person has set on the text @rarg{text-no}. @reqexample @example 1 23 @t{=1 1 @{ 110 230 @}} 2 73 110 @t{=2} 3 23 @t{=3 0 *} @end example This example shows how a user with a mark set on text number 110 removes it using the @req{unmark-text} call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person The person currently logged in does not exist (can't happen error.) @item not-marked The text @rarg{text-no} was not marked. @end table @node re-z-lookup @section re-z-lookup [74] (7) Recommended @findex re-z-lookup @example re-z-lookup [74] (( regexp : @lt{HOLLERITH}; want-persons : @lt{BOOL}; want-confs : @lt{BOOL} )) -> ( @lt{ARRAY} @lt{Conf-Z-Info} ); @end example This call returns a list of those conferences and/or persons matching the regular expression @rarg{regexp}. If @rarg{want-confs} is true, then the result will include non-mailbox conferences. If @rarg{want-persons} is true, then the result will include mailbox conferences. See also @ref{lookup-z-name}, for an alternative way to look up names. Refer to @ref{Name Expansion}, for more details on how name lookup works. @reqexample @example 1 74 @holl{2,.*} 1 1 @t{=1 4 @{ @holl{15,Test Conference} 0000 10 @holl{11,David Byers} 1001 6} @t{ @holl{21,Trains (-) Discussion} 0000 11 @holl{4,John} 1001 9 @}} 2 74 @holl{2,.*} 0 1 @t{=1 2 @{ @holl{15,Test Conference} 0000 10} @t{ @holl{21,Trains (-) Discussion} 0000 11 @}} 3 74 @holl{7,@badspell{T.*[cC]}} 1 1 @t{=3 2 @{ @holl{15,Test Conference} 0000 10} @t{ @holl{21,Trains (-) Discussion} 0000 11 @}} @end example This example shows three calls to @req{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 ``@badspell{T.*[cC]}''. @subheading Error codes @table @errorcode @item regexp-error Error compiling the regexp @rarg{regexp}. Perhaps the pattern is not a correct regexp. @end table @node get-version-info @section get-version-info [75] (7) Recommended @findex get-version-info @example get-version-info [75] ( ) -> ( @lt{Version-Info} ); @end example 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. @reqexample @example 1 75 @t{=1 9 @holl{7,lyskomd} @holl{5,1.9.0}} @end example 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. @subheading Error codes This call always succeeds. @node lookup-z-name @section lookup-z-name [76] (7) Recommended @findex lookup-z-name @example lookup-z-name [76] (( name : @lt{HOLLERITH}; want-pers : @lt{BOOL}; want-confs : @lt{BOOL} )) -> ( @lt{ARRAY} @lt{Conf-Z-Info} ); @end example This call looks up the name @rarg{name} in the server, and returns a list of all matching conferences and/or persons. If @rarg{want-confs} is true, then the result will include conferences that are not mailboxes. If @rarg{want-pers} is true, then the result will include conferences that are mailboxes. See also @ref{re-z-lookup}, for an alternative way to look up names. Refer to @ref{Name Expansion}, for details on the matching process. @reqexample @example 1 76 @holl{0,} 1 1 @t{=1 4 @{ @holl{15,Test Conference} 0000 10 @holl{11,David Byers} 1001 6} @t{ @holl{21,Trains (-) Discussion} 0000 11 @holl{4,John} 1001 9 @}} 2 76 @holl{0,} 0 1 @t{=1 2 @{ @holl{15,Test Conference} 0000 10} @t{ @holl{21,Trains (-) Discussion} 0000 11 @}} 3 76 @holl{3,T C} 1 1 @t{=3 2 @{ @holl{15,Test Conference} 0000 10} @t{ @holl{21,Trains (-) Discussion} 0000 11 @}} @end example This example shows three calls to @req{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''. @subheading Error codes This call always succeeds. @node set-last-read @section set-last-read [77] (8) Recommended @findex set-last-read @example set-last-read [77] (( conference : @lt{Conf-No}; last-read : @lt{Local-Text-No} )) -> ( ); @end example This call tells the server that the last local text number the person issuing the call has read in conference @rarg{conference} is @rarg{last-read}. This call is typically used when a user wants to have a specific number of unread texts in a particular conference. @reqexample @example 1 9 7 6 @t{=1 2 4 22 18 6 97 5 198 1 6 100 6 0 *} 2 77 6 3 @t{=2} 3 9 7 6 @t{=3 2 4 22 18 6 97 5 198 1 6 100 3 0 *} @end example 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 @req{set-last-read}, the @reqlink{query-read-texts} call reports that person 7 has read everything up to and including local text number 3. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conference} does not exist or is secret. @item not-member Not a member of conference @rarg{conference}. @end table @node get-uconf-stat @section get-uconf-stat [78] (8) Recommended @findex get-uconf-stat @example get-uconf-stat [78] ( conference : @lt{Conf-No} ) -> ( @lt{UConference} ); @end example This call returns some information about conference @rarg{conference}. The information it returns is sufficient for most uses of conference information, and this call should be used instead of @reqdlink{get-conf-stat} wherever possible@linkhere{}. It uses less bandwidth and the lyskomd server always keeps all @type{UConference} objects in memory, so this call is significantly faster than @req{get-conf-stat}. This is also currently the only way to get all the flag bits of the conference. @reqexample @example 1 50 6 @t{=1 @holl{8,Testconf} 0000 1 34 21 17 6 97 4 197 1} @t{ 37 3 22 18 6 97 5 198 1 5 4 5 0 5 0 77 4 1 6} 2 78 6 @t{=2 @holl{8,Testconf} 00001000 6 77} 3 50 7 @t{=3 @holl{11,David Byers} 1111 13 4 19 18 6 97 5 198 1} @t{ 13 4 19 18 6 97 5 198 1 7 0 7 0 0 0 77 1 1 0} 4 78 7 @t{=4 @holl{11,David Byers} 11111000 0 77} @end example This example shows the difference between @reqlink{get-conf-stat-old} and @req{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. @subheading Error codes @table @errorcode @item undefined-conference The conference @rarg{conference} does not exist or is secret. @item conference-zero @rarg{conference} is zero. @end table @node set-info @section set-info [79] (9) Recommended @findex set-info @example set-info [79] ( info : @lt{Info-Old} ) -> ( ); @end example This call sets the server information retrieved by @reqlink{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. @reqexample @example 1 79 10901 1 2 3 4 1080 @t{=1} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied Administrator bit not set or privileges not enabled. @item undefined-conference One of the conferences in @rarg{info} does not exist. @item no-such-text The MOTD text in @rarg{info} does not exist. @item mark-limit The MOTD text in @rarg{info} already has the maximum number of marks. @item text-zero This error message should never be returned, but lyskomd 1.9.0 erroneously returned this error message if the MOTD text in @rarg{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. @end table @node accept-async @section accept-async [80] (9) Recommended @findex accept-async @example accept-async [80] ( request-list : @lt{ARRAY} @lt{INT32} ) -> ( ); @end example This call advises the server that the client wants to receive the asynchronous messages listed in @rarg{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 @reqdlink{query-async} call@linkhere{}. Don't forget that message type 12 is personal, group and global text messages. Most users will not want these turned off. @reqexample @example 1 80 2 @{ 7 9 @} @t{=1} @end example 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). @subheading Error codes 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. @table @errorcode @item unknown-async At least one of the numbers in @rarg{request-list} is not the number of an async message the server knows about. The @field{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.) @item long-array The @rarg{request-list} was too long. Servers should always accept a @rarg{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. @end table @node query-async @section query-async [81] (9) Recommended @findex query-async @example query-async [81] ( ) -> ( @lt{ARRAY} @lt{INT32} ); @end example 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. @reqexample @example 1 81 @t{=1 7 @{ 0 5 7 9 11 12 13 @}} @end example 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. @xref{Asynchronous Messages}, for the currently recommended list of asynchronous messages that servers should preselect. @subheading Error codes This call always succeeds. @node user-active @section user-active [82] (9) Recommended @findex user-active @example user-active [82] ( ) -> ( ); @end example 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. @subheading Error codes This call always succeeds. @node who-is-on-dynamic @section who-is-on-dynamic [83] (9) Recommended @findex who-is-on-dynamic @example who-is-on-dynamic [83] (( want-visible : @lt{BOOL}; want-invisible : @lt{BOOL}; active-last : @lt{INT32} )) -> ( @lt{ARRAY} @lt{Dynamic-Session-Info} ); @end example This call returns a list of information about sessions. Only sessions with the desired visibility and activeness are returned. If @rarg{want-visible} is true then information about visible sessions is returned. If @rarg{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 @field{invisible} flag is set in the corresponding @type{Dynamic-Session-Info} that is returned. If @rarg{active-last} is zero then the result is a list of all sessions with the proper visibility. If @rarg{active-last} is nonzero then only sessions that have issued an @req{user-active} call within the last @rarg{active-last} seconds are included in the list. Sessions that have never issued an @req{user-active} call are always included (if they have the proper visibility). @subheading Error codes This call always succeeds. @node get-static-session-info @section get-static-session-info [84] (9) Recommended @findex get-static-session-info @example get-static-session-info [84] ( session-no : @lt{Session-No} ) -> ( @lt{Static-Session-Info} ); @end example This call returns information about session number @rarg{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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-session The session @rarg{session-no} does not exist. @end table @node get-collate-table @section get-collate-table [85] (10) Recommended @findex get-collate-table @example get-collate-table [85] ( ) -> ( @lt{HOLLERITH} ); @end example 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. @subheading Error codes This call always succeeds. @node create-text @section create-text [86] (10) Recommended @findex create-text @example create-text [86] (( text : @lt{HOLLERITH}; misc-info : @lt{ARRAY} @lt{Misc-Info}; aux-items : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( @lt{Text-No} ); @end example Creates a new text with contents from @rarg{text} and recipients etc. defined by @rarg{misc-info} (@pxref{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 line feed 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 @rarg{aux-items} are attached to the new text. The only Misc-Info items valid for this call are @misc{recpt}, @misc{cc-recpt}, @misc{bcc-recpt} (introduced in protocol version 10), @misc{comm-to} and @misc{footn-to}. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{text} is longer than the maximum length of a message. @item temporary-failure The text could not be created at the moment. @item no-such-text Attempt to comment or footnote a non-existent or secret text. @item not-author Attempt to footnote a text authored by someone else. @item footnote-limit Attempt to footnote a text with the maximum number of footnotes already set. @item comment-limit Attempt to comment a text with the maximum number of comments already set. @item index-out-of-range Attempt to create a text failed because we reached the maximum number of texts permitted. @item access-denied Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. @item illegal-misc Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list. @item illegal-aux-item One of the aux-items in @rarg{aux-items} is illegal. The tag might be out of range, the item not applicable to texts or whatever @item aux-item-permission One of the items looks valid but could not be created anyway. @item long-array Too many misc-items or aux-items were specified. @end table @node create-anonymous-text @section create-anonymous-text [87] (10) Recommended @findex create-anonymous-text @example create-anonymous-text [87] (( text : @lt{HOLLERITH}; misc-info : @lt{ARRAY} @lt{Misc-Info}; aux-items : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( @lt{Text-No} ); @end example Similar to @reqlink{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 @rarg{misc-info} array are @misc{recpt}, @misc{cc-recpt}, @misc{bcc-recpt} (introduced in protocol version 10), @misc{comm-to} and @misc{footn-to}. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{text} is longer than the maximum length of a message. @item temporary-failure The text could not be created at the moment. @item no-such-text Attempt to comment or footnote a non-existent or secret text. @item not-author Attempt to footnote a text authored by someone else. @item footnote-limit Attempt to footnote a text with the maximum number of footnotes already set. @item comment-limit Attempt to comment a text with the maximum number of comments already set. @item access-denied Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. @item anonymous-rejected Attempt to send an anonymous text to a conference that does not accept anonymous texts. @item illegal-misc Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list. @item illegal-aux-item One of the aux-items in @rarg{aux-items} is illegal. The tag might be out of range, the item not applicable to texts or whatever @item aux-item-permission One of the items looks valid but could not be created anyway. @end table @node create-conf @section create-conf [88] (10) Recommended @findex create-conf @example create-conf [88] (( name : @lt{HOLLERITH}; type : @lt{Any-Conf-Type}; aux-items : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( @lt{Conf-No} ); @end example This call is used to create new conferences. @rarg{name} is the name of the new conference and @rarg{type} is its type. If successful, the call returns the conference number of the newly created conference. The list @rarg{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 (@pxref{Security}). @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied The server does not allow anyone to create a conference and user does not have the @req{create-conf} bit set. May also be an attempt to create a conference with the @conftype{letterbox} bit set. @item conference-exists A conference named @rarg{name} already exists. @item bad-name @rarg{name} contains invalid characters. @item string-to-long @rarg{name} is too long to be used as a conference name. @item secret-public The conference type has the @conftype{secret} bit set, but the @conftype{rd-prot} bit is cleared. @item illegal-aux-item One of the aux-items in @rarg{aux-items} is illegal. The tag might be out of range, the item not applicable to conferences or whatever @item aux-item-permission One of the items looks valid but could not be created anyway. @end table @node create-person @section create-person [89] (10) Recommended @findex create-person @example create-person [89] (( name : @lt{HOLLERITH}; passwd : @lt{HOLLERITH}; flags : @lt{Personal-Flags}; aux-items : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( @lt{Pers-No} ); @end example 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 @rarg{aux-items} contains the aux items that are to be attached to the new person's mailbox conference. The person flags are set to @rarg{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. @subheading Error codes @table @errorcode @item login-first The session is not logged in and the server does not allow person creation before logging in. @item permission-denied The server does not allow anyone to create person and the person currently logged on does not have the @priv{create-pers} bit set. @item person-exists There is already a person named @rarg{name}. @item invalid-password The string @rarg{passwd} is not a valid password. @item illegal-aux-item One of the aux-items in @rarg{aux-items} is illegal. The tag might be out of range, the item not applicable to conferences or mailboxes or whatever. @item aux-item-permission One of the items looks valid but could not be created anyway. @end table @node get-text-stat @section get-text-stat [90] (10) Recommended @findex get-text-stat @example get-text-stat [90] ( text-no : @lt{Text-No} ) -> ( @lt{Text-Stat} ); @end example Get information about text number @rarg{text-no}. The text-stat contains information about the size of the text, its recipients, comments, author and more. @subheading Error codes @table @errorcode @item no-such-text The text @rarg{text-no} does not exist, or no read access. This error code will also be used when attempting to fetch any text except the motd-of-lyskom text without logging in first. @item text-zero Attempt to retrieve text number 0. @end table @node get-conf-stat @section get-conf-stat [91] (10) Recommended @findex get-conf-stat @example get-conf-stat [91] ( conf-no : @lt{Conf-No} ) -> ( @lt{Conference} ); @end example This call retrieves the conference data structure for conference number @rarg{conf-no}. @subheading Error codes @table @errorcode @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @end table @node modify-text-info @section modify-text-info [92] (10) Recommended @findex modify-text-info @example modify-text-info [92] (( text : @lt{Text-No}; delete : @lt{ARRAY} @lt{Aux-No}; add : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( ); @end example This call deletes the aux-items listed in @rarg{delete} from the text @rarg{text} and then adds the ones listed in @rarg{add} to the text. Either list may be empty, and the call is guaranteed to either completely fail or completely succeed. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text} does not exist or is secret. @item aux-item-permission No permission to delete one or more of the items in @rarg{delete}, or not enough permissions to add one or more of the items in @rarg{add}. @item illegal-aux-item One of the items in @rarg{add} is illegal for some reason. @end table @node modify-conf-info @section modify-conf-info [93] (10) Recommended @findex modify-conf-info @example modify-conf-info [93] (( conf : @lt{Conf-No}; delete : @lt{ARRAY} @lt{Aux-No}; add : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( ); @end example This call deleted the aux-items listed in @rarg{delete} from the conference @rarg{conf} and then adds the ones listed in @rarg{add} to the text. Either list may be empty, and the call is guaranteed to either completely fail or completely succeed. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conf} does not exist or is secret. @item aux-item-permission No permission to delete one or more of the items in @rarg{delete}, or not enough permissions to add one or more of the items in @rarg{add}. @item illegal-aux-item One of the items in @rarg{add} is illegal for some reason. @end table @node get-info @section get-info [94] (10) Recommended @findex get-info @example get-info [94] ( ) -> ( @lt{Info} ); @end example This call returns the @type{Info} structure for the server (@pxref{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. @subheading Error codes This call always succeeds. @node modify-system-info @section modify-system-info [95] (10) Recommended @findex modify-system-info @example modify-system-info [95] (( items-to-delete : @lt{ARRAY} @lt{Aux-No}; items-to-add : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( ); @end example This call modifies the aux-item list of the server information (which can be retrieved using @reqlink{get-info}.) It only succeeds when issued by a person with the admin bit set and privileges enabled. The items in @rarg{items-to-delete} are removed, and the items in @rarg{items-to-add} are added. This call is atomic; either all deletions or additions succeeded, or none of them is made. @subheading Error codes @table @errorcode @item login-first Login requires before issuing this call. @item permission-denied Admin bit not set or privileges not enabled. @item illegal-aux-item Attempt to create an invalid aux item. @item aux-item-permission Attempt to delete an undeletable item or create an uncreateable item. @end table @node query-predefined-aux-items @section query-predefined-aux-items [96] (10) Recommended @findex query-predefined-aux-items @example query-predefined-aux-items [96] ( ) -> ( @lt{ARRAY} @lt{INT32} ); @end example 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 @ref{Aux-Item Types}. @subheading Error codes This call always succeeds. @node set-expire @section set-expire [97] (10) Experimental @findex set-expire @example set-expire [97] (( conf-no : @lt{Conf-No}; expire : @lt{Garb-Nice} )) -> ( ); @end example This call sets the @rarg{expire} field of the conference @rarg{conf-no} to @rarg{expire}. This call can only be issued by the conference's supervisor or a privileged user. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @item permission-denied Not supervisor of conference @rarg{conf-no} and not privileged enough to complete the call anyway. @end table @node query-read-texts @section query-read-texts [98] (10) Recommended @findex query-read-texts @example query-read-texts [98] (( person : @lt{Pers-No}; conference : @lt{Conf-No} )) -> ( @lt{Membership} ); @end example 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. @rarg{person} is the person being queried and @rarg{conference} is the conference in question. Calling @req{query-read-texts} does not require the session to be logged in. @reqexample @example 1 98 6 1 @t{=1 32 5 11 12 7 93 1 193 1 1 20 133} @t{ 3 @{ 135 136 137 @} 5 01000000} @end example 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. The membership was added by person 5, and it is passive. @c FIXME: Is the example correct? Shouldn't there be a time @c after "5" and before "01000000"? / kent 990711 @subheading Error codes @table @errorcode @item undefined-person @rarg{person} does not exist, or no access to person. @item undefined-conference Conference @rarg{conference} does not exist, or is secret. @item conference-zero @rarg{conference} is zero. @item not-member @rarg{person} is not a member of @rarg{conference} or insufficient privileges to find out if @rarg{person} is a member. @end table @node get-membership @section get-membership [99] (10) Recommended @findex get-membership @example get-membership [99] (( person : @lt{Pers-No}; first : @lt{INT16}; no-of-confs : @lt{INT16}; want-read-texts : @lt{BOOL} )) -> ( @lt{ARRAY} @lt{Membership} ); @end example This call retrieves the membership record for a list of conferences for a single person. @rarg{person} is the person whose memberships are to be retrieved. @rarg{first} is the first position in the membership list to retrieve, numbered from 0 and up. @rarg{no-of-confs} is the number of membership records to retrieve. If @rarg{want-read-texts} is @samp{0}, the server will not send the contents of the @field{read-texts} array of the memberships. (The size will be transmitted, but a single asterisk (@samp{*}) will be sent instead of the array itself.) The server will return a membership list that is shorter than @rarg{no-of-confs} if @rarg{no-of-confs} + @rarg{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. @reqexample @example 1 99 5 0 3 1 @t{=1 2 @{ 49 14 17 13 8 91 5 255 1 5 255 0 0 * 5 00000000} @t{ 20 14 22 17 6 97 4 197 1 6 100 2 0 * 5 } @t{ 49 14 17 13 8 91 5 255 1 00000000 @}} 1 99 5 0 1 1 @t{=1 1 @{ 49 14 17 13 8 91 5 255 1 5 255 0 0 * 5 } @t{ 49 14 17 13 8 91 5 255 1 00000000 @}} 1 99 5 1 4 1 @t{=1 1 @{ 20 14 22 17 6 97 4 197 1 6 100 2 0 * 5 } @t{ 49 14 17 13 8 91 5 255 1 00000000 @}} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person The person @rarg{person} does not exist. @item undefined-conference The conference @rarg{person} does not exist or is secret. @item index-out-of-range @rarg{first} is higher than the index of the first conference in the person's membership list. @end table @node add-member @section add-member [100] (10) Recommended @findex add-member @example add-member [100] (( conf-no : @lt{Conf-No}; pers-no : @lt{Pers-No}; priority : @lt{INT8}; where : @lt{INT16}; type : @lt{Membership-Type} )) -> ( ); @end example Make the person @rarg{pers-no} a member of conference @rarg{conf-no}. The membership priority is set to @rarg{priority} and its position in the membership list is set to @rarg{where}. The membership flags are set to @rarg{type}. If the current user is adding a user he isn't supervisor of, the @field{invitation} bit of @rarg{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. @reqexample @example 1 99 119 0 10 0 @t{=1 1 @{ 49 14 17 13 8 91 5 255 1 119 255 0 0 * 119 00001111 @}} 1 100 1 119 250 0 10000000 @t{=1} 1 100 119 119 251 1 00000000 @t{=1} 1 99 119 0 10 0 @t{=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 @}} @end example 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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item undefined-person Person @rarg{pers-no} does not exist @item access-denied @c FIXME: the "or to change" part is bogus, right? Aren't those @c circumstances covered by permission-denied? Not enough permissions or privileges to add members to @rarg{conf-no} or to change privileges, position or type of a preexisting membership. @item permission-denied Person @rarg{pers-no} is already a member of conference @rarg{conf-no}, but the person logged on is not a supervisor and does not have enough privileges to change the priorities of person @rarg{pers-no}. @end table @node get-members @section get-members [101] (10) Recommended @findex get-members @example get-members [101] (( conf : @lt{Conf-No}; first : @lt{INT16}; no-of-members : @lt{INT16} )) -> ( @lt{ARRAY} @lt{Member} ); @end example This call returns a list of members of the conference @rarg{conf}. @rarg{first} is the first index in the membership to return, numbered from zero and up. @rarg{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. @reqexample @example 1 101 1 0 100 @t{=1 4 @{ 7 7 00000000 8 8 00000000 9 8 00000000 } @t{ 10 10 00000000 @}} 1 101 6 0 100 @t{=1 4 @{ 5 5 01000000 7 7 01000000 9 8 10000000 } @t{ 10 10 00000000 @}} 1 101 6 2 2 @t{=1 2 @{ 9 8 10000000 10 10 00000000 @}} @end example 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. @subheading Error codes @table @errorcode @item undefined-conference The conference @rarg{conf} does not exist or is secret. @item index-out-of-range @rarg{first} is higher than the number of members in @rarg{conf}. @end table @node set-membership-type @section set-membership-type [102] (10) Recommended @findex set-membership-type @example set-membership-type [102] (( pers : @lt{Pers-No}; conf : @lt{Conf-No}; type : @lt{Membership-Type} )) -> ( ); @end example This call modifies the type of a membership. The person @rarg{pers} membership in conference @rarg{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 @field{invitation} bit. It is possible that the server will not permit the @field{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. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item conference-zero @rarg{conf} is zero. @item undefined-conference The conference @rarg{conf} does not exist or is secret or the person @rarg{pers} does not exist or is secret. @item permission-denied Insufficient permissions to change the membership of @rarg{pers}. @item not-member Person @rarg{pers} is not a member of conference @rarg{conf}. @item invalid-membership-type The requested membership type @rarg{type} was not compatible with restrictions set on the server or on the conference @rarg{conf} @end table @node local-to-global @section local-to-global [103] (10) Recommended @findex local-to-global @example local-to-global [103] (( conf-no : @lt{Conf-No}; first-local-no : @lt{Local-Text-No}; no-of-existing-texts : @lt{INT32} )) -> ( @lt{Text-Mapping} ); @end example This call retrieves information that makes it possible to convert @rarg{no-of-existing-texts} existing local text numbers starting at @rarg{first-local-no} to global text numbers, provided that there are that many local texts. The @rarg{conf-no} parameter specifies which conference to look up local numbers in. @rarg{first-local-no} is the first number that the client is interested in. @rarg{no-of-existing-texts} is the maximum number of texts the client wants information about. Legal values for @rarg{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 @rarg{first-local-no}. @reqexample @example 1 103 93 1 5 @t{=1 1 7 1 1 1 6 @{ 1003 1005 1009 1029 0 1034 @}} 2 103 93 1 6 @t{=2 1 63 1 0 6 @{ 1 1003 2 1005 3 1009 4 1029 6 1034 62 1302 @}} 3 103 93 50 10 @t{=3 50 70 0 0 2 @{ 62 1302 69 1006 @}} @end example The above example shows three calls to @req{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 @type{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 @type{Text-Mapping}. The final call shows what happens when @rarg{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 @req{add-recipient} is used.) @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item long-array @rarg{no-of-existing-texts} was larger than 255. @item conf-zero @rarg{conf-no} was set to 0. @item local-text-zero @rarg{first-local-no} was set to 0. @item undef-conf The conference does not exist, or the client is not allowed to know that it exists. @item access-denied The conference exists, but the client is not allowed to retrieve information about the texts in the conference. @item no-such-local-text @rarg{first-local-no} is greater than the highest local text number that ever existed in the conference. @end table @node map-created-texts @section map-created-texts [104] (10) Recommended @findex map-created-texts @example map-created-texts [104] (( author : @lt{Pers-No}; first-local-no : @lt{Local-Text-No}; no-of-existing-texts : @lt{INT32} )) -> ( @lt{Text-Mapping} ); @end example Return text numbers for existing texts that @rarg{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 @ref{local-to-global}. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item long-array @rarg{no-of-existing-texts} was larger than 255. @item conf-zero @rarg{author} was set to 0. @item local-text-zero @rarg{first-local-no} was set to 0. @item undef-pers The conference does not exist, or the client is not allowed to know that it exists. @item no-such-local-text @rarg{first-local-no} is greater than the highest local text number that ever existed in the conference. @item access-denied The conference exists, but the client is not allowed to retrieve information about the texts in the conference. @end table @node set-keep-commented @section set-keep-commented [105] (10) Experimental @findex set-keep-commented @example set-keep-commented [105] (( conf-no : @lt{Conf-No}; keep-commented : @lt{Garb-Nice} )) -> ( ); @end example Sets the @rarg{keep-commented} field of the conference @rarg{conf-no} to @rarg{keep-commented}. This call can only be issued by a conference's supervisor or a privileged user. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @item permission-denied Not supervisor of conference @rarg{conf-no} and not privileged enough to complete the call anyway. @end table @node set-pers-flags @section set-pers-flags [106] (10) Recommended @findex set-pers-flags @example set-pers-flags [106] (( pers-no : @lt{Pers-No}; flags : @lt{Personal-Flags} )) -> ( ); @end example Set the flags field of person @rarg{pers-no} to @rarg{flags}. This call can only be issued by the person supervisor or a privileged user. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item conference-zero The @rarg{pers-no} parameter is zero. @item undefined-person The person does not exist, or the session does not have permission to know about the person. @item permission-denied Person exists, but the session does not have permission to change the flags. @end table @node Asynchronous Messages @chapter Asynchronous Messages 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 @reqlink{accept-async}. @menu * About Asynchronous Messages:: Introductory information about asynchronous messages. * async-new-text-old:: r A text has been created (0) * async-i-am-off:: O Logged off (obsolete) (1) * async-i-am-on-obsolete:: O Client changed i-am-on string (obsolete) (2) * async-new-name:: r Conference or person changed name (5) * async-i-am-on:: r Client changed i-am-doing string (6) * async-sync-db:: r Server is saving the database (7) * async-leave-conf:: r Person has been removed from a conference (8) * async-login:: r Someone has logged in (9) * async-broadcast:: O Broadcast message (obsolete) (10) * async-rejected-connection:: r LysKOM is full. Log out to make room. (11) * async-send-message:: r Text message to group or person (12) * async-logout:: r A person has logged out (13) * async-deleted-text:: r A text was deleted (14) * async-new-text:: r A text has been created (15) * async-new-recipient:: r A new recipient has been added to a text (16) * async-sub-recipient:: r A recipient has been removed from a text (17) * async-new-membership:: r A user has been added to a conference (18) @end menu @ifnottex @node About Asynchronous Messages @section About Asynchronous Messages @end ifnottex Clients can select which messages to receive by issuing an @reqdlink{accept-async} call@linkhere{}. They can find out which messages are being sent by issuing the @reqdlink{query-async} call@linkhere{}. 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 @req{accept-async} call to select which messages they want. Servers are encouraged to preselect the @async{async-new-text-old}, @async{async-new-name}, @async{async-sync-db}, @async{async-leave-conf}, @async{async-login}, @async{async-rejected-connection}, @async{async-send-message} and @async{async-logout} messages. These correspond to the useful messages that were sent prior to the introduction of @reqlink{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 @example :3 5 119 @holl{11,David Byers} @holl{13,David C Byers} @end example The parameters of each message are listed in the same format as server calls. @node async-new-text-old @section async-new-text-old (1) Obsolete (10) @amindex async-new-text-old @example async-new-text-old [0] (( text-no : @lt{Text-No}; text-stat : @lt{Text-Stat-Old} )); @end example This message is sent when a text is created. The text number of the text is sent in @aarg{text-no} and the text stat in @aarg{text-stat}. This message is sent to all logged-in members of any recipient of the text. In protocol version 10 this call has been superseded by @ref{async-new-text}. @node async-i-am-off @section async-i-am-off (1) Obsolete @amindex async-i-am-off @c obsolete @example async-i-am-off [1] ( person : @lt{Pers-No} ); @end example This message was sent when @aarg{person} logged off. It has been replaced by @asynclink{async-logout}, since this asynchronous message could not differentiate between sessions if the same person was logged in more than once. @node async-i-am-on-obsolete @section async-i-am-on-obsolete (1) Obsolete @amindex async-i-am-on-obsolete @c obsolete @example async-i-am-on-obsolete [2] (( person : @lt{Pers-No}; conference : @lt{Conf-No}; what-am-i-doing : @lt{HOLLERITH} )); @end example This message was sent when @aarg{person} changed his @code{what-i-am-doing} string to @aarg{what-am-i-doing} or his working conference to @aarg{conference}. It has been replaced by call number 6, @asynclink{async-i-am-on}, since this asynchronous message could not differentiate between sessions if the same person was logged in more than once. @node async-new-name @section async-new-name (1) Recommended @amindex async-new-name @example async-new-name [5] (( conf-no : @lt{Conf-No}; old-name : @lt{HOLLERITH}; new-name : @lt{HOLLERITH} )); @end example This message is sent when a person or conference changes names. The conference whose name is being changed is sent in @aarg{conf-no}, the old name in @aarg{old-name} and the new name in @aarg{new-name}. @node async-i-am-on @section async-i-am-on (1) Recommended @amindex async-i-am-on @example async-i-am-on [6] ( info : @lt{Who-Info} ); @end example This message is sent when a session's working conference, @code{what-i-am-doing} string (@pxref{change-what-i-am-doing}) or username changes. The new information is sent in @aarg{info}. @c FIXME: can the username change? @node async-sync-db @section async-sync-db (1) Recommended @amindex async-sync-db @example async-sync-db [7] ( ); @end example 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. @node async-leave-conf @section async-leave-conf (1) Recommended @amindex async-leave-conf @example async-leave-conf [8] ( conf-no : @lt{Conf-No} ); @end example 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 @aarg{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: @itemize @bullet @item The session issued a @reqdlink{sub-member} call@linkhere{}. @item Some other session issued a @reqdlink{sub-member} call@linkhere{}. @item The conference was deleted. @item The person was deleted. @end itemize This message is not sent if a membership is transformed from an active to a passive membership. @node async-login @section async-login (1) Recommended @amindex async-login @example async-login [9] (( pers-no : @lt{Pers-No}; session-no : @lt{Session-No} )); @end example This message is sent when someone logs in. The identity of the person logging in is sent in @aarg{pers-no}, and the session number in @aarg{session-no}. @node async-broadcast @section async-broadcast (1) Obsolete @amindex async-broadcast @c obsolete @example async-broadcast [10] (( sender : @lt{Pers-No}; message : @lt{HOLLERITH} )); @end example This message has been superseded by @asyncdlink{async-send-message} which is more flexible@linkhere{}. It used to be sent when the administrator (@aarg{sender}) broadcasted a string (@aarg{message}) to all LysKOM users, but is no longer used. @node async-rejected-connection @section async-rejected-connection (1) Recommended @amindex async-rejected-connection @example async-rejected-connection [11] ( ); @end example 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. @node async-send-message @section async-send-message (1) Recommended @amindex async-send-message @example async-send-message [12] (( recipient : @lt{Conf-No}; sender : @lt{Pers-No}; message : @lt{HOLLERITH} )); @end example This message is sent when someone (the @aarg{sender}) sends a message string (the @aarg{message}). The recipient of the message is sent in @aarg{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. @node async-logout @section async-logout (1) Recommended @amindex async-logout @example async-logout [13] (( pers-no : @lt{Pers-No}; session-no : @lt{Session-No} )); @end example This message is sent when someone logs out. @aarg{pers-no} is the person logging out and @aarg{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. @node async-deleted-text @section async-deleted-text (10) Recommended @amindex async-deleted-text @example async-deleted-text [14] (( text-no : @lt{Text-No}; text-stat : @lt{Text-Stat} )); @end example This message is sent when a text is deleted and the currently logged-in person is a member of one of the recipients. The text number being deleted is sent in @aarg{text-no} and the text stat in @aarg{text-stat}. @node async-new-text @section async-new-text (10) Recommended @amindex async-new-text @example async-new-text [15] (( text-no : @lt{Text-No}; text-stat : @lt{Text-Stat} )); @end example This message indicates that a new text has been created. The text has number @aarg{text-no}, and the text stat is @aarg{text-stat}. The message is sent to all logged-in members of any recipient of the text. @node async-new-recipient @section async-new-recipient (10) Recommended @amindex async-new-recipient @example async-new-recipient [16] (( text-no : @lt{Text-No}; conf-no : @lt{Conf-No}; type : @lt{Info-Type} )); @end example This message indicates that a new recipient has been added to text @aarg{text-no}. The recipient added is @aarg{conf-no} and the type of recipient is indicated by @aarg{type}. This message is sent to all recipients of the text that are permitted to know about the new recipient. @node async-sub-recipient @section async-sub-recipient (10) Recommended @amindex async-sub-recipient @example async-sub-recipient [17] (( text-no : @lt{Text-No}; conf-no : @lt{Conf-No}; type : @lt{Info-Type} )); @end example This message indicates that a recipient has been removed from text @aarg{text-no}. The recipient removed is @aarg{conf-no} and the type of recipient is indicated by @aarg{type}. This message is sent to everybody that were recipients of the text and that were permitted to know about the recipient. @node async-new-membership @section async-new-membership (10) Recommended @amindex async-new-membership @example async-new-membership [18] (( pers-no : @lt{Pers-No}; conf-no : @lt{Conf-No} )); @end example This message indicates that the membership for @aarg{pers-no} in conference @aarg{conf-no} has been added. This message is currently sent only to @aarg{pers-no}, but that may change in the future. See also @ref{async-leave-conf}. @node Error Codes @chapter Error Codes 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. @xref{Client-Server Dialog}, for more information about error responses, including the syntax of the error response. @table @code @item no-error (0) No error has occurred. @field{error-status} is undefined. This should never happen, but it might. @item not-implemented (2) The call has not been implemented yet. @field{error-status} is undefined. @item obsolete-call (3) The call is obsolete and no longer implemented. @field{error-status} is undefined. @item invalid-password (4) Attempt to set a password containing illegal characters, or to use an incorrect password. @item string-too-long (5) A string was too long (see descriptions of each call.) @field{error-status} indicates the maximum string length. @item login-first (6) Login is required before issuing the call. @field{error-status} is undefined. @item login-disallowed (7) The system is in single-user mode. You need to be privileged to log in despite this. @field{error-status} is undefined. @item conference-zero (8) Attempt to use conference number 0. @field{error-status} is undefined. @item undefined-conference (9) Attempt to access a non-existent or secret conference. @field{error-status} contains the conference number in question. @item undefined-person (10) Attempt to access a non-existent or secret person. @field{error-status} contains the person number in question. @item access-denied (11) No read/write access to something. This might be returned in response to an attempt to create a text, when the recipient conference and its super conferences are read-only, or when attempting to add a member to a conference without enough permission to do so. @field{error-status} indicates the object to which we didn't have enough permissions to. @item permission-denied (12) Not enough permissions to do something. The exact meaning of this response depends on the call. @field{error-status} indicated the object for which permission was lacking, or zero. @item not-member (13) The call requires the caller to be a member of some conference that the caller is not a member of. @field{error-status} indicates the conference in question. @item no-such-text (14) Attempt to access a text that either does not exist or is secret in some way. @field{error-status} indicates the text number in question. @item text-zero (15) Attempt to use text number 0. @field{error-status} is undefined. @item no-such-local-text (16) Attempt to access a text using a local text number that does not represent an existing text. @field{error-status} indicates the offending number. @item local-text-zero (17) Attempt to use local text number zero. @field{error-status} is undefined. @item bad-name (18) Attempt to use a name that's too long, too short or contains invalid characters. @field{error-status} is undefined. @item index-out-of-range (19) Attempt to use a number that's out of range. The range and meaning of the numbers depends on the call issued. @field{error-status} is undefined unless stated otherwise in the call documentation. @item conference-exists (20) Attempt to create a conference or person with a name that's already occupied. @field{error-status} is undefined. @item person-exists (21) Attempt to create a person with a name that's already occupied. @field{error-status} is undefined. This error code is probably not used, but you never know for sure. @item secret-public (22) Attempt to give a conference a type with @conftype{secret} bit set and the @conftype{rd-prot} bit unset. This is an error since such a conference type is inconsistent. @field{error-status} is undefined. @item letterbox (23) Attempt to change the @conftype{letterbox} flag of a conference. @field{error-status} indicates the conference number. @item ldb-error (24) Database is corrupted. @field{error-status} is an internal code. @item illegal-misc (25) Attempt to create an illegal misc item. @field{error-status} contains the index of the illegal item. @item illegal-info-type (26) Attempt to use a Misc-Info type (or Info-Type value) that the server knows nothing about. @field{error-status} is the type. @item already-recipient (27) Attempt to add a recipient that is already a recipient of the same type. @field{error-status} contains the recipient that already is. @item already-comment (28) Attempt to add a comment to a text twice over. @field{error-status} contains the text number of the text that already is a comment. @item already-footnote (29) Attempt to add a footnote to a text twice over. @field{error-status} contains the text number of the text that already is a footnote. @item not-recipient (30) Attempt to remove a recipient that isn't really a recipient. @field{error-status} contains the conference number in question. @item not-comment (31) Attempt to remove a comment link that does not exist. @field{error-status} contains the text number that isn't a comment. @item not-footnote (32) Attempt to remove a footnote link that does not exist. @field{error-status} contains the text number that isn't a footnote. @item recipient-limit (33) Attempt to add a recipient to a text that already has the maximum number of recipients. @field{error-status} is the text that has the maximum number of recipients. @item comment-limit (34) Attempt to add a comment to a text that already has the maximum number of comments. @field{error-status} is the text with the maximum number of comments. @item footnote-limit (35) Attempt to add a footnote to a text that already has the maximum number of footnote. @field{error-status} is the text with the maximum number of footnotes. @item mark-limit (36) Attempt to add a mark to a text that already has the maximum number of marks. @field{error-status} is the text with the maximum number of marks. @item not-author (37) Attempt to manipulate a text in a way that required the user to be the author of the text, when not in fact the author. @field{error-status} contains the text number in question. @item no-connect (38) Currently unused. @item out-of-memory (39) The server ran out of memory. @item server-is-crazy (40) Currently unused. @item client-is-crazy (41) Currently unused. @item undefined-session (42) Attempt to access a session that does not exist. @field{error-status} contains the offending session number. @item regexp-error (43) Error using a regexp. The regexp may be invalid or the server unable to compile it for other reasons. @field{error-status} is undefined. @item not-marked (44) Attempt to manipulate a text in a way that requires the text to be marked, when in fact it is not marked. @field{error-status} indicates the text in question. @item temporary-failure (45) Temporary failure. Try again later. @field{error-status} is undefined. @item long-array (46) An array sent to the server was too long. @field{error-status} is undefined. @item anonymous-rejected (47) Attempt to send an anonymous text to a conference that does not accept anonymous texts. @field{error-status} is undefined. @item illegal-aux-item (48) Attempt to create an invalid aux-item. Probably the tag or data are invalid. @field{error-status} contains the index in the aux-item list where the invalid item appears. @item aux-item-permission (49) Attempt to manipulate an aux-item without enough permissions. This response is sent when attempting to delete an item set by someone else or an item that can't be deleted, and when attempting to create an item without permissions to do so. @field{error-status} contains the index at which the item appears in the aux-item list sent to the server. @item unknown-async (50) Sent in response to a request for an asynchronous message the server does not send. The call succeeds, but this is sent as a warning to the client. @field{error-status} contains the message type the server did not understand. @item internal-error (51) The server has encountered a possibly recoverable internal error. @field{error-status} is undefined. @item feature-disabled (52) Attempt to use a feature that has been explicitly disabled in the server. @field{error-status} is undefined. @item message-not-sent (53) Attempt to send an asynchronous message failed for some reason. Perhaps the recipient is not accepting messages at the moment or there are no viable recipients for a group message. @field{error-status} is undefined. @item invalid-membership-type (54) A requested membership type was not compatible with restrictions set on the server or on a specific conference. @field{error-status} is undefined unless specifically mentioned in the documentation for a specific call. @end table @node Aux-Item Types @chapter Aux-Item Types Some of the aux-items below (mostly the ones that begin with "mx-") are used by mail importers. @table @samp @item content-type [1] (text) Specifies the content type of a text. Data is a valid MIME type or one of the special LysKOM types (@pxref{LysKOM Content Types}). 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. @item fast-reply [2] (text) Data is a string that constitutes a brief comment to the text. This comment should be displayed immediately after the text body. An item of this type will never be inherited, can always be deleted, is never anonymous and is never secret. @item cross-reference [3] (text, conference, letterbox) Data is a cross-reference to something else. The contents consist of a letter, a number, and optionally a space and a descriptive text. The letter must be one of T, C or P. T specifies that the cross-reference points to a text; C that it points to a conference; and P that it points to a person. The number is the id of the target of the cross reference. The descriptive text is simply that, a text that describes the cross-reference. For example, "T15 Check this out!" is a cross reference to text 15 with a description that reads "Check this out!", and "T17" is a cross reference without a description. The inherit bit is automatically cleared and the item can always be deleted. @item no-comments [4] (text) When this item is set, the author requests that nobody comments the text. This is advisory only; it is still possible to write comments, but clients should advise the user that this is contrary to the author's wishes. Data should be empty. This item may only be set by the author. The secret, hide-creator and inherit bits are automatically cleared. @item personal-comment [5] (text) When this item is set, the author requests only personal comments. This is advisory only; it is still possible to create regular comments, but clients should advise the user that the author prefers a personal comment. Data should be empty. This item may only be set by the author. The secret, hide-creator and inherit bits are automatically cleared. @item request-confirmation [6] (text) The author requests that everyone who reads the text confirms having done so by creating read-confirmation items on the text. Clients should ask users if they wish to confirm having read the text when it is displayed. Data should be empty. The hide-creator, secret and inherit bits are automatically cleared. @item read-confirm [7] (text) This item can be taken as confirmation that the item creator has read the text to which the item is attached. Clients should never ever create this item without an explicit confirmation from the user that the text has indeed been read. The hide-creator, secret and inherit bits are automatically cleared. Once created an item of this type cannot be deleted. @item redirect [8] (conference, letterbox) This item indicates that texts should not be sent to the conference, but be directed to some other target instead. Clients should notify users that attempt to send texts to the conference of the redirect and offer to send the text to the target of the redirect instead. A typical use of this item would be a user that does not read LysKOM very often and would like to advise other users to send e-mail instead. Data is PROTOCOL:ADDRESS where PROTOCOL is either "E-mail" or "LysKOM", and ADDRESS is either an e-mail address or a LysKOM conference. 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. @item x-face [9] (conference, letterbox, server) Data is the face of the person in compface format. Cool, @badspell{innit}? 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. @item alternate-name [10] (text, conference, letterbox) Data is a string that the client may use as an alternate to the name of a conference or the subject of a text. Note that the server does not match against this name when performing name lookups. Clients should only display alternate names created by the user currently logged on. The inherit flag is automatically cleared. @item pgp-signature [11] (text) Data is a PGP signature of the text. The signature should be the equivalent of what @samp{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. @item pgp-public-key [12] (letterbox) Data is the public key of the person. It is desirable that the public key contains a userid of the format "LysKOM +", where @var{n} is the number of the person in the LysKOM server specified in @var{server}. This rule is currently not enforced. This item can only be set by the person himself. The hide-creator, secret and inherit bits are automatically cleared. @item e-mail-address [13] (conference, letterbox, server) Data is an RFC 822-style email address. When set on a mailbox, it should be the email address of the person. If the person has multiple email addresses he may set several e-mail-address aux-items. 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. @item faq-text [14] (conference, server) Data is a decimal text number, which is a FAQ for the conference (or server). Creating an item of this type automatically causes creation of a faq-for-conf item. This item can only be set by the supervisor or server administrator. The hide-creator, secret, and inherit bits are automatically cleared. @item creating-software [15] (text) Data is the name and version number of the client that created the text. This aux-item can only be set by the author of the text. Once set, it cannot be removed or changed. A typical value would be @samp{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 @reqlink{set-client-version} call. The server may enforce this restriction. @item mx-author [16] (text) Data is a string containing the name of the author of an imported e-mail, extracted from the @code{From} header. This aux-item may be missing, if the mail address in the @code{From} header consists of just the @code{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: @code{Joe Q. Public} which may come from a @code{From} header containing @code{"Joe Q. Public" }. @item mx-from [17] (text) Data is the proper e-mail address (called @code{addr-spec} in the mail standards) extracted from the @code{From} header of an imported e-mail. Clients should display this address together with the @aux{mx-author}, preferably inside angles. If @aux{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: @code{john.q.public@@example.com} which may come from a @code{From} header containing @code{john.q.public@@example.com} or something like @code{"Joe Q. Public" }. @item mx-reply-to [18] (text) Data is the proper e-mail address (called @code{addr-spec} in the mail standards) extracted from the @code{Reply-To} header of an imported e-mail. Clients should use this for constructing replies to imported messages. @item mx-to [19] (text) Data is a single e-mail address from an email @code{To} header. Multiple @aux{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 @code{john.q.public@@example.com} and @code{"Joe Q. Public" } are valid. @item mx-cc [20] (text) Same as @aux{mx-to}, but applies to the @code{CC} header rather than the @code{To} header. @item mx-date [21] (text) Data is the date and time from the @code{Date} header of an imported email. Its format is @badspell{"YYYY-MM-DD hh:mm:ss TZ"}. @badspell{YYYY} is the year the message was sent, @badspell{MM} is the month, @badspell{DD} is the day, @badspell{hh} is the hour, @badspell{mm} is the minute and @badspell{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 "@badspell{+hhmm}" or "@badspell{-hhmm}", where @badspell{hh} is the number of hours offset from UTC and @badspell{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. @item mx-message-id [22] (text) Data is the @code{Message-ID} header of an imported e-mail, with whitespace and comments removed. The Message-ID should contain the surrounding angles. @item mx-in-reply-to [23] (text) Data is a string containing one item of the same form as the mx-message-id item described above. This is the Message-ID of another mail the current text is a comment to. Hopefully, this information comes from the @code{In-Reply-To} header of the imported e-mail, but it could also have been picked from the end of the @code{References} header line. If the text really comments more than one other text directly, it is allowed to attach more than one @aux{mx-in-reply-to} items to it. @item mx-misc [24] (text) Data is a string that contains all of the headers of an imported email, including @code{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. @item mx-allow-filter [25] (conference, letterbox) This aux-item has been declared obsolete. It was intended to supply the importer with information on how to filter incoming messages based on regular expressions matching header lines. @item mx-reject-forward [26] (conference, letterbox) This aux-item has been declared obsolete. It was intended to supplement mx-allow-filter by telling where rejected mails should be sent. @item notify-comments [27] (letterbox) Data is a decimal text number that the user is interested in. Clients should monitor this text for unread comments and present these to the user in some convenient manner. This is typically used by users that want to read comments to some text of theirs as soon as they arrive, rather than in the normal reading order. This item can only be set by the owner of the letterbox. No flags are forced or cleared. @item faq-for-conf [28] (text) Data is a decimal number specifying the conference a certain text is a FAQ for. The special number zero denotes that the text is a FAQ for the entire system. Items of this kind can only be created by the LysKOM server itself. Texts with this item are protected from garbage collection. @item recommended-conf [29] (server) Data is a decimal number specifying a conference that new members should automatically be added to, optionally followed by a space and a recommended priority, optionally followed by a space and a membership type. In the future, additional data may be defined; clients should be prepared to accept and ignore a space and any trailing data that may follow the membership type. A few examples might clarify what the data may look like: @table @code @item 1 Conference number 1. @item 2 32 Conference number 2, with priority 32. @item 3 250 11100000 Conference number 3, with priority 250. The membership should be secret, passive and have the invitation bit set. @item 4 253 01000000 garbage Conference number 4, with priority 253. The membership should be passive. The client should ignore the trailing garbage; it is reserved for future extensions. Note that clients are not allowed to create aux-items of this format, but they should be prepared to handle them correctly. @end table 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 @aux{recommended-conf}. @item allowed-content-type [30] (conference, letterbox, server) Data is a non-negative decimal priority number, followed by a space, followed by a LysKOM content type glob pattern. Clients should send texts to a conference only if the content-type matches any of the @aux{allowed-content-type} glob patterns of that conference. If the conference doesn't have any @aux{allowed-content-type}, the @aux{allowed-content-type} items of the server should be used. If the server also has no @aux{allowed-content-type} aux-items, it should be interpreted as if a single @aux{allowed-content-type} aux-item with the value @samp{1 text/plain} exists. If there are @aux{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 @aux{allowed-content-type} aux-items: @example 1 text/plain 2 text/x-kom-basic 2 text/enriched 3 text/* @end example These aux-items taken together means that @samp{text/plain} is preferred, that @samp{text/x-kom-basic} and @samp{text/enriched} can be used if there is a reason why @samp{text/plain} is inadequate, and that any text type (such as @samp{text/html}) is acceptable. Other content types, such as @samp{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. @item canonical-name [31] (server) This should be set to the official domain name of the server, optionally followed by a colon and the port number. The port number should only be used if a non-standard port is used. Examples: @samp{kom.lysator.liu.se:8300}, @samp{kom.lysator.liu.se}. The intent is that the @aux{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. @item mx-list-name [32] (conference) This item should only be used if the main purpose of the conference is to import a single external mailing list. The data should be the email address that is used to post to the list, such as @samp{bug-lyskom@@lysator.liu.se}. @item mx-mime-belongs-to [10100] (text) Data is a decimal text number that this text is an attachment to. Most likely, the current text is also a comment (or perhaps a footnote) to the text mentioned in the aux-item. A client can use this aux-item to alter the display format of the text (stating that this is an attachment, not a normal comment). @item mx-mime-part-in [10101] (text) Data is a decimal text number of a text that is an attachment to the current one. In other words: this is the converse of mx-mime-belongs-to. A client can use this aux-item to know which comments to mark as attachments; the remaining comments are assumed to be normal. @item mx-mime-misc [10102] (text) Data is a string that contains all of the MIME headers for the current text. It is set by the importer. The fields are concatenated with "\n". Clients are encouraged to provide a command to display this. @item mx-envelope-sender [10103] (text) Data is the envelope sender of an imported text. The mail server is supposed to pass this information to the importer, for inclusion here. @item mx-mime-file-name [10104] (text) Data is the file name of an attachment. Most likely, the importer gets this information from a @code{name} parameter on a @code{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. @end table @node Name Expansion @chapter Name Expansion Names in LysKOM can be expanded according to two rules, regexp matching or KOM conventions. @section Regexp Matching This type of expansion, used by the @reqdlink{re-z-lookup} call and its predecessors@linkhere{} simply matches @command{ed}(1) style regular expressions to names in the database to find the list of matching names. The matching is case sensitive. @section KOM Conventions This type of matching is a little more complicated. Patterns consist of words and parenthesized expressions, and contain implicit wildcards. The @command{lyskomd} program implements an approximation of theses conventions. Since @command{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 @reqdlink{get-collate-table} call@linkhere{}. 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. @node LysKOM Content Types @chapter LysKOM Content Types 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. @menu * Reformattable Text (text/x-kom-basic):: * The User Area (x-kom/user-area):: @end menu @node Reformattable Text (text/x-kom-basic) @section Reformattable Text 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. @itemize @bullet @item Lines must be no longer than 70 characters. @item Each line is terminated by a single newline character. @item Two newline characters in succession signal the end of the paragraph. @item There must be no whitespace or newlines after the last character @end itemize The following rules apply when reformatting: @itemize @bullet @item The indentation of the first line of a paragraph is to be applied to all lines in the paragraph. @item If the first line of a paragraph matches ">+ *" then the string that matched that regexp is to be prefixed to all lines of the paragraph. @end itemize 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. @node The User Area (x-kom/user-area) @section The User Area This content type indicates that the article contains a user area. @xref{The User Area}. @node The User Area @chapter 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 dictated by this protocol specification. Clients may also create one or more blocks. The entire user-area is coded as a @type{HOLLERITH}. This string in turn contains a list of pairs of @type{HOLLERITH} strings. Each pair consists of one string containing the block name and one containing the data. This format ensures that clients can copy or read past other clients' blocks without knowing their structure. The following block names have been defined: @table @code @item common The common block shared by all clients. The format of the common block is described below. @item elisp The block created by the Emacs list client. The format is completely undocumented, but you'll need a lisp reader to parse it. @item WWW-kom The block created by the web gateway WWW-kom. It has the same syntax as the common block, but the keys and values are not documented. @item rkom Used by Anders Magnusson . @end table If you're writing a client that uses the user-area, please let us know what you name your client's block. @section The Common Block This defines the theoretical structure of the common block. The real world probably does not agree entirely with this, and it is likely to change just as soon as I have time to define something better. In the mean while you're probably better off ignoring the common block and storing all your settings in a client block. The Emacs lisp client uses the common block, but I have a feeling that it might store data that other clients can't read. 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 line feed character. As of protocol version 10, values can be integers, strings, booleans or lists. The encoding is such that a value is encoded as a single protocol A token. That means that strings and lists are both 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 (new types will be encoded as HOLLERITHs.) The grammar below sort of defines the syntax of the common block. @c ispell-ignore @example common-block : settings settings : settings setting | /* empty */ setting : variable ' ' value '\n' variable : [A-Za-z-_0-9]+ value : boolean | HOLLERITH | list | integer boolean : 1 | 0 integer : -?[0-9]+ list : integer elems // Encoded in a HOLLERITH elems : elems value | empty @end example @c ispell-end-ignore Currently the following variables are used, but more may be added, and as of protocol version 10, clients should be able to cope with variables they know nothing of in the common block, as long as they are of one of the types above. Pre-protocol version 10 clients can't deal with HOLLERITHs in the common block. As of protocol 10 the following variables are stored in the common block: @table @code @item created-texts-are-read True if the user wants texts s/he creates to be marked as read automatically. Boolean. @item dashed-lines True if the user wants dashed lines around the text body when it's displayed. Boolean. @item presence-messages True if the user wants messages about people logging in and logging out of LysKOM. Boolean. @item print-number-of-unread-on-entrance True if the user wants to see the number of unread texts when entering a conference. Boolean. @item read-depth-first True if the user wants to read text in depth-first order. Boolean. @item reading-puts-comments-in-pointers-last True if the user wants the client to display comment links after the text body. Boolean. @item confirm-multiple-recipients True if the user wants the client to ask for confirmation before sending a text to many conferences. @item default-mark The default mark to set on marked texts. @end table @node Writing Clients @appendix Writing Clients (informative) This appendix is not really part of the protocol specification, but it contains some information that may be useful for client writers. @menu * Common Commands:: Common commands and how they're implemented. * Client Conventions:: Conventions clients should follow. @end menu @node Common Commands @section Common Commands 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. @menu * What do I have unread:: How to figure out which articles to present. @end menu @node What do I have unread @subsection What do I have unread 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 @field{last-text-read} and a list of local text numbers called @field{read-texts}. The person has marked all texts up to and including @field{last-text-read} as read, and also the texts listed in @field{read-texts}. All other texts in the conference are unread. Clients can use either the @req{query-read-texts} or @req{get-membership} calls to get membership data. The standard procedure for finding out which texts are unread is the following: @enumerate @item Call @req{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. @item Call @req{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. @item Call @req{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. @item Compare the highest existing local number in the conference (from the conference status) with the @field{last-text-read} field for the corresponding membership. If the highest existing local text is higher than @field{last-text-read}, the conference may contain unread texts. @item Get part of the local to global map from the conference starting at @field{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. @end enumerate Take care not to call get-map or get-membership too much since they tend to be expensive operations. Use @req{get-unread-confs} and @req{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. @node Client Conventions @section Client Conventions 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. @menu * Text formatting:: The format of texts in the database. * Content type specification:: Clients can tag the content type of a text. @end menu @node Text formatting @subsection Text formatting 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: @itemize @bullet @item Lines should be no longer than 72 characters. @item Lines are terminated with a single newline character. @item Paragraphs are separated by two newlines in succession. @item There are no empty lines at the end of the text. @end itemize 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 @reqdlink{send-message} call@linkhere{}. @node Content type specification @subsection Content type specification 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. @node Importing and Exporting E-Mail @appendix Importing and Exporting E-Mail (informative) 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 (@command{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. @section Importing e-mail 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. @subsection Recipients Although a mail message contains @code{To} and @code{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 @code{To} header contains a personal mail address. The mail is received using a tool like @command{procmail} and forwarded to the LysKOM importer. The envelope address will be correct, but the @code{To} header will still contain the personal address. The @command{komimportmail} importer uses addresses like ``@var{number}@@@var{server}'', where @var{number} is the number of the recipient and @var{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, @command{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 @code{john.q.public@@example.com} and @code{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 @code{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 @code{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. @c FIXME: Please elaborate on that... 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 @command{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. @subsection Threading The importer should do its best to thread messages. When the importer sees a new message it needs to look at the @code{In-Reply-To} header to see what the message is a reply to. If the @code{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 @code{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. 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. @subsection MIME issues 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 @command{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 @aux{mx-author}, text coded using the method in RFC 2047 should be decoded. @node Future changes @appendix Future changes (speculative) 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. @itemize @bullet @item Cryptography! LysKOM is sometimes used for sensitive information. It is unacceptable that everything is sent in the clear. Should we use TLS? This area needs further study. @item The information contained in the @type{Misc-Info} array should be integrated into the @type{Text-Stat}. There should be one array of recipients, one of texts that comments this text, and so on. This would make the @type{Misc-Info} type obsolete. @item The aux-items can be very large. It was a mistake to include them in the @type{Text-Stat}. They should probably be separated from the @type{Text-Stat}; retrieving the @type{Text-Stat} should only indicate which aux-items that exists. @item There is too few asynchronous messages. There are many situations where something can change without a client noticing it. There is more than one way to fix this, and it is not known which way is the best. @item The super conference is used for two purposes: to indicate where followups of original conferences should be sent, and to indicate where articles created by persons that are not permitted submitters should be sent. Occasionally one wants to send followups to one conference and unauthorized original articles to another conference. One way to fix this is to remove the @conftype{original} bit and introduce a @field{followups-to} field in the @type{Conference}. Doing this in a backwards-compatible way requires some thought@dots{} @item The security system is too complex, yet unable to do many useful things, and should be rethought. @item The @field{last-text-read} and @field{read-texts} fields of a @type{Membership} is a very poor way to store information about what is read. Consider the case where somebody has read everything up to text 100, and text 102-2002. Using the current protocol specification more than 2000 numbers must be transmitted to convey that information. A much more attractive solution would be to send a list of ranges of read texts. @item The @reqlink{mark-as-read} call is a reasonably good way to mark a single text as read (but one could argue that it should take a single @code{Text-No} and an @code{ARRAY Conf-No} as arguments), but there is no easy way to undo such an operation. You can use @reqlink{set-last-read} followed by a number of @req{mark-as-read} calls to get the desired effect, but it would be nice to have a @code{mark-as-unread} call. @item If the client issues several request without waiting for a reply, the replies will nevertheless always arrive in the same order as the requests were sent in. If a threaded version of the LysKOM server is ever made, it could possibly process two requests from the same client at the same time, and the answers could be returned in any order. However, the current clients are probably not written so that they can handle such reordering. 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 @field{ref-no} to match each reply to the corresponding call. @end itemize @node Protocol Version History @appendix Protocol Version History (informative) @section Protocol version 10 (first implemented in lyskomd 2.0.0) @table @asis @item Error codes The error codes are now documented. Several error codes were changed to more sane values while documenting the new behavior. @item New Server Calls These new calls have status Recommended. @itemize @bullet @item 85=get-collate-table @item 86=create-text @item 87=create-anonymous-text @item 88=create-conf @item 89=create-person @item 90=get-text-stat @item 91=get-conf-stat @item 92=modify-text-info @item 93=modify-conf-info @item 94=get-info @item 95=modify-system-info @item 96=query-predefined-aux-items @item 98=query-read-texts @item 99=get-membership @item 100=add-member @item 101=get-members @item 102=set-membership-type @item 103=local-to-global @item 104=map-created-texts @item 106=set-pers-flags @end itemize These new calls have status Experimental. @itemize @bullet @item 97=set-expire @item 105=set-keep-commented @end itemize @item Name changes @multitable {59=create-anonymous-text} {59=create-anonymous-text-old} @item Old name @tab New name @item 5=create-person @tab 5=create-person-old @item 9=query-read-texts @tab 9=query-read-texts-old @item 10=create-conf @tab 10=create-conf-old @item 13=get-conf-stat-old @tab 13=get-conf-stat-older @item 14=add-member @tab 14=add-member-old @item 26=get-text-stat @tab 26=get-text-stat-old @item 28=create-text @tab 28=create-text-old @item 36=get-info @tab 36=get-info-old @item 46=get-membership @tab 46=get-membership-old @item 48=get-members @tab 48=get-members-old @item 50=get-conf-stat @tab 50=get-conf-stat-old @item 59=create-anonymous-text @tab 59=create-anonymous-text-old @end multitable @item Status change The following calls have change status from Experimental to Recommended. @itemize @bullet @item 58=get-last-text @item 77=set-last-read @item 78=get-uconf-stat @end itemize The following calls have changed status from Recommended or Experimental to Obsolete. @itemize @bullet @item 5=create-person-old @item 9=query-read-texts-old @item 10=create-conf-old @item 14=add-member-old @item 26=get-text-stat-old @item 28=create-text-old @item 36=get-info-old @item 46=get-membership-old @item 47=get-created-texts @item 48=get-members-old @item 50=get-conf-stat-old @item 59=create-anonymous-text-old @end itemize @item New and Modified Structures @itemize @bullet @item Aux-Item @item Aux-Item-Input @item Conference @item Info @item Member @item Membership @item Membership-Type @item Misc-Info @item Text-Stat @end itemize @item Renamed Asynchronous Messages A @samp{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. @item New Asynchronous Messages @itemize @bullet @item 14=async-deleted-text @item 15=async-new-text @item 16=async-new-recipient @item 17=async-sub-recipient @item 18=async-new-membership @end itemize @item Notes @itemize @bullet @item Since protocol version 9 setting a priority of zero for a conference was supposed to indicate passive membership in a conference. It was largely up to the client to implement this. True passive memberships have been introduced in this protocol version through the Membership-type extension to the Membership type. In order to maintain compatibility with clients that interpret priority 0 as passive membership, the old calls @reqlink{add-member-old} and @reqlink{get-membership-old} perform magic, translating between priorities and membership types. The magic is documented with each call. @end itemize @end table @section Protocol version 9 (first implemented in lyskomd 1.9.0) @table @asis @item New functionality @itemize @bullet @item The server shall now reply with error @errorcode{not-implemented} when a client attempts to use an unimplemented call. This feature requires that the client uses newline as call terminator. @end itemize @item Added Commands @itemize @bullet @item 79=set-info: Can change server information. @item 80=accept-async: Can select asynchronous messages to receive. @item 81=query-async: Can query which messages are being send. @item 82=user-active @item 83=who-is-on-dynamic @item 84=get-static-session-info @end itemize @item Changed names @itemize @bullet @item @req{change-conference} was previously called @code{pepsi}. The name was changed, but not the functionality. @end itemize @item Status change @itemize @bullet @item 63=@req{who-is-on-ident} is now considered obsolete. @item 64=@req{get-session-info-ident} is now considered obsolete. @end itemize @end table @section Protocol version 8 (first implemented in lyskomd 1.8.0) @table @asis @item Added Functionality @itemize @bullet @item 30=add-recipient: Can change @misc{recpt} to @misc{cc-recpt} and vice versa. @item 21=set-conf-type: Accepts @type{Conf-Type} and @type{Extended-Conf-Type}. @item 10=create-conf: Accepts @type{Conf-Type} and @type{Extended-Conf-Type}. @end itemize @item New Commands @itemize @bullet @item 77=set-last-read @item 78=get-uconf-stat @end itemize @end table @section Protocol version 7 (first implemented in lyskomd 1.7.0) @table @asis @item Added Functionality @itemize @bullet @item 53=send-message: Recipient can be a conference or a person. @end itemize @item New Commands @itemize @bullet @item 74=re-z-lookup @item 75=get-version-info @item 76=lookup-z-name @end itemize @item Other @itemize @bullet @item The asynchronous message 1=i-am-off has been removed @end itemize @end table @section Protocol Version 6 (first implemented in lyskomd 1.4.0) @table @asis @item New Calls @itemize @bullet @item 67=lookup-person @item 68=lookup-conf @item 69=set-client-version @item 70=get-client-name @item 71=get-client-version @item 72=mark-text @item 73=unmark-text @end itemize @end table @section Protocol Version 5 (first implemented in lyskomd 1.3.0) @table @asis @item New Calls @itemize @bullet @item 65=re-lookup-person @item 66=re-lookup-conf @end itemize @end table @section Protocol Version 4 (first implemented in lyskomd 1.1.1) @table @asis @item New Calls @itemize @bullet @item 62=login @item 63=who-is-on-ident @item 64=get-session-info-ident @end itemize @end table @section Protocol Version 3 (first implemented in lyskomd 1.1.0) @table @asis @item New Calls @itemize @bullet @item 61=find-previous-text-no @item 60=find-next-text-no @item 59=create-anonymous-text @item 58=get-last-text @end itemize @end table @section Protocol Version 2 (first implemented in lyskomd 0.30.0) @table @asis @item New Calls @itemize @bullet @item 57=set-user-area @end itemize @end table @section Protocol Version 1 (first implemented in lyskomd 0.29.2) @table @asis @item New Calls All calls from 0--56. @end table @node Document Edition History @appendix Document Edition History (informative) @table @asis @item 10.4: 2001-05-24 @emph{Fixed errors:} Fixed the description of the @code{old-pwd} argument to @reqlink{set-passwd}. The content-type x-kom/basic was renamed to text/x-kom-basic. @emph{Previously undocumented stuff:} Documented several previously undocumented aspects of the protocol: the hello string used during connection establishment, the @code{items-to-delete} and @code{items-to-add} arguments of @req{modify-system-info}, the @code{type} argument of @req{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). @emph{New stuff:} Registered the "rkom" user-area block. @emph{New aux-items:} The following predefined aux-items were added: @aux{canonical-name} [31], @aux{mx-list-name} [32] @aux{mx-mime-belongs-to} [10100], @aux{mx-mime-part-in} [10101], @aux{mx-mime-misc} [10102], @aux{mx-envelope-sender} [10103] and @aux{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. @emph{Editorial changes:} Lots of editorial changes needed to publish an online version on the web at @uref{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 @file{texinfo.tex} this file cannot currently be typeset using @TeX{}. (All bugs are reported to the Texinfo maintainers.) @req{get-membership-old}, @req{get-membership} and @req{login} used to take an argument of type @code{BITSTRING(@var{a-single-field})}. The type has now been changed to @type{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. @item 10.3: 2000-09-09 Several aux-items can be set on letterboxes and not only conferences. A few can now be set on the server. The @aux{allowed-content-type} and @aux{recommended-conf} aux-items were added. The @aux{mx-allow-filter} and @aux{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. @item 10.2: 1999-07-23 Some typos and other minor errors were fixed. Distributed with lyskomd 2.0.2. @item 10.1: 1999-07-12 Call @req{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 @req{add-recipient}, @async{async-new-recipient} and @async{async-sub-recipient}.) Distributed with lyskomd 2.0.1. @item 10.0: 1999-06-27 The specification was translated to English and converted to Texinfo by David Byers. Protocol version 10. Distributed with lyskomd 2.0.0. Note: this edition incorrectly marked the @req{sub-comment} call as obsolete, and stated that regexp lookup was case insensitive. Both statements were wrong, and has since been fixed. @item 9.0: 1996-08-04 Protocol version 9. Distributed with lyskomd 1.9.0. @item 8.0: 1995-11-10 Protocol version 8. Distributed with lyskomd 1.8.0. @item 7.1: 1995-01-08. Protocol and document revision history were added by Per Cederqvist. Outline mode was used to make the document more manageable. This version was distributed with lyskomd 1.7.1. @item 7.0: 1994-12-31. The first specification with a version number. All calls that had been added since 1991-06-25 were documented. Pell and Per Cederqvist did the deed. This version was distributed with lyskomd 1.7.0. @item 1993-05-19. Linus Tolke wrote comments for some calls that were without comments. @item 1992-07-06. Linus Tolke converted the document to ISO 8859-1. @item 1991-08-12. Per Cederqvist started using version control for documentation. @item 1991-06-25. Lars Aronsson documented the protocol that was in use at the time. @end table @node Index @unnumbered Index @printindex fn @bye Local Variables: sentence-end: "[.?!][]\"')}]*\\($\\| $\\|\t\\| \\)[ \t\n]*" sentence-end-double-space: t ispell-local-dictionary: "american" ispell-skip-region-alist: ((ispell-words-keyword forward-line) ("^@\\(end\\|syncodeindex\\|\\(un\\)?macro\\) .*$") ("^@\\(printindex\\|set\\) .*$") ("@\\(uref\\|value\\|badspell\\)\ {[^{}]*\\({[^{}]*}\\)?[^{}]*}") ("@[a-z]+[{ ]") ("@[a-z]+$") ("\input texinfo.*$") ("ispell-ignore" . "ispell-end-ignore") ("^Local Variables:$" . "^End:$")) End: @c LocalWords: ACS BITSTRING BNF BOOL BortaKOM CC CSCW Cederqvist Dekker liu @c LocalWords: Elisp HOLLERITHs INT JSK JySKom KOM LysKOM lysator Magnusson @c LocalWords: Padrone's PortaCOM PottaKOM QZ RFC RPC Stat TLS TZ Tolke FIXME @c LocalWords: UConference UTC WinKOM abbrev'd addr admin aronsson async aux @c LocalWords: bcc cc ciokwe comm compface conf confs datatype dst elisp se @c LocalWords: exempel faq flg foo footn gazonk getmail guwal hakka hopi pell @c LocalWords: hostname html iconifies ident infos kajsa kom komimportmail om @c LocalWords: lage ldb letterbox letterboxes linefeed linus loc ludd luth db @c LocalWords: lyskom lyskomd markup misc motd msg mx nMessage nilkom nos ok @c LocalWords: passwd pepsi perm pers pgp pres priv procmail prot pwd ragge @c LocalWords: rec recpt ref regexp regexps rkom sans stat struct submitters @c LocalWords: sven svensson swascii sync synched synching texinfo tkom kent @c LocalWords: ttykom uconf undef unmark userid username val varg yoruba dont @c LocalWords: Nyheter davby Testconf com