static void Read_message() { static char mess[MAX_MESSLEN]; char sender[MAX_GROUP_NAME]; 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 service_type; int16 mess_type; int endian_mismatch; int i,j; int ret; service_type = 0; ret = SP_receive( Mbox, &service_type, sender, 100, &num_groups, target_groups, &mess_type, &endian_mismatch, sizeof(mess), mess ); printf("\n============================\n"); if( ret < 0 ) { 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, MAX_MEMBERS, &num_groups, target_groups, &mess_type, &endian_mismatch, sizeof(mess), mess ); } } if (ret < 0 ) { if( ! To_exit ) { SP_error( ret ); printf("\n============================\n"); printf("\nBye.\n"); } exit( 0 ); } if( Is_regular_mess( service_type ) ) { mess[ret] = 0; if ( Is_unreliable_mess( service_type ) ) printf("received UNRELIABLE "); else if( Is_reliable_mess( service_type ) ) printf("received RELIABLE "); else if( Is_fifo_mess( service_type ) ) printf("received FIFO "); else if( Is_causal_mess( service_type ) ) printf("received CAUSAL "); else if( Is_agreed_mess( service_type ) ) printf("received AGREED "); else if( Is_safe_mess( service_type ) ) printf("received SAFE "); printf("message from %s, of type %d, (endian %d) to %d groups \n(%d bytes): %s\n", 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 ) ) { 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",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", memb_info.changed_member ); }else if( Is_caused_leave_mess( service_type ) ){ 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", memb_info.changed_member ); }else if( Is_caused_network_mess( service_type ) ){ 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++ ) { 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 ); } for( j = 0; j < vssets[i].num_members; j++ ) printf("\t%s\n", members[j] ); } } }else if( Is_transition_mess( service_type ) ) { printf("received TRANSITIONAL membership for group %s\n", sender ); }else if( Is_caused_leave_mess( service_type ) ){ printf("received membership message that left group %s\n", sender ); }else printf("received incorrecty membership message of type 0x%x\n", service_type ); } else if ( Is_reject_mess( service_type ) ) { printf("REJECTED message from %s, of servicetype 0x%x messtype %d, (endian %d) to %d groups \n(%d bytes): %s\n", sender, service_type, mess_type, endian_mismatch, num_groups, ret, mess ); }else printf("received message of unknown message type 0x%x with ret %d\n", service_type, ret); printf("\n"); printf("User> "); fflush(stdout); }
int main(int argc, char **argv) { double t; exe = *argv; usage(argc, argv); FL_lib_init(); if ((err = FL_connect(daemon_name, user_name, 0, &mbox, priv_name)) != ACCEPT_SESSION) { fprintf(stderr, "FL_connect failure: "); FL_error(err); exit(1); } if (user_type == DELTA) { double *fl_join_times = (double*) malloc(sizeof(double) * num_joins_leaves); double *fl_leave_times = (double*) malloc(sizeof(double) * num_joins_leaves); double *fl_cmbo_times = (double*) malloc(sizeof(double) * num_joins_leaves); if (!fl_join_times || !fl_leave_times || !fl_cmbo_times) { exit(fprintf(stderr, "Couldn't mallocate tracking arrays!\r\n")); } for (i = 0; i < num_joins_leaves; ++i) { t = get_time_timeofday(); if ((err = FL_join(mbox, group_name)) < 0) { fprintf(stderr, "FL_join failure: "); FL_error(err); exit(1); } do { if ((mess_len = FL_receive(mbox, &service_type, sender, MY_MAX_NUM_GROUPS, &num_groups, groups, &mess_type, &endian_mismatch, MY_MAX_MESS_SIZE, mess, &more_messes)) < 0) { fprintf(stderr, "FL_receive failure: "); FL_error(mess_len); exit(1); } } while (!Is_reg_memb_mess(service_type)); fl_join_times[i] = get_time_timeofday() - t; if (should_sleep) { /* sleep for 4 times how long the join membership took */ /* allows membership to stabilize */ usleep((unsigned long) (4 * fl_join_times[i] * 1000)); } /* send a kill message if we are done */ if (i == num_joins_leaves - 1) { if ((mess_len = FL_multicast(mbox, SAFE_MESS, group_name, DIE_MESS, 0, 0)) < 0) { fprintf(stderr, "FL_multicast failure: "); FL_error(err); exit(1); } } t = get_time_timeofday(); if ((err = FL_leave(mbox, group_name)) < 0) { fprintf(stderr, "FL_leave failure: "); FL_error(err); exit(1); } do { if ((mess_len = FL_receive(mbox, &service_type, sender, MY_MAX_NUM_GROUPS, &num_groups, groups, &mess_type, &endian_mismatch, MY_MAX_MESS_SIZE, mess, &more_messes)) < 0) { fprintf(stderr, "FL_receive failure: "); FL_error(mess_len); exit(1); } } while (!Is_self_leave(service_type)); fl_leave_times[i] = get_time_timeofday() - t; fl_cmbo_times[i] = fl_join_times[i] + fl_leave_times[i]; if (should_sleep) { /* sleep for 4 times how long the join membership took */ /* allows membership to stabilize */ usleep((unsigned long) (4 * fl_join_times[i] * 1000)); } } /* compute timing statistics */ comp_stats(&fl_join_stats, fl_join_times, num_joins_leaves); comp_stats(&fl_leave_stats, fl_leave_times, num_joins_leaves); comp_stats(&fl_cmbo_stats, fl_cmbo_times, num_joins_leaves); /* output timing statistics */ if (pretty_print) { printf("Flush Membership Timings (includes Spread): Group Size: %d, # Joins/Leaves: %d\r\n\r\n", num_members, num_joins_leaves); printf("\tFlush Join: ind. total (90%%): %.6fms, ind. total: %.6fms\r\n", sp_join_stats.total90, sp_join_stats.total); printf("\tFlush Leave: ind. total (90%%): %.6fms, ind. total: %.6fms\r\n", sp_leave_stats.total90, sp_leave_stats.total); printf("\tFlush Join/Leave: ind. total (90%%): %.6fms, ind. total: %.6fms\r\n", sp_cmbo_stats.total90, sp_cmbo_stats.total); printf("\r\n\t\tGroup Size\t# Trials\tQ1\tMEDIAN\tQ3" "\tMIN (5%%)\tMEAN90\tSTDDEV90\tMAX (95%%)" "\tMIN\tMEAN\tSTDDEV\tMAX\r\n"); } printf("\tFL_Join:\t%d\t%d\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\r\n", num_members, num_joins_leaves, fl_join_stats.quart1, fl_join_stats.median, fl_join_stats.quart3, fl_join_stats.min5, fl_join_stats.mean90, fl_join_stats.stddev90, fl_join_stats.max95, fl_join_stats.min, fl_join_stats.mean, fl_join_stats.stddev, fl_join_stats.max); printf("\tFL_Leave:\t%d\t%d\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\r\n", num_members, num_joins_leaves, fl_leave_stats.quart1, fl_leave_stats.median, fl_leave_stats.quart3, fl_leave_stats.min5, fl_leave_stats.mean90, fl_leave_stats.stddev90, fl_leave_stats.max95, fl_leave_stats.min, fl_leave_stats.mean, fl_leave_stats.stddev, fl_leave_stats.max); printf("\tFL_Join + FL_Leave\t%d\t%d\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\r\n", num_members, num_joins_leaves, fl_cmbo_stats.quart1, fl_cmbo_stats.median, fl_cmbo_stats.quart3, fl_cmbo_stats.min5, fl_cmbo_stats.mean90, fl_cmbo_stats.stddev90, fl_cmbo_stats.max95, fl_cmbo_stats.min, fl_cmbo_stats.mean, fl_cmbo_stats.stddev, fl_cmbo_stats.max); } else if (user_type == LOAD_MEMBER) { if ((err = FL_join(mbox, group_name)) < 0) { fprintf(stderr, "FL_join failure: "); FL_error(err); exit(1); } while (1) { if ((mess_len = FL_receive(mbox, &service_type, sender, MY_MAX_NUM_GROUPS, &num_groups, groups, &mess_type, &endian_mismatch, MY_MAX_MESS_SIZE, mess, &more_messes)) < 0) { fprintf(stderr, "FL_receive failure: "); FL_error(mess_len); exit(1); } if (Is_flush_req_mess(service_type)) { if ((err = FL_flush(mbox, group_name)) < 0) { fprintf(stderr, "FL_flush failure: "); FL_error(err); exit(1); } } else if (Is_reg_memb_mess(service_type)) { if (Is_caused_leave_mess(service_type)) { if (about_to_die) { break; } } else if (!Is_caused_join_mess(service_type)) { exit(fprintf(stderr, "Unexpected membership type: %d\n", service_type)); } } else if (Is_safe_mess(service_type) && mess_type == DIE_MESS) { about_to_die = 1; } } printf("Success!\r\n"); } else { fprintf(stderr, "Unknown user type: %d\n", user_type); exit(printUsage(stderr)); } if ((err = FL_disconnect(mbox)) < 0) { fprintf(stderr, "FL_disconnect failure: "); FL_error(err); exit(1); } return 0; }
static PyObject * new_membership_msg(int type, PyObject *group, int num_members, char (*members)[MAX_GROUP_NAME], char *buffer, int size) { MembershipMsg *self; group_id grp_id; membership_info memb_info; int32 num_extra_members = 0; int i; int ret; assert(group != NULL); self = PyObject_New(MembershipMsg, &MembershipMsg_Type); if (self == NULL) return NULL; self->reason = type & CAUSED_BY_MASK; /* from sp.h defines */ self->msg_subtype = type & (TRANSITION_MESS | REG_MEMB_MESS); Py_INCREF(group); self->group = group; self->members = NULL; self->extra = NULL; self->group_id = NULL; self->changed_member = NULL; self->members = PyTuple_New(num_members); if (self->members == NULL) { Py_DECREF(self); return NULL; } for (i = 0; i < num_members; ++i) { PyObject *s = PyString_FromString(members[i]); if (!s) { Py_DECREF(self); return NULL; } PyTuple_SET_ITEM(self->members, i, s); } if ((ret = SP_get_memb_info(buffer, type, &memb_info)) < 0) { PyErr_Format(SpreadError, "error %d on SP_get_memb_info", ret); Py_DECREF(self); return NULL; } memcpy(&grp_id, &memb_info.gid, sizeof(group_id)); self->group_id = new_group_id(grp_id); if (self->group_id == NULL) { Py_DECREF(self); return NULL; } /* The extra attribute is a tuple initialized for 0 or more items. * If the member event is a single member event such as a join, leave or disconnect, * the changed member attribute is set from memb_info.changed_member * and a single value from vs_set, which is stored inside the message, is added to extra tuple. * If the member event is a merge or partition, the list of member names * from vs_set is stored in extra. */ if (Is_reg_memb_mess(type) && (Is_caused_join_mess(type) || Is_caused_disconnect_mess(type) || Is_caused_leave_mess(type))) { self->changed_member = PyString_FromString(memb_info.changed_member); if (!self->changed_member) { Py_DECREF(self); return NULL; } } else { self->changed_member = Py_BuildValue(""); } num_extra_members = memb_info.my_vs_set.num_members; self->extra = PyTuple_New(num_extra_members); if (self->extra == NULL) { Py_DECREF(self); return NULL; } if (num_extra_members > 0) { char (*member_names)[MAX_GROUP_NAME] = (char (*)[MAX_GROUP_NAME]) malloc(num_extra_members * MAX_GROUP_NAME); if (member_names == NULL) { Py_DECREF(self); PyErr_NoMemory(); return NULL; } if ((ret = SP_get_vs_set_members(buffer, &memb_info.my_vs_set, member_names, num_extra_members)) < 0) { PyErr_Format(SpreadError, "error %d on SP_get_vs_set_members", ret); Py_DECREF(self); free(member_names); return NULL; } for (i = 0; i < num_extra_members; i++) { PyObject *s; s = PyString_FromString(member_names[i]); if (!s) { Py_DECREF(self); free(member_names); return NULL; } PyTuple_SET_ITEM(self->extra, i, s); } free(member_names); } return (PyObject *)self; }
int main( int argc, char *argv[] ) { int ret; int service_type, num_groups; char sender[MAX_GROUP_NAME]; int16 mess_type; int dummy_endian_mismatch; int joined_members; int sender_index; int i,j; Usage( argc, argv ); if (Num_members == 0) { /* connecting to the relevant Spread daemon, no need for group info */ printf("flooder: connecting to %s\n", Spread_name ); ret = SP_connect( Spread_name, User, 0, 0, &Mbox, Private_group ) ; } else { /* connecting to the relevant Spread daemon, DO need group info */ printf("flooder: connecting to %s with group membership\n", Spread_name ); ret = SP_connect( Spread_name, User, 0, 1, &Mbox, Private_group ) ; } if(ret < 0) { SP_error( ret ); exit(1) ; } /* * Joining the process group. * * Note that this is not necessary in order to multicast the * messages, but only to demonstrate end-to-end behaviour. */ if( Read_only ) { printf("flooder: Only receiving messages\n"); SP_join( Mbox, "flooder" ); }else if( Write_only ) { printf("flooder: starting multicast of %d messages, %d bytes each (self discarding).\n", Num_messages, Num_bytes); }else{ SP_join( Mbox, "flooder" ); printf("flooder: starting multicast of %d messages, %d bytes each.\n", Num_messages, Num_bytes); } /* Wait for all members to join */ joined_members = 0; while( joined_members < Num_members) { service_type = 0; ret = SP_receive( Mbox, &service_type, sender, FLOODER_MAX_GROUPS, &num_groups, ret_groups, &mess_type, &dummy_endian_mismatch, sizeof(recv_mess), recv_mess ); if( ret < 0 ) { if ( (ret == GROUPS_TOO_SHORT) || (ret == BUFFER_TOO_SHORT) ) { printf("\n========Buffers or Groups too Short=======\n"); printf("Should NOT happen in wait for members! Program quitting\n"); exit(1); } } if( Is_regular_mess( service_type ) ) { mess[ret] = 0; if ( Is_unreliable_mess( service_type ) ) printf("received UNRELIABLE "); else if( Is_reliable_mess( service_type ) ) printf("received RELIABLE "); else if( Is_fifo_mess( service_type ) ) printf("received FIFO "); else if( Is_causal_mess( service_type ) ) printf("received CAUSAL "); else if( Is_agreed_mess( service_type ) ) printf("received AGREED "); else if( Is_safe_mess( service_type ) ) printf("received SAFE "); printf("message during wait for members, from %s, of type %d, (endian %d) to %d groups \n(%d bytes): %s\n", sender, mess_type, dummy_endian_mismatch, num_groups, ret, recv_mess ); }else if( Is_membership_mess( service_type ) ) { if ( Is_reg_memb_mess( service_type ) ) { 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", &ret_groups[i][0] ); /* update count of joined members */ joined_members = num_groups; }else if( Is_transition_mess( service_type ) ) { printf("received TRANSITIONAL membership for group %s\n", sender ); }else if( Is_caused_leave_mess( service_type ) ){ printf("received membership message that left group %s\n", sender ); }else printf("received incorrecty membership message of type 0x%x\n", service_type ); } else if ( Is_reject_mess( service_type ) ) { printf("REJECTED message from %s, of servicetype 0x%x messtype %d, (endian %d) to %d groups \n(%d bytes): %s\n", sender, service_type, mess_type, dummy_endian_mismatch, num_groups, ret, recv_mess ); }else printf("received message of unknown message type 0x%x with ret %d\n", service_type, ret); } /* joined_members < Num_members */ /* Update My_Counter_index field based on location of my name in last membership message */ if (Num_members) { My_Counter_index = mess_type; memcpy(&mess[0], &My_Counter_index, sizeof(int)); } for( i=1; i <= Num_messages; i++ ) { /* multicast a message unless Read_only */ if( !Read_only ) { if (Num_members) { ret = SP_multicast( Mbox, FIFO_MESS, "flooder", 0, Num_bytes, mess ); Send_Counter++; } else { ret = SP_multicast( Mbox, RELIABLE_MESS, "flooder", 0, Num_bytes, mess ); } if( ret != Num_bytes ) { if( ret < 0 ) { SP_error( ret ); exit(1); } printf("sent a different message %d -> %d\n", Num_bytes, ret ); } } /* receive a message (Read_only) or one of my messages */ if( Read_only || ( i > 200 && !Write_only ) ) { int notdone; do{ service_type = 0; ret = SP_receive( Mbox, &service_type, sender, FLOODER_MAX_GROUPS, &num_groups, ret_groups, &mess_type, &dummy_endian_mismatch, sizeof(recv_mess), recv_mess ); if( ret < 0 ) { 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, FLOODER_MAX_GROUPS, &num_groups, ret_groups, &mess_type, &dummy_endian_mismatch, sizeof(recv_mess), recv_mess ); } } if( ret < 0 ) { SP_error( ret ); exit(1); } if (Num_members) { /* update counters of received messages */ memcpy(&sender_index, &recv_mess[0], sizeof(int)); Recv_Counters[sender_index]++; /* printf("DEBUG: updated counter %d to value %d\n", sender_index, Recv_Counters[sender_index]); */ if (Recv_Counters[sender_index] == (Lowest_Recv_Counter + 1)) { /* Update Lowest_Recv_Counter */ Lowest_Recv_Counter = INT_MAX; for (j=0; j < Num_members; j++) { if (Recv_Counters[j] == 0) continue; if (Recv_Counters[j] < Lowest_Recv_Counter) Lowest_Recv_Counter = Recv_Counters[j]; } if (Lowest_Recv_Counter == INT_MAX) Lowest_Recv_Counter = 0; } /* Read loop is done if we send messages and we have received all * other senders messages upto 100 less then our current send count */ notdone = ( Lowest_Recv_Counter < (Send_Counter - 200) && !Read_only ); } else { notdone = (strcmp( sender, Private_group ) != 0 && !Read_only); } } while( notdone ); } /* report some progress... */ if( i%1000 == 0 ) printf("flooder: completed %6d messages of %d bytes\n",i, ret); } printf("flooder: completed multicast of %d messages, %d bytes each.\n", Num_messages, Num_bytes); return 0; }
static void Read_message() { static char mess[SPREAD_MESS_LEN]; char sender[MAX_GROUP_NAME]; 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 service_type; int16 mess_type; int endian_mismatch; int i,j; int ret; service_type = 0; ret = SP_receive( Mbox, &service_type, sender, 100, &num_groups, target_groups, &mess_type, &endian_mismatch, sizeof(mess), mess ); if( ret < 0 ) { 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, MAX_MEMBERS, &num_groups, target_groups, &mess_type, &endian_mismatch, sizeof(mess), mess ); } } if (ret < 0 ) { if( ! To_exit ) { SP_error( ret ); printf("\n============================\n"); printf("\nBye.\n"); } exit( 0 ); } if( Is_regular_mess( service_type ) ) { //printf("message from %s, of type %d, (endian %d) to %d groups \n(%d bytes): %s\n", sender, mess_type, endian_mismatch, num_groups, ret, mess ); typecheck* type = (typecheck*)mess; if (type->type == TYPE_JOIN_CHATROOM) { join_chatroom* dat = (join_chatroom*)mess; ret = add_user(dat->u_id,dat->sp_id,dat->chatroom); } else if (type->type == TYPE_LEAVE_CHATROOM) { leave_chatroom* dat = (leave_chatroom*)mess; rm_user(dat->sp_id); } else if (type->type == TYPE_SEND_MSG) { message* dat = (message*)mess; if (strlen(chatroom) == 0) add_room(chatroom); lamport* ts = malloc(sizeof(lamport)); ts->server_id = dat->timestamp.server_id; ts->index = dat->timestamp.index; printf("[%d,%d]\n",ts->server_id,ts->index); add_message(ts, dat->u_id, dat->chatroom, dat->mess); } else if (type->type == TYPE_LIKE_MSG) { like* dat = (like*)mess; lamport* lts = malloc(sizeof(lamport)); lamport* mts = malloc(sizeof(lamport)); lts->server_id = dat->timestamp.server_id; lts->index = dat->timestamp.index; mts->server_id = dat->timestamp.server_id; mts->index = dat->timestamp.index; ret = add_like(dat->like_state, lts, dat->u_id, chatroom, mts); printf("~~~~~~~~ %d:[%d,%d | %d,%d] %d %s %s \n",ret, lts->server_id,lts->index,mts->server_id,mts->index,dat->like_state,dat->u_id,chatroom); } master_print(); }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 ) ) { 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",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", memb_info.changed_member ); }else if( Is_caused_leave_mess( service_type ) ){ 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", memb_info.changed_member ); }else if( Is_caused_network_mess( service_type ) ){ 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++ ) { 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 ); } for( j = 0; j < vssets[i].num_members; j++ ) printf("\t%s\n", members[j] ); } } }else if( Is_transition_mess( service_type ) ) { printf("received TRANSITIONAL membership for group %s\n", sender ); }else if( Is_caused_leave_mess( service_type ) ){ printf("received membership message that left group %s\n", sender ); }else printf("received incorrecty membership message of type 0x%x\n", service_type ); } else if ( Is_reject_mess( service_type ) ) { printf("REJECTED message from %s, of servicetype 0x%x messtype %d, (endian %d) to %d groups \n(%d bytes): %s\n", sender, service_type, mess_type, endian_mismatch, num_groups, ret, mess ); }else printf("received message of unknown message type 0x%x with ret %d\n", service_type, ret); printf("\n"); fflush(stdout); }
int main(int argc, const char *argv[]) { char from[MAX_GROUP_NAME]; char message[MAX_MESSLEN]; membership_info memb_info; int num_groups; char target_groups[100][MAX_GROUP_NAME]; int16 mess_type; int endian_mismatch; int service_type; int loop = 1; int rc; int ret; int i; sqlite3 *mydb; char *dbName; char *zErrMsg; connectionStatus status = UNKNOWN; char buffer[MAX_GROUP_NAME]; char sqlBuffer[1024]; char *member; char *host; char *tok; char ch; extern char *optarg; char scratch[255]; global.connected=0; global.Group=(char *)NULL; global.configFileName=(char *)NULL; global.locked = 0; global.rawClient =1; global.debug = 0; #ifdef FICL global.appDir=(char *)NULL; #endif char *group=(char *)NULL; setSymbol("BUILD",__DATE__,LOCK,LOCAL); setSymbol("CLIENT","raw",UNLOCK,GLOBAL); setSymbol("SPREAD_SERVER","4803",UNLOCK,GLOBAL); setSymbol("GROUP","global",UNLOCK,GLOBAL); setSymbol("USER","dbCache",LOCK,GLOBAL); setSymbol("DEBUG","false",UNLOCK,GLOBAL); setSymbol("MODE","local",UNLOCK,GLOBAL); setSymbol("START_FILE","./dbCache.rc",UNLOCK,GLOBAL); while((ch = getopt(argc, ( char **)argv,"dhc:")) != -1) { switch(ch) { case 'c': setSymbol("START_FILE", optarg,LOCK,GLOBAL); break; case 'd': global.debug=1; break; case 'h': usage(); exit(0); break; } } loadFile(getSymbol("START_FILE")); if( global.debug ) { setBoolean("DEBUG",1); } global.debug = getBoolean("DEBUG"); if(global.debug) { dumpGlobals(); dumpSymbols(); } dbName = getSymbol("DATABASE"); connectToSpread(); while(loop) { status = UNKNOWN; ret = SP_receive(global.Mbox, &service_type, from, 100, &num_groups, target_groups, &mess_type, &endian_mismatch, sizeof(message), message); if (Is_membership_mess (service_type)) { ret = SP_get_memb_info(message, service_type, &memb_info); if (Is_caused_join_mess(service_type)) { status=JOINED; } if (Is_caused_leave_mess (service_type)) { status = LEFT; } if (Is_caused_disconnect_mess (service_type)) { status = DISCONNECTED; } if (Is_caused_network_mess (service_type)) { status = NETWORK; } rc = sqlite3_open(dbName, &mydb); for (i = 0; i < num_groups; i++) { if( global.debug) { printf("\t%s\n",(char *) &target_groups[i][0]); } strcpy(buffer, &target_groups[i][1]); member=strtok(buffer,"#"); host=strtok(NULL,"#"); if( global.debug) { printf("\t\tMember:%s\n", member); printf("\t\tHost :%s\n", host); } statusToText( status, scratch ); if (JOINED == status ) { sprintf( sqlBuffer,"insert or replace into status ( member, host, grp, state ) values ( '%s','%s','%s','%s');", member, host,from,scratch); } if( global.debug) { printf ("%s\n",sqlBuffer); } rc = sqlite3_exec(mydb, sqlBuffer, 0, 0, &zErrMsg); } strcpy(buffer, &memb_info.changed_member[1]); member=strtok(buffer,"#"); host=strtok(NULL,"#"); statusToText( status, scratch ); sprintf( sqlBuffer, "update status set state='%s' where member = '%s' and host ='%s';",scratch, member,host); if( global.debug) { printf("CHANGE: %s %s\n",member,host); printf("CHANGE: %s\n", scratch); printf ("%s\n",sqlBuffer); } rc = sqlite3_exec(mydb, sqlBuffer, 0, 0, &zErrMsg); sqlite3_close(mydb); } } printf("============ After\n"); dumpGlobals(); printf("Sender %s\n",from); printf("Message >%s<\n",message); toSpread(from,"Message recieved\n"); spreadJoin("TEST"); sleep(2); spreadLeave("TEST"); sleep(2); spreadDisconnect(); }
static void Read_message() { static char mess[MAX_MESSLEN]; char sender[MAX_GROUP_NAME]; 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 service_type; int16 mess_type; int endian_mismatch; int i,j; int ret, success =0; char server_group[1]; char *uname; service_type = 0; ret = SP_receive( Mbox, &service_type, sender, 100, &num_groups, target_groups, &mess_type, &endian_mismatch, sizeof(mess), mess ); if( ret < 0 ) { 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, MAX_MEMBERS, &num_groups, target_groups, &mess_type, &endian_mismatch, sizeof(mess), mess ); } } if (ret < 0 ) { if( ! To_exit ) { SP_error( ret ); printf("\n============================\n"); printf("\nBye.\n"); } exit( 0 ); } if( Is_regular_mess( service_type ) ) { mess[ret] = 0; //printf("message from %s, of type %d, (endian %d) to %d groups \n(%d bytes): %s\n", // sender, mess_type, endian_mismatch, num_groups, ret, mess ); //printf("private group is %s\n", Private_group); if (strncmp(Private_group, sender, strlen(Private_group)) != 0) { recv_server_msg((struct chat_packet *) mess, mess_type); } }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 ) ) { //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",memb_info.gid.id[0], memb_info.gid.id[1], memb_info.gid.id[2] ); sprintf(server_group, "c%d", connected); if (strncmp(sender, server_group, 2) == 0) { //printf("Server connection message\n"); for (i=0; i< num_groups; i++) { if (target_groups[i][1] == server_group[1]) { printf("Successfully connected to server %d\n>", connected); success = 1; show_menu(); } } if (!success) { printf("Server unavailable. Please try again later.\n>"); connected = 0; SP_leave(Mbox, sender); } } else { /*Membership message from chatroom. Show users in chat */ /*No longer here*/ } if( Is_caused_join_mess( service_type ) ) { //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", memb_info.changed_member ); }else if( Is_caused_disconnect_mess( service_type ) ){ //printf("Due to the DISCONNECT of %s\n", memb_info.changed_member ); if (strncmp(sender, server_group, 2) == 0 && memb_info.changed_member[1] == server_group[1]) { printf("Disconnected from server %s\n", server_group); SP_leave(Mbox, sender); /*Disconnect us from the server group */ if (chatroom != NULL) { sprintf(chatroom, "%s%d",chatroom, connected); SP_leave(Mbox, chatroom); chatroom[0]='\0'; chatroom_start = (struct node *)calloc(1,sizeof(struct node)); } connected = 0; /*we are no longer connected */ } }else if( Is_caused_network_mess( service_type ) ){ //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++ ) { 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 ); } for( j = 0; j < (int) vssets[i].num_members; j++ ) printf("\t%s\n", members[j] ); } } } else if( Is_transition_mess( service_type ) ) { //printf("received TRANSITIONAL membership for group %s\n", sender ); }else if ( Is_caused_leave_mess( service_type ) ){ //printf("received membership message that left group %s\n", sender ); } else printf("Incorrect mess type"); } else if (Is_reject_mess( service_type)) { printf("Rejcted"); } else printf("Unknown"); fflush(stdout); }