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

#include "busybox.h"
#include "xregex.h"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <dirent.h>
#include <fcntl.h>
#include <syslog.h>
#include <signal.h>
#include <errno.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, char *);

/* busybox functions */
static void msg_logger(int pri, const char * fmt, ... )__attribute__ ((format (printf, 2, 3)));
static void msg_logger_and_die(int pri, const char * fmt, ... )__attribute__ ((noreturn, format (printf, 2, 3)));
static void do_ioctl_and_die(int fd, int request, unsigned long event_mask_flag);
static void fork_and_execute(int die, char *arg0, char **arg );
static int get_uid_gid ( int, const char *);
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, char *ptr);
static unsigned int scan_dev_name(const char *d, unsigned int n, char *ptr);

/* Structs and vars */
static struct config_entry_struct *first_config = NULL;
static struct config_entry_struct *last_config = NULL;
static const char *mount_point = NULL;
static volatile int caught_signal = FALSE;
static volatile int caught_sighup = FALSE;
static struct initial_symlink_struct
{
    char *dest;
    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 * const bb_msg_proto_rev			= "protocol revision";
static const char * const bb_msg_bad_config		= "bad %s config file: %s";
static const char * const bb_msg_small_buffer		= "buffer too small";
static const char * const bb_msg_variable_not_found = "variable: %s not found";

/* Busybox functions  */
static void msg_logger(int pri, const char * fmt, ... )
{
	va_list ap;
	int ret;

	va_start(ap, fmt);
	ret = access ("/dev/log", F_OK);
	if (ret == 0) {
		openlog(bb_applet_name, 0, LOG_DAEMON);
		vsyslog( pri , fmt, ap);
		/* Man: A trailing newline is added when needed. */
		closelog();
	}
	/* ENABLE_DEVFSD_VERBOSE is always enabled if msg_logger is used */
	if ((ENABLE_DEVFSD_VERBOSE && ret) || ENABLE_DEBUG) {
		bb_error_msg(fmt, ap);
	}
	va_end(ap);
}

static void msg_logger_and_die(int pri, const char* fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	msg_logger(pri, fmt, ap);
	va_end(ap);
	exit(EXIT_FAILURE);
}

/* Busybox stuff */
#if defined(CONFIG_DEVFSD_VERBOSE) || defined(CONFIG_DEBUG)
#define devfsd_error_msg(fmt, args...)                bb_error_msg(fmt, ## args)
#define devfsd_perror_msg_and_die(fmt, args...)       bb_perror_msg_and_die(fmt, ## args)
#define devfsd_error_msg_and_die(fmt, args...)        bb_error_msg_and_die(fmt, ## args)
#if defined(CONFIG_DEBUG)
#define debug_msg_logger(x, fmt, args...)             msg_logger(x, fmt, ## args)
#else
#define debug_msg_logger(x, fmt, args...)
#endif
#else
#define debug_msg_logger(x, fmt, args...)
#define msg_logger(p, fmt, args...)
#define msg_logger_and_die(p, fmt, args...)           exit(1)
#define devfsd_perror_msg_and_die(fmt, args...)       exit(1)
#define devfsd_error_msg_and_die(fmt, args...)        exit(1)
#define devfsd_error_msg(fmt, args...)
#endif

static void do_ioctl_and_die(int fd, int request, unsigned long event_mask_flag)
{
	if (ioctl (fd, request, event_mask_flag) == -1)
		msg_logger_and_die(LOG_ERR, "ioctl");
}

static void fork_and_execute(int die, char *arg0, char **arg )
{
	switch ( fork () )
	{
	case 0:
		/*  Child  */
		break;
	case -1:
		/*  Parent: Error  : die or return */
		msg_logger(LOG_ERR,(char *) bb_msg_memory_exhausted);
		if(die)
			exit(EXIT_FAILURE);
		return;
	default:
		/*  Parent : ok : return or exit  */
		if(arg0 != NULL)
		{
			wait (NULL);
			return;
		}
		exit (EXIT_SUCCESS);
	}
	 /* Child : if arg0 != NULL do execvp */
	if(arg0 != NULL )
	{
		execvp (arg0, arg);
		msg_logger_and_die(LOG_ERR, "execvp");
	}
}

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, char *ptr)
{
	if( d[n - 4]=='d' && d[n - 3]=='i' && d[n - 2]=='s' && d[n - 1]=='c')
		return (2 + addendum);
	else if( d[n - 2]=='c' && d[n - 1]=='d')
		return (3 + addendum);
	else if(ptr[0]=='p' && ptr[1]=='a' && ptr[2]=='r' && ptr[3]=='t')
		return (4 + addendum);
	else if( ptr[n - 2]=='m' && ptr[n - 1]=='t')
		return (5 + addendum);
	else
		return 0;
}

static unsigned int scan_dev_name(const char *d, unsigned int n, 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);
	}
	else 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);
	}
	else if(d[0]=='s' && d[1]=='b' && d[2]=='p' && d[3]=='/')
	{
		return 10;
	}
	else if(d[0]=='v' && d[1]=='c' && d[2]=='c' && d[3]=='/')
	{
		return 11;
	}
	else 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)
{
	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();
		}
	}

	/* strip last / from mount point, so we don't need to check for it later */
	while( argv[1][1]!='\0' && argv[1][strlen(argv[1])-1] == '/' )
		argv[1][strlen(argv[1]) -1] = '\0';

	mount_point = argv[1];

	if (chdir (mount_point) != 0)
		devfsd_perror_msg_and_die(mount_point);

	fd = bb_xopen (".devfsd", O_RDONLY);

	if (fcntl (fd, F_SETFD, FD_CLOEXEC) != 0)
		devfsd_perror_msg_and_die("FD_CLOEXEC");

	if (ioctl (fd, DEVFSDIOC_GET_PROTO_REV, &proto_rev) == -1)
		msg_logger_and_die(LOG_ERR, "ioctl");

	/*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) )
	{
		bb_printf( "%s v%s\nDaemon %s:\t%d\nKernel-side %s:\t%d\n",
					 bb_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)  */
	do_ioctl_and_die(fd, DEVFSDIOC_SET_EVENT_MASK, 0);

	sigemptyset (&new_action.sa_mask);
	new_action.sa_flags = 0;

	/*  Set up SIGHUP and SIGUSR1 handlers  */
	new_action.sa_handler = signal_handler;
	if (sigaction (SIGHUP, &new_action, NULL) != 0 || sigaction (SIGUSR1, &new_action, NULL) != 0 )
		devfsd_error_msg_and_die( "sigaction");

	bb_printf("%s v%s  started for %s\n",bb_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 (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 (0);
	if (do_daemon)
	{
		/*  Release so that the child can grab it  */
		do_ioctl_and_die(fd, DEVFSDIOC_RELEASE_EVENT_QUEUE, 0);
		fork_and_execute(DIE, NULL, NULL);
		setsid ();        /*  Prevent hangups and become pgrp leader         */
	} 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 (CONFIG_FILE, FALSE, &event_mask);
		if (do_scan)
			dir_operation(SERVICE,mount_point,0,NULL);
	}
}   /*  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;

	debug_msg_logger(LOG_INFO, "%s: %s", __FUNCTION__, path);

	if (stat (path, &statbuf) == 0 )
	{
		/* Don't read 0 length files: ignored */
		/*if( statbuf.st_size == 0 )
				return;*/
		if ( S_ISDIR (statbuf.st_mode) )
		{
			/* strip last / from dirname so we don't need to check for it later */
			while( path  && path[1]!='\0' && path[strlen(path)-1] == '/')
				path[strlen(path) -1] = '\0';

			dir_operation(READ_CONFIG, path, 0, event_mask);
			return;
		}
		if ( ( fp = fopen (path, "r") ) != NULL )
		{
			while (fgets (buf, STRING_LENGTH, fp) != NULL)
			{
				/*  Skip whitespace  */
				for (line = buf; isspace (*line); ++line)
					/*VOID*/;
				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)
		msg_logger_and_die(LOG_ERR, "read config file: %s: %m", path);
	}
	return;
}   /*  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];
	char * msg="";
	char *ptr;
	int i;

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

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	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 = compare_string_array(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 );
		msg_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 = xmalloc (sizeof *new);
	memset (new, 0, 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 = compare_string_array(options, what );

	switch(i)
	{
		case 4:	/* "PERMISSIONS" */
			new->action.what = AC_PERMISSIONS;
			/*  Get user and group  */
			if ( ( ptr = strchr (p[0], '.') ) == 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] = bb_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 = bb_xstrdup (p[0]);
			new->u.copy.destination = bb_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;
	unsigned long tmp_event_mask;

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	/*  Tell devfs what events we care about  */
	tmp_event_mask = event_mask;
	do_ioctl_and_die(fd, DEVFSDIOC_SET_EVENT_MASK, tmp_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;

	debug_msg_logger(LOG_INFO, __FUNCTION__);
	if (ENABLE_DEBUG && info->overrun_count > 0)
		debug_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 */;

		debug_msg_logger(LOG_INFO, "%s: action.what %d", __FUNCTION__, entry->action.what);

		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;

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	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)
	{
		msg_logger(LOG_ERR, "Can't chmod or chown: %s: %m",info->devname);
	}
}   /*  End Function action_permissions  */

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

	argv[0] = MODPROBE;
	argv[1] = MODPROBE_SWITCH_1; /* "-k" */
	argv[2] = MODPROBE_SWITCH_2; /* "-C" */
	argv[3] = CONFIG_MODULES_DEVFS;
	argv[4] = device;
	argv[5] = NULL;

	snprintf (device, sizeof (device), "/dev/%s", info->devname);
	debug_msg_logger(LOG_INFO, "%s: %s %s %s %s %s",__FUNCTION__, argv[0],argv[1],argv[2],argv[3],argv[4]);
	fork_and_execute(DIE, argv[0], argv);
}  /*  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];

	debug_msg_logger(LOG_INFO ,__FUNCTION__);
	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;
	fork_and_execute(NO_DIE, argv[0], 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;

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	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))
		debug_msg_logger(LOG_ERR, "copy_inode: %s to %s: %m", source, destination);
	return;
}   /*  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;
	char *ptr=NULL;
	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 = strrchr (info->devname, '/') + 1;
			i=scan_dev_name(info->devname, info->namelen, ptr);

			debug_msg_logger(LOG_INFO, "%s: scan_dev_name = %d", __FUNCTION__, i);

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

	debug_msg_logger( LOG_INFO, "%s: %s", __FUNCTION__, compat_name);

	/*  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)
				debug_msg_logger(LOG_ERR, "unlink: %s: %m", compat_name);
			break;
		/*esac*/
	} /* switch(action) */
}   /*  End Function action_compat  */

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

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	dest_stat.st_mode = 0;
	snprintf (dpath, sizeof dpath, "%s%s", mount_point, spath + rootlen);
	lstat (dpath, &dest_stat);

	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];

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	if ( (source_stat->st_mode & S_IFMT) == (dest_stat->st_mode & S_IFMT) )
	{
		/*  Same type  */
		if ( S_ISLNK (source_stat->st_mode) )
		{
			if (( source_len = readlink (sourcepath, source_link, STRING_LENGTH - 1) ) < 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:
			if ( ( fd = socket (AF_UNIX, SOCK_STREAM, 0) ) < 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:
			if ( ( val = readlink (sourcepath, symlink_val, STRING_LENGTH - 1) ) < 0 )
				break;
			symlink_val[val] = '\0';
			if (symlink (symlink_val, destpath) == 0)
				return (TRUE);
			break;
		case S_IFREG:
			if ( ( fd = open (destpath, O_RDONLY | O_CREAT, new_mode & ~S_IFMT) ) < 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;

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	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;
	static char *msg;

	if (ENABLE_DEVFSD_VERBOSE)
		msg="user";

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	if(ENABLE_DEBUG && flag != UID && flag != GID)
		msg_logger_and_die(LOG_ERR,"%s: flag != UID && flag != GID", __FUNCTION__);

	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 ( flag == GID && ( grp_ent = getgrnam (string) ) != NULL )
		return (grp_ent->gr_gid);
	else 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;

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	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)
{
	debug_msg_logger(LOG_INFO, __FUNCTION__);

	caught_signal = TRUE;
	if (sig == SIGHUP)
		caught_sighup = TRUE;

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

static const char *get_variable (const char *variable, void *info)
{
	struct get_variable_info *gv_info = info;
	static char hostname[STRING_LENGTH], sbuf[STRING_LENGTH];
	const char *field_names[] = { "hostname", "mntpt", "devpath", "devname",
								   "uid", "gid", "mode", hostname, mount_point,
								   gv_info->devpath, gv_info->devname, 0 };
	int i;

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	if (gethostname (hostname, STRING_LENGTH - 1) != 0)
		msg_logger_and_die(LOG_ERR, "gethostname: %m");

		/* Here on error we should do exit(RV_SYS_ERROR), instead we do exit(EXIT_FAILURE) */
		hostname[STRING_LENGTH - 1] = '\0';

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

	if ( i > 6 || i < 0 || (i > 1 && gv_info == NULL))
			return (NULL);
	if( i >= 0 && i <= 3)
	{
		debug_msg_logger(LOG_INFO, "%s: i=%d %s", __FUNCTION__, i ,field_names[i+7]);
		return(field_names[i+7]);
	}

	if(i == 4 )
		sprintf (sbuf, "%u", gv_info->info->uid);
	else if(i == 5)
		sprintf (sbuf, "%u", gv_info->info->gid);
	else if(i == 6)
		sprintf (sbuf, "%o", gv_info->info->mode);

	debug_msg_logger(LOG_INFO, "%s: %s", __FUNCTION__, sbuf);

	return (sbuf);
}   /*  End Function get_variable  */

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

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	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[STRING_LENGTH];

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	if((dp = opendir( dir_name))==NULL)
	{
		debug_msg_logger(LOG_ERR, "opendir: %s: %m", dir_name);
		return;
	}

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

		if(de->d_name && *de->d_name == '.' && (!de->d_name[1] || (de->d_name[1] == '.' && !de->d_name[2])))
			continue;
		snprintf (path, sizeof (path), "%s/%s", dir_name, de->d_name);
		debug_msg_logger(LOG_ERR, "%s: %s", __FUNCTION__, path);

		if (lstat (path, &statbuf) != 0)
		{
			debug_msg_logger(LOG_ERR, "%s: %s: %m", __FUNCTION__, path);
			continue;
		}
		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;
		}
	}
	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.
*/
{
	debug_msg_logger(LOG_INFO, __FUNCTION__);

	if ( !make_dir_tree (newpath) )
		return (-1);

	if (symlink (oldpath, newpath) != 0)
    {
		if (errno != EEXIST)
		{
			debug_msg_logger(LOG_ERR, "%s: %s to %s: %m", __FUNCTION__, oldpath, newpath);
			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.
*/
{
	debug_msg_logger(LOG_INFO, __FUNCTION__);

	if (bb_make_directory( dirname((char *)path), -1, FILEUTILS_RECUR )==-1)
	{
		debug_msg_logger(LOG_ERR, "%s: %s: %m",__FUNCTION__, path);
		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];

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	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;

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	/*  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
{
	char *match;    /*  The string to match to (up to length)                */
	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;
	char *ptr;
	struct translate_struct *trans;
	unsigned int i;
	char mode;
	int indexx;
	const char *pty1;
	const char *pty2;
	size_t len;
	/* 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
	};

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	for (trans = translate_table; trans->match != NULL; ++trans)
	{
		 len = strlen (trans->match);

		if (strncmp (devname, trans->match, len) == 0)
		{
			if (trans->format == NULL)
				return (devname + len);
			sprintf (buffer, trans->format, devname + len);
			return (buffer);
		}
	}

	ptr = (strrchr (devname, '/') + 1);
	i = scan_dev_name(devname, namelen, ptr);

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

	debug_msg_logger(LOG_INFO, "%s: scan_dev_name = %d", __FUNCTION__, i);

	/* 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]);
	}

	if(ENABLE_DEBUG && compat_name!=NULL)
		msg_logger(LOG_INFO, "%s: compat_name  %s", __FUNCTION__, compat_name);

	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;

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	/* 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,
				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;

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	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];

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	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 */
					if ( ( env = getenv ("HOME") ) == NULL )
					{
						msg_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;
				if ( ( pwent = getpwnam (tmp) ) == NULL )
				{
					msg_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:
	msg_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];

	debug_msg_logger(LOG_INFO, __FUNCTION__);

	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;
		if ( ( env = get_variable_v2 (tmp, func, info) ) == NULL )
		{
			msg_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] != '-' )
	{
		msg_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':
				msg_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}"  */
	if ( ( env = get_variable_v2 (tmp, func, info) ) != 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:
	msg_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;

	debug_msg_logger(LOG_INFO, __FUNCTION__);

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

/* END OF CODE */
