#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#define MYPORT 3490 /* Puerto de escucha */
#define BACKLOG 10 /* Cantidad de conexiones máximas permit.*/
#define MAX 512 /*tamaño máximo del buff de lectura de archivo*/
int enviototal(int s, char buffer[],int *len);
int recibtotal(int s, char buffer[],int *len);
int main( ){
int sockfd, new_fd;
/* Escuchar sobre sock_fd, nuevas conexiones sobre new_fd*/
struct sockaddr_in dir_local; /*información sobre mi dirección*/
struct sockaddr_in dir_entrante;
/* información sobre la dirección del cliente*/
int yes=1,bytesrec,sin_size;
FILE* archivo;
char nomarch[40],carpeta[40],dir[100],httpmsj[100],
http200[ ]="HTTP 200:FILE FOUND",
http404[ ]="HTTP404:FILE NOT FOUND";
char *parse,*p;
int len,bytesleidos;
char buffer[512],bufferaux[512];
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit (1);
}
if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,
sizeof(int)) == -1)
{
perror("setsockopt");
exit (1);
}
dir_local.sin_family = AF_INET;
// Ordenación de bytes de la máquina
dir_local.sin_port = htons(MYPORT);
// short, Ordenación de bytes de la red
dir_local.sin_addr.s_addr = htonl(INADDR_ANY);
// Rellenar con mi dirección IP
memset(&(dir_local.sin_zero), ' ', 8);
// Poner a cero el resto de la estructura
if (bind(sockfd, (struct sockaddr *)&dir_local,
sizeof (struct sockaddr))== -1)
{
perror("bind");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1)
{
perror("listen");
exit(1);
}
while(1) {
sin_size =sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd,
(struct sockaddr *) &dir_entrante,&sin_size)) == -1)
{
perror("accept");
continue;
}
/*recibe nombre del archivo y se extrae del mensaje GET
el nombre para intentar la apertura*/
if ((bytesrecib=recv(new_fd, httpmsj, sizeof(httpmsj), 0)) == -1)
/*recibe mensaje get*/
{
perror("recv");
exit(1);
}
len=strlen(buffer);/*verificar si esta bien*/
while((bytesrecib>0)
{
if((bytesrecib=enviototal(new_fd,buffer,
&len))==-1)
/* asegura que se reciba la totalidad del buffer*/
{ perror("enviototal");
printf("Se recibieron %d bytes a causa del error
",len);
}
}/*fin while*/
if(((p=strstr(httpmsj,"r/n/r/n"))!=NULL)||
((p=strstr(httpmsj,"/n/n"))!=NULL))
{
parse=strtok(httpmsj,"/");
parse=strtok(NULL," ");
strcpy(nomarch,parse);
}
/*se arma la ruta de acceso*/
strcpy(carpeta,"/etc/");
sprintf(dir,("%s%s"),carpeta,nomarch);
/*apertura de archivo*/
archivo=fopen(dir,"rt");
/*se procede a mandar los mensajes http correspondientes e iniciar la transferencia*/
if(archivo)
{
len=strlen(http200);
if(enviototal(new_fd,http200,&len)==-1)
/*se asegura de que llegue la totalidad del mensaje HTTP 200*/
{ perror("enviototal");
printf("Se enviaron %d bytes a causa del error
",len);
}
len=strlen(buffer);
while((bytesleidos=fread(buffer,sizeof(buffer),1,archivo))!=0)
{
if(enviototal(new_fd,buffer,
&len)==-1)
/* asegura que llegue la totalidad del buffer*/
{ perror("enviototal");
printf("Se enviaron %d bytes a causa del error
",len);
}
}/*fin while*/
} /*fin then*/
else
{
len=strlen(http404);
if(enviototal(new_fd,http404,&len)==-1)
/*asegura que llegue la totalidad del mensaje HTTP 404*/
{ perror("enviototal");
printf("Se enviaron %d bytes a causa del error
",len);
}
} /*fin else*/
//cerrar el socket temporal
close(new_fd);
}
close(sockfd);
return 0;
}
int enviototal(int s, char buffer[],int *len)
{
int total=0; /*cuantos bytes se enviaron*/
int restantes=*len; /*cuantos bytes quedan en el buffer*/
int n;
while (total<*len) {
n=send(s,buffer+total,restantes,0);
if(n==-1) {break;}
total+=n;
restantes-=n;
} /*fin while*/
*len=total; /*devuelve la cantidad enviada*/
return (n=-1?-1:0); /*devuelve -1 si falla, 0 en cualquier otro caso*/
}
int recibtotal(int s, char buffer[],int *len)
{
int total=0; /*cuantos bytes se recibieron*/
int restantes=*len; /*cuantos bytes hay en el buffer*/
int n;
while (total<*len) {
n=recv(s,buffer+total,restantes,0);
if(n==-1) {break;}
total+=n;
restantes-=n;
} /*fin while*/
*len=total; /*devuelve la cantidad recibida*/
return (n=-1?-1:0); /*devuelve -1 si falla, 0 en cualquier otro caso*/
}