Advertisement
Solingen

Untitled

Jun 5th, 2024
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.54 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <arpa/inet.h>
  6. #include <sys/wait.h>
  7. #include <signal.h>
  8.  
  9. #define MAX_MSG_SIZE 500
  10. #define MAX_NAME_SIZE 50
  11.  
  12. typedef struct {
  13. char name[MAX_NAME_SIZE];
  14. struct sockaddr_in addr;
  15. } Friend;
  16.  
  17. Friend *friends = NULL;
  18. int num_friends = 0;
  19. int sock;
  20. char user_name[MAX_NAME_SIZE];
  21.  
  22. void send_message(const char *msg, struct sockaddr_in *addr);
  23.  
  24. void add_friend(const char *name, struct sockaddr_in *addr) {
  25. friends = realloc(friends, (num_friends + 1) * sizeof(Friend));
  26. if (friends != NULL) {
  27. strcpy(friends[num_friends].name, name);
  28. friends[num_friends].addr = *addr;
  29. num_friends++;
  30. }
  31. }
  32.  
  33. int is_friend(struct sockaddr_in *addr) {
  34. for (int i = 0; i < num_friends; i++) {
  35. if (friends[i].addr.sin_addr.s_addr == addr->sin_addr.s_addr &&
  36. friends[i].addr.sin_port == addr->sin_port) {
  37. return 1;
  38. }
  39. }
  40. return 0;
  41. }
  42.  
  43. void receive_messages() {
  44. struct sockaddr_in src_addr;
  45. socklen_t addr_len = sizeof(src_addr);
  46. char buffer[MAX_MSG_SIZE];
  47. while (1) {
  48. int msg_len = recvfrom(sock, buffer, MAX_MSG_SIZE, 0, (struct sockaddr *)&src_addr, &addr_len);
  49. if (msg_len > 0) {
  50. buffer[msg_len] = '\0';
  51. char *name = buffer;
  52. char *msg = buffer + strlen(name) + 1;
  53.  
  54. if (strcmp(msg, "#hi!") == 0) {
  55. send_message("#hello!", &src_addr);
  56. if (!is_friend(&src_addr)) {
  57. add_friend(name, &src_addr);
  58. }
  59. } else if (strcmp(msg, "#hello!") == 0) {
  60. if (!is_friend(&src_addr)) {
  61. add_friend(name, &src_addr);
  62. }
  63. } else {
  64. printf("%s: %s\n", name, msg);
  65. }
  66. }
  67. }
  68. }
  69.  
  70. void send_message(const char *msg, struct sockaddr_in *addr) {
  71. char buffer[MAX_MSG_SIZE];
  72. snprintf(buffer, MAX_MSG_SIZE, "%s%c%s%c", user_name, '\0', msg, '\0');
  73. sendto(sock, buffer, strlen(user_name) + 1 + strlen(msg) + 1, 0, (struct sockaddr *)addr, sizeof(*addr));
  74. }
  75.  
  76. void send_to_all(const char *msg) {
  77. for (int i = 0; i < num_friends; i++) {
  78. send_message(msg, &friends[i].addr);
  79. }
  80. }
  81.  
  82. void handle_command(const char *command) {
  83. if (strncmp(command, "@hi", 3) == 0) {
  84. char ip[INET_ADDRSTRLEN];
  85. int port;
  86. sscanf(command + 4, "%s %d", ip, &port);
  87. struct sockaddr_in new_friend;
  88. new_friend.sin_family = AF_INET;
  89. new_friend.sin_port = htons(port);
  90. inet_pton(AF_INET, ip, &new_friend.sin_addr);
  91. send_message("#hi!", &new_friend);
  92. } else if (strcmp(command, "@friends") == 0) {
  93. for (int i = 0; i < num_friends; i++) {
  94. printf("%s %s %d\n", friends[i].name, inet_ntoa(friends[i].addr.sin_addr), ntohs(friends[i].addr.sin_port));
  95. }
  96. } else if (strcmp(command, "@exit") == 0) {
  97. close(sock);
  98. exit(0);
  99. }
  100. }
  101.  
  102. void terminate_handler(int signum) {
  103. free(friends);
  104. close(sock);
  105. exit(0);
  106. }
  107.  
  108. int main(int argc, char *argv[]) {
  109. if (argc != 3) {
  110. fprintf(stderr, "Usage: %s <name> <port>\n", argv[0]);
  111. exit(1);
  112. }
  113.  
  114. signal(SIGTERM, terminate_handler);
  115. signal(SIGINT, terminate_handler);
  116.  
  117. friends = (Friend *)malloc(sizeof(Friend) * 10);
  118. if (friends == NULL) {
  119. perror("Error allocating memory for friends list");
  120. exit(1);
  121. }
  122.  
  123. strcpy(user_name, argv[1]);
  124. int port = atoi(argv[2]);
  125.  
  126. sock = socket(AF_INET, SOCK_DGRAM, 0);
  127. if (sock == -1) {
  128. perror("Error creating socket");
  129. exit(1);
  130. }
  131.  
  132. struct sockaddr_in server_addr;
  133. server_addr.sin_family = AF_INET;
  134. server_addr.sin_addr.s_addr = INADDR_ANY;
  135. server_addr.sin_port = htons(port);
  136.  
  137. if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
  138. perror("Error binding socket");
  139. exit(1);
  140. }
  141.  
  142. pid_t pid = fork();
  143. if (pid == -1) {
  144. perror("Error forking process");
  145. exit(1);
  146. } else if (pid == 0) {
  147. receive_messages();
  148. } else {
  149. char input[MAX_MSG_SIZE];
  150. while (1) {
  151. fgets(input, sizeof(input), stdin);
  152. input[strcspn(input, "\n")] = '\0';
  153. if (input[0] == '@') {
  154. handle_command(input);
  155. } else {
  156. send_to_all(input);
  157. }
  158. }
  159. }
  160.  
  161. return 0;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement