Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <unistd.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <sys/socket.h>
- #include <resolv.h>
- #include <sys/types.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- //Respuestas del servidor
- #define MODO_PASIVO 227
- #define PUERTO_DEFAULT 21
- #define SALIR 221
- #define ESPERA_USUARIO 220
- #define ESPERA_PASSWORD 331
- #define NO_INGRESADO 530
- #define MAL_SECUENCIA 503
- #define INGRESO_CORRECTO 230
- #define ABRIENDO_DC 150
- #define DC_ABIERTO 150
- #define CERRANDO_DC 226
- #define OPERACION_COMPLETA 250
- //Variables globales
- int socketControl;
- char server_reply[BUFSIZ], mensaje_cliente [BUFSIZ],auxiliar[BUFSIZ];
- int respuestaServidorEntero;
- struct sockaddr_in server;
- //Metodos
- void cd (char * parametro);
- void list();
- void user();
- void pwd();
- void sendfile(char * file_name);
- void recv_file(char *file);
- int socketPasivo();
- //Convertir todos los caracteres de un string en MAYUS
- void convertirAMayusculas(char * string) {
- // Convert to upper case
- char *s = string;
- while (*s) {
- *s = toupper((unsigned char) *s);
- s++;
- }
- }
- //VALIDACION NUMERO DE PUERTO
- int esPuertoValido(char * string){
- int devolver = string[0] == ':'; //Todo puerto valido tiene que empezar con ':' y luego ser un numero.
- int i;
- int longitud = strlen (string);
- for (i=1;i<longitud && devolver!= 0; i++)
- if (!isdigit(string[i])){
- devolver = 0;
- }
- return devolver;
- }
- //Muestra los comandos que se permiten ingresar durante la coneccion
- void mostrarAyuda(){
- printf("QUIT: Finaliza la ejecución del cliente.\n");
- printf("OPEN: <Servidor> [Puerto]. Realiza una conexion con el servidor y el puerto, en caso de ser especificado el mismo.\n");
- printf("USER: Especifica el usuario bajo la cual se desea acceder al servidor.\n");
- printf("PASS: Contraseña para identificarse con el usuario.\n");
- printf("PWD: Muestra el directorio actual.\n");
- printf("CD: <direccion> Cambio de directorio.\n");
- printf("LIST: Listado de archivos en directorio actual.\n");
- printf("PUT: <nombre archivo> EnvÃo de archivo al servidor.\n");
- printf("GET: <nombre archivo> Recepción del archivo indicado como argumento\n");
- printf("PASSIVE: Modo de transferencia pasivo\n");
- printf("ACTIVE: Modo de transferencia activo \n");
- }
- int main(int argc, char** argv)
- {
- //Validacion parametros de consola
- if(argc > 4){
- printf("Parametros incorrectos, [Servidor [:Puerto]] [-h] \n");
- exit(1);
- }
- int i;
- char * nombreServidor;
- int puertoServidor = PUERTO_DEFAULT;
- for(i=0; i < argc; i++){
- if(strcmp(argv[i],"-h") == 0){
- mostrarAyuda();
- exit(1);
- }
- if(i == 1){
- nombreServidor = argv[i];
- }
- if(i == 2){
- if(esPuertoValido(argv[i]))
- puertoServidor = atoi(argv[i]+1);
- else{
- printf("Puerto invalido \n");
- exit(1);
- }
- }
- if(i == 3){ //no es -h
- printf("Paremetros incorrectos \n");
- exit(1);
- }
- }
- //Declaracion de variables
- printf("\n Bienvenidos al cliente FTP!"); //mensaje bienvenida...
- //Creacion del socket
- if ((socketControl = socket(AF_INET, SOCK_STREAM, 0)) < 0){
- printf("\nError al crear socket..");
- exit(1);
- }
- printf("\nSocket creado correctamente");
- bzero(&server,sizeof(server));
- server.sin_family = AF_INET; //SETEA PROTOCOLO DE LA FAMILIA
- server.sin_port = htons(puertoServidor); //SETEA PUERTO DEL SERVIDOR
- while(1){ // WHILE ESPERANDO PARA HACER OPEN o QUIT o HELP
- //Conexion al servidor
- //LIMPIA BUFFER
- memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char));
- memset(auxiliar, '\0', BUFSIZ*sizeof(char));
- printf("\nftp> ");
- scanf("%s", mensaje_cliente);
- convertirAMayusculas(mensaje_cliente);// LO CONVIERTE TODO EN MAYUSUCULAS -> EN NO CASE SENSITIVE
- //Chequea que parametro se ingresa
- if(strcmp(mensaje_cliente, "QUIT") == 0){
- printf("\n Cerrando cliente ftp.");
- exit(0);
- }
- else{
- if(strcmp(mensaje_cliente, "HELP") == 0){
- mostrarAyuda();
- }
- else{
- if(strcmp(mensaje_cliente, "OPEN") != 0){
- printf("\n Comando invalido, utilice OPEN, QUIT o HELP.");
- }
- else{
- if(strcmp(mensaje_cliente, "OPEN") == 0){
- //Solicitud de datos para la conexion al servidor
- printf("\nIngrese la direccion del servidor: ");
- scanf("%s", auxiliar);
- nombreServidor = auxiliar;
- inet_aton(nombreServidor, &server.sin_addr);
- //Intenta conectar al servidor
- if (connect(socketControl , (struct sockaddr *)&server , sizeof(server)) < 0){
- perror("\nError en la conexion, servidor no disponible. Intente nuevamente ");
- }
- else{
- //Coneccion al servidor exitosa
- printf("\nConectado correctamente");
- while(1){ //WHILE UNA VEZ REALIZADA LA CONEXION TCP
- printf("ENTROOOOOOOOOOOOOOOO AL WHILEEEEE");
- memset(server_reply, '\0', BUFSIZ*sizeof(char));
- if( recv(socketControl , server_reply , sizeof(server_reply) , 0) < 0)
- printf("\nError al recibir respuesta del servidor.");
- printf("\n%s",server_reply); //Muestra respuesta de la ultima consulta
- respuestaServidorEntero = atoi(strtok(server_reply," ")) ; //Tomo la primer palabra de la respuesta (Que es el codigo establecido
- //en el RFC) y la paso a entero para poder usar el switch y que el codigo este mas bonito :)
- //SWITCH segun codigo respuesta del servidor
- switch(respuestaServidorEntero){
- case SALIR: // despues del QUIT (codigo 221)
- printf("\nCerrando cliente ftp.");
- exit(0);
- break;
- case ESPERA_PASSWORD://codigo 331
- memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char)); //LIMPIO COSAS VIEJAS
- //Lee pasword
- strcat(mensaje_cliente,"PASS ");
- char * password;
- password = getpass("Password requerido: "); //ESCONDE LO QUE ESCRIBIS EN PANTALLA
- printf("%s", password);
- strcat(mensaje_cliente,password);
- //free(password);
- strcat(mensaje_cliente, "\n");
- //Envia password
- if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
- perror("send");
- exit(2);
- }
- break;
- case ESPERA_USUARIO://codigo 220
- //printf("\n si no tenes usuario generalmente podes entrar como anonymous");
- //printf("\ncon contraseña con formato algo@algo.algo ");
- //Arma el mensaje que sera enviado al servidor
- printf("\n Usuario requerido: ");
- memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char)); //LIMPIO COSAS VIEJAS
- memset(auxiliar, '\0', BUFSIZ*sizeof(char));
- strcat(mensaje_cliente,"USER ");
- scanf("%s", auxiliar); //AUXILIAR ME SIRVE PARA PODER ARMAR EL STRING DE LA SIGUIENTE MANERA -> USER usuario\n
- strcat(mensaje_cliente, auxiliar);
- strcat(mensaje_cliente,"\n");
- //Envia el mensaje
- if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
- perror("send");
- exit(2);
- }
- break;
- default://COMPORTAMIENTO POR DEFECTO
- memset(auxiliar, '\0', BUFSIZ*sizeof(char));
- do{ //hago esto para mantenerme en este estado por si se pide Help.
- printf("\nftp> ");
- //Lee y arma el mensaje del cliente
- memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char));
- scanf("%s", mensaje_cliente);
- char parametros [BUFSIZ];
- convertirAMayusculas(mensaje_cliente); //TODO A MAYUS -> NO CASE SENSITIVE
- if(strcmp(mensaje_cliente, "HELP")==0){
- mostrarAyuda();
- }
- else{
- if(strcmp(mensaje_cliente, "USER")== 0){
- user();
- }
- else{
- if(strcmp(mensaje_cliente, "LIST")== 0){
- list();
- }
- else{
- if(strcmp(mensaje_cliente, "PWD") == 0){
- pwd();
- }
- else{
- if(strcmp(mensaje_cliente, "CD") == 0){
- scanf("%s", parametros);
- cd(parametros);
- }
- else{
- if(strcmp(mensaje_cliente, "GET") == 0){
- scanf("%s", parametros);
- recv_file(parametros);
- }
- else{
- if(strcmp(mensaje_cliente, "PUT") == 0){
- scanf("%s", parametros);
- sendfile(parametros);
- }
- }
- }
- }
- }
- }
- }
- }while(strcmp(mensaje_cliente, "HELP") == 0); //hago esto para mantenerme en este estado por si se pide Help.
- break;
- }
- }
- }
- }
- }
- }
- }
- }
- return 0;
- }
- //Solicita nombre del usuario con el que se desea entrar en la conexion y intenta loguearse
- void user(){
- //Armado del mensaje para enviarse al servidor
- printf("\n Nombre de usuario: ");
- scanf("%s", auxiliar);
- strcat(mensaje_cliente, " ");
- strcat(mensaje_cliente, auxiliar);
- strcat(mensaje_cliente,"\n");
- //Envia mensaje al servidor
- if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
- perror("send");
- exit(2);
- }
- }
- //Muestra direccion del directorio actual del servidor
- void pwd(){
- //toma del buffer el mensaje ingresado por el cliente
- strcat(mensaje_cliente,"\n");
- //Envia el mensaje al servidor
- if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
- perror("send");
- exit(2);
- }
- }
- //Lista archivos que estan contenidos en el directorio actual del servidor
- void list (){
- // Declaracion de variables
- int socketDatos;
- FILE *file;
- char *line;
- size_t len;
- line = NULL;
- len = 0;
- //Fin declaracion variables
- /* Entro a modo pasivo */
- socketDatos = socketPasivo(socketControl, server_reply);
- memset(server_reply, '\0', BUFSIZ*sizeof(char));//Limpia buffer de respuesta del servidor
- strcat(mensaje_cliente, "\n"); //inserta salto de linea al final del buffer del mensaje cliente
- send(socketControl, mensaje_cliente, strlen(mensaje_cliente) , 0);//envia mensaje del cliente al servidor
- if( recv(socketControl , server_reply , sizeof(server_reply) , 0) < 0)//recibe datos del servidor
- printf("\nError al recibir respuesta del servidor.");
- printf("\n%s", server_reply); //Recibe respuesta del servidor (codigo 150 si esta bien)
- int respuestaServidorEntero = atoi(strtok(server_reply," ")) ;
- if (respuestaServidorEntero == ABRIENDO_DC || respuestaServidorEntero == DC_ABIERTO){
- //Se transfirió el archivo
- //Se recupera archivo
- if ((file = fdopen(socketDatos, "r")) == NULL){
- exit(EXIT_FAILURE);
- printf("Se produjo un error al abrir el archivo\n");
- }
- printf("LIST: \n");
- //SE IMPRIME ARCHIVO EN FORMA DE LISTA
- while (getline(&line, &len, file) != -1){
- printf("%s \n", line);
- }
- fclose(file);//cierra archivo
- }
- else{
- printf("ERROR: %i \n", respuestaServidorEntero);
- }
- close(socketDatos);
- }
- int socketPasivo(){
- memset(server_reply, '\0', BUFSIZ*sizeof(char));
- send(socketControl, "PASV\n", 5, 0);
- if( recv(socketControl , server_reply , sizeof(server_reply) , 0) < 0)
- printf("\nError al recibir respuesta del servidor.");
- printf("respuesta -> %s \n", server_reply);
- if (strncmp(server_reply, "227", 3) == 0){
- /* Obtengo el numero de puerto */
- int contador = 0;
- int p1, p2;
- int puerto;
- char * aux;
- aux = strtok (server_reply,",");
- /*
- 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).
- */
- while (aux != NULL)
- {
- contador ++;
- if (contador == 5){
- p1 = atoi(aux);
- }
- if (contador == 6){
- p2 = atoi(aux);
- }
- aux = strtok (NULL, ",)");
- }
- puerto = p1 *256 + p2;
- struct sockaddr_in addr;
- char ip[100];
- strcpy(ip, inet_ntoa(server.sin_addr));
- printf("ip: %s\n",ip);
- int devolverSocketControl;
- //Creacion del socket
- if ((devolverSocketControl = socket(AF_INET, SOCK_STREAM, 0)) < 0){
- printf("\nError al crear socket..");
- exit(1);
- }
- printf("\nSocket creado correctamente");
- bzero(&addr,sizeof(addr));
- inet_aton(ip, &addr.sin_addr); //Setea el IP del servidor
- addr.sin_family = AF_INET; //PROTOCOLO DE LA FAMILIA
- addr.sin_port = htons(puerto); //PUERTO DEL SERVIDOR
- if (connect(devolverSocketControl, (struct sockaddr *)&addr , sizeof(addr)) < 0){
- perror("\nError en la conexion, servidor no disponible. Intente nuevamente ");
- exit(1);
- }
- return devolverSocketControl;
- }
- else{
- printf("Error 227");
- exit(1);
- }
- }
- /*Recibe archivo pasado por parametro desde el servidor
- * file_name : nombre del archivo a ser transmitido
- * */
- void recv_file(char* file_name){
- int sock = socketPasivo();
- char send_str [256]; /* mensaje del servidor*/
- int f; /* manejador de archivo para archivos recibidos*/
- ssize_t sent_bytes, rcvd_bytes, rcvd_file_size;
- int recv_count; /* contador de llamadas recv() */
- char recv_str[256]; /* buffer de almacenamiento para datos recibidos */
- size_t send_strlen; /* largo del mensaje transmitido */
- memset(send_str, '\0', 256 * sizeof(char));
- strcat(send_str,"RETR ");
- strcat(send_str, file_name);
- strcat(send_str, "\n");
- send_strlen = strlen(send_str); /* largo del mensajea ser transmitido*/
- if( (sent_bytes = send(socketControl, send_str, send_strlen, 0)) < 0 ) {
- perror("send error");
- }
- /* intenta crear un archivo para los datos recibis. 0644 = rw-r--r-- */
- if ( (f = open(file_name, O_WRONLY|O_CREAT, 0644)) < 0 ){
- perror("error creating file");
- }
- recv_count = 0; /* numero de llamadas recv() requeridas para recibir el archivo */
- rcvd_file_size = 0; /* largo del archivo recibido */
- /*recibe el archivo*/
- while ( (rcvd_bytes = recv(sock, recv_str, 256, 0)) > 0 )
- {
- recv_count++;
- rcvd_file_size += rcvd_bytes;
- if (write(f, recv_str, rcvd_bytes) < 0 )
- {
- perror("error writing to file");
- }
- }
- close(f); /* cierra archivo */
- printf("Client Received: %d bytes in %d recv(s)\n", rcvd_file_size,recv_count);
- }
- /*PUT<nombre archivo>
- * Transfiere archivo pasado por parametro al servidor
- * file_name : archivo que se desea tranmitir
- */
- void sendfile(char * file_name){
- int socket = socketPasivo();
- /* abre el archivo que se dea transferir */
- FILE *fp = fopen(file_name,"rb");
- if(fp==NULL)
- {
- printf("File opern error");
- }
- memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char) );
- strcat(mensaje_cliente, "STOR ");
- strcat(mensaje_cliente, file_name);
- strcat(mensaje_cliente, "\n");
- send(socketControl, mensaje_cliente, BUFSIZ * sizeof(char), 0);
- /* Lee los datos del archivo y los transfiere */
- while(1)
- {
- /* primero lee el archivo en trozos de 256 bytes */
- unsigned char buff[256]={0};
- int nread = fread(buff,1,256,fp);
- printf("Bytes read %d \n", nread);
- /* Si se lee completo, envia datos */
- if(nread > 0)
- {
- printf("Sending \n");
- write(socket, buff, nread);
- }
- /* hubo un error o llegamos a fin de archivo */
- if (nread < 256)
- {
- if (feof(fp))
- printf("End of file\n");
- if (ferror(fp))
- printf("Error reading\n");
- break;
- }
- }
- close(socket);
- }
- /*cd cambia el directorio actual remoto
- * parametros : nombre del direcctorio al que se desea entrar
- */
- void cd (char * parametros){
- //Se arma mensaje para enviar al servidor
- memset(server_reply, '\0', BUFSIZ*sizeof(char));
- memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char));
- strcat(mensaje_cliente, "CWD ");
- strcat(mensaje_cliente, parametros);
- strcat(mensaje_cliente, "\n");
- //Se envia mensaje al servidor
- if( send(socketControl, mensaje_cliente, strlen(mensaje_cliente), 0) < 0 ){
- perror("send");
- exit(2);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement