Advertisement
Aaaaa988

spo4

Apr 9th, 2021
730
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.49 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/socket.h>
  4. #include <arpa/inet.h>
  5. #include <string.h>
  6. #include <argp.h>
  7. #include <unistd.h>
  8. #include <regex.h>
  9.  
  10. #define ADDR_REGEX "\\(udp\\|tcp\\)://\\([0-9]\\+.[0-9]\\+.[0-9]\\+.[0-9]\\+\\):\\([0-9]\\+\\)"
  11.  
  12. char *ip_arg, *file_arg;
  13.  
  14. struct argp_option options[] = {{0}};
  15.  
  16. static int parse_opt(int key, char *arg, struct argp_state *state) {
  17.     int *arg_count = state->input;
  18.  
  19.     switch (key) {
  20.         case ARGP_KEY_ARG:
  21.             switch (*arg_count) {
  22.                 case 2:
  23.                     ip_arg = arg;
  24.                     break;
  25.                 case 1:
  26.                     file_arg = arg;
  27.                     break;
  28.             }
  29.             (*arg_count)--;
  30.             break;
  31.         case ARGP_KEY_END:
  32.             printf("\n");
  33.             if (*arg_count > 0)
  34.                 argp_failure(state, 1, 0, "not enough arguments");
  35.             else if (*arg_count < 0)
  36.                 argp_failure(state, 1, 0, "too many arguments");
  37.             break;
  38.     }
  39.     return 0;
  40. }
  41.  
  42. int main(int argc, char **argv) {
  43.     int sockfd, arg_count = 2;
  44.     struct sockaddr_in serv_addr;
  45.     char srv_proto[4] = {0}, srv_ip[24] = {0}, srv_port[8] = {0};
  46.  
  47.     struct argp argp = {options, parse_opt, "PROTOCOL://IP:PORT FILE"};
  48.     argp_parse(&argp, argc, argv, 0, 0, &arg_count);
  49.  
  50.     regex_t *regex = (regex_t *) malloc(sizeof(regex_t));
  51.     if (regcomp(regex, ADDR_REGEX, 0) != 0) {
  52.         fprintf(stderr, "regcomp failed\n");
  53.         exit(EXIT_FAILURE);
  54.     }
  55.     regmatch_t *regmatches = (regmatch_t *) malloc(4 * sizeof(regmatch_t));
  56.  
  57.     if (regexec(regex, ip_arg, 4, regmatches, REG_EXTENDED) != 0) {
  58.         fprintf(stderr, "failed to parse ip\n");
  59.         exit(EXIT_FAILURE);
  60.     }
  61.  
  62.     strncpy(srv_proto, ip_arg + regmatches[1].rm_so, regmatches[1].rm_eo - regmatches[1].rm_so);
  63.     strncpy(srv_ip, ip_arg + regmatches[2].rm_so, regmatches[2].rm_eo - regmatches[2].rm_so);
  64.     strncpy(srv_port, ip_arg + regmatches[3].rm_so, regmatches[3].rm_eo - regmatches[3].rm_so);
  65.  
  66.     if ((sockfd = socket(AF_INET, (strcmp(srv_proto, "tcp") == 0) ? SOCK_STREAM : SOCK_DGRAM, 0)) < 0) {
  67.         fprintf(stderr, "socket failed\n");
  68.         exit(EXIT_FAILURE);
  69.     }
  70.  
  71.     serv_addr.sin_family = AF_INET;
  72.     serv_addr.sin_port = strtol(srv_port, NULL, 10);
  73.  
  74.     if (inet_pton(AF_INET, srv_ip, &serv_addr.sin_addr) <= 0) {
  75.         fprintf(stderr, "pton failed\n");
  76.         exit(EXIT_FAILURE);
  77.     }
  78.  
  79.     if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) {
  80.         fprintf(stderr, "connect failed\n");
  81.         exit(EXIT_FAILURE);
  82.     }
  83.  
  84.     FILE *file = fopen(file_arg, "r");
  85.     while (!feof(file)) {
  86.         char fbuf[32] = {0};
  87.         int nbytes = fread(fbuf, 1, 32, file);
  88.         send(sockfd, fbuf, nbytes, 0);
  89.     }
  90.     fclose(file);
  91.  
  92.     return 0;
  93. }
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104. #include <stdio.h>
  105. #include <stdlib.h>
  106. #include <unistd.h>
  107. #include <sys/types.h>
  108. #include <sys/socket.h>
  109. #include <netinet/in.h>
  110.  
  111. int read_from_client(int filedes) {
  112.     char buffer[32];
  113.     int nbytes;
  114.     struct sockaddr_in si_other;
  115.     socklen_t slen = sizeof(si_other);
  116.  
  117.     nbytes = read(filedes, &buffer, 32);
  118.  
  119.     if (nbytes < 0) {
  120.         fprintf(stderr, "tcp read failed\n");
  121.         exit(EXIT_FAILURE);
  122.     } else if (nbytes == 0) {
  123.         return -1;
  124.     }
  125.  
  126.     getsockname(filedes, (struct sockaddr *) &si_other, &slen);
  127.  
  128.     char filename[12];
  129.     sprintf(filename, "%d.txt", si_other.sin_port);
  130.     fprintf(stdout, "TCP: writing file %s\n", filename);
  131.  
  132.     FILE *file = fopen(filename, "a+");
  133.     fwrite(buffer, nbytes, 1, file);
  134.     fclose(file);
  135.  
  136.     return 0;
  137. }
  138.  
  139. int read_from_udp(int sock) {
  140.     char buffer[32];
  141.     int nbytes;
  142.  
  143.     struct sockaddr_in si_other;
  144.     socklen_t slen = sizeof(si_other);
  145.  
  146.     nbytes = recvfrom(sock, buffer, 32, 0, (struct sockaddr *) &si_other, &slen);
  147.  
  148.     if (nbytes < 0) {
  149.         fprintf(stderr, "udp read failed\n");
  150.         exit(EXIT_FAILURE);
  151.     } else if (nbytes == 0) {
  152.         return -1;
  153.     }
  154.  
  155.     char filename[12];
  156.     sprintf(filename, "%d.txt", si_other.sin_port);
  157.     fprintf(stdout, "UDP: writing file %s\n", filename);
  158.  
  159.     FILE *file = fopen(filename, "a+");
  160.     fwrite(buffer, nbytes, 1, file);
  161.     fclose(file);
  162.  
  163.     return 0;
  164. }
  165.  
  166. int build_socket(int *sock, struct sockaddr_in *addr, int udp) {
  167.     socklen_t addrlen = sizeof(*addr);
  168.  
  169.     if ((*sock = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) {
  170.         fprintf(stderr, "socket failed\n");
  171.         exit(EXIT_FAILURE);
  172.     }
  173.  
  174.     addr->sin_family = AF_INET;
  175.     addr->sin_addr.s_addr = INADDR_ANY;
  176.     addr->sin_port = 0;
  177.  
  178.     if (bind(*sock, (struct sockaddr *) addr, addrlen) < 0) {
  179.         fprintf(stderr, "bind failed\n");
  180.         exit(EXIT_FAILURE);
  181.     }
  182.     getsockname(*sock, (struct sockaddr *) addr, &addrlen);
  183.  
  184.     if (!udp && listen(*sock, 3) < 0) {
  185.         fprintf(stderr, "listen failed\n");
  186.         exit(EXIT_FAILURE);
  187.     }
  188.  
  189.     return addr->sin_port;
  190. }
  191.  
  192. int main(int argc, char **argv) {
  193.     int socktcp, sockudp;
  194.     struct sockaddr_in addrtcp, addrudp;
  195.     socklen_t addrtcplen = sizeof(addrtcp), addrudplen = sizeof(addrudp);
  196.     fd_set active_fd_set, read_fd_set;
  197.  
  198.     fprintf(stdout, "tcp port: %d\n", build_socket(&socktcp, &addrtcp, 0));
  199.     fprintf(stdout, "udp port: %d\n", build_socket(&sockudp, &addrudp, 1));
  200.  
  201.     FD_ZERO(&active_fd_set);
  202.     FD_SET(socktcp, &active_fd_set);
  203.     FD_SET(sockudp, &active_fd_set);
  204.  
  205.     while (socktcp) {
  206.         read_fd_set = active_fd_set;
  207.         if (select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) {
  208.             fprintf(stderr, "select failed\n");
  209.             exit(EXIT_FAILURE);
  210.         }
  211.  
  212.         for (int i = 0; i < FD_SETSIZE; i++) {
  213.             if (FD_ISSET (i, &read_fd_set)) {
  214.                 if (i == socktcp) {
  215.                     int new;
  216.                     new = accept(socktcp, (struct sockaddr *) &addrtcp, &addrtcplen);
  217.  
  218.                     if (new < 0) {
  219.                         fprintf(stderr, "accept failed\n");
  220.                         exit(EXIT_FAILURE);
  221.                     }
  222.  
  223.                     FD_SET (new, &active_fd_set);
  224.                 } else if (i == sockudp) {
  225.                     read_from_udp(sockudp);
  226.                 } else {
  227.                     if (read_from_client(i) < 0) {
  228.                         close(i);
  229.                         FD_CLR (i, &active_fd_set);
  230.                     }
  231.                 }
  232.             }
  233.         }
  234.     }
  235. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement