/* vi: set sw=4 ts=4: */
/*
 *
 * mdev - Mini udev for busybox
 *
 * Copyright 2005 Rob Landley <rob@landley.net>
 * Copyright 2005 Frank Sorenson <frank@tuxrocks.com>
 *
 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
 */

#include "libbb.h"
#include "xregex.h"

struct globals {
	int root_major, root_minor;
};
#define G (*(struct globals*)&bb_common_bufsiz1)
#define root_major (G.root_major)
#define root_minor (G.root_minor)

/* Prevent infinite loops in /sys symlinks */
#define MAX_SYSFS_DEPTH 3

/* We use additional 64+ bytes in make_device() */
#define SCRATCH_SIZE 80

/* Builds an alias path.
 * This function potentionally reallocates the alias parameter.
 */
static char *build_alias(char *alias, const char *device_name)
{
	char *dest;

	/* ">bar/": rename to bar/device_name */
	/* ">bar[/]baz": rename to bar[/]baz */
	dest = strrchr(alias, '/');
	if (dest) { /* ">bar/[baz]" ? */
		*dest = '\0'; /* mkdir bar */
		bb_make_directory(alias, 0755, FILEUTILS_RECUR);
		*dest = '/';
		if (dest[1] == '\0') { /* ">bar/" => ">bar/device_name" */
			dest = alias;
			alias = concat_path_file(alias, device_name);
			free(dest);
		}
	}

	return alias;
}

/* mknod in /dev based on a path like "/sys/block/hda/hda1" */
/* NB: "mdev -s" may call us many times, do not leak memory/fds! */
static void make_device(char *path, int delete)
{
	const char *device_name;
	int major, minor, type, len;
	int mode = 0660;
	uid_t uid = 0;
	gid_t gid = 0;
	char *dev_maj_min = path + strlen(path);
	char *command = NULL;
	char *alias = NULL;
	char aliaslink = aliaslink; /* for compiler */

	/* Force the configuration file settings exactly. */
	umask(0);

	/* Try to read major/minor string.  Note that the kernel puts \n after
	 * the data, so we don't need to worry about null terminating the string
	 * because sscanf() will stop at the first nondigit, which \n is.  We
	 * also depend on path having writeable space after it.
	 */
	if (!delete) {
		strcpy(dev_maj_min, "/dev");
		len = open_read_close(path, dev_maj_min + 1, 64);
		*dev_maj_min++ = '\0';
		if (len < 1) {
			if (!ENABLE_FEATURE_MDEV_EXEC)
				return;
			/* no "dev" file, so just try to run script */
			*dev_maj_min = '\0';
		}
	}

	/* Determine device name, type, major and minor */
	device_name = bb_basename(path);
	/* http://kernel.org/doc/pending/hotplug.txt says that only
	 * "/sys/block/..." is for block devices. "/sys/bus" etc is not.
	 * But since 2.6.25 block devices are also in /sys/class/block.
	 * We use strstr("/block/") to forestall future surprises. */
        type = S_IFCHR;
	if (strstr(path, "/block/"))
	        type = S_IFBLK;

	if (ENABLE_FEATURE_MDEV_CONF) {
		parser_t *parser = config_open("/etc/mdev.conf");
		char *tokens[5];

		/* If we have config file, look up user settings */
		if (!parser)
			goto end_parse;

		while (config_read(parser, tokens, 4, 3, "# \t", PARSE_LAST_IS_GREEDY)) {
			regmatch_t off[1+9*ENABLE_FEATURE_MDEV_RENAME_REGEXP];
			char *val;

			/* Fields: regex uid:gid mode [alias] [cmd] */

			/* 1st field: regex to match this device */
			{
				regex_t match;
				int result;

				/* Is this it? */
				xregcomp(&match, tokens[0], REG_EXTENDED);
				result = regexec(&match, device_name, ARRAY_SIZE(off), off, 0);
				regfree(&match);

				//bb_error_msg("matches:");
				//for (int i = 0; i < ARRAY_SIZE(off); i++) {
				//	if (off[i].rm_so < 0) continue;
				//	bb_error_msg("match %d: '%.*s'\n", i,
				//		(int)(off[i].rm_eo - off[i].rm_so),
				//		device_name + off[i].rm_so);
				//}

				/* If not this device, skip rest of line */
				/* (regexec returns whole pattern as "range" 0) */
				if (result || off[0].rm_so
				 || ((int)off[0].rm_eo != (int)strlen(device_name))
				) {
					continue;
				}
			}

			/* This line matches: stop parsing the file
			 * after parsing the rest of fields */

			/* 2nd field: uid:gid - device ownership */
			{
				struct passwd *pass;
				struct group *grp;
				char *str_uid = tokens[1];
				char *str_gid = strchrnul(str_uid, ':');

				if (*str_gid)
					*str_gid++ = '\0';
				/* Parse UID */
				pass = getpwnam(str_uid);
				if (pass)
					uid = pass->pw_uid;
				else
					uid = strtoul(str_uid, NULL, 10);
				/* Parse GID */
				grp = getgrnam(str_gid);
				if (grp)
					gid = grp->gr_gid;
				else
					gid = strtoul(str_gid, NULL, 10);
			}

			/* 3rd field: mode - device permissions */
			mode = strtoul(tokens[2], NULL, 8);

			val = tokens[3];
			/* 4th field (opt): >alias */
#if ENABLE_FEATURE_MDEV_RENAME
			if (!val)
				break;
			aliaslink = *val;
			if (aliaslink == '>' || aliaslink == '=') {
				char *s;
#if ENABLE_FEATURE_MDEV_RENAME_REGEXP
				char *p;
				unsigned i, n;
#endif
				char *a = val;
				s = strchr(val, ' ');
				val = (s && s[1]) ? s+1 : NULL;
#if ENABLE_FEATURE_MDEV_RENAME_REGEXP
				/* substitute %1..9 with off[1..9], if any */
				n = 0;
				s = a;
				while (*s)
					if (*s++ == '%')
						n++;

				p = alias = xzalloc(strlen(a) + n * strlen(device_name));
				s = a + 1;
				while (*s) {
					*p = *s;
					if ('%' == *s) {
						i = (s[1] - '0');
						if (i <= 9 && off[i].rm_so >= 0) {
							n = off[i].rm_eo - off[i].rm_so;
							strncpy(p, device_name + off[i].rm_so, n);
							p += n - 1;
							s++;
						}
					}
					p++;
					s++;
				}
#else
				alias = xstrdup(a + 1);
#endif
			}
#endif /* ENABLE_FEATURE_MDEV_RENAME */

			/* The rest (opt): command to run */
			if (!val)
				break;
			if (ENABLE_FEATURE_MDEV_EXEC) {
				const char *s = "@$*";
				const char *s2 = strchr(s, *val);

				if (!s2)
					bb_error_msg_and_die("bad line %u", parser->lineno);

				/* Correlate the position in the "@$*" with the delete
				 * step so that we get the proper behavior:
				 * @cmd: run on create
				 * $cmd: run on delete
				 * *cmd: run on both
				 */
				if ((s2 - s + 1) /*1/2/3*/ & /*1/2*/ (1 + delete)) {
					command = xstrdup(val + 1);
				}
			}
			/* end of field parsing */
			break; /* we found matching line, stop */
		} /* end of "while line is read from /etc/mdev.conf" */

		config_close(parser);
	}
 end_parse:

	if (!delete && sscanf(dev_maj_min, "%u:%u", &major, &minor) == 2) {

		if (ENABLE_FEATURE_MDEV_RENAME)
			unlink(device_name);

		if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST)
			bb_perror_msg_and_die("mknod %s", device_name);

		if (major == root_major && minor == root_minor)
			symlink(device_name, "root");

		if (ENABLE_FEATURE_MDEV_CONF) {
			chown(device_name, uid, gid);

			if (ENABLE_FEATURE_MDEV_RENAME && alias) {
				alias = build_alias(alias, device_name);

				/* move the device, and optionally
				 * make a symlink to moved device node */
				if (rename(device_name, alias) == 0 && aliaslink == '>')
					symlink(alias, device_name);

				free(alias);
			}
		}
	}

	if (ENABLE_FEATURE_MDEV_EXEC && command) {
		/* setenv will leak memory, use putenv/unsetenv/free */
		char *s = xasprintf("MDEV=%s", device_name);
		putenv(s);
		if (system(command) == -1)
			bb_perror_msg_and_die("can't run '%s'", command);
		s[4] = '\0';
		unsetenv(s);
		free(s);
		free(command);
	}

	if (delete) {
		unlink(device_name);
		/* At creation time, device might have been moved
		 * and a symlink might have been created. Undo that. */
		if (ENABLE_FEATURE_MDEV_RENAME && alias) {
			alias = build_alias(alias, device_name);
			unlink(alias);
			free(alias);
		}
	}
}

/* File callback for /sys/ traversal */
static int FAST_FUNC fileAction(const char *fileName,
		struct stat *statbuf UNUSED_PARAM,
		void *userData,
		int depth UNUSED_PARAM)
{
	size_t len = strlen(fileName) - 4; /* can't underflow */
	char *scratch = userData;

	/* len check is for paranoid reasons */
	if (strcmp(fileName + len, "/dev") != 0 || len >= PATH_MAX)
		return FALSE;

	strcpy(scratch, fileName);
	scratch[len] = '\0';
	make_device(scratch, 0);

	return TRUE;
}

/* Directory callback for /sys/ traversal */
static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM,
		struct stat *statbuf UNUSED_PARAM,
		void *userData UNUSED_PARAM,
		int depth)
{
	return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE);
}

/* For the full gory details, see linux/Documentation/firmware_class/README
 *
 * Firmware loading works like this:
 * - kernel sets FIRMWARE env var
 * - userspace checks /lib/firmware/$FIRMWARE
 * - userspace waits for /sys/$DEVPATH/loading to appear
 * - userspace writes "1" to /sys/$DEVPATH/loading
 * - userspace copies /lib/firmware/$FIRMWARE into /sys/$DEVPATH/data
 * - userspace writes "0" (worked) or "-1" (failed) to /sys/$DEVPATH/loading
 * - kernel loads firmware into device
 */
static void load_firmware(const char *const firmware, const char *const sysfs_path)
{
	int cnt;
	int firmware_fd, loading_fd, data_fd;

	/* check for /lib/firmware/$FIRMWARE */
	xchdir("/lib/firmware");
	firmware_fd = xopen(firmware, O_RDONLY);

	/* in case we goto out ... */
	data_fd = -1;

	/* check for /sys/$DEVPATH/loading ... give 30 seconds to appear */
	xchdir(sysfs_path);
	for (cnt = 0; cnt < 30; ++cnt) {
		loading_fd = open("loading", O_WRONLY);
		if (loading_fd != -1)
			goto loading;
		sleep(1);
	}
	goto out;

 loading:
	/* tell kernel we're loading by `echo 1 > /sys/$DEVPATH/loading` */
	if (full_write(loading_fd, "1", 1) != 1)
		goto out;

	/* load firmware by `cat /lib/firmware/$FIRMWARE > /sys/$DEVPATH/data */
	data_fd = open("data", O_WRONLY);
	if (data_fd == -1)
		goto out;
	cnt = bb_copyfd_eof(firmware_fd, data_fd);

	/* tell kernel result by `echo [0|-1] > /sys/$DEVPATH/loading` */
	if (cnt > 0)
		full_write(loading_fd, "0", 1);
	else
		full_write(loading_fd, "-1", 2);

 out:
	if (ENABLE_FEATURE_CLEAN_UP) {
		close(firmware_fd);
		close(loading_fd);
		close(data_fd);
	}
}

int mdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int mdev_main(int argc UNUSED_PARAM, char **argv)
{
	RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE);

	/* We can be called as hotplug helper */
	/* Kernel cannot provide suitable stdio fds for us, do it ourself */
#if 1
	bb_sanitize_stdio();
#else
	/* Debug code */
	/* Replace LOGFILE by other file or device name if you need */
#define LOGFILE "/dev/console"
	/* Just making sure fd 0 is not closed,
	 * we don't really intend to read from it */
	xmove_fd(xopen("/", O_RDONLY), STDIN_FILENO);
	xmove_fd(xopen(LOGFILE, O_WRONLY|O_APPEND), STDOUT_FILENO);
	xmove_fd(xopen(LOGFILE, O_WRONLY|O_APPEND), STDERR_FILENO);
#endif

	xchdir("/dev");

	if (argv[1] && !strcmp(argv[1], "-s")) {
		/* Scan:
		 * mdev -s
		 */
		struct stat st;

		xstat("/", &st);
		root_major = major(st.st_dev);
		root_minor = minor(st.st_dev);

		/* ACTION_FOLLOWLINKS is needed since in newer kernels
		 * /sys/block/loop* (for example) are symlinks to dirs,
		 * not real directories.
		 * (kernel's CONFIG_SYSFS_DEPRECATED makes them real dirs,
		 * but we can't enforce that on users) */
		recursive_action("/sys/block",
			ACTION_RECURSE | ACTION_FOLLOWLINKS,
			fileAction, dirAction, temp, 0);
		recursive_action("/sys/class",
			ACTION_RECURSE | ACTION_FOLLOWLINKS,
			fileAction, dirAction, temp, 0);
	} else {
		char *seq;
		char *action;
		char *env_path;
		char seqbuf[sizeof(int)*3 + 2];
		int seqlen = seqlen; /* for compiler */

		/* Hotplug:
		 * env ACTION=... DEVPATH=... [SEQNUM=...] mdev
		 * ACTION can be "add" or "remove"
		 * DEVPATH is like "/block/sda" or "/class/input/mice"
		 */
		action = getenv("ACTION");
		env_path = getenv("DEVPATH");
		if (!action || !env_path)
			bb_show_usage();

		seq = getenv("SEQNUM");
		if (seq) {
			int timeout = 2000 / 32;
			do {
				seqlen = open_read_close("mdev.seq", seqbuf, sizeof(seqbuf-1));
				if (seqlen < 0)
					break;
				seqbuf[seqlen] = '\0';
				if (seqbuf[0] == '\n' /* seed file? */
				 || strcmp(seq, seqbuf) == 0 /* correct idx? */
				) {
					break;
				}
				usleep(32*1000);
			} while (--timeout);
		}

		snprintf(temp, PATH_MAX, "/sys%s", env_path);
		if (!strcmp(action, "remove"))
			make_device(temp, 1);
		else if (!strcmp(action, "add")) {
			make_device(temp, 0);

			if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) {
				char *fw = getenv("FIRMWARE");
				if (fw)
					load_firmware(fw, temp);
			}
		}

		if (seq && seqlen >= 0) {
			xopen_xwrite_close("mdev.seq", utoa(xatou(seq) + 1));
		}
	}

	if (ENABLE_FEATURE_CLEAN_UP)
		RELEASE_CONFIG_BUFFER(temp);

	return 0;
}
