From 19643a366517b3141d0bb74e1a160069774e0b2b Mon Sep 17 00:00:00 2001 From: "Mirar (Pontus Hagland)" <pike@sort.mirar.org> Date: Sun, 13 Jun 1999 01:01:50 +0200 Subject: [PATCH] inserted into pike as Protocols.LysKOM Rev: lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike:1.1 Rev: lib/modules/Protocols.pmod/LysKOM.pmod/Helper.pmod:1.1 Rev: lib/modules/Protocols.pmod/LysKOM.pmod/ProtocolTypes.pmod:1.1 Rev: lib/modules/Protocols.pmod/LysKOM.pmod/Raw.pike:1.1 Rev: lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod:1.1 Rev: lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike:1.1 --- .gitattributes | 3 + .../LysKOM.pmod/Connection.pike | 158 + .../Protocols.pmod/LysKOM.pmod/Helper.pmod | 360 +++ .../LysKOM.pmod/ProtocolTypes.pmod | 1075 +++++++ .../Protocols.pmod/LysKOM.pmod/Raw.pike | 453 +++ .../Protocols.pmod/LysKOM.pmod/Request.pmod | 2560 +++++++++++++++++ .../Protocols.pmod/LysKOM.pmod/Session.pike | 599 ++++ 7 files changed, 5208 insertions(+) create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/Helper.pmod create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/ProtocolTypes.pmod create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/Raw.pike create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike diff --git a/.gitattributes b/.gitattributes index 9a3eeb6a99..7d05fad768 100644 --- a/.gitattributes +++ b/.gitattributes @@ -43,6 +43,9 @@ testfont binary /lib/modules/Protocols.pmod/Ident.pmod foreign_ident /lib/modules/Protocols.pmod/LPD.pmod foreign_ident /lib/modules/Protocols.pmod/Line.pmod foreign_ident +/lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike foreign_ident +/lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod foreign_ident +/lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike foreign_ident /lib/modules/Protocols.pmod/Ports.pmod foreign_ident /lib/modules/Protocols.pmod/TELNET.pmod foreign_ident /lib/modules/Protocols.pmod/X.pmod/Atom.pmod foreign_ident diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike b/lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike new file mode 100644 index 0000000000..36f913a43b --- /dev/null +++ b/lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike @@ -0,0 +1,158 @@ +// $Id: Connection.pike,v 1.1 1999/06/12 23:01:49 mirar Exp $ +//! module Protocols +//! submodule LysKOM +//! class Session +// ^^^ this is just to get the classes sorted right. Session first, +// then Connection, then it doesn't matter +//! submodule LysKOM +//! class Connection +//! This class contains nice abstraction for calls into the +//! server. They are named "<i>call</i>", +//! "<tt>async_</tt><i>call</i>" or +//! "<tt>async_cb_</tt><i>call</i>", depending on +//! how you want the call to be done. +//! +//! method mixed /call/(mixed ...args) +//! method object async_/call/(mixed ...args) +//! method object async_cb_/call/(function callback,mixed ...args) +//! Do a call to the server. This really +//! clones a <link to=Protocols.LysKOM.Request>request</link> object, +//! and initialises it. /call/ is to be read as +//! one of the calls in the lyskom protocol. ('-' is replaced +//! with '_'.) (ie, logout, async_login or async_cb_get_conf_stat.) +//! +//! The first method is a synchronous call. This will +//! send the command, wait for the server to execute it, +//! and then return the result. +//! +//! The last two is asynchronous calls, returning the +//! initialised <link to=Protocols.LysKOM.Request>request</link> object. +//! + +import "."; + +object this=this_object(); +object con; // LysKOM.Raw + +//! +//! method void create(string server) +//! method void create(string server,mapping options) +//! <pre> +//! "login" : int|string - login as this person number +//! (get number from name) +//! "password" : string - send this login password +//! "invisible" : int(0..1) - login invisible +//! +//! advanced: +//! "port" : int - server port (default is 4894) +//! "whoami" : string - user name (default is from uid) +//! </pre> + +void create(string server,void|mapping options) +{ + if (!options) options=([]); + con=Raw(server,options->port,options->whoami); + if (!con->con) + { + con=0; + return; + } + + if (options->login) + { + if (stringp(options->login)) + { + array a=this->lookup_z_name(options->login,1,0); + if (sizeof(a)!=1) + error("LysKOM: The login name %O does not match 1 name " + "exact (%d hits)\n", + options->login,sizeof(a)); + options->login=a[0]->conf_no; + } + this->login(options->login, + options->password||"", + options->invisible); + } +} + +class SyncRequest +{ + program prog; + object ret; + + void create(program p,object _ret) + { + prog=p; + ret=_ret; + } + + mixed `()(mixed ...args) + { + mixed m; + object req=prog(con); + m=req->sync(@args); + if (!req->ok) + { + throw(req->error); +// error(sprintf("lyskom-error %d,%d: %s\n%-=75s\n", +// req->error->no, +// req->error->status, +// req->error->name, +// req->error->desc)); + } + if (!m) return ret; + else return m; + } +} + +class AsyncRequest +{ + program prog; + + void create(program p) + { + prog=p; + } + + mixed `()(mixed ...args) + { + object req=prog(con); + req->async(@args); + return req; + } +} + +class AsyncCBRequest +{ + program prog; + + void create(program p) + { + prog=p; + } + + mixed `()(function callback,mixed ...args) + { + object req=prog(con); + req->callback=callback; + req->async(@args); + return req; + } +} + +mixed `->(string request) +{ + program p; + if ( (p=Request[String.capitalize(request)]) ) + return SyncRequest(p,this_object()); + else if ( request[..5]=="async_" && + (p=Request[String.capitalize(request[6..])]) ) + return AsyncRequest(p); + else if ( request[..8]=="async_cb_" && + (p=Request[String.capitalize(request[9..])]) ) + return AsyncCBRequest(p); + else + return ::`[](request); +} + +mixed `[](string request) { return `->(request); } diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/Helper.pmod b/lib/modules/Protocols.pmod/LysKOM.pmod/Helper.pmod new file mode 100644 index 0000000000..02b2edbd10 --- /dev/null +++ b/lib/modules/Protocols.pmod/LysKOM.pmod/Helper.pmod @@ -0,0 +1,360 @@ +constant CONNECTION_CLOSED=-100; + +string encode(mixed ... z) // encode arguments +{ + return ((array(string))z)*" "; +} + +string H(string what) // encode hollerith +{ + return strlen(what)+"H"+what; +} + +string B(int(0..1) ... z) // encode bitfield +{ + string res=""; + res=((array(string))z)*""; + return res; +} + +array(string) A(mixed ... z) // encode array (use @) +{ + if (!sizeof(z)) return ({"0","*"}); + return ({""+sizeof(z)," { "+encode(@z)+" }"}); +} + +class LysKOMError +{ + constant iserror=1; + constant is_generic_error=1; + + int no; + string name; + string desc; + int status; + array(mixed) __backtrace; + + void create(int _no,string _name,string _desc,void|int _status) + { + no=_no; + name=_name; + desc=_desc; + status=_status; + __backtrace=backtrace(); + __backtrace=__backtrace[..sizeof(__backtrace)-3]; + } + + object clone(int status) + { + return LysKOMError(no,name,desc,status); + } + + mixed `[](mixed z) + { + switch (z) + { + case 0: return "Protocols.LysKOM: ["+no+"] "+name+"\n"; + case 1: return __backtrace; + } + } +} + +object lyskom_error(int no,void|int status) +{ + return LysKOMError(@_lyskomerror[no],status); +} + +mapping _lyskomerror= +([ + 0:({0,"no-error", + "No error has occurred. This should never " + "happen, but it might."}), + + 2:({2,"not-implemented", + "The call has not been implemented yet."}), + + 3:({3,"obsolete-call", + "The call is obsolete and no longer " + "implemented. Status value is " + "undefined."}), + + 4:({4,"invalid-password", + "Attempt to set a password containing " + "illegal characters, or to use an " + "incorrect password."}), + + 5:({5,"string-too-long", + "A string was too long (see descriptions " + "of each call.) Status value indicates " + "the maximum string length."}), + + 6:({6,"login-first", + "Login is required before issuing the " + "call. Status value is undefined. "}), + + 7:({7,"login-disallowed", + "The system is in single-user mode. You " + "need to be privileged to log in despite " + "this. "}), + + 8:({8,"conference-zero", + "Attempt to use conference number 0. "}), + + 9:({9,"undefined-conference", + "Attempt to access a non-existent or " + "secret conference. Status value contains " + "the conference number in question."}), + + 10:({10,"undefined-person", + "Attempt to access a non-existent or" + "secret person. Status value contains the" + "person number in question."}), + + 11:({11,"access-denied", + "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. Status value indicates the object" + "to which we didn't have enough" + "permissions to."}), + + 12:({12,"permission-denied", + "Not enough permissions to do something." + "The exact meaning of this response" + "depends on the call. Status value" + "indicated the object for which" + "permission was lacking, or zero."}), + + 13:({13,"not-member", + "The call requires the caller to be a" + "member of some conference that the" + "caller is not a member of. Status value" + "indicates the conference in question."}), + + 14:({14,"no-such-text", + "Attempt to access a text that either" + "does not exist or is secret in some way." + "status value indicates the text number" + "in question."}), + + 15:({15,"text-zero", + "Attempt to use text number 0. "}), + + 16:({16,"no-such-local-text", + "Attempt to access a text using a local" + "text number that does not represent an" + "existing text. Status value indicates" + "the offending number."}), + + 17:({17,"local-text-zero", + "Attempt to use local text number zero."}), + + 18:({18,"bad-name", + "Attempt to use a name that's too long," + "too short or contains invalid" + "characters. "}), + + 19:({19,"index-out-of-range", + "Attempt to use a number that's out of" + "range. The range and meaning of the" + "numbers depends on the call issued." + "status value is undefined."}), + + 20:({20,"conference-exists", + "Attempt to create a conference or person" + "with a name that's already occupied. "}), + + 21:({21,"person-exists", + "Attempt to create a person with a name" + "that's already occupied. This error code" + "is probably not used, but you never know" + "for sure."}), + + 22:({22,"secret-public", + "Attempt to give a conference a type with" + "@code{secret} bit set and the" + "@code{rd-prot} bit unset. This is an" + "error since such a conference type is" + "inconsistent. "}), + + 23:({23,"letterbox", + "Attempt to change the @code{letterbox}" + "flag of a conference. Status value" + "indicates the conference number."}), + + 24:({24,"ldb-error", + "Database is corrupted. Status value is" + "an internal code."}), + + 25:({25,"illegal-misc", + "Attempt to create an illegal misc item." + "status value contains the index of the" + "illegal item."}), + + 26:({26,"illegal-info-type", + "Attempt to use a Misc-Info type that the" + "server knows nothing about. "}), + + 27:({27,"already-recipient", + "Attempt to add a recipient that is" + "already a recipient of the same type." + "status value contains the recipient that" + "already is."}), + + 28:({28,"already-comment", + "Attempt to add a comment to a text twice" + "over. Status value contains the text" + "number of the text that already is a" + "comment."}), + + 29:({29,"already-footnote", + "Attempt to add a footnote to a text" + "twice over. Status value contains the" + "text number of the text that already is" + "a footnote."}), + + 30:({30,"not-recipient", + "Attempt to remove a recipient that isn't" + "really a recipient. Status value" + "contains the conference number in" + "question."}), + + 31:({31,"not-comment", + "Attempt to remove a comment link that" + "does not exist. Status value contains" + "the text number that isn't a comment. "}), + + 32:({32,"not-footnote", + "Attempt to remove a footnote link that" + "does not exist. Status value contains" + "the text number that isn't a footnote."}), + + 33:({33,"recipient-limit", + "Attempt to add a recipient to a text" + "that already has the maximum number of" + "recipients. Status value is the text" + "that has the maximum number of" + "recipients."}), + + 34:({34,"comment-limit", + "Attempt to add a comment to a text that" + "already has the maximum number of" + "comments. Status value is the text with" + "the maximum number of comments. "}), + + 35:({35,"footnote-limit", + "Attempt to add a footnote to a text that" + "already has the maximum number of" + "footnote. Status value is the text with" + "the maximum number of footnote. "}), + + 36:({36,"mark-limit", + "Attempt to add a mark to a text that" + "already has the maximum number of marks." + "status value is the text with the" + "maximum number of marks. "}), + + 37:({37,"not-author", + "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. Status value contains the text" + "number in question."}), + + 38:({38,"no-connect", + "Currently unused."}), + + 39:({39,"out-of-memory", + "The server ran out of memory."}), + + 40:({40,"server-is-crazy", + "Currently unused."}), + + 41:({41,"client-is-crazy", + "Currently unused."}), + + 42:({42,"undefined-session", + "Attempt to access a session that does" + "not exist. Status value contains the" + "offending session number."}), + + 43:({43,"regexp-error", + "Error using a regexp. The regexp may be" + "invalid or the server unable to compile" + "it for other reasons. "}), + + 44:({44,"not-marked", + "Attempt to manipulate a text in a way" + "that requires the text to be marked," + "when in fact it is not marked. Status" + "value indicates the text in question."}), + + 45:({45,"temporary-failure", + "Temporary failure. Try again later." + "@code{error-code} is undefined."}), + + 46:({46,"long-array", + "An array sent to the server was too" + "long. Status value is undefined."}), + + 47:({47,"anonymous-rejected", + "Attempt to send an anonymous text to a" + "conference that does not accept" + "anonymous texts. "}), + + 48:({48,"illegal-aux-item", + "Attempt to create an invalid aux-item." + "Probably the tag or data are invalid." + "status value contains the index in the" + "aux-item list where the invalid item" + "appears."}), + + 49:({49,"aux-item-permission", + "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. Status value" + "contains the index at which the item" + "appears in the aux-item list sent to the" + "server."}), + + 50:({50,"unknown-async", + "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. Status" + "value contains the message type the" + "server did not understand."}), + + 51:({51,"internal-error", + "The server has encountered a possibly" + "recoverable internal error. "}), + + 52:({52,"feature-disabled", + "Attempt to use a feature that has been" + "explicitly disabled in the server. "}), + + 53:({53,"message-not-sent", + "Attempt to send an asynchronous message" + "failed for some reason. Perhaps the" + "recipient is not accepting messages at" + "the moment."}), + + 54:({54,"invalid-membership-type", + "A requested membership type was not" + "compatible with restrictions set on the" + "server or on a specific conference." + "status value is undefined unless" + "specifically mentioned in the" + "documentation for a specific call."}), + + CONNECTION_CLOSED:({CONNECTION_CLOSED,"connection closed", + "LysKOM module: connection has been closed"}) +]); diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/ProtocolTypes.pmod b/lib/modules/Protocols.pmod/LysKOM.pmod/ProtocolTypes.pmod new file mode 100644 index 0000000000..af45aed44d --- /dev/null +++ b/lib/modules/Protocols.pmod/LysKOM.pmod/ProtocolTypes.pmod @@ -0,0 +1,1075 @@ +import .Helper; + + +// +// automatically generated datatypes +// + +class LysKOMTime +{ + int seconds; // INT32 + int minutes; // INT32 + int hours; // INT32 + int day; // INT32 + int month; // INT32 + int year; // INT32 + int day_of_week; // INT32 + int day_of_year; // INT32 + int(0..1) is_dst; // BOOL + + void create(string|array ...args) + { + seconds=(int)args[0]; // INT32 + minutes=(int)args[1]; // INT32 + hours=(int)args[2]; // INT32 + day=(int)args[3]; // INT32 + month=(int)args[4]; // INT32 + year=(int)args[5]; // INT32 + day_of_week=(int)args[6]; // INT32 + day_of_year=(int)args[7]; // INT32 + is_dst=(int)args[8]; // BOOL + } + + array encode() + { + return + ({ + seconds, // INT32 + minutes, // INT32 + hours, // INT32 + day, // INT32 + month, // INT32 + year, // INT32 + day_of_week, // INT32 + day_of_year, // INT32 + is_dst, // BOOL + }); + } +} + +class TextStatOld +{ + LysKOMTime creation_time; // Time + int(0..65535) author; // Pers-No + int no_of_lines; // INT32 + int no_of_chars; // INT32 + int(0..65535) no_of_marks; // INT16 + array(int) misc_info; // ARRAY Misc-Info + + void create(string|array ...args) + { + creation_time=LysKOMTime(@args[0..8]); // Time + author=(int)args[9]; // Pers-No + no_of_lines=(int)args[10]; // INT32 + no_of_chars=(int)args[11]; // INT32 + no_of_marks=(int)args[12]; // INT16 + // --- skip array size: args[13] + misc_info=(array(int))args[14]; // ARRAY Misc-Info + } + + array encode() + { + return + ({ + @creation_time->encode(), // Time + author, // Pers-No + no_of_lines, // INT32 + no_of_chars, // INT32 + no_of_marks, // INT16 + @A((array(string))misc_info), // ARRAY Misc-Info + }); + } +} + +class TextNumberPair +{ + int local_number; // Local-Text-No + int global_number; // Text-No + + void create(string|array ...args) + { + local_number=(int)args[0]; // Local-Text-No + global_number=(int)args[1]; // Text-No + } + + array encode() + { + return + ({ + local_number, // Local-Text-No + global_number, // Text-No + }); + } +} + +mixed LocalToGlobalBlock(array what) { werror("LysKOM: LocalToGlobalBlock unimplemented\n"); exit(-1); }; + +class TextMapping +{ + int range_begin; // Local-Text-No + int range_end; // Local-Text-No + int(0..1) later_texts_exists; // BOOL + mixed block; // Local-To-Global-Block + + void create(string|array ...args) + { + range_begin=(int)args[0]; // Local-Text-No + range_end=(int)args[1]; // Local-Text-No + later_texts_exists=(int)args[2]; // BOOL + block=LocalToGlobalBlock(args[3]); // Local-To-Global-Block + } + + array encode() + { + return + ({ + range_begin, // Local-Text-No + range_end, // Local-Text-No + later_texts_exists, // BOOL + @error("unimplemented"), // Local-To-Global-Block + }); + } +} + +constant sessionflagsnames = + ({ "invisible", "user_active_used", "user_absent", + "reserved3", "reserved4", "reserved5", "reserved6", + "reserved7" }); + +multiset(string) SessionFlags(string bits) +{ + multiset(string) res=(<>); + foreach (Array.transpose( ({sessionflagsnames,values(bits)}) ), + [string name,int z] ) + res[name]=z-'0'; + return res; +} + +class DynamicSessionInfo +{ + int session; // Session-No + int(0..65535) person; // Pers-No + int(0..65535) working_conference; // Conf-No + int idle_time; // INT32 + multiset(string) flags; // Session-Flags + string what_am_i_doing; // HOLLERITH + + void create(string|array ...args) + { + session=(int)args[0]; // Session-No + person=(int)args[1]; // Pers-No + working_conference=(int)args[2]; // Conf-No + idle_time=(int)args[3]; // INT32 + flags=SessionFlags(args[4]); // Session-Flags + what_am_i_doing=args[5]; // HOLLERITH + } + + array encode() + { + return + ({ + session, // Session-No + person, // Pers-No + working_conference, // Conf-No + idle_time, // INT32 + @B(@rows(flags,sessionflagsnames)), // Session-Flags + H(what_am_i_doing), // HOLLERITH + }); + } +} + +class SessionInfo +{ + int(0..65535) person; // Pers-No + int(0..65535) working_conference; // Conf-No + int session; // Session-No + string what_am_i_doing; // HOLLERITH + string username; // HOLLERITH + int idle_time; // INT32 + LysKOMTime connection_time; // Time + + void create(string|array ...args) + { + person=(int)args[0]; // Pers-No + working_conference=(int)args[1]; // Conf-No + session=(int)args[2]; // Session-No + what_am_i_doing=args[3]; // HOLLERITH + username=args[4]; // HOLLERITH + idle_time=(int)args[5]; // INT32 + connection_time=LysKOMTime(@args[6..14]); // Time + } + + array encode() + { + return + ({ + person, // Pers-No + working_conference, // Conf-No + session, // Session-No + H(what_am_i_doing), // HOLLERITH + H(username), // HOLLERITH + idle_time, // INT32 + @connection_time->encode(), // Time + }); + } +} + +class WhoInfo +{ + int(0..65535) person; // Pers-No + int(0..65535) working_conference; // Conf-No + int session; // Session-No + string what_am_i_doing; // HOLLERITH + string username; // HOLLERITH + + void create(string|array ...args) + { + person=(int)args[0]; // Pers-No + working_conference=(int)args[1]; // Conf-No + session=(int)args[2]; // Session-No + what_am_i_doing=args[3]; // HOLLERITH + username=args[4]; // HOLLERITH + } + + array encode() + { + return + ({ + person, // Pers-No + working_conference, // Conf-No + session, // Session-No + H(what_am_i_doing), // HOLLERITH + H(username), // HOLLERITH + }); + } +} + +constant personalflagsnames = + ({ "unread_is_secret", "flg2", "flg3", "flg4", "flg5", + "flg6", "flg7", "flg8" }); + +multiset(string) PersonalFlags(string bits) +{ + multiset(string) res=(<>); + foreach (Array.transpose( ({personalflagsnames,values(bits)}) ), + [string name,int z] ) + res[name]=z-'0'; + return res; +} + +constant auxitemflagsnames = + ({ "deleted", "inherit", "secret", "hide_creator", + "dont_garb", "reserved2", "reserved3", "reserved4" }); + +multiset(string) AuxItemFlags(string bits) +{ + multiset(string) res=(<>); + foreach (Array.transpose( ({auxitemflagsnames,values(bits)}) ), + [string name,int z] ) + res[name]=z-'0'; + return res; +} + +class AuxItem +{ + int aux_no; // Aux-No + int tag; // INT32 + int(0..65535) creator; // Pers-No + LysKOMTime created_at; // Time + multiset(string) flags; // Aux-Item-Flags + int inherit_limit; // INT32 + string data; // HOLLERITH + + void create(string|array ...args) + { + aux_no=(int)args[0]; // Aux-No + tag=(int)args[1]; // INT32 + creator=(int)args[2]; // Pers-No + created_at=LysKOMTime(@args[3..11]); // Time + flags=AuxItemFlags(args[12]); // Aux-Item-Flags + inherit_limit=(int)args[13]; // INT32 + data=args[14]; // HOLLERITH + } + + array encode() + { + return + ({ + aux_no, // Aux-No + tag, // INT32 + creator, // Pers-No + @created_at->encode(), // Time + @B(@rows(flags,auxitemflagsnames)), // Aux-Item-Flags + inherit_limit, // INT32 + H(data), // HOLLERITH + }); + } +} + +class TextStat +{ + LysKOMTime creation_time; // Time + int(0..65535) author; // Pers-No + int no_of_lines; // INT32 + int no_of_chars; // INT32 + int(0..65535) no_of_marks; // INT16 + array(int) misc_info; // ARRAY Misc-Info + array(AuxItem) aux_items; // ARRAY Aux-Item + + void create(string|array ...args) + { + creation_time=LysKOMTime(@args[0..8]); // Time + author=(int)args[9]; // Pers-No + no_of_lines=(int)args[10]; // INT32 + no_of_chars=(int)args[11]; // INT32 + no_of_marks=(int)args[12]; // INT16 + // --- skip array size: args[13] + misc_info=(array(int))args[14]; // ARRAY Misc-Info + // --- skip array size: args[15] + aux_items= // ARRAY Aux-Item + Array.map(args[16]/15, + lambda(array z) { return AuxItem(@z); }); + } + + array encode() + { + return + ({ + @creation_time->encode(), // Time + author, // Pers-No + no_of_lines, // INT32 + no_of_chars, // INT32 + no_of_marks, // INT16 + @A((array(string))misc_info), // ARRAY Misc-Info + A(`+(@Array.map(aux_items, // ARRAY Aux-Item + lambda(AuxItem z) + { return z->encode(); }))), + }); + } +} + +class InfoOld +{ + int version; // INT32 + int(0..65535) conf_pres_conf; // Conf-No + int(0..65535) pers_pres_conf; // Conf-No + int(0..65535) motd_conf; // Conf-No + int(0..65535) kom_news_conf; // Conf-No + int motd_of_lyskom; // Text-No + + void create(string|array ...args) + { + version=(int)args[0]; // INT32 + conf_pres_conf=(int)args[1]; // Conf-No + pers_pres_conf=(int)args[2]; // Conf-No + motd_conf=(int)args[3]; // Conf-No + kom_news_conf=(int)args[4]; // Conf-No + motd_of_lyskom=(int)args[5]; // Text-No + } + + array encode() + { + return + ({ + version, // INT32 + conf_pres_conf, // Conf-No + pers_pres_conf, // Conf-No + motd_conf, // Conf-No + kom_news_conf, // Conf-No + motd_of_lyskom, // Text-No + }); + } +} + +constant membershiptypenames = + ({ "invitation", "passive", "secret", "reserved1", + "reserved2", "reserved3", "reserved4", "reserved5" }); + +multiset(string) MembershipType(string bits) +{ + multiset(string) res=(<>); + foreach (Array.transpose( ({membershiptypenames,values(bits)}) ), + [string name,int z] ) + res[name]=z-'0'; + return res; +} + +class Membership +{ + int position; // INT32 + LysKOMTime last_time_read; // Time + int(0..65535) conf_no; // Conf-No + int(0..255) priority; // INT8 + int last_text_read; // Local-Text-No + array(int) read_texts; // ARRAY Local-Text-No + int(0..65535) added_by; // Pers-No + LysKOMTime added_at; // Time + multiset(string) type; // Membership-Type + + void create(string|array ...args) + { + position=(int)args[0]; // INT32 + last_time_read=LysKOMTime(@args[1..9]); // Time + conf_no=(int)args[10]; // Conf-No + priority=(int)args[11]; // INT8 + last_text_read=(int)args[12]; // Local-Text-No + // --- skip array size: args[13] + read_texts=(array(int))args[14]; // ARRAY Local-Text-No + added_by=(int)args[15]; // Pers-No + added_at=LysKOMTime(@args[16..24]); // Time + type=MembershipType(args[25]); // Membership-Type + } + + array encode() + { + return + ({ + position, // INT32 + @last_time_read->encode(), // Time + conf_no, // Conf-No + priority, // INT8 + last_text_read, // Local-Text-No + @A((array(string))read_texts), // ARRAY Local-Text-No + added_by, // Pers-No + @added_at->encode(), // Time + @B(@rows(type,membershiptypenames)), // Membership-Type + }); + } +} + +class Member +{ + int(0..65535) member; // Pers-No + int(0..65535) added_by; // Pers-No + LysKOMTime added_at; // Time + multiset(string) type; // Membership-Type + + void create(string|array ...args) + { + member=(int)args[0]; // Pers-No + added_by=(int)args[1]; // Pers-No + added_at=LysKOMTime(@args[2..10]); // Time + type=MembershipType(args[11]); // Membership-Type + } + + array encode() + { + return + ({ + member, // Pers-No + added_by, // Pers-No + @added_at->encode(), // Time + @B(@rows(type,membershiptypenames)), // Membership-Type + }); + } +} + +class MembershipOld +{ + LysKOMTime last_time_read; // Time + int(0..65535) conf_no; // Conf-No + int(0..255) priority; // INT8 + int last_text_read; // Local-Text-No + array(int) read_texts; // ARRAY Local-Text-No + + void create(string|array ...args) + { + last_time_read=LysKOMTime(@args[0..8]); // Time + conf_no=(int)args[9]; // Conf-No + priority=(int)args[10]; // INT8 + last_text_read=(int)args[11]; // Local-Text-No + // --- skip array size: args[12] + read_texts=(array(int))args[13]; // ARRAY Local-Text-No + } + + array encode() + { + return + ({ + @last_time_read->encode(), // Time + conf_no, // Conf-No + priority, // INT8 + last_text_read, // Local-Text-No + @A((array(string))read_texts), // ARRAY Local-Text-No + }); + } +} + +class Info +{ + int version; // INT32 + int(0..65535) conf_pres_conf; // Conf-No + int(0..65535) pers_pres_conf; // Conf-No + int(0..65535) motd_conf; // Conf-No + int(0..65535) kom_news_conf; // Conf-No + int motd_of_lyskom; // Text-No + array(AuxItem) aux_item_list; // ARRAY Aux-Item + + void create(string|array ...args) + { + version=(int)args[0]; // INT32 + conf_pres_conf=(int)args[1]; // Conf-No + pers_pres_conf=(int)args[2]; // Conf-No + motd_conf=(int)args[3]; // Conf-No + kom_news_conf=(int)args[4]; // Conf-No + motd_of_lyskom=(int)args[5]; // Text-No + // --- skip array size: args[6] + aux_item_list= // ARRAY Aux-Item + Array.map(args[7]/15, + lambda(array z) { return AuxItem(@z); }); + } + + array encode() + { + return + ({ + version, // INT32 + conf_pres_conf, // Conf-No + pers_pres_conf, // Conf-No + motd_conf, // Conf-No + kom_news_conf, // Conf-No + motd_of_lyskom, // Text-No + A(`+(@Array.map(aux_item_list, // ARRAY Aux-Item + lambda(AuxItem z) + { return z->encode(); }))), + }); + } +} + +class StaticSessionInfo +{ + string username; // HOLLERITH + string hostname; // HOLLERITH + string ident_user; // HOLLERITH + LysKOMTime connection_time; // Time + + void create(string|array ...args) + { + username=args[0]; // HOLLERITH + hostname=args[1]; // HOLLERITH + ident_user=args[2]; // HOLLERITH + connection_time=LysKOMTime(@args[3..11]); // Time + } + + array encode() + { + return + ({ + H(username), // HOLLERITH + H(hostname), // HOLLERITH + H(ident_user), // HOLLERITH + @connection_time->encode(), // Time + }); + } +} + +constant extendedconftypenames = + ({ "rd_prot", "original", "secret", "letterbox", + "allow_anonymous", "forbid_secret", "reserved2", + "reserved3" }); + +multiset(string) ExtendedConfType(string bits) +{ + multiset(string) res=(<>); + foreach (Array.transpose( ({extendedconftypenames,values(bits)}) ), + [string name,int z] ) + res[name]=z-'0'; + return res; +} + +class TextList +{ + int first_local_no; // Local-Text-No + array(int) texts; // ARRAY Text-No + + void create(string|array ...args) + { + first_local_no=(int)args[0]; // Local-Text-No + // --- skip array size: args[1] + texts=(array(int))args[2]; // ARRAY Text-No + } + + array encode() + { + return + ({ + first_local_no, // Local-Text-No + @A((array(string))texts), // ARRAY Text-No + }); + } +} + +class AuxItemInput +{ + int tag; // INT32 + multiset(string) flags; // Aux-Item-Flags + int inherit_limit; // INT32 + string data; // HOLLERITH + + void create(string|array ...args) + { + tag=(int)args[0]; // INT32 + flags=AuxItemFlags(args[1]); // Aux-Item-Flags + inherit_limit=(int)args[2]; // INT32 + data=args[3]; // HOLLERITH + } + + array encode() + { + return + ({ + tag, // INT32 + @B(@rows(flags,auxitemflagsnames)), // Aux-Item-Flags + inherit_limit, // INT32 + H(data), // HOLLERITH + }); + } +} + +class WhoInfoIdent +{ + int(0..65535) person; // Pers-No + int(0..65535) working_conference; // Conf-No + int session; // Session-No + string what_am_i_doing; // HOLLERITH + string username; // HOLLERITH + string hostname; // HOLLERITH + string ident_user; // HOLLERITH + + void create(string|array ...args) + { + person=(int)args[0]; // Pers-No + working_conference=(int)args[1]; // Conf-No + session=(int)args[2]; // Session-No + what_am_i_doing=args[3]; // HOLLERITH + username=args[4]; // HOLLERITH + hostname=args[5]; // HOLLERITH + ident_user=args[6]; // HOLLERITH + } + + array encode() + { + return + ({ + person, // Pers-No + working_conference, // Conf-No + session, // Session-No + H(what_am_i_doing), // HOLLERITH + H(username), // HOLLERITH + H(hostname), // HOLLERITH + H(ident_user), // HOLLERITH + }); + } +} + +constant conftypenames = + ({ "rd_prot", "original", "secret", "letterbox" }); + +multiset(string) ConfType(string bits) +{ + multiset(string) res=(<>); + foreach (Array.transpose( ({conftypenames,values(bits)}) ), + [string name,int z] ) + res[name]=z-'0'; + return res; +} + +class ConfZInfo +{ + string name; // HOLLERITH + multiset(string) type; // Conf-Type + int(0..65535) conf_no; // Conf-No + + void create(string|array ...args) + { + name=args[0]; // HOLLERITH + type=ConfType(args[1]); // Conf-Type + conf_no=(int)args[2]; // Conf-No + } + + array encode() + { + return + ({ + H(name), // HOLLERITH + @B(@rows(type,conftypenames)), // Conf-Type + conf_no, // Conf-No + }); + } +} + +class WhoInfoOld +{ + int(0..65535) person; // Pers-No + int(0..65535) working_conference; // Conf-No + string what_am_i_doing; // HOLLERITH + + void create(string|array ...args) + { + person=(int)args[0]; // Pers-No + working_conference=(int)args[1]; // Conf-No + what_am_i_doing=args[2]; // HOLLERITH + } + + array encode() + { + return + ({ + person, // Pers-No + working_conference, // Conf-No + H(what_am_i_doing), // HOLLERITH + }); + } +} + +class Mark +{ + int text_no; // Text-No + int(0..255) type; // INT8 + + void create(string|array ...args) + { + text_no=(int)args[0]; // Text-No + type=(int)args[1]; // INT8 + } + + array encode() + { + return + ({ + text_no, // Text-No + type, // INT8 + }); + } +} + +class Conference +{ + string name; // HOLLERITH + multiset(string) type; // Extended-Conf-Type + LysKOMTime creation_time; // Time + LysKOMTime last_written; // Time + int(0..65535) creator; // Pers-No + int presentation; // Text-No + int(0..65535) supervisor; // Conf-No + int(0..65535) permitted_submitters; // Conf-No + int(0..65535) super_conf; // Conf-No + int msg_of_day; // Text-No + int nice; // Garb-Nice + int keep_commented; // Garb-Nice + int(0..65535) no_of_members; // INT16 + int first_local_no; // Local-Text-No + int no_of_texts; // INT32 + int expire; // Garb-Nice + array(AuxItem) aux_items; // ARRAY Aux-Item + + void create(string|array ...args) + { + name=args[0]; // HOLLERITH + type=ExtendedConfType(args[1]); // Extended-Conf-Type + creation_time=LysKOMTime(@args[2..10]); // Time + last_written=LysKOMTime(@args[11..19]); // Time + creator=(int)args[20]; // Pers-No + presentation=(int)args[21]; // Text-No + supervisor=(int)args[22]; // Conf-No + permitted_submitters=(int)args[23]; // Conf-No + super_conf=(int)args[24]; // Conf-No + msg_of_day=(int)args[25]; // Text-No + nice=(int)args[26]; // Garb-Nice + keep_commented=(int)args[27]; // Garb-Nice + no_of_members=(int)args[28]; // INT16 + first_local_no=(int)args[29]; // Local-Text-No + no_of_texts=(int)args[30]; // INT32 + expire=(int)args[31]; // Garb-Nice + // --- skip array size: args[32] + aux_items= // ARRAY Aux-Item + Array.map(args[33]/15, + lambda(array z) { return AuxItem(@z); }); + } + + array encode() + { + return + ({ + H(name), // HOLLERITH + @B(@rows(type,extendedconftypenames)), // Extended-Conf-Type + @creation_time->encode(), // Time + @last_written->encode(), // Time + creator, // Pers-No + presentation, // Text-No + supervisor, // Conf-No + permitted_submitters, // Conf-No + super_conf, // Conf-No + msg_of_day, // Text-No + nice, // Garb-Nice + keep_commented, // Garb-Nice + no_of_members, // INT16 + first_local_no, // Local-Text-No + no_of_texts, // INT32 + expire, // Garb-Nice + A(`+(@Array.map(aux_items, // ARRAY Aux-Item + lambda(AuxItem z) + { return z->encode(); }))), + }); + } +} + +class ConferenceOld +{ + string name; // HOLLERITH + multiset(string) type; // Conf-Type + LysKOMTime creation_time; // Time + LysKOMTime last_written; // Time + int(0..65535) creator; // Pers-No + int presentation; // Text-No + int(0..65535) supervisor; // Conf-No + int(0..65535) permitted_submitters; // Conf-No + int(0..65535) super_conf; // Conf-No + int msg_of_day; // Text-No + int nice; // Garb-Nice + int(0..65535) no_of_members; // INT16 + int first_local_no; // Local-Text-No + int no_of_texts; // INT32 + + void create(string|array ...args) + { + name=args[0]; // HOLLERITH + type=ConfType(args[1]); // Conf-Type + creation_time=LysKOMTime(@args[2..10]); // Time + last_written=LysKOMTime(@args[11..19]); // Time + creator=(int)args[20]; // Pers-No + presentation=(int)args[21]; // Text-No + supervisor=(int)args[22]; // Conf-No + permitted_submitters=(int)args[23]; // Conf-No + super_conf=(int)args[24]; // Conf-No + msg_of_day=(int)args[25]; // Text-No + nice=(int)args[26]; // Garb-Nice + no_of_members=(int)args[27]; // INT16 + first_local_no=(int)args[28]; // Local-Text-No + no_of_texts=(int)args[29]; // INT32 + } + + array encode() + { + return + ({ + H(name), // HOLLERITH + @B(@rows(type,conftypenames)), // Conf-Type + @creation_time->encode(), // Time + @last_written->encode(), // Time + creator, // Pers-No + presentation, // Text-No + supervisor, // Conf-No + permitted_submitters, // Conf-No + super_conf, // Conf-No + msg_of_day, // Text-No + nice, // Garb-Nice + no_of_members, // INT16 + first_local_no, // Local-Text-No + no_of_texts, // INT32 + }); + } +} + +class SessionInfoIdent +{ + int(0..65535) person; // Pers-No + int(0..65535) working_conference; // Conf-No + int session; // Session-No + string what_am_i_doing; // HOLLERITH + string username; // HOLLERITH + string hostname; // HOLLERITH + string ident_user; // HOLLERITH + int idle_time; // INT32 + LysKOMTime connection_time; // Time + + void create(string|array ...args) + { + person=(int)args[0]; // Pers-No + working_conference=(int)args[1]; // Conf-No + session=(int)args[2]; // Session-No + what_am_i_doing=args[3]; // HOLLERITH + username=args[4]; // HOLLERITH + hostname=args[5]; // HOLLERITH + ident_user=args[6]; // HOLLERITH + idle_time=(int)args[7]; // INT32 + connection_time=LysKOMTime(@args[8..16]); // Time + } + + array encode() + { + return + ({ + person, // Pers-No + working_conference, // Conf-No + session, // Session-No + H(what_am_i_doing), // HOLLERITH + H(username), // HOLLERITH + H(hostname), // HOLLERITH + H(ident_user), // HOLLERITH + idle_time, // INT32 + @connection_time->encode(), // Time + }); + } +} + +class VersionInfo +{ + int protocol_version; // INT32 + string server_software; // HOLLERITH + string software_version; // HOLLERITH + + void create(string|array ...args) + { + protocol_version=(int)args[0]; // INT32 + server_software=args[1]; // HOLLERITH + software_version=args[2]; // HOLLERITH + } + + array encode() + { + return + ({ + protocol_version, // INT32 + H(server_software), // HOLLERITH + H(software_version), // HOLLERITH + }); + } +} + +class ConfListArchaic +{ + array(int(0..65535)) conf_nos; // ARRAY Conf-No + array(multiset(string)) conf_types; // ARRAY Conf-Type + + void create(string|array ...args) + { + // --- skip array size: args[0] + conf_nos=(array(int))args[1]; // ARRAY Conf-No + // --- skip array size: args[2] + conf_types= // ARRAY Conf-Type + Array.map(args[3], + lambda(string z) { return ConfType(z); }); + } + + array encode() + { + return + ({ + @A((array(string))conf_nos), // ARRAY Conf-No + A(`+(@Array.map(conf_types, // ARRAY Conf-Type + lambda(multiset(string) z) + { return B(@rows(z,conftypenames)); }))), + }); + } +} + +constant privbitsnames = + ({ "wheel", "admin", "statistic", "create_pers", + "create_conf", "change_name", "flg7", "flg8", + "flg9", "flg10", "flg11", "flg12", "flg13", + "flg14", "flg15", "flg16" }); + +multiset(string) PrivBits(string bits) +{ + multiset(string) res=(<>); + foreach (Array.transpose( ({privbitsnames,values(bits)}) ), + [string name,int z] ) + res[name]=z-'0'; + return res; +} + +class UConference +{ + string name; // HOLLERITH + multiset(string) type; // Extended-Conf-Type + int highest_local_no; // Local-Text-No + int nice; // Garb-Nice + + void create(string|array ...args) + { + name=args[0]; // HOLLERITH + type=ExtendedConfType(args[1]); // Extended-Conf-Type + highest_local_no=(int)args[2]; // Local-Text-No + nice=(int)args[3]; // Garb-Nice + } + + array encode() + { + return + ({ + H(name), // HOLLERITH + @B(@rows(type,extendedconftypenames)), // Extended-Conf-Type + highest_local_no, // Local-Text-No + nice, // Garb-Nice + }); + } +} + +class Person +{ + string username; // HOLLERITH + multiset(string) privileges; // Priv-Bits + multiset(string) flags; // Personal-Flags + LysKOMTime last_login; // Time + int user_area; // Text-No + int total_time_present; // INT32 + int sessions; // INT32 + int created_lines; // INT32 + int created_bytes; // INT32 + int read_texts; // INT32 + int no_of_text_fetches; // INT32 + int(0..65535) created_persons; // INT16 + int(0..65535) created_confs; // INT16 + int first_created_local_no; // INT32 + int no_of_created_texts; // INT32 + int(0..65535) no_of_marks; // INT16 + int(0..65535) no_of_confs; // INT16 + + void create(string|array ...args) + { + username=args[0]; // HOLLERITH + privileges=PrivBits(args[1]); // Priv-Bits + flags=PersonalFlags(args[2]); // Personal-Flags + last_login=LysKOMTime(@args[3..11]); // Time + user_area=(int)args[12]; // Text-No + total_time_present=(int)args[13]; // INT32 + sessions=(int)args[14]; // INT32 + created_lines=(int)args[15]; // INT32 + created_bytes=(int)args[16]; // INT32 + read_texts=(int)args[17]; // INT32 + no_of_text_fetches=(int)args[18]; // INT32 + created_persons=(int)args[19]; // INT16 + created_confs=(int)args[20]; // INT16 + first_created_local_no=(int)args[21]; // INT32 + no_of_created_texts=(int)args[22]; // INT32 + no_of_marks=(int)args[23]; // INT16 + no_of_confs=(int)args[24]; // INT16 + } + + array encode() + { + return + ({ + H(username), // HOLLERITH + @B(@rows(privileges,privbitsnames)), // Priv-Bits + @B(@rows(flags,personalflagsnames)), // Personal-Flags + @last_login->encode(), // Time + user_area, // Text-No + total_time_present, // INT32 + sessions, // INT32 + created_lines, // INT32 + created_bytes, // INT32 + read_texts, // INT32 + no_of_text_fetches, // INT32 + created_persons, // INT16 + created_confs, // INT16 + first_created_local_no, // INT32 + no_of_created_texts, // INT32 + no_of_marks, // INT16 + no_of_confs, // INT16 + }); + } +} + + diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/Raw.pike b/lib/modules/Protocols.pmod/LysKOM.pmod/Raw.pike new file mode 100644 index 0000000000..ce776491c9 --- /dev/null +++ b/lib/modules/Protocols.pmod/LysKOM.pmod/Raw.pike @@ -0,0 +1,453 @@ +import .Helper; + +/* debug */ +// function f=lambda() +// { +// call_out(f,0.5); + +// if (!con) +// return; + +// if (con->query_read_callback()!=recv) +// werror("no read callback\n"); + +// werror("asyncs: %4d queue: %4d out: %4d\n", +// sizeof(indices(async)), +// sizeof(sendqueue), +// out_req); +// }; +// mixed g=f(); + +//---------------- raw protocol -------------------------- + +/* connection object */ +object con; + +/* recieve buffer */ +string buf=""; + +/* outstanding calls */ +mapping(int:function(string:void)) async=([]); +int ref=1; + +/* asynchronous messages callback list */ +mapping(int:function(string:void)) async_callbacks=([]); + +/* max number of outstanding requests */ +int max_out_req=4; + +/* queue of send-objects */ +array(object) sendqueue=({}); + +/* outstanding requests */ +int out_req; + + +/*--- send/recv ------------------------ */ + +static inline int conwrite(string what) +{ +#ifdef LYSKOM_DEBUG + werror("-> %O\n",what); +#endif + int i=con->write(what)==strlen(what); + if (!i) { werror("write failed!!!\n"); _exit(1); } + return i; +} + +class Send +{ + int ref; + string request; + function(string:void) callback; + + void create(int rf,string r,function(string:void) c) + { + ref=rf; + request=r; + callback=c; + } + int cast(string i) { return ref; } + void write() + { + out_req++; + conwrite(ref+" "+request+"\r\n"); + async[ref]=callback; + } +} + +int send(string request, + function(string:void) callback) +{ + int r=++ref; + sendqueue+=({Send(r,request,callback)}); + flush_queue(); + return r; +} + +void flush_queue() +{ + while (sizeof(sendqueue) && out_req<max_out_req) + { + sendqueue[0]->write(); + sendqueue=sendqueue[1..]; + } +} + +mixed send_sync(string request) +{ + return sync_do(++ref,request); +} + +mixed sync_do(int ref,string|void request) +{ + mixed err; + string s; + array res; + + con->set_blocking(); + if (request) + { + if (!conwrite(ref+" "+request+"\r\n")) + { + connection_lost(); + return lyskom_error(CONNECTION_CLOSED); + } + out_req++; + } + else + { + array(int) o=(array(int))sendqueue; + int j=search(o,ref); + if (j==-1) + { + if (!async[ref]) + error("request ref %d not in queue, but no callback\n",ref); + m_delete(async,ref); + } + else + { + sendqueue[j]->write(); + sendqueue=sendqueue[..j-1]+sendqueue[j+1..]; + } + } + + for (;;) + { + s=con->read(0x7fffffff,1); + if (s=="") + { + con->set_nonblocking(recv,0,0); + connection_lost(); + return lyskom_error(CONNECTION_CLOSED); + } + err=catch { res=recv(0,s,ref); }; + if (err) + { + con->set_nonblocking(recv,0,0); + throw(err); + } + if (res) break; + } + + con->set_nonblocking(recv,0,0); + + return res; +} + +void|array|object recv(mixed x,string what,void|int syn) +{ +#ifdef LYSKOM_DEBUG + werror("<- %O\n",what); +#endif +// werror("<- (%d bytes) (%d asyncs left)\n",sizeof(what), +// sizeof(indices(async))); + + array|object ires=0; + buf+=what; + // wait for newline before we do anything at all + while (search(buf,"\n")!=-1) + { + mixed res; + int len; + // ok, try to figure out what we got + switch (buf[0]) + { + case ':': + [res,len]=try_parse(buf[1..]); + if (res) + { + buf=buf[len+1..]; + if (ref) + call_out(got_async_message,0,res); + else + got_async_message(res); + break; + } + return; + + case '=': + [res,len]=try_parse(buf[1..]); + if (res) + { + buf=buf[len+1..]; + if (syn && (int)res[0] == syn) + { + ires=res[1..]; // this is what we wait for + out_req--; + break; + } + if (ref) + call_out(got_reply,0,(int)res[0],res[1..]); + else + got_reply((int)res[0],res[1..]); + out_req--; + flush_queue(); + break; + } + return; + + case '%': + sscanf(buf,"%s\n%s",res,buf); + int ref,no,status; + if (sscanf(res,"%%%d %d %d",ref,no,status)==3) + { + if (ref==syn) + { + ires=lyskom_error(no,status); + out_req--; + break; + } + if (ref) + call_out(got_reply,0,ref,lyskom_error(no,status)); + else + got_reply(ref,lyskom_error(no,status)); + out_req--; + flush_queue(); + } + else + { + werror("LysKOM.Raw: generic error recieved: %O\n",res); + } + break; + + default: + werror("LysKOM.Raw: protocol error: %O\n",buf); + connection_lost(); + return; + } + } + return ires; +} + +void connection_lost() +{ + werror("CONNECTION LOST\n"); + catch { con->close(); }; + con=0; + // send error to all outstanding requests + foreach (values(async),function f) + if (f) f(lyskom_error(CONNECTION_CLOSED)); +} + +void create(string server,void|int port,void|string whoami) +{ + mixed err; + + if (!port) port=4894; + con=Stdio.File(); + err=catch { + if (!con->connect(server,port)) + { + object err=LysKOMError(-1,strerror(con->errno())-"\n", + "Failed to connect to server " + +server+".\n"); + throw(err); + return; + } + }; + if (err) + { + if (objectp(err) && err->iserror) throw(err); + err=LysKOMError(-1,err[0]-"\n", + "Failed to connect to server " + +server+".\n"); + throw(err); + } + + + conwrite("A"+H(whoami|| +#if constant(getpwuid) && constant(getuid) + (getpwuid(getuid())||({"*unknown*"}))[0]+ +#else + "*unknown*" +#endif + "%" +#if constant(uname) + +uname()->nodename +#else + "*unknown*" +#endif + )); + string reply=con->read(7); +#ifdef LYSKOM_DEBUG + werror("<- %O\n",reply); +#endif + if (reply!="LysKOM\n") + { + con->close(); + con=0; + return; + } + con->set_nonblocking(recv,0,0); + return; +} + +void set_async_callbacks(mapping(int:function(string:void)) m) +{ + async_callbacks=m; +} + +array(array(mixed)|int) try_parse(string what) +{ + array res=({}); + int len=0; + + array stack=({}); + + while (strlen(what)>1) + { + string a,b; + + switch(what[0]) + { + case '0'..'9': + // int, bitfield or hollerith + + if (sscanf(what,"%[0-9]%s",a,b)<2 || + b=="") + return ({0,0}); // incomplete + + if (b[0]=='H') // hollerith + { + if (strlen(b)<=(int)a) + return ({0,0}); // incomplete + res+=({b[1..(int)a]}); + len+=strlen(a)+strlen(res[-1])+2; + b=b[(int)a+1..]; + } + else // bitfield or int + { + res+=({a}); + len+=strlen(a)+1; + } + + if (b=="") return ({0,0}); // incomplete + + switch (b[0]) + { + case ' ': // cont + break; + case '\n': // done +// werror("ret: len=%d %O\n",len,res); + return ({res,len}); + default: + werror("reached unknown: %O\n",b); + exit(-1); + } + + what=b[1..]; + + break; + + case '{': // array start; + if (what[..1]=="{ ") + { + stack=({res})+stack; + res=({}); + len+=2; + what=what[2..]; + break; + } + if (what[..1]!="{") + { + werror("reached unknown: %O\n",what); + exit(-1); + } + return ({0,0}); + + case '*': // empty array + res+=({({})}); + len+=2; + switch (what[1]) + { + case ' ': // cont + break; + case '\n': // done + return ({res,len}); + default: + werror("reached unknown: %O\n",b); + exit(-1); + } + what=what[2..]; + break; + + case '}': // array end; + + if (stack==({})) + { + werror("protocol error: stack underflow\n",what); + connection_lost(); + return ({0,0}); + } + + res=stack[0]+({res}); + stack=stack[1..]; + + len+=2; + + switch (what[1]) + { + case ' ': // cont + break; + case '\n': // done + return ({res,len}); + default: + werror("reached unknown: %O\n",b); + exit(-1); + } + + what=what[2..]; + break; + + default: + werror("reached unknown: %O\n",what); + exit(-1); + } + } + + return ({0,0}); // incomplete +} + +void got_async_message(array what) +{ + // werror("got async: %O\n",what); +} + +void got_reply(int ref,object|array what) +{ + function call=async[ref]; + if (!call) + { + werror("LysKOM.Raw: lost callback for call %d\n",ref); + werror(master()->describe_backtrace(backtrace())); + return; + } + m_delete(async,ref); + call_out(call,0,what); +} + +void delete_async(int ref) +{ + m_delete(async,ref); +} diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod b/lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod new file mode 100644 index 0000000000..66df35c90f --- /dev/null +++ b/lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod @@ -0,0 +1,2560 @@ +// $Id: Request.pmod,v 1.1 1999/06/12 23:01:50 mirar Exp $ +//! module Protocols +//! submodule LysKOM +//! submodule Request +//! This class contains nice abstraction for calls into the +//! server. They are named "<i>call</i>", +//! "<tt>async_</tt><i>call</i>" or +//! "<tt>async_cb_</tt><i>call</i>", depending on +//! how you want the call to be done. + +import .Helper; +import .ProtocolTypes; + +int _no=1; + +//! class _Request +//! This is the main request class. All lyskom request +//! classes inherits this class. +//! +//! method void async(mixed ...args) +//! method mixed sync(mixed ...args) +//! initialise an asynchronous or a synchronous call, +//! the latter is also evaluating the result. This calls +//! 'indata' in itself, to get the correct arguments to +//! the lyskom protocol call. +//! +//! method void _async(int call, mixed_data) +//! method mixed _sync(int call, mixed_data) +//! initialise an asynchronous or a synchronous call, +//! the latter is also evaluating the result. These +//! are called by async and sync respectively. +//! +//! method mixed _reply(object|array what) +//! method mixed reply(object|array what) +//! _reply is called as callback to evaluate the result, +//! and calls reply in itself to do the real work. +//! +//! method mixed `()() +//! wait for the call to finish. +//! +//! variable int ok +//! tells if the call is executed ok +//! variable object error +//! how the call failed +//! The call is completed if (ok||error). +//! + +class _Request +{ + private Stdio.File raw; + private int ref; + + private mixed res; + +#if constant(thread_create) + private object wait_lock; + private object wait_mutex; +#endif + + function callback; + + void _async(int call,mixed ... data) + { + ref=raw->send(encode(call,@data),_reply); + } + + mixed _sync(int call,mixed ... data) + { + mixed res=raw->send_sync(encode(call,@data),_reply); + return _reply(res); + } + + mixed _reply(object|array what) + { + if (objectp(what)) + { + error=what; + failure(what); + } + else + { + ok=1; + res=reply(what); + } +#if constant(thread_create) + if (wait_lock) + destruct(wait_lock); +#endif + if (callback) callback(error||res); + + return res; + } + + mixed reply(array what); // virtual + void failure(object err); // virtual + array indata(mixed ...); // virtual + +#if constant(thread_create) + mixed `()() // wait + { + if (ok || error) return res; + wait_mutex=Thread.Mutex(); + wait_lock=wait_mutex->lock(); // lock it + wait_lock=wait_mutex->lock(1); // lock it again, ie wait + return res; + } +#else + mixed `()() // wait + { + if (ok || error) return res; + mixed tmp=_reply(raw->sync_do(ref)); + return tmp; + } +#endif + + // public + + int(0..1) ok; + object error; + + void create(Stdio.File _raw) + { + raw=_raw; + } + + void async(mixed ...args) + { + _async(@indata(@args)); + } + + mixed sync(mixed ...args) + { + return _sync(@indata(@args)); + } +} + +// +// automatically generated requests +// + +/* 0 */ +class Login_old +{ + inherit _Request; + + array indata(int(0..65535) person, + string passwd) + { + return ({0, + person, + H(passwd)}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 1 */ +class Logout +{ + inherit _Request; + + array indata() + { + return ({1}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 2 */ +class Change_conference +{ + inherit _Request; + + array indata(int(0..65535) conference) + { + return ({2, + conference}); + } + + int(0..65535) reply(array what) + { + return what[0]; /* INT16 */ + } + + void failure(object error) + { + } +} + +/* 3 */ +class Change_name +{ + inherit _Request; + + array indata(int(0..65535) conference, + string new_name) + { + return ({3, + conference, + H(new_name)}); + } + + string reply(array what) + { + return what[0]; /* HOLLERITH */ + } + + void failure(object error) + { + } +} + +/* 4 */ +class Change_what_i_am_doing +{ + inherit _Request; + + array indata(string what_am_i_doing) + { + return ({4, + H(what_am_i_doing)}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 5 */ +class Create_person_old +{ + inherit _Request; + + array indata(string name, + string passwd) + { + return ({5, + H(name), + H(passwd)}); + } + + string reply(array what) + { + return what[0]; /* HOLLERITH */ + } + + void failure(object error) + { + } +} + +/* 6 */ +class Get_person_stat_old +{ + inherit _Request; + + array indata(int(0..65535) person, + int mask) + { + return ({6, + person, + mask}); + } + + + Person person; + + Person reply(array what) + { + /* ( Person ) */ + return Person(@what); + } + + void failure(object error) + { + } +} + +/* 7 */ +class Set_priv_bits +{ + inherit _Request; + + array indata(int(0..65535) person, + multiset(string) privileges) + { + return ({7, + person, + @B(@rows(privileges,privbitsnames))}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 8 */ +class Set_passwd +{ + inherit _Request; + + array indata(int(0..65535) person, + string old_pwd, + string new_pwd) + { + return ({8, + person, + H(old_pwd), + H(new_pwd)}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 9 */ +class Query_read_texts_old +{ + inherit _Request; + + array indata(int(0..65535) person, + int(0..65535) conference) + { + return ({9, + person, + conference}); + } + + + MembershipOld membershipold; + + MembershipOld reply(array what) + { + /* ( Membership-Old ) */ + return MembershipOld(@what); + } + + void failure(object error) + { + } +} + +/* 10 */ +class Create_conf_old +{ + inherit _Request; + + array indata(string name, + multiset(string) type) + { + return ({10, + H(name), + @B(@rows(type,extendedconftypenames))}); + } + + int(0..65535) reply(array what) + { + return what[0]; /* Conf-No */ + } + + void failure(object error) + { + } +} + +/* 11 */ +class Delete_conf +{ + inherit _Request; + + array indata(int(0..65535) conf) + { + return ({11, + conf}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 12 */ +class Lookup_name +{ + inherit _Request; + + array indata(string name) + { + return ({12, + H(name)}); + } + + + ConfListArchaic conflistarchaic; + + ConfListArchaic reply(array what) + { + /* ( Conf-List-Archaic ) */ + return ConfListArchaic(@what); + } + + void failure(object error) + { + } +} + +/* 13 */ +class Get_conf_stat_older +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int mask) + { + return ({13, + conf_no, + mask}); + } + + + ConferenceOld conferenceold; + + ConferenceOld reply(array what) + { + /* ( Conference-Old ) */ + return ConferenceOld(@what); + } + + void failure(object error) + { + } +} + +/* 14 */ +class Add_member_old +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int(0..65535) pers_no, + int(0..255) priority, + int(0..65535) where) + { + return ({14, + conf_no, + pers_no, + priority, + where}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 15 */ +class Sub_member +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int(0..65535) pers_no) + { + return ({15, + conf_no, + pers_no}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 16 */ +class Set_presentation +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int text_no) + { + return ({16, + conf_no, + text_no}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 17 */ +class Set_etc_motd +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int text_no) + { + return ({17, + conf_no, + text_no}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 18 */ +class Set_supervisor +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int(0..65535) admin) + { + return ({18, + conf_no, + admin}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 19 */ +class Set_permitted_submitters +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int(0..65535) perm_sub) + { + return ({19, + conf_no, + perm_sub}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 20 */ +class Set_super_conf +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int(0..65535) super_conf) + { + return ({20, + conf_no, + super_conf}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 21 */ +class Set_conf_type +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + multiset(string) type) + { + return ({21, + conf_no, + @B(@rows(type,extendedconftypenames))}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 22 */ +class Set_garb_nice +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int nice) + { + return ({22, + conf_no, + nice}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 23 */ +class Get_marks +{ + inherit _Request; + + array indata() + { + return ({23}); + } + + + array(Mark) marks; + + array(Mark) reply(array what) + { + /* ( ARRAY Mark ) */ + return marks=Array.map(what[1]/2, + lambda(array z) { return Mark(@z); }); + } + + void failure(object error) + { + } +} + +/* 24 */ +class Mark_text_old +{ + inherit _Request; + + array indata(int text, + int(0..255) mark_type) + { + return ({24, + text, + mark_type}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 25 */ +class Get_text +{ + inherit _Request; + + array indata(int text, + int start_char, + int end_char) + { + return ({25, + text, + start_char, + end_char}); + } + + string reply(array what) + { + return what[0]; /* HOLLERITH */ + } + + void failure(object error) + { + } +} + +/* 26 */ +class Get_text_stat_old +{ + inherit _Request; + + array indata(int text_no) + { + return ({26, + text_no}); + } + + + TextStatOld textstatold; + + TextStatOld reply(array what) + { + /* ( Text-Stat-Old ) */ + return TextStatOld(@what); + } + + void failure(object error) + { + } +} + +/* 27 */ +class Mark_as_read +{ + inherit _Request; + + array indata(int(0..65535) conference, + array(int) text) + { + return ({27, + conference, + @A((array(string))text)}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 28 */ +class Create_text_old +{ + inherit _Request; + + array indata(string text, + array(int) misc_info) + { + return ({28, + H(text), + @A((array(string))misc_info)}); + } + + int reply(array what) + { + return what[0]; /* Text-No */ + } + + void failure(object error) + { + } +} + +/* 29 */ +class Delete_text +{ + inherit _Request; + + array indata(int text) + { + return ({29, + text}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 30 */ +class Add_recipient +{ + inherit _Request; + + array indata(int text_no, + int(0..65535) conf_no, + int recpt_type) + { + return ({30, + text_no, + conf_no, + recpt_type}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 31 */ +class Sub_recipient +{ + inherit _Request; + + array indata(int text_no, + int(0..65535) conf_no) + { + return ({31, + text_no, + conf_no}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 32 */ +class Add_comment +{ + inherit _Request; + + array indata(int text_no, + int comment_to) + { + return ({32, + text_no, + comment_to}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 33 */ +class Sub_comment +{ + inherit _Request; + + array indata(int text_no, + int comment_to) + { + return ({33, + text_no, + comment_to}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 34 */ +class Get_map +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int first_local_no, + int no_of_texts) + { + return ({34, + conf_no, + first_local_no, + no_of_texts}); + } + + + TextList textlist; + + TextList reply(array what) + { + /* ( Text-List ) */ + return TextList(@what); + } + + void failure(object error) + { + } +} + +/* 35 */ +class Get_time +{ + inherit _Request; + + array indata() + { + return ({35}); + } + + + LysKOMTime lyskomtime; + + LysKOMTime reply(array what) + { + /* ( Time ) */ + return LysKOMTime(@what); + } + + void failure(object error) + { + } +} + +/* 36 */ +class Get_info_old +{ + inherit _Request; + + array indata() + { + return ({36}); + } + + + InfoOld infoold; + + InfoOld reply(array what) + { + /* ( Info-Old ) */ + return InfoOld(@what); + } + + void failure(object error) + { + } +} + +/* 37 */ +class Add_footnote +{ + inherit _Request; + + array indata(int text_no) + { + return ({37, + text_no}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 38 */ +class Sub_footnote +{ + inherit _Request; + + array indata(int text_no, + int footnote_to) + { + return ({38, + text_no, + footnote_to}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 39 */ +class Who_is_on_old +{ + inherit _Request; + + array indata() + { + return ({39}); + } + + + array(WhoInfoOld) whoinfoolds; + + array(WhoInfoOld) reply(array what) + { + /* ( ARRAY Who-Info-Old ) */ + return whoinfoolds=Array.map(what[1]/3, + lambda(array z) { return WhoInfoOld(@z); }); + } + + void failure(object error) + { + } +} + +/* 40 */ +class Set_unread +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int no_of_unread) + { + return ({40, + conf_no, + no_of_unread}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 41 */ +class Set_motd_of_lyskom +{ + inherit _Request; + + array indata(int text_no) + { + return ({41, + text_no}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 42 */ +class Enable +{ + inherit _Request; + + array indata(int(0..255) level) + { + return ({42, + level}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 43 */ +class Sync_kom +{ + inherit _Request; + + array indata() + { + return ({43}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 44 */ +class Shutdown_kom +{ + inherit _Request; + + array indata(int(0..255) exit_val) + { + return ({44, + exit_val}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 45 */ +class Broadcast +{ + inherit _Request; + + array indata(string message) + { + return ({45, + H(message)}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 46 */ +class Get_membership_old +{ + inherit _Request; + + array indata(int(0..65535) person, + int(0..65535) first, + int(0..65535) no_of_confs, + int(0..1) want_read_texts) + { + return ({46, + person, + first, + no_of_confs, + B(want_read_texts)}); + } + + + array(MembershipOld) membershipolds; + + array(MembershipOld) reply(array what) + { + /* ( ARRAY Membership-Old ) */ + return membershipolds=Array.map(what[1]/14, + lambda(array z) { return MembershipOld(@z); }); + } + + void failure(object error) + { + } +} + +/* 47 */ +class Get_created_texts +{ + inherit _Request; + + array indata(int(0..65535) person, + int first, + int no_of_texts) + { + return ({47, + person, + first, + no_of_texts}); + } + + + TextList textlist; + + TextList reply(array what) + { + /* ( Text-List ) */ + return TextList(@what); + } + + void failure(object error) + { + } +} + +/* 48 */ +class Get_members_old +{ + inherit _Request; + + array indata(int(0..65535) conf, + int(0..65535) first, + int(0..65535) no_of_members) + { + return ({48, + conf, + first, + no_of_members}); + } + + array(int(0..65535)) persnos; + + array(int(0..65535)) reply(array what) + { + /* ( ARRAY Pers-No ) */ + return (array(int(0..65535)))what[1]; + } + + void failure(object error) + { + } +} + +/* 49 */ +class Get_person_stat +{ + inherit _Request; + + array indata(int(0..65535) pers_no) + { + return ({49, + pers_no}); + } + + + Person person; + + Person reply(array what) + { + /* ( Person ) */ + return Person(@what); + } + + void failure(object error) + { + } +} + +/* 50 */ +class Get_conf_stat_old +{ + inherit _Request; + + array indata(int(0..65535) conf_no) + { + return ({50, + conf_no}); + } + + + ConferenceOld conferenceold; + + ConferenceOld reply(array what) + { + /* ( Conference-Old ) */ + return ConferenceOld(@what); + } + + void failure(object error) + { + } +} + +/* 51 */ +class Who_is_on +{ + inherit _Request; + + array indata() + { + return ({51}); + } + + + array(WhoInfo) whoinfos; + + array(WhoInfo) reply(array what) + { + /* ( ARRAY Who-Info ) */ + return whoinfos=Array.map(what[1]/5, + lambda(array z) { return WhoInfo(@z); }); + } + + void failure(object error) + { + } +} + +/* 52 */ +class Get_unread_confs +{ + inherit _Request; + + array indata(int(0..65535) pers_no) + { + return ({52, + pers_no}); + } + + array(int(0..65535)) confnos; + + array(int(0..65535)) reply(array what) + { + /* ( ARRAY Conf-No ) */ + return (array(int(0..65535)))what[1]; + } + + void failure(object error) + { + } +} + +/* 53 */ +class Send_message +{ + inherit _Request; + + array indata(int(0..65535) recipient, + string message) + { + return ({53, + recipient, + H(message)}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 58 */ +class Get_last_text +{ + inherit _Request; + + array indata(LysKOMTime before) + { + return ({58, + @before->encode()}); + } + + int reply(array what) + { + return what[0]; /* Text-No */ + } + + void failure(object error) + { + } +} + +/* 59 */ +class Create_anonymous_text_old +{ + inherit _Request; + + array indata(string text, + array(int) misc_info) + { + return ({59, + H(text), + @A((array(string))misc_info)}); + } + + int reply(array what) + { + return what[0]; /* Text-No */ + } + + void failure(object error) + { + } +} + +/* 60 */ +class Find_next_text_no +{ + inherit _Request; + + array indata(int start) + { + return ({60, + start}); + } + + int reply(array what) + { + return what[0]; /* Text-No */ + } + + void failure(object error) + { + } +} + +/* 61 */ +class Find_previous_text_no +{ + inherit _Request; + + array indata(int start) + { + return ({61, + start}); + } + + int reply(array what) + { + return what[0]; /* Text-No */ + } + + void failure(object error) + { + } +} + +/* 62 */ +class Login +{ + inherit _Request; + + array indata(int(0..65535) person, + string passwd, + int(0..1) is_invisible) + { + return ({62, + person, + H(passwd), + B(is_invisible)}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 63 */ +class Who_is_on_ident +{ + inherit _Request; + + array indata() + { + return ({63}); + } + + + array(WhoInfoIdent) whoinfoidents; + + array(WhoInfoIdent) reply(array what) + { + /* ( ARRAY Who-Info-Ident ) */ + return whoinfoidents=Array.map(what[1]/7, + lambda(array z) { return WhoInfoIdent(@z); }); + } + + void failure(object error) + { + } +} + +/* 64 */ +class Get_session_info_ident +{ + inherit _Request; + + array indata(int session_no) + { + return ({64, + session_no}); + } + + + SessionInfoIdent sessioninfoident; + + SessionInfoIdent reply(array what) + { + /* ( Session-Info-Ident ) */ + return SessionInfoIdent(@what); + } + + void failure(object error) + { + } +} + +/* 65 */ +class Re_lookup_person +{ + inherit _Request; + + array indata(string regexp) + { + return ({65, + H(regexp)}); + } + + array(int(0..65535)) persnos; + + array(int(0..65535)) reply(array what) + { + /* ( ARRAY Pers-No ) */ + return (array(int(0..65535)))what[1]; + } + + void failure(object error) + { + } +} + +/* 66 */ +class Re_lookup_conf +{ + inherit _Request; + + array indata(string regexp) + { + return ({66, + H(regexp)}); + } + + array(int(0..65535)) confnos; + + array(int(0..65535)) reply(array what) + { + /* ( ARRAY Conf-No ) */ + return (array(int(0..65535)))what[1]; + } + + void failure(object error) + { + } +} + +/* 67 */ +class Lookup_person +{ + inherit _Request; + + array indata(string name) + { + return ({67, + H(name)}); + } + + array(int(0..65535)) persnos; + + array(int(0..65535)) reply(array what) + { + /* ( ARRAY Pers-No ) */ + return (array(int(0..65535)))what[1]; + } + + void failure(object error) + { + } +} + +/* 68 */ +class Lookup_conf +{ + inherit _Request; + + array indata(string name) + { + return ({68, + H(name)}); + } + + array(int(0..65535)) confnos; + + array(int(0..65535)) reply(array what) + { + /* ( ARRAY Conf-No ) */ + return (array(int(0..65535)))what[1]; + } + + void failure(object error) + { + } +} + +/* 69 */ +class Set_client_version +{ + inherit _Request; + + array indata(string client_name, + string client_version) + { + return ({69, + H(client_name), + H(client_version)}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 70 */ +class Get_client_name +{ + inherit _Request; + + array indata(int session) + { + return ({70, + session}); + } + + string reply(array what) + { + return what[0]; /* HOLLERITH */ + } + + void failure(object error) + { + } +} + +/* 71 */ +class Get_client_version +{ + inherit _Request; + + array indata(int session) + { + return ({71, + session}); + } + + string reply(array what) + { + return what[0]; /* HOLLERITH */ + } + + void failure(object error) + { + } +} + +/* 72 */ +class Mark_text +{ + inherit _Request; + + array indata(int text, + int(0..255) mark_type) + { + return ({72, + text, + mark_type}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 73 */ +class Unmark_text +{ + inherit _Request; + + array indata(int text_no) + { + return ({73, + text_no}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 74 */ +class Re_z_lookup +{ + inherit _Request; + + array indata(string regexp, + int(0..1) want_persons, + int(0..1) want_confs) + { + return ({74, + H(regexp), + want_persons, + want_confs}); + } + + + array(ConfZInfo) confzinfos; + + array(ConfZInfo) reply(array what) + { + /* ( ARRAY Conf-Z-Info ) */ + return confzinfos=Array.map(what[1]/3, + lambda(array z) { return ConfZInfo(@z); }); + } + + void failure(object error) + { + } +} + +/* 75 */ +class Get_version_info +{ + inherit _Request; + + array indata() + { + return ({75}); + } + + + VersionInfo versioninfo; + + VersionInfo reply(array what) + { + /* ( Version-Info ) */ + return VersionInfo(@what); + } + + void failure(object error) + { + } +} + +/* 76 */ +class Lookup_z_name +{ + inherit _Request; + + array indata(string name, + int(0..1) want_pers, + int(0..1) want_confs) + { + return ({76, + H(name), + want_pers, + want_confs}); + } + + + array(ConfZInfo) confzinfos; + + array(ConfZInfo) reply(array what) + { + /* ( ARRAY Conf-Z-Info ) */ + return confzinfos=Array.map(what[1]/3, + lambda(array z) { return ConfZInfo(@z); }); + } + + void failure(object error) + { + } +} + +/* 77 */ +class Set_last_read +{ + inherit _Request; + + array indata(int(0..65535) conference, + int last_read) + { + return ({77, + conference, + last_read}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 78 */ +class Get_uconf_stat +{ + inherit _Request; + + array indata(int(0..65535) conference) + { + return ({78, + conference}); + } + + + UConference uconference; + + UConference reply(array what) + { + /* ( UConference ) */ + return UConference(@what); + } + + void failure(object error) + { + } +} + +/* 79 */ +class Set_info +{ + inherit _Request; + + array indata(InfoOld info) + { + return ({79, + @info->encode()}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 80 */ +class Accept_async +{ + inherit _Request; + + array indata(array(int) request_list) + { + return ({80, + @A((array(string))request_list)}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 81 */ +class Query_async +{ + inherit _Request; + + array indata() + { + return ({81}); + } + + array(int) reply(array what) + { + return what[0]; /* ARRAY INT32 */ + } + + void failure(object error) + { + } +} + +/* 82 */ +class User_active +{ + inherit _Request; + + array indata() + { + return ({82}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 83 */ +class Who_is_on_dynamic +{ + inherit _Request; + + array indata(int(0..1) want_visible, + int(0..1) want_invisible, + int active_last) + { + return ({83, + want_visible, + want_invisible, + active_last}); + } + + + array(DynamicSessionInfo) dynamicsessioninfos; + + array(DynamicSessionInfo) reply(array what) + { + /* ( ARRAY Dynamic-Session-Info ) */ + return dynamicsessioninfos=Array.map(what[1]/6, + lambda(array z) { return DynamicSessionInfo(@z); }); + } + + void failure(object error) + { + } +} + +/* 84 */ +class Get_static_session_info +{ + inherit _Request; + + array indata(int session_no) + { + return ({84, + session_no}); + } + + + StaticSessionInfo staticsessioninfo; + + StaticSessionInfo reply(array what) + { + /* ( Static-Session-Info ) */ + return StaticSessionInfo(@what); + } + + void failure(object error) + { + } +} + +/* 85 */ +class Get_collate_table +{ + inherit _Request; + + array indata() + { + return ({85}); + } + + string reply(array what) + { + return what[0]; /* HOLLERITH */ + } + + void failure(object error) + { + } +} + +/* 86 */ +class Create_text +{ + inherit _Request; + + array indata(string text, + array(int) misc_info, + array(AuxItemInput) aux_items) + { + return ({86, + H(text), + @A((array(string))misc_info), + @A(`+(@Array.map(aux_items, + lambda(AuxItemInput z) + { return z->encode(); })))}); + } + + int reply(array what) + { + return what[0]; /* Text-No */ + } + + void failure(object error) + { + } +} + +/* 87 */ +class Create_anonymous_text +{ + inherit _Request; + + array indata(string text, + array(int) misc_info, + array(AuxItemInput) aux_items) + { + return ({87, + H(text), + @A((array(string))misc_info), + @A(`+(@Array.map(aux_items, + lambda(AuxItemInput z) + { return z->encode(); })))}); + } + + int reply(array what) + { + return what[0]; /* Text-No */ + } + + void failure(object error) + { + } +} + +/* 88 */ +class Create_conf +{ + inherit _Request; + + array indata(string name, + multiset(string) type, + array(AuxItemInput) aux_items) + { + return ({88, + H(name), + @B(@rows(type,extendedconftypenames)), + @A(`+(@Array.map(aux_items, + lambda(AuxItemInput z) + { return z->encode(); })))}); + } + + int(0..65535) reply(array what) + { + return what[0]; /* Conf-No */ + } + + void failure(object error) + { + } +} + +/* 89 */ +class Create_person +{ + inherit _Request; + + array indata(string name, + string passwd, + array(AuxItemInput) aux_items) + { + return ({89, + H(name), + H(passwd), + @A(`+(@Array.map(aux_items, + lambda(AuxItemInput z) + { return z->encode(); })))}); + } + + int(0..65535) reply(array what) + { + return what[0]; /* Pers-No */ + } + + void failure(object error) + { + } +} + +/* 90 */ +class Get_text_stat +{ + inherit _Request; + + array indata(int text_no) + { + return ({90, + text_no}); + } + + + TextStat textstat; + + TextStat reply(array what) + { + /* ( Text-Stat ) */ + return TextStat(@what); + } + + void failure(object error) + { + } +} + +/* 91 */ +class Get_conf_stat +{ + inherit _Request; + + array indata(int(0..65535) conf_no) + { + return ({91, + conf_no}); + } + + + Conference conference; + + Conference reply(array what) + { + /* ( Conference ) */ + return Conference(@what); + } + + void failure(object error) + { + } +} + +/* 92 */ +class Modify_text_info +{ + inherit _Request; + + array indata(int text, + array(int) delete, + array(AuxItemInput) add) + { + return ({92, + text, + @A((array(string))delete), + @A(`+(@Array.map(add, + lambda(AuxItemInput z) + { return z->encode(); })))}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 93 */ +class Modify_conf_info +{ + inherit _Request; + + array indata(int(0..65535) conf, + array(int) delete, + array(AuxItemInput) add) + { + return ({93, + conf, + @A((array(string))delete), + @A(`+(@Array.map(add, + lambda(AuxItemInput z) + { return z->encode(); })))}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 94 */ +class Get_info +{ + inherit _Request; + + array indata() + { + return ({94}); + } + + + Info info; + + Info reply(array what) + { + /* ( Info ) */ + return Info(@what); + } + + void failure(object error) + { + } +} + +/* 95 */ +class Modify_system_info +{ + inherit _Request; + + array indata(array(int) items_to_delete, + array(AuxItemInput) items_to_add) + { + return ({95, + @A((array(string))items_to_delete), + @A(`+(@Array.map(items_to_add, + lambda(AuxItemInput z) + { return z->encode(); })))}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 96 */ +class Query_predefined_aux_items +{ + inherit _Request; + + array indata() + { + return ({96}); + } + + array(int) reply(array what) + { + return what[0]; /* ARRAY INT32 */ + } + + void failure(object error) + { + } +} + +/* 97 */ +class Set_expire +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int expire) + { + return ({97, + conf_no, + expire}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 98 */ +class Query_read_texts +{ + inherit _Request; + + array indata(int(0..65535) person, + int(0..65535) conference) + { + return ({98, + person, + conference}); + } + + + Membership membership; + + Membership reply(array what) + { + /* ( Membership ) */ + return Membership(@what); + } + + void failure(object error) + { + } +} + +/* 99 */ +class Get_membership +{ + inherit _Request; + + array indata(int(0..65535) person, + int(0..65535) first, + int(0..65535) no_of_confs, + int(0..1) want_read_texts) + { + return ({99, + person, + first, + no_of_confs, + B(want_read_texts)}); + } + + + array(Membership) memberships; + + array(Membership) reply(array what) + { + /* ( ARRAY Membership ) */ + return memberships=Array.map(what[1]/26, + lambda(array z) { return Membership(@z); }); + } + + void failure(object error) + { + } +} + +/* 100 */ +class Add_member +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int(0..65535) pers_no, + int(0..255) priority, + int(0..65535) where, + multiset(string) type) + { + return ({100, + conf_no, + pers_no, + priority, + where, + @B(@rows(type,membershiptypenames))}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 101 */ +class Get_members +{ + inherit _Request; + + array indata(int(0..65535) conf, + int(0..65535) first, + int(0..65535) no_of_members) + { + return ({101, + conf, + first, + no_of_members}); + } + + + array(Member) members; + + array(Member) reply(array what) + { + /* ( ARRAY Member ) */ + return members=Array.map(what[1]/12, + lambda(array z) { return Member(@z); }); + } + + void failure(object error) + { + } +} + +/* 102 */ +class Set_membership_type +{ + inherit _Request; + + array indata(int(0..65535) pers, + int(0..65535) conf, + multiset(string) type) + { + return ({102, + pers, + conf, + @B(@rows(type,membershiptypenames))}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + +/* 103 */ +class Local_to_global +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int first_local_no, + int no_of_existing_texts) + { + return ({103, + conf_no, + first_local_no, + no_of_existing_texts}); + } + + + TextMapping textmapping; + + TextMapping reply(array what) + { + /* ( Text-Mapping ) */ + return TextMapping(@what); + } + + void failure(object error) + { + } +} + +/* 104 */ +class Map_created_texts +{ + inherit _Request; + + array indata(int(0..65535) author, + int first_local_no, + int no_of_existing_texts) + { + return ({104, + author, + first_local_no, + no_of_existing_texts}); + } + + + TextMapping textmapping; + + TextMapping reply(array what) + { + /* ( Text-Mapping ) */ + return TextMapping(@what); + } + + void failure(object error) + { + } +} + +/* 105 */ +class Set_keep_commented +{ + inherit _Request; + + array indata(int(0..65535) conf_no, + int keep_commented) + { + return ({105, + conf_no, + keep_commented}); + } + + void reply(array what) + { + } + + void failure(object error) + { + } +} + diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike b/lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike new file mode 100644 index 0000000000..11b6aea087 --- /dev/null +++ b/lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike @@ -0,0 +1,599 @@ +// $Id: Session.pike,v 1.1 1999/06/12 23:01:50 mirar Exp $ +//! module Protocols +//! submodule LysKOM +//! class Session + +import "."; + +Connection con; + +//! variable user +//! This variable contains the +//! <link to=Protocols.LysKOM.Session.Person>person</link> +//! that are logged in. + +object user; // logged in as this Person + +string server; + +int oldlevel; // level <10 protocol + +mapping(int:object) _text=([]); +mapping(int:object) _person=([]); +mapping(int:object) _conference=([]); + +//! method void create(string server) +//! method void create(string server,mapping options) +//! Initializes the session object, and opens +//! a connection to that server. +//! +//! options is a mapping of options, +//! <pre> +//! "login" : int|string - login as this person number +//! (get number from name) +//! "password" : string - send this login password +//! "invisible" : int(0..1) - login invisible +//! +//! advanced: +//! "port" : int - server port (default is 4894) +//! "whoami" : string - user name (default is from uid) +//! </pre> +//! +//! see also: Connection + +void create(object|string _server,void|mapping options) +{ + if (objectp(_server)) // clone + { + con = _server->con; + server = _server->server; + oldlevel = _server->oldlevel; + user = _server->user; + _person = _server->_person; + _conference= _server->_conference; + _text = _server->_text; + return; + } + server=_server; + con=Connection(_server,options); + user=(options && options->login)?person(options->login):0; +} + + +class MiscInfo +{ + class Recpt + { + object conf; + int local_no; + object received_at; + object sent_by; + object sent_at; + } + array(Recpt) recpt=({}); + array(Recpt) ccrecpt=({}); + array(Recpt) bccrecpt=({}); + + array(object) comm_to=({}); + array(object) comm_in=({}); + array(object) foot_to=({}); + array(object) foot_in=({}); + + void create(array(int) a) + { + int i; + object r; + for (i=0; i<sizeof(a);) + { + switch (a[i++]) + { + case 0: recpt+=({r=Recpt()}); r->conf=conference(a[i++]); break; + case 1: ccrecpt+=({r=Recpt()}); + r->conf=conference(a[i++]); break; + case 15: bccrecpt+=({r=Recpt()}); + r->conf=conference(a[i++]); break; + + case 2: comm_to+=({text(a[i++])}); break; + case 3: comm_in+=({text(a[i++])}); break; + case 4: foot_to+=({text(a[i++])}); break; + case 5: foot_in+=({text(a[i++])}); break; + + case 6: r->local_no=a[i++]; break; + case 7: r->received_at=ProtocolTypes.LysKOMTime(@a[i..i+8]); + i+=9; break; + case 8: r->sent_by=person(a[i++]); break; + case 9: r->sent_at=ProtocolTypes.LysKOMTime(@a[i..i+8]); + i+=9; break; + default: + error("unexpected selection in misc_info: %d\n",a[i-1]); + } + } + } +} + +#define FETCHERC(WHAT,TYPE,VAR,CALL,ARGS,CONV) \ + TYPE VAR; \ + private object fetch_##WHAT; \ + private array(function) fetch_##WHAT##_callbacks=({}); \ + \ + void prefetch_##WHAT##(void|function callback) \ + { \ + if (VAR) \ + { \ + if (callback) callback(this_object()); \ + return; \ + } \ + if (callback) fetch_##WHAT##_callbacks+=({callback}); \ + if (!fetch_##WHAT) \ + fetch_##WHAT= \ + con->async_cb_##CALL(lambda(mixed res) \ + { \ + if (objectp(res) && res->iserror) \ + err=res; \ + else \ + VAR=CONV; \ + fetch_##WHAT=0; \ + array m=fetch_##WHAT##_callbacks; \ + fetch_##WHAT##_callbacks=0; \ + m(this_object()); \ + },ARGS); \ + } \ + \ + inline void need_##WHAT() \ + { \ + if (VAR) return; \ + if (!fetch_##WHAT) prefetch_##WHAT(); \ + if (fetch_##WHAT) fetch_##WHAT(); \ + } +#define FETCHER(WHAT,TYPE,VAR,CALL,ARGS) \ + FETCHERC(WHAT,TYPE,VAR,CALL,ARGS,res) + +#define FETCHER2(WHAT,TYPE1,VAR1,TYPE2,VAR2,CALL1,CALL2,ARGS) \ + TYPE1 VAR1; \ + TYPE2 VAR2; \ + private object fetch_##WHAT; \ + private array(function) fetch_##WHAT##_callbacks=({}); \ + \ + private void _got_##WHAT##1(mixed res) \ + { \ + if (objectp(res) && res->iserror) \ + { \ + if (res->no==2) \ + { \ + oldlevel=1; \ + fetch_##WHAT=con->async_cb_##CALL2(_got_##WHAT##2,ARGS); \ + } \ + err=res; \ + } \ + else \ + VAR1=res; \ + array m=fetch_##WHAT##_callbacks; \ + fetch_##WHAT##_callbacks=({}); \ + m(this_object()); \ + } \ + \ + private void _got_##WHAT##2(mixed res) \ + { \ + if (objectp(res) && res->iserror) err=res; else VAR2=res; \ + array m=fetch_##WHAT##_callbacks; \ + fetch_##WHAT##_callbacks=({}); \ + m(this_object()); \ + } \ + \ + object prefetch_##WHAT##(void|function callback) \ + { \ + if (VAR1 || VAR2) \ + { \ + if (callback) callback(this_object()); \ + return this_object(); \ + } \ + if (callback) fetch_##WHAT##_callbacks+=({callback}); \ + if (!fetch_##WHAT) \ + if (oldlevel) \ + fetch_##WHAT=con->async_cb_##CALL2(_got_##WHAT##2,ARGS); \ + else \ + fetch_##WHAT=con->async_cb_##CALL1(_got_##WHAT##1,ARGS); \ + return this_object(); \ + } \ + \ + inline void need_##WHAT() \ + { \ + if (VAR1 || VAR2) return; \ + if (!fetch_##WHAT) prefetch_##WHAT(); \ + if (fetch_##WHAT) fetch_##WHAT(); \ + if (fetch_##WHAT) fetch_##WHAT(); \ + } + +#define FETCHERC2b(WHAT,TYPE,VAR,CALL,ARGS,CONV) \ + TYPE VAR; \ + private object fetch_##WHAT; \ + private array(function) fetch_##WHAT##_callbacks=({}); \ + \ + private void _got_##WHAT##1(mixed res) \ + { \ + if (objectp(res) && res->iserror) \ + { \ + if (res->no==2) \ + { \ + oldlevel=1; \ + fetch_##WHAT= \ + con->async_cb_##CALL##_old(_got_##WHAT##2,ARGS); \ + } \ + err=res; \ + } \ + else \ + VAR=CONV; \ + array m=fetch_##WHAT##_callbacks; \ + fetch_##WHAT##_callbacks=({}); \ + m(this_object()); \ + } \ + \ + private void _got_##WHAT##2(mixed res) \ + { \ + if (objectp(res) && res->iserror) err=res; \ + else VAR=CONV; \ + array m=fetch_##WHAT##_callbacks; \ + fetch_##WHAT##_callbacks=({}); \ + m(this_object()); \ + } \ + \ + object prefetch_##WHAT##(void|function callback) \ + { \ + if (VAR) \ + { \ + if (callback) callback(this_object()); \ + return this_object(); \ + } \ + if (callback) fetch_##WHAT##_callbacks+=({callback}); \ + if (!fetch_##WHAT) \ + if (oldlevel) \ + fetch_##WHAT=con->async_cb_##CALL##_old(_got_##WHAT##2,ARGS); \ + else \ + fetch_##WHAT=con->async_cb_##CALL(_got_##WHAT##1,ARGS); \ + return this_object(); \ + } \ + \ + inline void need_##WHAT() \ + { \ + if (VAR) return; \ + if (!fetch_##WHAT) prefetch_##WHAT(); \ + if (fetch_##WHAT) fetch_##WHAT(); \ + if (fetch_##WHAT) fetch_##WHAT(); \ + } + +class Text +{ + int no; + + MiscInfo _misc; + + object err; + + object _author; + + void create(int _no) + { + no=_no; + } + + FETCHERC(text,array(string),_text,get_text,@({no,0,0x7fffffff}), + array_sscanf(res,"%s\n%s")) + FETCHERC2b(stat,object,_stat,get_text_stat,@({no}), + (_misc=MiscInfo(res->misc_info),res)) + + mixed `[](string what) + { + switch (what) + { + case "create": + return create; + case "prefetch_text": + return prefetch_text; + case "prefetch_stat": + return prefetch_stat; + + case "no": + return no; + case "error": + return err; + + case "text": + need_text(); + return _text[1]; + + case "subject": + need_text(); + return _text[0]; + + case "author": + need_stat(); + return _author + || (_author=person(_stat->author)); + + case "misc": + need_stat(); + return _misc; + + case "lines": + need_text(); + return String.count(_text[1],"\n")+1; + + case "characters": + need_text(); + return strlen(_text[1]); + } + } + + mixed `->(string what) { return `[](what); } +} + + +object text(int no) +{ + return _text[no] || (_text[no]=Text(no)); +} + +class Membership +{ + int person; + int newtype; + object last_time_read; + int(0..255) priority; + int last_text_read; + array(int) read_texts; + int(0..65535) added_by; // new + object added_at; // new + multiset(string) type; // new + int position; // new + + object conf; + + void create(object mb,int pers) + { + person=pers; + + last_time_read=mb->last_time_read; + read_texts=mb->read_texts; + last_text_read=mb->last_text_read; + priority=mb->priority; + conf=conference(mb->conf_no); + + if (mb->type) + { + added_at=mb->added_at; + position=mb->position; + added_by=mb->added_by; + type=mb->type; + newtype=1; + } + } + + int number_unread() + { + return (conf->no_of_texts+conf->first_local_no-1) + -last_text_read -sizeof(read_texts); + } + + mixed `[](string what) + { + switch (what) + { + case "last_time_read": + case "read_texts": + case "last_text_read": + case "priority": + case "conf": + case "added_at": + case "position": + case "type": + case "number_unread": + return ::`[](what); + } + } +} + + +class Person +{ + int no; + + object conf; + + object err; + + FETCHER(stat,ProtocolTypes.Person,_person,get_person_stat,no); + FETCHERC(unread,array(object),_unread,get_unread_confs,no, + Array.map(res,conference)); + FETCHERC2b(membership,array(object),_membership,get_membership, + @({no,0,65535,1}), + Array.map(res,Membership,no)); + + void create(int _no) + { + no=_no; + conf=conference(no); + } + + mixed `[](string what) + { + switch (what) + { + case "create": + return create; + case "prefetch_stat": + return prefetch_stat; + case "prefetch_conf": + return conf->prefetch_stat; + case "prefetch_membership": + return prefetch_membership; + + case "no": + return no; + case "error": + return err; + case "user_area": + need_stat(); + return text(_person->user_area); + case "username": + case "privileges": + case "flags": + case "last_login": + case "total_time_present": + case "sessions": + case "created_lines": + case "created_bytes": + case "read_texts": + case "no_of_text_fetches": + case "created_persons": + case "created_confs": + case "first_created_local_no": + case "no_of_created_texts": + case "no_of_marks": + case "no_of_confs": + need_stat(); + return _person[what]; + case "unread": + need_unread(); + return _unread; + case "membership": + need_membership(); + return _membership; + } + + return conf[what]; + } + + mixed `->(string what) { return `[](what); } +} + +object person(int no) +{ + return _person[no] || (_person[no]=Person(no)); +} + +class Conference +{ + int no; + + private object err; + + FETCHER2(stat,ProtocolTypes.Conference,_conf, + ProtocolTypes.ConferenceOld,_confold, + get_conf_stat,get_conf_stat_old,no) + + void create(int _no) + { + no=_no; + } + + mixed `[](string what) + { + switch (what) + { + case "create": + return create; + case "prefetch_stat": + return prefetch_stat; + + case "no": + return no; + case "error": + return err; + + case "presentation": + case "msg_of_day": + need_stat(); + return text( (_conf||_confold)[what] ); + case "supervisor": + case "permitted_submitters": + case "super_conf": + need_stat(); + return conference( (_conf||_confold)[what] ); + case "creator": + need_stat(); + return person( (_conf||_confold)[what] ); + case "name": + case "type": + case "creation_time": + case "last_written": + case "nice": + case "no_of_members": + case "first_local_no": + case "no_of_texts": + need_stat(); + return (_conf||_confold)[what]; + } + } + + mixed `->(string what) { return `[](what); } +} + +object conference(int no) +{ + return _conference[no] || (_conference[no]=Conference(no)); +} + +//! +//! method array(object) try_complete_person(string orig) +//! Runs a LysKOM completion on the given string, +//! returning an array of confzinfos of the match. + +array(ProtocolTypes.ConfZInfo) try_complete_person(string orig) +{ + return con->lookup_z_name(orig,1,0); +} + +//! method login(int user_no,string password) +//! method login(int user_no,string password,int invisible) +//! Performs a login. Returns 1 on success or throws a lyskom error. + +int(1..1) login(int user_no,string password, + void|int invisible) +{ + con->login(user_no,password,invisible); + user=person(user_no); + return 1; +} + +//! method logout() +//! Logouts from the server. + +int(1..1) logout() +{ + if (con) + con->logout(); + return 1; +} + + +/* + +session->new_text(string subject, + string message, + void|object|array(object) mottagare, + void|object|array(object) comment_to, + void|object|array(object) footnote_to, + void|multiset flags); + +(conf)->new_text(string subject, + string message, + void|object|array(object) mottagare, + void|object|array(object) comment_to, + void|object|array(object) footnote_to, + void|multiset flags); + +(text)->comment(string subject, + string message, + void|object|array(object) mottagare, + void|object|array(object) comment_to, + void|object|array(object) footnote_to, + void|multiset flags); + +(text)->footnote(string subject, + string message, + void|object|array(object) mottagare, + void|object|array(object) comment_to, + void|object|array(object) footnote_to, + void|multiset flags); + +*/ -- GitLab