Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.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>
#include <pthread.h>
#define MYPORT 3490
#define BACKLOG 10
struct sockaddr_in server;
void *recibir(void *datos);
int socketirc(int sockirc, char *ip, int port);
typedef struct {
int sockirc;
int new_fd;
} data;
void sigchld_handler(int s)
{
while(wait(NULL) > 0);
}
void *recibir(void *datos) {
data *misdatos = (data *) datos;
char recvbuff[130];
int result = 0;
fd_set readset;
memset(&recvbuff, 0, sizeof(recvbuff));
do {
do {
FD_ZERO(&readset);
FD_SET(misdatos->sockirc, &readset);
result = select(misdatos->sockirc + 1, &readset, NULL, NULL, NULL);
} while (result == -1 && errno == EINTR);
if (result > 0) {
if (FD_ISSET(misdatos->sockirc, &readset)) {
result = recv(misdatos->sockirc, recvbuff, 128, 0);
if (result == 0) {
close(misdatos->sockirc);
break;
}
else {
if (send(misdatos->new_fd, recvbuff, result, 0) == -1)
perror("send");
}
}
}
else if (result < 0) {
printf("Error on select(): %s", strerror(errno));
break;
}
} while(1);
}
int socketirc(int sockirc, char *ip, int port)
{
if ((sockirc=socket(AF_INET, SOCK_STREAM, 0))==-1){
return;
}
server.sin_addr.s_addr=inet_network(ip);
server.sin_addr.s_addr=inet_addr(ip);
server.sin_family = AF_INET;
server.sin_port = htons(port);
bzero(&(server.sin_zero),8);
if(connect(sockirc, (struct sockaddr *)&server, sizeof(struct sockaddr))==-1){
exit(-1);
}
else
printf("funciona");
return sockirc;
}
main(void)
{
int sockfd, new_fd, sockirc, i, error, result = 0;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
int sin_size, conectado = 0;
struct sigaction sa;
int yes=1, next = 0, port = 0;
char recvbuff[130], *ptr, ip[15] = "vacio";
struct hostent *h;
data datos;
pthread_t idHilo;
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);
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MYPORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
memset(&(my_addr.sin_zero), '\0', 8);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))
== -1) {
perror("bind");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
while(1) {
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
perror("accept");
continue;
}
printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr));
if (!fork()) {
close(sockfd);
memset(&recvbuff, 0, sizeof(recvbuff));
for(;;)
{
if((result = recv(new_fd, recvbuff, 128, 0)))
{
if (strstr(recvbuff, "irc") != NULL && strstr(ip, "vacio")) {
ptr = strtok(recvbuff, " ");
i = 1;
while(ptr != NULL ) {
if (next == 1) {
port = atoi(ptr);
sockirc = socketirc(sockirc, ip, port);
datos.sockirc = sockirc;
datos.new_fd = new_fd;
error = pthread_create (&idHilo, NULL, recibir, (void *) &datos);
next = 0;
break;
}
if (strstr(ptr, "irc") != NULL && strstr(ip, "vacio")) {
if ((h=gethostbyname(ptr)) == NULL) {
herror("gethostbyname");
exit(1);
}
h->h_addr = inet_ntoa(*(struct in_addr*)h->h_addr);
strcpy(ip, h->h_addr);
next = 1;
}
printf("%d\n", i);
i++;
printf("%s\n", ptr);
ptr = strtok(NULL, " ");
}
}
else {
if (send(sockirc, recvbuff, result, 0) == -1)
perror("send");
}
}
}
close(new_fd);
exit(0);
}
close(new_fd);
}
return 0;
}
I'm going to keep testing the code, but apparently everything work fine. If someone else has any recommendation for my code, don't hesitate to post it.