/*
 * Opens a file descriptor and waits for text.
 * Specially formatted text will cause the program
 * to execute the command using a system() call.
 *
 * For a statically linked binary
 *
 *    gcc -static -o readcua readcua.c
 *
 */

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

#define BUFSIZE 1024

main(int argc, char **argv)
{
    char *file = "/dev/cua00";
    char *sysprefix = "!";
    int sysprefixlen;
    char buf[BUFSIZE];
    int fd, l;

    if (argc > 1) {
	file = argv[1];
    }
    if (argc > 2) {
	sysprefix = argv[2];
    }
    
    if ((fd = open(file, O_RDWR, 0777)) == -1) {
	fprintf(stderr, "unable to open %s\n", file);
	perror("open");
	exit(1);
    }

    sysprefixlen = strlen(sysprefix);

    printf("\x1B[3%d;4%dm%-32s %-16s\x1B[3%d;4%dm\n", 3,4, "remote administration tool", "version 1.0", 2,0);
    printf("\x1B[3%d;4%dm%-32s %-16s\x1B[3%d;4%dm\n", 3,4, "system prefix:", sysprefix, 2,0);
    printf("\x1B[3%d;4%dm%-32s %-16s\x1B[3%d;4%dm\n", 3,4, "control codes:", "? ! / \\ & =", 2,0);
    printf("\x1B[3%d;4%dm%-32s %-16s\x1B[3%d;4%dm\n", 3,4, "listening on device", file, 2,0);
    
    for(;;) {
	bzero(buf, BUFSIZE);
	if (l = read(fd, buf, BUFSIZE) > 0) {
	    if (strncmp(buf, sysprefix, sysprefixlen) == 0) {
		switch(buf[sysprefixlen]) {
		case '?':
		    bzero(buf, BUFSIZE);
		    printf("\x1B[3%d;4%dmPING\x1B[3%d;4%dm", 0,2, 2,0);		    
		    fflush(stdout);		    
		    snprintf(buf, BUFSIZE, "PONG\n");
		    write(fd, buf, strlen(buf));
		    printf("\x1B[3%d;4%dm - PONG\x1B[3%d;4%dm\n", 0,2, 2,0);  
		    fflush(stdout);
		    break;
		case '!':
		    printf("\x1B[3%d;4%dmOK\x1B[3%d;4%dm\n", 0,2, 2,0);
		    fflush(stdout);
		    break;
		case '/':
		    printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
		    fflush(stdout);
		    break;
		case '\\':
		    printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\x1B[0;0H");
		    fflush(stdout);
		    break;		    
		case '&':
		    printf("%c", 7);
		    fflush(stdout);
		    break;
		case '=':
		    printf(">\x1B[3%d;4%dm%s\x1B[3%d;4%dm< [%d]\x1B[3%d;4%dm\n", 7,4, buf, 6,0, l, 2,0);
		    fflush(stdout);
		    break;
		default:
		    printf("\x1B[3%d;4%dm", 3,0);
		    fflush(stdout);
		    printf(buf + sysprefixlen);
		    printf("\x1B[3%d;4%dm", 7,0);
		    fflush(stdout);
		    system(buf + sysprefixlen);
		    printf("\x1B[3%d;4%dm", 2,0);
		    fflush(stdout);
		    break;
		}
	    } else {
		if (l==1 && buf[0]==10) {
		    fflush(stdout);
		} else {
		    printf("\x1B[3%d;4%dm%s\x1B[3%d;4%dm", 2,0, buf, 2,0);
		    fflush(stdout);		
		}
	    }
	};
    }
}

