Commit 8bda3c68 authored by David Byers's avatar David Byers
Browse files

Tests for membership and async messages. Related bug fixes.

parent b4b514af
1998-12-29 David Byers <davby@ida.liu.se>
* src/server/testsuite/config/unix.exp (lyskomd_start): Added
optional third argument for stuff to put at the end of the config
file.
* src/server/prot-a-send-async.c (prot_a_async_new_membership):
Send the correct header.
* src/server/membership.c (add_member_common): Added calls to
send_async_new_membership.
(send_async_new_membership): Send message to the right recipients.
1998-12-28 David Byers <davby@ida.liu.se>
* src/server/membership.c (add_member_old): Don't set invitation
bit here. It is dealt with in add_member_common.
(do_change_priority): Don't change priority to zero if we are
being called from old functions. Just fake the passive bit.
(locate_membership_and_position): Return the correct position of
the membership.
1998-12-27 David Byers <davby@ida.liu.se>
* doc/Protocol-A.texi (Error Codes): Added
invalid-membership-type.
1998-12-26 David Byers <davby@ida.liu.se> 1998-12-26 David Byers <davby@ida.liu.se>
* doc/man/lyskomd.8 (value): Documented regexps use collate * doc/man/lyskomd.8 (value): Documented regexps use collate
......
...@@ -6,7 +6,10 @@ Before the next release ...@@ -6,7 +6,10 @@ Before the next release
These are show-stoppers that prevent a new release. These are show-stoppers that prevent a new release.
* Missinc test cases in 03.exp * Should the conference supervisor be able to set the secret bit of a
membership type? Probably yes.
* Missing test cases in 03.exp
* 89=create-person should probably not do an automatic login. (Wasn't * 89=create-person should probably not do an automatic login. (Wasn't
this discussed in KOM?) this discussed in KOM?)
......
\input texinfo @c -*-texinfo-*- \input texinfo @c -*-texinfo-*-
@c $Id: Protocol-A.texi,v 1.44 1998/12/26 22:40:12 byers Exp $ @c $Id: Protocol-A.texi,v 1.45 1998/12/29 10:55:32 byers Exp $
@c %**start of header @c %**start of header
@setfilename protocol-a.info @setfilename protocol-a.info
@settitle LysKOM Protocol A @settitle LysKOM Protocol A
...@@ -186,6 +186,8 @@ Lars Aronsson documented the protocol that was in use at the time. ...@@ -186,6 +186,8 @@ Lars Aronsson documented the protocol that was in use at the time.
@item 99=get-membership @item 99=get-membership
@item 100=add-member @item 100=add-member
@item 101=get-members @item 101=get-members
@item 102=local-to-global
@item 103=map-created-texts
@end itemize @end itemize
@item Removed Server Calls @item Removed Server Calls
...@@ -221,8 +223,22 @@ Lars Aronsson documented the protocol that was in use at the time. ...@@ -221,8 +223,22 @@ Lars Aronsson documented the protocol that was in use at the time.
@item async-deleted-text message @item async-deleted-text message
@item New async-new-text message @item New async-new-text message
@end itemize @end itemize
@item Notes
@itemize @bullet
@item Since protocol version 9 setting a priority of zero in a
conference was supposed to indicate passive membership in a conference.
It was largely up to the client to implement this. True passive
memberships have been introduced in this protocol version through the
Membership-type extension to Membership type. In order to maintain
compatibility with clients that interpret priority 0 as passive
membership, the old calls @pxref{add-member-old} and
@pxref{get-membership-old} perform magic, translating between priorities
and membership types. The magic is documented with each call.
@end itemize
@end table @end table
@subsection Protocol version 9.0 @subsection Protocol version 9.0
@table @asis @table @asis
...@@ -1151,14 +1167,29 @@ Create persons ...@@ -1151,14 +1167,29 @@ Create persons
@section Membership and Reading @section Membership and Reading
Persons' memberships in conferences are represented in the protocol as Persons' memberships in conferences are represented in the protocol as
arrays of @code{Membership}-typed values. This structure contains a arrays of @code{Membership}-typed values. This structure contains
record of what the person has read in that conference. information about how and when the membership was created and which
texts have been read in the conference.
The first part of the record is the @code{last-text-read} field. It
contains the highest local text number such that the person has read There are two kinds of memberships. An active membership indicates that
every text with an equal or lower local number. The second part of the the person is actively participating in the conference, wants to know if
record is the @code{read-texts} array, which contains the local text there are unread texts and wants to receive messages send to the
numbers higher than @code{last-text-read} that are also read. conference. A passive membership is similar to no membership at all. The
person is still a member but will not receive messages sent to the
conference and will not be notified when there are new texts. From the
user's perspective, passive membership should be like no membership at
all, but the server still remembers what the user has read in the
conference while he or she was an active member. Since protocol version
10 a bit in the membership type field of the membership structure
indicates the type of membership. Previously the server did not support
passive memberships, but there was a convention that clients should
treat the priority level zero as a passive membership.
The membership record indicates which texts have been read through the
@code{last-text-read} and @code{read-texts} fields. All texts with local
numbers up to @code{last-text-read} have been read. In addition, all
texts with local numbers contained in the @code{read-texts} array have
been read.
Finding out which articles a person has read in a particular conference Finding out which articles a person has read in a particular conference
requires a few calls. Normally, a client will retrieve a batch of requires a few calls. Normally, a client will retrieve a batch of
...@@ -1166,15 +1197,17 @@ perhaps 50 articles at a time. The outline of the process is as follows: ...@@ -1166,15 +1197,17 @@ perhaps 50 articles at a time. The outline of the process is as follows:
@enumerate @enumerate
@item Fetch the membership to get the @code{last-text-read} @item Fetch the membership to get the @code{last-text-read}
@item Translate 50 local numbers starting as @code{last-text-read} to global @item Use @pxref{local-to-global} to translate a number of local numbers
numbers. to global numbers.
@item Remove the local numbers that are in @code{read-texts} from the result @item Remove the global numbers corresponding to local numbers contained
in @code{read-texts} from the result
@item Get and translate more texts as needed. @item Get and translate more texts as needed.
@end enumerate @end enumerate
The process is complicated because of the translation between local and The process is complicated because of the translation between local and
global text numbers. In the future there will hopefully be a single call global text numbers. If the server does not implement the
that does this work in the server. @code{@pxref{local-to-global}} call, it is possible to use the less
efficient but perfectly serviceable @code{@pxref{get-map}} call instead.
@node Client-Server Dialog, ,Membership and Reading , Introduction @node Client-Server Dialog, ,Membership and Reading , Introduction
...@@ -2176,8 +2209,8 @@ The time when the person last read anything from the conference. ...@@ -2176,8 +2209,8 @@ The time when the person last read anything from the conference.
The conference this membership data pertains to. The conference this membership data pertains to.
@item priority @item priority
The priority the person has assigned to the conference. The higher the The priority the person has assigned to the conference. The higher the
number, the higher the priority. In the future, priority zero will be number, the higher the priority. In the past, priority zero indicated a
used to indicate a passive membership. passive membership. This usage is now obsolete.
@item last-text-read @item last-text-read
The local number of last text read in the conference. The local number of last text read in the conference.
@item read-texts @item read-texts
...@@ -3374,6 +3407,9 @@ This call can be used to change the priority and position of a ...@@ -3374,6 +3407,9 @@ This call can be used to change the priority and position of a
conference in the person's membership list if the person is already a conference in the person's membership list if the person is already a
member of the conference. member of the conference.
In protocol version 10, setting the priority to zero sets the passive
bit in the membership. The actual priority is not changed.
@example @example
1 46 119 0 10 0 1 46 119 0 10 0
@t{=1 1 @{ 49 14 17 13 8 91 5 255 1 119 255 0 0 * @}} @t{=1 1 @{ 49 14 17 13 8 91 5 255 1 119 255 0 0 * @}}
...@@ -4977,6 +5013,11 @@ The server will return a membership list that is shorter than ...@@ -4977,6 +5013,11 @@ The server will return a membership list that is shorter than
@code{no-of-confs} if @code{no-of-confs} + @code{first} is larger than @code{no-of-confs} if @code{no-of-confs} + @code{first} is larger than
the number of conferences the person is a member of. the number of conferences the person is a member of.
Servers that support protocol version 10 will return a priority of zero
if the passive bit in the membership record has been set (either by a
set-membership-type or by setting the priority of the conference to
zero.)
@example @example
1 46 5 0 3 1 1 46 5 0 3 1
@t{=1 2 @{ 49 14 17 13 8 91 5 255 1 5 255 0 0 * } @t{=1 2 @{ 49 14 17 13 8 91 5 255 1 5 255 0 0 * }
...@@ -7167,7 +7208,22 @@ the server's restrictions will result in an error. ...@@ -7167,7 +7208,22 @@ the server's restrictions will result in an error.
@item login-first @item login-first
Login required before issuing this call. Login required before issuing this call.
@c FIXME: more codes here @item conference-zero
@code{conf} is zero.
@item undefined-conference
The conference @code{conf} does not exist or is secret or the person
@code{pers} does not exist or is secret.
@item permission-denied
Insufficient permissions to change the membership of @code{pers}.
@item not-member
Person @code{pers} is not a member of conference @code{conf}.
@item invalid-membership-type
The requested membership type @code{type} was not compatible with
restrictions set on the server or on the conference @code{conf}
@end table @end table
...@@ -7812,6 +7868,11 @@ Attempt to send an asynchronous message failed for some reason. Perhaps ...@@ -7812,6 +7868,11 @@ Attempt to send an asynchronous message failed for some reason. Perhaps
the recipient is not accepting messages at the moment. the recipient is not accepting messages at the moment.
@code{error-status} is undefined. @code{error-status} is undefined.
@item invalid-membership-type (54)
A requested membership type was not compatible with restrictions set on
the server or on a specific conference. @code{error-status} is
undefined.
@end table @end table
......
/* /*
* $Id: manipulate.h,v 0.17 1998/12/26 22:40:42 byers Exp $ * $Id: manipulate.h,v 0.18 1998/12/29 10:55:36 byers Exp $
* Copyright (C) 1991, 1992, 1993, 1994, 1996 Lysator Academic Computer Association. * Copyright (C) 1991, 1992, 1993, 1994, 1996 Lysator Academic Computer Association.
* *
* This file is part of the LysKOM server. * This file is part of the LysKOM server.
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
* Please mail bug reports to bug-lyskom@lysator.liu.se. * Please mail bug reports to bug-lyskom@lysator.liu.se.
*/ */
/* /*
* $Id: manipulate.h,v 0.17 1998/12/26 22:40:42 byers Exp $ * $Id: manipulate.h,v 0.18 1998/12/29 10:55:36 byers Exp $
* *
* manipulate.h * manipulate.h
* *
...@@ -387,8 +387,6 @@ extern Bool ...@@ -387,8 +387,6 @@ extern Bool
unique_name( const String name, Conf_no conf_no ); unique_name( const String name, Conf_no conf_no );
/* /*
* Delete a member from a conference. * Delete a member from a conference.
* No checks are made on the parameters. * No checks are made on the parameters.
......
/* /*
* $Id: membership.c,v 0.38 1998/12/26 22:40:43 byers Exp $ * $Id: membership.c,v 0.39 1998/12/29 10:55:37 byers Exp $
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association.
* *
* This file is part of the LysKOM server. * This file is part of the LysKOM server.
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#define DEBUG_MARK_AS_READ #define DEBUG_MARK_AS_READ
static const char * static const char *
rcsid = "$Id: membership.c,v 0.38 1998/12/26 22:40:43 byers Exp $"; rcsid = "$Id: membership.c,v 0.39 1998/12/29 10:55:37 byers Exp $";
#include "rcs.h" #include "rcs.h"
USE(rcsid); USE(rcsid);
...@@ -172,9 +172,14 @@ do_change_priority (Membership * mship, ...@@ -172,9 +172,14 @@ do_change_priority (Membership * mship,
Member *mem; Member *mem;
if (priority == 0 && fake_passive) if (priority == 0 && fake_passive)
{
type->passive = 1; type->passive = 1;
}
else
{
mship->priority = priority; mship->priority = priority;
}
mship->type = *type; mship->type = *type;
/* Check range of where */ /* Check range of where */
...@@ -492,6 +497,29 @@ insert_loc_no(Local_text_no text, ...@@ -492,6 +497,29 @@ insert_loc_no(Local_text_no text,
return OK; return OK;
} }
/*
* Send a new-membership message to the affected person
*/
static void
send_async_new_membership(Pers_no pers_no,
Conf_no conf_no)
{
Connection *cptr = NULL;
Session_no i = 0;
while ((i = traverse_connections(i)) != 0)
{
cptr = get_conn_by_number(i);
if (cptr->pers_no == pers_no)
{
async_new_membership(cptr, pers_no, conf_no);
}
}
}
/* /*
* End of static functions * End of static functions
*/ */
...@@ -814,7 +842,7 @@ locate_membership_and_position(Conf_no conf_no, ...@@ -814,7 +842,7 @@ locate_membership_and_position(Conf_no conf_no,
{ {
if (position != NULL) if (position != NULL)
{ {
*position = i; *position = pers_p->conferences.no_of_confs - i;
} }
return confp; return confp;
} }
...@@ -878,23 +906,6 @@ sub_member( Conf_no conf_no, ...@@ -878,23 +906,6 @@ sub_member( Conf_no conf_no,
} }
static void send_async_new_membership(Pers_no pers_no,
Conf_no conf_no)
{
Connection *cptr = NULL;
Session_no i = 0;
while ((i = traverse_connections(i)) != 0)
{
cptr = get_conn_by_number(i);
if (is_supervisor(pers_no, NULL, ACTPERS, ACT_P))
{
async_new_membership(cptr, pers_no, conf_no);
}
}
}
/* /*
* Add a member to a conference (join a conference) or * Add a member to a conference (join a conference) or
* Change the priority of a conference. * Change the priority of a conference.
...@@ -967,19 +978,26 @@ add_member_common(Conf_no conf_no, ...@@ -967,19 +978,26 @@ add_member_common(Conf_no conf_no,
conf_supervisor = is_supervisor(conf_no, conf_c, ACTPERS, ACT_P); conf_supervisor = is_supervisor(conf_no, conf_c, ACTPERS, ACT_P);
/* Already a member, but a secret member? */ /* Already a member, but a secret member? */
if (!pers_supervisor && !conf_supervisor && if (mship->type.secret &&
!ENA(admin,2) && !ENA(wheel,8)) !pers_supervisor &&
!conf_supervisor &&
!ENA(admin,2) &&
!ENA(wheel,8))
{ {
/* FIXME: This leaks secret information */ /* FIXME: This leaks secret information */
/* The person is already a member, but we are not allowed /* The person is already a member, but we are not allowed
to know this. Pretend that the addition worked, and hope to know this. Pretend that the addition worked, and hope
that the user does not double-check */ that the user does not double-check */
log ("\nTHIS IS STRANGE\n");
return OK; return OK;
} }
/* He is already a member. Only change the priority. */ /* He is already a member. Only change the priority. */
if( !pers_supervisor && !ENA(admin,2) && !ENA(wheel, 8) ) if( !pers_supervisor &&
!ENA(admin,2) &&
!ENA(wheel, 8) )
{ {
/* Noone else can change one's priorities. */ /* Noone else can change one's priorities. */
err_stat = pers_no; err_stat = pers_no;
...@@ -991,22 +1009,23 @@ add_member_common(Conf_no conf_no, ...@@ -991,22 +1009,23 @@ add_member_common(Conf_no conf_no,
priority, where, pers_no, pers_p, priority, where, pers_no, pers_p,
type, fake_passive ); type, fake_passive );
send_async_new_membership(pers_no, conf_no);
} }
else else
{ {
if (pers_no != ACTPERS) if (pers_no != ACTPERS)
{
log("Person %lu added to conference %lu by %lu.\n", log("Person %lu added to conference %lu by %lu.\n",
(unsigned long)pers_no, (unsigned long)pers_no,
(unsigned long)conf_no, (unsigned long)conf_no,
(unsigned long)ACTPERS); (unsigned long)ACTPERS);
}
do_add_member(conf_no, conf_c, pers_no, pers_p, do_add_member(conf_no, conf_c, pers_no, pers_p,
priority, where, type, fake_passive); priority, where, type, fake_passive);
send_async_new_membership(pers_no, conf_no);
} }
send_async_new_membership(pers_no, conf_no);
return OK; return OK;
} }
...@@ -1019,9 +1038,7 @@ add_member_old(Conf_no conf_no, ...@@ -1019,9 +1038,7 @@ add_member_old(Conf_no conf_no,
{ {
Membership_type type; Membership_type type;
set_membership_type_bits(&type, param.invite_by_default,0,0,0,0,0,0,0); set_membership_type_bits(&type, 0,0,0,0,0,0,0,0);
if (pers_no == ACTPERS)
type.invitation = 0;
return add_member_common(conf_no, pers_no, priority, where, &type, TRUE); return add_member_common(conf_no, pers_no, priority, where, &type, TRUE);
} }
...@@ -1608,7 +1625,9 @@ extern Success set_membership_type(Pers_no pers_no, ...@@ -1608,7 +1625,9 @@ extern Success set_membership_type(Pers_no pers_no,
acc = access_perm(conf_no, conf_c, ACTPERS, ACT_P); acc = access_perm(conf_no, conf_c, ACTPERS, ACT_P);
if (acc == error) if (acc == error)
{
return FAILURE; return FAILURE;
}
if (acc == none) if (acc == none)
{ {
......
/* /*
* $Id: prot-a-send-async.c,v 0.20 1998/12/26 22:40:53 byers Exp $ * $Id: prot-a-send-async.c,v 0.21 1998/12/29 10:55:38 byers Exp $
* Copyright (C) 1991, 1993, 1994, 1995, 1996 Lysator Academic Computer Association. * Copyright (C) 1991, 1993, 1994, 1995, 1996 Lysator Academic Computer Association.
* *
* This file is part of the LysKOM server. * This file is part of the LysKOM server.
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#endif #endif
static const char * static const char *
rcsid = "$Id: prot-a-send-async.c,v 0.20 1998/12/26 22:40:53 byers Exp $"; rcsid = "$Id: prot-a-send-async.c,v 0.21 1998/12/29 10:55:38 byers Exp $";
#include "rcs.h" #include "rcs.h"
USE(rcsid); USE(rcsid);
...@@ -239,7 +239,7 @@ prot_a_async_new_membership(Connection *cptr, ...@@ -239,7 +239,7 @@ prot_a_async_new_membership(Connection *cptr,
Conf_no conf_no) Conf_no conf_no)
{ {
ASYNC_CHECK_ACCEPT(cptr, ay_new_membership); ASYNC_CHECK_ACCEPT(cptr, ay_new_membership);
async_header(cptr, 3, ay_new_membership); async_header(cptr, 2, ay_new_membership);
mux_printf(cptr, " %lu %lu", mux_printf(cptr, " %lu %lu",
(unsigned long)pers_no, (unsigned long)pers_no,
(unsigned long)conf_no); (unsigned long)conf_no);
......
...@@ -99,3 +99,21 @@ proc kom_set_supervisor { conf admin {result ""} {testname ""} } { ...@@ -99,3 +99,21 @@ proc kom_set_supervisor { conf admin {result ""} {testname ""} } {
set result [cres $result "=$ref_no"] set result [cres $result "=$ref_no"]
simple_expect $result $testname simple_expect $result $testname
} }
proc kom_add_member { conf pers prio where type {result ""} {testname ""}} {
global ref_no
kom_next_call
send "$ref_no 100 $conf $pers $prio $where $type\n"
set result [cres $result "=$ref_no"]
simple_expect $result $testname
}
proc kom_ping_server { } {
global ref_no
global any_time
kom_next_call
send "$ref_no 35\n"
simple_expect "=$ref_no $any_time"
}
...@@ -20,6 +20,8 @@ set maxint 2147483647 ...@@ -20,6 +20,8 @@ set maxint 2147483647
set clientport 53262 set clientport 53262
set muxport 53263 set muxport 53263
set aux_item_default_conf_file "../../../run-support/aux-items.conf"
# Fix the tty settings for minimum impact on the data flow. # Fix the tty settings for minimum impact on the data flow.
set stty_init "-echo -onlcr -ocrnl -istrip" set stty_init "-echo -onlcr -ocrnl -istrip"
...@@ -167,7 +169,8 @@ proc unanchored_expect {regex testname} { ...@@ -167,7 +169,8 @@ proc unanchored_expect {regex testname} {
unset test unset test
} }
proc lyskomd_start {{aux_item_conf_file "../../../run-support/aux-items.conf"}} { proc lyskomd_start {{aux_item_conf_file "" }
{extra_config ""}} {
global spawn_id global spawn_id
global server_id global server_id
global test global test
...@@ -179,6 +182,11 @@ proc lyskomd_start {{aux_item_conf_file "../../../run-support/aux-items.conf"}} ...@@ -179,6 +182,11 @@ proc lyskomd_start {{aux_item_conf_file "../../../run-support/aux-items.conf"}}
global srcdir global srcdir
global clientport global clientport
global muxport global muxport
global aux_item_default_conf_file
if { $aux_item_conf_file == "" } {
set aux_item_conf_file $aux_item_default_conf_file
}
# Check that we are in in the correct directory before removing # Check that we are in in the correct directory before removing
# directories... # directories...
...@@ -198,6 +206,7 @@ proc lyskomd_start {{aux_item_conf_file "../../../run-support/aux-items.conf"}} ...@@ -198,6 +206,7 @@ proc lyskomd_start {{aux_item_conf_file "../../../run-support/aux-items.conf"}}
puts $cf "Mux port: $muxport" puts $cf "Mux port: $muxport"
puts $cf "Prefix: $wd" puts $cf "Prefix: $wd"
puts $cf "Aux-item definition file: $wd/$aux_item_conf_file"