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>
- #define MODO_PASIVO 227
- #define PUERTO_DEFAULT 21
- //Respuestas del servidor
- #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
- int socketControl;
- char server_reply[BUFSIZ], mensaje_cliente [BUFSIZ],auxiliar[BUFSIZ];
- int respuestaServidorEntero;
- struct sockaddr_in server;
- void cd(char *rep);
- void list();
- void user();
- void pwd();
- int 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------------
- 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;
- }
- 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: Cambio de directorio.\n");
- printf("LIST: Listado de archivos en directorio actual.\n");
- printf("PUT: Envío de archivo al servidor.\n");
- printf("GET: 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... duh
- //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)); //FALTA IMPLEMENTAR EL OPEN !!!!
- // inet_aton("114.30.44.99", &server.sin_addr); //Setea el IP del servidor
- server.sin_family = AF_INET; //PROTOCOLO DE LA FAMILIA
- server.sin_port = htons(puertoServidor); //PUERTO DEL SERVIDOR
- while(1){ // WHILE ESPERANDO PARA HACER OPEN o QUIT o HELP
- //Conexion al servidor
- memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char)); //LIMPIO COSAS VIEJAS
- memset(auxiliar, '\0', BUFSIZ*sizeof(char));
- printf("\nftp> ");
- scanf("%s", mensaje_cliente);
- convertirAMayusculas(mensaje_cliente);// LO CONVIERTE TODO EN MAYUSUCULAS -> EN NO CASE SENSITIVE
- // strcat(mensaje_cliente, "OPEN");
- if(strcmp(mensaje_cliente, "QUIT") == 0){
- printf("\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){
- printf("\nIngrese la direccion del servidor: ");
- scanf("%s", auxiliar);
- // strcat(auxiliar, "114.30.44.99");
- nombreServidor = auxiliar;
- //printf("\nHOLA ->>>%i", strcmp(nombreServidor,"114.30.44.99") == 0);
- inet_aton(nombreServidor, &server.sin_addr);
- if (connect(socketControl , (struct sockaddr *)&server , sizeof(server)) < 0){
- perror("\nError en la conexion, servidor no disponible. Intente nuevamente ");
- }
- else{
- printf("\nConectado correctamente");
- while(1){ //WHILE UNA VEZ REALIZADA LA CONEXION TCP
- printf("MENSAJE : %s \n",mensaje_cliente);
- 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("%s",server_reply);
- 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 :)
- // printf("\n RESPUESTA --> %i", respuestaServidorEntero);
- // printf("\n RESPUESTA --> %i", respuestaServidorEntero == 221);
- switch(respuestaServidorEntero){
- case SALIR: // despues del QUIT
- printf("\nCerrando cliente ftp.");
- exit(0);
- break;
- case ESPERA_PASSWORD:
- //printf("\nPassword requerido: ");
- memset(mensaje_cliente, '\0', BUFSIZ*sizeof(char)); //LIMPIO COSAS VIEJAS
- 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");
- if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
- perror("send");
- exit(2);
- }
- break;
- case ESPERA_USUARIO:
- printf("\nPssssssssssss, si no tenes usuario generalmente podes entrar como anonymous");
- printf("\ncon contraseña del modo algo@algo.algo ;)");
- printf("\nUsuario 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");
- if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
- perror("send");
- exit(2);
- }
- break;
- default:
- memset(auxiliar, '\0', BUFSIZ*sizeof(char));
- do{ //hago esto para mantenerme en este estado por si se pide Help.
- printf("\nftp> ");
- 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);
- //char cwd[BUFSIZ];
- //char buff[BUFSIZ];
- 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");
- if( send(socketControl, mensaje_cliente, strlen(mensaje_cliente), 0) < 0 ){
- perror("send");
- exit(2);
- }
- if( recv(socketControl, server_reply, BUFSIZ * sizeof(char), 0 ) < 0){
- perror("recv");
- exit(5);
- }
- printf("cd %s\n",server_reply);
- printf("MENSAJE : %s \n",mensaje_cliente);
- }
- else{
- if(strcmp(mensaje_cliente, "GET") == 0){
- scanf("%s", parametros);
- recv_file(parametros);
- }
- }
- }
- }
- }
- }
- printf("MENSAJE : %s \n",mensaje_cliente);
- }while(strcmp(mensaje_cliente, "HELP") == 0); //hago esto para mantenerme en este estado por si se pide Help.
- break;
- }
- }
- }
- }
- }
- }
- }
- }
- return 0;
- }
- void user(){
- printf("\n Nombre de usuario: ");
- scanf("%s", auxiliar);
- strcat(mensaje_cliente, " ");
- strcat(mensaje_cliente, auxiliar);
- strcat(mensaje_cliente,"\n");
- if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
- perror("send");
- exit(2);
- }
- }
- void pwd(){
- strcat(mensaje_cliente,"\n");
- if( send(socketControl, mensaje_cliente, (strlen(mensaje_cliente)), 0) < 0 ){
- perror("send");
- exit(2);
- }
- }
- 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));
- strcat(mensaje_cliente, "\n");
- send(socketControl, mensaje_cliente, strlen(mensaje_cliente) , 0);
- if( recv(socketControl , server_reply , sizeof(server_reply) , 0) < 0)
- printf("\nError al recibir respuesta del servidor.");
- printf("%s \n", server_reply);
- respuestaServidorEntero = 150;
- //int respuestaServidorEntero = atoi(strtok(server_reply," ")) ;
- if (respuestaServidorEntero == ABRIENDO_DC || respuestaServidorEntero == DC_ABIERTO){
- //Conexion de datos
- //Segunda respuesta servidor
- 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("%s \n", server_reply);
- respuestaServidorEntero = 226;
- //respuestaServidorEntero = atoi(strtok(server_reply," ")) ;
- if (respuestaServidorEntero == CERRANDO_DC || respuestaServidorEntero == OPERACION_COMPLETA){
- //Se transfirió el archivo
- if ((file = fdopen(socketDatos, "r")) == NULL){
- exit(EXIT_FAILURE);
- printf("Se produjo un error al abrir el archivo\n");
- }
- printf("LIST: \n");
- while (getline(&line, &len, file) != -1){
- printf("%s \n", line);
- }
- //send(socketControl, "PWD\n", 4, 0);
- //recv(socketControl, server_reply, BUFSIZ * sizeof(char), 0);
- fclose(file);
- printf("xD\n");
- close(socketDatos);
- }
- else{
- printf("ERROR: %i \n", respuestaServidorEntero);
- }
- }
- else{
- printf("ERROR: %i \n", respuestaServidorEntero);
- }
- //close(socketDatos);
- printf("xD");
- }
- 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);
- }
- }
- void cd(char *rep){
- char cwd[BUFSIZ];
- char buff[BUFSIZ];
- memset(cwd, '\0', BUFSIZ);
- strcat(cwd, "CWD ");
- strcat(cwd, rep);
- strcat(cwd, "\n");
- if( send(socketControl, cwd, strlen(cwd)+1, 0) < 0 ){
- perror("send");
- exit(2);
- }
- memset(buff, '\0', BUFSIZ*sizeof(char));
- if( recv(socketControl, buff, sizeof(buff), 0 ) < 0){
- perror("recv");
- exit(5);
- }
- else printf("cd %s\n",buff);
- }
- int recv_file(char* file_name){
- int sock = socketPasivo();
- char send_str [256]; /* message to be sent to server*/
- int f; /* file handle for receiving file*/
- ssize_t sent_bytes, rcvd_bytes, rcvd_file_size;
- int recv_count; /* count of recv() calls*/
- char recv_str[256]; /* buffer to hold received data */
- size_t send_strlen; /* length of transmitted string */
- 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); /* length of message to be transmitted */
- if( (sent_bytes = send(socketControl, send_str, send_strlen, 0)) < 0 ) {
- perror("send error");
- return -1;
- }
- /* attempt to create file to save received data. 0644 = rw-r--r-- */
- if ( (f = open(file_name, O_WRONLY|O_CREAT, 0644)) < 0 ){
- perror("error creating file");
- return -1;
- }
- recv_count = 0; /* number of recv() calls required to receive the file */
- rcvd_file_size = 0; /* size of received file */
- /* continue receiving until ? (data or close) */
- 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");
- return -1;
- }
- }
- close(f); /* close file*/
- printf("Client Received: %d bytes in %d recv(s)\n", rcvd_file_size,recv_count);
- return rcvd_file_size;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement