Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <string.h>
- #include <argp.h>
- #include <unistd.h>
- #include <regex.h>
- #define ADDR_REGEX "\\(udp\\|tcp\\)://\\([0-9]\\+.[0-9]\\+.[0-9]\\+.[0-9]\\+\\):\\([0-9]\\+\\)"
- char *ip_arg, *file_arg;
- struct argp_option options[] = {{0}};
- static int parse_opt(int key, char *arg, struct argp_state *state) {
- int *arg_count = state->input;
- switch (key) {
- case ARGP_KEY_ARG:
- switch (*arg_count) {
- case 2:
- ip_arg = arg;
- break;
- case 1:
- file_arg = arg;
- break;
- }
- (*arg_count)--;
- break;
- case ARGP_KEY_END:
- printf("\n");
- if (*arg_count > 0)
- argp_failure(state, 1, 0, "not enough arguments");
- else if (*arg_count < 0)
- argp_failure(state, 1, 0, "too many arguments");
- break;
- }
- return 0;
- }
- int main(int argc, char **argv) {
- int sockfd, arg_count = 2;
- struct sockaddr_in serv_addr;
- char srv_proto[4] = {0}, srv_ip[24] = {0}, srv_port[8] = {0};
- struct argp argp = {options, parse_opt, "PROTOCOL://IP:PORT FILE"};
- argp_parse(&argp, argc, argv, 0, 0, &arg_count);
- regex_t *regex = (regex_t *) malloc(sizeof(regex_t));
- if (regcomp(regex, ADDR_REGEX, 0) != 0) {
- fprintf(stderr, "regcomp failed\n");
- exit(EXIT_FAILURE);
- }
- regmatch_t *regmatches = (regmatch_t *) malloc(4 * sizeof(regmatch_t));
- if (regexec(regex, ip_arg, 4, regmatches, REG_EXTENDED) != 0) {
- fprintf(stderr, "failed to parse ip\n");
- exit(EXIT_FAILURE);
- }
- strncpy(srv_proto, ip_arg + regmatches[1].rm_so, regmatches[1].rm_eo - regmatches[1].rm_so);
- strncpy(srv_ip, ip_arg + regmatches[2].rm_so, regmatches[2].rm_eo - regmatches[2].rm_so);
- strncpy(srv_port, ip_arg + regmatches[3].rm_so, regmatches[3].rm_eo - regmatches[3].rm_so);
- if ((sockfd = socket(AF_INET, (strcmp(srv_proto, "tcp") == 0) ? SOCK_STREAM : SOCK_DGRAM, 0)) < 0) {
- fprintf(stderr, "socket failed\n");
- exit(EXIT_FAILURE);
- }
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = strtol(srv_port, NULL, 10);
- if (inet_pton(AF_INET, srv_ip, &serv_addr.sin_addr) <= 0) {
- fprintf(stderr, "pton failed\n");
- exit(EXIT_FAILURE);
- }
- if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) {
- fprintf(stderr, "connect failed\n");
- exit(EXIT_FAILURE);
- }
- FILE *file = fopen(file_arg, "r");
- while (!feof(file)) {
- char fbuf[32] = {0};
- int nbytes = fread(fbuf, 1, 32, file);
- send(sockfd, fbuf, nbytes, 0);
- }
- fclose(file);
- return 0;
- }
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- int read_from_client(int filedes) {
- char buffer[32];
- int nbytes;
- struct sockaddr_in si_other;
- socklen_t slen = sizeof(si_other);
- nbytes = read(filedes, &buffer, 32);
- if (nbytes < 0) {
- fprintf(stderr, "tcp read failed\n");
- exit(EXIT_FAILURE);
- } else if (nbytes == 0) {
- return -1;
- }
- getsockname(filedes, (struct sockaddr *) &si_other, &slen);
- char filename[12];
- sprintf(filename, "%d.txt", si_other.sin_port);
- fprintf(stdout, "TCP: writing file %s\n", filename);
- FILE *file = fopen(filename, "a+");
- fwrite(buffer, nbytes, 1, file);
- fclose(file);
- return 0;
- }
- int read_from_udp(int sock) {
- char buffer[32];
- int nbytes;
- struct sockaddr_in si_other;
- socklen_t slen = sizeof(si_other);
- nbytes = recvfrom(sock, buffer, 32, 0, (struct sockaddr *) &si_other, &slen);
- if (nbytes < 0) {
- fprintf(stderr, "udp read failed\n");
- exit(EXIT_FAILURE);
- } else if (nbytes == 0) {
- return -1;
- }
- char filename[12];
- sprintf(filename, "%d.txt", si_other.sin_port);
- fprintf(stdout, "UDP: writing file %s\n", filename);
- FILE *file = fopen(filename, "a+");
- fwrite(buffer, nbytes, 1, file);
- fclose(file);
- return 0;
- }
- int build_socket(int *sock, struct sockaddr_in *addr, int udp) {
- socklen_t addrlen = sizeof(*addr);
- if ((*sock = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) {
- fprintf(stderr, "socket failed\n");
- exit(EXIT_FAILURE);
- }
- addr->sin_family = AF_INET;
- addr->sin_addr.s_addr = INADDR_ANY;
- addr->sin_port = 0;
- if (bind(*sock, (struct sockaddr *) addr, addrlen) < 0) {
- fprintf(stderr, "bind failed\n");
- exit(EXIT_FAILURE);
- }
- getsockname(*sock, (struct sockaddr *) addr, &addrlen);
- if (!udp && listen(*sock, 3) < 0) {
- fprintf(stderr, "listen failed\n");
- exit(EXIT_FAILURE);
- }
- return addr->sin_port;
- }
- int main(int argc, char **argv) {
- int socktcp, sockudp;
- struct sockaddr_in addrtcp, addrudp;
- socklen_t addrtcplen = sizeof(addrtcp), addrudplen = sizeof(addrudp);
- fd_set active_fd_set, read_fd_set;
- fprintf(stdout, "tcp port: %d\n", build_socket(&socktcp, &addrtcp, 0));
- fprintf(stdout, "udp port: %d\n", build_socket(&sockudp, &addrudp, 1));
- FD_ZERO(&active_fd_set);
- FD_SET(socktcp, &active_fd_set);
- FD_SET(sockudp, &active_fd_set);
- while (socktcp) {
- read_fd_set = active_fd_set;
- if (select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) {
- fprintf(stderr, "select failed\n");
- exit(EXIT_FAILURE);
- }
- for (int i = 0; i < FD_SETSIZE; i++) {
- if (FD_ISSET (i, &read_fd_set)) {
- if (i == socktcp) {
- int new;
- new = accept(socktcp, (struct sockaddr *) &addrtcp, &addrtcplen);
- if (new < 0) {
- fprintf(stderr, "accept failed\n");
- exit(EXIT_FAILURE);
- }
- FD_SET (new, &active_fd_set);
- } else if (i == sockudp) {
- read_from_udp(sockudp);
- } else {
- if (read_from_client(i) < 0) {
- close(i);
- FD_CLR (i, &active_fd_set);
- }
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement