Advertisement
Guest User

Untitled

a guest
Apr 25th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.58 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
  277.             (sizeof(char) * 5);
  278.     if (toSend == NULL || toSend->info == NULL) return;
  279.     char *fileName = (char *) malloc(sizeof(char) * 256);
  280.     char *nameFile = (char *) malloc(sizeof(char) * 256);
  281.     scanf("%s", fileName);
  282.     char *retr = (char *) malloc(sizeof(char) * (4 + 1 + strlen(fileName) + 2));
  283.     sprintf(retr, RETR, fileName);
  284.     char type[] = "TYPE I\r\n"; //тип файла
  285.     send(toSend->sock, type, length(type) * sizeof(char), 0);
  286.     get_ans(buf, &bytes_read, toSend->sock, 1);
  287.     if (strncmp(buf, "200", 3) == 0) {
  288.         char pasv[] = "PASV\r\n";
  289.         send(toSend->sock, pasv, length(pasv) * sizeof(char), 0);
  290.         get_ans(buf, &bytes_read, toSend->sock, 1);
  291.         if (strncmp(buf, "227", 3) == 0)
  292.             if (buf[i] == '(') flag = 1;
  293.         if (isdigit(buf[i]) && flag == 1)
  294.             tempNumber = tempNumber * 10 + buf[i] - '0';
  295.         if (buf[i] == ',' || buf[i] == ')') {
  296.             mas[j++] = tempNumber;
  297.             tempNumber = 0;
  298.         }
  299.     }
  300.     sprintf(ipAdress_toRecive, "%d.%d.%d.%d", mas[0], mas[1], mas[2], mas[3]);
  301.     sprintf(port_toRecive, "%d", mas[4] * 256 + mas[5]);
  302.     toRecive = new_conn(port_toRecive, ipAdress_toRecive);
  303.     if (connect(toRecive->sock, toRecive->info->ai_addr, toRecive->info->ai_addrlen) < 0) {
  304.         perror("connect");
  305.         close_handler(2);
  306.     }
  307.     send(toSend->sock, retr, length(retr) * sizeof(char), 0);
  308.     get_ans(buf, &bytes_read, toSend->sock, 1);
  309.     int wasSend = 0;
  310.     if (strncmp(buf, "150", 3) == 0) {
  311.         sprintf(nameFile, "%s", basename(fileName));
  312.         get_file(toRecive, nameFile);
  313.         if ((wasSend = is_one_answer(buf, bytes_read / (sizeof(char)))) == 0) {
  314.             get_ans(buf + wasSend, &bytes_read, toSend->sock, 1);
  315.         }
  316.     }
  317.  
  318.     free(port_toRecive);
  319.     free(ipAdress_toRecive);
  320.     free(fileName);
  321.     free(nameFile);
  322.     free(retr);
  323. }
  324.  
  325. void put(conn_t *toSend) {//функция передачи файла на сервер
  326.     int i = 0;
  327.     int flag = 0;
  328.     int tempNumber = 0;
  329.     int mas[6] = {0, 0, 0, 0, 0, 0};
  330.     int j = 0;
  331.     char *ipAdress_toRecive = (char *) malloc(sizeof(char) * 15);
  332.     char *port_toRecive = (char *) malloc
  333.             (sizeof(char) * 5);
  334.     if (toSend == NULL || toSend->info == NULL) return;
  335.     char *fileName = (char *) malloc(sizeof(char) * 256);
  336.     char *nameFile = (char *) malloc(sizeof(char) * 256);
  337.     scanf("%s", fileName);
  338.     char *stor = (char *) malloc(sizeof(char) * (4 + 1 + strlen(fileName) + 2));
  339.     sprintf(stor, STOR, fileName);
  340.     char type[] = "TYPE I\r\n";//тип файла
  341.     send(toSend->sock, type, length(type) * sizeof(char), 0);
  342.     get_ans(buf, &bytes_read, toSend->sock, 1);
  343.     if (strncmp(buf, "200", 3) == 0) {
  344.         char pasv[] = "PASV\r\n";
  345.         send(toSend->sock, pasv, length(pasv) * sizeof(char), 0);
  346.         get_ans(buf, &bytes_read, toSend->sock, 1);
  347.         if (strncmp(buf, "227", 3) == 0) {
  348.             for (; i < length(buf); ++i) {
  349.                 if (buf[i] == '(') flag = 1;
  350.                 if (isdigit(buf[i]) && flag == 1)
  351.                     tempNumber = tempNumber * 10 + buf[i] - '0';
  352.                 if (buf[i] == ',' || buf[i] == ')') {
  353.                     mas[j++] = tempNumber;
  354.                     tempNumber = 0;
  355.                 }
  356.             }
  357.             sprintf(ipAdress_toRecive, "%d.%d.%d.%d", mas[0], mas[1], mas[2], mas[3]);
  358.             sprintf(port_toRecive, "%d", mas[4] * 256 + mas[5]);
  359.             toRecive = new_conn(port_toRecive, ipAdress_toRecive);
  360.             if (connect(toRecive->sock, toRecive->info->ai_addr, toRecive->info->ai_addrlen) < 0) {
  361.                 perror("connect");
  362.                 close_handler(2);
  363.             }
  364.             send(toSend->sock, stor, length(stor) * sizeof(char), 0);
  365.             get_ans(buf, &bytes_read, toSend->sock, 1);
  366.             int wasSend = 0;
  367.             if (strncmp(buf, "150", 3) == 0) {
  368.                 if ((wasSend = is_one_answer(buf, bytes_read / (sizeof(char)))) == 0) {
  369.                     get_ans(buf + wasSend,
  370.                             &bytes_read, toSend->sock, 1);
  371.                 }
  372.             }
  373.         }
  374.     }
  375.     free(port_toRecive);
  376.     free(ipAdress_toRecive);
  377.     free(fileName);
  378.     free(nameFile);
  379.     free(stor);
  380. }
  381.  
  382. void pwd(conn_t *toSend) {//возвращает текущую директорию
  383.     if (!toSend || !toSend->info)
  384.         return;
  385.  
  386.     static char pwd[6];
  387.     snprintf(pwd, 6, PWD);
  388.     send(toSend->sock, pwd, 5, 0);
  389.     get_ans(buf, &bytes_read, toSend->sock, 1);
  390. }
  391.  
  392. void quit(conn_t *toSend) {
  393.     printf("Bye-bye\n");
  394.     close(toSend->sock);
  395.     freeaddrinfo(toSend->info);
  396. }
  397.  
  398. void main_loop() {
  399.     conn_t toSend;
  400.     command_t masOfCommands[] = {quit, open_, get, put, pwd, help, ls};
  401.     int commandNum;
  402.     do {
  403.         commandNum = get_command();
  404.         if (commandNum > -1)
  405.             masOfCommands[commandNum](&toSend);
  406.     } while (commandNum != 0);
  407. }
  408.  
  409. void set_ip(char *ip) {
  410.     struct ifaddrs *ifaddr, *ifa;
  411.     int family, s;
  412.     char host[NI_MAXHOST];
  413.     if (getifaddrs(&ifaddr) == -1) {
  414.         perror("getifaddrs");
  415.         exit(EXIT_FAILURE);
  416.     }
  417.     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
  418.         family = ifa->ifa_addr->sa_family;
  419.         if (family == AF_INET) {
  420.             s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0,
  421.                             NI_NUMERICHOST);
  422.             if (s != 0) {
  423.                 close_handler(-4);
  424.                 printf("getnameinfo() failed: %s\n", gai_strerror(s));
  425.             }
  426.             if (strcmp(ifa->ifa_name, "lo") != 0) {
  427.                 sprintf(ip, "%s", host);
  428.                 return;
  429.             }
  430.         }
  431.     }
  432. }
  433.  
  434. int main(int argc, char *argv[]) {
  435.     set_ip(my_ip);
  436.     signal(SIGINT, (sighandler) close_handler);
  437.     main_loop();
  438.     return 0;
  439. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement