/*
 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
 * Licensed under the GPL
 */

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <termios.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include "kern_util.h"
#include "user.h"
#include "chan_user.h"
#include "port.h"
#include "os.h"
#include "um_malloc.h"

struct port_chan {
	int raw;
	struct termios tt;
	void *kernel_data;
	char dev[sizeof("32768\0")];
};

static void *port_init(char *str, int device, const struct chan_opts *opts)
{
	struct port_chan *data;
	void *kern_data;
	char *end;
	int port;

	if(*str != ':'){
		printk("port_init : channel type 'port' must specify a "
		       "port number\n");
		return NULL;
	}
	str++;
	port = strtoul(str, &end, 0);
	if((*end != '\0') || (end == str)){
		printk("port_init : couldn't parse port '%s'\n", str);
		return NULL;
	}

	kern_data = port_data(port);
	if(kern_data == NULL)
		return NULL;

	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
	if(data == NULL)
		goto err;

	*data = ((struct port_chan) { .raw  		= opts->raw,
				      .kernel_data 	= kern_data });
	sprintf(data->dev, "%d", port);

	return data;
 err:
	port_kern_free(kern_data);
	return NULL;
}

static void port_free(void *d)
{
	struct port_chan *data = d;

	port_kern_free(data->kernel_data);
	kfree(data);
}

static int port_open(int input, int output, int primary, void *d,
		     char **dev_out)
{
	struct port_chan *data = d;
	int fd, err;

	fd = port_wait(data->kernel_data);
	if((fd >= 0) && data->raw){
		CATCH_EINTR(err = tcgetattr(fd, &data->tt));
		if(err)
			return err;

		err = raw(fd);
		if(err)
			return err;
	}
	*dev_out = data->dev;
	return fd;
}

static void port_close(int fd, void *d)
{
	struct port_chan *data = d;

	port_remove_dev(data->kernel_data);
	os_close_file(fd);
}

const struct chan_ops port_ops = {
	.type		= "port",
	.init		= port_init,
	.open		= port_open,
	.close		= port_close,
	.read	        = generic_read,
	.write		= generic_write,
	.console_write	= generic_console_write,
	.window_size	= generic_window_size,
	.free		= port_free,
	.winch		= 1,
};

int port_listen_fd(int port)
{
	struct sockaddr_in addr;
	int fd, err, arg;

	fd = socket(PF_INET, SOCK_STREAM, 0);
	if(fd == -1)
		return -errno;

	arg = 1;
	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0){
		err = -errno;
		goto out;
	}

	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){
		err = -errno;
		goto out;
	}

	if(listen(fd, 1) < 0){
		err = -errno;
		goto out;
	}

	err = os_set_fd_block(fd, 0);
	if(err < 0)
		goto out;

	return fd;
 out:
	os_close_file(fd);
	return err;
}

struct port_pre_exec_data {
	int sock_fd;
	int pipe_fd;
};

void port_pre_exec(void *arg)
{
	struct port_pre_exec_data *data = arg;

	dup2(data->sock_fd, 0);
	dup2(data->sock_fd, 1);
	dup2(data->sock_fd, 2);
	os_close_file(data->sock_fd);
	dup2(data->pipe_fd, 3);
	os_shutdown_socket(3, 1, 0);
	os_close_file(data->pipe_fd);
}

int port_connection(int fd, int *socket, int *pid_out)
{
	int new, err;
	char *argv[] = { "/usr/sbin/in.telnetd", "-L",
			 "/usr/lib/uml/port-helper", NULL };
	struct port_pre_exec_data data;

	new = os_accept_connection(fd);
	if(new < 0)
		return new;

	err = os_pipe(socket, 0, 0);
	if(err < 0)
		goto out_close;

	data = ((struct port_pre_exec_data)
		{ .sock_fd  		= new,
		  .pipe_fd 		= socket[1] });

	err = run_helper(port_pre_exec, &data, argv);
	if(err < 0)
		goto out_shutdown;

	*pid_out = err;
	return new;

 out_shutdown:
	os_shutdown_socket(socket[0], 1, 1);
	os_close_file(socket[0]);
	os_shutdown_socket(socket[1], 1, 1);
	os_close_file(socket[1]);
 out_close:
	os_close_file(new);
	return err;
}
