/* vi: set sw=4 ts=4: */
/*
 * Sysctl 1.01 - A utility to read and manipulate the sysctl parameters
 *
 * Copyright 1999 George Staikos
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 *
 * Changelog:
 * v1.01   - added -p <preload> to preload values from a file
 * v1.01.1 - busybox applet aware by <solar@gentoo.org>
 */

#include "libbb.h"

enum {
	FLAG_SHOW_KEYS       = 1 << 0,
	FLAG_SHOW_KEY_ERRORS = 1 << 1,
	FLAG_TABLE_FORMAT    = 1 << 2, /* not implemented */
	FLAG_SHOW_ALL        = 1 << 3,
	FLAG_PRELOAD_FILE    = 1 << 4,
	FLAG_WRITE           = 1 << 5,
};
#define OPTION_STR "neAapw"

static void sysctl_dots_to_slashes(char *name)
{
	char *cptr, *last_good, *end;

	/* Convert minimum number of '.' to '/' so that
	 * we end up with existing file's name.
	 *
	 * Example from bug 3894:
	 * net.ipv4.conf.eth0.100.mc_forwarding ->
	 * net/ipv4/conf/eth0.100/mc_forwarding
	 * NB: net/ipv4/conf/eth0/mc_forwarding *also exists*,
	 * therefore we must start from the end, and if
	 * we replaced even one . -> /, start over again,
	 * but never replace dots before the position
	 * where last replacement occurred.
	 *
	 * Another bug we later had is that
	 * net.ipv4.conf.eth0.100
	 * (without .mc_forwarding) was mishandled.
	 *
	 * To set up testing: modprobe 8021q; vconfig add eth0 100
	 */
	end = name + strlen(name);
	last_good = name - 1;
	*end = '.'; /* trick the loop into trying full name too */

 again:
	cptr = end;
	while (cptr > last_good) {
		if (*cptr == '.') {
			*cptr = '\0';
			//bb_error_msg("trying:'%s'", name);
			if (access(name, F_OK) == 0) {
				if (cptr != end) /* prevent trailing '/' */
					*cptr = '/';
				//bb_error_msg("replaced:'%s'", name);
				last_good = cptr;
				goto again;
			}
			*cptr = '.';
		}
		cptr--;
	}
	*end = '\0';
}

static int sysctl_act_on_setting(char *setting)
{
	int fd, retval = EXIT_SUCCESS;
	char *cptr, *outname;
	char *value = value; /* for compiler */

	outname = xstrdup(setting);

	cptr = outname;
	while (*cptr) {
		if (*cptr == '/')
			*cptr = '.';
		cptr++;
	}

	if (option_mask32 & FLAG_WRITE) {
		cptr = strchr(setting, '=');
		if (cptr == NULL) {
			bb_error_msg("error: '%s' must be of the form name=value",
				outname);
			retval = EXIT_FAILURE;
			goto end;
		}
		value = cptr + 1;	/* point to the value in name=value */
		if (setting == cptr || !*value) {
			bb_error_msg("error: malformed setting '%s'", outname);
			retval = EXIT_FAILURE;
			goto end;
		}
		*cptr = '\0';
		outname[cptr - setting] = '\0';
		/* procps 3.2.7 actually uses these flags */
		fd = open(setting, O_WRONLY|O_CREAT|O_TRUNC, 0666);
	} else {
		fd = open(setting, O_RDONLY);
	}

	if (fd < 0) {
		switch (errno) {
		case ENOENT:
			if (option_mask32 & FLAG_SHOW_KEY_ERRORS)
				bb_error_msg("error: '%s' is an unknown key", outname);
			break;
		default:
			bb_perror_msg("error %sing key '%s'",
					option_mask32 & FLAG_WRITE ?
						"sett" : "read",
					outname);
			break;
		}
		retval = EXIT_FAILURE;
		goto end;
	}

	if (option_mask32 & FLAG_WRITE) {
//TODO: procps 3.2.7 writes "value\n", note trailing "\n"
		xwrite_str(fd, value);
		close(fd);
		if (option_mask32 & FLAG_SHOW_KEYS)
			printf("%s = ", outname);
		puts(value);
	} else {
		char c;

		value = cptr = xmalloc_read(fd, NULL);
		close(fd);
		if (value == NULL) {
			bb_perror_msg("error reading key '%s'", outname);
			goto end;
		}

		/* dev.cdrom.info and sunrpc.transports, for example,
		 * are multi-line. Try "sysctl sunrpc.transports"
		 */
		while ((c = *cptr) != '\0') {
			if (option_mask32 & FLAG_SHOW_KEYS)
				printf("%s = ", outname);
			while (1) {
				fputc(c, stdout);
				cptr++;
				if (c == '\n')
					break;
				c = *cptr;
				if (c == '\0')
					break;
			}
		}
		free(value);
	}
 end:
	free(outname);
	return retval;
}

static int sysctl_act_recursive(const char *path)
{
	DIR *dirp;
	struct stat buf;
	struct dirent *entry;
	char *next;
	int retval = 0;

	stat(path, &buf);
	if (S_ISDIR(buf.st_mode) && !(option_mask32 & FLAG_WRITE)) {
		dirp = opendir(path);
		if (dirp == NULL)
			return -1;
		while ((entry = readdir(dirp)) != NULL) {
			next = concat_subpath_file(path, entry->d_name);
			if (next == NULL)
				continue; /* d_name is "." or ".." */
			/* if path was ".", drop "./" prefix: */
			retval |= sysctl_act_recursive((next[0] == '.' && next[1] == '/') ?
					    next + 2 : next);
			free(next);
		}
		closedir(dirp);
	} else {
		char *name = xstrdup(path);
		retval |= sysctl_act_on_setting(name);
		free(name);
	}

	return retval;
}

/* Set sysctl's from a conf file. Format example:
 * # Controls IP packet forwarding
 * net.ipv4.ip_forward = 0
 */
static int sysctl_handle_preload_file(const char *filename)
{
	char *token[2];
	parser_t *parser;

	parser = config_open(filename);
	/* Must do it _after_ config_open(): */
	xchdir("/proc/sys");
	/* xchroot(".") - if you are paranoid */

//TODO: ';' is comment char too
//TODO: comment may be only at line start. "var=1 #abc" - "1 #abc" is the value
// (but _whitespace_ from ends should be trimmed first (and we do it right))
//TODO: "var==1" is mishandled (must use "=1" as a value, but uses "1")
	while (config_read(parser, token, 2, 2, "# \t=", PARSE_NORMAL)) {
		sysctl_dots_to_slashes(token[0]);
		/* Save ~4 bytes by using parser internals */
		/* parser->line is big enough for sprintf */
		sprintf(parser->line, "%s=%s", token[0], token[1]);
		sysctl_act_recursive(parser->line);
	}
	if (ENABLE_FEATURE_CLEAN_UP)
		config_close(parser);
	return 0;
}

int sysctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int sysctl_main(int argc UNUSED_PARAM, char **argv)
{
	int retval;
	int opt;

	opt = getopt32(argv, "+" OPTION_STR); /* '+' - stop on first non-option */
	argv += optind;
	opt ^= (FLAG_SHOW_KEYS | FLAG_SHOW_KEY_ERRORS);
	option_mask32 = opt;

	if (opt & FLAG_PRELOAD_FILE) {
		option_mask32 |= FLAG_WRITE;
		/* xchdir("/proc/sys") is inside */
		return sysctl_handle_preload_file(*argv ? *argv : "/etc/sysctl.conf");
	}
	xchdir("/proc/sys");
	/* xchroot(".") - if you are paranoid */
	if (opt & (FLAG_TABLE_FORMAT | FLAG_SHOW_ALL)) {
		return sysctl_act_recursive(".");
	}

	retval = 0;
	while (*argv) {
		sysctl_dots_to_slashes(*argv);
		retval |= sysctl_act_recursive(*argv);
		argv++;
	}

	return retval;
}
