/* vi: set sw=4 ts=4: */
/*
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */

/*
	devfsd implementation for busybox

	Copyright (C) 2003 by Tito Ragusa <farmatito@tiscali.it>

	Busybox version is based on some previous work and ideas
	Copyright (C) [2003] by [Matteo Croce] <3297627799@wind.it>

	devfsd.c

	Main file for  devfsd  (devfs daemon for Linux).

    Copyright (C) 1998-2002  Richard Gooch

	devfsd.h

    Header file for  devfsd  (devfs daemon for Linux).

    Copyright (C) 1998-2000  Richard Gooch

	compat_name.c

    Compatibility name file for  devfsd  (build compatibility names).

    Copyright (C) 1998-2002  Richard Gooch

	expression.c

    This code provides Borne Shell-like expression expansion.

    Copyright (C) 1997-1999  Richard Gooch

	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., 675 Mass Ave, Cambridge, MA 02139, USA.

    Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
    The postal address is:
      Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
*/
//config:config DEVFSD
//config:	bool "devfsd (obsolete)"
//config:	default n
//config:	select FEATURE_SYSLOG
//config:	help
//config:	This is deprecated and should NOT be used anymore.
//config:	Use linux >= 2.6 (optionally with hotplug) and mdev instead!
//config:	See docs/mdev.txt for detailed instructions on how to use mdev
//config:	instead.
//config:
//config:	Provides compatibility with old device names on a devfs systems.
//config:	You should set it to true if you have devfs enabled.
//config:	The following keywords in devsfd.conf are supported:
//config:	"CLEAR_CONFIG", "INCLUDE", "OPTIONAL_INCLUDE", "RESTORE",
//config:	"PERMISSIONS", "EXECUTE", "COPY", "IGNORE",
//config:	"MKOLDCOMPAT", "MKNEWCOMPAT","RMOLDCOMPAT", "RMNEWCOMPAT".
//config:
//config:	But only if they are written UPPERCASE!!!!!!!!
//config:
//config:config DEVFSD_MODLOAD
//config:	bool "Adds support for MODLOAD keyword in devsfd.conf"
//config:	default y
//config:	depends on DEVFSD
//config:	help
//config:	This actually doesn't work with busybox modutils but needs
//config:	the external modutils.
//config:
//config:config DEVFSD_FG_NP
//config:	bool "Enable the -fg and -np options"
//config:	default y
//config:	depends on DEVFSD
//config:	help
//config:	-fg  Run the daemon in the foreground.
//config:	-np  Exit after parsing config. Do not poll for events.
//config:
//config:config DEVFSD_VERBOSE
//config:	bool "Increases logging (and size)"
//config:	default y
//config:	depends on DEVFSD
//config:	help
//config:	Increases logging to stderr or syslog.
//config:
//config:config FEATURE_DEVFS
//config:	bool "Use devfs names for all devices (obsolete)"
//config:	default n
//config:	help
//config:	This is obsolete and should NOT be used anymore.
//config:	Use linux >= 2.6 (optionally with hotplug) and mdev instead!
//config:
//config:	For legacy systems -- if there is no way around devfsd -- this
//config:	tells busybox to look for names like /dev/loop/0 instead of
//config:	/dev/loop0. If your /dev directory has normal names instead of
//config:	devfs names, you don't want this.

//applet:IF_DEVFSD(APPLET(devfsd, BB_DIR_SBIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_DEVFSD) += devfsd.o

//usage:#define devfsd_trivial_usage
//usage:       "mntpnt [-v]" IF_DEVFSD_FG_NP("[-fg][-np]")
//usage:#define devfsd_full_usage "\n\n"
//usage:       "Manage devfs permissions and old device name symlinks\n"
//usage:     "\n	mntpnt	The mount point where devfs is mounted"
//usage:     "\n	-v	Print the protocol version numbers for devfsd"
//usage:     "\n		and the kernel-side protocol version and exit"
//usage:	IF_DEVFSD_FG_NP(
//usage:     "\n	-fg	Run in foreground"
//usage:     "\n	-np	Exit after parsing the configuration file"
//usage:     "\n		and processing synthetic REGISTER events,"
//usage:     "\n		don't poll for events"
//usage:	)

#include "libbb.h"
#include "xregex.h"
#include <syslog.h>

#include <sys/un.h>
#include <sys/sysmacros.h>

/* Various defines taken from linux/major.h */
#define IDE0_MAJOR	3
#define IDE1_MAJOR	22
#define IDE2_MAJOR	33
#define IDE3_MAJOR	34
#define IDE4_MAJOR	56
#define IDE5_MAJOR	57
#define IDE6_MAJOR	88
#define IDE7_MAJOR	89
#define IDE8_MAJOR	90
#define IDE9_MAJOR	91


/* Various defines taken from linux/devfs_fs.h */
#define DEVFSD_PROTOCOL_REVISION_KERNEL  5
#define DEVFSD_IOCTL_BASE	'd'
/*  These are the various ioctls  */
#define DEVFSDIOC_GET_PROTO_REV         _IOR(DEVFSD_IOCTL_BASE, 0, int)
#define DEVFSDIOC_SET_EVENT_MASK        _IOW(DEVFSD_IOCTL_BASE, 2, int)
#define DEVFSDIOC_RELEASE_EVENT_QUEUE   _IOW(DEVFSD_IOCTL_BASE, 3, int)
#define DEVFSDIOC_SET_CONFIG_DEBUG_MASK _IOW(DEVFSD_IOCTL_BASE, 4, int)
#define DEVFSD_NOTIFY_REGISTERED    0
#define DEVFSD_NOTIFY_UNREGISTERED  1
#define DEVFSD_NOTIFY_ASYNC_OPEN    2
#define DEVFSD_NOTIFY_CLOSE         3
#define DEVFSD_NOTIFY_LOOKUP        4
#define DEVFSD_NOTIFY_CHANGE        5
#define DEVFSD_NOTIFY_CREATE        6
#define DEVFSD_NOTIFY_DELETE        7
#define DEVFS_PATHLEN               1024
/*  Never change this otherwise the binary interface will change   */

struct devfsd_notify_struct {
	/*  Use native C types to ensure same types in kernel and user space     */
	unsigned int type;           /*  DEVFSD_NOTIFY_* value                   */
	unsigned int mode;           /*  Mode of the inode or device entry       */
	unsigned int major;          /*  Major number of device entry            */
	unsigned int minor;          /*  Minor number of device entry            */
	unsigned int uid;            /*  Uid of process, inode or device entry   */
	unsigned int gid;            /*  Gid of process, inode or device entry   */
	unsigned int overrun_count;  /*  Number of lost events                   */
	unsigned int namelen;        /*  Number of characters not including '\0' */
	/*  The device name MUST come last                                       */
	char devname[DEVFS_PATHLEN]; /*  This will be '\0' terminated            */
};

#define BUFFER_SIZE 16384
#define DEVFSD_VERSION "1.3.25"
#define CONFIG_FILE  "/etc/devfsd.conf"
#define MODPROBE		"/sbin/modprobe"
#define MODPROBE_SWITCH_1 "-k"
#define MODPROBE_SWITCH_2 "-C"
#define CONFIG_MODULES_DEVFS "/etc/modules.devfs"
#define MAX_ARGS     (6 + 1)
#define MAX_SUBEXPR  10
#define STRING_LENGTH 255

/* for get_uid_gid() */
#define UID			0
#define GID			1

/* fork_and_execute() */
# define DIE			1
# define NO_DIE			0

/* for dir_operation() */
#define RESTORE		0
#define SERVICE		1
#define READ_CONFIG 2

/*  Update only after changing code to reflect new protocol  */
#define DEVFSD_PROTOCOL_REVISION_DAEMON  5

/*  Compile-time check  */
#if DEVFSD_PROTOCOL_REVISION_KERNEL != DEVFSD_PROTOCOL_REVISION_DAEMON
#error protocol version mismatch. Update your kernel headers
#endif

#define AC_PERMISSIONS				0
#define AC_MODLOAD					1
#define AC_EXECUTE					2
#define AC_MFUNCTION				3	/* not supported by busybox */
#define AC_CFUNCTION				4	/* not supported by busybox */
#define AC_COPY						5
#define AC_IGNORE					6
#define AC_MKOLDCOMPAT				7
#define AC_MKNEWCOMPAT				8
#define AC_RMOLDCOMPAT				9
#define AC_RMNEWCOMPAT				10
#define AC_RESTORE					11

struct permissions_type {
	mode_t mode;
	uid_t uid;
	gid_t gid;
};

struct execute_type {
	char *argv[MAX_ARGS + 1];  /*  argv[0] must always be the programme  */
};

struct copy_type {
	const char *source;
	const char *destination;
};

struct action_type {
	unsigned int what;
	unsigned int when;
};

struct config_entry_struct {
	struct action_type action;
	regex_t preg;
	union
	{
	struct permissions_type permissions;
	struct execute_type execute;
	struct copy_type copy;
	}
	u;
	struct config_entry_struct *next;
};

struct get_variable_info {
	const struct devfsd_notify_struct *info;
	const char *devname;
	char devpath[STRING_LENGTH];
};

static void dir_operation(int , const char * , int,  unsigned long*);
static void service(struct stat statbuf, char *path);
static int st_expr_expand(char *, unsigned, const char *, const char *(*)(const char *, void *), void *);
static const char *get_old_name(const char *, unsigned, char *, unsigned, unsigned);
static int mksymlink(const char *oldpath, const char *newpath);
static void read_config_file(char *path, int optional, unsigned long *event_mask);
static void process_config_line(const char *, unsigned long *);
static int  do_servicing(int, unsigned long);
static void service_name(const struct devfsd_notify_struct *);
static void action_permissions(const struct devfsd_notify_struct *, const struct config_entry_struct *);
static void action_execute(const struct devfsd_notify_struct *, const struct config_entry_struct *,
							const regmatch_t *, unsigned);
static void action_modload(const struct devfsd_notify_struct *info, const struct config_entry_struct *entry);
static void action_copy(const struct devfsd_notify_struct *, const struct config_entry_struct *,
						const regmatch_t *, unsigned);
static void action_compat(const struct devfsd_notify_struct *, unsigned);
static void free_config(void);
static void restore(char *spath, struct stat source_stat, int rootlen);
static int copy_inode(const char *, const struct stat *, mode_t, const char *, const struct stat *);
static mode_t get_mode(const char *);
static void signal_handler(int);
static const char *get_variable(const char *, void *);
static int make_dir_tree(const char *);
static int expand_expression(char *, unsigned, const char *, const char *(*)(const char *, void *), void *,
							const char *, const regmatch_t *, unsigned);
static void expand_regexp(char *, size_t, const char *, const char *, const regmatch_t *, unsigned);
static const char *expand_variable(	char *, unsigned, unsigned *, const char *,
									const char *(*)(const char *, void *), void *);
static const char *get_variable_v2(const char *, const char *(*)(const char *, void *), void *);
static char get_old_ide_name(unsigned, unsigned);
static char *write_old_sd_name(char *, unsigned, unsigned, const char *);

/* busybox functions */
static int get_uid_gid(int flag, const char *string);
static void safe_memcpy(char * dest, const char * src, int len);
static unsigned int scan_dev_name_common(const char *d, unsigned int n, int addendum, const char *ptr);
static unsigned int scan_dev_name(const char *d, unsigned int n, const char *ptr);

/* Structs and vars */
static struct config_entry_struct *first_config = NULL;
static struct config_entry_struct *last_config = NULL;
static char *mount_point = NULL;
static volatile int caught_signal = FALSE;
static volatile int caught_sighup = FALSE;
static struct initial_symlink_struct {
	const char *dest;
	const char *name;
} initial_symlinks[] = {
	{"/proc/self/fd", "fd"},
	{"fd/0", "stdin"},
	{"fd/1", "stdout"},
	{"fd/2", "stderr"},
	{NULL, NULL},
};

static struct event_type {
	unsigned int type;        /*  The DEVFSD_NOTIFY_* value                  */
	const char *config_name;  /*  The name used in the config file           */
} event_types[] = {
	{DEVFSD_NOTIFY_REGISTERED,   "REGISTER"},
	{DEVFSD_NOTIFY_UNREGISTERED, "UNREGISTER"},
	{DEVFSD_NOTIFY_ASYNC_OPEN,   "ASYNC_OPEN"},
	{DEVFSD_NOTIFY_CLOSE,        "CLOSE"},
	{DEVFSD_NOTIFY_LOOKUP,       "LOOKUP"},
	{DEVFSD_NOTIFY_CHANGE,       "CHANGE"},
	{DEVFSD_NOTIFY_CREATE,       "CREATE"},
	{DEVFSD_NOTIFY_DELETE,       "DELETE"},
	{0xffffffff,                 NULL}
};

/* Busybox messages */

static const char bb_msg_proto_rev[] ALIGN1          = "protocol revision";
static const char bb_msg_bad_config[] ALIGN1         = "bad %s config file: %s";
static const char bb_msg_small_buffer[] ALIGN1       = "buffer too small";
static const char bb_msg_variable_not_found[] ALIGN1 = "variable: %s not found";

/* Busybox stuff */
#if ENABLE_DEVFSD_VERBOSE || ENABLE_DEBUG
#define info_logger(p, fmt, args...)                 bb_info_msg(fmt, ## args)
#define simple_info_logger(p, msg)                   bb_simple_info_msg(msg)
#define msg_logger(p, fmt, args...)                  bb_error_msg(fmt, ## args)
#define simple_msg_logger(p, msg)                    bb_simple_error_msg(msg)
#define msg_logger_and_die(p, fmt, args...)          bb_error_msg_and_die(fmt, ## args)
#define simple_msg_logger_and_die(p, msg)            bb_simple_error_msg_and_die(msg)
#define error_logger(p, fmt, args...)                bb_perror_msg(fmt, ## args)
#define error_logger_and_die(p, fmt, args...)        bb_perror_msg_and_die(fmt, ## args)
#else
#define info_logger(p, fmt, args...)
#define simple_info_logger(p, msg)
#define msg_logger(p, fmt, args...)
#define simple_msg_logger(p, msg)
#define msg_logger_and_die(p, fmt, args...)           exit(EXIT_FAILURE)
#define simple_msg_logger_and_die(p, msg)             exit(EXIT_FAILURE)
#define error_logger(p, fmt, args...)
#define error_logger_and_die(p, fmt, args...)         exit(EXIT_FAILURE)
#endif

static void safe_memcpy(char *dest, const char *src, int len)
{
	memcpy(dest, src, len);
	dest[len] = '\0';
}

static unsigned int scan_dev_name_common(const char *d, unsigned int n, int addendum, const char *ptr)
{
	if (d[n - 4] == 'd' && d[n - 3] == 'i' && d[n - 2] == 's' && d[n - 1] == 'c')
		return 2 + addendum;
	if (d[n - 2] == 'c' && d[n - 1] == 'd')
		return 3 + addendum;
	if (ptr[0] == 'p' && ptr[1] == 'a' && ptr[2] == 'r' && ptr[3] == 't')
		return 4 + addendum;
	if (ptr[n - 2] == 'm' && ptr[n - 1] == 't')
		return 5 + addendum;
	return 0;
}

static unsigned int scan_dev_name(const char *d, unsigned int n, const char *ptr)
{
	if (d[0] == 's' && d[1] == 'c' && d[2] == 's' && d[3] == 'i' && d[4] == '/') {
		if (d[n - 7] == 'g' && d[n - 6] == 'e' && d[n - 5] == 'n'
			&& d[n - 4] == 'e' && d[n - 3] == 'r' && d[n - 2] == 'i' && d[n - 1] == 'c'
		)
			return 1;
		return scan_dev_name_common(d, n, 0, ptr);
	}
	if (d[0] == 'i' && d[1] == 'd' && d[2] == 'e' && d[3] == '/'
		&& d[4] == 'h' && d[5] == 'o' && d[6] == 's' && d[7] == 't'
	)
		return scan_dev_name_common(d, n, 4, ptr);
	if (d[0] == 's' && d[1] == 'b' && d[2] == 'p' && d[3] == '/')
		return 10;
	if (d[0] == 'v' && d[1] == 'c' && d[2] == 'c' && d[3] == '/')
		return 11;
	if (d[0] == 'p' && d[1] == 't' && d[2] == 'y' && d[3] == '/')
		return 12;
	return 0;
}

/*  Public functions follow  */

int devfsd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int devfsd_main(int argc, char **argv)
{
	int print_version = FALSE;
	int do_daemon = TRUE;
	int no_polling = FALSE;
	int do_scan;
	int fd, proto_rev, count;
	unsigned long event_mask = 0;
	struct sigaction new_action;
	struct initial_symlink_struct *curr;

	if (argc < 2)
		bb_show_usage();

	for (count = 2; count < argc; ++count) {
		if (argv[count][0] == '-') {
			if (argv[count][1] == 'v' && !argv[count][2]) /* -v */
				print_version = TRUE;
			else if (ENABLE_DEVFSD_FG_NP && argv[count][1] == 'f'
			 && argv[count][2] == 'g' && !argv[count][3]) /* -fg */
				do_daemon = FALSE;
			else if (ENABLE_DEVFSD_FG_NP && argv[count][1] == 'n'
			 && argv[count][2] == 'p' && !argv[count][3]) /* -np */
				no_polling = TRUE;
			else
				bb_show_usage();
		}
	}

	mount_point = bb_simplify_path(argv[1]);

	xchdir(mount_point);

	fd = xopen(".devfsd", O_RDONLY);
	close_on_exec_on(fd);
	xioctl(fd, DEVFSDIOC_GET_PROTO_REV, &proto_rev);

	/*setup initial entries */
	for (curr = initial_symlinks; curr->dest != NULL; ++curr)
		symlink(curr->dest, curr->name);

	/* NB: The check for CONFIG_FILE is done in read_config_file() */

	if (print_version || (DEVFSD_PROTOCOL_REVISION_DAEMON != proto_rev)) {
		printf("%s v%s\nDaemon %s:\t%d\nKernel-side %s:\t%d\n",
				applet_name, DEVFSD_VERSION, bb_msg_proto_rev,
				DEVFSD_PROTOCOL_REVISION_DAEMON, bb_msg_proto_rev, proto_rev);
		if (DEVFSD_PROTOCOL_REVISION_DAEMON != proto_rev)
			bb_error_msg_and_die("%s mismatch!", bb_msg_proto_rev);
		exit(EXIT_SUCCESS); /* -v */
	}
	/*  Tell kernel we are special(i.e. we get to see hidden entries)  */
	xioctl(fd, DEVFSDIOC_SET_EVENT_MASK, 0);

	/*  Set up SIGHUP and SIGUSR1 handlers  */
	sigemptyset(&new_action.sa_mask);
	new_action.sa_flags = 0;
	new_action.sa_handler = signal_handler;
	sigaction_set(SIGHUP, &new_action);
	sigaction_set(SIGUSR1, &new_action);

	printf("%s v%s started for %s\n", applet_name, DEVFSD_VERSION, mount_point);

	/*  Set umask so that mknod(2), open(2) and mkdir(2) have complete control over permissions  */
	umask(0);
	read_config_file((char*)CONFIG_FILE, FALSE, &event_mask);
	/*  Do the scan before forking, so that boot scripts see the finished product  */
	dir_operation(SERVICE, mount_point, 0, NULL);

	if (ENABLE_DEVFSD_FG_NP && no_polling)
		exit(EXIT_SUCCESS);

	if (ENABLE_DEVFSD_VERBOSE || ENABLE_DEBUG)
		logmode = LOGMODE_BOTH;
	else if (do_daemon == TRUE)
		logmode = LOGMODE_SYSLOG;
	/* This is the default */
	/*else
		logmode = LOGMODE_STDIO; */

	if (do_daemon) {
		/*  Release so that the child can grab it  */
		xioctl(fd, DEVFSDIOC_RELEASE_EVENT_QUEUE, 0);
		bb_daemonize_or_rexec(0, argv);
	} else if (ENABLE_DEVFSD_FG_NP) {
		setpgid(0, 0);  /*  Become process group leader                    */
	}

	while (TRUE) {
		do_scan = do_servicing(fd, event_mask);

		free_config();
		read_config_file((char*)CONFIG_FILE, FALSE, &event_mask);
		if (do_scan)
			dir_operation(SERVICE, mount_point, 0, NULL);
	}
	if (ENABLE_FEATURE_CLEAN_UP) free(mount_point);
}   /*  End Function main  */


/*  Private functions follow  */

static void read_config_file(char *path, int optional, unsigned long *event_mask)
/*  [SUMMARY] Read a configuration database.
    <path> The path to read the database from. If this is a directory, all
    entries in that directory will be read(except hidden entries).
    <optional> If TRUE, the routine will silently ignore a missing config file.
    <event_mask> The event mask is written here. This is not initialised.
    [RETURNS] Nothing.
*/
{
	struct stat statbuf;
	FILE *fp;
	char buf[STRING_LENGTH];
	char *line = NULL;
	char *p;

	if (stat(path, &statbuf) == 0) {
		/* Don't read 0 length files: ignored */
		/*if (statbuf.st_size == 0)
				return;*/
		if (S_ISDIR(statbuf.st_mode)) {
			p = bb_simplify_path(path);
			dir_operation(READ_CONFIG, p, 0, event_mask);
			free(p);
			return;
		}
		fp = fopen_for_read(path);
		if (fp != NULL) {
			while (fgets(buf, STRING_LENGTH, fp) != NULL) {
				/*  Skip whitespace  */
				line = buf;
				line = skip_whitespace(line);
				if (line[0] == '\0' || line[0] == '#')
					continue;
				process_config_line(line, event_mask);
			}
			fclose(fp);
		} else {
			goto read_config_file_err;
		}
	} else {
read_config_file_err:
		if (optional == 0 && errno == ENOENT)
			error_logger_and_die(LOG_ERR, "read config file: %s", path);
	}
}   /*  End Function read_config_file   */

static void process_config_line(const char *line, unsigned long *event_mask)
/*  [SUMMARY] Process a line from a configuration file.
    <line> The configuration line.
    <event_mask> The event mask is written here. This is not initialised.
    [RETURNS] Nothing.
*/
{
	int  num_args, count;
	struct config_entry_struct *new;
	char p[MAX_ARGS][STRING_LENGTH];
	char when[STRING_LENGTH], what[STRING_LENGTH];
	char name[STRING_LENGTH];
	const char *msg = "";
	char *ptr;
	int i;

	/* !!!! Only Uppercase Keywords in devsfd.conf */
	static const char options[] ALIGN1 =
		"CLEAR_CONFIG\0""INCLUDE\0""OPTIONAL_INCLUDE\0"
		"RESTORE\0""PERMISSIONS\0""MODLOAD\0""EXECUTE\0"
		"COPY\0""IGNORE\0""MKOLDCOMPAT\0""MKNEWCOMPAT\0"
		"RMOLDCOMPAT\0""RMNEWCOMPAT\0";

	for (count = 0; count < MAX_ARGS; ++count)
		p[count][0] = '\0';
	num_args = sscanf(line, "%s %s %s %s %s %s %s %s %s %s",
			when, name, what,
			p[0], p[1], p[2], p[3], p[4], p[5], p[6]);

	i = index_in_strings(options, when);

	/* "CLEAR_CONFIG" */
	if (i == 0) {
		free_config();
		*event_mask = 0;
		return;
	}

	if (num_args < 2)
		goto process_config_line_err;

	/* "INCLUDE" & "OPTIONAL_INCLUDE" */
	if (i == 1 || i == 2) {
		st_expr_expand(name, STRING_LENGTH, name, get_variable, NULL);
		info_logger(LOG_INFO, "%sinclude: %s", (toupper(when[0]) == 'I') ? "": "optional_", name);
		read_config_file(name, (toupper(when[0]) == 'I') ? FALSE : TRUE, event_mask);
		return;
	}
	/* "RESTORE" */
	if (i == 3) {
		dir_operation(RESTORE, name, strlen(name),NULL);
		return;
	}
	if (num_args < 3)
		goto process_config_line_err;

	new = xzalloc(sizeof *new);

	for (count = 0; event_types[count].config_name != NULL; ++count) {
		if (strcasecmp(when, event_types[count].config_name) != 0)
			continue;
		new->action.when = event_types[count].type;
		break;
	}
	if (event_types[count].config_name == NULL) {
		msg = "WHEN in";
		goto process_config_line_err;
	}

	i = index_in_strings(options, what);

	switch (i) {
		case 4:	/* "PERMISSIONS" */
			new->action.what = AC_PERMISSIONS;
			/*  Get user and group  */
			ptr = strchr(p[0], '.');
			if (ptr == NULL) {
				msg = "UID.GID";
				goto process_config_line_err; /*"missing '.' in UID.GID"*/
			}

			*ptr++ = '\0';
			new->u.permissions.uid = get_uid_gid(UID, p[0]);
			new->u.permissions.gid = get_uid_gid(GID, ptr);
			/*  Get mode  */
			new->u.permissions.mode = get_mode(p[1]);
			break;
		case 5:	/*  MODLOAD */
			/*This  action will pass "/dev/$devname"(i.e. "/dev/" prefixed to
			the device name) to the module loading  facility.  In  addition,
			the /etc/modules.devfs configuration file is used.*/
			if (ENABLE_DEVFSD_MODLOAD)
				new->action.what = AC_MODLOAD;
			break;
		case 6: /* EXECUTE */
			new->action.what = AC_EXECUTE;
			num_args -= 3;

			for (count = 0; count < num_args; ++count)
				new->u.execute.argv[count] = xstrdup(p[count]);

			new->u.execute.argv[num_args] = NULL;
			break;
		case 7: /* COPY */
			new->action.what = AC_COPY;
			num_args -= 3;
			if (num_args != 2)
				goto process_config_line_err; /* missing path and function in line */

			new->u.copy.source = xstrdup(p[0]);
			new->u.copy.destination = xstrdup(p[1]);
			break;
		case 8: /* IGNORE */
		/* FALLTROUGH */
		case 9: /* MKOLDCOMPAT */
		/* FALLTROUGH */
		case 10: /* MKNEWCOMPAT */
		/* FALLTROUGH */
		case 11:/* RMOLDCOMPAT */
		/* FALLTROUGH */
		case 12: /* RMNEWCOMPAT */
		/*	AC_IGNORE					6
			AC_MKOLDCOMPAT				7
			AC_MKNEWCOMPAT				8
			AC_RMOLDCOMPAT				9
			AC_RMNEWCOMPAT				10*/
			new->action.what = i - 2;
			break;
		default:
			msg = "WHAT in";
			goto process_config_line_err;
		/*esac*/
	} /* switch (i) */

	xregcomp(&new->preg, name, REG_EXTENDED);

	*event_mask |= 1 << new->action.when;
	new->next = NULL;
	if (first_config == NULL)
		first_config = new;
	else
		last_config->next = new;
	last_config = new;
	return;

 process_config_line_err:
	msg_logger_and_die(LOG_ERR, bb_msg_bad_config, msg, line);
}  /*  End Function process_config_line   */

static int do_servicing(int fd, unsigned long event_mask)
/*  [SUMMARY] Service devfs changes until a signal is received.
    <fd> The open control file.
    <event_mask> The event mask.
    [RETURNS] TRUE if SIGHUP was caught, else FALSE.
*/
{
	ssize_t bytes;
	struct devfsd_notify_struct info;

	/* (void*) cast is only in order to match prototype */
	xioctl(fd, DEVFSDIOC_SET_EVENT_MASK, (void*)event_mask);
	while (!caught_signal) {
		errno = 0;
		bytes = read(fd, (char *) &info, sizeof info);
		if (caught_signal)
			break;      /*  Must test for this first     */
		if (errno == EINTR)
			continue;  /*  Yes, the order is important  */
		if (bytes < 1)
			break;
		service_name(&info);
	}
	if (caught_signal) {
		int c_sighup = caught_sighup;

		caught_signal = FALSE;
		caught_sighup = FALSE;
		return c_sighup;
	}
	simple_msg_logger_and_die(LOG_ERR, "read error on control file");
}   /*  End Function do_servicing  */

static void service_name(const struct devfsd_notify_struct *info)
/*  [SUMMARY] Service a single devfs change.
    <info> The devfs change.
    [RETURNS] Nothing.
*/
{
	unsigned int n;
	regmatch_t mbuf[MAX_SUBEXPR];
	struct config_entry_struct *entry;

	if (ENABLE_DEBUG && info->overrun_count > 0)
		msg_logger(LOG_ERR, "lost %u events", info->overrun_count);

	/*  Discard lookups on "/dev/log" and "/dev/initctl"  */
	if (info->type == DEVFSD_NOTIFY_LOOKUP
		&& ((info->devname[0] == 'l' && info->devname[1] == 'o'
		&& info->devname[2] == 'g' && !info->devname[3])
		|| (info->devname[0] == 'i' && info->devname[1] == 'n'
		&& info->devname[2] == 'i' && info->devname[3] == 't'
		&& info->devname[4] == 'c' && info->devname[5] == 't'
		&& info->devname[6] == 'l' && !info->devname[7]))
	)
		return;

	for (entry = first_config; entry != NULL; entry = entry->next) {
		/*  First check if action matches the type, then check if name matches */
		if (info->type != entry->action.when
		|| regexec(&entry->preg, info->devname, MAX_SUBEXPR, mbuf, 0) != 0)
			continue;
		for (n = 0;(n < MAX_SUBEXPR) && (mbuf[n].rm_so != -1); ++n)
			/* VOID */;

		switch (entry->action.what) {
			case AC_PERMISSIONS:
				action_permissions(info, entry);
				break;
			case AC_MODLOAD:
				if (ENABLE_DEVFSD_MODLOAD)
					action_modload(info, entry);
				break;
			case AC_EXECUTE:
				action_execute(info, entry, mbuf, n);
				break;
			case AC_COPY:
				action_copy(info, entry, mbuf, n);
				break;
			case AC_IGNORE:
				return;
				/*break;*/
			case AC_MKOLDCOMPAT:
			case AC_MKNEWCOMPAT:
			case AC_RMOLDCOMPAT:
			case AC_RMNEWCOMPAT:
				action_compat(info, entry->action.what);
				break;
			default:
				simple_msg_logger_and_die(LOG_ERR, "Unknown action");
		}
	}
}   /*  End Function service_name  */

static void action_permissions(const struct devfsd_notify_struct *info,
				const struct config_entry_struct *entry)
/*  [SUMMARY] Update permissions for a device entry.
    <info> The devfs change.
    <entry> The config file entry.
    [RETURNS] Nothing.
*/
{
	struct stat statbuf;

	if (stat(info->devname, &statbuf) != 0
	 || chmod(info->devname, (statbuf.st_mode & S_IFMT) | (entry->u.permissions.mode & ~S_IFMT)) != 0
	 || chown(info->devname, entry->u.permissions.uid, entry->u.permissions.gid) != 0
	)
		error_logger(LOG_ERR, "Can't chmod or chown: %s", info->devname);
}   /*  End Function action_permissions  */

static void action_modload(const struct devfsd_notify_struct *info,
			const struct config_entry_struct *entry UNUSED_PARAM)
/*  [SUMMARY] Load a module.
    <info> The devfs change.
    <entry> The config file entry.
    [RETURNS] Nothing.
*/
{
	char *argv[6];

	argv[0] = (char*)MODPROBE;
	argv[1] = (char*)MODPROBE_SWITCH_1; /* "-k" */
	argv[2] = (char*)MODPROBE_SWITCH_2; /* "-C" */
	argv[3] = (char*)CONFIG_MODULES_DEVFS;
	argv[4] = concat_path_file("/dev", info->devname); /* device */
	argv[5] = NULL;

	spawn_and_wait(argv);
	free(argv[4]);
}  /*  End Function action_modload  */

static void action_execute(const struct devfsd_notify_struct *info,
			const struct config_entry_struct *entry,
			const regmatch_t *regexpr, unsigned int numexpr)
/*  [SUMMARY] Execute a programme.
    <info> The devfs change.
    <entry> The config file entry.
    <regexpr> The number of subexpression(start, end) offsets within the
    device name.
    <numexpr> The number of elements within <<regexpr>>.
    [RETURNS] Nothing.
*/
{
	unsigned int count;
	struct get_variable_info gv_info;
	char *argv[MAX_ARGS + 1];
	char largv[MAX_ARGS + 1][STRING_LENGTH];

	gv_info.info = info;
	gv_info.devname = info->devname;
	snprintf(gv_info.devpath, sizeof(gv_info.devpath), "%s/%s", mount_point, info->devname);
	for (count = 0; entry->u.execute.argv[count] != NULL; ++count) {
		expand_expression(largv[count], STRING_LENGTH,
				entry->u.execute.argv[count],
				get_variable, &gv_info,
				gv_info.devname, regexpr, numexpr);
		argv[count] = largv[count];
	}
	argv[count] = NULL;
	spawn_and_wait(argv);
}   /*  End Function action_execute  */


static void action_copy(const struct devfsd_notify_struct *info,
			const struct config_entry_struct *entry,
			const regmatch_t *regexpr, unsigned int numexpr)
/*  [SUMMARY] Copy permissions.
    <info> The devfs change.
    <entry> The config file entry.
    <regexpr> This list of subexpression(start, end) offsets within the
    device name.
    <numexpr> The number of elements in <<regexpr>>.
    [RETURNS] Nothing.
*/
{
	mode_t new_mode;
	struct get_variable_info gv_info;
	struct stat source_stat, dest_stat;
	char source[STRING_LENGTH], destination[STRING_LENGTH];
	int ret = 0;

	dest_stat.st_mode = 0;

	if ((info->type == DEVFSD_NOTIFY_CHANGE) && S_ISLNK(info->mode))
		return;
	gv_info.info = info;
	gv_info.devname = info->devname;

	snprintf(gv_info.devpath, sizeof(gv_info.devpath), "%s/%s", mount_point, info->devname);
	expand_expression(source, STRING_LENGTH, entry->u.copy.source,
				get_variable, &gv_info, gv_info.devname,
				regexpr, numexpr);

	expand_expression(destination, STRING_LENGTH, entry->u.copy.destination,
				get_variable, &gv_info, gv_info.devname,
				regexpr, numexpr);

	if (!make_dir_tree(destination) || lstat(source, &source_stat) != 0)
			return;
	lstat(destination, &dest_stat);
	new_mode = source_stat.st_mode & ~S_ISVTX;
	if (info->type == DEVFSD_NOTIFY_CREATE)
		new_mode |= S_ISVTX;
	else if ((info->type == DEVFSD_NOTIFY_CHANGE) &&(dest_stat.st_mode & S_ISVTX))
		new_mode |= S_ISVTX;
	ret = copy_inode(destination, &dest_stat, new_mode, source, &source_stat);
	if (ENABLE_DEBUG && ret && (errno != EEXIST))
		error_logger(LOG_ERR, "copy_inode: %s to %s", source, destination);
}   /*  End Function action_copy  */

static void action_compat(const struct devfsd_notify_struct *info, unsigned int action)
/*  [SUMMARY] Process a compatibility request.
    <info> The devfs change.
    <action> The action to take.
    [RETURNS] Nothing.
*/
{
	int ret;
	const char *compat_name = NULL;
	const char *dest_name = info->devname;
	const char *ptr;
	char compat_buf[STRING_LENGTH], dest_buf[STRING_LENGTH];
	int mode, host, bus, target, lun;
	unsigned int i;
	char rewind_;
	/* 1 to 5  "scsi/" , 6 to 9 "ide/host" */
	static const char *const fmt[] = {
		NULL ,
		"sg/c%db%dt%du%d",		/* scsi/generic */
		"sd/c%db%dt%du%d",		/* scsi/disc */
		"sr/c%db%dt%du%d",		/* scsi/cd */
		"sd/c%db%dt%du%dp%d",		/* scsi/part */
		"st/c%db%dt%du%dm%d%c",		/* scsi/mt */
		"ide/hd/c%db%dt%du%d",		/* ide/host/disc */
		"ide/cd/c%db%dt%du%d",		/* ide/host/cd */
		"ide/hd/c%db%dt%du%dp%d",	/* ide/host/part */
		"ide/mt/c%db%dt%du%d%s",	/* ide/host/mt */
		NULL
	};

	/*  First construct compatibility name  */
	switch (action) {
		case AC_MKOLDCOMPAT:
		case AC_RMOLDCOMPAT:
			compat_name = get_old_name(info->devname, info->namelen, compat_buf, info->major, info->minor);
			break;
		case AC_MKNEWCOMPAT:
		case AC_RMNEWCOMPAT:
			ptr = bb_basename(info->devname);
			i = scan_dev_name(info->devname, info->namelen, ptr);

			/* nothing found */
			if (i == 0 || i > 9)
				return;

			sscanf(info->devname + ((i < 6) ? 5 : 4), "host%d/bus%d/target%d/lun%d/", &host, &bus, &target, &lun);
			snprintf(dest_buf, sizeof(dest_buf), "../%s", info->devname + (( i > 5) ? 4 : 0));
			dest_name = dest_buf;
			compat_name = compat_buf;


			/* 1 == scsi/generic  2 == scsi/disc 3 == scsi/cd 6 == ide/host/disc 7 == ide/host/cd */
			if (i == 1 || i == 2 || i == 3 || i == 6 || i ==7)
				sprintf(compat_buf, fmt[i], host, bus, target, lun);

			/* 4 == scsi/part 8 == ide/host/part */
			if (i == 4 || i == 8)
				sprintf(compat_buf, fmt[i], host, bus, target, lun, atoi(ptr + 4));

			/* 5 == scsi/mt */
			if (i == 5) {
				rewind_ = info->devname[info->namelen - 1];
				if (rewind_ != 'n')
					rewind_ = '\0';
				mode=0;
				if (ptr[2] ==  'l' /*108*/ || ptr[2] == 'm'/*109*/)
					mode = ptr[2] - 107; /* 1 or 2 */
				if (ptr[2] ==  'a')
					mode = 3;
				sprintf(compat_buf, fmt[i], host, bus, target, lun, mode, rewind_);
			}

			/* 9 == ide/host/mt */
			if (i ==  9)
				snprintf(compat_buf, sizeof(compat_buf), fmt[i], host, bus, target, lun, ptr + 2);
		/* esac */
	} /* switch (action) */

	if (compat_name == NULL)
		return;

	/*  Now decide what to do with it  */
	switch (action) {
		case AC_MKOLDCOMPAT:
		case AC_MKNEWCOMPAT:
			mksymlink(dest_name, compat_name);
			break;
		case AC_RMOLDCOMPAT:
		case AC_RMNEWCOMPAT:
			ret = unlink(compat_name);
			if (ENABLE_DEBUG && ret)
				error_logger(LOG_ERR, "unlink: %s", compat_name);
			break;
		/*esac*/
	} /* switch (action) */
}   /*  End Function action_compat  */

static void restore(char *spath, struct stat source_stat, int rootlen)
{
	char *dpath;
	struct stat dest_stat;

	dest_stat.st_mode = 0;
	dpath = concat_path_file(mount_point, spath + rootlen);
	lstat(dpath, &dest_stat);
	free(dpath);
	if (S_ISLNK(source_stat.st_mode) || (source_stat.st_mode & S_ISVTX))
		copy_inode(dpath, &dest_stat, (source_stat.st_mode & ~S_ISVTX), spath, &source_stat);

	if (S_ISDIR(source_stat.st_mode))
		dir_operation(RESTORE, spath, rootlen, NULL);
}


static int copy_inode(const char *destpath, const struct stat *dest_stat,
			mode_t new_mode,
			const char *sourcepath, const struct stat *source_stat)
/*  [SUMMARY] Copy an inode.
    <destpath> The destination path. An existing inode may be deleted.
    <dest_stat> The destination stat(2) information.
    <new_mode> The desired new mode for the destination.
    <sourcepath> The source path.
    <source_stat> The source stat(2) information.
    [RETURNS] TRUE on success, else FALSE.
*/
{
	int source_len, dest_len;
	char source_link[STRING_LENGTH], dest_link[STRING_LENGTH];
	int fd, val;
	struct sockaddr_un un_addr;
	char symlink_val[STRING_LENGTH];

	if ((source_stat->st_mode & S_IFMT) ==(dest_stat->st_mode & S_IFMT)) {
		/*  Same type  */
		if (S_ISLNK(source_stat->st_mode)) {
			source_len = readlink(sourcepath, source_link, STRING_LENGTH - 1);
			if ((source_len < 0)
			 || (dest_len = readlink(destpath, dest_link, STRING_LENGTH - 1)) < 0
			)
				return FALSE;
			source_link[source_len]	= '\0';
			dest_link[dest_len]	= '\0';
			if ((source_len != dest_len) || (strcmp(source_link, dest_link) != 0)) {
				unlink(destpath);
				symlink(source_link, destpath);
			}
			return TRUE;
		}   /*  Else not a symlink  */
		chmod(destpath, new_mode & ~S_IFMT);
		chown(destpath, source_stat->st_uid, source_stat->st_gid);
		return TRUE;
	}
	/*  Different types: unlink and create  */
	unlink(destpath);
	switch (source_stat->st_mode & S_IFMT) {
		case S_IFSOCK:
			fd = socket(AF_UNIX, SOCK_STREAM, 0);
			if (fd < 0)
				break;
			un_addr.sun_family = AF_UNIX;
			snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s", destpath);
			val = bind(fd, (struct sockaddr *) &un_addr, (int) sizeof un_addr);
			close(fd);
			if (val != 0 || chmod(destpath, new_mode & ~S_IFMT) != 0)
				break;
			goto do_chown;
		case S_IFLNK:
			val = readlink(sourcepath, symlink_val, STRING_LENGTH - 1);
			if (val < 0)
				break;
			symlink_val[val] = '\0';
			if (symlink(symlink_val, destpath) == 0)
				return TRUE;
			break;
		case S_IFREG:
			fd = open(destpath, O_RDONLY | O_CREAT, new_mode & ~S_IFMT);
			if (fd < 0)
				break;
			close(fd);
			if (chmod(destpath, new_mode & ~S_IFMT) != 0)
				break;
			goto do_chown;
		case S_IFBLK:
		case S_IFCHR:
		case S_IFIFO:
			if (mknod(destpath, new_mode, source_stat->st_rdev) != 0)
				break;
			goto do_chown;
		case S_IFDIR:
			if (mkdir(destpath, new_mode & ~S_IFMT) != 0)
				break;
do_chown:
			if (chown(destpath, source_stat->st_uid, source_stat->st_gid) == 0)
				return TRUE;
			/*break;*/
	}
	return FALSE;
}   /*  End Function copy_inode  */

static void free_config(void)
/*  [SUMMARY] Free the configuration information.
    [RETURNS] Nothing.
*/
{
	struct config_entry_struct *c_entry;
	void *next;

	for (c_entry = first_config; c_entry != NULL; c_entry = next) {
		unsigned int count;

		next = c_entry->next;
		regfree(&c_entry->preg);
		if (c_entry->action.what == AC_EXECUTE) {
			for (count = 0; count < MAX_ARGS; ++count) {
				if (c_entry->u.execute.argv[count] == NULL)
					break;
				free(c_entry->u.execute.argv[count]);
			}
		}
		free(c_entry);
	}
	first_config = NULL;
	last_config = NULL;
}   /*  End Function free_config  */

static int get_uid_gid(int flag, const char *string)
/*  [SUMMARY] Convert a string to a UID or GID value.
	<flag> "UID" or "GID".
	<string> The string.
    [RETURNS] The UID or GID value.
*/
{
	struct passwd *pw_ent;
	struct group *grp_ent;
	const char *msg;

	if (isdigit(string[0]) || ((string[0] == '-') && isdigit(string[1])))
		return atoi(string);

	if (flag == UID && (pw_ent = getpwnam(string)) != NULL)
		return pw_ent->pw_uid;

	if (ENABLE_DEVFSD_VERBOSE)
		msg = "user";

	if (flag == GID) {
		if ((grp_ent = getgrnam(string)) != NULL)
			return grp_ent->gr_gid;
		if (ENABLE_DEVFSD_VERBOSE)
			msg = "group";
	}

	if (ENABLE_DEVFSD_VERBOSE)
		msg_logger(LOG_ERR, "unknown %s: %s, defaulting to %cid=0",  msg, string, msg[0]);
	return 0;
}/*  End Function get_uid_gid  */

static mode_t get_mode(const char *string)
/*  [SUMMARY] Convert a string to a mode value.
    <string> The string.
    [RETURNS] The mode value.
*/
{
	mode_t mode;
	int i;

	if (isdigit(string[0]))
		return strtoul(string, NULL, 8);
	if (strlen(string) != 9)
		msg_logger_and_die(LOG_ERR, "bad mode: %s", string);

	mode = 0;
	i = S_IRUSR;
	while (i > 0) {
		if (string[0] == 'r' || string[0] == 'w' || string[0] == 'x')
			mode += i;
		i = i / 2;
		string++;
	}
	return mode;
}   /*  End Function get_mode  */

static void signal_handler(int sig)
{
	caught_signal = TRUE;
	if (sig == SIGHUP)
		caught_sighup = TRUE;

	info_logger(LOG_INFO, "Caught signal %d", sig);
}   /*  End Function signal_handler  */

static const char *get_variable(const char *variable, void *info)
{
	static char *hostname;

	struct get_variable_info *gv_info = info;
	const char *field_names[] = {
			"hostname", "mntpt", "devpath", "devname", "uid", "gid", "mode",
			NULL, mount_point, gv_info->devpath, gv_info->devname, NULL
	};
	int i;

	if (!hostname)
		hostname = safe_gethostname();
	field_names[7] = hostname;

	/* index_in_str_array returns i>=0  */
	i = index_in_str_array(field_names, variable);

	if (i > 6 || i < 0 || (i > 1 && gv_info == NULL))
		return NULL;
	if (i >= 0 && i <= 3)
		return field_names[i + 7];

	if (i == 4)
		return auto_string(xasprintf("%u", gv_info->info->uid));
	if (i == 5)
		return auto_string(xasprintf("%u", gv_info->info->gid));
	/* i == 6 */
	return auto_string(xasprintf("%o", gv_info->info->mode));
}   /*  End Function get_variable  */

static void service(struct stat statbuf, char *path)
{
	struct devfsd_notify_struct info;

	memset(&info, 0, sizeof info);
	info.type = DEVFSD_NOTIFY_REGISTERED;
	info.mode = statbuf.st_mode;
	info.major = major(statbuf.st_rdev);
	info.minor = minor(statbuf.st_rdev);
	info.uid = statbuf.st_uid;
	info.gid = statbuf.st_gid;
	snprintf(info.devname, sizeof(info.devname), "%s", path + strlen(mount_point) + 1);
	info.namelen = strlen(info.devname);
	service_name(&info);
	if (S_ISDIR(statbuf.st_mode))
		dir_operation(SERVICE, path, 0, NULL);
}

static void dir_operation(int type, const char * dir_name, int var, unsigned long *event_mask)
/*  [SUMMARY] Scan a directory tree and generate register events on leaf nodes.
	<flag> To choose which function to perform
	<dp> The directory pointer. This is closed upon completion.
    <dir_name> The name of the directory.
	<rootlen> string length parameter.
    [RETURNS] Nothing.
*/
{
	struct stat statbuf;
	DIR *dp;
	struct dirent *de;
	char *path;

	dp = warn_opendir(dir_name);
	if (dp == NULL)
		return;

	while ((de = readdir(dp)) != NULL) {

		if (de->d_name && DOT_OR_DOTDOT(de->d_name))
			continue;
		path = concat_path_file(dir_name, de->d_name);
		if (lstat(path, &statbuf) == 0) {
			switch (type) {
				case SERVICE:
					service(statbuf, path);
					break;
				case RESTORE:
					restore(path, statbuf, var);
					break;
				case READ_CONFIG:
					read_config_file(path, var, event_mask);
					break;
			}
		}
		free(path);
	}
	closedir(dp);
}   /*  End Function do_scan_and_service  */

static int mksymlink(const char *oldpath, const char *newpath)
/*  [SUMMARY] Create a symlink, creating intervening directories as required.
    <oldpath> The string contained in the symlink.
    <newpath> The name of the new symlink.
    [RETURNS] 0 on success, else -1.
*/
{
	if (!make_dir_tree(newpath))
		return -1;

	if (symlink(oldpath, newpath) != 0) {
		if (errno != EEXIST)
			return -1;
	}
	return 0;
}   /*  End Function mksymlink  */


static int make_dir_tree(const char *path)
/*  [SUMMARY] Creating intervening directories for a path as required.
    <path> The full pathname(including the leaf node).
    [RETURNS] TRUE on success, else FALSE.
*/
{
	if (bb_make_directory(dirname((char *)path), -1, FILEUTILS_RECUR) == -1)
		return FALSE;
	return TRUE;
} /*  End Function make_dir_tree  */

static int expand_expression(char *output, unsigned int outsize,
			const char *input,
			const char *(*get_variable_func)(const char *variable, void *info),
			void *info,
			const char *devname,
			const regmatch_t *ex, unsigned int numexp)
/*  [SUMMARY] Expand environment variables and regular subexpressions in string.
    <output> The output expanded expression is written here.
    <length> The size of the output buffer.
    <input> The input expression. This may equal <<output>>.
    <get_variable> A function which will be used to get variable values. If
    this returns NULL, the environment is searched instead. If this is NULL,
    only the environment is searched.
    <info> An arbitrary pointer passed to <<get_variable>>.
    <devname> Device name; specifically, this is the string that contains all
    of the regular subexpressions.
    <ex> Array of start / end offsets into info->devname for each subexpression
    <numexp> Number of regular subexpressions found in <<devname>>.
    [RETURNS] TRUE on success, else FALSE.
*/
{
	char temp[STRING_LENGTH];

	if (!st_expr_expand(temp, STRING_LENGTH, input, get_variable_func, info))
		return FALSE;
	expand_regexp(output, outsize, temp, devname, ex, numexp);
	return TRUE;
}   /*  End Function expand_expression  */

static void expand_regexp(char *output, size_t outsize, const char *input,
			const char *devname,
			const regmatch_t *ex, unsigned int numex)
/*  [SUMMARY] Expand all occurrences of the regular subexpressions \0 to \9.
    <output> The output expanded expression is written here.
    <outsize> The size of the output buffer.
    <input> The input expression. This may NOT equal <<output>>, because
    supporting that would require yet another string-copy. However, it's not
    hard to write a simple wrapper function to add this functionality for those
    few cases that need it.
    <devname> Device name; specifically, this is the string that contains all
    of the regular subexpressions.
    <ex> An array of start and end offsets into <<devname>>, one for each
    subexpression
    <numex> Number of subexpressions in the offset-array <<ex>>.
    [RETURNS] Nothing.
*/
{
	const char last_exp = '0' - 1 + numex;
	int c = -1;

	/*  Guarantee NULL termination by writing an explicit '\0' character into
	the very last byte  */
	if (outsize)
		output[--outsize] = '\0';
	/*  Copy the input string into the output buffer, replacing '\\' with '\'
	and '\0' .. '\9' with subexpressions 0 .. 9, if they exist. Other \x
	codes are deleted  */
	while ((c != '\0') && (outsize != 0)) {
		c = *input;
		++input;
		if (c == '\\') {
			c = *input;
			++input;
			if (c != '\\') {
				if ((c >= '0') && (c <= last_exp)) {
					const regmatch_t *subexp = ex + (c - '0');
					unsigned int sublen = subexp->rm_eo - subexp->rm_so;

					/*  Range checking  */
					if (sublen > outsize)
						sublen = outsize;
					strncpy(output, devname + subexp->rm_so, sublen);
					output += sublen;
					outsize -= sublen;
				}
				continue;
			}
		}
		*output = c;
		++output;
		--outsize;
	} /* while */
}   /*  End Function expand_regexp  */


/* from compat_name.c */

struct translate_struct {
	const char *match;    /*  The string to match to(up to length)                */
	const char *format;   /*  Format of output, "%s" takes data past match string,
			NULL is effectively "%s"(just more efficient)       */
};

static struct translate_struct translate_table[] =
{
	{"sound/",     NULL},
	{"printers/",  "lp%s"},
	{"v4l/",       NULL},
	{"parports/",  "parport%s"},
	{"fb/",        "fb%s"},
	{"netlink/",   NULL},
	{"loop/",      "loop%s"},
	{"floppy/",    "fd%s"},
	{"rd/",        "ram%s"},
	{"md/",        "md%s"},         /*  Meta-devices                         */
	{"vc/",        "tty%s"},
	{"misc/",      NULL},
	{"isdn/",      NULL},
	{"pg/",        "pg%s"},         /*  Parallel port generic ATAPI interface*/
	{"i2c/",       "i2c-%s"},
	{"staliomem/", "staliomem%s"},  /*  Stallion serial driver control       */
	{"tts/E",      "ttyE%s"},       /*  Stallion serial driver               */
	{"cua/E",      "cue%s"},        /*  Stallion serial driver callout       */
	{"tts/R",      "ttyR%s"},       /*  Rocketport serial driver             */
	{"cua/R",      "cur%s"},        /*  Rocketport serial driver callout     */
	{"ip2/",       "ip2%s"},        /*  Computone serial driver control      */
	{"tts/F",      "ttyF%s"},       /*  Computone serial driver              */
	{"cua/F",      "cuf%s"},        /*  Computone serial driver callout      */
	{"tts/C",      "ttyC%s"},       /*  Cyclades serial driver               */
	{"cua/C",      "cub%s"},        /*  Cyclades serial driver callout       */
	{"tts/",       "ttyS%s"},       /*  Generic serial: must be after others */
	{"cua/",       "cua%s"},        /*  Generic serial: must be after others */
	{"input/js",   "js%s"},         /*  Joystick driver                      */
	{NULL,         NULL}
};

const char *get_old_name(const char *devname, unsigned int namelen,
			char *buffer, unsigned int major, unsigned int minor)
/*  [SUMMARY] Translate a kernel-supplied name into an old name.
    <devname> The device name provided by the kernel.
    <namelen> The length of the name.
    <buffer> A buffer that may be used. This should be at least 128 bytes long.
    <major> The major number for the device.
    <minor> The minor number for the device.
    [RETURNS] A pointer to the old name if known, else NULL.
*/
{
	const char *compat_name = NULL;
	const char *ptr;
	struct translate_struct *trans;
	unsigned int i;
	char mode;
	int indexx;
	const char *pty1;
	const char *pty2;
	/* 1 to 5  "scsi/" , 6 to 9 "ide/host", 10 sbp/, 11 vcc/, 12 pty/ */
	static const char *const fmt[] = {
		NULL ,
		"sg%u",			/* scsi/generic */
		NULL,			/* scsi/disc */
		"sr%u",			/* scsi/cd */
		NULL,			/* scsi/part */
		"nst%u%c",		/* scsi/mt */
		"hd%c"	,		/* ide/host/disc */
		"hd%c"	,		/* ide/host/cd */
		"hd%c%s",		/* ide/host/part */
		"%sht%d",		/* ide/host/mt */
		"sbpcd%u",		/* sbp/ */
		"vcs%s",		/* vcc/ */
		"%cty%c%c",		/* pty/ */
		NULL
	};

	for (trans = translate_table; trans->match != NULL; ++trans) {
		char *after_match = is_prefixed_with(devname, trans->match);
		if (after_match) {
			if (trans->format == NULL)
				return after_match;
			sprintf(buffer, trans->format, after_match);
			return buffer;
		}
	}

	ptr = bb_basename(devname);
	i = scan_dev_name(devname, namelen, ptr);

	if (i > 0 && i < 13)
		compat_name = buffer;
	else
		return NULL;

	/* 1 == scsi/generic, 3 == scsi/cd, 10 == sbp/ */
	if (i == 1 || i == 3 || i == 10)
		sprintf(buffer, fmt[i], minor);

	/* 2 ==scsi/disc, 4 == scsi/part */
	if (i == 2 || i == 4)
		compat_name = write_old_sd_name(buffer, major, minor, ((i == 2) ? "" : (ptr + 4)));

	/* 5 == scsi/mt */
	if (i == 5) {
		mode = ptr[2];
		if (mode == 'n')
			mode = '\0';
		sprintf(buffer, fmt[i], minor & 0x1f, mode);
		if (devname[namelen - 1] != 'n')
			++compat_name;
	}
	/* 6 == ide/host/disc, 7 == ide/host/cd, 8 == ide/host/part */
	if (i == 6 || i == 7 || i == 8)
		/* last arg should be ignored for i == 6 or i== 7 */
		sprintf(buffer, fmt[i] , get_old_ide_name(major, minor), ptr + 4);

	/* 9 ==  ide/host/mt */
	if (i == 9)
		sprintf(buffer, fmt[i], ptr + 2, minor & 0x7f);

	/*  11 == vcc/ */
	if (i == 11) {
		sprintf(buffer, fmt[i], devname + 4);
		if (buffer[3] == '0')
			buffer[3] = '\0';
	}
	/* 12 ==  pty/ */
	if (i == 12) {
		pty1 = "pqrstuvwxyzabcde";
		pty2 = "0123456789abcdef";
		indexx = atoi(devname + 5);
		sprintf(buffer, fmt[i], (devname[4] == 'm') ? 'p' : 't', pty1[indexx >> 4], pty2[indexx & 0x0f]);
	}
	return compat_name;
}   /*  End Function get_old_name  */

static char get_old_ide_name(unsigned int major, unsigned int minor)
/*  [SUMMARY] Get the old IDE name for a device.
    <major> The major number for the device.
    <minor> The minor number for the device.
    [RETURNS] The drive letter.
*/
{
	char letter = 'y';	/* 121 */
	char c = 'a';		/*  97 */
	int i = IDE0_MAJOR;

	/* I hope it works like the previous code as it saves a few bytes. Tito ;P */
	do {
		if (i == IDE0_MAJOR || i == IDE1_MAJOR || i == IDE2_MAJOR
		 || i == IDE3_MAJOR || i == IDE4_MAJOR || i == IDE5_MAJOR
		 || i == IDE6_MAJOR || i == IDE7_MAJOR || i == IDE8_MAJOR
		 || i == IDE9_MAJOR
		) {
			if ((unsigned int)i == major) {
				letter = c;
				break;
			}
			c += 2;
		}
		i++;
	} while (i <= IDE9_MAJOR);

	if (minor > 63)
		++letter;
	return letter;
}   /*  End Function get_old_ide_name  */

static char *write_old_sd_name(char *buffer,
				unsigned int major, unsigned int minor,
				const char *part)
/*  [SUMMARY] Write the old SCSI disc name to a buffer.
    <buffer> The buffer to write to.
    <major> The major number for the device.
    <minor> The minor number for the device.
    <part> The partition string. Must be "" for a whole-disc entry.
    [RETURNS] A pointer to the buffer on success, else NULL.
*/
{
	unsigned int disc_index;

	if (major == 8) {
		sprintf(buffer, "sd%c%s", 'a' + (minor >> 4), part);
		return buffer;
	}
	if ((major > 64) && (major < 72)) {
		disc_index = ((major - 64) << 4) +(minor >> 4);
		if (disc_index < 26)
			sprintf(buffer, "sd%c%s", 'a' + disc_index, part);
		else
			sprintf(buffer, "sd%c%c%s", 'a' +(disc_index / 26) - 1, 'a' + disc_index % 26, part);
		return buffer;
	}
	return NULL;
}   /*  End Function write_old_sd_name  */


/*  expression.c */

/*EXPERIMENTAL_FUNCTION*/

int st_expr_expand(char *output, unsigned int length, const char *input,
		const char *(*get_variable_func)(const char *variable,
						void *info),
		void *info)
/*  [SUMMARY] Expand an expression using Borne Shell-like unquoted rules.
    <output> The output expanded expression is written here.
    <length> The size of the output buffer.
    <input> The input expression. This may equal <<output>>.
    <get_variable> A function which will be used to get variable values. If
    this returns NULL, the environment is searched instead. If this is NULL,
    only the environment is searched.
    <info> An arbitrary pointer passed to <<get_variable>>.
    [RETURNS] TRUE on success, else FALSE.
*/
{
	char ch;
	unsigned int len;
	unsigned int out_pos = 0;
	const char *env;
	const char *ptr;
	struct passwd *pwent;
	char buffer[BUFFER_SIZE], tmp[STRING_LENGTH];

	if (length > BUFFER_SIZE)
		length = BUFFER_SIZE;
	for (; TRUE; ++input) {
		switch (ch = *input) {
			case '$':
				/*  Variable expansion  */
				input = expand_variable(buffer, length, &out_pos, ++input, get_variable_func, info);
				if (input == NULL)
					return FALSE;
				break;
			case '~':
				/*  Home directory expansion  */
				ch = input[1];
				if (isspace(ch) ||(ch == '/') ||(ch == '\0')) {
					/* User's own home directory: leave separator for next time */
					env = getenv("HOME");
					if (env == NULL) {
						info_logger(LOG_INFO, bb_msg_variable_not_found, "HOME");
						return FALSE;
					}
					len = strlen(env);
					if (len + out_pos >= length)
						goto st_expr_expand_out;
					memcpy(buffer + out_pos, env, len + 1);
					out_pos += len;
					continue;
				}
				/*  Someone else's home directory  */
				for (ptr = ++input; !isspace(ch) && (ch != '/') && (ch != '\0'); ch = *++ptr)
					/* VOID */;
				len = ptr - input;
				if (len >= sizeof tmp)
					goto st_expr_expand_out;
				safe_memcpy(tmp, input, len);
				input = ptr - 1;
				pwent = getpwnam(tmp);
				if (pwent == NULL) {
					info_logger(LOG_INFO, "no pwent for: %s", tmp);
					return FALSE;
				}
				len = strlen(pwent->pw_dir);
				if (len + out_pos >= length)
					goto st_expr_expand_out;
				memcpy(buffer + out_pos, pwent->pw_dir, len + 1);
				out_pos += len;
				break;
			case '\0':
			/* Falltrough */
			default:
				if (out_pos >= length)
					goto st_expr_expand_out;
				buffer[out_pos++] = ch;
				if (ch == '\0') {
					memcpy(output, buffer, out_pos);
					return TRUE;
				}
				break;
			/* esac */
		}
	}
	return FALSE;
st_expr_expand_out:
	simple_info_logger(LOG_INFO, bb_msg_small_buffer);
	return FALSE;
}   /*  End Function st_expr_expand  */


/*  Private functions follow  */

static const char *expand_variable(char *buffer, unsigned int length,
				unsigned int *out_pos, const char *input,
				const char *(*func)(const char *variable,
							void *info),
				void *info)
/*  [SUMMARY] Expand a variable.
    <buffer> The buffer to write to.
    <length> The length of the output buffer.
    <out_pos> The current output position. This is updated.
    <input> A pointer to the input character pointer.
    <func> A function which will be used to get variable values. If this
    returns NULL, the environment is searched instead. If this is NULL, only
    the environment is searched.
    <info> An arbitrary pointer passed to <<func>>.
    <errfp> Diagnostic messages are written here.
    [RETURNS] A pointer to the end of this subexpression on success, else NULL.
*/
{
	char ch;
	int len;
	unsigned int open_braces;
	const char *env, *ptr;
	char tmp[STRING_LENGTH];

	ch = input[0];
	if (ch == '$') {
		/*  Special case for "$$": PID  */
		sprintf(tmp, "%d", (int) getpid());
		len = strlen(tmp);
		if (len + *out_pos >= length)
			goto expand_variable_out;

		memcpy(buffer + *out_pos, tmp, len + 1);
		out_pos += len;
		return input;
	}
	/*  Ordinary variable expansion, possibly in braces  */
	if (ch != '{') {
		/*  Simple variable expansion  */
		for (ptr = input; isalnum(ch) || (ch == '_') || (ch == ':'); ch = *++ptr)
			/* VOID */;
		len = ptr - input;
		if ((size_t)len >= sizeof tmp)
			goto expand_variable_out;

		safe_memcpy(tmp, input, len);
		input = ptr - 1;
		env = get_variable_v2(tmp, func, info);
		if (env == NULL) {
			info_logger(LOG_INFO, bb_msg_variable_not_found, tmp);
			return NULL;
		}
		len = strlen(env);
		if (len + *out_pos >= length)
			goto expand_variable_out;

		memcpy(buffer + *out_pos, env, len + 1);
		*out_pos += len;
		return input;
	}
	/*  Variable in braces: check for ':' tricks  */
	ch = *++input;
	for (ptr = input; isalnum(ch) || (ch == '_'); ch = *++ptr)
		/* VOID */;
	if (ch == '}') {
		/*  Must be simple variable expansion with "${var}"  */
		len = ptr - input;
		if ((size_t)len >= sizeof tmp)
			goto expand_variable_out;

		safe_memcpy(tmp, input, len);
		ptr = expand_variable(buffer, length, out_pos, tmp, func, info);
		if (ptr == NULL)
			return NULL;
		return input + len;
	}
	if (ch != ':' || ptr[1] != '-') {
		simple_info_logger(LOG_INFO, "illegal char in var name");
		return NULL;
	}
	/*  It's that handy "${var:-word}" expression. Check if var is defined  */
	len = ptr - input;
	if ((size_t)len >= sizeof tmp)
		goto expand_variable_out;

	safe_memcpy(tmp, input, len);
	/*  Move input pointer to ':'  */
	input = ptr;
	/*  First skip to closing brace, taking note of nested expressions  */
	ptr += 2;
	ch = ptr[0];
	for (open_braces = 1; open_braces > 0; ch = *++ptr) {
		switch (ch) {
			case '{':
				++open_braces;
				break;
			case '}':
				--open_braces;
				break;
			case '\0':
				info_logger(LOG_INFO, "\"}\" not found in: %s", input);
				return NULL;
			default:
				break;
		}
	}
	--ptr;
	/*  At this point ptr should point to closing brace of "${var:-word}"  */
	env = get_variable_v2(tmp, func, info);
	if (env != NULL) {
		/*  Found environment variable, so skip the input to the closing brace
			and return the variable  */
		input = ptr;
		len = strlen(env);
		if (len + *out_pos >= length)
			goto expand_variable_out;

		memcpy(buffer + *out_pos, env, len + 1);
		*out_pos += len;
		return input;
	}
	/*  Environment variable was not found, so process word. Advance input
	pointer to start of word in "${var:-word}"  */
	input += 2;
	len = ptr - input;
	if ((size_t)len >= sizeof tmp)
		goto expand_variable_out;

	safe_memcpy(tmp, input, len);
	input = ptr;
	if (!st_expr_expand(tmp, STRING_LENGTH, tmp, func, info))
		return NULL;
	len = strlen(tmp);
	if (len + *out_pos >= length)
		goto expand_variable_out;

	memcpy(buffer + *out_pos, tmp, len + 1);
	*out_pos += len;
	return input;
expand_variable_out:
	simple_info_logger(LOG_INFO, bb_msg_small_buffer);
	return NULL;
}   /*  End Function expand_variable  */


static const char *get_variable_v2(const char *variable,
				const char *(*func)(const char *variable, void *info),
				void *info)
/*  [SUMMARY] Get a variable from the environment or .
    <variable> The variable name.
    <func> A function which will be used to get the variable. If this returns
    NULL, the environment is searched instead. If this is NULL, only the
    environment is searched.
    [RETURNS] The value of the variable on success, else NULL.
*/
{
	const char *value;

	if (func != NULL) {
		value = (*func)(variable, info);
		if (value != NULL)
			return value;
	}
	return getenv(variable);
}   /*  End Function get_variable  */

/* END OF CODE */
