#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <dirent.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <sys/param.h>
#include "init.h"
#include "os.h"
#include "user.h"
#include "mode.h"

#define UML_DIR "~/.uml/"

#define UMID_LEN 64

/* Changed by set_umid, which is run early in boot */
char umid[UMID_LEN] = { 0 };

/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
static char *uml_dir = UML_DIR;

static int __init make_uml_dir(void)
{
	char dir[512] = { '\0' };
	int len, err;

	if(*uml_dir == '~'){
		char *home = getenv("HOME");

		err = -ENOENT;
		if(home == NULL){
			printk("make_uml_dir : no value in environment for "
			       "$HOME\n");
			goto err;
		}
		strlcpy(dir, home, sizeof(dir));
		uml_dir++;
	}
	strlcat(dir, uml_dir, sizeof(dir));
	len = strlen(dir);
	if (len > 0 && dir[len - 1] != '/')
		strlcat(dir, "/", sizeof(dir));

	err = -ENOMEM;
	uml_dir = malloc(strlen(dir) + 1);
	if (uml_dir == NULL) {
		printf("make_uml_dir : malloc failed, errno = %d\n", errno);
		goto err;
	}
	strcpy(uml_dir, dir);

	if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
	        printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno));
		err = -errno;
		goto err_free;
	}
	return 0;

err_free:
	free(uml_dir);
err:
	uml_dir = NULL;
	return err;
}

/*
 * Unlinks the files contained in @dir and then removes @dir.
 * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We
 * ignore ENOENT errors for anything (they happen, strangely enough - possibly due
 * to races between multiple dying UML threads).
 */
static int remove_files_and_dir(char *dir)
{
	DIR *directory;
	struct dirent *ent;
	int len;
	char file[256];
	int ret;

	directory = opendir(dir);
	if (directory == NULL) {
		if (errno != ENOENT)
			return -errno;
		else
			return 0;
	}

	while ((ent = readdir(directory)) != NULL) {
		if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
			continue;
		len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
		if (len > sizeof(file)) {
			ret = -E2BIG;
			goto out;
		}

		sprintf(file, "%s/%s", dir, ent->d_name);
		if (unlink(file) < 0 && errno != ENOENT) {
			ret = -errno;
			goto out;
		}
	}

	if (rmdir(dir) < 0 && errno != ENOENT) {
		ret = -errno;
		goto out;
	}

	ret = 0;
out:
	closedir(directory);
	return ret;
}

/* This says that there isn't already a user of the specified directory even if
 * there are errors during the checking.  This is because if these errors
 * happen, the directory is unusable by the pre-existing UML, so we might as
 * well take it over.  This could happen either by
 * 	the existing UML somehow corrupting its umid directory
 * 	something other than UML sticking stuff in the directory
 *	this boot racing with a shutdown of the other UML
 * In any of these cases, the directory isn't useful for anything else.
 *
 * Boolean return: 1 if in use, 0 otherwise.
 */
static inline int is_umdir_used(char *dir)
{
	char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
	char pid[sizeof("nnnnn\0")], *end;
	int dead, fd, p, n, err;

	n = snprintf(file, sizeof(file), "%s/pid", dir);
	if(n >= sizeof(file)){
		printk("is_umdir_used - pid filename too long\n");
		err = -E2BIG;
		goto out;
	}

	dead = 0;
	fd = open(file, O_RDONLY);
	if(fd < 0) {
		fd = -errno;
		if(fd != -ENOENT){
			printk("is_umdir_used : couldn't open pid file '%s', "
			       "err = %d\n", file, -fd);
		}
		goto out;
	}

	err = 0;
	n = read(fd, pid, sizeof(pid));
	if(n < 0){
		printk("is_umdir_used : couldn't read pid file '%s', "
		       "err = %d\n", file, errno);
		goto out_close;
	} else if(n == 0){
		printk("is_umdir_used : couldn't read pid file '%s', "
		       "0-byte read\n", file);
		goto out_close;
	}

	p = strtoul(pid, &end, 0);
	if(end == pid){
		printk("is_umdir_used : couldn't parse pid file '%s', "
		       "errno = %d\n", file, errno);
		goto out_close;
	}

	if((kill(p, 0) == 0) || (errno != ESRCH)){
		printk("umid \"%s\" is already in use by pid %d\n", umid, p);
		return 1;
	}

out_close:
	close(fd);
out:
	return 0;
}

/*
 * Try to remove the directory @dir unless it's in use.
 * Precondition: @dir exists.
 * Returns 0 for success, < 0 for failure in removal or if the directory is in
 * use.
 */
static int umdir_take_if_dead(char *dir)
{
	int ret;
	if (is_umdir_used(dir))
		return -EEXIST;

	ret = remove_files_and_dir(dir);
	if (ret) {
		printk("is_umdir_used - remove_files_and_dir failed with "
		       "err = %d\n", ret);
	}
	return ret;
}

static void __init create_pid_file(void)
{
	char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
	char pid[sizeof("nnnnn\0")];
	int fd, n;

	if(umid_file_name("pid", file, sizeof(file)))
		return;

	fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644);
	if(fd < 0){
		printk("Open of machine pid file \"%s\" failed: %s\n",
		       file, strerror(errno));
		return;
	}

	snprintf(pid, sizeof(pid), "%d\n", getpid());
	n = write(fd, pid, strlen(pid));
	if(n != strlen(pid))
		printk("Write of pid file failed - err = %d\n", errno);

	close(fd);
}

int __init set_umid(char *name)
{
	if(strlen(name) > UMID_LEN - 1)
		return -E2BIG;

	strlcpy(umid, name, sizeof(umid));

	return 0;
}

static int umid_setup = 0;

int __init make_umid(void)
{
	int fd, err;
	char tmp[256];

	if(umid_setup)
		return 0;

	make_uml_dir();

	if(*umid == '\0'){
		strlcpy(tmp, uml_dir, sizeof(tmp));
		strlcat(tmp, "XXXXXX", sizeof(tmp));
		fd = mkstemp(tmp);
		if(fd < 0){
			printk("make_umid - mkstemp(%s) failed: %s\n",
			       tmp, strerror(errno));
			err = -errno;
			goto err;
		}

		close(fd);

		set_umid(&tmp[strlen(uml_dir)]);

		/* There's a nice tiny little race between this unlink and
		 * the mkdir below.  It'd be nice if there were a mkstemp
		 * for directories.
		 */
		if(unlink(tmp)){
			err = -errno;
			goto err;
		}
	}

	snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid);
	err = mkdir(tmp, 0777);
	if(err < 0){
		err = -errno;
		if(err != -EEXIST)
			goto err;

		if (umdir_take_if_dead(tmp) < 0)
			goto err;

		err = mkdir(tmp, 0777);
	}
	if(err){
		err = -errno;
		printk("Failed to create '%s' - err = %d\n", umid, -errno);
		goto err;
	}

	umid_setup = 1;

	create_pid_file();

	err = 0;
 err:
	return err;
}

static int __init make_umid_init(void)
{
	if(!make_umid())
		return 0;

	/* If initializing with the given umid failed, then try again with
	 * a random one.
	 */
	printk("Failed to initialize umid \"%s\", trying with a random umid\n",
	       umid);
	*umid = '\0';
	make_umid();

	return 0;
}

__initcall(make_umid_init);

int __init umid_file_name(char *name, char *buf, int len)
{
	int n, err;

	err = make_umid();
	if(err)
		return err;

	n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name);
	if(n >= len){
		printk("umid_file_name : buffer too short\n");
		return -E2BIG;
	}

	return 0;
}

char *get_umid(void)
{
	return umid;
}

static int __init set_uml_dir(char *name, int *add)
{
	if(*name == '\0'){
		printf("uml_dir can't be an empty string\n");
		return 0;
	}

	if(name[strlen(name) - 1] == '/'){
		uml_dir = name;
		return 0;
	}

	uml_dir = malloc(strlen(name) + 2);
	if(uml_dir == NULL){
		printf("Failed to malloc uml_dir - error = %d\n", errno);

		/* Return 0 here because do_initcalls doesn't look at
		 * the return value.
		 */
		return 0;
	}
	sprintf(uml_dir, "%s/", name);

	return 0;
}

__uml_setup("uml_dir=", set_uml_dir,
"uml_dir=<directory>\n"
"    The location to place the pid and umid files.\n\n"
);

static void remove_umid_dir(void)
{
	char dir[strlen(uml_dir) + UMID_LEN + 1], err;

	sprintf(dir, "%s%s", uml_dir, umid);
	err = remove_files_and_dir(dir);
	if(err)
		printf("remove_umid_dir - remove_files_and_dir failed with "
		       "err = %d\n", err);
}

__uml_exitcall(remove_umid_dir);
