Advertisement
Guest User

Untitled

a guest
May 15th, 2017
562
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.14 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <netinet/in.h>
  3. #include <arpa/inet.h>
  4. #include <sys/socket.h>
  5. #include <resolv.h>
  6. #include <sys/types.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <ctype.h>
  10. #include <string.h>
  11. #include <sys/stat.h>
  12. #include <fcntl.h>
  13.  
  14. #define MODO_PASIVO 227
  15. #define PUERTO_DEFAULT 21
  16. //Respuestas del servidor
  17. #define SALIR 221
  18. #define ESPERA_USUARIO 220
  19. #define ESPERA_PASSWORD 331
  20. #define NO_INGRESADO 530
  21. #define MAL_SECUENCIA 503
  22. #define INGRESO_CORRECTO 230
  23. #define ABRIENDO_DC 150
  24. #define DC_ABIERTO 150
  25. #define CERRANDO_DC 226
  26. #define OPERACION_COMPLETA 250
  27.  
  28. int socketControl;
  29. char server_reply[BUFSIZ], mensaje_cliente [BUFSIZ],auxiliar[BUFSIZ];
  30. int respuestaServidorEntero;
  31. struct sockaddr_in server;
  32. void cd(char *rep);
  33. void list();
  34. void user();
  35. void pwd();
  36. int recv_file(char *file);
  37. int socketPasivo();
  38.  
  39. //--------Convertir todos los caracteres de un string en MAYUS
  40. void convertirAMayusculas(char * string) {
  41.   // Convert to upper case
  42.   char *s = string;
  43.   while (*s) {
  44.     *s = toupper((unsigned char) *s);
  45.     s++;
  46.   }
  47.  
  48. }
  49.  
  50. //---------VALIDACION NUMERO------------
  51. int esPuertoValido(char * string){
  52.     int devolver = string[0] == ':'; //Todo puerto valido tiene que empezar con ':' y luego ser un numero.
  53.     int i;
  54.     int longitud = strlen (string);
  55.     for (i=1;i<longitud && devolver!= 0; i++)
  56.         if (!isdigit(string[i])){
  57.             devolver = 0;
  58.         }
  59.     return devolver;
  60. }
  61.  
  62. void mostrarAyuda(){
  63.     printf("QUIT: Finaliza la ejecución del cliente.\n");
  64.     printf("OPEN: <Servidor> [Puerto]. Realiza una conexion con el servidor y el puerto, en caso de ser especificado el mismo.\n");
  65.     printf("USER: Especifica el usuario bajo la cual se desea acceder al servidor.\n");
  66.     printf("PASS: Contraseña para identificarse con el usuario.\n");
  67.     printf("PWD: Muestra el directorio actual.\n");
  68.     printf("CD: Cambio de directorio.\n");
  69.     printf("LIST: Listado de archivos en directorio actual.\n");
  70.     printf("PUT: Envío de archivo al servidor.\n");
  71.     printf("GET: Recepción del archivo indicado como argumento\n");
  72.     printf("PASSIVE: Modo de transferencia pasivo\n");
  73.     printf("ACTIVE: Modo de transferencia activo \n");
  74. }
  75.  
  76. int main(int argc, char** argv)
  77. {
  78.     //Validacion parametros de consola
  79.     if(argc > 4){
  80.         printf("Parametros incorrectos, [Servidor [:Puerto]] [-h] \n");
  81.         exit(1);
  82.     }
  83.     int i;
  84.     char * nombreServidor;
  85.     int puertoServidor = PUERTO_DEFAULT;
  86.  
  87.     for(i=0; i < argc; i++){
  88.         if(strcmp(argv[i],"-h") == 0){
  89.             mostrarAyuda();
  90.             exit(1);
  91.         }
  92.         if(i == 1){
  93.             nombreServidor = argv[i];
  94.         }
  95.         if(i == 2){
  96.             if(esPuertoValido(argv[i]))
  97.                 puertoServidor = atoi(argv[i]+1);
  98.             else{
  99.                 printf("Puerto invalido \n");
  100.                 exit(1);
  101.             }
  102.         }
  103.         if(i == 3){ //no es -h
  104.             printf("Paremetros incorrectos \n");
  105.             exit(1);
  106.         }
  107.     }
  108.     //Declaracion de variables
  109.     printf("\n Bienvenidos al cliente FTP!"); //mensaje bienvenida... duh
  110.     //Creacion del socket
  111.  
  112.     if ((socketControl = socket(AF_INET, SOCK_STREAM, 0)) < 0){
  113.         printf("\nError al crear socket..");
  114.         exit(1);
  115.     }
  116.     printf("\nSocket creado correctamente");
  117.     bzero(&server,sizeof(server));                  //FALTA IMPLEMENTAR EL OPEN !!!!
  118. //    inet_aton("114.30.44.99", &server.sin_addr);      //Setea el IP del servidor
  119.     server.sin_family = AF_INET;                     //PROTOCOLO DE LA FAMILIA
  120.     server.sin_port = htons(puertoServidor);        //PUERTO DEL SERVIDOR
  121.     while(1){ // WHILE ESPERANDO PARA HACER OPEN o QUIT o HELP
  122.         //Conexion al servidor
  123.         memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char)); //LIMPIO COSAS VIEJAS
  124.         memset(auxiliar, '\0', BUFSIZ*sizeof(char));
  125.         printf("\nftp> ");
  126.         scanf("%s", mensaje_cliente);
  127.         convertirAMayusculas(mensaje_cliente);// LO CONVIERTE TODO EN MAYUSUCULAS -> EN NO CASE SENSITIVE
  128.  
  129.        // strcat(mensaje_cliente, "OPEN");
  130.         if(strcmp(mensaje_cliente, "QUIT") == 0){
  131.             printf("\Cerrando cliente ftp.");
  132.             exit(0);
  133.         }
  134.         else{
  135.             if(strcmp(mensaje_cliente, "HELP") == 0){
  136.                 mostrarAyuda();
  137.             }
  138.             else{
  139.                 if(strcmp(mensaje_cliente, "OPEN") != 0){
  140.                     printf("\n Comando invalido, utilice OPEN, QUIT o HELP.");
  141.                 }
  142.                 else{
  143.                     if(strcmp(mensaje_cliente, "OPEN") == 0){
  144.                         printf("\nIngrese la direccion del servidor: ");
  145.                         scanf("%s", auxiliar);
  146.                         // strcat(auxiliar, "114.30.44.99");
  147.                         nombreServidor = auxiliar;
  148.                         //printf("\nHOLA ->>>%i", strcmp(nombreServidor,"114.30.44.99") == 0);
  149.                         inet_aton(nombreServidor, &server.sin_addr);
  150.                         if (connect(socketControl , (struct sockaddr *)&server , sizeof(server)) < 0){
  151.                             perror("\nError en la conexion, servidor no disponible. Intente nuevamente ");
  152.                         }
  153.                         else{
  154.                             printf("\nConectado correctamente");
  155.                             while(1){ //WHILE UNA VEZ REALIZADA LA CONEXION TCP
  156.                                 printf("MENSAJE : %s  \n",mensaje_cliente);
  157.                                 memset(server_reply, '\0', BUFSIZ*sizeof(char));
  158.                                 if( recv(socketControl , server_reply , sizeof(server_reply) , 0) < 0)
  159.                                     printf("\nError al recibir respuesta del servidor.");
  160.                                 printf("%s",server_reply);
  161.                                 respuestaServidorEntero = atoi(strtok(server_reply," ")) ; //Tomo la primer palabra de la respuesta (Que es el codigo establecido
  162.                                                                                             //en el RFC) y la paso a entero para poder usar el switch y que el codigo este mas bonito :)
  163.                                // printf("\n RESPUESTA --> %i", respuestaServidorEntero);
  164.                                // printf("\n RESPUESTA --> %i", respuestaServidorEntero == 221);
  165.                                 switch(respuestaServidorEntero){
  166.                                     case SALIR: // despues del QUIT
  167.                                         printf("\nCerrando cliente ftp.");
  168.                                         exit(0);
  169.                                         break;
  170.                                     case ESPERA_PASSWORD:
  171.                                         //printf("\nPassword requerido: ");
  172.                                         memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char)); //LIMPIO COSAS VIEJAS
  173.                                         strcat(mensaje_cliente,"PASS ");
  174.                                         char * password;
  175.                                         password = getpass("Password requerido: "); //ESCONDE LO QUE ESCRIBIS EN PANTALLA
  176.                                         printf("%s", password);
  177.                                         strcat(mensaje_cliente,password);
  178.                                         free(password);
  179.                                         strcat(mensaje_cliente, "\n");
  180.                                         if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
  181.                                             perror("send");
  182.                                             exit(2);
  183.                                         }
  184.                                         break;
  185.                                     case ESPERA_USUARIO:
  186.                                         printf("\nPssssssssssss, si no tenes usuario generalmente podes entrar como anonymous");
  187.                                         printf("\ncon contraseña del modo algo@algo.algo ;)");
  188.                                         printf("\nUsuario requerido: ");
  189.                                         memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char)); //LIMPIO COSAS VIEJAS
  190.                                         memset(auxiliar, '\0', BUFSIZ*sizeof(char));
  191.                                         strcat(mensaje_cliente,"USER ");
  192.                                         scanf("%s", auxiliar);  //AUXILIAR ME SIRVE PARA PODER ARMAR EL STRING DE LA SIGUIENTE MANERA -> USER usuario\n
  193.                                         strcat(mensaje_cliente, auxiliar);
  194.                                         strcat(mensaje_cliente,"\n");
  195.                                         if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
  196.                                             perror("send");
  197.                                             exit(2);
  198.                                         }
  199.                                         break;
  200.                                     default:
  201.                                         memset(auxiliar, '\0', BUFSIZ*sizeof(char));
  202.                                         do{   //hago esto para mantenerme en este estado por si se pide Help.
  203.                                             printf("\nftp> ");
  204.                                             memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char));
  205.                                             scanf("%s", mensaje_cliente);
  206.                                             char parametros [BUFSIZ];
  207.                                             convertirAMayusculas(mensaje_cliente); //TODO A MAYUS -> NO CASE SENSITIVE
  208.                                             if(strcmp(mensaje_cliente, "HELP")==0){
  209.                                                 mostrarAyuda();
  210.                                             }
  211.                                             else{
  212.                                                 if(strcmp(mensaje_cliente, "USER")== 0){
  213.                                                     user();
  214.                                                 }
  215.                                                 else{
  216.                                                      if(strcmp(mensaje_cliente, "LIST")== 0){
  217.                                                          list();
  218.                                                      }
  219.                                                      else{
  220.                                                         if(strcmp(mensaje_cliente, "PWD") == 0){
  221.                                                             pwd();
  222.                                                         }
  223.                                                         else{
  224.                                                             if(strcmp(mensaje_cliente, "CD") == 0){
  225.                                                                 scanf("%s", parametros);
  226.                                                                 //char cwd[BUFSIZ];
  227.                                                                 //char buff[BUFSIZ];
  228.                                                                 memset(server_reply, '\0', BUFSIZ*sizeof(char));
  229.                                                                 memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char));
  230.                                                                 strcat(mensaje_cliente, "CWD ");
  231.                                                                 strcat(mensaje_cliente, parametros);
  232.                                                                 strcat(mensaje_cliente, "\n");
  233.  
  234.                                                                 if( send(socketControl, mensaje_cliente, strlen(mensaje_cliente), 0) < 0 ){
  235.  
  236.                                                                     perror("send");
  237.                                                                     exit(2);
  238.                                                                 }
  239.                                                                 if( recv(socketControl, server_reply, BUFSIZ * sizeof(char), 0 ) < 0){
  240.                                                                     perror("recv");
  241.                                                                     exit(5);
  242.                                                                 }
  243.                                                                 printf("cd %s\n",server_reply);
  244.                                                                 printf("MENSAJE : %s  \n",mensaje_cliente);
  245.                                                             }
  246.                                                             else{
  247.                                                                 if(strcmp(mensaje_cliente, "GET") == 0){
  248.                                                                     scanf("%s", parametros);
  249.                                                                     recv_file(parametros);
  250.                                                                 }
  251.                                                             }
  252.                                                         }
  253.                                                      }
  254.                                                 }
  255.                                             }
  256.                                             printf("MENSAJE : %s  \n",mensaje_cliente);
  257.                                         }while(strcmp(mensaje_cliente, "HELP") == 0); //hago esto para mantenerme en este estado por si se pide Help.
  258.                                         break;
  259.                                     }
  260.                             }
  261.                         }
  262.                     }
  263.                 }
  264.             }
  265.         }
  266.     }
  267.     return 0;
  268. }
  269. void user(){
  270.     printf("\n Nombre de usuario: ");
  271.     scanf("%s", auxiliar);
  272.     strcat(mensaje_cliente, " ");
  273.     strcat(mensaje_cliente, auxiliar);
  274.     strcat(mensaje_cliente,"\n");
  275.     if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
  276.         perror("send");
  277.         exit(2);
  278.     }
  279. }
  280.  
  281. void pwd(){
  282.     strcat(mensaje_cliente,"\n");
  283.     if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
  284.         perror("send");
  285.         exit(2);
  286.     }
  287. }
  288.  
  289. void list (){
  290.     // Declaracion de variables
  291.     int socketDatos;
  292.     FILE *file;
  293.     char *line;
  294.     size_t len;
  295.  
  296.     line = NULL;
  297.     len = 0;
  298.     //Fin declaracion variables
  299.  
  300.     /* Entro a modo pasivo */
  301.     socketDatos = socketPasivo(socketControl, server_reply);
  302.  
  303.     memset(server_reply, '\0', BUFSIZ*sizeof(char));
  304.     strcat(mensaje_cliente, "\n");
  305.     send(socketControl, mensaje_cliente, strlen(mensaje_cliente) , 0);
  306.     if( recv(socketControl , server_reply , sizeof(server_reply) , 0) < 0)
  307.         printf("\nError al recibir respuesta del servidor.");
  308.     printf("%s \n", server_reply);
  309.     respuestaServidorEntero = 150;
  310.     //int respuestaServidorEntero = atoi(strtok(server_reply," ")) ;
  311.     if (respuestaServidorEntero == ABRIENDO_DC || respuestaServidorEntero == DC_ABIERTO){
  312.         //Conexion de datos
  313.         //Segunda respuesta servidor
  314.         memset(server_reply, '\0', BUFSIZ*sizeof(char));
  315.         if( recv(socketControl , server_reply , sizeof(server_reply) , 0) < 0)
  316.             printf("\nError al recibir respuesta del servidor.");
  317.         printf("%s \n", server_reply);
  318.         respuestaServidorEntero = 226;
  319.         //respuestaServidorEntero = atoi(strtok(server_reply," ")) ;
  320.         if (respuestaServidorEntero == CERRANDO_DC || respuestaServidorEntero == OPERACION_COMPLETA){
  321.             //Se transfirió el archivo
  322.  
  323.             if ((file = fdopen(socketDatos, "r")) == NULL){
  324.                 exit(EXIT_FAILURE);
  325.                 printf("Se produjo un error al abrir el archivo\n");
  326.             }
  327.             printf("LIST: \n");
  328.             while (getline(&line, &len, file) != -1){
  329.                     printf("%s \n", line);
  330.             }
  331.             //send(socketControl, "PWD\n", 4, 0);
  332.             //recv(socketControl, server_reply, BUFSIZ * sizeof(char), 0);
  333.             fclose(file);
  334.             printf("xD\n");
  335.             close(socketDatos);
  336.         }
  337.         else{
  338.             printf("ERROR: %i \n", respuestaServidorEntero);
  339.         }
  340.     }
  341.     else{
  342.         printf("ERROR: %i \n", respuestaServidorEntero);
  343.     }
  344.     //close(socketDatos);
  345.     printf("xD");
  346.     }
  347.  
  348. int socketPasivo(){
  349.     memset(server_reply, '\0', BUFSIZ*sizeof(char));
  350.     send(socketControl, "PASV\n", 5, 0);
  351.  
  352.     if( recv(socketControl , server_reply , sizeof(server_reply) , 0) < 0)
  353.         printf("\nError al recibir respuesta del servidor.");
  354.     printf("respuesta -> %s \n", server_reply);
  355.     if (strncmp(server_reply, "227", 3) == 0){
  356.         /* Obtengo el numero de puerto */
  357.         int contador = 0;
  358.         int p1, p2;
  359.         int puerto;
  360.         char * aux;
  361.         aux = strtok (server_reply,",");
  362.         /*
  363.             227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).
  364.         */
  365.         while (aux != NULL)
  366.         {
  367.             contador ++;
  368.             if (contador == 5){
  369.                 p1 = atoi(aux);
  370.             }
  371.             if (contador == 6){
  372.                 p2 = atoi(aux);
  373.             }
  374.             aux = strtok (NULL, ",)");
  375.         }
  376.         puerto = p1 *256 + p2;
  377.         struct sockaddr_in addr;
  378.         char ip[100];
  379.         strcpy(ip, inet_ntoa(server.sin_addr));
  380.         printf("ip: %s\n",ip);
  381.         int devolverSocketControl;
  382.         //Creacion del socket
  383.         if ((devolverSocketControl = socket(AF_INET, SOCK_STREAM, 0)) < 0){
  384.             printf("\nError al crear socket..");
  385.             exit(1);
  386.         }
  387.         printf("\nSocket creado correctamente");
  388.         bzero(&addr,sizeof(addr));
  389.         inet_aton(ip, &addr.sin_addr);      //Setea el IP del servidor
  390.         addr.sin_family = AF_INET;                     //PROTOCOLO DE LA FAMILIA
  391.         addr.sin_port = htons(puerto);        //PUERTO DEL SERVIDOR
  392.         if (connect(devolverSocketControl, (struct sockaddr *)&addr , sizeof(addr)) < 0){
  393.             perror("\nError en la conexion, servidor no disponible. Intente nuevamente ");
  394.             exit(1);
  395.         }
  396.         return devolverSocketControl;
  397.     }
  398.     else{
  399.         printf("Error 227");
  400.         exit(1);
  401.     }
  402. }
  403.  
  404. void cd(char *rep){
  405.  
  406.     char cwd[BUFSIZ];
  407.     char buff[BUFSIZ];
  408.  
  409.     memset(cwd, '\0', BUFSIZ);
  410.     strcat(cwd, "CWD ");
  411.     strcat(cwd, rep);
  412.     strcat(cwd, "\n");
  413.  
  414.     if( send(socketControl, cwd, strlen(cwd)+1, 0) < 0 ){
  415.  
  416.         perror("send");
  417.         exit(2);
  418.     }
  419.     memset(buff, '\0', BUFSIZ*sizeof(char));
  420.     if( recv(socketControl, buff, sizeof(buff), 0 ) < 0){
  421.  
  422.         perror("recv");
  423.         exit(5);
  424.     }
  425.     else printf("cd %s\n",buff);
  426. }
  427.  
  428. int recv_file(char* file_name){
  429.      int sock = socketPasivo();
  430.      char send_str [256]; /* message to be sent to server*/
  431.      int f; /* file handle for receiving file*/
  432.      ssize_t sent_bytes, rcvd_bytes, rcvd_file_size;
  433.      int recv_count; /* count of recv() calls*/
  434.      char recv_str[256]; /* buffer to hold received data */
  435.      size_t send_strlen; /* length of transmitted string */
  436.      memset(send_str, '\0', 256 * sizeof(char));
  437.      strcat(send_str,"RETR ");
  438.      strcat(send_str, file_name);
  439.      strcat(send_str, "\n");
  440.      send_strlen = strlen(send_str); /* length of message to be transmitted */
  441.      if( (sent_bytes = send(socketControl, send_str, send_strlen, 0)) < 0 ) {
  442.         perror("send error");
  443.         return -1;
  444.      }
  445.      /* attempt to create file to save received data. 0644 = rw-r--r-- */
  446.      if ( (f = open(file_name, O_WRONLY|O_CREAT, 0644)) < 0 ){
  447.          perror("error creating file");
  448.          return -1;
  449.      }
  450.  
  451.      recv_count = 0; /* number of recv() calls required to receive the file */
  452.      rcvd_file_size = 0; /* size of received file */
  453.  
  454.      /* continue receiving until ? (data or close) */
  455.      while ( (rcvd_bytes = recv(sock, recv_str, 256, 0)) > 0 )
  456.      {
  457.          recv_count++;
  458.          rcvd_file_size += rcvd_bytes;
  459.  
  460.          if (write(f, recv_str, rcvd_bytes) < 0 )
  461.          {
  462.             perror("error writing to file");
  463.             return -1;
  464.          }
  465.      }
  466.      close(f); /* close file*/
  467.      printf("Client Received: %d bytes in %d recv(s)\n", rcvd_file_size,recv_count);
  468.      return rcvd_file_size;
  469. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement