Advertisement
Guest User

Untitled

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