Advertisement
Solingen

Untitled

Jun 9th, 2024
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.53 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 <signal.h>
  7. #include <sys/wait.h>
  8. #include <fcntl.h>
  9.  
  10. #define MAX_MSG_SIZE 500
  11. #define MAX_NAME_SIZE 50
  12.  
  13. typedef struct {
  14. char name[MAX_NAME_SIZE];
  15. struct sockaddr_in addr;
  16. } Friend;
  17.  
  18. Friend *friends = NULL;
  19. int num_friends = 0;
  20. int sock;
  21. char user_name[MAX_NAME_SIZE];
  22. int friends_fd;
  23.  
  24. void handle_sigint(int sig) {
  25. close(friends_fd);
  26. close(sock);
  27. exit(0);
  28. }
  29.  
  30. void send_message(const char *msg, struct sockaddr_in *addr) {
  31. char buffer[MAX_MSG_SIZE];
  32. snprintf(buffer, MAX_MSG_SIZE, "%s%c%s%c", user_name, '\0', msg, '\0');
  33. sendto(sock, buffer, strlen(user_name) + 1 + strlen(msg) + 1, 0, (struct sockaddr *)addr, sizeof(*addr));
  34. }
  35.  
  36. void add_friend(const char *name, struct sockaddr_in *addr) {
  37. for (int i = 0; i < num_friends; i++) {
  38. if (strcmp(friends[i].name, name) == 0 && friends[i].addr.sin_addr.s_addr == addr->sin_addr.s_addr && friends[i].addr.sin_port == addr->sin_port) {
  39. return; // Friend already exists
  40. }
  41. }
  42. friends = realloc(friends, (num_friends + 1) * sizeof(Friend));
  43. if (friends == NULL) {
  44. perror("Error reallocating memory");
  45. exit(1);
  46. }
  47. strcpy(friends[num_friends].name, name);
  48. friends[num_friends].addr = *addr;
  49. num_friends++;
  50.  
  51. FILE *fp = fopen("polz.txt", "a");
  52. if (fp != NULL) {
  53. fprintf(fp, "%s %s %d\n", name, inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
  54. fclose(fp);
  55. }
  56. }
  57.  
  58. int is_friend(struct sockaddr_in *addr) {
  59. for (int i = 0; i < num_friends; i++) {
  60. if (friends[i].addr.sin_addr.s_addr == addr->sin_addr.s_addr && friends[i].addr.sin_port == addr->sin_port) {
  61. return 1;
  62. }
  63. }
  64. return 0;
  65. }
  66.  
  67. void receive_messages() {
  68. struct sockaddr_in src_addr;
  69. socklen_t addr_len = sizeof(src_addr);
  70. char buffer[MAX_MSG_SIZE];
  71. while (1) {
  72. int msg_len = recvfrom(sock, buffer, MAX_MSG_SIZE, 0, (struct sockaddr *)&src_addr, &addr_len);
  73. if (msg_len > 0) {
  74. buffer[msg_len] = '\0';
  75. char *name = buffer;
  76. char *msg = buffer + strlen(name) + 1;
  77.  
  78. if (strcmp(msg, "#hi!") == 0) {
  79. send_message("#hello!", &src_addr);
  80. if (!is_friend(&src_addr)) {
  81. add_friend(name, &src_addr);
  82. }
  83. } else if (strcmp(msg, "#hello!") == 0) {
  84. if (!is_friend(&src_addr)) {
  85. add_friend(name, &src_addr);
  86. }
  87. } else {
  88. printf("%s: %s\n", name, msg);
  89. }
  90. }
  91. }
  92. }
  93.  
  94. void send_to_all(const char *msg) {
  95. for (int i = 0; i < num_friends; i++) {
  96. if (strcmp(friends[i].name, user_name) != 0) { // Check if the message is not being sent to self
  97. send_message(msg, &friends[i].addr);
  98. }
  99. }
  100. }
  101.  
  102. void handle_command(const char *command) {
  103. if (strncmp(command, "@hi", 3) == 0) {
  104. char ip[INET_ADDRSTRLEN];
  105. int port;
  106. sscanf(command + 4, "%s %d", ip, &port);
  107. struct sockaddr_in new_friend;
  108. new_friend.sin_family = AF_INET;
  109. new_friend.sin_port = htons(port);
  110. inet_pton(AF_INET, ip, &new_friend.sin_addr);
  111. send_message("#hi!", &new_friend);
  112. } else if (strcmp(command, "@friends") == 0) {
  113. for (int i = 0; i < num_friends; i++) {
  114. if (strcmp(friends[i].name, user_name) != 0) {
  115. printf("%s %s %d\n", friends[i].name, inet_ntoa(friends[i].addr.sin_addr), ntohs(friends[i].addr.sin_port));
  116. }
  117. }
  118. } else if (strcmp(command, "@exit") == 0) {
  119. kill(0, SIGINT);
  120. }
  121. }
  122.  
  123. void load_friends() {
  124. FILE *fp = fopen("polz.txt", "r");
  125. if (fp == NULL) {
  126. return;
  127. }
  128. char line[256];
  129. char name[MAX_NAME_SIZE];
  130. char ip[INET_ADDRSTRLEN];
  131. int port;
  132. while (fgets(line, sizeof(line), fp)) {
  133. sscanf(line, "%s %s %d", name, ip, &port);
  134. struct sockaddr_in addr;
  135. addr.sin_family = AF_INET;
  136. addr.sin_port = htons(port);
  137. inet_pton(AF_INET, ip, &addr.sin_addr);
  138. add_friend(name, &addr);
  139. }
  140. fclose(fp);
  141. }
  142.  
  143. int main(int argc, char *argv[]) {
  144. if (argc != 3) {
  145. fprintf(stderr, "Usage: %s <name> <port>\n", argv[0]);
  146. exit(1);
  147. }
  148.  
  149. strcpy(user_name, argv[1]);
  150. int port = atoi(argv[2]);
  151.  
  152. sock = socket(AF_INET, SOCK_DGRAM, 0);
  153. if (sock == -1) {
  154. perror("Error creating socket");
  155. exit(1);
  156. }
  157.  
  158. struct sockaddr_in server_addr;
  159. server_addr.sin_family = AF_INET;
  160. server_addr.sin_addr.s_addr = INADDR_ANY;
  161. server_addr.sin_port = htons(port);
  162.  
  163. if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
  164. perror("Error binding socket");
  165. exit(1);
  166. }
  167.  
  168. signal(SIGINT, handle_sigint);
  169.  
  170. // Load friends from file
  171. load_friends();
  172.  
  173. if (fork() == 0) {
  174. // Child process for receiving messages
  175. receive_messages();
  176. } else {
  177. // Parent process for sending messages
  178. char input[MAX_MSG_SIZE];
  179. while (1) {
  180. fgets(input, sizeof(input), stdin);
  181. input[strcspn(input, "\n")] = '\0';
  182. if (input[0] == '@') {
  183. handle_command(input);
  184. } else {
  185. send_to_all(input);
  186. }
  187. }
  188. }
  189.  
  190. close(sock);
  191. return 0;
  192. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement