Advertisement
Solingen

Untitled

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