/*
 *
 *  OBEX Server
 *
 *  Copyright (C) 2007-2010  Nokia Corporation
 *  Copyright (C) 2007-2010  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <inttypes.h>

#include <glib.h>

#include "obexd.h"
#include "plugin.h"
#include "log.h"
#include "obex.h"
#include "manager.h"
#include "mimetype.h"
#include "service.h"
#include "ftp.h"
#include "filesystem.h"

#define LST_TYPE "x-obex/folder-listing"
#define CAP_TYPE "x-obex/capability"

static const uint8_t FTP_TARGET[TARGET_SIZE] = {
			0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2,
			0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 };

struct ftp_session {
	struct obex_session *os;
	char *folder;
};

static void set_folder(struct ftp_session *ftp, const char *new_folder)
{
	DBG("%p folder %s", ftp, new_folder);

	g_free(ftp->folder);

	ftp->folder = new_folder ? g_strdup(new_folder) : NULL;
}

static int get_by_type(struct ftp_session *ftp, const char *type)
{
	struct obex_session *os = ftp->os;
	const char *capability = obex_option_capability();
	const char *name = obex_get_name(os);
	char *path;
	int err;

	DBG("%p name %s type %s", ftp, name, type);

	if (type == NULL && name == NULL)
		return -EBADR;

	if (type != NULL && g_ascii_strcasecmp(type, CAP_TYPE) == 0)
		return obex_get_stream_start(os, capability);

	if (name != NULL && !is_filename(name))
		return -EBADR;

	path = g_build_filename(ftp->folder, name, NULL);
	err = obex_get_stream_start(os, path);

	g_free(path);

	return err;
}

void *ftp_connect(struct obex_session *os, int *err)
{
	struct ftp_session *ftp;
	const char *root_folder;

	DBG("");

	root_folder = obex_option_root_folder();

	manager_register_session(os);

	ftp = g_new0(struct ftp_session, 1);
	set_folder(ftp, root_folder);
	ftp->os = os;

	if (err)
		*err = 0;

	DBG("session %p created", ftp);

	return ftp;
}

int ftp_get(struct obex_session *os, void *user_data)
{
	struct ftp_session *ftp = user_data;
	const char *type = obex_get_type(os);
	int ret;

	DBG("%p", ftp);

	if (ftp->folder == NULL)
		return -ENOENT;

	ret = get_by_type(ftp, type);
	if (ret < 0)
		return ret;

	return 0;
}

static int ftp_delete(struct ftp_session *ftp, const char *name)
{
	char *path;
	int ret = 0;

	DBG("%p name %s", ftp, name);

	if (!(ftp->folder && name))
		return -EINVAL;

	path = g_build_filename(ftp->folder, name, NULL);

	if (obex_remove(ftp->os, path) < 0)
		ret = -errno;

	g_free(path);

	return ret;
}

int ftp_chkput(struct obex_session *os, void *user_data)
{
	struct ftp_session *ftp = user_data;
	const char *name = obex_get_name(os);
	char *path;
	int ret;

	DBG("%p name %s", ftp, name);

	if (name == NULL)
		return -EBADR;

	if (!is_filename(name))
		return -EBADR;

	if (obex_get_size(os) == OBJECT_SIZE_DELETE)
		return 0;

	path = g_build_filename(ftp->folder, name, NULL);

	ret = obex_put_stream_start(os, path);

	g_free(path);

	return ret;
}

int ftp_put(struct obex_session *os, void *user_data)
{
	struct ftp_session *ftp = user_data;
	const char *name = obex_get_name(os);
	ssize_t size = obex_get_size(os);

	DBG("%p name %s size %zd", ftp, name, size);

	if (ftp->folder == NULL)
		return -EPERM;

	if (name == NULL)
		return -EBADR;

	if (!is_filename(name))
		return -EBADR;

	if (size == OBJECT_SIZE_DELETE)
		return ftp_delete(ftp, name);

	return 0;
}

int ftp_setpath(struct obex_session *os, void *user_data)
{
	struct ftp_session *ftp = user_data;
	const char *root_folder, *name;
	const uint8_t *nonhdr;
	char *fullname;
	struct stat dstat;
	gboolean root;
	int err;

	if (obex_get_non_header_data(os, &nonhdr) != 2) {
		error("Set path failed: flag and constants not found!");
		return -EBADMSG;
	}

	name = obex_get_name(os);
	root_folder = obex_option_root_folder();
	root = g_str_equal(root_folder, ftp->folder);

	DBG("%p name %s", ftp, name);

	/* Check flag "Backup" */
	if ((nonhdr[0] & 0x01) == 0x01) {
		DBG("Set to parent path");

		if (root)
			return -EPERM;

		fullname = g_path_get_dirname(ftp->folder);
		set_folder(ftp, fullname);
		g_free(fullname);

		DBG("Set to parent path: %s", ftp->folder);

		return 0;
	}

	if (!name) {
		DBG("Set path failed: name missing!");
		return -EINVAL;
	}

	if (strlen(name) == 0) {
		DBG("Set to root");
		set_folder(ftp, root_folder);
		return 0;
	}

	/* Check and set to name path */
	if (!is_filename(name)) {
		error("Set path failed: name incorrect!");
		return -EPERM;
	}

	fullname = g_build_filename(ftp->folder, name, NULL);

	DBG("Fullname: %s", fullname);

	err = verify_path(fullname);

	if (err < 0)
		goto done;

	err = stat(fullname, &dstat);

	if (err < 0) {
		err = -errno;

		if (err == -ENOENT)
			goto not_found;

		DBG("stat: %s(%d)", strerror(-err), -err);

		goto done;
	}

	if (S_ISDIR(dstat.st_mode) && (dstat.st_mode & S_IRUSR) &&
						(dstat.st_mode & S_IXUSR)) {
		set_folder(ftp, fullname);
		goto done;
	}

	err = -EPERM;
	goto done;

not_found:
	if (nonhdr[0] != 0) {
		err = -ENOENT;
		goto done;
	}

	if (mkdir(fullname, 0755) <  0) {
		err = -errno;
		DBG("mkdir: %s(%d)", strerror(-err), -err);
		goto done;
	}

	err = 0;
	set_folder(ftp, fullname);

done:
	g_free(fullname);
	return err;
}

static gboolean is_valid_path(const char *path)
{
	gchar **elements, **cur;
	int depth = 0;

	elements = g_strsplit(path, "/", 0);

	for (cur = elements; *cur != NULL; cur++) {
		if (**cur == '\0' || strcmp(*cur, ".") == 0)
			continue;

		if (strcmp(*cur, "..") == 0) {
			depth--;
			if (depth < 0)
				break;
			continue;
		}

		depth++;
	}

	g_strfreev(elements);

	if (depth < 0)
		return FALSE;

	return TRUE;
}

static char *ftp_build_filename(struct ftp_session *ftp, const char *destname)
{
	char *filename;

	/* DestName can either be relative or absolute (FTP style) */
	if (destname[0] == '/')
		filename = g_build_filename(obex_option_root_folder(),
                                                                destname, NULL);
	else
		filename = g_build_filename(ftp->folder, destname, NULL);

	if (is_valid_path(filename + strlen(obex_option_root_folder())))
		return filename;

	g_free(filename);

	return NULL;
}

static int ftp_copy(struct ftp_session *ftp, const char *name,
							const char *destname)
{
	char *source, *destination, *destdir;
	int ret;

	DBG("%p name %s destination %s", ftp, name, destname);

	if (ftp->folder == NULL) {
		error("No folder set");
		return -ENOENT;
	}

	if (name == NULL || destname == NULL)
		return -EINVAL;

	destination = ftp_build_filename(ftp, destname);

	if (destination == NULL)
		return -EBADR;

	destdir = g_path_get_dirname(destination);
	ret = verify_path(destdir);
	g_free(destdir);

	if (ret < 0)
		return ret;

	source = g_build_filename(ftp->folder, name, NULL);

	ret = obex_copy(ftp->os, source, destination);

	g_free(source);
	g_free(destination);

	return ret;
}

static int ftp_move(struct ftp_session *ftp, const char *name,
							const char *destname)
{
	char *source, *destination, *destdir;
	int ret;

	DBG("%p name %s destname %s", ftp, name, destname);

	if (ftp->folder == NULL) {
		error("No folder set");
		return -ENOENT;
	}

	if (name == NULL || destname == NULL)
		return -EINVAL;

	destination = ftp_build_filename(ftp, destname);

	if (destination == NULL)
		return -EBADR;

	destdir = g_path_get_dirname(destination);
	ret = verify_path(destdir);
	g_free(destdir);

	if (ret < 0)
		return ret;

	source = g_build_filename(ftp->folder, name, NULL);

	ret = obex_move(ftp->os, source, destination);

	g_free(source);
	g_free(destination);

	return ret;
}

int ftp_action(struct obex_session *os, void *user_data)
{
	struct ftp_session *ftp = user_data;
	const char *name, *destname;
	uint8_t action_id;

	name = obex_get_name(os);
	if (name == NULL || !is_filename(name))
		return -EBADR;

	destname = obex_get_destname(os);
	action_id = obex_get_action_id(os);

	DBG("%p action 0x%x", ftp, action_id);

	switch (action_id) {
	case 0x00: /* Copy Object */
		return ftp_copy(ftp, name, destname);
	case 0x01: /* Move/Rename Object */
		return ftp_move(ftp, name, destname);
	default:
		return -ENOSYS;
	}
}

void ftp_disconnect(struct obex_session *os, void *user_data)
{
	struct ftp_session *ftp = user_data;

	DBG("%p", ftp);

	manager_unregister_session(os);

	g_free(ftp->folder);
	g_free(ftp);
}

static struct obex_service_driver ftp = {
	.name = "File Transfer server",
	.service = OBEX_FTP,
	.target = FTP_TARGET,
	.target_size = TARGET_SIZE,
	.connect = ftp_connect,
	.get = ftp_get,
	.put = ftp_put,
	.chkput = ftp_chkput,
	.setpath = ftp_setpath,
	.action = ftp_action,
	.disconnect = ftp_disconnect
};

static int ftp_init(void)
{
	return obex_service_driver_register(&ftp);
}

static void ftp_exit(void)
{
	obex_service_driver_unregister(&ftp);
}

OBEX_PLUGIN_DEFINE(ftp, ftp_init, ftp_exit)
