Author: jonathan
Date: 2006-03-01 08:12:14 -0500 (Wed, 01 Mar 2006)
New Revision: 315
Modified:
trunk/daemon/Changelog
trunk/examples/simple_user.c
trunk/examples/user.c
trunk/include/sp.h
trunk/include/sp_func.h
trunk/libspread/fl.c
trunk/libspread/sp.c
Log:
Include nice membership body parsing functions for applications to use. These
replace the old method of walking through the byte array in the membership body
to extract the vs_sets and gid. Deprecate the old functions SP_get_offset*
as they are extremely confusing to use. New functions SP_get_memb_info(),
SP_get_vs_sets_info() and SP_get_vs_set_members() return strutures with the
fields filled in.
Update flush library to use new api and update example programs.
Modified: trunk/daemon/Changelog
===================================================================
--- trunk/daemon/Changelog 2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/daemon/Changelog 2006-03-01 13:12:14 UTC (rev 315)
@@ -1,3 +1,14 @@
+Wed Mar 1 08:05:32 2006 Jonathan Stanton <[email protected]>
+
+ * libspread/sp.c, fl.c, include/sp.h, sp_func.h (SP_get_vs* memb_info()):
+ Add new membership parsing functions SP_get_memb_info(),
+ SP_get_vs_sets_info() and SP_get_vs_set_members() to analyze
+ the contents of the mesage body of membership messages.
+ Deprecate old functions that just gave byte locations within
+ body as they are too confusing.
+ * examples/user.c, simple_user.c: Update example programs
+ to use new membership parsing functions.
+
Wed Feb 8 03:44:23 2006 Jonathan Stanton <[email protected]>
* arch.h: Add HAVE_STRERROR for Windows builds. This avoids
Modified: trunk/examples/simple_user.c
===================================================================
--- trunk/examples/simple_user.c 2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/examples/simple_user.c 2006-03-01 13:12:14 UTC (rev 315)
@@ -102,9 +102,8 @@
static char mess[102400];
char sender[MAX_GROUP_NAME];
char target_groups[100][MAX_GROUP_NAME];
- group_id *grp_id;
int num_groups;
- int num_bytes;
+ membership_info memb_info;
int service_type;
int16 mess_type;
int endian_mismatch;
@@ -136,11 +135,14 @@
}else if( Is_membership_mess( service_type ) ){
/* A membership notification */
+ ret = SP_get_memb_info( mess, service_type, &memb_info );
+ if (ret < 0) {
+ printf("BUG: membership message does not have valid body\n");
+ SP_error( ret );
+ exit( 1 );
+ }
if ( Is_reg_memb_mess( service_type ) )
{
- num_bytes = 0;
- grp_id = (group_id *)&mess[num_bytes];
- num_bytes += sizeof( group_id );
printf("received REGULAR membership ");
if( Is_caused_join_mess( service_type ) ) printf("caused by JOIN ");
if( Is_caused_leave_mess( service_type ) ) printf("caused by LEAVE ");
@@ -149,7 +151,7 @@
sender, num_groups );
for( i=0; i < num_groups; i++ )
printf("\t%s\n", &target_groups[i][0] );
- printf("grp id is %d %d %d\n",grp_id->id[0], grp_id->id[1], grp_id->id[2] );
+ printf("grp id is %d %d %d\n",memb_info.gid.id[0], memb_info.gid.id[1], memb_info.gid.id[2] );
}else if( Is_transition_mess( service_type ) ) {
printf("received TRANSITIONAL membership for group %s\n", sender );
}else if( Is_caused_leave_mess( service_type ) ){
Modified: trunk/examples/user.c
===================================================================
--- trunk/examples/user.c 2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/examples/user.c 2006-03-01 13:12:14 UTC (rev 315)
@@ -80,6 +80,8 @@
static int To_exit = 0;
#define MAX_MESSLEN 102400
+#define MAX_VSSETS 10
+#define MAX_MEMBERS 100
#ifdef _REENTRANT
@@ -383,15 +385,13 @@
static char mess[MAX_MESSLEN];
char sender[MAX_GROUP_NAME];
- char target_groups[100][MAX_GROUP_NAME];
- group_id *grp_id_ptr;
- int32u *num_vs_sets_ptr;
- int32u local_vs_set_offset;
- char *vs_set_size_ptr;
- int32u vs_set_size;
- char *vs_set_members;
+ char target_groups[MAX_MEMBERS][MAX_GROUP_NAME];
+ membership_info memb_info;
+ vs_set_info vssets[MAX_VSSETS];
+ unsigned int my_vsset_index;
+ int num_vs_sets;
+ char members[MAX_MEMBERS][MAX_GROUP_NAME];
int num_groups;
- int num_bytes;
int service_type;
int16 mess_type;
int endian_mismatch;
@@ -408,7 +408,7 @@
if ( (ret == GROUPS_TOO_SHORT) || (ret == BUFFER_TOO_SHORT) ) {
service_type = DROP_RECV;
printf("\n========Buffers or Groups too Short=======\n");
- ret = SP_receive( Mbox, &service_type, sender, 100, &num_groups, target_groups,
+ ret = SP_receive( Mbox, &service_type, sender, MAX_MEMBERS, &num_groups, target_groups,
&mess_type, &endian_mismatch, sizeof(mess), mess );
}
}
@@ -435,47 +435,48 @@
sender, mess_type, endian_mismatch, num_groups, ret, mess );
}else if( Is_membership_mess( service_type ) )
{
+ ret = SP_get_memb_info( mess, service_type, &memb_info );
+ if (ret < 0) {
+ printf("BUG: membership message does not have valid body\n");
+ SP_error( ret );
+ exit( 1 );
+ }
if ( Is_reg_memb_mess( service_type ) )
{
- num_bytes = SP_get_gid_offset_memb_mess();
- grp_id_ptr = (group_id *)&mess[num_bytes];
- num_bytes = SP_get_num_vs_sets_offset_memb_mess();
- num_vs_sets_ptr = (int32u *)&mess[num_bytes];
- local_vs_set_offset = SP_get_local_vs_set_offset_memb_mess(mess);
- num_bytes = SP_get_first_vs_set_offset_memb_mess();
- num_bytes += SP_get_vs_set_size_offset_vs_set();
- vs_set_size_ptr = &mess[num_bytes];
- num_bytes += SP_get_vs_set_members_offset_vs_set();
- vs_set_members = &mess[num_bytes];
-
printf("Received REGULAR membership for group %s with %d members, where I am member %d:\n",
sender, num_groups, mess_type );
for( i=0; i < num_groups; i++ )
printf("\t%s\n", &target_groups[i][0] );
- printf("grp id is %d %d %d\n",grp_id_ptr->id[0], grp_id_ptr->id[1], grp_id_ptr->id[2] );
+ printf("grp id is %d %d %d\n",memb_info.gid.id[0], memb_info.gid.id[1], memb_info.gid.id[2] );
if( Is_caused_join_mess( service_type ) )
{
- printf("Due to the JOIN of %s\n", vs_set_members );
+ printf("Due to the JOIN of %s\n", memb_info.changed_member );
}else if( Is_caused_leave_mess( service_type ) ){
- printf("Due to the LEAVE of %s\n", vs_set_members);
+ printf("Due to the LEAVE of %s\n", memb_info.changed_member );
}else if( Is_caused_disconnect_mess( service_type ) ){
- printf("Due to the DISCONNECT of %s\n", vs_set_members );
+ printf("Due to the DISCONNECT of %s\n", memb_info.changed_member );
}else if( Is_caused_network_mess( service_type ) ){
- printf("Due to NETWORK change with %u VS sets\n", *num_vs_sets_ptr);
- for( i = 0; i < *num_vs_sets_ptr; ++i )
+ printf("Due to NETWORK change with %u VS sets\n", memb_info.num_vs_sets);
+ num_vs_sets = SP_get_vs_sets_info( mess, &vssets[0], MAX_VSSETS, &my_vsset_index );
+ if (num_vs_sets < 0) {
+ printf("BUG: membership message has more then %d vs sets. Recompile with larger MAX_VSSETS\n", MAX_VSSETS);
+ SP_error( num_vs_sets );
+ exit( 1 );
+ }
+ for( i = 0; i < num_vs_sets; i++ )
{
- if( 0 != i )
- {
- vs_set_size_ptr = vs_set_members;
- vs_set_members += sizeof(int32u);
+ printf("%s VS set %d has %u members:\n",
+ (i == my_vsset_index) ?
+ ("LOCAL") : ("OTHER"), i, vssets[i].num_members );
+ ret = SP_get_vs_set_members(mess, &vssets[i], members, MAX_MEMBERS);
+ if (ret < 0) {
+ printf("VS Set has more then %d members. Recompile with larger MAX_MEMBERS\n", MAX_MEMBERS);
+ SP_error( ret );
+ exit( 1 );
}
- memcpy( &vs_set_size, vs_set_size_ptr, sizeof(int32u) );
- printf("%s VS set %d has %d members:\n",
- (vs_set_size_ptr - mess == local_vs_set_offset) ?
- ("LOCAL") : ("OTHER"), i, vs_set_size );
- for( j = 0; j < vs_set_size; j++, vs_set_members += MAX_GROUP_NAME )
- printf("\t%s\n", vs_set_members );
+ for( j = 0; j < vssets[i].num_members; j++ )
+ printf("\t%s\n", members[j] );
}
}
}else if( Is_transition_mess( service_type ) ) {
Modified: trunk/include/sp.h
===================================================================
--- trunk/include/sp.h 2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/include/sp.h 2006-03-01 13:12:14 UTC (rev 315)
@@ -148,7 +148,18 @@
int32 id[3];
} group_id;
+typedef struct dummy_vs_set_info {
+ unsigned int num_members;
+ unsigned int members_offset; /* offset from beginning of msg body*/
+} vs_set_info;
+typedef struct dummy_membership_info {
+ group_id gid;
+ char changed_member[MAX_GROUP_NAME]; /* filled in on CAUSED_BY_JOIN, CAUSED_BY_LEAVE or CAUSED_BY_DISCONNECT only */
+ unsigned int num_vs_sets;
+ vs_set_info my_vs_set;
+} membership_info;
+
#include "sp_events.h"
#include "sp_func.h"
#ifdef __cplusplus
Modified: trunk/include/sp_func.h
===================================================================
--- trunk/include/sp_func.h 2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/include/sp_func.h 2006-03-01 13:12:14 UTC (rev 315)
@@ -93,21 +93,31 @@
int16 *mess_type, int *endian_mismatch,
scatter *scat_mess );
-/* FIXME: We could make something much friendlier here. */
-/* returns offset in memb. message of gid (group id), num_vs_sets,
- * offset to local vs_set, and first vs_set */
-int SP_get_gid_offset_memb_mess(void);
-int SP_get_num_vs_sets_offset_memb_mess(void);
-int SP_get_first_vs_set_offset_memb_mess(void);
-/* returns offset into the buffer for a vs_set of the number of
- * members in the vs_set. */
-int SP_get_vs_set_size_offset_vs_set(void);
-int SP_get_vs_set_members_offset_vs_set(void);
-/* returns value from regular membership message */
-int SP_get_offset_to_local_vs_set_offset(void);
-int SP_get_local_vs_set_offset_memb_mess( char *reg_memb_mess );
-int SP_get_local_vs_set_offset_memb_scat( const scatter *reg_memb_scat );
+/* get membership info from a message */
+int SP_get_memb_info( const char *memb_mess,
+ const service service_type,
+ membership_info *memb_info);
+int SP_get_vs_sets_info( const char *memb_mess,
+ vs_set_info *vs_sets,
+ int num_vs_sets,
+ unsigned int *my_vs_set_index);
+int SP_get_vs_set_members( const char *memb_mess,
+ const vs_set_info *vs_set,
+ char member_names[][MAX_GROUP_NAME],
+ int member_names_len);
+int SP_scat_get_memb_info( const scatter *memb_mess_scat,
+ const service service_type,
+ membership_info *memb_info);
+int SP_scat_get_vs_sets_info( const scatter *memb_mess_scat,
+ vs_set_info *vs_sets,
+ int num_vs_sets,
+ unsigned int *my_vs_set_index);
+int SP_scat_get_vs_set_members( const scatter *memb_mess_scat,
+ const vs_set_info *vs_set,
+ char member_names[][MAX_GROUP_NAME],
+ int member_names_len);
+
int SP_poll( mailbox mbox );
int SP_equal_group_ids( group_id g1, group_id g2 );
Modified: trunk/libspread/fl.c
===================================================================
--- trunk/libspread/fl.c 2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/libspread/fl.c 2006-03-01 13:12:14 UTC (rev 315)
@@ -1432,13 +1432,12 @@
}
}
} else if (Is_reg_memb_mess(*m->serv_type)) {
+ membership_info m_info;
/* if its a regular membership message read the group id out of the msg */
assert(m->ret >= sizeof(group_id) + sizeof(int) + MAX_GROUP_NAME); /* ensure received */
- err = scatp_begin(&pos, scat);
- assert(err == 0);
- err = scatp_jforward(&pos, SP_get_gid_offset_memb_mess());
- assert(err == SP_get_gid_offset_memb_mess());
- err = scatp_cpy1((char*) &m->dst_gid, &pos, sizeof(group_id)); /* copy out new gid */
+ err = SP_scat_get_memb_info( scat, *m->serv_type, &m_info);
+
+ memcpy(&m->dst_gid, &m_info.gid, sizeof(group_id) );
assert(err == sizeof(group_id)); /* already endian corrected */
DEBUG(std_stkfprintf(stderr, 0, "Recvd a SP reg memb mess: New SP gid is %d %d %d\n",
m->dst_gid.id[0], m->dst_gid.id[1], m->dst_gid.id[2]));
@@ -1978,38 +1977,22 @@
static char*
determine_leavers(stdhash *leavers, view *last_sp_view, gc_recv_mess *m) {
- char delta[MAX_GROUP_NAME], *delta_ptr = delta, *ret = 0;
+ char *ret = 0;
int i;
- scatter *scat;
- scatp pos;
long err;
- stduint32 offset;
stduint32 num_membs;
+ membership_info m_info;
+ char (*members)[MAX_GROUP_NAME];
DEBUG(std_stkfprintf(stderr, 1, "determine_leavers: old gid %d %d %d -> new gid %d %d %d\n",
last_sp_view->gid.id[0], last_sp_view->gid.id[1],
last_sp_view->gid.id[2], m->dst_gid.id[0], m->dst_gid.id[1],
m->dst_gid.id[2]));
- get_scat_info(m, &i, &scat); /* i is a dummy variable here */
+ err = SP_scat_get_memb_info( m->scat_mess, *m->serv_type, &m_info);
+ assert(err == 1);
+ num_membs = m_info.my_vs_set.num_members;
- err = scatp_set(&pos, scat, SP_get_offset_to_local_vs_set_offset(), SEEK_SET);
- assert(err == 0);
-
- err = scatp_cpy1((char*) &offset, &pos, sizeof(stduint32));
- assert(err == sizeof(stduint32));
-
- offset += SP_get_first_vs_set_offset_memb_mess(); /* get local VS offset */
-
- err = scatp_set(&pos, scat, offset, SEEK_SET);
- assert(err == offset);
-
- err = scatp_cpy1((char*) &num_membs, &pos, sizeof(stduint32)); /* read out num membs */
- assert(err == sizeof(stduint32));
-
- err = scatp_jforward(&pos, sizeof(stduint32)); /* advance to vs_set */
- assert(err == sizeof(stduint32));
-
if (!Is_caused_network_mess(*m->serv_type)) { /* join, leave, or disconnection */
assert(num_membs == 1);
@@ -2018,13 +2001,11 @@
stdhash_construct(leavers, sizeof(char*), 0,
group_name_ptr_cmp, group_name_ptr_hashcode, 0);
- err = scatp_cpy1(delta, &pos, MAX_GROUP_NAME); /* read out joiner/leaver/disconnector */
- assert(err == MAX_GROUP_NAME);
- delta[MAX_GROUP_NAME - 1] = 0; /* ensure null termination */
if ((ret = (char*) malloc(MAX_GROUP_NAME)) == 0)
stderr_abort("(%s, %d): malloc(%d)\n", __FILE__, __LINE__, MAX_GROUP_NAME);
- strncpy(ret, delta, MAX_GROUP_NAME); /* strndup delta member for return */
+ memcpy( ret, m_info.changed_member, MAX_GROUP_NAME); /* read out joiner/leaver/disconnector */
+ ret[MAX_GROUP_NAME - 1] = 0; /* ensure null termination */
DEBUG(std_stkfprintf(stderr, 0, "delta memb: '%s'\n", delta));
if (!Is_caused_join_mess(*m->serv_type)) { /* insert leaver into leavers */
@@ -2037,13 +2018,14 @@
stdhash_copy_construct(leavers, &last_sp_view->orig_membs); /* copy last SP membership */
DEBUG(std_stkfprintf(stderr, 0, "Num_membs %u\n", num_membs));
+ if ((members = (char (*)[MAX_GROUP_NAME])malloc(num_membs * sizeof( *members ) ) ) == 0)
+ stderr_abort("(%s, %d): malloc(%d)\n", __FILE__, __LINE__, num_membs * MAX_GROUP_NAME);
+ err = SP_scat_get_vs_set_members( m->scat_mess, &m_info.my_vs_set, members, num_membs);
+ assert(err == num_membs);
for (i = 0; i < num_membs; ++i) { /* remove members that came with me: leaves who left */
- err = scatp_adv_cpy1(&delta_ptr, &pos, MAX_GROUP_NAME, 0, 1);
- assert(err == MAX_GROUP_NAME);
-
- delta[MAX_GROUP_NAME - 1] = 0; /* ensure null termination */
+ members[i][MAX_GROUP_NAME -1] = 0;
err = stdhash_size(leavers);
- stdhash_erase_key(leavers, &delta_ptr);
+ stdhash_erase_key(leavers, &(members[i][0]));
assert(err == stdhash_size(leavers) + 1);
}
}
Modified: trunk/libspread/sp.c
===================================================================
--- trunk/libspread/sp.c 2006-02-21 05:26:22 UTC (rev 314)
+++ trunk/libspread/sp.c 2006-03-01 13:12:14 UTC (rev 315)
@@ -67,9 +67,23 @@
#include "sess_types.h"
#include "scatter.h"
#include "alarm.h"
-#include "sp_func.h"
#include "acm.h"
+/* SP functions need these types, but internal headers do not */
+typedef struct dummy_vs_set_info {
+ unsigned int num_members;
+ unsigned int members_offset; /* offset from beginning of msg body*/
+} vs_set_info;
+
+typedef struct dummy_membership_info {
+ group_id gid;
+ char changed_member[MAX_GROUP_NAME]; /* filled in on CAUSED_BY_JOIN, CAUSED_BY_LEAVE or CAUSED_BY_DISCONNECT only */
+ unsigned int num_vs_sets;
+ vs_set_info my_vs_set;
+} membership_info;
+
+#include "sp_func.h"
+
enum sp_sess_state {
SESS_UNUSED,
SESS_ACTIVE,
@@ -1764,6 +1778,9 @@
else return( 0 );
}
+/* get membership info from a message */
+
+/* internal only for now -- maybe static? */
int SP_get_gid_offset_memb_mess(void)
{
return 0;
@@ -1794,6 +1811,199 @@
return sizeof(int32u);
}
+/* public functions */
+int SP_get_memb_info( const char *memb_mess,
+ const service service_type,
+ membership_info *memb_info)
+{
+ int32u my_vs_offset;
+
+ if ( !Is_membership_mess( service_type ) )
+ return(ILLEGAL_MESSAGE);
+
+ memcpy( &memb_info->gid, &memb_mess[SP_get_gid_offset_memb_mess()], sizeof(group_id));
+
+ if ( Is_reg_memb_mess( service_type ) )
+ {
+ if( Is_caused_join_mess( service_type ) ||
+ Is_caused_leave_mess( service_type ) ||
+ Is_caused_disconnect_mess( service_type ) )
+ {
+ memcpy(memb_info->changed_member, &memb_mess[SP_get_first_vs_set_offset_memb_mess()+SP_get_vs_set_members_offset_vs_set()], MAX_GROUP_NAME);
+ } else if( Is_caused_network_mess( service_type ) )
+ {
+ memset(memb_info->changed_member, 0, MAX_GROUP_NAME);
+ }
+ memb_info->num_vs_sets = *((int32u *)&memb_mess[SP_get_num_vs_sets_offset_memb_mess()]);
+ my_vs_offset = *((int32u *)&memb_mess[SP_get_offset_to_local_vs_set_offset()]);
+ my_vs_offset += SP_get_first_vs_set_offset_memb_mess();
+ memb_info->my_vs_set.num_members = *((int32u *)&memb_mess[my_vs_offset + SP_get_vs_set_size_offset_vs_set()]);
+ memb_info->my_vs_set.members_offset = my_vs_offset + SP_get_vs_set_members_offset_vs_set();
+ } else {
+ /* Is transitional */
+ memb_info->num_vs_sets = 0;
+ memb_info->my_vs_set.num_members = 0;
+ memb_info->my_vs_set.members_offset = 0;
+ }
+ return( 1 );
+}
+
+
+int SP_get_vs_sets_info( const char *memb_mess,
+ vs_set_info *vs_sets,
+ int num_vs_sets,
+ unsigned int *my_vs_set_index)
+{
+ unsigned int actual_num_vs_sets;
+ unsigned int memb_offset, local_vs_set_offset;
+ int i;
+
+ actual_num_vs_sets = *((int32u *)&memb_mess[SP_get_num_vs_sets_offset_memb_mess()]);
+
+ if (num_vs_sets < actual_num_vs_sets)
+ return(BUFFER_TOO_SHORT);
+
+ local_vs_set_offset = *((int32u *)&memb_mess[SP_get_offset_to_local_vs_set_offset()]);
+ local_vs_set_offset += SP_get_first_vs_set_offset_memb_mess();
+ memb_offset = SP_get_first_vs_set_offset_memb_mess();
+
+ for ( i=0; i < num_vs_sets; i++, vs_sets++ )
+ {
+ if (memb_offset == local_vs_set_offset)
+ *my_vs_set_index = i;
+ vs_sets->num_members = *(int32u *)&memb_mess[memb_offset];
+ memb_offset += SP_get_vs_set_members_offset_vs_set();
+ vs_sets->members_offset = memb_offset;
+ memb_offset += (vs_sets->num_members * MAX_GROUP_NAME) ;
+ }
+ return ( actual_num_vs_sets );
+}
+
+int SP_get_vs_set_members( const char *memb_mess,
+ const vs_set_info *vs_set,
+ char member_names[][MAX_GROUP_NAME],
+ int member_names_len)
+{
+ int i;
+ const char *members_ptr;
+
+ if (member_names_len < vs_set->num_members)
+ return(BUFFER_TOO_SHORT);
+
+ members_ptr = &memb_mess[vs_set->members_offset];
+ for ( i=0; i < vs_set->num_members; i++, members_ptr += MAX_GROUP_NAME )
+ {
+ memcpy(&member_names[i][0], members_ptr, MAX_GROUP_NAME);
+ }
+ return( vs_set->num_members );
+}
+
+static void scat_read(void *dest_ptr, const scatter *msg, int start_byte, int copy_size)
+{
+ int scat, scat_index, bytes_index, bytes_to_copy;
+
+ scat = 0;
+ scat_index = 0;
+ while(start_byte > msg->elements[scat].len)
+ {
+ scat++;
+ start_byte -= msg->elements[scat].len;
+ }
+ scat_index = start_byte;
+ for( bytes_index = 0; bytes_index < copy_size ; bytes_index += bytes_to_copy )
+ {
+ bytes_to_copy = copy_size - bytes_index;
+ if( bytes_to_copy > msg->elements[scat].len - scat_index )
+ bytes_to_copy = msg->elements[scat].len - scat_index;
+ memcpy( dest_ptr, &(msg->elements[scat].buf[scat_index]), bytes_to_copy );
+ if( bytes_to_copy == msg->elements[scat].len - scat_index )
+ {
+ scat_index = 0;
+ ++scat;
+ } else {
+ scat_index = bytes_to_copy;
+ }
+ }
+}
+
+int SP_scat_get_memb_info( const scatter *memb_mess_scat,
+ const service service_type,
+ membership_info *memb_info)
+{
+ int32u my_vs_offset;
+
+ if ( !Is_membership_mess( service_type ) )
+ return(ILLEGAL_MESSAGE);
+
+ scat_read( &memb_info->gid, memb_mess_scat, 0, sizeof( group_id ));
+
+ if ( Is_reg_memb_mess( service_type ) )
+ {
+ if( Is_caused_join_mess( service_type ) ||
+ Is_caused_leave_mess( service_type ) ||
+ Is_caused_disconnect_mess( service_type ) )
+ {
+ scat_read(memb_info->changed_member, memb_mess_scat, SP_get_first_vs_set_offset_memb_mess()+SP_get_vs_set_members_offset_vs_set(), MAX_GROUP_NAME );
+ } else if( Is_caused_network_mess( service_type ) )
+ {
+ memset(memb_info->changed_member, 0, MAX_GROUP_NAME);
+ }
+ scat_read( &(memb_info->num_vs_sets), memb_mess_scat, SP_get_num_vs_sets_offset_memb_mess(), sizeof( int32u ) );
+ scat_read( &my_vs_offset, memb_mess_scat, SP_get_offset_to_local_vs_set_offset(), sizeof( int32u ));
+ my_vs_offset += SP_get_first_vs_set_offset_memb_mess();
+ scat_read( &(memb_info->my_vs_set.num_members), memb_mess_scat, my_vs_offset + SP_get_vs_set_size_offset_vs_set(), sizeof( int32u ) );
+ memb_info->my_vs_set.members_offset = my_vs_offset + SP_get_vs_set_members_offset_vs_set();
+ } else {
+ /* Is transitional */
+ memb_info->num_vs_sets = 0;
+ memb_info->my_vs_set.num_members = 0;
+ memb_info->my_vs_set.members_offset = 0;
+ }
+ return( 1 );
+}
+int SP_scat_get_vs_sets_info( const scatter *memb_mess_scat,
+ vs_set_info *vs_sets,
+ int num_vs_sets,
+ unsigned int *my_vs_set_index)
+{
+ unsigned int actual_num_vs_sets;
+ unsigned int memb_offset, local_vs_set_offset;
+ int i;
+
+ scat_read( &actual_num_vs_sets, memb_mess_scat, SP_get_num_vs_sets_offset_memb_mess(), sizeof( int32u ) );
+
+ if (num_vs_sets < actual_num_vs_sets)
+ return(BUFFER_TOO_SHORT);
+
+ scat_read( &local_vs_set_offset, memb_mess_scat, SP_get_offset_to_local_vs_set_offset(), sizeof( int32u ) );
+ local_vs_set_offset += SP_get_first_vs_set_offset_memb_mess();
+ memb_offset = SP_get_first_vs_set_offset_memb_mess();
+
+ for ( i=0; i < num_vs_sets; i++, vs_sets++ )
+ {
+ if (memb_offset == local_vs_set_offset)
+ *my_vs_set_index = i;
+
+ scat_read(&(vs_sets->num_members), memb_mess_scat, memb_offset, sizeof( int32u ) );
+ memb_offset += SP_get_vs_set_members_offset_vs_set();
+ vs_sets->members_offset = memb_offset;
+ memb_offset += (vs_sets->num_members * MAX_GROUP_NAME) ;
+ }
+ return ( actual_num_vs_sets );
+}
+int SP_scat_get_vs_set_members( const scatter *memb_mess_scat,
+ const vs_set_info *vs_set,
+ char member_names[][MAX_GROUP_NAME],
+ int member_names_len)
+{
+ if (member_names_len < vs_set->num_members)
+ return(BUFFER_TOO_SHORT);
+
+ scat_read( member_names, memb_mess_scat, vs_set->members_offset, vs_set->num_members * MAX_GROUP_NAME);
+ return( vs_set->num_members );
+}
+
+
int SP_get_local_vs_set_offset_memb_mess( char *reg_memb_mess )
{
int32u offset;
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.