Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- #include <getopt.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- struct Server {
- char ip[255];
- int port;
- };
- uint64_t MultModulo(uint64_t a, uint64_t b, uint64_t mod) {
- uint64_t result = 0;
- a = a % mod;
- while (b > 0) {
- if (b % 2 == 1)
- result = (result + a) % mod;
- a = (a * 2) % mod;
- b /= 2;
- }
- return result % mod;
- }
- bool ConvertStringToUI64(const char *str, uint64_t *val) {
- char *end = NULL;
- unsigned long long i = strtoull(str, &end, 10);
- if (errno == ERANGE) {
- fprintf(stderr, "Out of uint64_t range: %s\n", str);
- return false;
- }
- if (errno != 0)
- return false;
- *val = i;
- return true;
- }
- int main(int argc, char **argv) {
- uint64_t k = -1;
- uint64_t mod = -1;
- char servers[255] = {'\0'}; // max filename length = 255
- while (true) {
- int current_optind = optind ? optind : 1;
- static struct option options[] = {{"k", required_argument, 0, 0},
- {"mod", required_argument, 0, 0},
- {"servers", required_argument, 0, 0},
- {0, 0, 0, 0}};
- int option_index = 0;
- int c = getopt_long(argc, argv, "", options, &option_index);
- if (c == -1)
- break;
- switch (c) {
- case 0: {
- switch (option_index) {
- case 0:
- ConvertStringToUI64(optarg, &k);
- if (k < 1)
- {
- printf("k must be positive");
- return 1;
- }
- break;
- case 1:
- ConvertStringToUI64(optarg, &mod);
- if (mod < 1)
- {
- printf("mod must be positive");
- return 1;
- }
- break;
- case 2:
- memcpy(servers, optarg, strlen(optarg));
- break;
- default:
- printf("Index %d is out of options\n", option_index);
- }
- } break;
- case '?':
- printf("Arguments error\n");
- break;
- default:
- fprintf(stderr, "getopt returned character code 0%o?\n", c);
- }
- }
- if (k == -1 || mod == -1 || !strlen(servers)) {
- fprintf(stderr, "Using: %s --k 1000 --mod 5 --servers /path/to/file\n",
- argv[0]);
- return 1;
- }
- FILE *serversFile;
- serversFile = fopen(servers, "r");
- if (serversFile == NULL)
- {
- printf("Could not open servers file");
- return 1;
- }
- char buff[255];
- int port;
- unsigned int servers_num = 0;
- struct Server *to = malloc(sizeof(struct Server) * servers_num);
- while (fscanf(serversFile, "%s:%d\n", buff, &port))
- {
- to[0].port = port;
- memcpy(to[0].ip, buff, sizeof(buff));
- servers_num++;
- }
- uint64_t result = 1;
- int sockets[servers_num];
- for (int i = 0; i < servers_num; i++) {
- struct hostent *hostname = gethostbyname(to[i].ip);
- if (hostname == NULL) {
- fprintf(stderr, "gethostbyname failed with %s\n", to[i].ip);
- exit(1);
- }
- struct sockaddr_in server;
- server.sin_family = AF_INET;
- server.sin_port = htons(to[i].port);
- server.sin_addr.s_addr = *((unsigned long *)hostname->h_addr);
- sockets[i] = socket(AF_INET, SOCK_STREAM, 0);
- if (sockets[i] < 0) {
- fprintf(stderr, "Socket creation failed!\n");
- exit(1);
- }
- if (connect(sockets[i], (struct sockaddr *)&server, sizeof(server)) < 0) {
- fprintf(stderr, "Connection failed\n");
- exit(1);
- }
- uint64_t begin = i*k/servers_num;
- uint64_t end = (i+1)*k/servers_num;
- char task[sizeof(uint64_t) * 3];
- memcpy(task, &begin, sizeof(uint64_t));
- memcpy(task + sizeof(uint64_t), &end, sizeof(uint64_t));
- memcpy(task + 2 * sizeof(uint64_t), &mod, sizeof(uint64_t));
- if (send(sockets[i], task, sizeof(task), 0) < 0) {
- fprintf(stderr, "Send failed\n");
- exit(1);
- }
- }
- for (int i = 0; i < servers_num; i++)
- {
- char response[sizeof(uint64_t)];
- if (recv(sockets[i], response, sizeof(response), 0) < 0) {
- fprintf(stderr, "Recieve failed\n");
- exit(1);
- }
- uint64_t answer = 0;
- memcpy(&answer, response, sizeof(uint64_t));
- result = (result * answer) % mod;
- close(sockets[i]);
- }
- printf("answer: %lu\n", result);
- free(to);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement