Advertisement
Guest User

Untitled

a guest
Apr 24th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.54 KB | None | 0 0
  1. #include <fcntl.h>
  2. #include <arpa/inet.h>
  3. #include <signal.h>
  4. #include <sys/stat.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <unistd.h>
  8. #include <string.h>
  9. #include <netdb.h>
  10. #include <ifaddrs.h>
  11. #include <ctype.h>
  12.  
  13. #define MAX_COMMAND_SIZE 4 //макимальный размер команды
  14. #define USER "USER %s\r\n" //имя пользователя
  15. #define PASS "PASS %s\r\n" //пароль
  16. #define PWD "PWD\r\n"
  17. #define RETR "RETR %s\r\n" //RETR — Скачать файл. Перед RETR должна быть команда PASV или PORT.
  18. #define LIST "LIST %s\r\n" // LIST Возвращает список файлов директории.
  19. #define STOR "STOR %s\r\n" // Закачать файл. Перед STOR должна быть команда PASV или PORT.
  20.  
  21. static char buf[1024];
  22. static int bytes_read;
  23. static char my_ip[23];
  24.  
  25. typedef void (*sighandler)(int);
  26.  
  27. typedef struct {
  28.     int sock;
  29.     struct addrinfo *info;
  30. }  conn_t;
  31.  
  32. typedef void (*command_t) (conn_t *);
  33.  
  34. conn_t* toListen = NULL, *toRecive = NULL;
  35.  
  36.  
  37.  
  38. void to_default(conn_t *connection)
  39. {
  40.     if (connection) {
  41.         connection->sock = -1;
  42.         connection->info = NULL;
  43.     }
  44. }
  45.  
  46. int is_one_answer(const char *buf, int len)
  47. {
  48.     int i = 0;
  49.     while(i < len && !(buf[i - 1] == '\r' && buf[i] == '\n')) ++i;
  50.     if (i + 2 == len) return 0;
  51.     if (i + 1 == len) return 0;
  52.     return i + 1;
  53. }
  54.  
  55. void close_handler(int c) { //экстренное завершение соединения из-за возникшей ошибки
  56.     if (toListen && toListen->sock >= 0)
  57.         close(toListen->sock);
  58.  
  59.     printf("Interupting programm. Closing connection.\n");
  60.     exit(c);
  61. }
  62.  
  63. conn_t *new_conn(const char *port, const char *ipAdress)
  64. {
  65.     conn_t *conn = (conn_t *) malloc(sizeof(conn_t));
  66.     to_default(conn);
  67.     int status;
  68.     addrinfo hints;
  69.     memset(&hints, 0, sizeof hints);
  70.     hints.ai_family = AF_INET; //AF_UNSPEC; hints.ai_socktype = SOCK_STREAM;
  71.     if (ipAdress == NULL) hints.ai_flags = AI_PASSIVE;
  72.     printf("connection port:%s\n", port);
  73.     status = getaddrinfo(ipAdress, port, &hints, &(conn->info));
  74.  
  75.     conn->sock = socket(conn->info->ai_family, conn->info->ai_socktype,
  76.                                  conn->info->ai_protocol); // установка сокета
  77.     if (conn->sock < 0) {
  78.         perror("socket");
  79.         close_handler(1);
  80.     }
  81.     return conn;
  82. }
  83.  
  84. int get_list(conn_t *connection) {
  85.     char buf[1024];
  86.     int bytes_read;
  87.     while (1) {
  88.         bytes_read = recv(connection->sock, buf, 1024, 0);
  89.         if (bytes_read <= 0) {
  90.             break;
  91.         }
  92.         write(1, buf, bytes_read);
  93.     }
  94.     close(connection->sock);
  95.     freeaddrinfo(connection->info);
  96.     free(connection);
  97.     return 0;
  98. }
  99.  
  100. int get_file(conn_t *connection, char *fileName) {
  101.     int fileNameDescriptor = open(fileName, O_WRONLY | O_TRUNC | O_CREAT, 0664);
  102.     printf("%s\n", fileName);
  103.     char buf_here[1024];
  104.     int bytes_read_here = 0;
  105.     while ((bytes_read_here = recv(connection->sock, buf_here, 1000, 0)) > 0) {
  106.         write(fileNameDescriptor,
  107.               buf_here, bytes_read_here);
  108.     }
  109.     close(fileNameDescriptor);
  110.     close(connection->sock);
  111.     freeaddrinfo(connection->info);
  112.     free(connection);
  113.     return 0;
  114. }
  115.  
  116. int get_command() {
  117.     static char command[MAX_COMMAND_SIZE];
  118.     int commandNum = -1;
  119.     printf("ftp> ");
  120.     scanf("%s", command);
  121.     if (strcmp(command, "open") == 0) {
  122.         commandNum = 1;
  123.     }
  124.     if (strcmp(command, "get") == 0) {
  125.         commandNum = 2;
  126.     }
  127.     if (strcmp(command, "put") == 0) {
  128.         commandNum = 3;
  129.     }
  130.     if (strcmp(command, "pwd") == 0) {
  131.         commandNum = 4;
  132.     }
  133.     if (strcmp(command, "help") == 0) {
  134.         commandNum = 5;
  135.     }
  136.     if (strcmp(command, "ls") == 0) {
  137.         commandNum = 6;
  138.     }
  139.     if (strcmp(command, "quit") == 0) {
  140.         commandNum = 0;
  141.     }
  142.     return commandNum;
  143. }
  144.  
  145. int length(const char *str) {
  146.     int count = 0;
  147.     while (str[count++] != '\n');
  148.     return count;
  149. }
  150.  
  151. void get_ans(char *buf, int *bytes_read, int sock, int fileDescriptor) {
  152.     *bytes_read = (int)recv(sock, buf, 1024, 0);
  153.     buf[(*bytes_read)++] = '\n';
  154.     if (fileDescriptor > -1)
  155.         write(fileDescriptor, buf, *bytes_read);
  156. }
  157.  
  158. void help(conn_t*) {
  159.     printf("open - open connection\n");
  160.     printf("pwd\n");
  161.     printf("get - get file\n");
  162.     printf("put - put file\n");
  163.     printf("quit\n");
  164.     printf("help - help\n");
  165.     printf("ls - list directory\n");
  166. }
  167.  
  168. void open(conn_t *toSend) { // открытие соединения
  169.     static char ip_addr[15];
  170.  
  171.     do {
  172.         scanf("%s", ip_addr);
  173.     } while (strlen(ip_addr) == 0);
  174.  
  175.     *toSend = *(new_conn("21", ip_addr));
  176.     if (connect(toSend->sock, toSend->info->ai_addr, toSend->info->ai_addrlen) < 0) {
  177.         perror("connect");
  178.         close_handler(2);
  179.     }
  180.  
  181.     get_ans(buf, &bytes_read, toSend->sock, 1);
  182.  
  183.     if (strncmp(buf, "220", 3) != 0)
  184.         to_default(toSend);
  185.     else {
  186.         printf("Write your login: ");
  187.         char *username = (char *) malloc(sizeof(char) * 256);
  188.         scanf("%s", username);
  189.         char *user = (char *) malloc(sizeof(char) * (4 + 1 + strlen(username) + 2));
  190.         sprintf(user, USER, username);
  191.         free(username);
  192.         send(toSend->sock, user, length(user) * sizeof(char), 0);
  193.         get_ans(buf, &bytes_read, toSend->sock, 1);
  194.         free(user);
  195.         if (strncmp(buf, "331", 3) != 0)
  196.             to_default(toSend);
  197.         else {
  198.             printf("Write your password: ");
  199.             char *password = (char *) malloc(sizeof(char) * 256);
  200.             scanf("%s", password);
  201.             char *pass = (char *) malloc(sizeof(char) * (4 + 1 + strlen(password) + 2));
  202.             sprintf(pass, PASS, password);
  203.             free(password);
  204.             send(toSend->sock, pass, length(pass) * sizeof(char), 0);
  205.             free(pass);
  206.             get_ans(buf, &bytes_read, toSend->sock, 1);
  207.             if (strncmp(buf, "230", 3) != 0) to_default(toSend);
  208.         }
  209.     }
  210. }
  211.  
  212. void ls(conn_t *toSend) {//функция,которая выдает файлы из текущей директории
  213.     int i = 0;
  214.     int flag = 0;
  215.     int tempNumber = 0;
  216.     int mas[6] = {0, 0, 0, 0, 0, 0};
  217.     int j = 0;
  218.     char *ipAdress_toRecive = (char *) malloc(sizeof(char) * 15);
  219.     char *port_toRecive = (char *) malloc
  220.             (sizeof(char) * 5);
  221.     if (toSend == NULL || toSend->info == NULL) return;
  222.     char *dir = (char *) malloc(sizeof(char) * 15);
  223.     scanf("%s", dir);
  224.     char *list = (char *) malloc(sizeof(char) * (4 + 2));
  225.     sprintf(list, LIST, dir);
  226.     char type[] = "TYPE I\r\n";
  227.     send(toSend->sock, type, length(type) * sizeof(char), 0);
  228.     get_ans(buf, &bytes_read, toSend->sock, 1);
  229.     if (strncmp(buf, "200", 3) == 0) {
  230.         char pasv[] = "PASV\r\n";
  231.         send(toSend->sock, pasv, length(pasv) * sizeof(char), 0);
  232.         get_ans(buf, &bytes_read, toSend->sock, 1);
  233.         if (strncmp(buf, "227", 3) == 0) {
  234.             for (; i < length(buf); ++i) {
  235.                 if (buf[i] == '(') flag = 1;
  236.                 if (isdigit(buf[i]) && flag == 1)
  237.                     tempNumber = tempNumber * 10 + buf[i] - '0';
  238.                 if (buf[i] == ',' || buf[i] == ')') {
  239.                     mas[j++] = tempNumber;
  240.                     tempNumber = 0;
  241.                 }
  242.             }
  243.             sprintf(ipAdress_toRecive, "%d.%d.%d.%d", mas[0], mas[1], mas[2], mas[3]);
  244.             sprintf(port_toRecive, "%d", mas[4] * 256 + mas[5]);
  245.             toRecive = new_conn(port_toRecive, ipAdress_toRecive);
  246.             if (connect(toRecive->sock, toRecive->info->ai_addr,
  247.                         toRecive->info->ai_addrlen) < 0) {
  248.                 perror("connect");
  249.                 close_handler(2);
  250.             }
  251.             send(toSend->sock, list, length(list) * sizeof(char), 0);
  252.             get_ans(buf, &bytes_read, toSend->sock, 1);
  253.             int wasSend = 0;
  254.             if (strncmp(buf, "150", 3) == 0) {
  255.                 get_list(toRecive);
  256.                 if ((wasSend = is_one_answer(buf, bytes_read / (sizeof(char)))) == 0) {
  257.                     get_ans(buf + wasSend, &bytes_read, toSend->sock, 1);
  258.                 }
  259.             }
  260.         }
  261.     }
  262.     free(port_toRecive);
  263.     free(ipAdress_toRecive);
  264.     free(list);
  265.     free(dir);
  266. }
  267.  
  268. void get(conn_t *toSend) {//получение файла с сервера
  269.     int i = 0;
  270.     int flag = 0;
  271.     int tempNumber = 0;
  272.     int mas[6] = {0, 0, 0, 0, 0, 0};
  273.     int j = 0;
  274.     char *ipAdress_toRecive = (char *) malloc(sizeof(char) * 15);
  275.     char *port_toRecive = (char *) malloc
  276.             (sizeof(char) * 5);
  277.     if (toSend == NULL || toSend->info == NULL) return;
  278.     char *fileName = (char *) malloc(sizeof(char) * 256);
  279.     char *nameFile = (char *) malloc(sizeof(char) * 256);
  280.     scanf("%s", fileName);
  281.     char *retr = (char *) malloc(sizeof(char) * (4 + 1 + strlen(fileName) + 2));
  282.     sprintf(retr, RETR, fileName);
  283.     char type[] = "TYPE I\r\n"; //тип файла
  284.     send(toSend->sock, type, length(type) * sizeof(char), 0);
  285.     get_ans(buf, &bytes_read, toSend->sock, 1);
  286.     if (strncmp(buf, "200", 3) == 0) {
  287.         char pasv[] = "PASV\r\n";
  288.         send(toSend->sock, pasv, length(pasv) * sizeof(char), 0);
  289.         get_ans(buf, &bytes_read, toSend->sock, 1);
  290.         if (strncmp(buf, "227", 3) == 0)
  291.             if (buf[i] == '(') flag = 1;
  292.         if (isdigit(buf[i]) && flag == 1)
  293.             tempNumber = tempNumber * 10 + buf[i] - '0';
  294.         if (buf[i] == ',' || buf[i] == ')') {
  295.             mas[j++] = tempNumber;
  296.             tempNumber = 0;
  297.         }
  298.     }
  299.     sprintf(ipAdress_toRecive, "%d.%d.%d.%d", mas[0], mas[1], mas[2], mas[3]);
  300.     sprintf(port_toRecive, "%d", mas[4] * 256 + mas[5]);
  301.     toRecive = new_conn(port_toRecive, ipAdress_toRecive);
  302.     if (connect(toRecive->sock, toRecive->info->ai_addr, toRecive->info->ai_addrlen) < 0) {
  303.         perror("connect");
  304.         close_handler(2);
  305.     }
  306.     send(toSend->sock, retr, length(retr) * sizeof(char), 0);
  307.     get_ans(buf, &bytes_read, toSend->sock, 1);
  308.     int wasSend = 0;
  309.     if (strncmp(buf, "150", 3) == 0) {
  310.         sprintf(nameFile, "%s", basename(fileName));
  311.         get_file(toRecive, nameFile);
  312.         if ((wasSend = is_one_answer(buf, bytes_read / (sizeof(char)))) == 0) {
  313.             get_ans(buf + wasSend, &bytes_read, toSend->sock, 1);
  314.         }
  315.     }
  316.  
  317.     free(port_toRecive);
  318.     free(ipAdress_toRecive);
  319.     free(fileName);
  320.     free(nameFile);
  321.     free(retr);
  322. }
  323.  
  324. void put(conn_t *toSend) {//функция передачи файла на сервер
  325.     int i = 0;
  326.     int flag = 0;
  327.     int tempNumber = 0;
  328.     int mas[6] = {0, 0, 0, 0, 0, 0};
  329.     int j = 0;
  330.     char *ipAdress_toRecive = (char *) malloc(sizeof(char) * 15);
  331.     char *port_toRecive = (char *) malloc
  332.             (sizeof(char) * 5);
  333.     if (toSend == NULL || toSend->info == NULL) return;
  334.     char *fileName = (char *) malloc(sizeof(char) * 256);
  335.     char *nameFile = (char *) malloc(sizeof(char) * 256);
  336.     scanf("%s", fileName);
  337.     char *stor = (char *) malloc(sizeof(char) * (4 + 1 + strlen(fileName) + 2));
  338.     sprintf(stor, STOR, fileName);
  339.     char type[] = "TYPE I\r\n";//тип файла
  340.     send(toSend->sock, type, length(type) * sizeof(char), 0);
  341.     get_ans(buf, &bytes_read, toSend->sock, 1);
  342.     if (strncmp(buf, "200", 3) == 0) {
  343.         char pasv[] = "PASV\r\n";
  344.         send(toSend->sock, pasv, length(pasv) * sizeof(char), 0);
  345.         get_ans(buf, &bytes_read, toSend->sock, 1);
  346.         if (strncmp(buf, "227", 3) == 0) {
  347.             for (; i < length(buf); ++i) {
  348.                 if (buf[i] == '(') flag = 1;
  349.                 if (isdigit(buf[i]) && flag == 1)
  350.                     tempNumber = tempNumber * 10 + buf[i] - '0';
  351.                 if (buf[i] == ',' || buf[i] == ')') {
  352.                     mas[j++] = tempNumber;
  353.                     tempNumber = 0;
  354.                 }
  355.             }
  356.             sprintf(ipAdress_toRecive, "%d.%d.%d.%d", mas[0], mas[1], mas[2], mas[3]);
  357.             sprintf(port_toRecive, "%d", mas[4] * 256 + mas[5]);
  358.             toRecive = new_conn(port_toRecive, ipAdress_toRecive);
  359.             if (connect(toRecive->sock, toRecive->info->ai_addr, toRecive->info->ai_addrlen) < 0) {
  360.                 perror("connect");
  361.                 close_handler(2);
  362.             }
  363.             send(toSend->sock, stor, length(stor) * sizeof(char), 0);
  364.             get_ans(buf, &bytes_read, toSend->sock, 1);
  365.             int wasSend = 0;
  366.             if (strncmp(buf, "150", 3) == 0) {
  367.                 if ((wasSend = is_one_answer(buf, bytes_read / (sizeof(char)))) == 0) {
  368.                     get_ans(buf + wasSend,
  369.                             &bytes_read, toSend->sock, 1);
  370.                 }
  371.             }
  372.         }
  373.     }
  374.     free(port_toRecive);
  375.     free(ipAdress_toRecive);
  376.     free(fileName);
  377.     free(nameFile);
  378.     free(stor);
  379. }
  380.  
  381. void pwd(conn_t *toSend) {//возвращает текущую директорию
  382.     if (!toSend || !toSend->info)
  383.         return;
  384.  
  385.     static char pwd[6];
  386.     snprintf(pwd, 6, PWD);
  387.     send(toSend->sock, pwd, 5, 0);
  388.     get_ans(buf, &bytes_read, toSend->sock, 1);
  389. }
  390.  
  391. void quit(conn_t *toSend) {
  392.     printf("Bye-bye\n");
  393.     close(toSend->sock);
  394.     freeaddrinfo(toSend->info);
  395. }
  396.  
  397. void main_loop() {
  398.     conn_t toSend;
  399.     command_t masOfCommands[] = {quit, open, get, put, pwd, help, ls};
  400.     int commandNum;
  401.     do {
  402.         commandNum = get_command();
  403.         if (commandNum > -1)
  404.             masOfCommands[commandNum](&toSend);
  405.     } while (commandNum != 0);
  406. }
  407.  
  408. void set_ip(char *ip) {
  409.     struct ifaddrs *ifaddr, *ifa;
  410.     int family, s;
  411.     char host[NI_MAXHOST];
  412.     if (getifaddrs(&ifaddr) == -1) {
  413.         perror("getifaddrs");
  414.         exit(EXIT_FAILURE);
  415.     }
  416.     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
  417.         family = ifa->ifa_addr->sa_family;
  418.         if (family == AF_INET) {
  419.             s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0,
  420.                             NI_NUMERICHOST);
  421.             if (s != 0) {
  422.                 close_handler(-4);
  423.                 printf("getnameinfo() failed: %s\n", gai_strerror(s));
  424.             }
  425.             if (strcmp(ifa->ifa_name, "lo") != 0) {
  426.                 sprintf(ip, "%s", host);
  427.                 return;
  428.             }
  429.         }
  430.     }
  431. }
  432.  
  433. int main(int argc, char *argv[]) {
  434.     set_ip(my_ip);
  435.     signal(SIGINT, (sighandler) close_handler);
  436.     main_loop();
  437.     return 0;
  438. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement