void join_room(char *group) { int ret; struct chat_packet *c; char server_group[1]; sprintf(server_group, "%d", connected); /*Convert server id to string for spread groupname*/ //c = malloc(sizeof(struct chat_packet)); // //bzero(c, sizeof(struct chat_packet)); c = (struct chat_packet *) calloc(1, sizeof(struct chat_packet)); /*better than malloc, zeros out memory*/ if ( group == "1" || group == "2" || group == "3" || group == "4" || group == "5") { printf("Chatrooms cannot be 1-5. These are reserved\n>"); } else if (strlen(username) < 1) { printf("Please set your username before joining a chat room\n>"); } else { /*Disjoin from current group */ if (strlen(chatroom) > 0) { printf("leaving chatroom, %s\n", chatroom); sprintf(chatroom, "%s%d",chatroom, connected); SP_leave(Mbox, chatroom); } //printf("chatroom length = %d\n", strlen(chatroom)); /* Send request to server to join a group */ strncpy(c->client_group, Private_group, MAX_GROUP_NAME); strncpy(c->name, username, strlen(username)); //printf("Sending join with %s", Private_group); strncpy(c->group, group, strlen(group)); c->type = 5; ret = SP_multicast(Mbox, AGREED_MESS, server_group, 2, sizeof(struct chat_packet), (char *)c); if( ret < 0 ) { SP_error( ret ); } } }
void join_server(char *server_id) { int ret; struct chat_packet *c; struct chat_packet *r; 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=0; int16 mess_type; int endian_mismatch; char group[80]; c = (struct chat_packet *)calloc(1,sizeof(struct chat_packet)); r = (struct chat_packet *)calloc(1,sizeof(struct chat_packet)); c->type = 2;//Request to join server strncpy(c->text, Private_group, strlen(Private_group)); c->server_id = atoi(server_id); //printf("Sending private grup %s to server", Private_group); strncpy(c->client_group, Private_group, MAX_GROUP_NAME); /* Send Message */ if (connected > 0) { /*Leave current group*/ sprintf(group, "c%d", connected); SP_leave(Mbox, group); } /* ret = SP_multicast(Mbox, AGREED_MESS, server_id, 2, sizeof(struct chat_packet), (char *)c); */ /* That was the old way. New way is join the server group */ sprintf(group, "c%d", atoi(server_id)); ret = SP_join(Mbox, group); connected = atoi(server_id); /*Set connected. Note we still need response from server, but we need to pass this to the recv connect */ if( ret < 0 ) { SP_error( ret ); } }
static void User_command() { char command[130]; char mess[MAX_MESSLEN]; char group[80]; char groups[10][MAX_GROUP_NAME]; int num_groups; unsigned int mess_len; int ret; int i; for( i=0; i < sizeof(command); i++ ) command[i] = 0; if( fgets( command, 130, stdin ) == NULL ) Bye(); switch( command[0] ) { case 'j': ret = sscanf( &command[2], "%s", group ); if( ret < 1 ) { printf(" invalid group \n"); break; } ret = SP_join( Mbox, group ); if( ret < 0 ) SP_error( ret ); break; case 'l': ret = sscanf( &command[2], "%s", group ); if( ret < 1 ) { printf(" invalid group \n"); break; } ret = SP_leave( Mbox, group ); if( ret < 0 ) SP_error( ret ); break; case 's': num_groups = sscanf(&command[2], "%s%s%s%s%s%s%s%s%s%s", groups[0], groups[1], groups[2], groups[3], groups[4], groups[5], groups[6], groups[7], groups[8], groups[9] ); if( num_groups < 1 ) { printf(" invalid group \n"); break; } printf("enter message: "); if (fgets(mess, 200, stdin) == NULL) Bye(); mess_len = strlen( mess ); #ifdef _REENTRANT #ifdef __bsdi__ /* bsdi bug - doing a close when another thread blocks on the socket causes a seg fault */ ret = send( Mbox, mess, 0, 0 ); if( ret < 0 ) { SP_error( CONNECTION_CLOSED ); Bye(); } #endif /* __bsdi__ */ #endif /* _REENTRANT */ ret= SP_multigroup_multicast( Mbox, SAFE_MESS, num_groups, (const char (*)[MAX_GROUP_NAME]) groups, 1, mess_len, mess ); if( ret < 0 ) { SP_error( ret ); Bye(); } Num_sent++; break; case 'b': ret=sscanf( &command[2], "%s", group ); if( ret != 1 ) strcpy( group, "dummy_group_name" ); printf("enter size of each message: "); if (fgets(mess, 200, stdin) == NULL) Bye(); ret=sscanf(mess, "%u", &mess_len ); if( ret !=1 ) mess_len = Previous_len; if( mess_len > MAX_MESSLEN ) mess_len = MAX_MESSLEN; Previous_len = mess_len; printf("sending 10 messages of %u bytes\n", mess_len ); for( i=0; i<10; i++ ) { Num_sent++; sprintf( mess, "mess num %d ", Num_sent ); #ifdef _REENTRANT #ifdef __bsdi__ /* bsdi bug - doing a close when another thread blocks on the socket causes a seg fault */ ret = send( Mbox, mess, 0,0 ); if( ret < 0 ) { SP_error( CONNECTION_CLOSED ); Bye(); } #endif /* __bsdi__ */ #endif /* _REENTRANT */ ret= SP_multicast( Mbox, FIFO_MESS, group, 2, mess_len, mess ); if( ret < 0 ) { SP_error( ret ); Bye(); } printf("sent message %d (total %d)\n", i+1, Num_sent ); } break; #ifndef _REENTRANT case 'r': Read_message(); break; case 'p': ret = SP_poll( Mbox ); printf("Polling sais: %d\n", ret ); break; case 'e': E_attach_fd( Mbox, READ_FD, Read_message, 0, NULL, HIGH_PRIORITY ); break; case 'd': E_detach_fd( Mbox, READ_FD ); break; #endif /* _REENTRANT */ case 'q': Bye(); break; default: printf("\nUnknown commnad\n"); Print_menu(); break; } printf("\nUser> "); fflush(stdout); }
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); }
static void User_command() { char command[130]; char mtext[80]; char mess[MAX_MESSLEN]; char group[80]; char groups[10][MAX_GROUP_NAME]; int num_groups; unsigned int mess_len; int ret; int i; int like; sp_time test_timeout; char server_id[1]; for( i=0; i < sizeof(command); i++ ) command[i] = 0; if( fgets( command, 130, stdin ) == NULL ) Bye(); /* remove newline from string */ command[strlen(command) -1] = 0; switch( command[0] ) { case 'j': ret = sscanf( &command[2], "%s", group ); if (connected > 0) { if( ret < 1 ) { printf(" invalid chatroom \n> "); break; } join_room(group); } else {printf("You must connect to a server first\n>"); } break; case 'c': ret = sscanf( &command[2], "%s", group ); if( ret < 1 ) { printf(" invalid server id \n> "); break; } join_server(group); break; case 'q': Bye(); exit(0); break; case '?': show_menu(); break; case 'u': if (connected > 0 ) { ret = sscanf( &command[2], "%s", username); if( ret < 1 ) { printf(" Invalid Username\n> "); break; } else { printf("Username set to %s\n> ", username); /*If in chatroom, disconnect */ if (strlen(chatroom) > 0) { sprintf(chatroom, "%s%d",chatroom, connected); printf("leaving chatroom, %s due to username change\n", chatroom); SP_leave(Mbox, chatroom); } } } else {printf("You must connect to a server first\n>"); } break; case 'a': if (connected > 0) { strncpy(mtext, &command[2], 130); if( strlen(mtext) < 1) { printf(" invalid message\n> "); break; } send_msg(mtext); } else {printf("You must connect to a server first\n>"); } break; case 'l': if (connected > 0) { ret = sscanf( &command[2], "%d", &like ); if( ret < 1) { printf(" invalid line\n> "); break; } like_msg(like, 1); } else {printf("You must connect to a server first\n>"); } break; case 'r': if (connected > 0) { ret = sscanf( &command[2], "%d", &like); if (ret < 1) { printf(" invalid line\n> "); break; } like_msg(like, 0); } else {printf("You must connect to a server first\n>"); } break; case 'h': if (strlen(chatroom) != 0) { print_history(); printf("> "); } else printf("You are not in a chatroom.\n>"); break; case 'v': if (connected > 0) { show_servers(); } else {printf("You must connect to a server first\n>"); } break; default: printf("> "); break; } fflush(stdout); }