@@ -28,12 +28,22 @@ std::vector<int> sock_fds;
2828// Keep track of all users and their sock_fds
2929std::unordered_map<int , int > users;
3030
31+ std::unordered_map<std::string, int > usernames;
32+
3133// Available commands
32- const char * commands = {" whisper" };
34+ std::vector<std::string> commands = {" whisper" , " view " };
3335
3436// Mutex for sync
3537pthread_mutex_t sock_fds_mutex PTHREAD_MUTEX_INITIALIZER ;
3638pthread_mutex_t users_mutex PTHREAD_MUTEX_INITIALIZER ;
39+ pthread_mutex_t usernames_mutex PTHREAD_MUTEX_INITIALIZER ;
40+
41+ // Trims strings of whitespaces
42+ std::string trim (const std::string& str) {
43+ size_t start = str.find_first_not_of (" \n\r\t " );
44+ size_t end = str.find_last_not_of (" \n\r\t " );
45+ return (start == std::string::npos || end == std::string::npos) ? " " : str.substr (start, end - start + 1 );
46+ }
3747
3848// Broadcasts received messages to all clients
3949void broadcastMsg (const char *data, const char *username, int uid){
@@ -58,7 +68,40 @@ int whisperMsg(int uid, const char *username, const char *private_msg){
5868 pthread_mutex_unlock (&users_mutex);
5969
6070 if (write (sock_fd, message, sizeof (message))==-1 ){
61- std::cout << " Failed to whisper message to client!" << std::endl;
71+ std::cout << " Failed to send whisper response message to client!" << std::endl;
72+ return 0 ;
73+ }
74+ return 1 ;
75+ }
76+
77+ int viewAllUsers (int sock_fd){
78+ char message[BUFLEN ];
79+ bzero (message, sizeof (message));
80+ strcpy (message, " \n All connected users:\n " );
81+
82+ pthread_mutex_lock (&usernames_mutex);
83+ for (auto it: usernames){
84+ char user[100 ];
85+ bzero (user, sizeof (user));
86+ snprintf (user, sizeof (user), " %s : %d\n " , it.first .c_str (), it.second );
87+ strcat (message, user);
88+ }
89+ pthread_mutex_unlock (&usernames_mutex);
90+
91+ if (write (sock_fd, message, strlen (message))==-1 ){
92+ std::cout << " Failed to send view clients response to client!" << std::endl;
93+ return 0 ;
94+ }
95+ return 1 ;
96+ }
97+
98+ int sendInvalidCommandError (int sock_fd){
99+ char message[BUFLEN ];
100+ bzero (message, sizeof (message));
101+
102+ snprintf (message, sizeof (message), " Invalid command!" );
103+ if (write (sock_fd, message, sizeof (message))==-1 ){
104+ std::cout << " Failed to send invalid command response to client!" << std::endl;
62105 return 0 ;
63106 }
64107 return 1 ;
@@ -93,17 +136,18 @@ void *handleClient(void *client){
93136
94137 // Command is received
95138 if (r_buff[0 ]==' /' ){
96- char command[10 ];
97139 char user_id[10 ];
98140 bzero (private_msg, sizeof (private_msg));
99141
100142 char *ptr = r_buff + 1 ;
101143 char *temp;
102144 temp = strtok (ptr, " " );
103145 int args = 0 ;
146+ std::string cmd;
104147 while (temp!=NULL ){
105148 if (args==0 ){
106- strcpy (command, temp);
149+ cmd = std::string (temp);
150+ cmd = trim (cmd);
107151 args++;
108152 }else if (args==1 ){
109153 strcpy (user_id, temp);
@@ -115,7 +159,13 @@ void *handleClient(void *client){
115159 temp = strtok (NULL , " " );
116160 }
117161
118- whisperMsg (atoi (user_id), username, private_msg);
162+ if (cmd==" whisper" ){
163+ whisperMsg (atoi (user_id), username, private_msg);
164+ }else if (cmd==" view" ){
165+ viewAllUsers (sock_fd);
166+ }else {
167+ sendInvalidCommandError (sock_fd);
168+ }
119169 }else {
120170 // Message is received
121171 std::cout << username << " [" << uid << " ]" << " says: " << r_buff << std::endl;
@@ -198,6 +248,9 @@ int main(int argc, char **argv){
198248 strcpy (c->username , username);
199249
200250 users[uid] = client_fd;
251+ std::string name = username;
252+ name = trim (name);
253+ usernames[name] = uid;
201254
202255 // Create a new thread for every client
203256 pthread_t tid;
0 commit comments