/* This file is the main loop that will just pass the data between
 * the pipes.  It will just stay in a select for most of its life,
 * and it will wake up whenever there is any data.
 */

#include <sys/param.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdio.h>
#include <conndefs.h>
#include <commands.h>

extern fd_set readmaster;
extern int listener_sock;
extern int debug;
extern char NewHost[];

#ifdef XSERVER
extern int xlistener;
#endif XSERVER

loop()
{
    fd_set readfd, exceptfd;
    int sock;
    char count;
    char data[MYBUFSIZ];
    char channel;
    int len;
    struct timeval timeout;

    if(debug)
	printf("Entered Loop\n");

    while (1) {
	bcopy((char *)&readmaster, (char *)&readfd, sizeof(fd_set));
	bcopy((char *)&readmaster, (char *)&exceptfd, sizeof(fd_set));

	timeout.tv_sec = 20;
	timeout.tv_usec = 0;
	select(FD_SETSIZE, &readfd, (fd_set *)0, &exceptfd, &timeout);
 
	count = 0;
	len = 0;
	channel = 0;

#ifdef XSERVER
	if (FD_ISSET(listener_sock, &readfd) ||
	    FD_ISSET(listener_sock, &exceptfd)) { /* New Remote CLIENT? */
	    sock = get_connection(listener_sock);
	    close(sock);	/* Get rid of it -- one at a time! */
	}

	if (FD_ISSET(xlistener, &readfd) ||
	    FD_ISSET(xlistener, &exceptfd)) /* New X Connection */
	    create_new_x_client();
	
#endif XSERVER


	/* Check the main pipe -- forward data from the
	 * pipe to the correct channel or execute the
	 * command if its channel 0
	 */
	if (FD_ISSET(conn_list[0].fd, &readfd) ||
	    FD_ISSET(conn_list[0].fd, &exceptfd)) {
	    receive_data(data, &len, &channel);
	    if (!channel)	/* Channel 0 == Command */
		execute_command(data, len);
	    else
		data_to_channel(channel, data, len);
	}

	/* Check the remote channels and try to get data
	 * from them.  Then forward that data over the
	 * main pipe.
	 */
	for (count = 1; count < MAXCHANNELS; count++) {
	    if (conn_list[count].inuse == INUSE)
		if (FD_ISSET(conn_list[count].fd, &readfd) ||
		    FD_ISSET(conn_list[count].fd, &exceptfd)) {
		    len = data_from_channel(count, data);
		    send_data(count, data, len);
		}
	}
    }
}

#ifdef XSERVER
create_new_x_client()
{
    int sock;
    char channel;
    char data[MAXHOSTNAMELEN+2];
    int i;

    if (sock = get_connection(xlistener)) {
	if (debug)
	    printf("New connection. ");
	for (channel = 1; channel < MAXCHANNELS; channel++) 
	    if (conn_list[channel].inuse == NOTINUSE) {	/* Free channel */
		printf("Channel %d.\n", channel);
		conn_list[channel].inuse = INUSE;
		conn_list[channel].fd = sock;
		add_listener(sock);

		data[0] = channel;
		data[1] = CMD_CREATE;

		for (i = 0; i < MAXHOSTNAMELEN && NewHost[i] != NULL; i++)
		  data[i+2] = NewHost[i];
		send_data(0, data, strlen(data+2)+3);
		listen(xlistener, 1);
		return;
	    }
    }
    printf(" No Channels.\n");
    close (sock);
    return;
}
#endif XSERVER
