/* This file contains the code to concatinate the multitude of
 * connections into ONE TCP connection.
 */

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

extern int debug;
extern int errno;

send_data(channel, data, len)
char channel;
char data[];
int len;
{
    int i;
    char hi, low;
    char *p = data;

    hi = len/100;
    low = len%100;

    if (len <= 0)
	return;

    if (debug)
	printf("Writing data.  Channel %d, %d (%d,%d) bytes.\n", channel, len,
	       hi, low);

    if (write(conn_list[0].fd, &channel, 1) < 0) 
	if (errno == EPIPE) {
	    main_pipe_closed();
	    return -1;
	}
    else
	while(write(conn_list[0].fd, &channel, 1) != 1);

    while (write(conn_list[0].fd, &hi, 1) != 1);
    while (write(conn_list[0].fd, &low, 1) != 1);
    
    if (debug) {
	for (i = 0; i < len; i++) 
	    printf("%x ", data[i]);
	printf("\n");
    }

    while (len > 0) {
	i = write(conn_list[0].fd, p, len);

	if (i > 0) {
	    len -= i;
	    p += i;
	} else if (i < 0 && errno == EPIPE) {
	    fprintf(stderr, "Lost main socket!\n");
	    main_pipe_closed();
	    return -1;
	} else {
	    if (debug)
		fprintf(stderr, "Bad write!\n");
	}
    }
    return 1;

}

receive_data(data, len, channel)
char data[];
int *len;
char *channel;
{
    int i;
    char hi, low;
    int numtoread;
    char *p = data;
    fd_set readfd;

    if (debug)
	printf("Reading data...");

    *len = 0;
    hi = low = 0;

    if (read (conn_list[0].fd, channel, 1) < 1) {
	printf("NULL Read from main socket.\n");
	main_pipe_closed();
	return -1;
    }    

    /* Make sure I get good data if it got past the channel! */

    FD_ZERO(&readfd);
    FD_SET(conn_list[0].fd, &readfd);
    select(conn_list[0].fd +1, &readfd, (fd_set *)0, &readfd, NULL);
    if (read (conn_list[0].fd, &hi, 1) != 1) {
	main_pipe_closed();
	return -1;
    }

    FD_ZERO(&readfd);
    FD_SET(conn_list[0].fd, &readfd);
    select(conn_list[0].fd +1, &readfd, (fd_set *)0, &readfd, NULL);
    if (read (conn_list[0].fd, &low, 1) != 1) {
	main_pipe_closed();
	return -1;
    }

    *len = 100*hi + low;

    if (*len <= 0) {
	fprintf(stderr, "I THOUGHT I had to read %d bytes! (%d %d)\n", len, hi, low);
	main_pipe_closed();
	return -1;
    }

    if (debug)
	printf("Channel %d, %d (%d,%d) bytes\n", *channel, *len, hi, low);

    numtoread = *len;
    while (numtoread > 0) {
	i = read (conn_list[0].fd, p, numtoread);

	if (i > 0) {
	    numtoread -= i;
	    p += i;
	} else if (i < 0) {
	    switch(errno) {

	    case EWOULDBLOCK:
		continue;

	    default:
		perror("Read");
		fprintf(stderr, "Lost main socket!\n");
		main_pipe_closed();
		return -1;
	    }
	} else {		/* i == 0 */
	    perror("Read");
	    fprintf(stderr, "Zero Read\n");
	    main_pipe_closed();
	    return -1;
	}
    }

    if (debug) {
	for (i = 0; i < *len; i++)
	    printf("%x ", data[i]);
	printf("\n");
    }

    return(0);

}

execute_command(data, len)
char data[];
int len;
{
    char channel = data[0];
    char command = data[1];

    if (command > HIGHEST_COMMAND) {
	fprintf(stderr, "Unknown command: %d\n", command);
	return;
    }

    commands[command](channel, data+2);
}
    
send_remote_command(command, channel)
char command;
char channel;
{
    char data[5];

    data[0] = channel;
    data[1] = command;
    data[2] = 0;
    data[3] = 0;

    send_data(0, data, 2);
}

