/* ftp.c */
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>
#define BUFTAM 8192
/*Esta función es necesaria para comprobar error
en el código de respuesta recibido*/
int codigoOK(int s,char *b, int *n, char c)
{
if ((*n=read(s,b,BUFTAM))<0)
{
perror("Leyendo");
exit(1);
}
if (b[0]!=c)
{
return 0;
}
return 1;
}
int main(int argc, char *argv[])
{
int s1,s2, n, f, opt;
struct sockaddr_in sa;
struct hostent *phe;
char buffer[BUFTAM], *p;
unsigned int srv[6];
/*Deberemos optener la dirección IP mediante el
nombre del Servidor de alojamiento de FTP, para193.166.3.1
poder realizar el proceso de conexión*/
if (!inet_aton (argv[3],&sa.sin_addr))
{
if (!(phe=gethostbyname(argv[3])))
{
fprintf(stderr, "El Host no existe\n");
exit(1);
}
memcpy(&sa.sin_addr.s_addr,phe->h_addr,phe->h_length);
}
sa.sin_family=AF_INET;
sa.sin_port=htons(21);
if ((s1=socket(PF_INET,SOCK_STREAM,0))<0) //Descriptor de socket
{
perror("Error al abrir el Socket");
exit(1);
}
if(connect(s1,(struct sockaddr *)&sa,sizeof(sa))<0)
{
perror("Error al llamar a connect"); //Mensaje de error si connect no ha funcionado
exit(1);
}
if (!codigoOK(s1,buffer,&n, '2'))
{
fprintf(stderr, "El servidor rechazó la conexión\n");
exit(1);
}
while (n==BUFTAM)
{
if ((n=read(s1,buffer,BUFTAM))<0)
{
perror("Error al leer");
exit(1);
}
}
sprintf(buffer,"USER %s\n",argv[1]);
n=strlen(buffer);
if (write(s1,buffer,n)!=n)
{
perror("Error al escribir");
exit(1);
}
if (!codigoOK(s1,buffer,&n,'3'))
{
fprintf(stderr, "Problema con USER: ");
buffer[n]=0;
fprintf(stderr, "%s\n", buffer);
exit(1);
}
sprintf(buffer, "PASS %s\n",argv[2] );
n=strlen(buffer);
if (write(s1,buffer,n)!=n)
{
perror("write");
exit(1);
}
if (!codigoOK(s1,buffer,&n,'2'))
{
fprintf(stderr, "Problema con PASS: ");
buffer[n]=0;
fprintf(stderr, "%s\n", buffer);
exit(1);
}
if (write(s1,"TYPE I \n",7)!=7)
{
perror("write");
exit(1);
}
if (!codigoOK(s1,buffer,&n,'2'))
{
fprintf(stderr, "Problema con TYPE: ");
buffer[n]=0;
fprintf(stderr, "%s\n", buffer);
exit(1);
}
if (write(s1,"PASV \n",5)!=5)
{
perror("write");
exit(1);
}
if (!codigoOK(s1,buffer,&n,'2'))
{
fprintf(stderr, "Problema con PASV: ");
buffer[n]=0;
fprintf(stderr, "%s\n", buffer);
exit(1);
}
if (!(p=strchr(buffer,'(')))
{
fprintf(stderr, "Error con el formato de respuesta del PASV");
exit(1);
}
sscanf(p+1,"%i,%i,%i,%i,%i,%i",&srv[2],&srv[3],&srv[4],&srv[5],&srv[0],&srv[1]);
sa.sin_family=AF_INET;
sa.sin_port=srv[1]*256+srv[0];
sa.sin_addr.s_addr=(srv[5]<<24)+(srv[4]<<16)+(srv[3]<<8)+srv[2];
sprintf(buffer,"RETR %s\n",argv[4]);
n=strlen(buffer);
if (write(s1,buffer,n)!=n)
{
perror("write");
exit(1);
}
sprintf(buffer, "RETR %s\n",argv[4]);
n=strlen(buffer);
if (write(s1,buffer,n)!=n)
{
perror("write");
exit(1);
}
if((s2=socket(PF_INET,SOCK_STREAM,0))<0)
{
perror("socket");
exit(1);
}
if(connect(s2,(struct sockaddr *)&sa,sizeof(sa))<0)
{
perror("Error al llamar a connect"); //Mensaje de error si connect no ha funcionado
exit(1);
}
if (!codigoOK(s1,buffer,&n,'1'))
{
fprintf(stderr, "Problema con RETR: ");
buffer[n]=0;
fprintf(stderr, "%s\n", buffer);
exit(1);
}
if (p=strrchr(argv[4],'/'))
{
p++;
}
else
{
p=argv[4];
}
if ((f=open(p,O_WRONLY | O_CREAT, 0664))<0)
{
perror("open");
exit(1);
}
do
{
if ((n=read(s2,buffer,BUFTAM))<0)
{
perror("read");
exit(1);
}
write(f,buffer,n);
}
while(n);
if (!codigoOK(s1,buffer,&n,'2'));
{
fprintf(stderr, "Problema con RETR: ");
buffer[n]=0;
fprintf(stderr, "%s\n", buffer);
exit(1);
}
close (f);
close (s1);
close (s2);
}
Comentarios sobre la versión: V-1 (0)
No hay comentarios