diff --git a/ChangeLog b/ChangeLog index 2cb38ed34db01293b3acde6e9bb85bc5342d39f4..d0757533b0731a0966b75718369c00d55adb23d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,38 @@ lyskomd.0/08.exp. * src/server/testsuite/lyskomd.0/08.exp: New file. +1999-05-18 David Byers <davby@ida.liu.se> + + * doc/lyskomd.texi: Merged dbck.texi and hacking.texi into + lyskomd.texi. + + * src/server/testsuite/lyskomd.0/03.exp: Updated + query-predefined-aux-items result. + + * src/server/testsuite/lyskomd.0/01.exp: Updated + query-predefined-aux-items result. + + * src/server/aux-items.c (undelete_aux_item_list): Fixed + conference/text mixup + (delete_aux_item_list): Same here. + (undelete_aux_item_list): Save kom_errno and err_stat across call. + + * src/server/aux-item-def-parse.y: Deal with disabled definitions + in a more sensible manner. + + * src/server/aux-items.c (aux_item_add_perm): Check the disabled + field of the aux-item definition. + + * src/server/aux-items.h: Added disabled field. + +1999-05-17 David Byers <davby@ida.liu.se> + + * src/server/aux-items.c (aux_item_list_add_items): New utility + function. + (system_add_aux_item_list): Use aux_item_list_add_items. + (text_stat_add_aux_item_list): Use aux_item_list_add_items. + (conf_stat_add_aux_item_list): Use aux_item_list_add_items. + 1999-05-16 Per Cederqvist <ceder@lysator.liu.se> Use a global variable to store the current time, so that it is @@ -111,6 +143,24 @@ * src/server/ram-smalloc.c: Don't test USE_GNU_MALLOC; that symbol was removed 1998-08-09. +1999-05-16 David Byers <davby@ida.liu.se> + + * src/server/aux-items.c (prepare_aux_item): Don't clear the link + field of the aux item. + (aux_inherit_items): Clear the link in the copied item before + calling add triggers. + (aux_item_link_items): New function. + (aux_item_trigger_mirror_faq): Use aux_item_link_items. + (aux_item_trigger_link_item): Use aux_item_link_items. + (aux_item_call_add_triggers): Fix the trigger data after calling + each trigger since one of them might move the aux item list in + memory. + +1999-05-15 David Byers <davby@ida.liu.se> + + * src/server/aux-items.c (aux_item_trigger_link_item): New + function for debugging linking aux items. + 1999-05-14 Per Cederqvist <ceder@lysator.liu.se> Fixes to the test suite. @@ -143,6 +193,116 @@ (lyskomd_fail_start): Likewise. Find the database files relative to top_srcdir. +1999-05-14 David Byers <davby@ida.liu.se> + + * src/server/text.c (do_create_text): Return long-array if there + are too many misc items. + (modify_text_info): Set err_stat to max length when returning + KOM_LONG_ARRAY. + + * src/include/kom-types.h (Info_datum): Added unknown_type to + union. + + * src/server/text.c (find_recipient): Add unknown_info to the + switch. Stop the server if COMPILE_CHECKS is undefined. + (is_member_in_recpt): Same here. + (do_delete_misc): Same here. + (do_sub_recpt): Same here. + (sender): Same here. + (is_sender): Same here. + (is_comm_sender): Same here. + (skip_recp): Same here. + (recp_sent_by): Same here. + (filter_secret_info): Same here. + (do_delete_text): Same here. + (check_double_subm): Same here. + (check_double_comm): Same here. + (create_text_check_misc): Return an illegal-info-typye if we see + an unknown info. Set err_stat to the index of the bad item when + returning a KOM_ILL_MISC. + (create_text_add_miscs): Same here. + + * src/server/prot-a.c (prot_a_destruct): Free the misc_info_list + field of the connection. + + * src/server/membership.c (add_rec_time): Handle unknown_info and + other unknown misc info types by shutting down the server. + + * src/server/call-switch.awk: Add support for misc_info_list in + fncdef.txt. + + * src/server/text.c (create_text_old): Changed parameter list to + use Misc_info_list instead of an integer and a Misc_info pointer. + (create_text): Same here. + (create_anonymous_text): Same here. + (create_anonymous_text_old): Same here. + + * src/server/fncdef.txt: Changed all "num c_misc_info_p" to + misc_info_list. + + * src/server/prot-a-parse-arg-c.awk: The aux_item type works again. + Allow misc_info_list as a type name. + + * src/server/prot-a-parse.c (prot_a_parse_misc_info_list): New + function. + + * src/server/prot-a.c (prot_a_init): Initialize the misc_info_list + field. + + * src/server/internal-connections.c (kill_client): Use + misc_info_list field of Connection. + + * src/server/connections.c (free_parsed): Clear the misc_info_list + field. + + * src/include/kom-types.h (Misc_info_list): New type + + * src/server/internal-connections.c (init_connection): Initialize + hunt_parse_pos, array_hunt_depth and array_hunt_num. Initialize + misc_info_list. + + * src/server/prot-a-parse.c (prot_a_hunt_array_end): New function + hunts for the end of an array.c + + * src/server/prot-a.c (prot_a_init): Initialize hunt_parse_pos and + array_hunt_num. + + + * src/include/kom-types.h (Info_type): Added unknown info type. + + * src/server/prot-a-parse.c (prot_a_parse_misc_info): Parse all + misc-info types that the server knows about. Unknown types + generate a protocol error. + + * src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp (1021): + Expcet long-array and not protocol-error. + + * src/server/prot-a-parse.c (prot_a_parse_aux_item_list): Discard + the part of the list that is longer than the max rather than send + a protocol error. + +1999-05-13 David Byers <davby@ida.liu.se> + + * src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp + (protocol_error): Removed expected failure. + + * src/server/admin.c (modify_server_info): Return KOM_LONG_ARRAY + when we see a long array. + + * src/server/conference.c (modify_conf_info): Return + KOM_LONG_ARRAY when we see a long array. + + * src/server/text.c (modify_text_info): Return KOM_LONG_ARRAY when + we see a long array. + + * src/server/prot-a-parse.c (prot_a_parse_num_list): Truncate a + parsed array to one more than the maximum length and skip all + other elements. + + * src/server/aux-items.c (undelete_aux_item_list): Log if the link + type is undefined and do not attempt to undelete. + (delete_aux_item_list): Likewise. + 1999-05-13 Per Cederqvist <ceder@gratia> Distribute the leaks tests, and run them during "make check". diff --git a/TODO b/TODO index 4d654f99d13dfce8215856e9b97df74adebe7457..5c56e84f1d67440c792f528028ff4cbe76476524 100644 --- a/TODO +++ b/TODO @@ -9,11 +9,13 @@ Testfall f * Showstoppers -** Make sure that there are no "expected failures" in the test suite. - ** Consider changing many paths so that it is safe to install lyskomd with prefix=/usr/local. + How about saving this for the next release and then support + various other path conventions? + + ** Consider removing the pid file on exit. ** Consider locking the database, so that dbck cannot do harm, and so @@ -29,25 +31,36 @@ Testfall f ** Documentation Issues -*** Document "%%Unsupported protocol" message - -*** Document "%% No connections left" message - *** Remove the text "In all likelihood, the implementation of this flag is screwed up." from lyskomd.texi after checking that supervisor-only works properly. -*** Move dbck.texi, hacking.tex and lyskomdb.texi into lyskomd.texi. - Two reasons: there are too many manuals, and automake apparently - doesn't allow more than one file to include version.texi. +*** Document updateLysKOM in lyskomd.texi. + There should be an "Invoking updateLysKOM" node. + updateLysKOM should use the "Status file" parameter (and other + parameters). (DONE) + Use parameters in src/server/updateLysKOM.c`savecore(). (DONE) + I will do this --ceder -*** Fix doc/lyskomdb.texi (Version 1) (see FIXME comments). +*** Document komrunning in lyskomd.texi. + There should be an "Invoking komrunning" node. + komrunning should be rewritten i C; it only works with BSD-style ps + programs. (DONE, but it no longer displays the process) + I am doing this --ceder *** Dump all little doc files into the texinfo manuals. + Remaining: + disc-cache.spec lyskomd.texi �vers�tt, uppdatera + local-to-global.doc lyskomd.texi ceder? + prot-a-tankar * + prot_a * + security-levels.txt Protocol-A.texi DONE + what-is-unread.swe Protocol-A.texi DONE I will do this --DCB *** Fix the node structure of Protocol-A.texi (3228867). I will do this --DCB + Looks done... *** Update/rewrite README. @@ -62,8 +75,6 @@ Testfall f *** The protocol revision section of Protocol-A.info is incomplete. I will do this --ceder -*** Document that session number 0 can be used in call 55. - ** Build Issues *** Check that texinfo.tex is included in a proper place by automake. @@ -76,6 +87,12 @@ Testfall f ** Testing +*** Try sending in negative lengths whenever we can send an array. + DONE for misc-info-list, add-aux delete-aux + +*** Check that we don't leak memory when truncating a long + aux_item_list send from the client. + *** In prot_a_get_token, what is an insane token length? *** Test validation of regexps containing groups. Try "X\\(YZ\\)?X". @@ -87,13 +104,6 @@ Testfall f *** Should anyone be able to set their letterbox to secret? -*** There is no way to set the Personal_flags. It's not even obvious - where it gets its initial value! This is Not Good At All. - -*** If we try to create a pers or conf and have reached the limit - of how many confs we can create, lyskomd just dies. Nasty. It - should return index-out-of-range, like create-text. - *** Timestamps of various things are not synchronized. This is seen easily when lyskomd executes really slowly. Known cases: last-written does not match text-stat (FIXED) @@ -671,6 +681,59 @@ Testfall f removed. (1108039). REJECT: too much work to be worth it. +*** Document "%%Unsupported protocol" message + DONE. + +*** Document "%% No connections left" message + DONE. + +*** Fix doc/lyskomdb.texi (Version 1) (see FIXME comments). + DONE. + +*** Document that session number 0 can be used in call 55. + DONE. + +*** There is no way to set the Personal_flags. It's not even obvious + where it gets its initial value! This is Not Good At All. + DONE. + +*** If we try to create a pers or conf and have reached the limit + of how many confs we can create, lyskomd just dies. Nasty. It + should return index-out-of-range, like create-text. + DONE. + +** When we pass a read-only misc item in create-text we get a protocol + error. We should get an illegal-misc. We can't just pass it through + since create_text_add_miscs will abort if it sees one of these misc + items. + DONE. + +** Parsing arrays that are longer than the maximum length is not + handled very well. Right now we return a protocol error most of the + time, but perhaps it would be better to return a protocol error + only when the array is insanely long, not just when it is longer + than the max. So we could have a global max array length parameter. + DONE. + +** Make sure that there are no "expected failures" in the test suite. + DONE. + +** Try sending a too-long aux-item list + DONE. + +** Send a too-long misc-item list + DONE. + +** Sending a too-long delete or add list crashes the server. + DONE. + +** Call add-recipient with really bogus info type + DONE. + +*** Move dbck.texi, hacking.tex and lyskomdb.texi into lyskomd.texi. + Two reasons: there are too many manuals, and automake apparently + doesn't allow more than one file to include version.texi. + DONE. * In progress diff --git a/doc/Protocol-A.texi b/doc/Protocol-A.texi index b3d1d1b9e9041e49f32bc643ad584a6c0791c6c2..c9b9eb2718b4a07e95ad89e2dd17d224c64f0c1b 100644 --- a/doc/Protocol-A.texi +++ b/doc/Protocol-A.texi @@ -2,7 +2,7 @@ @c @c FIXME: Explain how the garb works with nice and keep-commented @c -@c $Id: Protocol-A.texi,v 1.63 1999/05/13 11:35:24 ceder Exp $ +@c $Id: Protocol-A.texi,v 1.64 1999/05/18 13:06:18 byers Exp $ @c %**start of header @setfilename protocol-a.info @settitle LysKOM Protocol A @@ -61,7 +61,7 @@ another language under the same conditions as for modified versions. @end titlepage @ifinfo -@node Top +@node Top, Overview, (dir), (dir) @top LysKOM Protocol A This document specifies version 10 of LysKOM Protocol A. @@ -87,7 +87,7 @@ publication. @end menu @end ifinfo -@node Overview +@node Overview, Introduction, Top, Top @chapter Overview LysKOM is a conferencing system@footnote{Or in modern terms, enabling @@ -132,7 +132,7 @@ The LysKOM developers can be reached by email to @code{lyskom@@lysator.liu.se}. * Notation:: @end menu -@node Document Revision History +@node Document Revision History, Protocol Version History, Overview, Overview @section Document Revision History @table @asis @@ -170,7 +170,7 @@ Per Cederqvist started using version control for documentation. Lars Aronsson documented the protocol that was in use at the time. @end table -@node Protocol Version History +@node Protocol Version History, Notation, Document Revision History, Overview @section Protocol Version History @subsection Protocol version 10 (first implemented in lyskomd 2.0.0) @@ -412,7 +412,7 @@ All calls from 0--56. @end table -@node Notation +@node Notation, , Protocol Version History, Overview @section Notation This specification uses a BNF-like grammar to describe the protocol and @@ -435,7 +435,7 @@ literal strings. There is to be no whitespace before or after literal strings unless there is whitespace in the literal itself. -@node Introduction +@node Introduction, Data Types, Overview, Top @chapter Introduction This chapter introduces the concepts used in LysKOM, such as articles, @@ -452,7 +452,7 @@ conferences and sessions. @end menu -@node Articles +@node Articles, Conferences, Introduction, Introduction @section Articles An article is represented as a value of the type @code{Text-Stat} and a @@ -482,7 +482,7 @@ The server call @code{local-to-global} does this. -@node Conferences +@node Conferences, The Misc-Info List, Articles, Introduction @section Conferences Conferences hold articles. They are represented in the protocol as a @@ -535,7 +535,7 @@ changed to this type, preexisting secret members remain secret. * Persons and Sessions:: @end menu -@node Persons and Sessions +@node Persons and Sessions, , Conferences, Conferences @subsection Persons and Sessions Persons are represented in the protocol by values of the type @@ -553,7 +553,7 @@ the network connection is closed; a user can log in and out repeatedly in a single session. -@node The Misc-Info List +@node The Misc-Info List, The Aux-Item List, Conferences, Introduction @section The Misc-Info List The @code{Misc-Info} list contains tagged data. The fields are sent in @@ -702,7 +702,7 @@ article number which is a footnote to this article. @end table -@node The Aux-Item List +@node The Aux-Item List, Security, The Misc-Info List, Introduction @section The Aux-Item List The aux-item list is used as a generic extension mechanism in the LysKOM @@ -716,7 +716,7 @@ server and in protocol A. * Defining New Aux-Item Types:: @end menu -@node About Aux-Items +@node About Aux-Items, Predefined Aux-Item Types, The Aux-Item List, The Aux-Item List @subsection About Aux-Items Aux-items were introduced in protocol version 10 as a mechanism for @@ -748,7 +748,7 @@ no understanding of the contents can successfully parse the item anyway -@node Predefined Aux-Item Types +@node Predefined Aux-Item Types, Client-Specific Aux-Item Types, About Aux-Items, The Aux-Item List @subsection Predefined Aux-Item Types Predefined Aux-Item types are part of Protocol A, and clients should @@ -1065,7 +1065,7 @@ collection. @end table -@node Client-Specific Aux-Item Types +@node Client-Specific Aux-Item Types, Experimental Aux-Item Types, Predefined Aux-Item Types, The Aux-Item List @subsection Client-Specific Aux-Item Types Client-specific items do not cause the server to perform any magic. All @@ -1087,7 +1087,7 @@ If you want a range of numbers, send e-mail to the LysKOM development group. -@node Experimental Aux-Item Types +@node Experimental Aux-Item Types, Defining New Aux-Item Types, Client-Specific Aux-Item Types, The Aux-Item List @subsection Experimental Aux-Item Types Experimental numbers are free for all. Use 'em any way you want. All @@ -1095,7 +1095,7 @@ numbers in the range 20000-29999 are for experimental use. -@node Defining New Aux-Item Types +@node Defining New Aux-Item Types, , Experimental Aux-Item Types, The Aux-Item List @subsection Defining New Aux-Item Types If you want a new predefined item type, just document what it does, what @@ -1121,7 +1121,7 @@ much less painful process than adding new calls. -@node Security +@node Security, Membership and Reading, The Aux-Item List, Introduction @section Security Security in LysKOM is based on two components. Each person has a set of @@ -1195,7 +1195,7 @@ Create persons @end table -@node Membership and Reading +@node Membership and Reading, Client-Server Dialog, Security, Introduction @section Membership and Reading Persons' memberships in conferences are represented in the protocol as @@ -1242,7 +1242,7 @@ global text numbers. If the server does not implement the efficient but perfectly serviceable @pxref{get-map} call instead. -@node Client-Server Dialog +@node Client-Server Dialog, , Membership and Reading, Introduction @section Client-Server Dialog The client-server dialog consists of two phases, establishing the connection @@ -1259,7 +1259,7 @@ the user connecting is followed by a newline character. When the server has accepted the connection its reply is protocol-dependent. Protocol A servers will reply with the string -@code{LysKOM} on a single line. +@code{LysKOM} on a single line if the connection attampt is successful. @example % telnet kom.lysator.liu.se 4894 @@ -1270,6 +1270,17 @@ protocol-dependent. Protocol A servers will reply with the string LysKOM @end example +Besides the string "LysKOM", the server may respond with "%%Unsupported +protocol" or "%% No connections left.". + +The "%%Unsupported protocol" reply is sent if the server does not +understand the requested protocol. + +The "%% No connections left" reply is sent if the server is not +accepting additional connections. This error is transient. The next +connection attempt may succeed. Clients should wait a few seconds before +attempting to make another connection after receiving this error. + After connecting, calls to the server can be made. Most calls require the user to log in, but some calls can be made without a log-in. Calls to the server are made by sending a reference number followed by the @@ -1288,7 +1299,7 @@ request or an error code preceded by an indicator and the reference number. @example - server-reply ::= ok-reply | error-reply; + server-reply ::= ok-reply | error-reply | protocol-error; ok-reply ::= ( "=" @@ -1304,6 +1315,8 @@ number. ) error-no ::= INT32; + + protocol-error ::= "%% LysKOM protocol error." @end example Our notation is not flexible enough to specify the two-way nature of the @@ -1311,8 +1324,8 @@ communication. @code{ref-no} in the reply is always the same as @code{ref-no} in the corresponding request. @code{reply-data} depends on which request was made and is specified together with each request. -Please note that there is no whitespace after the initial indicator in -the reply. +Note that there is no whitespace after the initial indicator in the +reply. Error reporting is covered in more detail in chapter @ref{Error Codes}. @@ -1327,8 +1340,14 @@ and understand requests using the older conventions, but clients must conform to the current convention of separating data elements with spaces and terminating all requests with a linefeed character. +If the request is syntactically incorrect, the server will respond with +the string "%% LysKOM protocol error." The server will attempt to +recover from the error, but in some cases complete recovery may not be +possible, which may result in one or more subsequent requests being +lost. + -@node Data Types +@node Data Types, Protocol Requests, Introduction, Top @chapter Data Types The data types in protocol A come in two flavors. The first (vanilla) @@ -1342,7 +1361,7 @@ while complex data types include things such as conferences and people. * Name Expansion:: @end menu -@node Simple Data Types +@node Simple Data Types, LysKOM Data Types, Data Types, Data Types @section Simple Data Types @subsection Integers @@ -1531,7 +1550,7 @@ corresponding @code{<type>} is its type. Structures are transmitted as a sequence of their fields. -@node LysKOM Data Types +@node LysKOM Data Types, Name Expansion, Simple Data Types, Data Types @section LysKOM Data Types In this section the data types specific to LysKOM are defined. Most of @@ -2711,7 +2730,7 @@ The dynamic session flags (see above.) What the client is doing. This string is set by the client. @end table -@node Name Expansion +@node Name Expansion, , LysKOM Data Types, Data Types @section Name Expansion Names in LysKOM can be expanded according to two rules, regexp matching @@ -2756,7 +2775,7 @@ equivalent according to swascii rules. -@node Protocol Requests +@node Protocol Requests, Asynchronous Messages, Data Types, Top @chapter Protocol Requests This chapter documents all calls that can be made to the server. All @@ -2893,10 +2912,9 @@ in the example. * local-to-global:: r Map local text numbers to global ones (103) * map-created-texts:: r Map texts created by a person to glogal (104) * set-keep-commented:: r Set how new comments protect old texts (105) -* set-pers-flags:: r Set the flags on a person (106) @end menu -@node login-old +@node login-old, logout, Protocol Requests, Protocol Requests @section login-old (1) Obsolete @findex login-old @@ -2922,7 +2940,7 @@ error-status indicates the person number. @end table -@node logout +@node logout, change-conference, login-old, Protocol Requests @section logout (1) Recommended @findex logout @@ -2946,7 +2964,7 @@ places less load on the server than does creating new sessions. This call never fails. -@node change-conference +@node change-conference, change-name, logout, Protocol Requests @section change-conference (1) Recommended @findex change-conference @@ -2975,7 +2993,7 @@ The user currently logged in is not a member of @code{conference}. @end table -@node change-name +@node change-name, change-what-i-am-doing, change-conference, Protocol Requests @section change-name (1) Recommended @findex change-name @@ -3018,7 +3036,7 @@ There are invalid characters in @code{new-name}. @end table -@node change-what-i-am-doing +@node change-what-i-am-doing, create-person-old, change-name, Protocol Requests @section change-what-i-am-doing (1) Recommended @findex change-what-i-am-doing @@ -3040,7 +3058,7 @@ using LysKOM. Clients are encouraged to use this call creatively. -@node create-person-old +@node create-person-old, get-person-stat-old, change-what-i-am-doing, Protocol Requests @section create-person-old (1) Obsolete (10) @findex create-person-old @@ -3092,7 +3110,7 @@ The string @code{passwd} is not a valid password. -@node get-person-stat-old +@node get-person-stat-old, set-priv-bits, create-person-old, Protocol Requests @section get-person-stat-old (1) Obsolete @findex get-person-stat-old @@ -3122,7 +3140,7 @@ Conference @code{person} does not exist or is secret. @code{conference} is zero. @end table -@node set-priv-bits +@node set-priv-bits, set-passwd, get-person-stat-old, Protocol Requests @section set-priv-bits (1) Recommended @findex set-priv-bits @@ -3167,7 +3185,7 @@ and privilege level set to 6 or higher. @end table -@node set-passwd +@node set-passwd, query-read-texts-old, set-priv-bits, Protocol Requests @section set-passwd (1) Recommended @findex set-passwd @@ -3214,7 +3232,7 @@ privilege level 7 or higher enabled. -@node query-read-texts-old +@node query-read-texts-old, create-conf-old, set-passwd, Protocol Requests @section query-read-texts-old (1) Obsolete (10) @findex query-read-texts-old @@ -3264,7 +3282,7 @@ Conference @code{conference} does not exist, or is secret. -@node create-conf-old +@node create-conf-old, delete-conf, query-read-texts-old, Protocol Requests @section create-conf-old (1) Obsolete (10) @findex create-conf-old @@ -3348,7 +3366,7 @@ The conference type has the @code{secret} bit set, but the -@node delete-conf +@node delete-conf, lookup-name, create-conf-old, Protocol Requests @section delete-conf (1) Recommended @findex delete-conf @@ -3397,7 +3415,7 @@ is corrupt.) @end table -@node lookup-name +@node lookup-name, get-conf-stat-older, delete-conf, Protocol Requests @section lookup-name (1) Obsolete @findex lookup-name @@ -3434,7 +3452,7 @@ has been broken into three lines to fit on the page.) This call always succeeds. -@node get-conf-stat-older +@node get-conf-stat-older, add-member-old, lookup-name, Protocol Requests @section get-conf-stat-older (1) Obsolete @findex get-conf-stat-older @@ -3466,7 +3484,7 @@ returned instead of the name. -@node add-member-old +@node add-member-old, sub-member, get-conf-stat-older, Protocol Requests @section add-member-old (1) Obsolete (10) @i{Example:} @@ -3534,7 +3552,7 @@ privileges to change the priorities of person @code{pers-no}. -@node sub-member +@node sub-member, set-presentation, add-member-old, Protocol Requests @section sub-member (1) Recommended @findex sub-member @@ -3590,7 +3608,7 @@ Not supervisor of conference @code{conf-no} or not supervisor of person -@node set-presentation +@node set-presentation, set-etc-motd, sub-member, Protocol Requests @section set-presentation (1) Recommended @findex set-presentation @@ -3656,7 +3674,7 @@ marks. -@node set-etc-motd +@node set-etc-motd, set-supervisor, set-presentation, Protocol Requests @section set-etc-motd (1) Recommended @findex set-etc-motd @@ -3718,7 +3736,7 @@ marks. -@node set-supervisor +@node set-supervisor, set-permitted-submitters, set-etc-motd, Protocol Requests @section set-supervisor (1) Recommended @findex set-supervisor @@ -3781,7 +3799,7 @@ conference @code{conf-no}. -@node set-permitted-submitters +@node set-permitted-submitters, set-super-conf, set-supervisor, Protocol Requests @section set-permitted-submitters (1) Recommended @findex set-permitted-submitters @@ -3842,7 +3860,7 @@ Not enough permissions to change the permitted submitters of conference -@node set-super-conf +@node set-super-conf, set-conf-type, set-permitted-submitters, Protocol Requests @section set-super-conf (1) Recommended @findex set-super-conf @@ -3882,7 +3900,7 @@ Not enough permissions to change super-conference of conference -@node set-conf-type +@node set-conf-type, set-garb-nice, set-super-conf, Protocol Requests @section set-conf-type (1) Recommended @findex set-conf-type @@ -3935,7 +3953,7 @@ membership type. @end table -@node set-garb-nice +@node set-garb-nice, get-marks, set-conf-type, Protocol Requests @section set-garb-nice (1) Recommended @findex set-garb-nice @@ -3979,7 +3997,7 @@ Not enough permissions to change the expiration time for conference -@node get-marks +@node get-marks, mark-text-old, set-garb-nice, Protocol Requests @section get-marks (1) Recommended @findex get-marks @@ -4009,7 +4027,7 @@ Login required before issuing this call. -@node mark-text-old +@node mark-text-old, get-text, get-marks, Protocol Requests @section mark-text-old (1) Obsolete @findex mark-text-old @@ -4047,7 +4065,7 @@ many marks, or cause the text to have too many marks. -@node get-text +@node get-text, get-text-stat-old, mark-text-old, Protocol Requests @section get-text (1) Recommended @findex get-text @@ -4098,7 +4116,7 @@ Attempt to retrieve text number 0. -@node get-text-stat-old +@node get-text-stat-old, mark-as-read, get-text, Protocol Requests @section get-text-stat-old (1) Obsolete (10) @findex get-text-stat-old @@ -4139,7 +4157,7 @@ Attempt to retrieve text number 0. -@node mark-as-read +@node mark-as-read, create-text-old, get-text-stat-old, Protocol Requests @section mark-as-read (1) Recommended @findex mark-as-read @@ -4201,7 +4219,7 @@ One of the numbers in @code{text} is zero. -@node create-text-old +@node create-text-old, delete-text, mark-as-read, Protocol Requests @section create-text-old (1) Obsolete (10) @findex create-text-old @@ -4277,7 +4295,7 @@ an unknown misc item in the misc-info list. -@node delete-text +@node delete-text, add-recipient, create-text-old, Protocol Requests @section delete-text (1) Recommended @findex delete-text @@ -4311,7 +4329,7 @@ author. -@node add-recipient +@node add-recipient, sub-recipient, delete-text, Protocol Requests @section add-recipient (1) Recommended @findex add-recipient @@ -4395,7 +4413,7 @@ super conf chain. -@node sub-recipient +@node sub-recipient, add-comment, add-recipient, Protocol Requests @section sub-recipient (1) Recommended @findex sub-recipient @@ -4451,7 +4469,7 @@ Not supervisor of text author or conference, and not sender of text to @end table -@node add-comment +@node add-comment, sub-comment, sub-recipient, Protocol Requests @section add-comment (1) Recommended @findex add-comment @@ -4503,7 +4521,7 @@ The text @code{comment-to} already has the maximum number of comments. -@node sub-comment +@node sub-comment, get-map, add-comment, Protocol Requests @section sub-comment (1) Obsolete (10) @findex sub-comment @@ -4554,7 +4572,7 @@ anyway. -@node get-map +@node get-map, get-time, sub-comment, Protocol Requests @section get-map (1) Recommended @findex get-map @@ -4655,7 +4673,7 @@ ever has existed in this conference. -@node get-time +@node get-time, get-info-old, get-map, Protocol Requests @section get-time (1) Recommended @findex get-time @@ -4683,7 +4701,7 @@ This call always succeeds -@node get-info-old +@node get-info-old, add-footnote, get-time, Protocol Requests @section get-info-old (1) Obsolete (10) @findex get-info-old @@ -4719,7 +4737,7 @@ This call always succeeds. -@node add-footnote +@node add-footnote, sub-footnote, get-info-old, Protocol Requests @section add-footnote (1) Recommended @findex add-footnote @@ -4772,7 +4790,7 @@ Text @code{text-no} is already a footnote to @code{footnote-to}. -@node sub-footnote +@node sub-footnote, who-is-on-old, add-footnote, Protocol Requests @section sub-footnote (1) Recommended @findex sub-footnote @@ -4820,7 +4838,7 @@ set and enabled to complete call anyway. -@node who-is-on-old +@node who-is-on-old, set-unread, sub-footnote, Protocol Requests @section who-is-on-old (1) Obsolete @findex who-is-on-old @@ -4844,7 +4862,7 @@ This call always succeeds. -@node set-unread +@node set-unread, set-motd-of-lyskom, who-is-on-old, Protocol Requests @section set-unread (1) Recommended @findex set-unread @@ -4890,7 +4908,7 @@ Not a member of conference @code{conf-no}. -@node set-motd-of-lyskom +@node set-motd-of-lyskom, enable, set-unread, Protocol Requests @section set-motd-of-lyskom (1) Recommended @findex set-motd-of-lyskom @@ -4930,7 +4948,7 @@ The text @code{text-no} already has the maximum number of marks. @end table -@node enable +@node enable, sync-kom, set-motd-of-lyskom, Protocol Requests @section enable (1) Recommended @findex enable @@ -4963,7 +4981,7 @@ Login required before issuing this call. @end table -@node sync-kom +@node sync-kom, shutdown-kom, enable, Protocol Requests @section sync-kom (1) Recommended @findex sync-kom @@ -5001,7 +5019,7 @@ Administrator bit not set or privileges not enabled. @end table -@node shutdown-kom +@node shutdown-kom, broadcast, sync-kom, Protocol Requests @section shutdown-kom (1) Recommended @findex shutdown-kom @@ -5035,7 +5053,7 @@ Administrator bit not set or privileges not enabled. @end table -@node broadcast +@node broadcast, get-membership-old, shutdown-kom, Protocol Requests @section broadcast (1) Obsolete @findex broadcast @@ -5059,7 +5077,7 @@ Messages have been disabled. @end table -@node get-membership-old +@node get-membership-old, get-created-texts, broadcast, Protocol Requests @section get-membership-old (1) Obsolete (10) @findex get-membership-old @@ -5124,7 +5142,7 @@ person's membership list. -@node get-created-texts +@node get-created-texts, get-members-old, get-membership-old, Protocol Requests @section get-created-texts (1) Obsolete (10) @findex get-created-texts @@ -5196,7 +5214,7 @@ text. -@node get-members-old +@node get-members-old, get-person-stat, get-created-texts, Protocol Requests @section get-members-old (1) Obsolete (10) @findex get-members-old @@ -5238,7 +5256,7 @@ The conference @code{conf} does not exist or is secret. -@node get-person-stat +@node get-person-stat, get-conf-stat-old, get-members-old, Protocol Requests @section get-person-stat (1) Recommended @findex get-person-stat @@ -5275,7 +5293,7 @@ The conference @code{pers-no} does not exist or is secret. @end table -@node get-conf-stat-old +@node get-conf-stat-old, who-is-on, get-person-stat, Protocol Requests @section get-conf-stat-old (1) Obsolete (10) @findex get-conf-stat-old @@ -5320,7 +5338,7 @@ The conference @code{conf-no} does not exist or is secret. -@node who-is-on +@node who-is-on, get-unread-confs, get-conf-stat-old, Protocol Requests @section who-is-on (1) Obsolete (9) @findex who-is-on @@ -5342,7 +5360,7 @@ structure is described elsewhere (@pxref{LysKOM Data Types}.) This call always succeeds. -@node get-unread-confs +@node get-unread-confs, send-message, who-is-on, Protocol Requests @section get-unread-confs (1) Recommended @findex get-unread-confs @@ -5387,7 +5405,7 @@ Person @code{pers-no} does not exist or is secret. -@node send-message +@node send-message, get-session-info, get-unread-confs, Protocol Requests @section send-message (1) Recommended @findex send-message @@ -5434,7 +5452,7 @@ message. @end table -@node get-session-info +@node get-session-info, disconnect, send-message, Protocol Requests @section get-session-info (1) Obsolete @findex get-session-info @@ -5459,7 +5477,7 @@ The session @code{session-no} does not exist. -@node disconnect +@node disconnect, who-am-i, get-session-info, Protocol Requests @section disconnect (1) Recommended @findex disconnect @@ -5473,6 +5491,10 @@ server. A session can always disconnect itself, even without logging in. If the session is logged in as user @i{foo} it can also disconnect any session logged in as a person for which @i{foo} is the supervisor. +Session number zero is always interpreted as the session making the +call, so the easiest way to disconnect the current session is to +disconnect session zero. + @example 1 56 @t{=1 7} @@ -5483,10 +5505,11 @@ session logged in as a person for which @i{foo} is the supervisor. @end example In this example the client asks for its own session number, then -disconnects itself. The asynchronous message sent just before the -session is disconnected is the logout message for the user that was -logged on in the session. The ``Connection closed by foreign host.'' is -not part of the server output. This message was generated by telnet. +disconnects itself (disconnection session 0 would have had the same +effect.) The asynchronous message sent just before the session is +disconnected is the logout message for the user that was logged on in +the session. The ``Connection closed by foreign host.'' is not part of +the server output. This message was generated by telnet. @unnumberedsubsec Error codes @@ -5503,7 +5526,7 @@ The session @code{session-no} does not exist. @end table -@node who-am-i +@node who-am-i, set-user-area, disconnect, Protocol Requests @section who-am-i (1) Recommended @findex who-am-i @@ -5529,7 +5552,7 @@ This call always succeeds. -@node set-user-area +@node set-user-area, get-last-text, who-am-i, Protocol Requests @section set-user-area (2) Recommended @findex set-user-area @@ -5571,7 +5594,7 @@ Not enough access to person @code{pers-no} to complete the call. @end table -@node get-last-text +@node get-last-text, create-anonymous-text-old, set-user-area, Protocol Requests @section get-last-text (3) Recommended @findex get-last-text @@ -5614,7 +5637,7 @@ This call never fails. -@node create-anonymous-text-old +@node create-anonymous-text-old, find-next-text-no, get-last-text, Protocol Requests @section create-anonymous-text-old (3) Obsolete (10) @findex create-anonymous-text-old @@ -5688,7 +5711,7 @@ an unknown misc item in the misc-info list. -@node find-next-text-no +@node find-next-text-no, find-previous-text-no, create-anonymous-text-old, Protocol Requests @section find-next-text-no (3) Recommended @findex find-next-text-no @@ -5721,7 +5744,7 @@ There is no text following text @code{start}. @end table -@node find-previous-text-no +@node find-previous-text-no, login, find-next-text-no, Protocol Requests @section find-previous-text-no (3) Recommended @findex find-previous-text-no @@ -5755,7 +5778,7 @@ There is no text preceding text @code{start}. -@node login +@node login, who-is-on-ident, find-previous-text-no, Protocol Requests @section login (4) Recommended @findex login @@ -5815,7 +5838,7 @@ Attempt to log in as person number 0. -@node who-is-on-ident +@node who-is-on-ident, get-session-info-ident, login, Protocol Requests @section who-is-on-ident (4) Obsolete (9) @findex who-is-on-ident @@ -5833,7 +5856,7 @@ sessions. This call always succeeds. -@node get-session-info-ident +@node get-session-info-ident, re-lookup-person, who-is-on-ident, Protocol Requests @section get-session-info-ident (4) Obsolete (9) @findex get-session-info-ident @@ -5855,7 +5878,7 @@ The session @code{session-no} does not exist. @end table -@node re-lookup-person +@node re-lookup-person, re-lookup-conf, get-session-info-ident, Protocol Requests @section re-lookup-person (5) Obsolete @findex re-lookup-person @@ -5878,7 +5901,7 @@ not a correct regexp. @end table -@node re-lookup-conf +@node re-lookup-conf, lookup-person, re-lookup-person, Protocol Requests @section re-lookup-conf (5) Obsolete @findex re-lookup-conf @@ -5903,7 +5926,7 @@ not a correct regexp. -@node lookup-person +@node lookup-person, lookup-conf, re-lookup-conf, Protocol Requests @section lookup-person (6) Obsolete @findex lookup-person @@ -5924,7 +5947,7 @@ This call always succeeds. -@node lookup-conf +@node lookup-conf, set-client-version, lookup-person, Protocol Requests @section lookup-conf (6) Obsolete @findex lookup-conf @@ -5945,7 +5968,7 @@ This call always succeeds. -@node set-client-version +@node set-client-version, get-client-name, lookup-conf, Protocol Requests @section set-client-version (6) Recommended @findex set-client-version @@ -5993,7 +6016,7 @@ is undefined. @end table -@node get-client-name +@node get-client-name, get-client-version, set-client-version, Protocol Requests @section get-client-name (6) Recommended @findex get-client-name @@ -6020,7 +6043,7 @@ The session @code{session} does not exist. @end table -@node get-client-version +@node get-client-version, mark-text, get-client-name, Protocol Requests @section get-client-version (6) Recommended @findex get-client-version @@ -6048,7 +6071,7 @@ The session @code{session} does not exist. -@node mark-text +@node mark-text, unmark-text, get-client-version, Protocol Requests @section mark-text (4) Recommended @findex mark-text @@ -6096,7 +6119,7 @@ Already the maximum number of marks on text @code{text}. -@node unmark-text +@node unmark-text, re-z-lookup, mark-text, Protocol Requests @section unmark-text (4) Recommended @findex unmark-text @@ -6132,7 +6155,7 @@ The text @code{text-no} was not marked. @end table -@node re-z-lookup +@node re-z-lookup, get-version-info, unmark-text, Protocol Requests @section re-z-lookup (7) Recommended @findex re-z-lookup @@ -6184,7 +6207,7 @@ not a correct regexp. -@node get-version-info +@node get-version-info, lookup-z-name, re-z-lookup, Protocol Requests @section get-version-info (7) Recommended @findex get-version-info @@ -6212,7 +6235,7 @@ This call always succeeds. -@node lookup-z-name +@node lookup-z-name, set-last-read, get-version-info, Protocol Requests @section lookup-z-name (7) Recommended @findex lookup-z-name @@ -6256,7 +6279,7 @@ and persons matching the pattern ``T C''. This call always succeeds. -@node set-last-read +@node set-last-read, get-uconf-stat, lookup-z-name, Protocol Requests @section set-last-read (8) Recommended @findex set-last-read @@ -6298,7 +6321,7 @@ Not a member of conference @code{conference}. -@node get-uconf-stat +@node get-uconf-stat, set-info, set-last-read, Protocol Requests @section get-uconf-stat (8) Recommended @findex get-uconf-stat @@ -6346,7 +6369,7 @@ The conference @code{conference} does not exist or is secret. -@node set-info +@node set-info, accept-async, get-uconf-stat, Protocol Requests @section set-info (9) Recommended @findex set-info @@ -6398,7 +6421,7 @@ day, and the current implementation of the server does accept MOTD to be 0. @end table -@node accept-async +@node accept-async, query-async, set-info, Protocol Requests @section accept-async (9) Recommended @findex accept-async @@ -6454,7 +6477,7 @@ overrun. @end table -@node query-async +@node query-async, user-active, accept-async, Protocol Requests @section query-async (9) Recommended @findex query-async @@ -6489,7 +6512,7 @@ list of asynchronous messages that servers should preselect. This call always succeeds. -@node user-active +@node user-active, who-is-on-dynamic, query-async, Protocol Requests @section user-active (9) Recommended @findex user-active @@ -6513,7 +6536,7 @@ avoid excessive network and server load. This call always succeeds. -@node who-is-on-dynamic +@node who-is-on-dynamic, get-static-session-info, user-active, Protocol Requests @section who-is-on-dynamic (9) Recommended @findex who-is-on-dynamic @@ -6548,7 +6571,7 @@ have the proper visibility). This call always succeeds. -@node get-static-session-info +@node get-static-session-info, get-collate-table, who-is-on-dynamic, Protocol Requests @section get-static-session-info (9) Recommended @findex get-static-session-info @@ -6573,7 +6596,7 @@ The session @code{session-no} does not exist. -@node get-collate-table +@node get-collate-table, create-text, get-static-session-info, Protocol Requests @section get-collate-table (10) Recommended @findex get-collate-table @@ -6598,7 +6621,7 @@ This call always succeeds. -@node create-text +@node create-text, create-anonymous-text, get-collate-table, Protocol Requests @section create-text (10) Recommended @findex create-text @@ -6662,10 +6685,12 @@ One of the aux-items in @code{aux-items} is illegal. The tag might be out of range, the item not applicable to texts or whatever @item aux-item-permission One of the items looks valid but could not be created anyway. +@item long-array +Too many misc-items or aux-items were specified. @end table -@node create-anonymous-text +@node create-anonymous-text, create-conf, create-text, Protocol Requests @section create-anonymous-text (10) Recommended @findex create-anonymous-text @@ -6730,7 +6755,7 @@ One of the items looks valid but could not be created anyway. -@node create-conf +@node create-conf, create-person, create-anonymous-text, Protocol Requests @section create-conf (10) Recommended @findex create-conf @@ -6786,7 +6811,7 @@ One of the items looks valid but could not be created anyway. -@node create-person +@node create-person, get-text-stat, create-conf, Protocol Requests @section create-person (10) Recommended @findex create-person @@ -6844,7 +6869,7 @@ One of the items looks valid but could not be created anyway. -@node get-text-stat +@node get-text-stat, get-conf-stat, create-person, Protocol Requests @section get-text-stat (10) Recommended @findex get-text-stat @@ -6872,7 +6897,7 @@ Attempt to retrieve text number 0. -@node get-conf-stat +@node get-conf-stat, modify-text-info, get-text-stat, Protocol Requests @section get-conf-stat (10) Recommended @findex get-conf-stat @@ -6893,7 +6918,7 @@ The conference @code{conf-no} does not exist or is secret. -@node modify-text-info +@node modify-text-info, modify-conf-info, get-conf-stat, Protocol Requests @section modify-text-info (10) Recommended @findex modify-text-info @@ -6927,7 +6952,7 @@ One of the items in @code{add} is illegal for some reason. -@node modify-conf-info +@node modify-conf-info, get-info, modify-text-info, Protocol Requests @section modify-conf-info (10) Recommended @findex modify-conf-info @@ -6960,7 +6985,7 @@ One of the items in @code{add} is illegal for some reason. -@node get-info +@node get-info, modify-system-info, modify-conf-info, Protocol Requests @section get-info (10) Recommended @findex get-info @@ -6981,7 +7006,7 @@ This call always succeeds. -@node modify-system-info +@node modify-system-info, query-predefined-aux-items, get-info, Protocol Requests @section modify-system-info (10) Recommended @findex modify-system-info @@ -7009,7 +7034,7 @@ Attempt to delete an undeletable item or create an uncreateable item. @end table -@node query-predefined-aux-items +@node query-predefined-aux-items, set-expire, modify-system-info, Protocol Requests @section query-predefined-aux-items (10) Recommended @findex query-predefined-aux-items @@ -7029,7 +7054,7 @@ This call always succeeds. -@node set-expire +@node set-expire, query-read-texts, query-predefined-aux-items, Protocol Requests @section set-expire (10) Recommended @findex set-expire @@ -7055,7 +7080,7 @@ Not supervisor of conference @code{conf-no} and not privileged enough to complete the call anyway. @end table -@node query-read-texts +@node query-read-texts, get-membership, set-expire, Protocol Requests @section query-read-texts (10) Recommended @findex query-read-texts @@ -7106,7 +7131,7 @@ privileges to find out if @code{person} is a member. @end table -@node get-membership +@node get-membership, add-member, query-read-texts, Protocol Requests @section get-membership (10) Recommended @findex get-membership @@ -7170,7 +7195,7 @@ person's membership list. @end table -@node add-member +@node add-member, get-members, get-membership, Protocol Requests @section add-member (10) Recommended @findex add-member @@ -7244,7 +7269,7 @@ privileges to change the priorities of person @code{pers-no}. -@node get-members +@node get-members, set-membership-type, add-member, Protocol Requests @section get-members (10) Recommended @findex get-members @@ -7289,7 +7314,7 @@ The conference @code{conf} does not exist or is secret. @end table -@node set-membership-type +@node set-membership-type, local-to-global, get-members, Protocol Requests @section set-membership-type (10) Recommended @findex set-membership-type @@ -7335,7 +7360,7 @@ restrictions set on the server or on the conference @code{conf} @end table -@node local-to-global +@node local-to-global, map-created-texts, set-membership-type, Protocol Requests @section local-to-global (10) Recommended @findex local-to-global @@ -7432,7 +7457,7 @@ ever existed in the conference. @end table -@node map-created-texts +@node map-created-texts, set-keep-commented, local-to-global, Protocol Requests @section map-created-texts (10) Recommended @findex map-created-texts @@ -7482,7 +7507,7 @@ information about the texts in the conference. @end table -@node set-keep-commented +@node set-keep-commented, , map-created-texts, Protocol Requests @section set-keep-commented (10) Recommended @findex set-keep-commented @@ -7509,7 +7534,11 @@ complete the call anyway. @end table -@node set-pers-flags, , set-keep-commented, Protocol Requests +@menu +* set-pers-flags:: +@end menu + +@node set-pers-flags, , set-keep-commented, set-keep-commented @subsection set-pers-flags (10) Recommended @findex set-pers-flags @@ -7538,7 +7567,7 @@ flags. @end table -@node Asynchronous Messages +@node Asynchronous Messages, Error Codes, Protocol Requests, Top @chapter Asynchronous Messages Asynchronous messages are information messages sent from the server to @@ -7594,7 +7623,7 @@ reject them if a client uses it as an argument to ------------------------------------------------------------------------------- @end menu -@node async-new-text-old +@node async-new-text-old, async-i-am-off, Asynchronous Messages, Asynchronous Messages @section async-new-text-old (1) Obsolete (10) @example @@ -7610,7 +7639,7 @@ In protocol version 10 this call has been superceded by @ref{async-new-text}. -@node async-i-am-off +@node async-i-am-off, async-i-am-on-obsolete, async-new-text-old, Asynchronous Messages @section async-i-am-off (1) Obsolete @example @@ -7622,7 +7651,7 @@ call @code{Async logout}. -@node async-i-am-on-obsolete +@node async-i-am-on-obsolete, async-new-name, async-i-am-off, Asynchronous Messages @section async-i-am-on-obsolete (1) Obsolete @example @@ -7637,7 +7666,7 @@ working conference. It has been replaced by call number 6, -@node async-new-name +@node async-new-name, async-i-am-on, async-i-am-on-obsolete, Asynchronous Messages @section async-new-name (1) Recommended @example @@ -7653,7 +7682,7 @@ old name in @code{old-name} and the new name in @code{new-name}. -@node async-i-am-on +@node async-i-am-on, async-sync-db, async-new-name, Asynchronous Messages @section async-i-am-on (1) Recommended @example @@ -7667,7 +7696,7 @@ FIXME: can the username change? -@node async-sync-db +@node async-sync-db, async-leave-conf, async-i-am-on, Asynchronous Messages @section async-sync-db (1) Recommended @example @@ -7680,7 +7709,7 @@ difference between the two cases. -@node async-leave-conf +@node async-leave-conf, async-login, async-sync-db, Asynchronous Messages @section async-leave-conf (1) Recommended @example @@ -7710,7 +7739,7 @@ This message is not sent if a membership is transformed from an active to a passive membership. -@node async-login +@node async-login, async-broadcast, async-leave-conf, Asynchronous Messages @section async-login (1) Recommended @example @@ -7724,7 +7753,7 @@ logging in is sent in @code{pers-no}. -@node async-broadcast +@node async-broadcast, async-rejected-connection, async-login, Asynchronous Messages @section async-broadcast (1) Obsolete @example @@ -7739,7 +7768,7 @@ to all LysKOM users, but is no longer used. -@node async-rejected-connection +@node async-rejected-connection, async-send-message, async-broadcast, Asynchronous Messages @section async-rejected-connection (1) Recommended @example @@ -7753,7 +7782,7 @@ to allow more connections. -@node async-send-message +@node async-send-message, async-logout, async-rejected-connection, Asynchronous Messages @section async-send-message (1) Recommended @example @@ -7771,7 +7800,7 @@ of the mailbox conference. -@node async-logout +@node async-logout, async-deleted-text, async-send-message, Asynchronous Messages @section async-async-logout (1) Recommended @example @@ -7786,7 +7815,7 @@ if there is nobody logged on in the session. -@node async-deleted-text +@node async-deleted-text, async-new-text, async-logout, Asynchronous Messages @section async-deleted-text (10) Recommended @example @@ -7800,7 +7829,7 @@ deleted is sent in @code{text-no} and the text stat in @code{text-stat.} -@node async-new-text +@node async-new-text, async-new-recipient, async-deleted-text, Asynchronous Messages @section async-new-text (10) Recommended @example @@ -7813,7 +7842,7 @@ number @code{text-no}, and the text stat is @code{text-stat}. The message is sent to all logged-in members of any recipient of the text. -@node async-new-recipient +@node async-new-recipient, async-sub-recipient, async-new-text, Asynchronous Messages @section async-new-recipient (10) Recommended @example @@ -7830,7 +7859,7 @@ recipient. -@node async-sub-recipient +@node async-sub-recipient, async-new-membership, async-new-recipient, Asynchronous Messages @section async-sub-recipient (10) Recommended @example @@ -7846,7 +7875,7 @@ recipients of the text that are permitted to know about the new recipient. -@node async-new-membership +@node async-new-membership, , async-sub-recipient, Asynchronous Messages @section async-new-membership (10) Recommended @example @@ -7863,7 +7892,7 @@ See also @pxref{async-leave-conf}. -@node Error Codes +@node Error Codes, LysKOM Content Types, Asynchronous Messages, Top @chapter Error Codes @@ -7872,16 +7901,28 @@ error reply, as defined below and earlier (@pxref{Client-Server Dialog}). @example - error-reply ::= + error-reply ::= normal-error | special-error + + normal-error ::= ( "%" ref-no : INT32; error-no : Error-No; error-status : INT32; ) + special-error ::= "%% LysKOM protocol error." + | "%%Insane token length." + | "%%Insane array size." + | "%%No connections left." + error-no ::= INT32; @end example +The server may return two different types of errors. Normal errors are +replies to syntactically correct calls to the server. Special errors are +replies to syntactically incorrect calls and responses to exceptional +conditions. + A client should be prepared for any error code in response to any call, no matter if the response makes any sense or not. The value returned in @code{error-status} was more or less undefined before protocol version @@ -7903,6 +7944,58 @@ completely since bugs might cause the wrong error message to be sent or new errors might be added later on. +@menu +* Special Errors:: +* Normal Errors:: +@end menu + +@node Special Errors, Normal Errors, Error Codes, Error Codes +@section Special Errors + +Special errors are sent in reply to syntactically incorrect calls to the +server. With the exception of the "No connections left" message, these +should never appear in the client-server dialog. If they do, there is +probably a bug in the client. + +@table @asis +@item "%% LysKOM protocol error." +The client has sent a request that does not comply with protocol A. The +server will attempt to recover from this error, but additional calls may +be silently lost, and the server may send replies that the client does +not expect. This error is also returned when the client sends an array +that is longer than the maximum allowed by the server. + +@item "%%No connections left." +This error is only sent when the client attempts to connect to the +server. It indicates that the server is not accepting additional +connections. This error is transient: the client may be able to connect +later. Clients should not attempt to connect immediately after +receiving this message. + +@item "%%Insane token length." +The client has sent a single token that is insanely long. Typically this +means that the client has sent several kilobytes worth of digits, or +something similar. This is never returned for long strings. The server +will automatically disconnect a client who sends a token with an insane +length. + +@item "%%Insane array size." +The client has send an array with a negative length. The server is not +easily fooled. The server will automatically disconnect a client who +sends an array with an insane length. + +@end table + + +@node Normal Errors, , Special Errors, Error Codes +@section Normal Errors + +Normal errors are sent in reply to syntactically correct calls to the +server. The client should accept any error code in response to any call, +even if the error code in question is not listed in the description of +the call, and even if the error code in question is not defined in the +protocol specification yet. + @table @code @item no-error (0) @@ -8011,7 +8104,7 @@ index of the illegal item. @item illegal-info-type (26) Attempt to use a Misc-Info type that the server knows nothing about. -@code{error-status} is undefined. +@code{error-status} is the type. @item already-recipient (27) Attempt to add a recipient that is already a recipient of the same type. @@ -8143,7 +8236,7 @@ specific call. -@node LysKOM Content Types +@node LysKOM Content Types, The User Area, Error Codes, Top @chapter LysKOM Content Types LysKOM defines a few special content types for texts. They are all @@ -8157,7 +8250,7 @@ text/html. * Conference Lists (x-kom/conflist):: @end menu -@node Reformattable Text (x-kom/basic) +@node Reformattable Text (x-kom/basic), The User Area (x-kom/user-area), LysKOM Content Types, LysKOM Content Types @section Reformattable Text This type of content corresponds to the mime type x-kom/basic. It is raw @@ -8181,13 +8274,13 @@ that matched that regexp is to be prefixed to all lines of the paragraph. @end itemize -@node The User Area (x-kom/user-area) +@node The User Area (x-kom/user-area), Conference Lists (x-kom/conflist), Reformattable Text (x-kom/basic), LysKOM Content Types @section The User Area -@node Conference Lists (x-kom/conflist) +@node Conference Lists (x-kom/conflist), , The User Area (x-kom/user-area), LysKOM Content Types @section Conference Lists -@node The User Area +@node The User Area, Writing Clients, LysKOM Content Types, Top @chapter The User Area The user area is a regular text that is used to store client-specific @@ -8307,7 +8400,7 @@ The default mark to set on marked texts. -@node Writing Clients +@node Writing Clients, Importing and Exporting E-Mail, The User Area, Top @chapter Writing Clients This chapter is not really part of the protocol specification, but @@ -8318,7 +8411,7 @@ it contains some information that may be useful for client writers. * Client Conventions:: Conventions clients should follow. @end menu -@node Common Commands +@node Common Commands, Client Conventions, Writing Clients, Writing Clients @section Common Commands Most clients will implement certain commands. This main purpose of this @@ -8331,17 +8424,71 @@ to answer some questions that seem to come up over and over again. * Review the last N by FOO to BAR:: @end menu -@node What do I have unread +@node What do I have unread, Only read the most recent N texts, Common Commands, Common Commands @subsection What do I have unread -@node Only read the most recent N texts +Each person has a membership list containing the conferences the persin +is a member of. Each element is an object of type Membership. Among +other things it contains the number of the conference, the priority of +the membership, when the person most recently marked a text as read in +the conference, and which texts the person has read. + +The list of read texts consists of two parts: a local text number called +@code{last-text-read} and a list of local text numbers called +@code{read-texts}. The person has marked all texts up to and including +@code{last-text-read} as read, and also the texts listed in +@code{read-texts}. All other texts in the conference are unread. Clients +can use either the @code{@ref{query-read-texts}} or +@code{@ref{get-membership}} calls to get membership data. + +The standard procedure for finding out which texts are unread is the +following: + +@enumerate +@item Call @code{@ref{get-unread-confs}} for the person. +This returns a list of conferences in which the person may have unread +texts. This call may return conferences that do not contain any unread +texts, but it will never forget to return a conference that does contain +an unread text. + +@item Call @code{@ref{query-read-texts}} for each conference returned in +the previous step. This will return the membership data for all the +conferences that may contain unread texts. + +@item Call @code{@ref{get-conf-stat}} for each conference returned in +the first step. The conference status will be needed shortly. Repeat the +following steps for each conference. + +@item Compare the highest existing local number in the conference (from +the conference status) with the @code{last-text-read} field for the +corresponding membership. If the highest existing local text is higher +than @code{last-text-read}, the conference may contain unread texts. + +@item Get part of the local to global map from the conference starting +at @code{last-text-read} and ending at the highest existing local +number. Every local number in the map that is not read according to the +membership data and that has a mapping to a global number is an unread +text. You might say that you remove the read texts from the map to get +the unread texts. + +@end enumerate + +Take care not to call get-map or get-membership too much since they tend +to be expensive operations. Use @code{get-unread-confs} and +@code{query-read-texts} to minimize the work. Another point to remember +is that the server will send asynchronous messages with information +about new texts. Clients need to listen to these messages. + + + +@node Only read the most recent N texts, Review the last N by FOO to BAR, What do I have unread, Common Commands @subsection Only read the most recent N texts -@node Review the last N by FOO to BAR +@node Review the last N by FOO to BAR, , Only read the most recent N texts, Common Commands @subsection Review the last N by FOO to BAR -@node Client Conventions +@node Client Conventions, , Common Commands, Writing Clients @section Client Conventions There are certain conventions that most clients follow, and that users @@ -8356,7 +8503,7 @@ will go away when the protocol is updated to correct these deficiencies. @end menu -@node Text formatting +@node Text formatting, Content type specification, Client Conventions, Client Conventions @subsection Text formatting Traditionally the only clients for LysKOM were text-based and only @@ -8384,7 +8531,7 @@ The same conventions apply to messages sent with the @pxref{send-message} call. -@node Content type specification +@node Content type specification, Remote control, Text formatting, Client Conventions @subsection Content type specification This convention is understood by all popular clients. If the first line @@ -8397,7 +8544,7 @@ aux-items to specify content type instead. -@node Remote control +@node Remote control, , Content type specification, Client Conventions @subsection Remote control This convention is only implemented by the Emacs-Lisp client, but since @@ -8406,7 +8553,7 @@ between clients, transferred by messages sent using @pxref{send-message}. -@node Importing and Exporting E-Mail +@node Importing and Exporting E-Mail, Type Index, Writing Clients, Top @chapter Importing and Exporting E-Mail E-mail importing and exporting is not implemented. This chapter contains @@ -8579,12 +8726,12 @@ function exporter () -@node Type Index +@node Type Index, Request Index, Importing and Exporting E-Mail, Top @chapter Type Index @printindex tp -@node Request Index +@node Request Index, , Type Index, Top @chapter Request Index @printindex fn diff --git a/doc/lyskomd.texi b/doc/lyskomd.texi index 3c1b81421439d8be2b8995cff944d4721462da07..33ac9b7ae9355dd2ddb17ae122ed52da7c0b9f96 100644 --- a/doc/lyskomd.texi +++ b/doc/lyskomd.texi @@ -1,5 +1,5 @@ \input texinfo -@c $Id: lyskomd.texi,v 1.16 1999/05/16 19:12:10 ceder Exp $ +@c $Id: lyskomd.texi,v 1.17 1999/05/18 13:06:21 byers Exp $ @c %**start of header @setfilename lyskomd.info @include version.texi @@ -50,7 +50,7 @@ another language under the same conditions as for modified versions. @end titlepage @ifinfo -@node Top +@node Top, Copying, (dir), (dir) @top lyskomd lyskomd is a server for the LysKOM conferencing system. This info file @@ -65,12 +65,14 @@ documents version @value{VERSION} of lyskomd. * Invoking updateLysKOM:: How to run updateLysKOM. * Invoking komrunning:: How to run komrunning. * Administration:: Administering a LysKOM server. -* Bugs:: Known bugs. +* Bugs:: Known bugs in lyskomd. +* DBCK Reference:: Checking and repairing the database. +* Hacking:: Notes for server developers. @end menu @end ifinfo -@node Copying +@node Copying, Overview, Top, Top @chapter Copying lyskomd is free software. It is distributed under the Gnu General Public @@ -78,7 +80,7 @@ License version 2. The file COPYING in the top level of the distribution contains the text of the license. -@node Overview +@node Overview, Installation, Copying, Top @chapter Overview LysKOM is a conferencing system@footnote{Or in modern terms, enabling @@ -117,7 +119,7 @@ future. -@node Installation +@node Installation, Configuration, Overview, Top @chapter Installation Instructions for compiling and installing lyskomd are in the file @@ -125,7 +127,7 @@ INSTALL, located in the top level of the lyskomd distribution. Installation should be straightforward on most platforms. -@node Configuration +@node Configuration, Running lyskomd, Installation, Top @chapter Configuration There are two configuration files for lyskomd. One defines the server @@ -138,7 +140,7 @@ Aux-Item List,The Aux-Item List}. @end menu -@node Server Configuration File +@node Server Configuration File, Aux-Item Definition File, Configuration, Configuration @section Server Configuration File The server reads its configuration from a configuration file. The @@ -156,7 +158,7 @@ ignored. * Parameters:: Valid configuration parameters. @end menu -@node Parameter Types +@node Parameter Types, Parameters, Server Configuration File, Server Configuration File @subsection Parameter Types Every parameter has a type. The legal types are: @@ -189,7 +191,7 @@ text number or perhaps a timeout. @end table -@node Parameters +@node Parameters, , Parameter Types, Server Configuration File @subsection Parameters @table @code @@ -601,7 +603,7 @@ status file. Actually, it is the age of the status file (named with @end table -@node Aux-Item Definition File +@node Aux-Item Definition File, , Server Configuration File, Configuration @section Aux-Item Definition File The default aux-item definition file should not be changed unless it is @@ -794,7 +796,7 @@ validation function. -@node Running lyskomd +@node Running lyskomd, Invoking updateLysKOM, Configuration, Top @chapter Running lyskomd This section explains how to run lyskomd, the files it uses and how it @@ -807,7 +809,7 @@ can be controlled while running. @end menu -@node Invoking lyskomd +@node Invoking lyskomd, Signals, Running lyskomd, Running lyskomd @section Invoking lyskomd @example @@ -828,7 +830,7 @@ The optional @var{config-file} argument can be used to specify the server configuration file. @xref{Server Configuration File}. -@node Signals +@node Signals, Files, Invoking lyskomd, Running lyskomd @section Signals It is possible to control some aspects of lyskomd using Unix signals. @@ -852,7 +854,7 @@ until the child is done and then continues. @end table -@node Files +@node Files, , Signals, Running lyskomd @section Files Used by lyskomd All file names can be changed in the server configuration file. @@ -894,7 +896,7 @@ the server configuration file. @end table -@node Invoking updateLysKOM +@node Invoking updateLysKOM, Invoking komrunning, Running lyskomd, Top @chapter Invoking updateLysKOM @example @@ -915,7 +917,7 @@ number and exit. @code{updateLysKOM} is normally run from @code{cron}; @pxref{Administration}. -@node Invoking komrunning +@node Invoking komrunning, Administration, Invoking updateLysKOM, Top @chapter Invoking komrunning @example @@ -944,7 +946,7 @@ the boot sequence. @samp{-v} and @samp{-V} causes @code{komrunning} to report its version number and exit. -@node Administration +@node Administration, Bugs, Invoking komrunning, Top @chapter Administration The first thing you will have to do is to follow the instructions in the @@ -1015,7 +1017,8 @@ by @code{updateLysKOM} the next time it is run. @code{komrunning} only removes the lock file. -@node Bugs +@node Bugs, DBCK Reference, Administration, Top +@comment node-name, next, previous, up @chapter Known Bugs @itemize @bullet @@ -1036,5 +1039,1358 @@ the edges. + +@c ====================================================================== +@c ====================================================================== +@c == == +@c == DBCK REFERENCE == +@c == == +@c ====================================================================== +@c ====================================================================== + +@node DBCK Reference, Hacking, Bugs, Top +@comment node-name, next, previous, up +@chapter DBCK Reference + +dbck is a program that can is used for minor database maintenance tasks +and for repairing a corrupt lyskomd database. + +@menu +* DBCK Overview:: Overview of dbck. +* Invoking dbck:: How to run dbck. +* DBCK Notes:: Notes about running dbck. +* DBCK Files:: Files used by dbck. +* DBCK Bugs:: Known bugs in dbck. +@end menu + + +@node DBCK Overview, Invoking dbck, DBCK Reference, DBCK Reference +@comment node-name, next, previous, up +@section Overview + +The dbck program is used for minor maintenance of the LysKOM database +and for repairing corrupt databases. In brief it performs the following +functions: + +@itemize @bullet +@item Compact the text file to remove deleted texts. +@item Repair inconsistent membership information. +@item Repair invalid recipients +@item Repair inconsistent comment links +@item Correct invalid local text numbers +@item Correct invalid text maps +@item Set special conferences +@item Convert between database formats +@end itemize + + +@node Invoking dbck, DBCK Notes, DBCK Overview, DBCK Reference +@comment node-name, next, previous, up +@section Invoking dbck + +The functionality of dbck is controlled through command-line switches. +These are documented below. + +If @code{dbck} is invoked without any options it will read the database +and report on its integrity. No files will be modified. + +@menu +* General Options:: Controlling the overall behavior of dbck. +* Database Repair Options:: Repairing errors in the LysKOM database. +* Format Conversion Options:: Converting the database file to a new format. +* Database Maintenance Options:: Options for database maintenance. +* Reporting Options:: Options controlling status reports. +@end menu + + +@node General Options, Database Repair Options, Invoking dbck, Invoking dbck +@comment node-name, next, previous, up +@subsection General Options + +These options control the general behavior of lyskomd. + +@table @asis +@item @code{-h} or @code{--help} +Give a usage message (which includes the version number and the +compiled-in default location of the config file) and exit immediately. + +@item @code{-v} or @code{--verbose} +Verbose mode. Report not only errors but the status of the database. + +@item @code{-F} or @code{--force-output} +This option forces dbck to write the database file. Normally @code{dbck} +will only write a new database file if changes have been made for some +other reason. If you want to simply convert a database from one version +to another, you will probably have to give this option. +@end table + + +@node Database Repair Options, Format Conversion Options, General Options, Invoking dbck +@comment node-name, next, previous, up +@subsection Database Repair Options + +The following options control database repair. + +@table @asis +@item @code{-i} or @code{--interactive} +Run interactively. If any inconsistency is found, a remedial cure will +be suggested and the user must confirm the correction. + +@item @code{-r} or @code{--auto-repair} +Repair simple errors without asking. + +@item @code{-c} or @code{--set-change-name} +Consider it an error if the @code{change-name} capability of a person is +not set. Due to a bug that capability was never set for newly created +persons in release 1.6.1 of lyskomd. This option can be used to repair +the damage. +@end table + + +@node Format Conversion Options, Database Maintenance Options, Database Repair Options, Invoking dbck +@comment node-name, next, previous, up +@subsection Format Conversion Options + +dbck can be used to conver the LysKOM database from one storage format +to another. This is necessary only when moving the database to a new +server version. + +@table @asis +@item @code{-F} or @code{--force-output} +This option forces dbck to write the database file. Normally @code{dbck} +will only write a new database file if changes have been made for some +other reason. If you want to simply convert a database from one version +to another, you will probably have to give this option. + +@item @code{-o} or @code{--output-version} +This option is used to set the output version of the database. This +option will normally be used in conjunction with the @code{-F} option. + +Version 1.9 of @code{lyskomd} requires database version 1; version 2.0 +requires database version 2. Versions of @code{lyskomd} prior to 1.9 +requires database version 0. Note that information is irrevocably lost +when converting from a higher to a lower database version. This options +requires an argument: the output format version. +@end table + + +@node Database Maintenance Options, Reporting Options, Format Conversion Options, Invoking dbck +@comment node-name, next, previous, up +@subsection Database Update Options + +dbck can be used to update certain aspects of the database that either +were impossible to update in early versions of protocol A or that are +inconvenient in all protocol versions. + +@table @asis +@item @code{-g} or @code{--compact-text-mass} +Do garbage collection on the texts part of the database. This removes +all unreferenced texts from the database. + +@item @code{-P} or @code{--clear-password} +Clear the password of a specified user. This option is silently ignored +if the user does not exist. This option requires an argument: the ID of +the person whose password is to be cleared. + +@item @code{-G} or @code{--grant-all} +Grant all privileges to the specified user. This option is silently +ignored if the user does not exist. This option requires an argument: +the ID of the person who is to be granted all privileges. + +@item @code{--pers-pres-conf} +Set the person presentation conference of the server to the specified +conference. Since version 1.9 of lyskomd the @code{set-info} call can be +used to do this. + +@item @code{--conf-pres-conf} +Set the conference presentation conference of the server to the specified +conference. Since version 1.9 of lyskomd the @code{set-info} call can be +used to do this. + +@item @code{--motd-conf} +Set the message-of-the-day conference of the server to the specified +conference. Since version 1.9 of lyskomd the @code{set-info} call can be +used to do this. + +@item @code{--kom-news-conf} +Set the news-about-lyskom conference of the server to the specified +conference. Since version 1.9 of lyskomd the @code{set-info} call can be +used to do this. + +@item @code{--motd-of-kom} +Set the message of the day of the server to the specified text. Since +version 1.9 of lyskomd the @code{set-info} call can be used to do this. +@end table + + +@node Reporting Options, , Database Maintenance Options, Invoking dbck +@comment node-name, next, previous, up +@subsection Reporting Options + +These options control reporting of information about the database. + +@table @asis +@item @code{-s} or @code{--print-statistics} +Gather statistics about the lengths of texts. A table containing the +frequence of all lengths that are currently present is printed. + +@item @code{-t} or @code{--list-text-no} +Print ``Checking @i{text-no}'' for every text that examined. +@b{Warning:} This produces lots of output. +@end table + + +@node DBCK Notes, DBCK Files, Invoking dbck, DBCK Reference +@comment node-name, next, previous, up +@section Notes for DBCK + +The messages ``Conference @var{conf-no} has a bad Text-list. Starts with +0'' and ``Person @var{pers-no} has created @var{num} conferences, not +@var{num} (as said in person-stat).'' are normal. If you get them when +you specify the @code{-g} option, let @code{dbck} repair them and run +@code{dbck -g} again. + + +@node DBCK Files, DBCK Bugs, DBCK Notes, DBCK Reference +@comment node-name, next, previous, up +@section Files Used by dbck + +dbck uses the same files as @code{lyskomd} (@xref{(lyskomd)}.) + +All file names can be changed in the server configuration file. +@xref{(lyskomd)Parameters}. + +@table @file +@item /usr/lyskom +Default value of @code{Prefix}. The default of this value is set at compile +time, but it can be changed in the server configuration file. +@xref{(lyskomd)Parameters}. + +@item @code{Prefix}/db/lyskomd-data +Half of the database: all status information. + +@item @code{Prefix}/db/lyskomd-texts +The other half of the database: the actual texts. + +@item @code{Prefix}/db/lyskomd-backup +A backup copy of @code{lyskomd-data}. Never, ever delete this file +unless you know what you are doing, or you may lose the entire data +base. Most of the time this is the only complete database file! + +@end table + + +@node DBCK Bugs, , DBCK Files, DBCK Reference +@comment node-name, next, previous, up +@section Known Bugs + +@itemize @bullet +@item Does not lock the database. +@item Never checks if the database is locked. +@item Should have an unlock database option. +@item Does not check that the data file and text file are consistent. +@end itemize + + + + + +@c ====================================================================== +@c ====================================================================== +@c == == +@c == LYSKOMD HACKING GUIDE == +@c == == +@c ====================================================================== +@c ====================================================================== + + +@node Hacking, , DBCK Reference, Top +@comment node-name, next, previous, up +@chapter Hacking lyskomd + + +@menu +* The Database:: +* Adding Configuration Parameters:: How to add configuration options. +* Adding Asynchronous Messages:: Adding protocol A messages. +* Adding a New Protocol Request:: Adding protocol A calls. +* Adding Aux-Item Types:: Adding predefined aux item types. +* Modifying Stored Types:: Modifying types stored in the DB. +* Notes:: Mixed notes. +* Debugging and Testing:: How to test and debug the server. +@end menu + +@node The Database, Adding Configuration Parameters, Hacking, Hacking +@comment node-name, next, previous, up +@section The Database + +@c FIXME: ramkomd �r d�d! L�nge leve LysKOM! +@c FIXME: +@c FIXME: Jag har tillsammans med Inge kommit p� ett s�tt att dels f� ner +@c FIXME: v�ntetiden i samband med syncningar till <1 sekund, dels f� ner +@c FIXME: storleken p� serverprocessen till mer rimliga niv�er. Denna l�sning +@c FIXME: lider dock av det stora problemet att den kr�ver dubbelt s� mycket +@c FIXME: diskutrymme som den egentligen beh�ver. Det g�r �ven ramkomd, s� det +@c FIXME: �r ingen f�rs�mring i det avseendet. Dock �r detta bara en tempor�r +@c FIXME: l�sning i v�ntan p� ldb. +@c FIXME: +@c FIXME: Varf�r spara allt p� en g�ng? Varf�r inte spara en liten del av filen +@c FIXME: i taget, och utf�ra n�gra atomiska anrop mellan varje liten +@c FIXME: delsynkning? Ungef�r s� t�nkte jag n�r jag kom p� f�ljande schema f�r +@c FIXME: hur man kan g�ra det hela b�ttre �n det �r nu. +@c FIXME: +@c FIXME: Den databas som ligger p� fil �r en �gonblickbild (snapshot) av det +@c FIXME: som finns i LysKOM. S� �r det i ramkomd; s� blir det i diskomd. +@c FIXME: (B�ttre namn, n�gon? lyskomd tycker jag �r reserverat f�r den version +@c FIXME: som har en riktig cache&ldb.) I ramkomd skrivs allt ut p� disk +@c FIXME: samtidigt. I diskomd minns man bara vad som skall sparas, och sparar +@c FIXME: bara en bit i taget. +@c FIXME: +@c FIXME: I ramkomd finns allt inne i ram-minnet (i teorin. I praktiken �r det +@c FIXME: mesta utswappat - n�got som m�rks varje g�ng det �r dags att synca!). +@c FIXME: I diskomd ligger det mesta p� disk. I minnet finns dels det som har +@c FIXME: anv�nts nyligen, dels det som �r �ndrat och �nnu ej syncat. Diskomd +@c FIXME: har alltid minst en, ofta tv�, databasfiler �ppna: +@c FIXME: +@c FIXME: Fil A Senaste kompletta fil. +@c FIXME: Fil B Fil under uppbyggnad. +@c FIXME: +@c FIXME: (Dessutom textmassefilen, precis som ramkomd nuf�rtiden.) +@c FIXME: +@c FIXME: S� till detaljerna: +@c FIXME: +@c FIXME: Det finns tre typer av objekt som ber�rs av den h�r �ndringen: +@c FIXME: Text_stat, Person och Conference. Jag anv�nder Person som ett exempel +@c FIXME: nedan. +@c FIXME: +@c FIXME: I ram-cache.c finns en array +@c FIXME: +@c FIXME: Person *pers_arr[ MAX_CONF ]; +@c FIXME: +@c FIXME: Den byts mot +@c FIXME: +@c FIXME: Cache_node *pers_arr[ MAX_CONF ]; +@c FIXME: +@c FIXME: typedef struct cache_node � +@c FIXME: Bool exists; +@c FIXME: Bool exists_b; +@c FIXME: Bool dirty; /* �r *ptr modifierad? */ +@c FIXME: void *snap_shot; +@c FIXME: void *ptr; +@c FIXME: off_t pos; +@c FIXME: off_t pos_b; +@c FIXME: struct cache_node *lru_link; +@c FIXME: int lock_cnt; +@c FIXME: � Cache_node; +@c FIXME: +@c FIXME: +@c FIXME: +@c FIXME: UPPSTART +@c FIXME: +@c FIXME: N�r servern startas scannar den igenom datafilen (fil A) och fyller i +@c FIXME: f�ltet exists till TRUE/FALSE och pos till att peka p� b�rjan av det +@c FIXME: st�lle i filen d�r data ligger. �vriga f�lt s�tts till FALSE/NULL/0. +@c FIXME: +@c FIXME: +@c FIXME: +@c FIXME: CACHE_GET_PERSON +@c FIXME: +@c FIXME: N�r ovanliggande rutiner vill l�sa en person h�nder f�ljande: +@c FIXME: +@c FIXME: !exists Returnera NULL +@c FIXME: ptr != NULL L�gg noden f�rst i lru_link. Returnera ptr. +@c FIXME: snap_shot != NULL Kopiera snap_shot till ptr. L�gg noden f�rst i +@c FIXME: lru_link. Returnera ptr. +@c FIXME: annars L�s in fr�n fil A, s�tt ptr till den inl�sta +@c FIXME: structen, l�gg noden f�rst i lru_link, +@c FIXME: returnera ptr. +@c FIXME: +@c FIXME: +@c FIXME: MARK_PERSON_AS_CHANGED +@c FIXME: +@c FIXME: N�r n�got har �ndrats s�tts dirty-flaggan till TRUE. +@c FIXME: +@c FIXME: +@c FIXME: CREATE_PERSON +@c FIXME: +@c FIXME: S�tt exists=TRUE, dirty=TRUE, ptr och lru. +@c FIXME: +@c FIXME: +@c FIXME: DELETE_PERSON +@c FIXME: +@c FIXME: S�tt exists=FALSE. ptr=NULL. Troligtvis error om lock_cnt != 0. +@c FIXME: +@c FIXME: +@c FIXME: +@c FIXME: THROW-OUT +@c FIXME: +@c FIXME: F�r att inte diskomd ska bli f�r stor sl�ngs saker ut ur cachen. +@c FIXME: Algoritm: tag f�rsta elementet i lru_list. Om dirty==FALSE och +@c FIXME: ptr!=NULL och lock_cnt==0 s� frig�r ptr. Upprepa tills antalet noder +@c FIXME: med ptr!=NULL och dirty==FALSE �r mindre �n antalet "rena" element man +@c FIXME: vill ha inne i minnet. (Smutsiga element sl�ngs aldrig ut.) +@c FIXME: +@c FIXME: +@c FIXME: LOCK_PERSON +@c FIXME: +@c FIXME: �ka lock_cnt. +@c FIXME: +@c FIXME: +@c FIXME: UNLOCK_PERSON +@c FIXME: +@c FIXME: Minska lock_cnt. +@c FIXME: +@c FIXME: +@c FIXME: PRE-SYNC +@c FIXME: +@c FIXME: Utsparningen till fil sker i tre steg. F�rst sveper man �ver alla +@c FIXME: Cache_noder. F�r alla som har dirty=TRUE g�r man f�ljande: +@c FIXME: +@c FIXME: if ( lock_cnt == 0 ) � +@c FIXME: snap_shot = ptr; (Pekartilldelning, ej kopiering av inneh�llet.) +@c FIXME: ptr = NULL; +@c FIXME: Ta bort ptr ur lru-kedjan. +@c FIXME: � else � +@c FIXME: snap_shot = copy(ptr); +@c FIXME: � +@c FIXME: +@c FIXME: dirty = FALSE; +@c FIXME: +@c FIXME: F�r _alla_ noder g�rs dessutom f�ljande: +@c FIXME: +@c FIXME: b_exists==exists; +@c FIXME: +@c FIXME: +@c FIXME: SYNC +@c FIXME: +@c FIXME: Steg tv� utf�rs en liten bit i taget. Till exempel s� skulle man kunna +@c FIXME: spara en person efter varje atomiskt anrop, eller s�. +@c FIXME: +@c FIXME: b_exists==FALSE? S�tt pos_b. Skriv "@@\n" till fil B. +@c FIXME: �r snap_shot != NULL? S�tt pos_b. Skriv ut inneh�llet i snap_shot +@c FIXME: till fil B. +@c FIXME: dirty==FALSE && ptr!=NULL Skriv ut inneh�llet i ptr till fil B. +@c FIXME: annars: Kopiera fr�n fil A till fil B. (Eftersom man +@c FIXME: vet b�de var blocket b�rjar och slutar kan man +@c FIXME: kopiera blocket utan att bry sig om vad som +@c FIXME: st�r i det -> v�ldigt lite CPU g�r �t). +@c FIXME: +@c FIXME: +@c FIXME: +@c FIXME: +@c FIXME: POST-SYNC +@c FIXME: +@c FIXME: N�r alla Person:er har hanterats som i SYNC ovan �r det dags f�r det +@c FIXME: tredje steget. D� g�r man igenom alla Cache_node:er och g�r f�ljande: +@c FIXME: +@c FIXME: pos = pos_b; +@c FIXME: file_b = FALSE; +@c FIXME: free(snap_shot); +@c FIXME: snap_shot = NULL; +@c FIXME: +@c FIXME: Fil B som man f�rut hade �ppen f�r skrivning �ppnar man i st�llet f�r +@c FIXME: l�sning som fil A. +@c FIXME: +@c FIXME: +@c FIXME: +@c FIXME: +@c FIXME: ANM�RKNINGAR +@c FIXME: +@c FIXME: Inneh�llet i snap_shot �r alltid "smutsigt" j�mf�rt med inneh�llet i +@c FIXME: fil A. Det som snap_shot pekar p� finns aldrig med i lru-kedjan. +@c FIXME: + + + +@node Adding Configuration Parameters, Adding Asynchronous Messages, The Database, Hacking +@comment node-name, next, previous, up +@section Adding Configuration Parameters + +Make sure that you really understand what you want to configure. Think +it over again. Find a good, descriptive name for it. + +Decide what values the parameter can be set to. Integers? Booleans? + +Document the parameter in @code{lyskomd.texi}. + +Add a field to @code{stuct kom_par} in @code{param.h}. + +Add it to @code{parameters[]} in @code{server-config.c}. See +@code{conf-file.h} and maybe @code{conf-file.c} for information on this +structure. + +Make sure that the parameter is used instead of any previous hard-coded +value. Make sure that @code{dbck} can cope with it. + + +@node Adding Asynchronous Messages, Adding a New Protocol Request, Adding Configuration Parameters, Hacking +@comment node-name, next, previous, up +@section Adding Asynchronous Messages + +@table @code + +@item async.h +Add the message in @code{typedef enum @{ @} Async}. Make sure that +@code{ay_dummy_last} is one more than any other message. If the message +is to be sent by default, which is @i{not} recommended, place its number +info @code{ASYNC_DEFAULT_MESSAGES}. + +@item prot-a-send-async.c +@item prot-a-send-async.h +Write a function that sends the message. This function is responsible +for writing the message to a particular connection and for ensuring that +the message is not sent to clients who do not want it. Make sure that +the second argument to @code{async_header} really is the number of +elements being sent. Arrays count as two elements: the item count and +the elements. + +@item send-async.c +@item send-async.h +Write a function that sends the message to appropriate clients. This +function is responsible for checking that async messages should be sent +at all, for each client check if it allowed to see the message and +ensure that the protocol specified by the connection is appropriate. The +send function should either take a @code{struct connection *} as an +argument and send the message to that connection, or loop over all +connections. Most send functions take a connection pointer; the looping +is dealt with elsewhere. + +@item Make sure that the message is sent in appropriate places. + +@item Document the message type in @code{Protocol-A.texi}. + +@end table + +@menu +* Function Templates for prot-a-send-async.c:: +* Function Templates for send-async.c:: +@end menu + + +@node Function Templates for prot-a-send-async.c, Function Templates for send-async.c, Adding Asynchronous Messages, Adding Asynchronous Messages +@comment node-name, next, previous, up +@subsection Function Templates for prot-a-send-async.c + +This is what a typical function in @code{prot-a-send-async.c} should +look like. This function is responsible for checking that the client is +accepting the message and writing the message itself to the connection. + +@example +void +prot_a_async_@i{something}(Connection *cptr, + @i{parameters}) +@{ + ASYNC_CHECK_ACCEPT(cptr, ay_@i{something}); + async_header(cptr, @i{num_tokens}, ay_@i{something}); + /* Output the body of the message */ + async_trailer(cptr); +@} +@end example + + +@node Function Templates for send-async.c, , Function Templates for prot-a-send-async.c, Adding Asynchronous Messages +@comment node-name, next, previous, up +@subsection Function Templates for send-async.h + +This is what a typical function in @code{send-async.c} should look like. +This function is responsible for sending the message to all connections +that are appropriate, not sending it if the server is not supposed to +send messages at all, and for checking that the protocol specified by +the client is one the server knows. + +@example +void async_@i{something}( @i{parameters} ) +@{ + Connection *cptr; + Session_no i = 0; + + if (!param.send_async_messages) + return; + + while ((i = traverse_connections(i)) != 0) + @{ + cptr = get_conn_by_number(i); + + switch(cptr->protocol) + @{ + case 0: + /* No protocol specified yet */ + break; + case 'A': + /* Check that connection is logged on. We might + want to check other things here too, such as + if the connection is allowed to see the message */ + if (cptr->username_valid == TRUE) + prot_a_async_@i{something}(cptr, @i{parameters}); + break; + default: + restart_kom("async_@i{something}(): bad protocol.\n"); + break; + @} + @} +@} +@end example + +Template for a function that sends to a single connection: +@example +void async_@i{something}(struct connection *cptr, + @i{parameters}) +@{ + if (!param.send_async_messages) + return; + + switch(cptr->protocol) + @{ + case 0: + /* No protocol specified yet */ + break; + case 'A': + /* Check that connection is logged on. We might + want to check other things here too, such as + if the connection is allowed to see the message */ + if (cptr->username_valid == TRUE) + prot_a_async_@i{something}(cptr, @i{parameters}); + break; + default: + restart_kom("async_@i{something}(): bad protocol.\n"); + break; + @} +@} +@end example + + +@node Adding a New Protocol Request, Adding Aux-Item Types, Adding Asynchronous Messages, Hacking +@comment node-name, next, previous, up +@section Adding a New Protocol Request + +Before doing anything, think again. Make sure that the protocol request +is needed, is in line with the rest of the protocol, behaves the way +people want it to, and that everyone involved agrees that it is a good +idea. + +@enumerate +@item Document the request in @code{Protocol-A.texi} + +@item Declare the function in @code{include/services.h} + +@item Declare the function @i{last} in @code{server/fncdef.txt}. It +should be given a call number one higher than the currently existing +highest contiguous call number. + +@item If the function takes a pn input parameter of a new type, changes +need to be made in several places. @xref{Adding New Input Types}. + +@item If the function takes too many parameters of type @code{num}, +@code{string} or @code{c_string}, the definition of @code{Connection} in +@code{server/connection.h} has to be changed. + +@item If the function has an output parameter of a new type, changes +need to be made in several plaves. @xref{Adding New Result Types}. + +@item Write the function in a suitable place in the server directory. + +@item Write tests for the new function in +@code{server/testsuite/lyskomd.0}. Write one file for testing the +functionality. Write tests in @code{01.exp} (behavior when the client is +not logged on) and @code{03.exp} (normal behavior.) + +@item Run the testsuite to make sure nothing old has been broken. +@end enumerate + +It is no longer necessary to update prot_a_is_legal_fnc since it is +generated automatically. + + +@menu +* Adding New Input Types:: Procedure for adding input types. +* Adding New Result Types:: Procedure for adding output types. +* Modifying Output Types:: Procedure for modifying output types. +@end menu + + +@node Adding New Input Types, Adding New Result Types, Adding a New Protocol Request, Adding a New Protocol Request +@comment node-name, next, previous, up +@subsection Adding New Input Types + +Changes need to be made in the following files: + +@table @code +@item Protocol-A.texi +Document the new type. + +@item server/call-switch.awk +The new type has to be added to the cascaded ifs that translate the type +name to code that points to the appropriate field in a +@code{Connection} structure. + +@item server/prot-a-parse-arg-c.awk +The new type has to be added to the cascaded ifs that create the +argument list parser. + +@item server/connections.h +The definition of @code{Connection} must be extended with a field where +the parse value can be stored. Don't even think about trying to reuse an +existing field. It's more trouble than it's worth. + +@item server/connection.c +Free the contents of the field in @code{free_parsed()}. + +@item server/internal-connections.c +Initialize the contents of the field in @code{init_connection()}. + +@end table + + + +@node Adding New Result Types, Modifying Output Types, Adding New Input Types, Adding a New Protocol Request +@comment node-name, next, previous, up +@subsection Adding New Result Types + +Changes need to be made in the following files: + +@table @code +@item Protocol-A.texi +Document the new type. + +@item server/prot-a.c +Add a line in the @code{prot_a_reply} switch that calls the correct +output function. + +@item server/connections.h +Add the type in @code{Res_type}and @code{Result_holder}. + +@item server/prot-a-output.c +@item server/prot-a-output.h +Write a function that outputs the new type +to a connection. Use the existing functions as templates. +@end table + + +@node Modifying Output Types, , Adding New Result Types, Adding a New Protocol Request +@comment node-name, next, previous, up +@subsection Modifying Output Types + +When you modify an existing type you have to rename the old version of +the type since it will still be used in existing calls. The convention +hs previously been to rename @code{Something} to @code{Something_old}, +but the preferred method is to append an underscore and the protocol +version in which the current version of the type was introduced. For +example, if the type @code{Gazonk} was introduced in protocol version +11, and a new version is to be introduced in protocol version 15, the +current @code{Gazonk} structure is renamed to @code{Gazonk_11}. + +This is to avoid names like @code{Something_older}, +@code{Something_oldest} and @code{Something_Truly_Ancient}. + + +Changes need to be made to the following files: + +@table @code +@item Protocol-A.texi +Document the new type in the appropriate section. Rename the existing +type in the type documentation and in all calls that return it. Be +thorough! + +@item fncdef.txt +Rewrite all calls that use the modified type so they use the old version +of the type. + +@item prot-a.c +Modify the current line in @code{prot_a_reply} for the existing version +of the type, and add a new line for the new version of the type. + +@item connections.h +Modify the existing entry in @code{Res_type} and @code{Result_holder}, +if necessary. This should only be necessary if the server uses both a +new and old type internally, which is not recommended. Add new entries +for the new version of the type. + +@item prot-a-output.h +@item prot-a-output.c +Rename the existing output routing according to the new name of the +type. Write a new output routine for the new version of the type. + +@item memory.c +If there are functions for the type in @code{memory.c}, make sure that +your new type is initialized, cleared and copied in an appropriate +manner. + +@end table + +If the type you modify is stored in the database, make sure it gets +saved properly. @xref{Modifying Stored Types}. + + +@node Adding Aux-Item Types, Modifying Stored Types, Adding a New Protocol Request, Hacking +@comment node-name, next, previous, up +@section Adding Aux-Item Types + +@enumerate +@item Document the new type in Protocol-A.texi + +@item Write a definition of the new type in +@code{run-support/aux-items.conf}. + +@item Write test cases for the new type in +@code{server/testsuite/lyskomd.0/03.exp}. + +@item If the new type requires add, delete or undelete triggers that do +not already exist, declare the trigger functions in @code{aux-items.c} +and add them to the @code{aux_item_triggers} array in the same file. + +@item If the new type is so complex that is cannot be fully defined in +@code{aux-items.conf}, then add it to the @code{compiled_aux_items} +array in @code{aux-items.c}. Note that this functionality has not been +tested until someone actually adds one of these beasts, so watch your +step. + +@end enumerate + + +@node Modifying Stored Types, Notes, Adding Aux-Item Types, Hacking +@comment node-name, next, previous, up +@section Modifying Stored Types + +If you want to modify an existing type that is stored in the database, +think again. Can the job be done with aux-items instead? Is it really +necessary? + +Be very, very careful when doing this. You have to make sure that the +type as sent in old calls and async messages is not changed in any way. +You have to make sure that the type can be stored to and read from the +database. + +@enumerate +@item Document the changes in Protocol-A.texi if the change is visible +in the protocol. + +@item Bump the database version number by one for the next release of +the server. + +@item Write a function in @file{ram-output.c} to output the new format. +Update all old functions in @file{ram-output.c} that are database +version dependent so that they can deal with the new database format. + +@item Write a function in @file{ram-parse.c} to read the new format. +Update all old functions in @file{ram-parse.c} that are database version +dependent so that they can deal with the new database format. + +@item Set the default database format in @file{ram-parse.c} and +@code{ram-output.c}. The variables to change are @code{input_format} and +@code{output_format}, respectively. + +@item Don't forget to update the functions in @file{memory.c} + +@end enumerate + +@menu +* Template for ram-output.c:: +* Template for ram-parse.c:: +@end menu + + +@node Template for ram-output.c, Template for ram-parse.c, Modifying Stored Types, Modifying Stored Types +@comment node-name, next, previous, up +@subsection Template for ram-output.c + +For types that can be output in several different formats, use the +following templates for them. You have to be able to output in all +formats, or @code{dbck} will be unable to convert between formats. + +@example +static void +foutput_@i{something}_0(FILE *fp, @i{something} *o) +@{ + /* Output version 0 of @i{something} */ +@} + +static void +foutput_@i{something}_1(FILE *fp, @i{something} *o) +@{ + /* Output version 1 of @i{something} */ +@} + +static void +foutput_info_2(FILE *fp, @i{something} *o) +@{ + /* Output version 2 of @i{something} */ +@} + + +void foutput_@i{something}(FILE *fp, @i{something} *o) +@{ + switch(output_format) + @{ + case 0: + foutput_@i{something}_0(fp, info); + break; + case 1: + foutput_@i{something}_1(fp, info); + break; + case 2: + foutput_@i{something}_2(fp, info); + break; + default: + restart_kom("unknown database format: %d", output_format); + break; + @} +@} +@end example + +Note that if two versions are the same, only write one functions. For +example, if version 0 and version 1 are the same, only write an +@code{foutput_@i{something}_0} function and call it from both case 0 and +case 1. + +@node Template for ram-parse.c, , Template for ram-output.c, Modifying Stored Types +@comment node-name, next, previous, up +@subsection Template for ram-parse.c + +@example +static Success +fparse_@i{something}_0(FILE *fp, @i{something} *o) +@{ + /* Parse version 0 */ + return OK; +@} + +static Success +fparse_@i{something}_1(FILE *fp, @i{something} *o) +@{ + /* Parse verson 1 */ + return OK; +@} + +static Success +fparse_@i{something}_2(FILE *fp, @i{something} *o) +@{ + /* Parse verson 2 */ + return OK; +@} + +extern Success +fparse_@i{something}(FILE *fp, @i{something} *o) +@{ + if ( fparse_long_errors != 0 ) + @{ + log("fparse_info(): fparse_long_errors == %d on entry. Reset.\n", + fparse_long_errors); + fparse_long_errors = 0; + @} + + switch (input_format) + @{ + case 0: + return fparse_@i{something}_0(fp, o); + break; + case 1: + return fparse_@i{something}_1(fp, o); + break; + case 2: + return fparse_@i{something}_2(fp, o); + break; + default: + restart_kom("unknown input format: %d\n", input_format); + return FAILURE; + break; + @} +@} +@end example + +Note that if two versions are the same, only write one functions. For +example, if version 0 and version 1 are the same, only write an +@code{fparse_@i{something}_0} function and call it from both case 0 and +case 1. + + +@node Notes, Debugging and Testing, Modifying Stored Types, Hacking +@comment node-name, next, previous, up +@section Hacking Notes + +@menu +* Parsing Bit Fields:: How to parse bit fields properly. +* Membership Notes:: How members and memberships are handled. +* Linking Pairs of Aux Items:: How to link pairs of aux items. +* Notes for fncdef.txt:: Format of the fncdef.txt file. +* Traversing Connections:: How to traverse connections in lyskomd. +@end menu + + +@node Parsing Bit Fields, Membership Notes, Notes, Notes +@comment node-name, next, previous, up +@subsection Parsing Bit Fields + +The parser for a bit field parameter type should be very tolerant of the +length of the token. Anything from a single bit and up should be +permitted. The parser should use default values for bits that are not +provided and ignore extra bits. + +Here is a model function: + +@example +void +prot_a_parse_bitfield(Connection *client, + Bitfield *res) +@{ + String token; + String_size len; + + token = prot_a_get_token(client); + len = s_strlen(token); + if (len <= 0) + longjmp(parse_env, ISC_PROTOCOL_ERR); + + init_bitfield(res); + switch (len = s_strlen(token)) + @{ + default: + case 8: res->bit_8 = token.string[ 7 ]; + case 7: res->bit_7 = token.string[ 6 ]; + case 6: res->bit_6 = token.string[ 5 ]; + case 5: res->bit_5 = token.string[ 4 ]; + case 4: res->bit_4 = token.string[ 3 ]; + case 3: res->bit_3 = token.string[ 2 ]; + case 2: res->bit_2 = token.string[ 1 ]; + case 1: res->bit_1 = token.string[ 0 ]; + @} +@} +@end example + +The function gets the token, checks the sanity of the length, then +initialized the result to its default values. Then it does a switch on +all token lengths that are equal to or smaller than the number of bits +the server knows about. The fall-through ensures that all bits in the +token are read. + + +@node Membership Notes, Linking Pairs of Aux Items, Parsing Bit Fields, Notes +@comment node-name, next, previous, up +@subsection Membership Notes + +The @code{position} field in the membership is @i{not} stored. It has to +be set every time a membership is requested for transmission to the +client. + + + +@node Linking Pairs of Aux Items, Notes for fncdef.txt, Membership Notes, Notes +@comment node-name, next, previous, up +@subsection Linking Pairs of Aux Items + +Sometimes two aux items need to work in tandem. The first instance of +this was the FAQ and FAQ-for-conference items. The FAQ item contains the +text number of a text that is a FAQ for a conference. The +FAQ-for-conference item contains the conference for which a text is a +FAQ. This is needed so that deletion of the text properly removes the +aux-item on the conf (plus, it's nice to be able to see that a text is a +FAQ.) + +The @code{linked_item} field in the Aux_item structure is for linking +items. The linking must be managed through the use of triggers. This +field is not visible in the protocol. It is saved in the database. It is +not possible to have more than one link per item. + +Please remember the following points. + +@itemize @bullet + +@item The target of a link should have a link back. All links need to go +both ways. + +@item In the add trigger for one end, create the other end of the link +and set the @code{linked_item} field in both items. Don't forget to mark +the objects at both ends as changed. + +@item Deletion and undeletion of the other side of the link will be +managed automatically. You don't need delete and undelete triggers +simply to destroy the other side of a link. + +@item Don't kill the server because one end is missing. It is possible +for the administrator to remove an item manually. Log a message and +continue working. + +@end itemize + + + + + + +@node Notes for fncdef.txt, Traversing Connections, Linking Pairs of Aux Items, Notes +@comment node-name, next, previous, up +@subsection Notes for fncdef.txt + +The fncdef.txt file is used to define the RPC functions. Each line +consists of the call number, the return type of the call, the parameters +and the output types of the call. + +Some examples: + +@example + 10 number create_conf_old c_string (param.conf_name_len) conf_type + 12 success lookup_name c_string (param.conf_name_len) : conf_list +@end example + +The first line defines a call named @code{create_conf_old} that takes +two arguments, a string that can only be as long as +@code{param.conf_name_len} and a @code{conf_type}. It returns a number +to the client. If the service call returns -1, the server will return an +error. The @code{create_conf_old} call has RPC number 10. + +The second line defines a call named @code{lookup_name} that takes a +string argument that can be no longer than @code{param.conf_name_len}, +and returns a @code{conf_list}. The service call returns a +@code{Success}. If it does not return @code{OK}, the server will return +an error. The @code{lookup_name} call has RPC number 12. + + +@subsubsection Scripts That Use fncdef.txt + +The following scripts operate on @code{fncdef.txt}. If you make +modifications to the format of @code{fncdef.txt}, you have to update +these scripts. + +@table @code +@item call-switch.awk +Generates @code{call-switch.incl}, which is included by +@code{connections.c} + +@item com-h.awk +Generates @code{com.h}, which is included by several files. + +@item fnc-def-init.awk +Generates @code{fnc-def-init.incl}, which is included by +@code{connections.c}. + +@item prot-a-is-legal-fnc.awk +Generates @code{prot-a-is-legal-fnc.incl}, which is included by +@code{prot-a.c} + +@item prot-a-parse-arg-c.awk +@item prot-a-parse-arg-h.awk +Generates @code{prot-a-parse-arg.c} and @code{prot-a-parse-arg.h}. +@end table + + +@node Traversing Connections, , Notes for fncdef.txt, Notes +@comment node-name, next, previous, up +@subsection Traversing Connections + +Since session 0 is interpreted as the currently active session by +get_conn_by_number it is important to be careful when traversing +sessions. Code like this does not work since it will do one iteration +through the loop with @code{sess} set to zero. This formerly caused +@code{get_conn_by_number} to return @code{NULL}, but now causes it to +return the session pointer for the current session. + +@example + for (sess = 0; (sess = traverse_connections(sess)) != 0; ) + @{ + cptr = get_conn_by_number(sess); + ... + @} +@end example + +The canonical traversal code looks like this: + +@example + Session_no session = 0; + while ((session = traverse_connections(session)) != 0) + @{ + cptr = get_conn_by_number(session); + ... + @} +@end example + +This code has @code{session} set to a session number before ever +entering the loop. + + +@node Debugging and Testing, , Notes, Hacking +@comment node-name, next, previous, up +@section Debugging and Testing + +We're slowly adding support for debugging and testing lyskomd properly. + +@menu +* The Test Suite:: The lyskomd regression test suite. +* Configuration Options:: Debugging options for the configure script. +* Coverage Testing:: How to do coverage testing with gcov. +* Debug Calls:: Special protocol A calls for testing. +@end menu + +@node The Test Suite, Configuration Options, Debugging and Testing, Debugging and Testing +@comment node-name, next, previous, up +@subsection The Test Suite + +The lyskomd test suite is in src/server/testsuite. Please extend this +with additional test cases every time you make modifications to the +server. Run the test suite often to make sure that your changes did not +break anything. + +The file config/prot-a.exp contains some support for protocol A. Don't +use these functions in test cases. Use them to set up the inital +database and for things tht have to be done, such as logins and enabling +privileges, but that don't need to be tested. Also, don't count on all +the code in prot-a.exp to be fully functional. Add new functions to this +file as you see fit. + +The basic structure of a test case is the following: + +@example +source "config/prot-a.exp" +read_versions + +lyskomd_start +client_start 0 +talk_to client 0 +kom_connect "DejaGnu test suite" + +@i{The test cases} + +talk_to client 0 +kom_logout +kom_login 5 [holl "gazonk"] 0 +kom_enable 255 +send "9999 44 0\n" +simple_expect "=9999" + +client_death 0 +lyskomd_death +@end example + +Use the existing test cases as templates. + + +@node Configuration Options, Coverage Testing, The Test Suite, Debugging and Testing +@comment node-name, next, previous, up +@subsection Configuration Options + +There are several testing and debugging-related configuration options +for lyskomd. Some of them also apply to libisc. + +@table @code +@item --with-purify +Build lyskomd with Purify. This currently does not work. + +@item --with-efence +Build lyskomd with Electric Fence for checking buffer overruns. This +option does work. + +@item --with-checker +Build lyskomd with Gnu Checker for checking memory accesses, leaks, file +descriptors and all kinds of stuff. As of Checker version 0.99.6, Gnu +Checker cannot deal with lyskomd. Once built, and this requires +modifications to Checker (at least on Linux) it reports spurious errors. +Still, the option is here for those who want to try it out. + +@item --with-gcov +Build lyskomd with instrumentation for @code{gcov}. You have to use this +option if you want to run @code{gcov} on lyskomd. For @code{gcov} to be +effective, you should turn off optimization as well. + +@item --with-optimization=@i{value} +Build lyskomd with the specified level of optimization. Use either +numeric values to select the level of optimization, or say +@code{--with-optimization=no} or @code{--without-optimization} to turn +optimization off. + +@end table + + + +@node Coverage Testing, Debug Calls, Configuration Options, Debugging and Testing +@comment node-name, next, previous, up +@subsection Coverage Testing + +When you write new code, make sure that it is completely covered by the +test suite. Run the lyskomd configure script with the +@code{--with-gcov}, @code{--with-debug-calls} and +@code{--without-optimization} flags to instrument the server for +coverage testing with gcov. + +If you run configure without the @code{--without-optimization} option, +the server will be compiled with optimizations on. This is fine, but the +coverage data from gcov isn't completely reliable since parts of the +program may have been optimized out of existance. + +Recompile everything, then run the test suite. Next do @code{gcov -f } +@i{filename} to compute coverage information for the file @i{filename}. +The resulting file @i{filename}@code{.gcov} shows which lines have been +executed, and which haven't been run. Try to get 100% coverage. + + +@node Debug Calls, , Coverage Testing, Debugging and Testing +@comment node-name, next, previous, up +@subsection Debug Calls + +Run the configure script with @code{--with-debug-calls} to compile in +support for debugging calls in the server. These calls are strictly for +making testing easier (or possible.) They are not official, and they may +change at any time. + +@menu +* memory-info:: Get information from malloc (1000) +* set-marks:: Set the number of marks on a text (1001) +* backdate-text:: Change the creation date of a text (1002) +@end menu + +@node memory-info, set-marks, Debug Calls, Debug Calls +@comment node-name, next, previous, up +@subsubsection memory-info (DEBUG) Experimential + +@findex memory-info +@example + memory-info [1000] ( ) + -> (( arena : INT32; + ordblks : INT32; + smblks : INT32; + hblks : INT32; + hblkhd : INT32; + usmblks : INT32; + fsmblks : INT32; + uordblks : INT32; + fordblks : INT32; + keepcost : INT32; )); +@end example + +This call returns the data returned by @code{mallinfo} in the server. +See the man page for @code{mallinfo} for explanations of the fields. + +@node set-marks, backdate-text, memory-info, Debug Calls +@comment node-name, next, previous, up +@subsubsection set-marks (DEBUG) Experimental + +@findex set-marks +@example + set-marks [1001] (( text-no : Text_no; + no-of-marks : INT32; )) + -> ( ); +@end example + +Set the number of marks on text @code{text-no} to @code{no-of-marks}, +regardless of how many marks it really has. This call is useful for +forcing the database into a state where the number of marks is incorrect +in some way. + + +@node backdate-text, , set-marks, Debug Calls +@comment node-name, next, previous, up +@subsubsection backdate-text (DEBUG) Experimental + +@findex backdate-text +@example + backdate-text [1002] (( text-no : Text_no; + seconds : INT32; )) + -> ( ); +@end example + +Backdate a text in the server. Change the creation date of text +@code{text-no} so it appears to have been created @code{seconds} earlier +than it was actually created. This can be used to test the garbage +collector. + + + @contents @bye diff --git a/doc/lyskomdb.texi b/doc/lyskomdb.texi index ba6ccb7b098a24820caa14557d78b45c281dec19..d7eb445f21012a6545d7270cf8bca4d491a4f984 100644 --- a/doc/lyskomdb.texi +++ b/doc/lyskomdb.texi @@ -1,5 +1,5 @@ \input texinfo -@c $Id: lyskomdb.texi,v 1.2 1999/04/03 21:58:09 ceder Exp $ +@c $Id: lyskomdb.texi,v 1.3 1999/05/18 13:06:22 byers Exp $ @c %**start of header @setfilename lyskomdb.info @settitle "lyskomd Database Format Specification" @@ -220,16 +220,13 @@ deleted : @BB{-C} @II{integer} @BB{NL} The integer in the conference, text and person records is the ID of the record. This implies that records can be in any order. -@c FIXME: doesn't it store the first unused number? There is probably a -@c fence error here. /ceder -The @II{next-free-num} record is used to store the highest ID of any -conference in the system. There may be several of these records in the -database. +The @II{next-free-num} record is used to store the next available ID for +conferences in the system. There may be several of these records in the +database. -@c FIXME: doesn't it store the first unused number? There is probably a -@c fence error here. /ceder -The @II{next-text-num} record is used to store the highest ID of any text -in the system. There may be several of these records in the database. +The @II{next-text-num} record is used to store the next available ID for +texts in the system. There may be several of these records in the +database. A conference or text must have a number lower than the closest @II{next-free-num} or @II{next-text-num} preceding it. diff --git a/src/include/kom-types.h b/src/include/kom-types.h index 5a1c2d3f6947b25ed840e3f41949876d46eb723c..1c6027c466269e95c10d735c2ce2e19cdfce4777 100644 --- a/src/include/kom-types.h +++ b/src/include/kom-types.h @@ -1,5 +1,5 @@ /* - * $Id: kom-types.h,v 0.34 1999/05/12 13:24:27 byers Exp $ + * $Id: kom-types.h,v 0.35 1999/05/18 13:06:26 byers Exp $ * Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -185,7 +185,7 @@ typedef enum { rec_time = 7, /* 7 Received at (time) */ sent_by = 8, /* 8 Sent by (person) */ sent_at = 9, /* 9 Sent at (time) */ - bcc_recpt = 15 /* 15 BCC recipient (for kannedom) */ + bcc_recpt = 15, /* 15 BCC recipient (for kannedom) */ #ifdef PROT_a , x_person = 11, /* 11 External person id. (Global_name). */ @@ -193,6 +193,8 @@ typedef enum { x_text = 13, /* 13 External text. (Global_text). */ x_system = 14 /* 14 External system identification (System_id). */ #endif + + unknown_info = 4711 /* Internal use only. Unknown misc item encountered */ } Info_type; #ifdef PROT_a @@ -223,6 +225,7 @@ typedef union { Global_text global_text; System_id system_id; #endif + Info_type unknown_type; } Info_datum; @@ -233,6 +236,12 @@ typedef struct { } Misc_info; +typedef struct { + unsigned short no_of_misc; + Misc_info * misc; +} Misc_info_list; + + typedef struct { unsigned int deleted : 1; /* This item has been deleted */ unsigned int inherit : 1; /* Copy to comments */ diff --git a/src/include/services.h b/src/include/services.h index 46c0412afa3323d00c0c7741157e8fde8858b787..629ebc7fe0583b323ad67feee245409f8f30a05e 100644 --- a/src/include/services.h +++ b/src/include/services.h @@ -1,5 +1,5 @@ /* - * $Id: services.h,v 0.44 1999/05/12 13:24:28 byers Exp $ + * $Id: services.h,v 0.45 1999/05/18 13:06:27 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -485,26 +485,22 @@ KOM_( mark_as_read (Conf_no conference, /* Returns 0 on error */ extern Text_no KOM_( create_text (const String message, - unsigned short no_of_misc, - CONST Misc_info * misc, + CONST Misc_info_list * misc, Aux_item_list * aux )); extern Text_no KOM_( create_text_old (const String message, - unsigned short no_of_misc, - CONST Misc_info * misc )); + CONST Misc_info_list * misc )); /* Returns 0 on error. This function is experimental. */ extern Text_no KOM_( create_anonymous_text (const String message, - unsigned short no_of_misc, - CONST Misc_info * misc, + CONST Misc_info_list * misc, Aux_item_list *aux )); extern Text_no KOM_( create_anonymous_text_old (const String message, - unsigned short no_of_misc, - CONST Misc_info * misc )); + CONST Misc_info_list * misc )); extern Success KOM_( delete_text( Text_no text_no )); diff --git a/src/server/admin.c b/src/server/admin.c index c647437d9410be2e42e0aef27f138677e2848f3a..b04e396522d400b340e1c746ab7d7f8289ec29fa 100644 --- a/src/server/admin.c +++ b/src/server/admin.c @@ -1,5 +1,5 @@ /* - * $Id: admin.c,v 0.36 1999/05/16 21:45:00 ceder Exp $ + * $Id: admin.c,v 0.37 1999/05/18 13:06:45 byers Exp $ * Copyright (C) 1991, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -33,7 +33,7 @@ #endif static const char * -rcsid = "$Id: admin.c,v 0.36 1999/05/16 21:45:00 ceder Exp $"; +rcsid = "$Id: admin.c,v 0.37 1999/05/18 13:06:45 byers Exp $"; #include "rcs.h" USE(rcsid); @@ -372,6 +372,21 @@ modify_server_info(Number_list *items_to_delete, Aux_item_list *items_to_add) { CHK_LOGIN(FAILURE); + + if (items_to_delete->length > param.max_delete_aux) + { + kom_errno = KOM_LONG_ARRAY; + err_stat = param.max_delete_aux; + return FAILURE; + } + + if (items_to_add->length > param.max_add_aux) + { + kom_errno = KOM_LONG_ARRAY; + err_stat = param.max_add_aux; + return FAILURE; + } + if ( !ENA(admin, 1) ) { err_stat = 0; diff --git a/src/server/aux-item-def-parse.y b/src/server/aux-item-def-parse.y index 2516bcccaf6f6c73ede8cf04cbfef5c43283cea2..b761bde23811bc797e4f25fdb2b1e1d2f2472040 100644 --- a/src/server/aux-item-def-parse.y +++ b/src/server/aux-item-def-parse.y @@ -1,6 +1,6 @@ %{ /* - * $Id: aux-item-def-parse.y,v 1.5 1999/05/12 13:24:55 byers Exp $ + * $Id: aux-item-def-parse.y,v 1.6 1999/05/18 13:06:45 byers Exp $ * Copyright (C) 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -213,8 +213,9 @@ head : NUMBER ':' ID '(' targets ')' } | NUMBER ':' ID '(' targets ')' DISABLED { - def.tag = 0; + def.tag = $1; def.name = s_crea_c_str($3); + def.disabled = TRUE; s_clear(&($3)); $3 = EMPTY_STRING; yylval.str = EMPTY_STRING; diff --git a/src/server/aux-items.c b/src/server/aux-items.c index 57fdfe86a0a4c3cc67b254fc81d2eccf158ba501..de6924cca630cdcfd4bbffa72e2719b7a68089b5 100644 --- a/src/server/aux-items.c +++ b/src/server/aux-items.c @@ -1,5 +1,5 @@ /* - * $Id: aux-items.c,v 1.11 1999/05/16 21:45:15 ceder Exp $ + * $Id: aux-items.c,v 1.12 1999/05/18 13:06:46 byers Exp $ * Copyright (C) 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -77,6 +77,7 @@ static Aux_item_definition compiled_aux_items[] = void aux_item_trigger_mark_text(Aux_item_trigger_data *); void aux_item_trigger_unmark_text(Aux_item_trigger_data *); void aux_item_trigger_mirror_faq(Aux_item_trigger_data *); +void aux_item_trigger_link_item(Aux_item_trigger_data *data); /* Forward declarations of validators */ @@ -93,6 +94,7 @@ aux_item_triggers [] = { "mark-text", aux_item_trigger_mark_text }, { "unmark-text", aux_item_trigger_unmark_text }, { "link-faq", aux_item_trigger_mirror_faq }, + { "link-item", aux_item_trigger_link_item }, { NULL, NULL } }; @@ -115,6 +117,7 @@ Aux_item_definition empty_aux_item_definition = 0, /* Tag */ { 0,0,0,0,0,0,0,0 }, /* Clear flags */ { 0,0,0,0,0,0,0,0 }, /* Set flags */ + 0, /* Disabled */ 0, /* Author only */ 0, /* Supervisor only */ 0, /* System only */ @@ -149,6 +152,7 @@ static Aux_item_definition simple_aux_item = 0, /* Tag */ { 0,0,0,0,0,0,0,0 }, /* Clear flags */ { 0,0,0,0,0,0,0,0 }, /* Set flags */ + 0, /* Disabled */ 0, /* Author only */ 0, /* Supervisor only */ 0, /* System only */ @@ -304,6 +308,106 @@ find_aux_item_definition(Aux_item *item) * ====================================================================== */ + +/* TRIGGER THINGS */ + + +static void +aux_item_fix_trigger_data(Aux_item_trigger_data *data) +{ + switch (data->object_type) + { + case TEXT_OBJECT_TYPE: + data->item = &((Text_stat *)data->object)->aux_item_list.items[data->item_index]; + break; + case CONF_OBJECT_TYPE: + data->item = &((Conference *)data->object)->aux_item_list.items[data->item_index]; + break; + case INFO_OBJECT_TYPE: + data->item = &((Info *)data->object)->aux_item_list.items[data->item_index]; + break; + + default: + break; + } +} + + +static void +aux_item_call_add_triggers(Aux_item_definition *def, + Object_type object_type, + unsigned long item_index, + unsigned long integer_argument, + void * pointer_argument, + Aux_item * item) +{ + unsigned long i; + Aux_item_trigger_data data; + + data.action = AUX_ITEM_ADD_ACTION; + data.object_type = object_type; + data.item_index = item_index; + data.object_no = integer_argument; + data.object = pointer_argument; + data.item = item; + + for (i = 0; i < def->num_add_triggers; i++) + { + (*(def->add_triggers[i]))(&data); + aux_item_fix_trigger_data(&data); + } +} + +static void +aux_item_call_delete_triggers(Aux_item_definition *def, + Object_type object_type, + unsigned long item_index, + unsigned long integer_argument, + void * pointer_argument, + Aux_item *item) +{ + unsigned long i; + Aux_item_trigger_data data; + + data.action = AUX_ITEM_DELETE_ACTION; + data.object_type = object_type; + data.item_index = item_index; + data.object_no = integer_argument; + data.object = pointer_argument; + data.item = item; + + for (i = 0; i < def->num_delete_triggers; i++) + { + (*(def->delete_triggers[i]))(&data); + } +} + +static void +aux_item_call_undelete_triggers(Aux_item_definition *def, + Object_type object_type, + unsigned long item_index, + unsigned long integer_argument, + void * pointer_argument, + Aux_item * item) +{ + unsigned long i; + Aux_item_trigger_data data; + + data.action = AUX_ITEM_UNDELETE_ACTION; + data.object_type = object_type; + data.item_index = item_index; + data.object_no = integer_argument; + data.object = pointer_argument; + data.item = item; + + for (i = 0; i < def->num_undelete_triggers; i++) + { + (*(def->undelete_triggers[i]))(&data); + } +} + + + /* * initialize_aux_items * @@ -406,81 +510,306 @@ initialize_aux_items(char *aux_def_file) } -/* TRIGGER THINGS */ - -static void -aux_item_call_add_triggers(Aux_item_definition *def, - Object_type object_type, - unsigned long item_index, - unsigned long integer_argument, - void * pointer_argument, - Aux_item * item) +long +find_aux_item_index(Aux_item_list *list, unsigned long aux_no) { unsigned long i; - Aux_item_trigger_data data; + + for (i = 0; i < list->length; i++) + { + if (list->items[i].aux_no == aux_no) + return i; + } + + return -1; +} + + +/* Find the aux item list containing the item that ITEM is linked to */ + +static Aux_item_list * +find_linked_aux_item_list(Aux_item *item) +{ + Text_stat *text_stat; + Conference *conf_stat; - data.action = AUX_ITEM_ADD_ACTION; - data.object_type = object_type; - data.item_index = item_index; - data.object_no = integer_argument; - data.object = pointer_argument; - data.item = item; + switch (item->linked_item.target_type) + { + case NO_OBJECT_TYPE: + return NULL; - for (i = 0; i < def->num_add_triggers; i++) + case TEXT_OBJECT_TYPE: + GET_T_STAT(text_stat, item->linked_item.target_object.text, NULL); + return &text_stat->aux_item_list; + + case CONF_OBJECT_TYPE: + GET_C_STAT(conf_stat, item->linked_item.target_object.conf, NULL); + return &conf_stat->aux_item_list; + + case INFO_OBJECT_TYPE: + return &kom_info.aux_item_list; + + case PERS_OBJECT_TYPE: + default: + /* No lists in these items */ + kom_log("find_linked_aux_item_list: Bad aux_item somewhere: link to person or other kind."); + return NULL; + } +} + +/* Find the aux item that ITEM is linked to */ + +static Aux_item * +find_linked_aux_item(Aux_item *item) +{ + Aux_item_list *target_list; + + target_list = find_linked_aux_item_list(item); + if (target_list == NULL) + return NULL; + + return find_aux_item(target_list, item->linked_item.target_item); +} + +/* Mark the object linked to by an aux_item as changed */ + +static void +mark_linked_object_as_changed(Aux_item *item) +{ + Text_stat *text_stat; + Conference *conf_stat; + + switch (item->linked_item.target_type) { - (*(def->add_triggers[i]))(&data); + case TEXT_OBJECT_TYPE: + VOID_GET_T_STAT(text_stat, item->linked_item.target_object.text); + mark_text_as_changed(item->linked_item.target_object.text); + break; + + case CONF_OBJECT_TYPE: + VOID_GET_C_STAT(conf_stat, item->linked_item.target_object.conf); + mark_conference_as_changed(item->linked_item.target_object.conf); + break; + + case INFO_OBJECT_TYPE: + case PERS_OBJECT_TYPE: + default: + /* Need no commit for these objects */ } } + + + +/* + * Utility function for linking aux items. This function will take + * care of adding the appropriate item to the appropriate list. + * + * Note that this may cause aux-item lists to be realloced, so pointers + * into such lists may become invalid. Take particular care with the + * pointers in aux-item trigger data + * + * Call aux_item_fix_trigger_data if you need to fix the contents of + * trigger data after calling this function. + */ + + static void -aux_item_call_delete_triggers(Aux_item_definition *def, - Object_type object_type, - unsigned long item_index, - unsigned long integer_argument, - void * pointer_argument, - Aux_item *item) +aux_item_link_items(Object_type src_type, /* Source object type */ + unsigned long src_no, /* Source object pointer */ + void *src_ptr, /* Source pointer */ + Aux_item *src_item, /* Source item */ + + Object_type dst_type, /* Destination obj type */ + unsigned long dst_no, /* Destination obj pointer */ + void *dst_ptr, /* Destination pointer */ + Aux_item *dst_item_data) { - unsigned long i; - Aux_item_trigger_data data; - - data.action = AUX_ITEM_DELETE_ACTION; - data.object_type = object_type; - data.item_index = item_index; - data.object_no = integer_argument; - data.object = pointer_argument; - data.item = item; + Aux_item_list item_list; - for (i = 0; i < def->num_delete_triggers; i++) + /* Get a pointer to the destination object */ + + if (dst_ptr == NULL) { - (*(def->delete_triggers[i]))(&data); + switch (dst_type) + { + case TEXT_OBJECT_TYPE: + dst_ptr = cached_get_text_stat(dst_no); + break; + case CONF_OBJECT_TYPE: + dst_ptr = cached_get_conf_stat(dst_no); + break; + case INFO_OBJECT_TYPE: + dst_ptr = &kom_info; + break; + default: + break; + } + } + + if (dst_ptr == NULL || src_ptr == NULL) + return; + + + /* Set up the linking information in the destination item */ + + dst_item_data->linked_item.target_type = src_type; + dst_item_data->linked_item.target_item = src_item->aux_no; + switch (src_type) + { + case TEXT_OBJECT_TYPE: dst_item_data->linked_item.target_object.text = src_no; break; + case CONF_OBJECT_TYPE: dst_item_data->linked_item.target_object.conf = src_no; break; + case INFO_OBJECT_TYPE: + default: + dst_item_data->linked_item.target_object.text = 0; } + + + /* Set up the linking information in the source item */ + + src_item->linked_item.target_type = dst_type; + src_item->linked_item.target_item = 0; + switch (dst_type) + { + case TEXT_OBJECT_TYPE: + src_item->linked_item.target_object.text = dst_no; + src_item->linked_item.target_item = ((Text_stat *)dst_ptr)->highest_aux + 1; + break; + case CONF_OBJECT_TYPE: + src_item->linked_item.target_object.conf = dst_no; + src_item->linked_item.target_item = ((Conference *)dst_ptr)->highest_aux + 1; + break; + case INFO_OBJECT_TYPE: + src_item->linked_item.target_item = ((Info *)dst_ptr)->highest_aux_no + 1; + src_item->linked_item.target_object.text = 0; + src_item->linked_item.target_object.conf = 0; + break; + default: + src_item->linked_item.target_item = 0; + src_item->linked_item.target_object.text = 0; + src_item->linked_item.target_object.conf = 0; + } + + + /* Set up an item list to add */ + + item_list.length = 1; + item_list.items = dst_item_data; + prepare_aux_item_list(&item_list, 0); + + + /* + * Add the item and mark the destination as changed + * + * Note that these calls may cause the aux item list of the + * destination to move in memory due to calls to realloc. + */ + + switch (dst_type) + { + case TEXT_OBJECT_TYPE: + text_stat_add_aux_item_list((Text_stat *)dst_ptr, + (Text_no)dst_no, &item_list, 0); + mark_text_as_changed((Text_no)dst_no); + break; + case CONF_OBJECT_TYPE: + conf_stat_add_aux_item_list((Conference *)dst_ptr, + (Conf_no)dst_no, &item_list, 0); + mark_conference_as_changed((Conf_no)dst_no); + break; + + case INFO_OBJECT_TYPE: + system_add_aux_item_list((Info *)dst_ptr, &item_list, 0); + break; + + default: + break; + } + + /* + * Set src_item to NULL since there is a chance that it is + * no longer valid (this happens when the source and destination + * objects are the same and reallocing the aux item list causes + * it to move in memory + */ + + src_item = NULL; + + /* + * Mark the source object as changed + */ + + mark_linked_object_as_changed(dst_item_data); } + + + static void -aux_item_call_undelete_triggers(Aux_item_definition *def, - Object_type object_type, - unsigned long item_index, - unsigned long integer_argument, - void * pointer_argument, - Aux_item * item) +aux_item_list_add_items(Aux_item_list *add_to_list, + Aux_item_list *items_to_add, + Object_type object_type, + unsigned long object_no, + void *object_ptr, + unsigned long *highest_ptr, + Pers_no item_creator) { - unsigned long i; - Aux_item_trigger_data data; - - data.action = AUX_ITEM_UNDELETE_ACTION; - data.object_type = object_type; - data.item_index = item_index; - data.object_no = integer_argument; - data.object = pointer_argument; - data.item = item; + unsigned long i; + unsigned long highest_local; + unsigned long start_index; - for (i = 0; i < def->num_undelete_triggers; i++) + if (items_to_add == NULL) + return; + + /* + * Make local copies of variables we need in their original state + */ + + start_index = add_to_list->length; + highest_local = *highest_ptr; + + /* + * Set up the target list so it looks like we've added + * items to it already. That way it is semi-safe to call + * this function recursively. + */ + + add_to_list->items = srealloc(add_to_list->items, + (add_to_list->length + items_to_add->length) * + sizeof(Aux_item)); + add_to_list->length += items_to_add->length; + *highest_ptr = *highest_ptr + items_to_add->length; + + for (i = 0; i < items_to_add->length; i++) { - (*(def->undelete_triggers[i]))(&data); + init_aux_item(&add_to_list->items[start_index + i]); + } + + /* + * Now add the items and call the add triggers + */ + + for (i = 0; i < items_to_add->length; i++) + { + highest_local += 1; + copy_aux_item(&add_to_list->items[i + start_index], + &items_to_add->items[i]); + add_to_list->items[i + start_index].aux_no = highest_local; + add_to_list->items[i + start_index].creator = item_creator; + aux_item_call_add_triggers( + find_aux_item_definition(&items_to_add->items[i]), + object_type, + i + start_index, + object_no, + object_ptr, + &add_to_list->items[i + start_index]); } } + + + /* * prepare_aux_item_list * @@ -533,7 +862,6 @@ void prepare_aux_item(Aux_item *item, item->creator = creator; item->sent_at = current_time; - init_aux_item_link(&item->linked_item); } @@ -630,7 +958,7 @@ static Bool aux_item_validate(Aux_item_validation_data validation_data) default: kom_log("BUG: unknown aux_item validator type"); - break; + } } @@ -691,6 +1019,12 @@ aux_item_add_perm(Aux_item *item, return FALSE; } + if (def->disabled) + { + kom_errno = KOM_ILL_AUX; + return FALSE; + } + switch (object_type) { case TEXT_OBJECT_TYPE: can_add_when = def->text_a; break; @@ -830,7 +1164,7 @@ aux_inherit_items(Aux_item_list *target, Aux_item item; Aux_item_definition *def; - /* FIXME: Inheriting linked items is strange, but works. */ + /* Inheriting linked items is strange, but works. */ if (!target || !parent) return; @@ -856,6 +1190,7 @@ aux_inherit_items(Aux_item_list *target, continue; copy_aux_item(&item, &parent->items[i]); + init_aux_item_link(&item.linked_item); prepare_aux_item(&item, parent->items[i].creator, def); if (item.inherit_limit != 0) item.inherit_limit -= 1; @@ -976,97 +1311,6 @@ check_delete_aux_item_list(Number_list *items_to_delete, return OK; } - - -long -find_aux_item_index(Aux_item_list *list, unsigned long aux_no) -{ - unsigned long i; - - for (i = 0; i < list->length; i++) - { - if (list->items[i].aux_no == aux_no) - return i; - } - - return -1; -} - - -/* Find the aux item list containing the item that ITEM is linked to */ - -static Aux_item_list * -find_linked_aux_item_list(Aux_item *item) -{ - Text_stat *text_stat; - Conference *conf_stat; - - switch (item->linked_item.target_type) - { - case NO_OBJECT_TYPE: - return NULL; - - case TEXT_OBJECT_TYPE: - GET_T_STAT(text_stat, item->linked_item.target_object.text, NULL); - return &text_stat->aux_item_list; - - case CONF_OBJECT_TYPE: - GET_C_STAT(conf_stat, item->linked_item.target_object.conf, NULL); - return &conf_stat->aux_item_list; - - case INFO_OBJECT_TYPE: - return &kom_info.aux_item_list; - - case PERS_OBJECT_TYPE: - default: - /* No lists in these items */ - kom_log("find_linked_aux_item_list: Bad aux_item somewhere: link to person or other kind."); - return NULL; - } -} - -/* Find the aux item that ITEM is linked to */ - -static Aux_item * -find_linked_aux_item(Aux_item *item) -{ - Aux_item_list *target_list; - - target_list = find_linked_aux_item_list(item); - if (target_list == NULL) - return NULL; - - return find_aux_item(target_list, item->linked_item.target_item); -} - -/* Mark the object linked to by an aux_item as changed */ - -static void -mark_linked_object_as_changed(Aux_item *item) -{ - Text_stat *text_stat; - Conference *conf_stat; - - switch (item->linked_item.target_type) - { - case TEXT_OBJECT_TYPE: - VOID_GET_T_STAT(text_stat, item->linked_item.target_object.text); - mark_text_as_changed(item->linked_item.target_object.text); - break; - - case CONF_OBJECT_TYPE: - VOID_GET_C_STAT(conf_stat, item->linked_item.target_object.conf); - mark_conference_as_changed(item->linked_item.target_object.conf); - break; - - case INFO_OBJECT_TYPE: - case PERS_OBJECT_TYPE: - default: - /* Need no commit for these objects */ - } -} - - /* * delete_aux_item_list * @@ -1133,20 +1377,23 @@ delete_aux_item_list(Number_list *items_to_delete, { case CONF_OBJECT_TYPE: linked_object_no = item->linked_item.target_object.conf; - linked_object = (void*)cached_get_text_stat(linked_object_no); + linked_object = (void*)cached_get_conf_stat(linked_object_no); break; case TEXT_OBJECT_TYPE: linked_object_no = item->linked_item.target_object.text; - linked_object = (void*)cached_get_conf_stat(linked_object_no); + linked_object = (void*)cached_get_text_stat(linked_object_no); break; case INFO_OBJECT_TYPE: linked_object_no = 0; linked_object = NULL; break; default: - restart_kom("delete_aux_item_list(): bad target type\n"); + kom_log("delete_aux_item_list(): bad target type\n"); + return; } + /* We only get here if the link type is known */ + delete_aux_item_list(&linked_delete, linked_item_list, item->linked_item.target_type, @@ -1169,6 +1416,8 @@ undelete_aux_item_list(Number_list *items_to_undelete, unsigned long object_no, void *object) { + Kom_err saved_kom_errno; + unsigned long saved_err_stat; long i; Aux_item *item; Aux_item *linked_item; @@ -1179,6 +1428,9 @@ undelete_aux_item_list(Number_list *items_to_undelete, Number_list linked_undelete; void *linked_object; + saved_kom_errno = kom_errno; + saved_err_stat = err_stat; + for (i = 0; i < items_to_undelete->length; i++) { if (items_to_undelete->data[i] == 0) @@ -1220,20 +1472,25 @@ undelete_aux_item_list(Number_list *items_to_undelete, { case CONF_OBJECT_TYPE: linked_object_no = item->linked_item.target_object.conf; - linked_object = (void*)cached_get_text_stat(linked_object_no); + linked_object = (void*)cached_get_conf_stat(linked_object_no); break; case TEXT_OBJECT_TYPE: linked_object_no = item->linked_item.target_object.text; - linked_object = (void*)cached_get_conf_stat(linked_object_no); + linked_object = (void*)cached_get_text_stat(linked_object_no); break; case INFO_OBJECT_TYPE: linked_object_no = 0; linked_object = NULL; break; default: - restart_kom("undelete_aux_item_list(): bad link type\n"); + kom_log("undelete_aux_item_list(): bad link type\n"); + kom_errno = saved_kom_errno; + err_stat = saved_err_stat; + return; } + /* We only get here if the link type is known */ + undelete_aux_item_list(&linked_undelete, linked_item_list, item->linked_item.target_type, @@ -1241,6 +1498,9 @@ undelete_aux_item_list(Number_list *items_to_undelete, linked_object); } } + + kom_errno = saved_kom_errno; + err_stat = saved_err_stat; } @@ -1424,34 +1684,13 @@ void text_stat_add_aux_item_list(Text_stat *text_s, Aux_item_list *item_list, Pers_no item_creator) { - unsigned long i; - - if (item_list == NULL) - return; - - text_s->aux_item_list.items = srealloc(text_s->aux_item_list.items, - (text_s->aux_item_list.length + - item_list->length) * - sizeof(Aux_item)); - - for (i = 0; i < item_list->length; i++) - { - text_s->highest_aux += 1; - item_list->items[i].aux_no = text_s->highest_aux; - item_list->items[i].creator = item_creator; - - copy_aux_item( - &text_s->aux_item_list.items[text_s->aux_item_list.length], - &item_list->items[i]); - text_s->aux_item_list.length += 1; - aux_item_call_add_triggers( - find_aux_item_definition(&item_list->items[i]), - TEXT_OBJECT_TYPE, - text_s->aux_item_list.length - 1, - text_no, - text_s, - &item_list->items[i]); - } + aux_item_list_add_items(&text_s->aux_item_list, + item_list, + TEXT_OBJECT_TYPE, + text_no, + text_s, + &text_s->highest_aux, + item_creator); } @@ -1521,32 +1760,16 @@ conf_stat_add_aux_item_list(Conference *conf, Aux_item_list *item_list, Pers_no item_creator) { - unsigned long i; + aux_item_list_add_items(&conf->aux_item_list, + item_list, + CONF_OBJECT_TYPE, + conf_no, + conf, + &conf->highest_aux, + item_creator); +} - if (item_list == NULL) - return; - conf->aux_item_list.items = srealloc(conf->aux_item_list.items, - (conf->aux_item_list.length + - item_list->length) * - sizeof(Aux_item)); - for (i = 0; i < item_list->length; i++) - { - conf->highest_aux += 1; - item_list->items[i].aux_no = conf->highest_aux; - item_list->items[i].creator = item_creator; - copy_aux_item(&conf->aux_item_list.items[conf->aux_item_list.length], - &item_list->items[i]); - conf->aux_item_list.length += 1; - aux_item_call_add_triggers( - find_aux_item_definition(&item_list->items[i]), - CONF_OBJECT_TYPE, - conf->aux_item_list.length - 1, - conf_no, - conf, - &item_list->items[i]); - } -} Success system_check_add_aux_item_list(Info *info, Aux_item_list *list, @@ -1599,32 +1822,13 @@ system_add_aux_item_list(Info *info, Aux_item_list *item_list, Pers_no item_creator) { - unsigned long i; - - if (item_list == NULL) - return; - - info->aux_item_list.items = srealloc(info->aux_item_list.items, - (info->aux_item_list.length + - item_list->length) * - sizeof(Aux_item)); - for (i = 0; i < item_list->length; i++) - { - info->highest_aux_no += 1; - item_list->items[i].aux_no = info->highest_aux_no; - item_list->items[i].creator = item_creator; - copy_aux_item(&info->aux_item_list.items[info->aux_item_list.length], - &item_list->items[i]); - info->aux_item_list.length += 1; - - aux_item_call_add_triggers( - find_aux_item_definition(&item_list->items[i]), - INFO_OBJECT_TYPE, - info->aux_item_list.length - 1, - 0, - info, - &item_list->items[i]); - } + aux_item_list_add_items(&info->aux_item_list, + item_list, + INFO_OBJECT_TYPE, + 0, + info, + &info->highest_aux_no, + item_creator); } extern Success @@ -1683,59 +1887,160 @@ void aux_item_trigger_unmark_text(Aux_item_trigger_data *data) void aux_item_trigger_mirror_faq(Aux_item_trigger_data *data) { - Conference *conf_stat; - Conf_no conf_no; Text_no text_no; - Text_stat *text_stat; - Aux_item_list items; Aux_item item_data; char conf_no_string[40]; - String_size ill_char; - String_size end_pos; + String_size ill_char, end_pos; + String str; + if (data->object_type != CONF_OBJECT_TYPE || data->object == NULL) return; - init_aux_item(&item_data); - conf_stat = (Conference *)data->object; - conf_no = (Conf_no)data->object_no; - text_no = s_strtol(conf_stat->aux_item_list.items[data->item_index].data, - &ill_char, - 10); + /* Get the object number of where we want to put the new item */ - VOID_GET_T_STAT(text_stat, text_no); + text_no = s_strtol(data->item->data, &ill_char, 10); - sprintf(conf_no_string, "%-40lu", (unsigned long)conf_no); + /* Create the string for the new item */ + + sprintf(conf_no_string, "%-40lu", (unsigned long)data->object_no); + str = s_fcrea_str(conf_no_string); + end_pos = s_strchr(str, ' ', 0); + if (end_pos != -1) + { + s_strdel(&str, end_pos, s_strlen(str) - 1); + } + + /* Fill in the new item */ + + init_aux_item(&item_data); item_data.tag = 28; /* Mirror of FAQ item */ - item_data.data = s_fcrea_str(conf_no_string); - end_pos = s_strchr(item_data.data, ' ', 0); - if (end_pos != -1) - s_strdel(&item_data.data, end_pos, s_strlen(item_data.data) - 1); + item_data.data = str; + + + /* Create the link */ + + aux_item_link_items(data->object_type, + data->object_no, + data->object, + data->item, + + TEXT_OBJECT_TYPE, + text_no, + NULL, + &item_data + ); +} - /* Set up the link from the text to the conference */ + +/* + * Generic link trigger. This is primarily for testing. + * + * The item must contain three fields, separated with a space character. + * Field one is a character containing specifying the object type the + * other end of the link is supposed to be in. If it is 'C', the link is + * to a conference. If it is 'T', the link is to a text. If it is 'I', + * the link is to the system info. + * + * The second field is the item tag to use for the other end of the link. + * + * The third field is the object id of the target object. For the + * system info it is ignored but must be present. + * + * Some examples: + * "C 99 123": Link to an item of type 99 in conference 123 + * "I 92 9": Link to an item of type 92 in the system info + * "T 22 191": Link to an item of type 22 in text 191 + * + * The created item will contain the same kind of information. + */ + +void aux_item_trigger_link_item(Aux_item_trigger_data *data) +{ + char object_no_string[100]; + char *tmp_str; + char type_char; + Object_type target_object_type; + unsigned long target_item_tag, target_object_no; + int nread; + Aux_item item_data; - item_data.linked_item.target_type = CONF_OBJECT_TYPE; - item_data.linked_item.target_object.conf = conf_no; - item_data.linked_item.target_item = data->item->aux_no; - - items.length = 1; - items.items = &item_data; + init_aux_item(&item_data); - prepare_aux_item_list(&items, 0); + /* ---------------------------------------- + * Find the data for the linked item + * + * The object type, object id and item tag + * are in the item the trigger is called + * for + * + * The string is given by the current item + */ - text_stat_add_aux_item_list(text_stat, text_no, &items, 0); - mark_text_as_changed(text_no); + tmp_str = s_crea_c_str(data->item->data); + nread = sscanf(tmp_str, + "%c %lu %lu", + &type_char, + &target_item_tag, + &target_object_no); + sfree(tmp_str); + if (nread != 3) + return; + + switch (type_char) + { + case 'T': target_object_type = TEXT_OBJECT_TYPE; break; + case 'C': target_object_type = CONF_OBJECT_TYPE; break; + case 'I': target_object_type = INFO_OBJECT_TYPE; break; + default: return; + } + + + /* Create the string for the linked item */ + + switch (data->object_type) + { + case TEXT_OBJECT_TYPE: type_char = 'T'; break; + case CONF_OBJECT_TYPE: type_char = 'C'; break; + case INFO_OBJECT_TYPE: type_char = 'I'; break; + default: type_char = '?'; break; + } + + sprintf(object_no_string, "%c %lu %lu", + type_char, + (unsigned long)data->item->tag, + (unsigned long)data->object_no); - /* Set up the link from the conference to the text */ - data->item->linked_item.target_type = TEXT_OBJECT_TYPE; - data->item->linked_item.target_object.text = text_no; - data->item->linked_item.target_item = text_stat->highest_aux; - mark_conference_as_changed(conf_no); + /* + * Create the mirror item in item_data + * + * Item tag is found above + * Item data is found above + * Item link target item is the item-no of the current item + * Item link target object type is the object type in the trigger data + * Item link target object no is the object no in the trigger data + */ + + item_data.tag = target_item_tag; + item_data.data = s_fcrea_str(object_no_string); + + aux_item_link_items(data->object_type, + data->object_no, + data->object, + data->item, + + target_object_type, + target_object_no, + NULL, + &item_data + ); } + + /* * Aux item validators */ diff --git a/src/server/aux-items.h b/src/server/aux-items.h index 0a4ef7eb3001ae9e37f1ad7753eeb2af956f0f95..681778dd79b4605ba1ca2c5dcfbe959eeb32f0fd 100644 --- a/src/server/aux-items.h +++ b/src/server/aux-items.h @@ -1,5 +1,5 @@ /* - * $Id: aux-items.h,v 1.8 1999/05/16 21:45:25 ceder Exp $ + * $Id: aux-items.h,v 1.9 1999/05/18 13:06:47 byers Exp $ * Copyright (C) 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -121,6 +121,7 @@ struct Aux_item_definition_s { unsigned long tag; Aux_item_flags clear_flags; Aux_item_flags set_flags; + Bool disabled; Bool author_only; Bool supervisor_only; Bool system_only; diff --git a/src/server/call-switch.awk b/src/server/call-switch.awk index 214ab177f9f4f32c278203155aed3e39e8b763a5..ba04c9ef09aaafa4e900567ecf489e2a7123c4c4 100644 --- a/src/server/call-switch.awk +++ b/src/server/call-switch.awk @@ -1,5 +1,5 @@ # -# $Id: call-switch.awk,v 0.17 1999/05/12 13:25:00 byers Exp $ +# $Id: call-switch.awk,v 0.18 1999/05/18 13:06:48 byers Exp $ # Copyright (C) 1991, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. # # This file is part of the LysKOM server. @@ -22,7 +22,7 @@ # # Please mail bug reports to bug-lyskom@lysator.liu.se. # -# $Id: call-switch.awk,v 0.17 1999/05/12 13:25:00 byers Exp $ +# $Id: call-switch.awk,v 0.18 1999/05/18 13:06:48 byers Exp $ BEGIN { printf("/* Don't edit this file - it is generated automatically"); printf(" from\n call-switch.awk and fncdef.txt */\n"); @@ -69,10 +69,10 @@ $1 != "#" && $1 != "" { printf("&client->membership_type"); else if ( $i == "c_local_text_no_p" ) printf("client->c_local_text_no_p"); - else if ( $i == "c_misc_info_p" ) - printf("client->c_misc_info_p"); else if ( $i == "aux_item_list") printf("&client->aux_item_list"); + else if ( $i == "misc_info_list") + printf("&client->misc_info_list"); else if ( $i == "time_date" ) printf("&client->time"); else if ( $i == "info" ) diff --git a/src/server/conference.c b/src/server/conference.c index c73646d04d604b10e0125eeac06dc43ed854e790..89bfc5b609915a27a70ed14398ac18ae7d8e9a09 100644 --- a/src/server/conference.c +++ b/src/server/conference.c @@ -1,5 +1,5 @@ /* - * $Id: conference.c,v 0.47 1999/05/16 21:45:36 ceder Exp $ + * $Id: conference.c,v 0.48 1999/05/18 13:06:49 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -35,7 +35,7 @@ static const char * -rcsid = "$Id: conference.c,v 0.47 1999/05/16 21:45:36 ceder Exp $"; +rcsid = "$Id: conference.c,v 0.48 1999/05/18 13:06:49 byers Exp $"; #include "rcs.h" USE(rcsid); @@ -1348,6 +1348,21 @@ modify_conf_info(Conf_no conf_no, Conference *conf; CHK_LOGIN(FAILURE); + + if (items_to_delete->length > param.max_delete_aux) + { + kom_errno = KOM_LONG_ARRAY; + err_stat = param.max_delete_aux; + return FAILURE; + } + + if (aux->length > param.max_add_aux) + { + kom_errno = KOM_LONG_ARRAY; + err_stat = param.max_add_aux; + return FAILURE; + } + GET_C_STAT(conf, conf_no, FAILURE); /* Check if we may delete and add the items */ diff --git a/src/server/connections.c b/src/server/connections.c index b0179a9221fba6668d27fea136ac5048b3f67111..6d7f4e57da1893d7e8c0810b076f610abcfc8d44 100644 --- a/src/server/connections.c +++ b/src/server/connections.c @@ -1,5 +1,5 @@ /* - * $Id: connections.c,v 0.59 1999/05/16 21:45:47 ceder Exp $ + * $Id: connections.c,v 0.60 1999/05/18 13:06:50 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -36,7 +36,7 @@ #endif static const char * -rcsid = "$Id: connections.c,v 0.59 1999/05/16 21:45:47 ceder Exp $"; +rcsid = "$Id: connections.c,v 0.60 1999/05/18 13:06:50 byers Exp $"; #include "rcs.h" USE(rcsid); @@ -294,8 +294,9 @@ free_parsed(Connection *client) s_clear(&client->c_string0); s_clear(&client->c_string1); client->string0 = EMPTY_STRING; /* So that no one frees it. */ - sfree( client->c_misc_info_p ); - client->c_misc_info_p = NULL; + sfree(client->misc_info_list.misc); + client->misc_info_list.misc = 0; + client->misc_info_list.no_of_misc = 0; s_clear(&client->aux_item.data); sfree( client->c_local_text_no_p); client->c_local_text_no_p = NULL; @@ -305,6 +306,9 @@ free_parsed(Connection *client) client->array_parse_pos = 0; client->struct_parse_pos = 0; client->string_parse_pos = 0; + client->hunt_parse_pos = 0; + client->array_hunt_num = 0; + client->array_hunt_depth = 0; sfree(client->num_list.data); client->num_list.data = NULL; client->num_list.length = 0; diff --git a/src/server/connections.h b/src/server/connections.h index 6b806f0b21f2f72870fc232a5e3d5022635a450d..aca1a3675ec06d8be166aa97ed98fee4395150ff 100644 --- a/src/server/connections.h +++ b/src/server/connections.h @@ -1,5 +1,5 @@ /* - * $Id: connections.h,v 0.41 1999/05/12 13:25:05 byers Exp $ + * $Id: connections.h,v 0.42 1999/05/18 13:06:51 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -23,7 +23,7 @@ * Please mail bug reports to bug-lyskom@lysator.liu.se. */ /* - * $Id: connections.h,v 0.41 1999/05/12 13:25:05 byers Exp $ + * $Id: connections.h,v 0.42 1999/05/18 13:06:51 byers Exp $ * * connections.h -- The top level of the communication packet. * @@ -73,6 +73,10 @@ typedef struct connection { int array_parse_index; int struct_parse_pos; int string_parse_pos; + int hunt_parse_pos; + + int array_hunt_num; + int array_hunt_depth; int ref_no; Call_header function; /* Function to call. */ @@ -92,7 +96,7 @@ typedef struct connection { String c_string1; String string0; /* This string is used for strings that * are freed by the routines in services.c */ - Misc_info *c_misc_info_p; /* Freead by free_parsed(). */ + Misc_info_list misc_info_list; Aux_item_list aux_item_list; /* Freed by free_parsed() */ Aux_item aux_item; /* Freed by free_parsed() */ Local_text_no *c_local_text_no_p; /* Freead by free_parsed(). */ diff --git a/src/server/fncdef.txt b/src/server/fncdef.txt index 471b4acc5b6290997cca788f3324ff1da3b286d1..ed6388e008b9c07c883bf0ad43d27fb0ed513785 100644 --- a/src/server/fncdef.txt +++ b/src/server/fncdef.txt @@ -1,5 +1,5 @@ # -# $Id: fncdef.txt,v 0.39 1999/05/12 13:25:09 byers Exp $ +# $Id: fncdef.txt,v 0.40 1999/05/18 13:06:52 byers Exp $ # Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997 # Lysator Academic Computer Association. # @@ -23,7 +23,7 @@ # # Please mail bug reports to bug-lyskom@lysator.liu.se. # -# $Id: fncdef.txt,v 0.39 1999/05/12 13:25:09 byers Exp $ +# $Id: fncdef.txt,v 0.40 1999/05/18 13:06:52 byers Exp $ # # This file is used to describe the functions in services.c. All # functions that are reachable from the clients are listed here, together @@ -68,7 +68,7 @@ 25 success get_text num num num : string 26 success get_text_stat_old num : text_stat_old 27 success mark_as_read num num c_local_text_no_p (param.mark_as_read_chunk) -28 number create_text_old c_string (param.text_len) num c_misc_info_p (param.max_crea_misc) +28 number create_text_old c_string (param.text_len) misc_info_list (param.max_crea_misc) 29 success delete_text num 30 success add_recipient num num num 31 success sub_recipient num num @@ -105,7 +105,7 @@ # Protocol version 3 # 58 success get_last_text time_date : text_no -59 number create_anonymous_text_old c_string (param.text_len) num c_misc_info_p (param.max_crea_misc) +59 number create_anonymous_text_old c_string (param.text_len) misc_info_list (param.max_crea_misc) 60 success find_next_text_no num : text_no 61 success find_previous_text_no num : text_no # @@ -153,8 +153,8 @@ # Protocol version 10 # 85 success get_collate_table : string -86 number create_text c_string (param.text_len) num c_misc_info_p (param.max_crea_misc) aux_item_list (param.max_add_aux) -87 number create_anonymous_text c_string (param.text_len) num c_misc_info_p (param.max_crea_misc) aux_item_list (param.max_add_aux) +86 number create_text c_string (param.text_len) misc_info_list (param.max_crea_misc) aux_item_list (param.max_add_aux) +87 number create_anonymous_text c_string (param.text_len) misc_info_list (param.max_crea_misc) aux_item_list (param.max_add_aux) 88 number create_conf c_string (param.conf_name_len) conf_type aux_item_list (param.max_add_aux) 89 number create_person c_string (param.conf_name_len) c_string (param.pwd_len) pers_flags aux_item_list (param.max_add_aux) 90 success get_text_stat num : text_stat diff --git a/src/server/internal-connections.c b/src/server/internal-connections.c index 1be0b48fd61032f3f57a7d0abd1c104dda564a86..f33c14e3ae4235762fcf8d374aaf04c59e229256 100644 --- a/src/server/internal-connections.c +++ b/src/server/internal-connections.c @@ -1,5 +1,5 @@ /* - * $Id: internal-connections.c,v 0.36 1999/05/16 21:45:59 ceder Exp $ + * $Id: internal-connections.c,v 0.37 1999/05/18 13:06:53 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -35,7 +35,7 @@ static const char * -rcsid = "$Id: internal-connections.c,v 0.36 1999/05/16 21:45:59 ceder Exp $"; +rcsid = "$Id: internal-connections.c,v 0.37 1999/05/18 13:06:53 byers Exp $"; #include "rcs.h" USE(rcsid); @@ -108,6 +108,9 @@ init_connection(Connection *conn) conn->array_parse_index = 0; conn->struct_parse_pos = 0; conn->string_parse_pos = 0; + conn->hunt_parse_pos = 0; + conn->array_hunt_num = 0; + conn->array_hunt_depth = 0; conn->ref_no = 0; conn->function = call_fnc_login_old; conn->num0 = 0; @@ -117,7 +120,8 @@ init_connection(Connection *conn) conn->c_string0 = EMPTY_STRING; conn->c_string1 = EMPTY_STRING; conn->string0 = EMPTY_STRING; - conn->c_misc_info_p = NULL; + conn->misc_info_list.no_of_misc = 0; + conn->misc_info_list.misc = NULL; conn->aux_item.data = EMPTY_STRING; conn->aux_item_list.items = NULL; conn->aux_item_list.length = 0; @@ -275,9 +279,11 @@ kill_client(Connection *cp) kom_log("kill_client(): unexpected string remains.\n"); } - if ( cp->c_misc_info_p != NULL || cp->c_local_text_no_p != NULL ) + if ( cp->misc_info_list.misc != NULL || cp->c_local_text_no_p != NULL ) kom_log("kill_client(): unexpected remaining data.\n"); + /* FIXME: Check for remaining data in aux-item structures */ + sfree(cp); --no_of_allocated_connections; } diff --git a/src/server/membership.c b/src/server/membership.c index 1e71b051f29e95b098cf517a2c15bc090b54bbf7..6f1edca47504b18d8a3393d6171e7544d45e4b4e 100644 --- a/src/server/membership.c +++ b/src/server/membership.c @@ -1,5 +1,5 @@ /* - * $Id: membership.c,v 0.43 1999/05/16 21:46:10 ceder Exp $ + * $Id: membership.c,v 0.44 1999/05/18 13:06:54 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -38,7 +38,7 @@ #define DEBUG_MARK_AS_READ static const char * -rcsid = "$Id: membership.c,v 0.43 1999/05/16 21:46:10 ceder Exp $"; +rcsid = "$Id: membership.c,v 0.44 1999/05/18 13:06:54 byers Exp $"; #include "rcs.h" USE(rcsid); @@ -337,6 +337,10 @@ add_rec_time(Conference * conf_c, case sent_by: case sent_at: break; + + case unknown_info: + default: + restart_kom("ERROR: bogus misc_info type detected in text %lu\n", text_no); } } diff --git a/src/server/param.h b/src/server/param.h index bfe2b862d51726a93f25f23e80a9aa885a6eea0b..85dda75ceecc619e99582c01b58b772b30058c01 100644 --- a/src/server/param.h +++ b/src/server/param.h @@ -1,5 +1,5 @@ /* - * $Id: param.h,v 1.25 1999/05/12 13:25:18 byers Exp $ + * $Id: param.h,v 1.26 1999/05/18 13:06:54 byers Exp $ * Copyright (C) 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -59,6 +59,7 @@ struct kom_par { char *nologin_file; char *lyskomd_path; char *savecore_path; + int y2k_compat; int timeout; int garbtimeout; int synctimeout; diff --git a/src/server/prot-a-output.c b/src/server/prot-a-output.c index fdc53f38b24a973f7069f6093b2cffd8d8315cf1..7a3b4ceaf6c2fb2d7a9f6f285c0dffed45d141c4 100644 --- a/src/server/prot-a-output.c +++ b/src/server/prot-a-output.c @@ -1,5 +1,5 @@ /* - * $Id: prot-a-output.c,v 0.44 1999/05/17 22:54:37 ceder Exp $ + * $Id: prot-a-output.c,v 0.45 1999/05/18 13:06:55 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -35,7 +35,7 @@ #endif static const char * -rcsid = "$Id: prot-a-output.c,v 0.44 1999/05/17 22:54:37 ceder Exp $"; +rcsid = "$Id: prot-a-output.c,v 0.45 1999/05/18 13:06:55 byers Exp $"; #include "rcs.h" USE(rcsid); @@ -759,7 +759,7 @@ prot_a_output_misc_info(Connection *fp, } } - +/* void prot_a_output_time(Connection *fp, time_t clk) @@ -771,18 +771,54 @@ prot_a_output_time(Connection *fp, prot_a_output_ul(fp, t->tm_sec); prot_a_output_ul(fp, t->tm_min); prot_a_output_ul(fp, t->tm_hour); + prot_a_output_ul(fp, t->tm_mday); + prot_a_output_ul(fp, t->tm_mon); + prot_a_output_ul(fp, t->tm_year); + prot_a_output_ul(fp, t->tm_wday); + prot_a_output_ul(fp, t->tm_yday); + prot_a_output_ul(fp, t->tm_isdst); +} +*/ + +void +prot_a_output_time(Connection *fp, + time_t clk) +{ + struct tm *t; + + t = localtime( &clk ); /* Please don't tell anyone that you saw this code. It is fun, - mostly harmless, and it only affects a single day. Don't spoil - the fun in advance! */ - if (t->tm_year == 100 && t->tm_mday == 1 && t->tm_mon == 0 - && t->tm_wday == 6 && t->tm_yday == 1) + mostly harmless, and it only affects as many days as the + server admin wants (default is two.) + + Don't spoil the fun */ + + if (t->tm_year == 100 && t->tm_yday < param.y2k_compat) { - isc_puts(" 32 11 99 6 366", fp->isc_session); - prot_a_output_ul(fp, t->tm_isdst); - return; + t->tm_year -= 1; /* Back to 1999 */ + t->tm_mday = t->tm_yday + 31; /* December 31+yday */ + t->tm_yday += 365; /* yday includes all of 1999 */ + t->tm_mon = 11; /* Always december */ } + prot_a_output_ul(fp, t->tm_sec); + prot_a_output_ul(fp, t->tm_min); + prot_a_output_ul(fp, t->tm_hour); +/* ======= */ +/* / * Please don't tell anyone that you saw this code. It is fun, */ +/* mostly harmless, and it only affects a single day. Don't spoil */ +/* the fun in advance! * / */ +/* */ +/* if (t->tm_year == 100 && t->tm_mday == 1 && t->tm_mon == 0 */ +/* && t->tm_wday == 6 && t->tm_yday == 1) */ +/* { */ +/* isc_puts(" 32 11 99 6 366", fp->isc_session); */ +/* prot_a_output_ul(fp, t->tm_isdst); */ +/* return; */ +/* } */ +/* */ +/* >>>>>>> 0.44 */ prot_a_output_ul(fp, t->tm_mday); prot_a_output_ul(fp, t->tm_mon); prot_a_output_ul(fp, t->tm_year); diff --git a/src/server/prot-a-parse-arg-c.awk b/src/server/prot-a-parse-arg-c.awk index 062dd52c832ba019bf37a45339f6c6dd27e3b97e..a5e2827bc1e42b072ea5fe584c56d6dded190015 100644 --- a/src/server/prot-a-parse-arg-c.awk +++ b/src/server/prot-a-parse-arg-c.awk @@ -1,5 +1,5 @@ # -# $Id: prot-a-parse-arg-c.awk,v 0.22 1999/05/12 13:25:21 byers Exp $ +# $Id: prot-a-parse-arg-c.awk,v 0.23 1999/05/18 13:06:56 byers Exp $ # Copyright (C) 1991, 1992, 1993, 1994, 1996 Lysator Academic Computer Association. # # This file is part of the LysKOM server. @@ -22,7 +22,7 @@ # # Please mail bug reports to bug-lyskom@lysator.liu.se. # -# $Id: prot-a-parse-arg-c.awk,v 0.22 1999/05/12 13:25:21 byers Exp $ +# $Id: prot-a-parse-arg-c.awk,v 0.23 1999/05/18 13:06:56 byers Exp $ BEGIN { printf("/* Don't edit this file - it is generated automatically"); printf(" from\n prot-a-parse-arg-c.awk and fncdef.txt */\n\n"); @@ -139,9 +139,11 @@ $1 != "#" && $1 != "" { printf("\t longjmp(parse_env, ISC_PROTOCOL_ERR);\n"); } else if ( $i == "aux_item" ) - printf("\tprot_a_parse_aux_item_list(client, &client->aux_item);\n"); + printf("\tprot_a_parse_aux_item(client, &client->aux_item);\n"); else if ( $i == "aux_item_list" ) printf("\tprot_a_parse_aux_item_list(client, &client->aux_item_list, %s);\n", $(++i)); + else if ( $i == "misc_info_list" ) + printf("\tprot_a_parse_misc_info_list(client, &client->misc_info_list, %s);\n", $(++i)); else if ( $i == "time_date" ) printf("\tprot_a_parse_time_date(client, &client->time);\n"); else if ( $i == "info" ) diff --git a/src/server/prot-a-parse.c b/src/server/prot-a-parse.c index 0e8b3e265530a8ba87b821c2bac3491ec8fa4bb6..c829811787845bf32ed4dea7a88da9d01f770d09 100644 --- a/src/server/prot-a-parse.c +++ b/src/server/prot-a-parse.c @@ -1,5 +1,5 @@ /* - * $Id: prot-a-parse.c,v 0.37 1999/05/12 13:25:22 byers Exp $ + * $Id: prot-a-parse.c,v 0.38 1999/05/18 13:06:57 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -34,7 +34,7 @@ #endif static const char * -rcsid = "$Id: prot-a-parse.c,v 0.37 1999/05/12 13:25:22 byers Exp $"; +rcsid = "$Id: prot-a-parse.c,v 0.38 1999/05/18 13:06:57 byers Exp $"; #include "rcs.h" USE(rcsid); @@ -69,6 +69,10 @@ USE(rcsid); BUGDECL; +/* Forward declarations */ + +static void prot_a_hunt_array_end(Connection *client); + /* * Return next token from the input stream. Note that the String returned * by this call points into data that might be freed by the next call to @@ -157,10 +161,15 @@ prot_a_parse_num_list(Connection *client, longjmp(parse_env, ISC_PROTOCOL_ERR); if (res->length <= maxlen) + { res->data = smalloc(sizeof(*res->data) * res->length); + } else { - assert(res->data == NULL); + /* Parse one element more than the maximum to allow clients + of this function to detect the too-long array if they + want to */ + res->data = smalloc(sizeof(*res->data) * (maxlen + 1)); } client->array_parse_index = 0; @@ -170,13 +179,24 @@ prot_a_parse_num_list(Connection *client, while (client->array_parse_index < res->length) { long tmp = prot_a_parse_long(client); - if (res->data != NULL) - res->data[client->array_parse_index] = tmp; - ++client->array_parse_index; + + /* Enter the value into the array only if the + parse index is inside the allocated array */ + + if (client->array_parse_index < res->length && + client->array_parse_index < (maxlen + 1)) + { + res->data[client->array_parse_index] = tmp; + } + client->array_parse_index += 1; } client->array_parse_pos = 3; /* Fall through */ case 3: /* Closing brace. */ + /* Adjust the result length if we were parsing a long array */ + res->length = min(maxlen+1, res->length); + + /* Read the closing brace */ if ( parse_nonwhite_char(client) != '}' ) longjmp(parse_env, ISC_PROTOCOL_ERR); default: @@ -383,6 +403,9 @@ prot_a_parse_string(Connection *client, /* Fall through */ case 2: /* Was the string too long? If so, skip the truncated data. */ + /* It looks like we're leaving one extra character in the + string here, which is necessary if we want clients of + this function to be able to detect long strings. */ client_len = result->len; truncated_len = min(maxlen+1, client_len); @@ -455,11 +478,12 @@ prot_a_parse_aux_item(Connection *client, extern void prot_a_parse_aux_item_list(Connection *client, Aux_item_list *result, - unsigned long maxlen) + int maxlen) { static unsigned long err_cnt = 0; int i; long len; + Aux_item dummy_aux_item; switch (client->array_parse_pos) { @@ -488,11 +512,17 @@ prot_a_parse_aux_item_list(Connection *client, case 1: if ( parse_nonwhite_char(client) != '{' ) longjmp(parse_env, ISC_PROTOCOL_ERR); - if ( result->length > maxlen ) - longjmp(parse_env, ISC_PROTOCOL_ERR); - result->items = smalloc(result->length * sizeof(Aux_item)); - for (i = 0; i < result->length; i++) + if (result->length <= maxlen) + { + result->items = smalloc(result->length * sizeof(Aux_item)); + } + else + { + result->items = smalloc((maxlen+1) * sizeof(Aux_item)); + } + + for (i = 0; i < min(result->length, maxlen+1); i++) { result->items[i].data = EMPTY_STRING; } @@ -501,12 +531,27 @@ prot_a_parse_aux_item_list(Connection *client, case 2: while( client->array_parse_index < result->length ) { - prot_a_parse_aux_item(client, - &result->items[client->array_parse_index]); + /* Enter a parsed aux item into the list only if we + have parsed less than the length of the list */ + if (client->array_parse_index < result->length && + client->array_parse_index <= maxlen) + { + prot_a_parse_aux_item(client, + &result->items[ + client->array_parse_index]); + } + else + { + prot_a_parse_aux_item(client, &dummy_aux_item); + } client->array_parse_index += 1; } client->array_parse_pos = 3; case 3: + /* Adjust the length of the result to the length allocated */ + result->length = min(result->length, maxlen+1); + + /* Read the closing brace */ if ( parse_nonwhite_char(client) != '}' ) longjmp(parse_env, ISC_PROTOCOL_ERR); default: @@ -514,11 +559,105 @@ prot_a_parse_aux_item_list(Connection *client, } } +extern void +prot_a_parse_misc_info_list(Connection *client, + Misc_info_list *result, + int maxlen) +{ + static unsigned long err_cnt = 0; + int i; + long len; + Misc_info dummy_misc_info; + + switch (client->array_parse_pos) + { + case 0: + if ((result->no_of_misc != 0 || result->misc != NULL) && err_cnt++ < 20) + { + kom_log("WNG: prot_a_parse_aux_item_list(): len = %lu data = %lu\n", + (unsigned long)result->no_of_misc, (unsigned long)result->misc); + result->no_of_misc = 0; + result->misc = NULL; + if (err_cnt == 20) + kom_log("The above warning is now turned off."); + } + + len = prot_a_parse_long(client); + if (len < 0) + { + isc_puts("%%Insane array size.\n", client->isc_session); + isc_flush(client->isc_session); + longjmp(parse_env, ISC_LOGOUT); + } + result->no_of_misc = len; + client->array_parse_pos = 1; + /* Fall through */ + + case 1: + if ( parse_nonwhite_char(client) != '{' ) + longjmp(parse_env, ISC_PROTOCOL_ERR); + + if (result->no_of_misc <= maxlen) + { + result->misc = smalloc(result->no_of_misc * sizeof(Misc_info)); + } + else + { + result->misc = smalloc((maxlen+1) * sizeof(Misc_info)); + } + + for (i = 0; i < min(result->no_of_misc, maxlen+1); i++) + { + result->misc[i].type = unknown_info; + } + client->array_parse_index = 0; + client->array_parse_pos = 2; + case 2: + while( client->array_parse_index < result->no_of_misc ) + { + /* Enter a parsed aux item into the list only if we + have parsed less than the no_of_misc of the list */ + if (client->array_parse_index < result->no_of_misc && + client->array_parse_index <= maxlen) + { + prot_a_parse_misc_info(client, + &result->misc[ + client->array_parse_index]); + + /* If the most recently parsed item is an unknown, the + misc-info parser will have skipped to the end of the + array. Make allowances for this. */ + if (result->misc[client->array_parse_index].type == unknown_info) + { + result->no_of_misc = client->array_parse_index + 1; + } + } + else + { + prot_a_parse_misc_info(client, &dummy_misc_info); + } + client->array_parse_index += 1; + } + client->array_parse_pos = 3; + case 3: + /* Adjust the no_of_misc of the result to the length allocated */ + result->no_of_misc = min(result->no_of_misc, maxlen+1); + + /* Read the closing brace */ + if ( parse_nonwhite_char(client) != '}' ) + longjmp(parse_env, ISC_PROTOCOL_ERR); + default: + client->array_parse_pos = 0; + } +} + extern void prot_a_parse_misc_info(Connection *client, Misc_info *result) { + struct tm tmp_time; + switch ( client->struct_parse_pos ) { case 0: @@ -560,16 +699,32 @@ prot_a_parse_misc_info(Connection *client, break; case comm_in: + result->datum.commented_in = prot_a_parse_long(client); + break; + case footn_in: + result->datum.footnoted_in = prot_a_parse_long(client); + break; + case rec_time: + prot_a_parse_time_date(client, &tmp_time); + result->datum.received_at = mktime(&tmp_time); + break; + case sent_by: + result->datum.sender = prot_a_parse_long(client); + break; + case sent_at: - /* Fall through */ - -#ifndef COMPILE_CHECKS + prot_a_parse_time_date(client, &tmp_time); + result->datum.sent_at = mktime(&tmp_time); + break; + default: -#endif - longjmp(parse_env, ISC_PROTOCOL_ERR); + result->datum.unknown_type = result->type; + result->type = unknown_info; + client->array_hunt_depth = 1; + prot_a_hunt_array_end(client); } default: client->struct_parse_pos = 0; @@ -768,3 +923,129 @@ prot_a_hunt_nl(Connection *client) } } } + +/* + * Hunt for the end of an array. For this to work you need to set + * array_hunt_depth to the number of nested arrays you want to + * break out of (normally 1.) After this call the next token on + * the input stream from the client will be the closing brace of + * the array. + */ + +static void +prot_a_hunt_array_end(Connection *client) +{ + String_size number_end; + String_size len; + + while (1) + { + switch (client->hunt_parse_pos) + { + case 0: /* whitspace/simple tokens */ + if ( client->first_to_parse >= s_strlen(client->unparsed) ) + longjmp(parse_env, ISC_MSG_INCOMPLETE); + + switch(client->unparsed.string[client->first_to_parse]) + { + case ' ': + case '\r': + case '\t': + case '*': + case '\n': + client->first_to_parse++; + break; + case '{': + client->array_hunt_depth += 1; + client->first_to_parse++; + break; + case '}': + client->array_hunt_depth -= 1; + if (client->array_hunt_depth <= 0) + { + client->hunt_parse_pos = 0; + return; + } + else + { + client->first_to_parse++; + } + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + /* Entering a number -- possibly a string. */ + /* Don't increase first_to_parse. */ + client->hunt_parse_pos = 1; + break; + default: + longjmp(parse_env, ISC_PROTOCOL_ERR); + } + break; + case 1: /* number/string */ + /* Entering a number. The first char is known to be a digit. + Parse the entire number at once. */ + len = client->unparsed.string[client->first_to_parse] - '0'; + for (number_end = client->first_to_parse + 1; + number_end < s_strlen(client->unparsed); + number_end++) + { + if (client->unparsed.string[number_end] >= '0' + && client->unparsed.string[number_end] <= '9') + { + len = 10 * len + client->unparsed.string[number_end] - '0'; + } + else + { + /* The end of the number was reached. */ + break; + } + } + + if (number_end == s_strlen(client->unparsed)) + longjmp(parse_env, ISC_MSG_INCOMPLETE); + + if (client->unparsed.string[number_end] == 'H') + { + /* We are entering a string. Use num0 to store the + lenght of the string to skip. */ + client->array_hunt_num = len; + client->first_to_parse = number_end + 1; + client->hunt_parse_pos = 2; + } + else + { + /* We have just skipped past a number that was not the + start of a string. */ + client->first_to_parse = number_end; + client->hunt_parse_pos = 0; + } + break; + case 2: /* Skipping a string. */ + if (client->array_hunt_num == 0) + { + /* The entire string has been skipped. */ + client->hunt_parse_pos = 0; + break; + } + len = s_strlen(client->unparsed) - client->first_to_parse; + if (client->array_hunt_num <= len) + { + /* The entire string is present. Skip it. */ + client->first_to_parse += client->array_hunt_num; + client->hunt_parse_pos = 0; + break; + } + else + { + /* Skip as much of the string as possible. */ + client->array_hunt_num -= len; + client->first_to_parse = s_strlen(client->unparsed); + longjmp(parse_env, ISC_MSG_INCOMPLETE); + } + abort(); /* NOTREACHED */ + default: + abort(); + } + } +} diff --git a/src/server/prot-a-parse.h b/src/server/prot-a-parse.h index a32e3cc07e8f71e7a587ade73525a496af274ce3..68275a8bc283c04749897d1c4115d211a56d99cc 100644 --- a/src/server/prot-a-parse.h +++ b/src/server/prot-a-parse.h @@ -1,5 +1,5 @@ /* - * $Id: prot-a-parse.h,v 0.16 1999/05/12 13:25:23 byers Exp $ + * $Id: prot-a-parse.h,v 0.17 1999/05/18 13:06:58 byers Exp $ * Copyright (C) 1991, 1992, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -23,7 +23,7 @@ * Please mail bug reports to bug-lyskom@lysator.liu.se. */ /* - * $Id: prot-a-parse.h,v 0.16 1999/05/12 13:25:23 byers Exp $ + * $Id: prot-a-parse.h,v 0.17 1999/05/18 13:06:58 byers Exp $ * */ extern long @@ -67,9 +67,13 @@ prot_a_parse_aux_item(Connection *client, extern void prot_a_parse_aux_item_list(Connection *client, Aux_item_list *result, - unsigned long maxlen); + int maxlen); extern void +prot_a_parse_misc_info_list(Connection *client, + Misc_info_list *result, + int maxlen); +extern void prot_a_parse_misc_info(Connection *client, Misc_info *result); diff --git a/src/server/prot-a.c b/src/server/prot-a.c index b00e5a31f9e48b3e59739a989c481e14ef3d517c..5630dcb97e4fc0e5dc37ba6f224e9cb0223f313b 100644 --- a/src/server/prot-a.c +++ b/src/server/prot-a.c @@ -1,5 +1,5 @@ /* - * $Id: prot-a.c,v 0.56 1999/04/28 22:13:14 ceder Exp $ + * $Id: prot-a.c,v 0.57 1999/05/18 13:06:59 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -32,7 +32,7 @@ #endif static const char * -rcsid = "$Id: prot-a.c,v 0.56 1999/04/28 22:13:14 ceder Exp $"; +rcsid = "$Id: prot-a.c,v 0.57 1999/05/18 13:06:59 byers Exp $"; #include "rcs.h" USE(rcsid); @@ -310,6 +310,9 @@ prot_a_init(Connection *conn) conn->array_parse_pos = 0; conn->struct_parse_pos = 0; conn->string_parse_pos = 0; + conn->hunt_parse_pos = 0; + conn->array_hunt_num = 0; + conn->array_hunt_depth = 0; conn->ref_no = 0; conn->function = call_fnc_login_old; conn->num0 = 0; @@ -319,7 +322,8 @@ prot_a_init(Connection *conn) conn->c_string0 = EMPTY_STRING; conn->c_string1 = EMPTY_STRING; conn->string0 = EMPTY_STRING; - conn->c_misc_info_p = NULL; + conn->misc_info_list.misc = NULL; + conn->misc_info_list.no_of_misc = 0; conn->aux_item_list.items = NULL; conn->aux_item_list.length = 0; conn->c_local_text_no_p = NULL; @@ -348,7 +352,11 @@ prot_a_destruct(Connection *conn) conn->aux_item_list.length = 0; sfree(conn->aux_item_list.items); conn->aux_item_list.items = NULL; - sfree(conn->c_misc_info_p); + + conn->misc_info_list.no_of_misc = 0; + sfree(conn->misc_info_list.misc); + conn->misc_info_list.misc = NULL; + sfree(conn->c_local_text_no_p); } diff --git a/src/server/server-config.c b/src/server/server-config.c index 57771b6d6caf8bf6c32d6f4a6c2f9712ed2749f7..f97c12c845822370ec7dff741bda396ea0f0ffa7 100644 --- a/src/server/server-config.c +++ b/src/server/server-config.c @@ -1,5 +1,5 @@ /* - * $Id: server-config.c,v 0.59 1999/05/12 13:25:31 byers Exp $ + * $Id: server-config.c,v 0.60 1999/05/18 13:07:00 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -37,7 +37,7 @@ #endif static const char * -rcsid = "$Id: server-config.c,v 0.59 1999/05/12 13:25:31 byers Exp $"; +rcsid = "$Id: server-config.c,v 0.60 1999/05/18 13:07:00 byers Exp $"; #include "rcs.h" USE(rcsid); @@ -149,6 +149,12 @@ static const struct parameter parameters[] = { {"Nologin file", assign_string, 0, 1, "/etc/nologin", ¶m.nologin_file}, + /* Stuff */ + + { "Y2K Compatibility", + assign_int, 0, 1, "2", ¶m.y2k_compat }, + + /* Performance tuning parameters (milliseconds) */ {"Idle timeout", diff --git a/src/server/session.c b/src/server/session.c index e64151df0e8028bc3d403227e00c72bef323caf3..4d75f83904d9328bdae774a4a9950f4fab364381 100644 --- a/src/server/session.c +++ b/src/server/session.c @@ -1,5 +1,5 @@ /* - * $Id: session.c,v 0.46 1999/05/16 21:46:57 ceder Exp $ + * $Id: session.c,v 0.47 1999/05/18 13:07:01 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -34,7 +34,7 @@ #endif static const char * -rcsid = "$Id: session.c,v 0.46 1999/05/16 21:46:57 ceder Exp $"; +rcsid = "$Id: session.c,v 0.47 1999/05/18 13:07:01 byers Exp $"; #include "rcs.h" USE(rcsid); @@ -936,7 +936,11 @@ accept_async(Number_list *num_list) * Check agains maliciously long arrays */ - if (num_list->data == NULL && num_list->length > 0) + /* FIXME: The following test only needs one branch depending on + FIXME: which implementation of prot_a_parse_num_list we go with. */ + + if (num_list->length > param.accept_async_len || + (num_list->data == NULL && num_list->length > 0)) { err_stat = 0; kom_errno = KOM_LONG_ARRAY; diff --git a/src/server/testsuite/lyskomd.0/01.exp b/src/server/testsuite/lyskomd.0/01.exp index fd645ecfd759038edaeec0e0824dea7e768e1d48..a3ee14cfa431fafb391ee04c1beb7eb665b9b86d 100644 --- a/src/server/testsuite/lyskomd.0/01.exp +++ b/src/server/testsuite/lyskomd.0/01.exp @@ -351,7 +351,7 @@ send "1113 95 0 { } 0 { }\n" simple_expect "%1113 6 0" "modify-system-info" # 96:query-predefined-aux-items send "1114 96\n" -simple_expect "=1114 26 { 28 27 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" "query-predefined-aux-items" +simple_expect "=1114 28 { 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" "query-predefined-aux-items" # 97:set-expire send "1115 97 1 76\n" simple_expect "%1115 6 0" "set-expire" diff --git a/src/server/testsuite/lyskomd.0/03.exp b/src/server/testsuite/lyskomd.0/03.exp index 106766eed91d62fae5debf5624258093fa814b1e..c16bd9e9388abc028cd20fb8593f600bd92aecf8 100644 --- a/src/server/testsuite/lyskomd.0/03.exp +++ b/src/server/testsuite/lyskomd.0/03.exp @@ -114,7 +114,7 @@ simple_expect "=1009" # exactly these aux-items. It shouldn't be hard to fix the test suite # when more items are added. send "1010 96\n" -simple_expect "=1010 26 { 28 27 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" +simple_expect "=1010 28 { 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" send "1011 82\n" simple_expect "=1011" @@ -1259,7 +1259,7 @@ simple_expect "=1345 $server_compat_version 1 2 3 4 0 1 { 1 9 5 $any_time 000000 # test call 96 (query-predefined-aux-items) talk_to client 1 send "1346 96\n" -simple_expect "=1346 26 { 28 27 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" +simple_expect "=1346 28 { 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" # test call 97 (set-expire) send "1347 97 10 7123123\n" diff --git a/src/server/testsuite/lyskomd.0/aux-items-cov.exp b/src/server/testsuite/lyskomd.0/aux-items-cov.exp index 80310cacad685790fab6732348ed519d38a9375a..cdc6f879afe6f61181dc27a4bb94572aa3d3fa0c 100644 --- a/src/server/testsuite/lyskomd.0/aux-items-cov.exp +++ b/src/server/testsuite/lyskomd.0/aux-items-cov.exp @@ -42,7 +42,10 @@ read_versions source "$srcdir/config/prot-a.exp" -lyskomd_start "lyskomd.0/aux-items.cov" +lyskomd_start "lyskomd.0/aux-items.cov" "\ +Max aux_items deleted per call: 10 +Max aux_items added per call: 10" + client_start 0 talk_to client 0 @@ -107,6 +110,9 @@ simple_expect "=4000" send "4001 95 0 { } 1 { 1004 00000000 0 [holl "999"] }\n" simple_expect "=4001" +send "4002 94\n" +simple_expect "=4002 $any_num $any_num $any_num $any_num $any_num $any_num 1 { 1 1004 5 $any_time 00000000 0 [holl "999"] }" + # Attempt to create item with a broken validation regexp, twice send "5000 95 0 { } 1 { 1000 00000000 0 [holl "ABC"] }\n" @@ -131,6 +137,276 @@ simple_expect "=5003" # FIXME: Call to aux_item_trigger_mark_text on item added to text? # FIXME: Call to aux_item_trigger_unmark_text on item added to text? +# FIXME: Call to modify-X-info with a too-long delete list +# FIXME: Call to modify-X-info with a too-long add list + +send "5100 92 1 11 { 1 2 3 4 5 6 7 8 9 10 11 } 0 { }\n" +simple_expect "%5100 46 10" + +send "5101 92 1 0 { } 11 { 1 00000000 0 [holl "X"] 2 00000000 0 [holl "X"] 3 00000000 0 [holl "X"] 4 00000000 0 [holl "X"] 5 00000000 0 [holl "X"] 6 00000000 0 [holl "X"] 7 00000000 0 [holl "X"] 8 00000000 0 [holl "X"] 9 00000000 0 [holl "X"] 10 00000000 0 [holl "X"] 11 00000000 0 [holl "X"] }\n" +simple_expect "%5101 46 10" + +send "5102 93 5 11 { 1 2 3 4 5 6 7 8 9 10 11 } 0 { }\n" +simple_expect "%5102 46 10" + +send "5103 93 5 0 { } 11 { 1 00000000 0 [holl "X"] 2 00000000 0 [holl "X"] 3 00000000 0 [holl "X"] 4 00000000 0 [holl "X"] 5 00000000 0 [holl "X"] 6 00000000 0 [holl "X"] 7 00000000 0 [holl "X"] 8 00000000 0 [holl "X"] 9 00000000 0 [holl "X"] 10 00000000 0 [holl "X"] 11 00000000 0 [holl "X"] }\n" +simple_expect "%5103 46 10" + +send "5104 95 11 { 1 2 3 4 5 6 7 8 9 10 11 } 0 { }\n" +simple_expect "%5104 46 10" + +send "5105 95 0 { } 11 { 1 00000000 0 [holl "X"] 2 00000000 0 [holl "X"] 3 00000000 0 [holl "X"] 4 00000000 0 [holl "X"] 5 00000000 0 [holl "X"] 6 00000000 0 [holl "X"] 7 00000000 0 [holl "X"] 8 00000000 0 [holl "X"] 9 00000000 0 [holl "X"] 10 00000000 0 [holl "X"] 11 00000000 0 [holl "X"] }\n" +simple_expect "%5105 46 10" + + + +# Test linking aux items + +# Create on text link to conf +# Create on text link to info +# Create on text link to text + +kom_login 5 "gazonk" 0 +send "5998 86 [holl "Testing"] 1 { 0 5 } 0 { }\n" +simple_expect "=5998 4" + +send "5999 86 [holl "Jesting"] 1 { 0 5 } 0 { }\n" +simple_expect "=5999 5" + +send "6000 92 4 0 { } 3 { 1006 00000000 0 [holl "T 1007 5"] 1006 00000000 0 [holl "C 1007 5"] 1006 00000000 0 [holl "I 1007 0"] }\n" +simple_expect "=6000" + +send "6001 90 5\n" +simple_expect "=6001 $any_time 5 0 7 0 2 { 0 5 6 3 } 1 { 1 1007 0 $any_time 00000000 0 [holl "T 1006 4"] }" + +send "6002 91 5\n" +simple_expect "=6002 [holl "Administrat�r .f�r. LysKOM"] 10011000 $any_time $any_time 5 0 5 0 0 0 77 77 1 1 3 0 1 { 1 1007 0 $any_time 00000000 0 [holl "T 1006 4"] }" + +send "6003 94\n" +simple_expect "=6003 $any_num $any_num $any_num $any_num $any_num $any_num 2 { 1 1004 5 $any_time 00000000 0 [holl "999"] 2 1007 0 $any_time 00000000 0 [holl "T 1006 4"] }" + + +send "6100 88 [holl "C7"] 00000000 0 { }\n" +simple_expect "=6100 7" + +send "6101 88 [holl "C8"] 00000000 0 { }\n" +simple_expect "=6101 8" + + +# Create on conf link to conf +# Create on conf link to info +# Create on conf link to text + +send "6102 93 7 0 { } 3 { 1006 00000000 0 [holl "T 1007 5"] 1006 00000000 0 [holl "C 1007 8"] 1006 00000000 0 [holl "I 1007 0"] }\n" +simple_expect "=6102" + +send "6103 90 5\n" +simple_expect "=6103 $any_time 5 0 7 0 2 { 0 5 6 3 } 2 { 1 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 2 1007 0 $any_time 00000000 0 [holl "C 1006 7"] }" + +send "6104 91 8\n" +simple_expect "=6104 [holl "C8"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 1 { 1 1007 0 $any_time 00000000 0 [holl "C 1006 7"] }" + +send "6105 94\n" +simple_expect "=6105 $any_num $any_num $any_num $any_num $any_num $any_num 3 { 1 1004 5 $any_time 00000000 0 [holl "999"] 2 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 3 1007 0 $any_time 00000000 0 [holl "C 1006 7"] }" + + +# Create on info link to conf +# Create on info link to info +# Create on info link to text + +kom_enable 255 + +send "6106 95 0 { } 3 { 1006 00000000 0 [holl "T 1007 5"] 1006 00000000 0 [holl "C 1007 8"] 1006 00000000 0 [holl "I 1007 0"] }\n" +simple_expect "=6106" + +send "6107 90 5\n" +simple_expect "=6107 $any_time 5 0 7 0 2 { 0 5 6 3 } 3 { 1 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 2 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 3 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6108 91 8\n" +simple_expect "=6108 [holl "C8"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 2 { 1 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 2 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6109 94\n" +simple_expect "=6109 $any_num $any_num $any_num $any_num $any_num $any_num 7 { 1 1004 5 $any_time 00000000 0 [holl "999"] 2 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 3 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] 5 1006 5 $any_time 00000000 0 [holl "C 1007 8"] 6 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 7 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + + + +# Delete manually created text items + +send "6200 92 4 3 { 1 2 3 } 0 { }\n" +simple_expect "=6200" + +send "6201 90 5\n" +simple_expect "=6201 $any_time 5 0 7 0 2 { 0 5 6 3 } 2 { 2 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 3 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6202 91 5\n" +simple_expect "=6202 [holl "Administrat�r .f�r. LysKOM"] 10011000 $any_time $any_time 5 0 5 0 0 0 77 77 1 1 3 0 0 \\*" + +send "6203 94\n" +simple_expect "=6203 $any_num $any_num $any_num $any_num $any_num $any_num 6 { 1 1004 5 $any_time 00000000 0 [holl "999"] 3 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] 5 1006 5 $any_time 00000000 0 [holl "C 1007 8"] 6 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 7 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + + +# Delete manually created conf item + +send "6204 93 7 3 { 1 2 3 } 0 { }\n" +simple_expect "=6204" + +send "6205 90 5\n" +simple_expect "=6205 $any_time 5 0 7 0 2 { 0 5 6 3 } 1 { 3 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6206 91 8\n" +simple_expect "=6206 [holl "C8"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 1 { 2 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6207 94\n" +simple_expect "=6207 $any_num $any_num $any_num $any_num $any_num $any_num 5 { 1 1004 5 $any_time 00000000 0 [holl "999"] 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] 5 1006 5 $any_time 00000000 0 [holl "C 1007 8"] 6 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 7 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + + +# Delete manually created info item + +kom_enable 255 + +send "6208 95 3 { 4 5 6 } 0 { }\n" +simple_expect "=6208" + +send "6209 90 5\n" +simple_expect "=6209 $any_time 5 0 7 0 2 { 0 5 6 3 } 0 \\*" + +send "6210 91 8\n" +simple_expect "=6210 [holl "C8"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 0 \\*" + +send "6211 94\n" +simple_expect "=6211 $any_num $any_num $any_num $any_num $any_num $any_num 1 { 1 1004 5 $any_time 00000000 0 [holl "999"] }" + + +# Delete auto created info item + +send "6212 92 4 0 { } 3 { 1006 00000000 0 [holl "T 1007 5"] 1006 00000000 0 [holl "C 1007 5"] 1006 00000000 0 [holl "I 1007 0"] }\n" +simple_expect "=6212" + +send "6213 90 4\n" +simple_expect "=6213 $any_time 5 0 7 0 2 { 0 5 6 2 } 3 { 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] 5 1006 5 $any_time 00000000 0 [holl "C 1007 5"] 6 1006 5 $any_time 00000000 0 [holl "I 1007 0"] }" + + +send "6214 94\n" +simple_expect "=6214 $any_num $any_num $any_num $any_num $any_num $any_num 2 { 1 1004 5 $any_time 00000000 0 [holl "999"] 8 1007 0 $any_time 00000000 0 [holl "T 1006 4"] }" + +send "6215 95 1 { 8 } 0 { }\n" +simple_expect "=6215" + +send "6216 94\n" +simple_expect "=6216 $any_num $any_num $any_num $any_num $any_num $any_num 1 { 1 1004 5 $any_time 00000000 0 [holl "999"] }" + +send "62160 90 4\n" +simple_expect "=62160 $any_time 5 0 7 0 2 { 0 5 6 2 } 2 { 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] 5 1006 5 $any_time 00000000 0 [holl "C 1007 5"] }" + + +# Delete auto created conf item + +send "6217 91 5\n" +simple_expect "=6217 [holl "Administrat�r .f�r. LysKOM"] 10011000 $any_time $any_time 5 0 5 0 0 0 77 77 1 1 3 0 1 { 2 1007 0 $any_time 00000000 0 [holl "T 1006 4"] }" + +send "6218 93 5 1 { 2 } 0 { }\n" +simple_expect "=6218" + +send "6219 91 5\n" +simple_expect "=6219 [holl "Administrat�r .f�r. LysKOM"] 10011000 $any_time $any_time 5 0 5 0 0 0 77 77 1 1 3 0 0 \\*" + +send "6220 90 4\n" +simple_expect "=6220 $any_time 5 0 7 0 2 { 0 5 6 2 } 1 { 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] }" + + +# Delete auto created text item + +send "6221 90 5\n" +simple_expect "=6221 $any_time 5 0 7 0 2 { 0 5 6 3 } 1 { 4 1007 0 $any_time 00000000 0 [holl "T 1006 4"] }" + +send "6222 92 5 1 { 4 } 0 { }\n" +simple_expect "=6222" + +send "6223 90 5\n" +simple_expect "=6223 $any_time 5 0 7 0 2 { 0 5 6 3 } 0 \\*" + +send "6224 90 4\n" +simple_expect "=6224 $any_time 5 0 7 0 2 { 0 5 6 2 } 0 \\*" + + +# Delete text with items linked to text, conf and info +# Delete conf with items linked to text, conf and info + +# FIXME: Test cases here + + +# Text with permanent item, items linked to conf, text, info +# Conf with permanent item, items linked to conf, text, info +# Info with permanent item, items linked to conf, text, info +# Attempt to delete all (this should cover undelete functions) + +# Create the items (bracketed by non-linked items for additional testing) + +send "6300 92 4 0 { } 5 { 2000 00000000 0 [holl "A"] 1006 00000000 0 [holl "T 1007 4"] 1006 00000000 0 [holl "C 1007 7"] 1006 00000000 0 [holl "I 1007 0"] 1008 00000000 0 [holl "X"] }\n" +simple_expect "=6300" + +send "6301 93 7 0 { } 5 { 2000 00000000 0 [holl "A"] 1006 00000000 0 [holl "T 1007 4"] 1006 00000000 0 [holl "C 1007 7"] 1006 00000000 0 [holl "I 1007 0"] 1008 00000000 0 [holl "X"] }\n" +simple_expect "=6301" + +send "6302 95 0 { } 5 { 2000 00000000 0 [holl "A"] 1006 00000000 0 [holl "T 1007 4"] 1006 00000000 0 [holl "C 1007 7"] 1006 00000000 0 [holl "I 1007 0"] 1008 00000000 0 [holl "X"] }\n" +simple_expect "=6302" + + +# Check the original data + +send "6303 90 4\n" +simple_expect "=6303 $any_time 5 0 7 0 2 { 0 5 6 2 } 8 { 7 2000 5 $any_time 00000000 0 [holl "A"] 8 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 9 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 10 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 11 1008 5 $any_time 00000000 0 [holl "X"] 12 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 13 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 14 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6304 91 7\n" +simple_expect "=6304 [holl "C7"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 8 { 4 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 5 2000 5 $any_time 00000000 0 [holl "A"] 6 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 7 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 8 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 9 1008 5 $any_time 00000000 0 [holl "X"] 10 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 11 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6305 94\n" +simple_expect "=6305 $any_num $any_num $any_num $any_num $any_num $any_num 9 { 1 1004 5 $any_time 00000000 0 [holl "999"] 9 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 10 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 11 2000 5 $any_time 00000000 0 [holl "A"] 12 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 13 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 14 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 15 1008 5 $any_time 00000000 0 [holl "X"] 16 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + + + +# Attempt to delete all items on the text + +send "6307 92 4 5 { 7 8 9 10 11 } 1 { 1009 00000000 0 [holl "X"] }\n" +simple_expect "%6307 48 0" + +send "6308 90 4\n" +simple_expect "=6308 $any_time 5 0 7 0 2 { 0 5 6 2 } 8 { 7 2000 5 $any_time 00000000 0 [holl "A"] 8 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 9 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 10 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 11 1008 5 $any_time 00000000 0 [holl "X"] 12 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 13 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 14 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6309 91 7\n" +simple_expect "=6309 [holl "C7"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 8 { 4 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 5 2000 5 $any_time 00000000 0 [holl "A"] 6 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 7 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 8 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 9 1008 5 $any_time 00000000 0 [holl "X"] 10 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 11 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6310 94\n" +simple_expect "=6310 $any_num $any_num $any_num $any_num $any_num $any_num 9 { 1 1004 5 $any_time 00000000 0 [holl "999"] 9 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 10 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 11 2000 5 $any_time 00000000 0 [holl "A"] 12 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 13 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 14 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 15 1008 5 $any_time 00000000 0 [holl "X"] 16 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +# FIXME: Check all linked objects too + +send "6311 93 7 5 { 5 6 7 8 9 } 1 { 1009 00000000 0 [holl "X"] }\n" +simple_expect "%6311 48 0" + +send "6312 90 4\n" +simple_expect "=6312 $any_time 5 0 7 0 2 { 0 5 6 2 } 8 { 7 2000 5 $any_time 00000000 0 [holl "A"] 8 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 9 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 10 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 11 1008 5 $any_time 00000000 0 [holl "X"] 12 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 13 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 14 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6313 91 7\n" +simple_expect "=6313 [holl "C7"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 8 { 4 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 5 2000 5 $any_time 00000000 0 [holl "A"] 6 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 7 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 8 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 9 1008 5 $any_time 00000000 0 [holl "X"] 10 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 11 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6314 94\n" +simple_expect "=6314 $any_num $any_num $any_num $any_num $any_num $any_num 9 { 1 1004 5 $any_time 00000000 0 [holl "999"] 9 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 10 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 11 2000 5 $any_time 00000000 0 [holl "A"] 12 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 13 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 14 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 15 1008 5 $any_time 00000000 0 [holl "X"] 16 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + + +send "6315 95 6 { 1 11 12 13 14 15 } 1 { 1009 00000000 0 [holl "X"] }\n" +simple_expect "%6315 48 0" + +send "6316 90 4\n" +simple_expect "=6316 $any_time 5 0 7 0 2 { 0 5 6 2 } 8 { 7 2000 5 $any_time 00000000 0 [holl "A"] 8 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 9 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 10 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 11 1008 5 $any_time 00000000 0 [holl "X"] 12 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 13 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 14 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6317 91 7\n" +simple_expect "=6317 [holl "C7"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 8 { 4 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 5 2000 5 $any_time 00000000 0 [holl "A"] 6 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 7 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 8 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 9 1008 5 $any_time 00000000 0 [holl "X"] 10 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 11 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + +send "6318 94\n" +simple_expect "=6318 $any_num $any_num $any_num $any_num $any_num $any_num 9 { 1 1004 5 $any_time 00000000 0 [holl "999"] 9 1007 0 $any_time 00000000 0 [holl "T 1006 4"] 10 1007 0 $any_time 00000000 0 [holl "C 1006 7"] 11 2000 5 $any_time 00000000 0 [holl "A"] 12 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 13 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 14 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 15 1008 5 $any_time 00000000 0 [holl "X"] 16 1007 0 $any_time 00000000 0 [holl "I 1006 0"] }" + + # Finish @@ -144,5 +420,5 @@ lyskomd_death # Try some broken config files -lyskomd_fail_start "lyskomd.0/broken-aux-items.conf" +# lyskomd_fail_start "lyskomd.0/broken-aux-items.conf" diff --git a/src/server/testsuite/lyskomd.0/aux-items.cov b/src/server/testsuite/lyskomd.0/aux-items.cov index 8a0bd29d9d200eb0f83926f21fc56de0b60c36e7..cd978407704cfb231ef9ba25a58c5210cb5c0944 100644 --- a/src/server/testsuite/lyskomd.0/aux-items.cov +++ b/src/server/testsuite/lyskomd.0/aux-items.cov @@ -12,11 +12,6 @@ author-only = true; } -# 1002 : invalid-trigger (any) -# { -# add-trigger = fubar(); -# } - 1003 : mark-text (any) { add-trigger = mark-text(); @@ -31,3 +26,24 @@ { system-only = true; } + +1006 : linking (any) +{ + add-trigger = link-item(); +} + +1007 : linking-target (any) +{ +} + +1008 : nothing-special (any) +{ +} + +1009 : cant-create (any) disabled +{ +} + +2000 : nothing-special (any) +{ +} diff --git a/src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp b/src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp index 0d26a3e4b1f941c7873f6bacc0f18db9e890acac..79b35373d41a764665dd37a26209b11000819e31 100644 --- a/src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp +++ b/src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp @@ -19,6 +19,7 @@ lyskomd_start "" "\ Max password length: 8 Max aux_items deleted per call: 1 Max aux_items added per call: 1 +Max links per text: 4 Max text length: 100 " @@ -172,23 +173,77 @@ client_start 0 kom_connect [holl "DejaGnu Test Suite"] kom_accept_async "0 { }" -# Try to send a long aux-item list +# Try to send a long number list + +kom_login 5 "gazonk" 0 send "1020 92 1 10 { 1 2 3 4 5 6 7 8 9 10 } 0 { }\n" -simple_expect "%1020 6 0" -setup_xfail "*" -fail "Exceed max num_list length" +simple_expect "%1020 46 1" -send "1021 92 1 0 { } 2 { 1 00000000 0 [holl "A"] 2 00000000 0 [holl "B"] }\n" -protocol_error +send "1021 92 1 0 { } 3 { 1 00000000 0 [holl "A"] 2 00000000 0 [holl "B"] 3 00000000 0 [holl "C"] }\n" +simple_expect "%1021 46 1" + +# Try to send a short delete list, add list and misc-info list + +send "1022 92 1 -1 { } 0 { }\n" +simple_expect "%%Insane array size." +client_death 0 +client_start 0 +talk_to client 0 +kom_connect "DejaGnu Test Lager" +kom_accept_async "0 { }" + +send "1023 92 1 0 { } -1 { }\n" +simple_expect "%%Insane array size." +client_death 0 +client_start 0 +talk_to client 0 +kom_connect "DejaGnu Test Lager" +kom_accept_async "0 { }" + +send "1024 86 [holl "TX"] -1 { } 0 { }\n" +simple_expect "%%Insane array size." +client_death 0 +client_start 0 +talk_to client 0 +kom_connect "DejaGnu Test Lager" +kom_accept_async "0 { }" + +send "1025 86 [holl "TX"] 0 { } -1 { }\n" +simple_expect "%%Insane array size." +client_death 0 +client_start 0 +talk_to client 0 +kom_connect "DejaGnu Test Lager" +kom_accept_async "0 { }" +# Bad syntax for misc-info list -# Send a misc-info list that contains an invalid item and a footn_to -# (Yes, footn_to is untested in 00-06.exp!) +send "1026 86 [holl "TX"] 1 2 0 { }\n" +protocol_error -send "1021 86 [holl "TX"] 2 { 4 10 999 999 } 0 { }\n" +send "1027 86 [holl "TX"] 1 { 0 2 0 { }\n" protocol_error +# Send a long misc-info list + +kom_login 5 "gazonk" 0 +send "1028 86 [holl "TX"] 6 { 0 1 0 2 0 3 0 4 0 9 0 10 } 0 { }\n" +simple_expect "%1028 46 4" + +send "1029 86 [holl "TX"] 4 { 5 0 7 1 2 3 4 5 6 7 8 9 8 5 9 1 2 3 4 5 6 7 8 9 } 0 { }\n" +simple_expect "%1029 25 0" + + + + +# Send a misc-info list that contains an invalid item with complex data + +kom_login 5 "gazonk" 0 + +send "1042 86 [holl "TX"] 1 { 999 999 3HABC 1 { 1 { } } } 0 { }\n" +simple_expect "%1042 26 999" + # Tests for prot_a_hunt_nl diff --git a/src/server/testsuite/lyskomd.0/text-cov.exp b/src/server/testsuite/lyskomd.0/text-cov.exp index bb6fd635356a9e0b7a663066e78e94d144b11b09..cae6b25052604a342a9ef538b84f33c4b4cc6dc6 100644 --- a/src/server/testsuite/lyskomd.0/text-cov.exp +++ b/src/server/testsuite/lyskomd.0/text-cov.exp @@ -199,6 +199,11 @@ simple_expect "=1207" send "1208 31 9 13\n" simple_expect "%1208 30 13" +# Add a recipient with a bogus type + +send "1209 30 9 13 6\n" +simple_expect "%1209 26 6" + # Call create-text when we have no access to one of the recipients @@ -527,9 +532,7 @@ simple_expect "%2603 47 0" # Attempt to crete a text with a comm-in item send "2604 86 [holl "T33 (oops)"] 2 { 0 10 3 32 } 0 { }\n" -simple_expect "%% LysKOM protocol error." -setup_xfail "*" -fail "got protocol error instead of illegal-misc" +simple_expect "%2604 25 1" # Attempt to recpt, cc, bcc a conference that does not exist diff --git a/src/server/text.c b/src/server/text.c index b18c01f3234c728d20a7adfbf20f75095278cf13..b0d93a80bef4cf3e92d82843b78ed207c77c3589 100644 --- a/src/server/text.c +++ b/src/server/text.c @@ -1,5 +1,5 @@ /* - * $Id: text.c,v 0.64 1999/05/16 21:47:36 ceder Exp $ + * $Id: text.c,v 0.65 1999/05/18 13:07:02 byers Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -34,7 +34,7 @@ #endif static const char * -rcsid = "$Id: text.c,v 0.64 1999/05/16 21:47:36 ceder Exp $"; +rcsid = "$Id: text.c,v 0.65 1999/05/18 13:07:02 byers Exp $"; #include "rcs.h" USE(rcsid); @@ -233,6 +233,7 @@ find_recipient(Conf_no conf_no, break; #ifndef COMPILE_CHECKS + case unknown_info: default: restart_kom("find_recipient(): illegal misc_item\n"); #endif @@ -515,6 +516,7 @@ is_member_in_recpt(Person *person, break; #ifndef COMPILE_CHECKS + case unknown_info: default: kom_log("%s: is_member_in_recpt(): bad misc_item.\n", __FILE__); break; @@ -593,6 +595,7 @@ do_delete_misc (u_short * no_of_misc, break; #ifndef COMPILE_CHECKS + case unknown_info: default: restart_kom("do_delete_misc() - illegal misc"); #endif @@ -730,6 +733,7 @@ do_sub_recpt (Text_no text_no, break; #ifndef COMPILE_CHECKS + case unknown_info: default: kom_log("%s: do_sub_recpt(): bad misc_item.\n", __FILE__); break; @@ -903,10 +907,11 @@ sender(Text_stat * t_stat, break; /* These may come before a sent_by. */ #ifndef COMPILE_CHECKS + case unknown_info: default: - kom_log("ERROR: sender(): Illegal misc_item found.\n"); - return 0; + restart_kom("ERROR: sender(): Illegal misc_item found.\n"); #endif + } } return 0; /* No sender. */ @@ -966,6 +971,7 @@ is_sender(Text_stat * text_s, break; #ifndef COMPILE_CHECKS + case unknown_info: default: restart_kom("is_sender(): Illegal misc_item found.\n"); #endif @@ -1016,6 +1022,7 @@ is_comm_sender(Text_stat * text_s, break; #ifndef COMPILE_CHECKS + case unknown_info: default: restart_kom("is_comm_sender(): Illegal misc_item found.\n"); #endif @@ -1134,6 +1141,7 @@ skip_recp (Misc_info ** misc, ready = TRUE; break; #ifndef COMPILE_CHECKS + case unknown_info: default: restart_kom("skip_recp() - illegal misc\n"); #endif @@ -1178,6 +1186,7 @@ recp_sent_by(Misc_info *misc, Misc_info *end, return FALSE; #ifndef COMPILE_CHECKS + case unknown_info: default: restart_kom("recp_sent_by() - illegal misc\n"); #endif @@ -1314,6 +1323,7 @@ filter_secret_info(Text_stat *result, break; #ifndef COMPILE_CHECKS + case unknown_info: default: restart_kom("filter_secret_info() - illegal misc_item!\n"); #endif @@ -1657,6 +1667,7 @@ do_delete_text(Text_no text_no, case sent_at: restart_kom("do_delete_text(): Illegal misc-item syntax.\n"); #ifndef COMPILE_CHECKS + case unknown_info: default: restart_kom("do_delete_text(): Illegal misc-item.\n"); #endif @@ -1850,6 +1861,7 @@ check_double_subm (Misc_info * misc, break; #ifndef COMPILE_CHECKS + case unknown_info: default: kom_log("%s: check_double_subm(): bad misc_item.\n", __FILE__); break; @@ -1894,6 +1906,7 @@ check_double_comm (Misc_info *misc, break; #ifndef COMPILE_CHECKS + case unknown_info: default: kom_log("%s: check_double_subm(): bad misc_item.\n", __FILE__); break; @@ -2098,6 +2111,11 @@ create_text_check_misc (u_short * no_of_misc, case loc_no: /* Ignore loc_no */ break; + case unknown_info: /* Unrecognized info type */ + err_stat = misc[i].datum.unknown_type; + kom_errno = KOM_ILLEGAL_INFO_TYPE; + return FAILURE; + case comm_in: case footn_in: case rec_time: @@ -2107,6 +2125,7 @@ create_text_check_misc (u_short * no_of_misc, #ifndef COMPILE_CHECKS default: #endif + err_stat = i; kom_errno = KOM_ILL_MISC; return FAILURE; } @@ -2236,6 +2255,7 @@ create_text_add_miscs(Text_no new_text, case sent_at: /* Fall through */ #ifndef COMPILE_CHECKS + case unknown_info: default: #endif restart_kom("create_text_add_misc() - illegal Info_type"); @@ -2414,13 +2434,13 @@ ok_to_create_next_text(void) extern Text_no create_text_old(const String message, - u_short no_of_misc, - Misc_info * misc) + Misc_info_list * misc_l) { Text_stat *t_stat; Text_no text; - text = do_create_text(message, no_of_misc, misc, NULL, FALSE, &t_stat); + text = do_create_text(message, misc_l->no_of_misc, + misc_l->misc, NULL, FALSE, &t_stat); if (text != 0) { @@ -2435,14 +2455,14 @@ create_text_old(const String message, extern Text_no create_text(const String message, - u_short no_of_misc, - Misc_info * misc, + Misc_info_list * misc_l, Aux_item_list * aux) { Text_stat *t_stat; Text_no text; - text = do_create_text(message, no_of_misc, misc, aux, FALSE, &t_stat); + text = do_create_text(message, misc_l->no_of_misc, + misc_l->misc, aux, FALSE, &t_stat); if (text != 0) { @@ -2465,14 +2485,14 @@ create_text(const String message, extern Text_no create_anonymous_text(const String message, - u_short no_of_misc, - Misc_info * misc, + Misc_info_list* misc_l, Aux_item_list * aux) { Text_no text; Text_stat * t_stat; - text = do_create_text(message, no_of_misc, misc, aux, TRUE, &t_stat); + text = do_create_text(message, misc_l->no_of_misc, + misc_l->misc, aux, TRUE, &t_stat); if (text != 0) { @@ -2485,13 +2505,13 @@ create_anonymous_text(const String message, extern Text_no create_anonymous_text_old(const String message, - u_short no_of_misc, - Misc_info * misc ) + Misc_info_list * misc_l ) { Text_no text; Text_stat * t_stat; - text = do_create_text(message, no_of_misc, misc, NULL, TRUE, &t_stat); + text = do_create_text(message, misc_l->no_of_misc, + misc_l->misc, NULL, TRUE, &t_stat); if (text != 0) { @@ -2520,6 +2540,13 @@ do_create_text(const String message, CHK_LOGIN(0); + if (no_of_misc > param.max_crea_misc) + { + err_stat = param.max_crea_misc; + kom_errno = KOM_LONG_ARRAY; + return 0; + } + /* Check the length of the text. */ if ( s_strlen (message) > param.text_len ) @@ -2930,6 +2957,7 @@ add_recipient( Text_no text_no, case rec_time: case sent_by: case sent_at: + case unknown_info: /* Fall through */ #ifndef COMPILE_CHECKS default: @@ -3352,6 +3380,21 @@ modify_text_info(Text_no text, Text_stat *text_s; CHK_LOGIN(FAILURE); + + if (items_to_delete->length > param.max_delete_aux) + { + kom_errno = KOM_LONG_ARRAY; + err_stat = param.max_delete_aux; + return FAILURE; + } + + if (aux->length > param.max_add_aux) + { + kom_errno = KOM_LONG_ARRAY; + err_stat = param.max_add_aux; + return FAILURE; + } + GET_T_STAT(text_s, text, FAILURE); /* Check if we may delete and add the items */