/* 
 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and 
 * geoffrey hing <ghing@net.ohio-state.edu>
 * Licensed under the GPL
 */

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include "init.h"
#include "user.h"
#include "kern_util.h"
#include "os.h"

#define TTY_LOG_DIR "./"

/* Set early in boot and then unchanged */
static char *tty_log_dir = TTY_LOG_DIR;
static int tty_log_fd = -1;

#define TTY_LOG_OPEN 1
#define TTY_LOG_CLOSE 2
#define TTY_LOG_WRITE 3
#define TTY_LOG_EXEC 4

#define TTY_READ 1
#define TTY_WRITE 2

struct tty_log_buf {
	int what;
	unsigned long tty;
	int len;
	int direction;
	unsigned long sec;
	unsigned long usec;
};

int open_tty_log(void *tty, void *current_tty)
{
	struct timeval tv;
	struct tty_log_buf data;
	char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
	int fd;

	gettimeofday(&tv, NULL);
	if(tty_log_fd != -1){
		data = ((struct tty_log_buf) { .what 	= TTY_LOG_OPEN,
					       .tty  = (unsigned long) tty,
					       .len  = sizeof(current_tty),
					       .direction = 0,
					       .sec = tv.tv_sec,
					       .usec = tv.tv_usec } );
		os_write_file(tty_log_fd, &data, sizeof(data));
		os_write_file(tty_log_fd, &current_tty, data.len);
		return(tty_log_fd);
	}

	sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
 		(unsigned int) tv.tv_usec);

	fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
			  0644);
	if(fd < 0){
		printk("open_tty_log : couldn't open '%s', errno = %d\n",
		       buf, -fd);
	}
	return(fd);
}

void close_tty_log(int fd, void *tty)
{
	struct tty_log_buf data;
	struct timeval tv;

	if(tty_log_fd != -1){
		gettimeofday(&tv, NULL);
		data = ((struct tty_log_buf) { .what 	= TTY_LOG_CLOSE,
					       .tty  = (unsigned long) tty,
					       .len  = 0,
					       .direction = 0,
					       .sec = tv.tv_sec,
					       .usec = tv.tv_usec } );
		os_write_file(tty_log_fd, &data, sizeof(data));
		return;
	}
	os_close_file(fd);
}

static int log_chunk(int fd, const char *buf, int len)
{
	int total = 0, try, missed, n;
	char chunk[64];

	while(len > 0){
		try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
		missed = copy_from_user_proc(chunk, (char *) buf, try);
		try -= missed;
		n = os_write_file(fd, chunk, try);
		if(n != try) {
			if(n < 0)
				return(n);
			return(-EIO);
		}
		if(missed != 0)
			return(-EFAULT);

		len -= try;
		total += try;
		buf += try;
	}

	return(total);
}

int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
{
	struct timeval tv;
	struct tty_log_buf data;
	int direction;

	if(fd == tty_log_fd){
		gettimeofday(&tv, NULL);
		direction = is_read ? TTY_READ : TTY_WRITE;
		data = ((struct tty_log_buf) { .what 	= TTY_LOG_WRITE,
					       .tty  = (unsigned long) tty,
					       .len  = len,
					       .direction = direction,
					       .sec = tv.tv_sec,
					       .usec = tv.tv_usec } );
		os_write_file(tty_log_fd, &data, sizeof(data));
	}

	return(log_chunk(fd, buf, len));
}

void log_exec(char **argv, void *tty)
{
	struct timeval tv;
	struct tty_log_buf data;
	char **ptr,*arg;
	int len;

	if(tty_log_fd == -1) return;

	gettimeofday(&tv, NULL);

	len = 0;
	for(ptr = argv; ; ptr++){
		if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
			return;
		if(arg == NULL) break;
		len += strlen_user_proc(arg);
	}

	data = ((struct tty_log_buf) { .what 	= TTY_LOG_EXEC,
				       .tty  = (unsigned long) tty,
				       .len  = len,
				       .direction = 0,
				       .sec = tv.tv_sec,
				       .usec = tv.tv_usec } );
	os_write_file(tty_log_fd, &data, sizeof(data));

	for(ptr = argv; ; ptr++){
		if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
			return;
		if(arg == NULL) break;
		log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
	}
}

extern void register_tty_logger(int (*opener)(void *, void *),
				int (*writer)(int, const char *, int,
					      void *, int),
				void (*closer)(int, void *));

static int register_logger(void)
{
	register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
	return(0);
}

__uml_initcall(register_logger);

static int __init set_tty_log_dir(char *name, int *add)
{
	tty_log_dir = name;
	return 0;
}

__uml_setup("tty_log_dir=", set_tty_log_dir,
"tty_log_dir=<directory>\n"
"    This is used to specify the directory where the logs of all pty\n"
"    data from this UML machine will be written.\n\n"
);

static int __init set_tty_log_fd(char *name, int *add)
{
	char *end;

	tty_log_fd = strtoul(name, &end, 0);
	if((*end != '\0') || (end == name)){
		printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
		tty_log_fd = -1;
	}

	*add = 0;
	return 0;
}

__uml_setup("tty_log_fd=", set_tty_log_fd,
"tty_log_fd=<fd>\n"
"    This is used to specify a preconfigured file descriptor to which all\n"
"    tty data will be written.  Preconfigure the descriptor with something\n"
"    like '10>tty_log tty_log_fd=10'.\n\n"
);


/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * Emacs will notice this stuff at the end of the file and automatically
 * adjust the settings for this buffer only.  This must remain at the end
 * of the file.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-file-style: "linux"
 * End:
 */
