/* 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.
*/

//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_error_msg(fmt, ## args)
#define msg_logger(p, fmt, args...)                  bb_error_msg(fmt, ## args)
#define msg_logger_and_die(p, fmt, args...)          bb_error_msg_and_die(fmt, ## args)
#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 msg_logger_and_die(p, fmt, args...)           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;
	}
	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:
				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:
	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] != '-') {
		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:
	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 */
