/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2011 Nest Labs, Inc. All rights reserved.
 *
 *    Author: Grant Erickson <grant@nestlabs.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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 <errno.h>
#include <string.h>

#include <sys/resource.h>

#include <glib.h>

#include <connman/log.h>

#define CONNMAN_RLIMIT_SET(r, lp, err, label)				\
	do {								\
		err = __connman_rlimit_set(r, lp, #r);			\
		if (err < 0)						\
			goto label;					\
	} while (0)

struct connman_rlimit {
	gboolean set;
	rlim_t limit;
};

struct connman_rlimits {
#if defined(RLIMIT_AS)
	struct connman_rlimit as;
#endif
	struct connman_rlimit core, data, fsize, nofile, stack;
#if defined(RLIMIT_MEMLOCK)
	struct connman_rlimit memlock;
#endif
#if defined(RLIMIT_NPROC)
	struct connman_rlimit nproc;
#endif
};

#if defined(RLIMIT_AS)
static const char * RLIMIT_AS_KEY	= "rlimit-as";
#endif
static const char * RLIMIT_CORE_KEY	= "rlimit-core";
static const char * RLIMIT_DATA_KEY	= "rlimit-data";
static const char * RLIMIT_FSIZE_KEY	= "rlimit-fsize";
static const char * RLIMIT_NOFILE_KEY	= "rlimit-nofile";
static const char * RLIMIT_STACK_KEY 	= "rlimit-stack";
#if defined(RLIMIT_NPROC)
static const char * RLIMIT_NPROC_KEY 	= "rlimit-nproc";
#endif
#if defined(RLIMIT_MEMLOCK)
static const char * RLIMIT_MEMLOCK_KEY	= "rlimit-memlock";
#endif

static int set_one_rlimit(int resource, rlim_t limit, const char *name)
{
	int err;
	struct rlimit rl;
	rl.rlim_cur = rl.rlim_max = limit;

	DBG("resource %d limit %u name %s", resource, (unsigned)limit, name);

	err = setrlimit(resource, &rl);

	if (err < 0) {
		connman_warn("setrlimit(%s, {%u, %u}) failed: %s",
			     name, (unsigned)limit,
			     (unsigned)limit,
			     strerror(errno));

		return -errno;
	}

	return err;
}

static inline int __connman_rlimit_set(int resource,
				       const struct connman_rlimit *limit,
				       const char *name)
{
	int err = 0;

	if (limit->set)
		err = set_one_rlimit(resource, limit->limit, name);

	return err;
}

static int __connman_rlimits_enforce(const struct connman_rlimits *limits)
{
	int err;

	if (limits == NULL)
		return 0;

#if defined(RLIMIT_AS)
	CONNMAN_RLIMIT_SET(RLIMIT_AS,	   &limits->as,	     err, done);
#endif
	CONNMAN_RLIMIT_SET(RLIMIT_CORE,	   &limits->core,    err, done);
	CONNMAN_RLIMIT_SET(RLIMIT_DATA,	   &limits->data,    err, done);
	CONNMAN_RLIMIT_SET(RLIMIT_FSIZE,   &limits->fsize,   err, done);
	CONNMAN_RLIMIT_SET(RLIMIT_NOFILE,  &limits->nofile,  err, done);
	CONNMAN_RLIMIT_SET(RLIMIT_STACK,   &limits->stack,   err, done);
#if defined(RLIMIT_MEMLOCK)
	CONNMAN_RLIMIT_SET(RLIMIT_MEMLOCK, &limits->memlock, err, done);
#endif
#if defined(RLIMIT_NPROC)
	CONNMAN_RLIMIT_SET(RLIMIT_NPROC,   &limits->nproc,   err, done);
#endif

 done:
	return err;
}

static void __connman_rlimit_read(GKeyFile *keyfile, const gchar *key,
				  struct connman_rlimit *limit)
{
	const char *group = "rlimits";
	gint temp;
	GError *error = NULL;

	if (keyfile != NULL && key != NULL && limit != NULL) {
		temp = g_key_file_get_integer(keyfile, group, key, &error);

		DBG("key %s temp %d error %p", key, temp, error);

		if (error == NULL) {
			limit->set = TRUE;
			limit->limit = temp;
		} else {
			limit->set = FALSE;
			limit->limit = 0;
			g_clear_error(&error);
		}

		DBG("set %u limit %u", limit->set, (unsigned)limit->limit);
	}
}

static GKeyFile *__connman_rlimits_open(const gchar *path)
{
	GKeyFile *keyfile;
	gchar *data = NULL;
	gboolean result;
	gsize length;

	DBG("path %s", path);

	result = g_file_get_contents(path, &data, &length, NULL);

	keyfile = g_key_file_new();

	if (result == FALSE)
		goto done;

	if (length > 0)
		g_key_file_load_from_data(keyfile, data, length, 0, NULL);

	g_free(data);

done:
	DBG("keyfile %p", keyfile);

	return keyfile;
}

static int __connman_rlimits_load(const gchar *path,
				  struct connman_rlimits *limits)
{
	GKeyFile *keyfile;

	if (limits == NULL)
		return -EINVAL;

	keyfile = __connman_rlimits_open(path);

	if (keyfile == NULL)
		return -EIO;

#if defined(RLIMIT_AS)
	__connman_rlimit_read(keyfile, RLIMIT_AS_KEY,      &limits->as);
#endif
	__connman_rlimit_read(keyfile, RLIMIT_CORE_KEY,    &limits->core);
	__connman_rlimit_read(keyfile, RLIMIT_DATA_KEY,    &limits->data);
	__connman_rlimit_read(keyfile, RLIMIT_FSIZE_KEY,   &limits->fsize);
	__connman_rlimit_read(keyfile, RLIMIT_NOFILE_KEY,  &limits->nofile);
	__connman_rlimit_read(keyfile, RLIMIT_STACK_KEY,   &limits->stack);
#if defined(RLIMIT_NPROC)
	__connman_rlimit_read(keyfile, RLIMIT_NPROC_KEY,   &limits->nproc);
#endif
#if defined(RLIMIT_MEMLOCK)
	__connman_rlimit_read(keyfile, RLIMIT_MEMLOCK_KEY, &limits->memlock);
#endif

	g_key_file_free(keyfile);

	return 0;
}

int __connman_rlimits_init(const gchar *path)
{
	struct connman_rlimits rlimits;
	int err;

	if (path == NULL)
		return -EINVAL;

	err = __connman_rlimits_load(path, &rlimits);

	if (err < 0)
		return err;

	return __connman_rlimits_enforce(&rlimits);
}
