#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <X11/Xos.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <X11/Xfuncs.h>
#include <X11/ICE/ICElib.h>
#include "xfwp.h"
#include "transport.h"
int
doSetupRemClientListen(
char ** listen_port_string,
struct clientDataStruct * program_data,
char * server_address)
{
int this_server;
int one = 1;
struct sockaddr_in rem_sockaddr_in;
int listen_port;
char hostname[MAX_HOSTNAME_LEN];
struct timeval time_val;
struct timezone time_zone;
int num_servers = program_data->config_info->num_servers;
for (this_server = 0;
this_server < num_servers && server_array[this_server] != NULL;
this_server++);
if (this_server == num_servers)
{
(void) fprintf(stderr,
"Maximum number of server connections has been reached (%d)\n",
program_data->config_info->num_servers);
return FAILURE;
}
listen_port = this_server + X_SERVER_PORT_BASE + 1;
if ((server_array[this_server] =
(struct server_list *) malloc(sizeof(struct server_list))) == NULL)
{
(void) fprintf(stderr,"malloc - server_array\n");
return FAILURE;
}
if ((server_array[this_server]->client_listen_fd =
socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
(void) fprintf(stderr,"socket call failed\n");
free(server_array[this_server]);
server_array[this_server] = NULL;
return FAILURE;
}
gettimeofday(&time_val, &time_zone);
server_array[this_server]->creation_time = time_val.tv_sec;
server_array[this_server]->time_to_close =
global_data.config_info->client_listen_timeout;
bzero((char * ) &rem_sockaddr_in, sizeof(rem_sockaddr_in));
rem_sockaddr_in.sin_family = AF_INET;
#ifdef BSD44SOCKETS
rem_sockaddr_in.sin_len = sizeof rem_sockaddr_in;
#endif
#ifdef SO_REUSEADDR
if (setsockopt(server_array[this_server]->client_listen_fd,
SOL_SOCKET, SO_REUSEADDR,
(char *) &one, sizeof(int)) < 0)
{
(void) fprintf(stderr, "setsockopt(SO_REUSEADDR) failed\n");
returnFailure:
close(server_array[this_server]->client_listen_fd);
free(server_array[this_server]);
server_array[this_server] = NULL;
return FAILURE;
}
#endif
while (True) {
rem_sockaddr_in.sin_port = htons(listen_port);
if (bind(server_array[this_server]->client_listen_fd,
(struct sockaddr *)&rem_sockaddr_in,
sizeof(rem_sockaddr_in)) == 0)
break;
if (errno != EADDRINUSE)
{
(void) fprintf(stderr,"bind call failed\n");
goto returnFailure;
}
listen_port++;
if (listen_port > 65535)
{
(void) fprintf(stderr,"failed to find a valid port for bind\n");
goto returnFailure;
}
}
#ifdef DEBUG
(void) fprintf (stderr, "Client connect port: %d\n", listen_port);
#endif
if (listen(server_array[this_server]->client_listen_fd, SOMAXCONN) < 0)
{
(void) fprintf(stderr, "listen call failed\n");
goto returnFailure;
}
*(program_data->nfds) = max(*(program_data->nfds),
server_array[this_server]->client_listen_fd + 1);
if ((gethostname(hostname, MAX_HOSTNAME_LEN)) < 0)
{
(void) fprintf(stderr, "gethostname call failed\n");
goto returnFailure;
}
if (((*listen_port_string) =
(char *) malloc (strlen(hostname) + 10)) == NULL)
{
(void) fprintf(stderr, "malloc - proxy address\n");
goto returnFailure;
}
(void) sprintf (*listen_port_string, "%s:%d", hostname,
listen_port - X_SERVER_PORT_BASE);
if ((server_array[this_server]->x_server_hostport =
strdup (server_address)) == NULL)
{
(void) fprintf(stderr, "malloc - server_array string\n");
free(*listen_port_string);
*listen_port_string = NULL;
goto returnFailure;
}
if ((server_array[this_server]->listen_port_string =
strdup (*listen_port_string)) == NULL)
{
(void) fprintf(stderr, "malloc - server_array string\n");
free(server_array[this_server]->x_server_hostport);
free(*listen_port_string);
*listen_port_string = NULL;
goto returnFailure;
}
FD_SET(server_array[this_server]->client_listen_fd, program_data->rinit);
return SUCCESS;
}
void
doSelect(struct
config * config_info,
int * nfds,
int * nready,
fd_set * readable,
fd_set * writable)
{
if ((*nready = select(*nfds,
readable,
writable,
NULL,
&config_info->select_timeout)) == -1)
{
if (errno == EINTR)
return;
(void) fprintf(stderr, "select call failed\n");
perror("select");
exit(1);
}
}
int
doServerConnectSetup(
char * x_server_hostport,
int * server_connect_fd,
struct sockaddr_in * server_sockaddr_in)
{
struct hostent * hostptr;
char * server_name_base;
char server_port_base[10];
int server_port;
int i = 0;
char * tmp_str;
char * tmp_hostport_str;
if ((tmp_hostport_str = strdup (x_server_hostport)) == NULL)
{
(void) fprintf(stderr, "malloc - hostport copy\n");
return FAILURE;
}
tmp_str = x_server_hostport;
while (tmp_str[i] != ':')
tmp_str++;
tmp_str++;
strcpy(server_port_base, tmp_str);
server_name_base = strtok(tmp_hostport_str,":");
server_port = atoi(server_port_base) + X_SERVER_PORT_BASE;
hostptr = gethostbyname(server_name_base);
free(tmp_hostport_str);
if (hostptr == NULL)
{
(void) fprintf(stderr, "gethostbyname call failed\n");
return FAILURE;
}
if ((*server_connect_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
(void) fprintf(stderr, "socket call for server failed: %s\n",
strerror(errno));
return FAILURE;
}
memset(server_sockaddr_in, 0, sizeof(*server_sockaddr_in));
server_sockaddr_in->sin_family = hostptr->h_addrtype;
#ifdef BSD44SOCKETS
server_sockaddr_in->sin_len = sizeof server_sockaddr_in;
#endif
memcpy((char *) &server_sockaddr_in->sin_addr,
hostptr->h_addr,
hostptr->h_length);
server_sockaddr_in->sin_port = htons(server_port);
return SUCCESS;
}
int
doServerConnect(
int * server_connect_fd,
struct sockaddr_in * server_sockaddr_in)
{
if(connect(*server_connect_fd, (struct sockaddr * )server_sockaddr_in,
sizeof(*server_sockaddr_in)) < 0)
{
(void) fprintf(stderr, "connect call to server failed: %s\n",
strerror(errno));
return FAILURE;
}
return SUCCESS;
}