Advertisement
Solingen

Untitled

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