/*
 * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 * Licensed under the GPL.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/termios.h>
#include <sys/wait.h>
#include <net_user.h>
#include <os.h>
#include "slip.h"
#include <um_malloc.h>

static int slip_user_init(void *data, void *dev)
{
	struct slip_data *pri = data;

	pri->dev = dev;
	return 0;
}

static int set_up_tty(int fd)
{
	int i;
	struct termios tios;

	if (tcgetattr(fd, &tios) < 0) {
		printk(UM_KERN_ERR "could not get initial terminal "
		       "attributes\n");
		return -1;
	}

	tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
	tios.c_iflag = IGNBRK | IGNPAR;
	tios.c_oflag = 0;
	tios.c_lflag = 0;
	for (i = 0; i < NCCS; i++)
		tios.c_cc[i] = 0;
	tios.c_cc[VMIN] = 1;
	tios.c_cc[VTIME] = 0;

	cfsetospeed(&tios, B38400);
	cfsetispeed(&tios, B38400);

	if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
		printk(UM_KERN_ERR "failed to set terminal attributes\n");
		return -1;
	}
	return 0;
}

struct slip_pre_exec_data {
	int stdin_fd;
	int stdout_fd;
	int close_me;
};

static void slip_pre_exec(void *arg)
{
	struct slip_pre_exec_data *data = arg;

	if (data->stdin_fd >= 0)
		dup2(data->stdin_fd, 0);
	dup2(data->stdout_fd, 1);
	if (data->close_me >= 0)
		close(data->close_me);
}

static int slip_tramp(char **argv, int fd)
{
	struct slip_pre_exec_data pe_data;
	char *output;
	int pid, fds[2], err, output_len;

	err = os_pipe(fds, 1, 0);
	if (err < 0) {
		printk(UM_KERN_ERR "slip_tramp : pipe failed, err = %d\n",
		       -err);
		goto out;
	}

	err = 0;
	pe_data.stdin_fd = fd;
	pe_data.stdout_fd = fds[1];
	pe_data.close_me = fds[0];
	err = run_helper(slip_pre_exec, &pe_data, argv);
	if (err < 0)
		goto out_close;
	pid = err;

	output_len = UM_KERN_PAGE_SIZE;
	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
	if (output == NULL) {
		printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
		       "buffer\n");
		os_kill_process(pid, 1);
		err = -ENOMEM;
		goto out_close;
	}

	close(fds[1]);
	read_output(fds[0], output, output_len);
	printk("%s", output);

	err = helper_wait(pid);
	close(fds[0]);

	kfree(output);
	return err;

out_close:
	close(fds[0]);
	close(fds[1]);
out:
	return err;
}

static int slip_open(void *data)
{
	struct slip_data *pri = data;
	char version_buf[sizeof("nnnnn\0")];
	char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
	char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
			 NULL };
	int sfd, mfd, err;

	err = get_pty();
	if (err < 0) {
		printk(UM_KERN_ERR "slip-open : Failed to open pty, err = %d\n",
		       -err);
		goto out;
	}
	mfd = err;

	err = open(ptsname(mfd), O_RDWR, 0);
	if (err < 0) {
		printk(UM_KERN_ERR "Couldn't open tty for slip line, "
		       "err = %d\n", -err);
		goto out_close;
	}
	sfd = err;

	if (set_up_tty(sfd))
		goto out_close2;

	pri->slave = sfd;
	pri->slip.pos = 0;
	pri->slip.esc = 0;
	if (pri->gate_addr != NULL) {
		sprintf(version_buf, "%d", UML_NET_VERSION);
		strcpy(gate_buf, pri->gate_addr);

		err = slip_tramp(argv, sfd);

		if (err < 0) {
			printk(UM_KERN_ERR "slip_tramp failed - err = %d\n",
			       -err);
			goto out_close2;
		}
		err = os_get_ifname(pri->slave, pri->name);
		if (err < 0) {
			printk(UM_KERN_ERR "get_ifname failed, err = %d\n",
			       -err);
			goto out_close2;
		}
		iter_addresses(pri->dev, open_addr, pri->name);
	}
	else {
		err = os_set_slip(sfd);
		if (err < 0) {
			printk(UM_KERN_ERR "Failed to set slip discipline "
			       "encapsulation - err = %d\n", -err);
			goto out_close2;
		}
	}
	return mfd;
out_close2:
	close(sfd);
out_close:
	close(mfd);
out:
	return err;
}

static void slip_close(int fd, void *data)
{
	struct slip_data *pri = data;
	char version_buf[sizeof("nnnnn\0")];
	char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
			 NULL };
	int err;

	if (pri->gate_addr != NULL)
		iter_addresses(pri->dev, close_addr, pri->name);

	sprintf(version_buf, "%d", UML_NET_VERSION);

	err = slip_tramp(argv, pri->slave);

	if (err != 0)
		printk(UM_KERN_ERR "slip_tramp failed - errno = %d\n", -err);
	close(fd);
	close(pri->slave);
	pri->slave = -1;
}

int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
{
	return slip_proto_read(fd, buf, len, &pri->slip);
}

int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
{
	return slip_proto_write(fd, buf, len, &pri->slip);
}

static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
			  void *data)
{
	struct slip_data *pri = data;

	if (pri->slave < 0)
		return;
	open_addr(addr, netmask, pri->name);
}

static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
			    void *data)
{
	struct slip_data *pri = data;

	if (pri->slave < 0)
		return;
	close_addr(addr, netmask, pri->name);
}

const struct net_user_info slip_user_info = {
	.init		= slip_user_init,
	.open		= slip_open,
	.close	 	= slip_close,
	.remove	 	= NULL,
	.add_address	= slip_add_addr,
	.delete_address = slip_del_addr,
	.mtu		= BUF_SIZE,
	.max_packet	= BUF_SIZE,
};
