Advertisement
Guest User

Untitled

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