Advertisement
tftrgi11

Untitled

Jun 19th, 2020
1,356
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.41 KB | None | 0 0
  1. #include <stdbool.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6.  
  7. #include <errno.h>
  8. #include <getopt.h>
  9. #include <netdb.h>
  10. #include <netinet/in.h>
  11. #include <netinet/ip.h>
  12. #include <sys/socket.h>
  13. #include <sys/types.h>
  14.  
  15. struct Server {
  16.   char ip[255];
  17.   int port;
  18. };
  19.  
  20. uint64_t MultModulo(uint64_t a, uint64_t b, uint64_t mod) {
  21.   uint64_t result = 0;
  22.   a = a % mod;
  23.   while (b > 0) {
  24.     if (b % 2 == 1)
  25.       result = (result + a) % mod;
  26.     a = (a * 2) % mod;
  27.     b /= 2;
  28.   }
  29.  
  30.   return result % mod;
  31. }
  32.  
  33. bool ConvertStringToUI64(const char *str, uint64_t *val) {
  34.   char *end = NULL;
  35.   unsigned long long i = strtoull(str, &end, 10);
  36.   if (errno == ERANGE) {
  37.     fprintf(stderr, "Out of uint64_t range: %s\n", str);
  38.     return false;
  39.   }
  40.  
  41.   if (errno != 0)
  42.     return false;
  43.  
  44.   *val = i;
  45.   return true;
  46. }
  47.  
  48. int main(int argc, char **argv) {
  49.   uint64_t k = -1;
  50.   uint64_t mod = -1;
  51.   char servers[255] = {'\0'}; // max filename length = 255
  52.  
  53.   while (true) {
  54.     int current_optind = optind ? optind : 1;
  55.  
  56.     static struct option options[] = {{"k", required_argument, 0, 0},
  57.                                       {"mod", required_argument, 0, 0},
  58.                                       {"servers", required_argument, 0, 0},
  59.                                       {0, 0, 0, 0}};
  60.  
  61.     int option_index = 0;
  62.     int c = getopt_long(argc, argv, "", options, &option_index);
  63.  
  64.     if (c == -1)
  65.       break;
  66.  
  67.     switch (c) {
  68.     case 0: {
  69.       switch (option_index) {
  70.       case 0:
  71.         ConvertStringToUI64(optarg, &k);
  72.         if (k < 1)
  73.         {
  74.             printf("k must be positive");
  75.             return 1;
  76.         }
  77.         break;
  78.       case 1:
  79.         ConvertStringToUI64(optarg, &mod);
  80.         if (mod < 1)
  81.         {
  82.             printf("mod must be positive");
  83.             return 1;
  84.         }
  85.         break;
  86.       case 2:
  87.         memcpy(servers, optarg, strlen(optarg));
  88.         break;
  89.       default:
  90.         printf("Index %d is out of options\n", option_index);
  91.       }
  92.     } break;
  93.  
  94.     case '?':
  95.       printf("Arguments error\n");
  96.       break;
  97.     default:
  98.       fprintf(stderr, "getopt returned character code 0%o?\n", c);
  99.     }
  100.   }
  101.  
  102.   if (k == -1 || mod == -1 || !strlen(servers)) {
  103.     fprintf(stderr, "Using: %s --k 1000 --mod 5 --servers /path/to/file\n",
  104.             argv[0]);
  105.     return 1;
  106.   }
  107.  
  108.   FILE *serversFile;
  109.  
  110.   serversFile = fopen(servers, "r");
  111.   if (serversFile == NULL)
  112.   {
  113.       printf("Could not open servers file");
  114.       return 1;
  115.   }
  116.   char buff[255];
  117.   int port;
  118.   unsigned int servers_num = 0;
  119.   struct Server *to = malloc(sizeof(struct Server) * servers_num);
  120.   while (fscanf(serversFile, "%s:%d\n", buff, &port))
  121.   {
  122.       to[0].port = port;
  123.       memcpy(to[0].ip, buff, sizeof(buff));
  124.       servers_num++;
  125.   }
  126.  
  127.  
  128.   uint64_t result = 1;
  129.   int sockets[servers_num];
  130.   for (int i = 0; i < servers_num; i++) {
  131.     struct hostent *hostname = gethostbyname(to[i].ip);
  132.     if (hostname == NULL) {
  133.       fprintf(stderr, "gethostbyname failed with %s\n", to[i].ip);
  134.       exit(1);
  135.     }
  136.  
  137.     struct sockaddr_in server;
  138.     server.sin_family = AF_INET;
  139.     server.sin_port = htons(to[i].port);
  140.     server.sin_addr.s_addr = *((unsigned long *)hostname->h_addr);
  141.  
  142.     sockets[i] = socket(AF_INET, SOCK_STREAM, 0);
  143.     if (sockets[i] < 0) {
  144.       fprintf(stderr, "Socket creation failed!\n");
  145.       exit(1);
  146.     }
  147.  
  148.     if (connect(sockets[i], (struct sockaddr *)&server, sizeof(server)) < 0) {
  149.       fprintf(stderr, "Connection failed\n");
  150.       exit(1);
  151.     }
  152.  
  153.     uint64_t begin = i*k/servers_num;
  154.     uint64_t end = (i+1)*k/servers_num;
  155.  
  156.     char task[sizeof(uint64_t) * 3];
  157.     memcpy(task, &begin, sizeof(uint64_t));
  158.     memcpy(task + sizeof(uint64_t), &end, sizeof(uint64_t));
  159.     memcpy(task + 2 * sizeof(uint64_t), &mod, sizeof(uint64_t));
  160.  
  161.     if (send(sockets[i], task, sizeof(task), 0) < 0) {
  162.       fprintf(stderr, "Send failed\n");
  163.       exit(1);
  164.     }
  165.   }
  166.  
  167. for (int i = 0; i < servers_num; i++)
  168. {
  169.     char response[sizeof(uint64_t)];
  170.     if (recv(sockets[i], response, sizeof(response), 0) < 0) {
  171.       fprintf(stderr, "Recieve failed\n");
  172.       exit(1);
  173.     }
  174.     uint64_t answer = 0;
  175.     memcpy(&answer, response, sizeof(uint64_t));
  176.     result = (result * answer) % mod;
  177.     close(sockets[i]);
  178. }
  179.  
  180.   printf("answer: %lu\n", result);
  181.   free(to);
  182.  
  183.   return 0;
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement