Advertisement
Guest User

Proyecto.c

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