/* 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 PLATFORM_LINUX
//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:	select PLATFORM_LINUX
//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 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 */
