Patch from Tito, size optimisation, cleanup noise when in debugging

mode, adds support for MODLOAD keyword in devfsd.conf, provides a
cleaned up version of example/devfsd.conf
This commit is contained in:
Glenn L McGrath 2003-11-30 23:46:06 +00:00
parent 5be6a200f0
commit 3860b2ebd6
3 changed files with 197 additions and 238 deletions

View File

@ -25,11 +25,10 @@ UNREGISTER .* RMNEWCOMPAT
# Enable module autoloading. You may comment this out if you don't use # Enable module autoloading. You may comment this out if you don't use
# autoloading # autoloading
# Not supported by busybox # Supported by busybox when CONFIG_DEVFSD_MODLOAD is set.
#LOOKUP .* MODLOAD # This actually doesn't work with busybox modutils but needs
# Maybe one of these works for busybox # the real modutils' modprobe
#LOOKUP .* EXECUTE /sbin/modprobe -k -v -C /etc/modules.devfs * LOOKUP .* MODLOAD
#REGISTER .* EXECUTE /sbin/modprobe -k -v -C /etc/modules.devfs *
# Uncomment the following if you want to set the group to "tty" for the # Uncomment the following if you want to set the group to "tty" for the
# pseudo-tty devices. This is necessary so that mesg(1) can later be used to # pseudo-tty devices. This is necessary so that mesg(1) can later be used to
@ -68,7 +67,6 @@ RESTORE /lib/dev-state
REGISTER ^cdroms/cdrom0$ EXECUTE /bin/ln -sf $devname cdrom REGISTER ^cdroms/cdrom0$ EXECUTE /bin/ln -sf $devname cdrom
UNREGISTER ^cdroms/cdrom0$ EXECUTE /bin/rm -f cdrom UNREGISTER ^cdroms/cdrom0$ EXECUTE /bin/rm -f cdrom
#REGISTER ^v4l/video0$ CFUNCTION GLOBAL mksymlink v4l/video0 video #REGISTER ^v4l/video0$ CFUNCTION GLOBAL mksymlink v4l/video0 video
#UNREGISTER ^v4l/video0$ CFUNCTION GLOBAL unlink video #UNREGISTER ^v4l/video0$ CFUNCTION GLOBAL unlink video
#REGISTER ^radio0$ CFUNCTION GLOBAL mksymlink radio0 radio #REGISTER ^radio0$ CFUNCTION GLOBAL mksymlink radio0 radio
@ -80,18 +78,23 @@ REGISTER ^radio0$ EXECUTE /bin/ln -sf radio0 radio
UNREGISTER ^radio0$ EXECUTE /bin/rm -f radio UNREGISTER ^radio0$ EXECUTE /bin/rm -f radio
# ALSA stuff # ALSA stuff
# Not supported by busybox
#LOOKUP snd MODLOAD ACTION snd #LOOKUP snd MODLOAD ACTION snd
# Maybe this works for busybox
#LOOKUP snd EXECUTE /sbin/modprobe -k -v -C /etc/modules.devfs snd
# Uncomment this to let PAM manage devfs # Uncomment this to let PAM manage devfs
# Not supported by busybox
#REGISTER .* CFUNCTION /lib/security/pam_console_apply_devfsd.so pam_console_apply_single $devpath #REGISTER .* CFUNCTION /lib/security/pam_console_apply_devfsd.so pam_console_apply_single $devpath
# Uncomment this to manage USB mouse # Uncomment this to manage USB mouse
# Not supported by busybox
#REGISTER ^input/mouse0$ CFUNCTION GLOBAL mksymlink $devname usbmouse #REGISTER ^input/mouse0$ CFUNCTION GLOBAL mksymlink $devname usbmouse
#UNREGISTER ^input/mouse0$ CFUNCTION GLOBAL unlink usbmouse #UNREGISTER ^input/mouse0$ CFUNCTION GLOBAL unlink usbmouse
# Busybox # Busybox
#REGISTER ^input/mouse0$ EXECUTE /bin/ln -sf $devname usbmouse
#UNREGISTER ^input/mouse0$ EXECUTE /bin/rm -f usbmouse
# Not supported by busybox
#REGISTER ^input/mice$ CFUNCTION GLOBAL mksymlink $devname usbmouse
#UNREGISTER ^input/mice$ CFUNCTION GLOBAL unlink usbmouse
# Busybox
REGISTER ^input/mice$ EXECUTE /bin/ln -sf $devname usbmouse REGISTER ^input/mice$ EXECUTE /bin/ln -sf $devname usbmouse
UNREGISTER ^input/mice$ EXECUTE /bin/rm -f usbmouse UNREGISTER ^input/mice$ EXECUTE /bin/rm -f usbmouse
@ -107,75 +110,24 @@ LOOKUP ^(ide/hd/c[0-9]+b[0-9]+t[0-9]+u[0-9]+)p[0-9]+$ EXECUTE /bin/dd if=$mntpn
LOOKUP ^(hd[a-z])[0-9]+$ EXECUTE /bin/dd if=$mntpnt/\1 of=/dev/null count=1 LOOKUP ^(hd[a-z])[0-9]+$ EXECUTE /bin/dd if=$mntpnt/\1 of=/dev/null count=1
# IDE-SCSI NEWCOMPAT /dev/sd/* names # IDE-SCSI NEWCOMPAT /dev/sd/* names
#LOOKUP ^(sd/c[0-9]+b[0-9]+t[0-9]+u[0-9]+)p[0-9]+$ EXECUTE /bin/dd if=$mntpnt/\1 of=/dev/null count=1 #LOOKUP ^(sd/c[0-9]+b[0-9]+t[0-9]+u[0-9]+)p[0-9]+$ EXECUTE /bin/dd if=$mntpnt/\1 of=/dev/null count=1
# SCSI OLDCOMPAT /dev/scd? names #SCSI OLDCOMPAT /dev/scd? names
LOOKUP ^(scd+)[0-9]+$ EXECUTE /bin/dd if=$mntpnt/\1 of=/dev/null count=1 LOOKUP ^(scd+)[0-9]+$ EXECUTE /bin/dd if=$mntpnt/\1 of=/dev/null count=1
REGISTER ^dvb/card[0-9]+/[^/]+$ PERMISSIONS root.video 0660 REGISTER ^dvb/card[0-9]+/[^/]+$ PERMISSIONS root.video 0660
# Busybox # Not supported by busybox
#REGISTER ^dvb/card([0-9]+)/([^/0-9]*)[0-9]+$ CFUNCTION GLOBAL mksymlink /dev/$devname ost/\2\1 #REGISTER ^dvb/card([0-9]+)/([^/0-9]*)[0-9]+$ CFUNCTION GLOBAL mksymlink /dev/$devname ost/\2\1
#UNREGISTER ^dvb/card([0-9]+)/([^/0-9]*)[0-9]+$ CFUNCTION GLOBAL unlink ost/\2\1 #UNREGISTER ^dvb/card([0-9]+)/([^/0-9]*)[0-9]+$ CFUNCTION GLOBAL unlink ost/\2\1
# Busybox
REGISTER ^dvb/card([0-9]+)/([^/0-9]*)[0-9]+$ EXECUTE /bin/ln -sf /dev/$devname ost/\2\1 REGISTER ^dvb/card([0-9]+)/([^/0-9]*)[0-9]+$ EXECUTE /bin/ln -sf /dev/$devname ost/\2\1
UNREGISTER ^dvb/card([0-9]+)/([^/0-9]*)[0-9]+$ EXECUTE /bin/rm -f ost/\2\1 UNREGISTER ^dvb/card([0-9]+)/([^/0-9]*)[0-9]+$ EXECUTE /bin/rm -f ost/\2\1
# Include package-generated files from /etc/devfs/conf.d # Include package-generated files from /etc/devfs/conf.d
# Supported by busybox # Supported by busybox
#OPTIONAL_INCLUDE /etc/devfs/conf.d/dvd.conf # INCLUDE /etc/devfs/conf.d/
#INCLUDE /etc/devfs/conf.d/dvd.conf INCLUDE /etc/devfs/busybox/
#OPTIONAL_INCLUDE /etc/devfs/conf.d/ # Busybox: just for testing
#INCLUDE /etc/devfs/conf.d/ #INCLUDE /etc/devfs/nothing/
#INCLUDE /etc/devfs/nothing/nothing
#/etc/devfs/conf.d/dvd.conf #OPTIONAL_INCLUDE /etc/devfs/nothing/
#REGISTER ^ide/host0/bus1/target1/lun0/cd$ CFUNCTION GLOBAL mksymlink ide/host0/bus1/target1/lun0/cd dvd #OPTIONAL_INCLUDE /etc/devfs/nothing/nothing
#UNREGISTER ^ide/host0/bus1/target1/lun0/cd$ CFUNCTION GLOBAL unlink dvd
REGISTER ^ide/host0/bus1/target1/lun0/cd$ EXECUTE ln -sf ide/host0/bus1/target1/lun0/cd dvd
UNREGISTER ^ide/host0/bus1/target1/lun0/cd$ EXECUTE rm -f dvd
#/etc/devfs/conf.d/dynamic.conf
# dynamic desktop and co
REGISTER .*/part.* EXECUTE /etc/dynamic/scripts/part.script add $devpath
UNREGISTER .*/part.* EXECUTE /etc/dynamic/scripts/part.script del $devpath
REGISTER v4l/video.* EXECUTE /etc/dynamic/scripts/webcam.script add $devpath
UNREGISTER v4l/video.* EXECUTE /etc/dynamic/scripts/webcam.script del $devpath
REGISTER usb/scanner.* EXECUTE /etc/dynamic/scripts/scanner.script add $devpath
UNREGISTER usb/scanner.* EXECUTE /etc/dynamic/scripts/scanner.script del $devpath
REGISTER usb/rio500 EXECUTE /etc/dynamic/scripts/rio500.script add $devpath
UNREGISTER usb/rio500 EXECUTE /etc/dynamic/scripts/rio500.script del $devpath
REGISTER usb/tts/[13579] EXECUTE /etc/dynamic/scripts/visor.script add $devpath
UNREGISTER usb/tts/[13579] EXECUTE /etc/dynamic/scripts/visor.script del $devpath
REGISTER (usb/lp.*|printers/.*) EXECUTE /etc/dynamic/scripts/lp.script add $devpath
UNREGISTER (usb/lp.*|printers/.*) EXECUTE /etc/dynamic/scripts/lp.script del $devpath
#/etc/devfs/conf.d/modem.conf
#REGISTER ^$ CFUNCTION GLOBAL mksymlink modem
#UNREGISTER ^$ CFUNCTION GLOBAL unlink modem
REGISTER ^tts/0$ EXECUTE ln -sf $devname modem
UNREGISTER ^$ EXECUTE rm -f modem
#/etc/devfs/conf.d/mouse.conf
#REGISTER ^misc/psaux$ CFUNCTION GLOBAL mksymlink misc/psaux mouse
#UNREGISTER ^misc/psaux$ CFUNCTION GLOBAL unlink mouse
REGISTER ^misc/psaux$ EXECUTE ln -sf misc/psaux mouse
UNREGISTER ^misc/psaux$ EXECUTE rm -f mouse
#/etc/devfs/conf.d/psaux.conf
#REGISTER ^misc/psaux$ CFUNCTION GLOBAL mksymlink misc/psaux psaux
#UNREGISTER ^misc/psaux$ CFUNCTION GLOBAL unlink psaux
REGISTER ^misc/psaux$ EXECUTE ln -sf misc/psaux psaux
UNREGISTER ^misc/psaux$ EXECUTE rm -f psaux
#/etc/devfs/conf.d/rdvd.conf
REGISTER ^ide/host0/bus1/target1/lun0/cd$ EXECUTE /etc/dynamic/scripts/rawdevice.script add /dev/ide/host0/bus1/target1/lun0/cd /dev/rdvd
UNREGISTER ^ide/host0/bus1/target1/lun0/cd$ EXECUTE /etc/dynamic/scripts/rawdevice.script del /dev/rdvd
#/etc/devfs/conf.d/ttyS0.conf
#REGISTER ^tts/0$ CFUNCTION GLOBAL mksymlink tts/0 ttyS0
#UNREGISTER ^tts/0$ CFUNCTION GLOBAL unlink ttyS0
REGISTER ^tts/0$ EXECUTE ln -sf $devname ttyS0
UNREGISTER ^tts/0$ EXECUTE rm -f ttyS0

View File

@ -47,6 +47,13 @@ config CONFIG_DEVFSD
Provides compatibility with old device names on a devfs systems. Provides compatibility with old device names on a devfs systems.
You should set it to true if you have devfs enabled. You should set it to true if you have devfs enabled.
config CONFIG_DEVFSD_MODLOAD
bool "Adds support for MODLOAD action"
default n
depends on CONFIG_DEVFSD
help
This actually doesn't work with busybox modutils but needs the real modutils.
config CONFIG_DEVFSD_VERBOSE config CONFIG_DEVFSD_VERBOSE
bool "Increases logging to stderr and syslog" bool "Increases logging to stderr and syslog"
default n default n

View File

@ -129,6 +129,8 @@ struct devfsd_notify_struct
#define BUFFER_SIZE 16384 #define BUFFER_SIZE 16384
#define DEVFSD_VERSION "1.3.25" #define DEVFSD_VERSION "1.3.25"
#define CONFIG_FILE "/etc/devfsd.conf" #define CONFIG_FILE "/etc/devfsd.conf"
#define MODPROBE "/sbin/modprobe"
#define CONFIG_MODULES_DEVFS "/etc/modules.devfs"
#define MAX_ARGS (6 + 1) #define MAX_ARGS (6 + 1)
#define MAX_SUBEXPR 10 #define MAX_SUBEXPR 10
#define STRING_LENGTH 255 #define STRING_LENGTH 255
@ -138,10 +140,15 @@ struct devfsd_notify_struct
#define GID 1 #define GID 1
/* for msg_logger(), do_ioctl(), /* for msg_logger(), do_ioctl(),
fork_and_execute() and xopendir(). */ fork_and_execute() */
# define DIE 1 # define DIE 1
# define NO_DIE 0 # 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 */ /* Update only after changing code to reflect new protocol */
#define DEVFSD_PROTOCOL_REVISION_DAEMON 5 #define DEVFSD_PROTOCOL_REVISION_DAEMON 5
@ -151,11 +158,11 @@ struct devfsd_notify_struct
#endif #endif
#define AC_PERMISSIONS 0 #define AC_PERMISSIONS 0
#define AC_MODLOAD 1 /* not supported by busybox */ #define AC_MODLOAD 1
#define AC_EXECUTE 2 #define AC_EXECUTE 2
#define AC_MFUNCTION 3 /* not supported by busybox */ #define AC_MFUNCTION 3 /* not supported by busybox */
#define AC_CFUNCTION 4 /* not supported by busybox */ #define AC_CFUNCTION 4 /* not supported by busybox */
#define AC_COPY 5 #define AC_COPY 5
#define AC_IGNORE 6 #define AC_IGNORE 6
#define AC_MKOLDCOMPAT 7 #define AC_MKOLDCOMPAT 7
#define AC_MKNEWCOMPAT 8 #define AC_MKNEWCOMPAT 8
@ -209,6 +216,8 @@ struct get_variable_info
char devpath[STRING_LENGTH]; 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 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 const char *get_old_name(const char *, unsigned, char *, unsigned, unsigned);
static int mksymlink (const char *oldpath, const char *newpath); static int mksymlink (const char *oldpath, const char *newpath);
@ -219,16 +228,18 @@ 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_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 *, static void action_execute (const struct devfsd_notify_struct *, const struct config_entry_struct *,
const regmatch_t *, unsigned); const regmatch_t *, unsigned);
#ifdef CONFIG_DEVFSD_MODLOAD
static void action_modload (const struct devfsd_notify_struct *info, const struct config_entry_struct *entry);
#endif
static void action_copy (const struct devfsd_notify_struct *, const struct config_entry_struct *, static void action_copy (const struct devfsd_notify_struct *, const struct config_entry_struct *,
const regmatch_t *, unsigned); const regmatch_t *, unsigned);
static void action_compat (const struct devfsd_notify_struct *, unsigned); static void action_compat (const struct devfsd_notify_struct *, unsigned);
static void free_config (void); static void free_config (void);
static void do_restore (const char *, int); 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 int copy_inode (const char *, const struct stat *, mode_t, const char *, const struct stat *);
static mode_t get_mode (const char *); static mode_t get_mode (const char *);
static void signal_handler (int); static void signal_handler (int);
static const char *get_variable (const char *, void *); static const char *get_variable (const char *, void *);
static void do_scan_and_service (const char *);
static int make_dir_tree (const char *); static int make_dir_tree (const char *);
static int expand_expression(char *, unsigned, const char *, const char *(*)(const char *, void *), void *, static int expand_expression(char *, unsigned, const char *, const char *(*)(const char *, void *), void *,
const char *, const regmatch_t *, unsigned ); const char *, const regmatch_t *, unsigned );
@ -243,7 +254,6 @@ static char *write_old_sd_name (char *, unsigned, unsigned, char *);
static void msg_logger(int die, int pri, const char * fmt, ... ); static void msg_logger(int die, int pri, const char * fmt, ... );
static void do_ioctl(int die, int fd, int request, unsigned long event_mask_flag); static void do_ioctl(int die, int fd, int request, unsigned long event_mask_flag);
static void fork_and_execute(int die, char *arg0, char **arg ); static void fork_and_execute(int die, char *arg0, char **arg );
DIR * xopendir(int die, const char * dir_name);
static int get_uid_gid ( int, const char *); static int get_uid_gid ( int, const char *);
static void safe_memcpy( char * dest, const char * src, int len); static void safe_memcpy( char * dest, const char * src, int len);
@ -318,7 +328,7 @@ static void msg_logger(int die, int pri, const char * fmt, ... )
static void do_ioctl(int die, int fd, int request, unsigned long event_mask_flag) static void do_ioctl(int die, int fd, int request, unsigned long event_mask_flag)
{ {
if (ioctl (fd, request, event_mask_flag) != 0) if (ioctl (fd, request, event_mask_flag) != 0)
msg_logger(die, LOG_ERR, "ioctl() failed: %m\n"); msg_logger(die, LOG_ERR, "ioctl(): %m\n");
} }
static void fork_and_execute(int die, char *arg0, char **arg ) static void fork_and_execute(int die, char *arg0, char **arg )
@ -345,21 +355,10 @@ static void fork_and_execute(int die, char *arg0, char **arg )
if(arg0 != NULL ) if(arg0 != NULL )
{ {
execvp (arg0, arg); execvp (arg0, arg);
msg_logger(DIE, LOG_ERR, "execvp() failed: %s: %m\n", arg0); msg_logger(DIE, LOG_ERR, "execvp(): %s: %m\n", arg0);
} }
} }
DIR * xopendir(int die, const char * dir_name)
{
DIR *dp;
if ( ( dp = opendir (dir_name) ) == NULL )
msg_logger( die, LOG_ERR, "opendir() failed: %s: %m\n", dir_name);
/* if die == DIE not reached else return NULL */
return dp;
}
static void safe_memcpy( char *dest, const char *src, int len) static void safe_memcpy( char *dest, const char *src, int len)
{ {
memcpy (dest , src , len ); memcpy (dest , src , len );
@ -437,7 +436,7 @@ int devfsd_main (int argc, char **argv)
umask (0); umask (0);
read_config_file (CONFIG_FILE, FALSE, &event_mask); read_config_file (CONFIG_FILE, FALSE, &event_mask);
/* Do the scan before forking, so that boot scripts see the finished product */ /* Do the scan before forking, so that boot scripts see the finished product */
do_scan_and_service (mount_point); dir_operation(SERVICE,mount_point,0,NULL);
if (no_polling) if (no_polling)
exit (0); exit (0);
if (do_daemon) if (do_daemon)
@ -457,7 +456,7 @@ int devfsd_main (int argc, char **argv)
free_config (); free_config ();
read_config_file (CONFIG_FILE, FALSE, &event_mask); read_config_file (CONFIG_FILE, FALSE, &event_mask);
if (do_scan) if (do_scan)
do_scan_and_service (mount_point); dir_operation(SERVICE,mount_point,0,NULL);
} }
} /* End Function main */ } /* End Function main */
@ -476,32 +475,17 @@ static void read_config_file (const char *path, int optional, unsigned long *eve
struct stat statbuf; struct stat statbuf;
FILE *fp; FILE *fp;
char buf[STRING_LENGTH]; char buf[STRING_LENGTH];
char *line=NULL;
#ifdef CONFIG_DEVFSD_DEBUG #ifdef CONFIG_DEVFSD_DEBUG
msg_logger( NO_DIE, LOG_INFO, "read_config_file()\n"); msg_logger( NO_DIE, LOG_INFO, "read_config_file()\n");
#endif #endif
if (stat (path, &statbuf) != 0 || statbuf.st_size == 0 ) if (stat (path, &statbuf) != 0 || statbuf.st_size == 0 )
msg_logger((optional == 0 )? DIE : NO_DIE, LOG_ERR, " %s: %m\n", path); goto read_config_file_err;
if ( S_ISDIR (statbuf.st_mode) ) if ( S_ISDIR (statbuf.st_mode) )
{ {
dir_operation(READ_CONFIG, path, 0, event_mask);
DIR *dp;
struct dirent *de;
dp = xopendir(DIE, path);
while ( ( de = readdir (dp) ) != NULL )
{
char fname[STRING_LENGTH];
if (de->d_name[0] == '.')
continue;
snprintf (fname, STRING_LENGTH, "%s/%s", path, de->d_name);
read_config_file (fname, optional, event_mask);
}
closedir (dp);
return; return;
} }
@ -509,9 +493,13 @@ static void read_config_file (const char *path, int optional, unsigned long *eve
{ {
while (fgets (buf, STRING_LENGTH, fp) != NULL) while (fgets (buf, STRING_LENGTH, fp) != NULL)
{ {
char *line; /* GETS(3) Linux Programmer's Manual
fgets() reads in at most one less than size characters from stream and
buf[strlen (buf) - 1] = '\0'; stores them into the buffer pointed to by s. Reading stops after an
EOF or a newline. If a newline is read, it is stored into the buffer.
A '\0' is stored after the last character in the buffer.
*/
/*buf[strlen (buf) - 1] = '\0';*/
/* Skip whitespace */ /* Skip whitespace */
for (line = buf; isspace (*line); ++line) for (line = buf; isspace (*line); ++line)
/*VOID*/; /*VOID*/;
@ -520,12 +508,13 @@ static void read_config_file (const char *path, int optional, unsigned long *eve
process_config_line (line, event_mask); process_config_line (line, event_mask);
} }
fclose (fp); fclose (fp);
#ifdef CONFIG_DEVFSD_VERBOSE errno=0;
msg_logger( NO_DIE, LOG_INFO, "read config file: %s\n", path);
#endif
return;
} }
msg_logger(( (optional == 0) && (errno == ENOENT) )? DIE : NO_DIE, LOG_ERR, " %s: %m\n", path); read_config_file_err:
#ifdef CONFIG_DEVFSD_VERBOSE
msg_logger(((optional == 0 ) && (errno == ENOENT))? DIE : NO_DIE, LOG_ERR, "read config file: %s: %m\n", path);
#endif
return;
} /* End Function read_config_file */ } /* End Function read_config_file */
static void process_config_line (const char *line, unsigned long *event_mask) static void process_config_line (const char *line, unsigned long *event_mask)
@ -541,6 +530,8 @@ static void process_config_line (const char *line, unsigned long *event_mask)
char when[STRING_LENGTH], what[STRING_LENGTH]; char when[STRING_LENGTH], what[STRING_LENGTH];
char name[STRING_LENGTH]; char name[STRING_LENGTH];
char * msg=""; char * msg="";
char *ptr;
#ifdef CONFIG_DEVFSD_DEBUG #ifdef CONFIG_DEVFSD_DEBUG
msg_logger( NO_DIE, LOG_INFO, "process_config_line()\n"); msg_logger( NO_DIE, LOG_INFO, "process_config_line()\n");
#endif #endif
@ -562,12 +553,15 @@ static void process_config_line (const char *line, unsigned long *event_mask)
(strcasecmp (when, "OPTIONAL_INCLUDE") == 0) ) (strcasecmp (when, "OPTIONAL_INCLUDE") == 0) )
{ {
st_expr_expand (name, STRING_LENGTH, name, get_variable, NULL ); st_expr_expand (name, STRING_LENGTH, name, get_variable, NULL );
#ifdef CONFIG_DEVFSD_VERBOSE
msg_logger( NO_DIE, LOG_INFO, "%sinclude: %s\n",(toupper (when[0]) == 'I') ? "": "optional_", name);
#endif
read_config_file (name, (toupper (when[0]) == 'I') ? FALSE : TRUE, event_mask); read_config_file (name, (toupper (when[0]) == 'I') ? FALSE : TRUE, event_mask);
return; return;
} }
if (strcasecmp (when, "RESTORE") == 0) if (strcasecmp (when, "RESTORE") == 0)
{ {
do_restore ( name, strlen (name) ); dir_operation(RESTORE,name, strlen (name),NULL);
return; return;
} }
if (num_args < 3) if (num_args < 3)
@ -591,8 +585,6 @@ static void process_config_line (const char *line, unsigned long *event_mask)
if (strcasecmp (what, "PERMISSIONS") == 0) if (strcasecmp (what, "PERMISSIONS") == 0)
{ {
char *ptr;
new->action.what = AC_PERMISSIONS; new->action.what = AC_PERMISSIONS;
/* Get user and group */ /* Get user and group */
if ( ( ptr = strchr (p[0], '.') ) == NULL ) if ( ( ptr = strchr (p[0], '.') ) == NULL )
@ -607,6 +599,14 @@ static void process_config_line (const char *line, unsigned long *event_mask)
/* Get mode */ /* Get mode */
new->u.permissions.mode = get_mode (p[1]); new->u.permissions.mode = get_mode (p[1]);
} }
#ifdef CONFIG_DEVFSD_MODLOAD
else if (strcasecmp (what, "MODLOAD") == 0)
/*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.*/
new->action.what = AC_MODLOAD;
#endif
else if (strcasecmp (what, "EXECUTE") == 0) else if (strcasecmp (what, "EXECUTE") == 0)
{ {
new->action.what = AC_EXECUTE; new->action.what = AC_EXECUTE;
@ -673,11 +673,6 @@ static int do_servicing (int fd, unsigned long event_mask)
#endif #endif
/* Tell devfs what events we care about */ /* Tell devfs what events we care about */
tmp_event_mask = event_mask; tmp_event_mask = event_mask;
/* May need to trap inode creates to watch for syslogd(8) starting */
/*if (!syslog_is_open && !no_syslog)
{
tmp_event_mask |= 1 << DEVFSD_NOTIFY_CREATE; *//*FIXME I'm not sure if this line is needed. TITO */
/*}*/
do_ioctl(DIE, fd, DEVFSDIOC_SET_EVENT_MASK, tmp_event_mask); do_ioctl(DIE, fd, DEVFSDIOC_SET_EVENT_MASK, tmp_event_mask);
while (!caught_signal) while (!caught_signal)
{ {
@ -689,14 +684,6 @@ static int do_servicing (int fd, unsigned long event_mask)
continue; /* Yes, the order is important */ continue; /* Yes, the order is important */
if (bytes < 1) if (bytes < 1)
break; break;
/* Special trap for "/dev/log" creation */
/* Open syslog, now that "/dev/log" exists */
/*if (!syslog_is_open && !no_syslog &&
(info.type == DEVFSD_NOTIFY_CREATE) &&(strcmp (info.devname, "log") == 0) )
{
do_open_syslog ();
do_ioctl(DIE, fd, DEVFSDIOC_SET_EVENT_MASK, event_mask);*/ /*FIXME I'm not sure if this line is needed. TITO */
/*}*/
service_name (&info); service_name (&info);
} }
if (caught_signal) if (caught_signal)
@ -752,6 +739,14 @@ static void service_name (const struct devfsd_notify_struct *info)
#endif #endif
action_permissions (info, entry); action_permissions (info, entry);
break; break;
#ifdef CONFIG_DEVFSD_MODLOAD
case AC_MODLOAD:
#ifdef CONFIG_DEVFSD_DEBUG
msg_logger( NO_DIE, LOG_INFO, "AC_MODLOAD\n");
#endif
action_modload (info, entry);
break;
#endif
case AC_EXECUTE: case AC_EXECUTE:
#ifdef CONFIG_DEVFSD_DEBUG #ifdef CONFIG_DEVFSD_DEBUG
msg_logger( NO_DIE, LOG_INFO, "AC_EXECUTE\n"); msg_logger( NO_DIE, LOG_INFO, "AC_EXECUTE\n");
@ -805,13 +800,39 @@ static void action_permissions (const struct devfsd_notify_struct *info,
chown (info->devname, entry->u.permissions.uid, entry->u.permissions.gid) != 0) chown (info->devname, entry->u.permissions.uid, entry->u.permissions.gid) != 0)
{ {
#ifdef CONFIG_DEVFSD_VERBOSE #ifdef CONFIG_DEVFSD_VERBOSE
msg_logger( NO_DIE, LOG_ERR, "chmod() or chown() error for: %s: %m\n",info->devname); msg_logger( NO_DIE, LOG_ERR, "chmod() or chown(): %s: %m\n",info->devname);
#endif #endif
return; return;
} }
} /* End Function action_permissions */ } /* End Function action_permissions */
#ifdef CONFIG_DEVFSD_MODLOAD
static void action_modload (const struct devfsd_notify_struct *info,
const struct config_entry_struct *entry)
/* [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] = "-k";
argv[2] = "-C";
argv[3] = CONFIG_MODULES_DEVFS;
argv[4] = device;
argv[5] = NULL;
#ifdef CONFIG_DEVFSD_DEBUG
msg_logger( NO_DIE, LOG_INFO, "action_modload()\n");
#endif
snprintf (device, sizeof (device), "/dev/%s", info->devname);
fork_and_execute(DIE, argv[0], argv);
} /* End Function action_modload */
#endif
static void action_execute (const struct devfsd_notify_struct *info, static void action_execute (const struct devfsd_notify_struct *info,
const struct config_entry_struct *entry, const struct config_entry_struct *entry,
const regmatch_t *regexpr, unsigned int numexpr) const regmatch_t *regexpr, unsigned int numexpr)
@ -903,8 +924,7 @@ static void action_copy (const struct devfsd_notify_struct *info,
regexpr, numexpr); regexpr, numexpr);
if ( !make_dir_tree (destination) || lstat (source, &source_stat) != 0) if ( !make_dir_tree (destination) || lstat (source, &source_stat) != 0)
goto action_copy_error; return;
lstat (destination, &dest_stat); lstat (destination, &dest_stat);
new_mode = source_stat.st_mode & ~S_ISVTX; new_mode = source_stat.st_mode & ~S_ISVTX;
if (info->type == DEVFSD_NOTIFY_CREATE) if (info->type == DEVFSD_NOTIFY_CREATE)
@ -913,13 +933,11 @@ static void action_copy (const struct devfsd_notify_struct *info,
new_mode |= S_ISVTX; new_mode |= S_ISVTX;
#ifdef CONFIG_DEVFSD_VERBOSE #ifdef CONFIG_DEVFSD_VERBOSE
if ( !copy_inode (destination, &dest_stat, new_mode, source, &source_stat) ) if ( !copy_inode (destination, &dest_stat, new_mode, source, &source_stat) )
action_copy_error: msg_logger( NO_DIE, LOG_ERR, "copy_inode(): %s to %s: %m\n", source, destination);
msg_logger( NO_DIE, LOG_ERR, "error copying: %s to %s: %m\n", source, destination);
#else #else
copy_inode (destination, &dest_stat, new_mode, source,&source_stat); copy_inode (destination, &dest_stat, new_mode, source, &source_stat);
action_copy_error:
return;
#endif #endif
return;
} /* End Function action_copy */ } /* End Function action_copy */
static void action_compat (const struct devfsd_notify_struct *info, static void action_compat (const struct devfsd_notify_struct *info,
@ -1041,53 +1059,26 @@ static void action_compat (const struct devfsd_notify_struct *info,
} }
} /* End Function action_compat */ } /* End Function action_compat */
static void do_restore (const char *dir_name, int rootlen) static void restore(char *spath, struct stat source_stat, int rootlen)
/* [SUMMARY] Restore state from a directory.
<dir_name> The directory containing the backing store.
<rootlen> The length of the root of the state directory hierarchy.
[RETURNS] Nothing.
*/
{ {
DIR *dp; char dpath[STRING_LENGTH];
struct dirent *de; struct stat dest_stat;
#ifdef CONFIG_DEVFSD_DEBUG #ifdef CONFIG_DEVFSD_DEBUG
msg_logger( NO_DIE, LOG_INFO, "do_restore()\n"); msg_logger( NO_DIE, LOG_INFO, "restore()\n");
#endif #endif
if( (dp = xopendir(NO_DIE, dir_name))== NULL) dest_stat.st_mode = 0;
return; snprintf (dpath, sizeof dpath, "%s%s", mount_point, spath + rootlen);
lstat (dpath, &dest_stat);
while ( (de = readdir (dp) ) != NULL ) 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);
char spath[STRING_LENGTH], dpath[STRING_LENGTH];
struct stat source_stat, dest_stat; if ( S_ISDIR (source_stat.st_mode) )
dest_stat.st_mode = 0; dir_operation(RESTORE, spath, rootlen,NULL);
}
if ( (strcmp (de->d_name, ".") == 0) || (strcmp (de->d_name, "..") == 0) )
continue;
snprintf (spath, sizeof spath, "%s/%s", dir_name, de->d_name);
if (lstat (spath, &source_stat) != 0)
{
#ifdef CONFIG_DEVFSD_VERBOSE
msg_logger( NO_DIE, LOG_ERR, "%s: %m\n", spath);
#endif
continue;
}
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) )
do_restore (spath, rootlen);
}
closedir (dp);
} /* End Function do_restore */
static int copy_inode (const char *destpath, const struct stat *dest_stat, static int copy_inode (const char *destpath, const struct stat *dest_stat,
mode_t new_mode, mode_t new_mode,
@ -1148,9 +1139,7 @@ static int copy_inode (const char *destpath, const struct stat *dest_stat,
close (fd); close (fd);
if (val != 0 || chmod (destpath, new_mode & ~S_IFMT) != 0) if (val != 0 || chmod (destpath, new_mode & ~S_IFMT) != 0)
break; break;
if (chown (destpath, source_stat->st_uid, source_stat->st_gid) == 0) goto do_chown;
return (TRUE);
break;
case S_IFLNK: case S_IFLNK:
if ( ( val = readlink (sourcepath, symlink_val, STRING_LENGTH - 1) ) < 0 ) if ( ( val = readlink (sourcepath, symlink_val, STRING_LENGTH - 1) ) < 0 )
break; break;
@ -1164,23 +1153,19 @@ static int copy_inode (const char *destpath, const struct stat *dest_stat,
close (fd); close (fd);
if (chmod (destpath, new_mode & ~S_IFMT) != 0) if (chmod (destpath, new_mode & ~S_IFMT) != 0)
break; break;
if (chown (destpath, source_stat->st_uid, source_stat->st_gid) == 0) goto do_chown;
return (TRUE);
break;
case S_IFBLK: case S_IFBLK:
case S_IFCHR: case S_IFCHR:
case S_IFIFO: case S_IFIFO:
if (mknod (destpath, new_mode, source_stat->st_rdev) != 0) if (mknod (destpath, new_mode, source_stat->st_rdev) != 0)
break; break;
if (chown (destpath, source_stat->st_uid, source_stat->st_gid) == 0) goto do_chown;
return (TRUE);
break;
case S_IFDIR: case S_IFDIR:
if (mkdir (destpath, new_mode & ~S_IFMT) != 0) if (mkdir (destpath, new_mode & ~S_IFMT) != 0)
break; break;
do_chown:
if (chown (destpath, source_stat->st_uid, source_stat->st_gid) == 0) if (chown (destpath, source_stat->st_uid, source_stat->st_gid) == 0)
return (TRUE); return (TRUE);
return (TRUE);
/*break;*/ /*break;*/
} }
return (FALSE); return (FALSE);
@ -1228,15 +1213,14 @@ static int get_uid_gid (int flag, const char *string)
{ {
struct passwd *pw_ent; struct passwd *pw_ent;
struct group *grp_ent; struct group *grp_ent;
char * msg_a="user"; char * msg="user";
char * msg_b="U";
#ifdef CONFIG_DEVFSD_DEBUG #ifdef CONFIG_DEVFSD_DEBUG
msg_logger( NO_DIE, LOG_INFO, "get_uid_gid()\n"); msg_logger( NO_DIE, LOG_INFO, "get_uid_gid()\n");
if(flag != UID && flag != GID ) if(flag != UID && flag != GID )
msg_logger( DIE, LOG_ERR,"flag != UID && flag != GID\n"); msg_logger( DIE, LOG_ERR,"get_uid_gid(): flag != UID && flag != GID\n");
#endif #endif
if ( isdigit (string[0]) || ( (string[0] == '-') && isdigit (string[1]) ) ) if ( isdigit (string[0]) || ( (string[0] == '-') && isdigit (string[1]) ) )
@ -1248,12 +1232,9 @@ static int get_uid_gid (int flag, const char *string)
if ( flag == GID && ( grp_ent = getgrnam (string) ) != NULL ) if ( flag == GID && ( grp_ent = getgrnam (string) ) != NULL )
return (grp_ent->gr_gid); return (grp_ent->gr_gid);
else else
{ msg="group";
msg_a="group";
msg_b="G";
}
msg_logger( NO_DIE, LOG_ERR,"unknown %s: %s, defaulting to %cID=0\n", msg_a, string, msg_b); msg_logger( NO_DIE, LOG_ERR,"unknown %s: %s, defaulting to %cID=0\n", msg, string, msg[0] - 32);
return (0); return (0);
}/* End Function get_uid_gid */ }/* End Function get_uid_gid */
@ -1264,7 +1245,7 @@ static mode_t get_mode (const char *string)
*/ */
{ {
mode_t mode; mode_t mode;
int i;
#ifdef CONFIG_DEVFSD_DEBUG #ifdef CONFIG_DEVFSD_DEBUG
msg_logger( NO_DIE, LOG_INFO, "get_mode()\n"); msg_logger( NO_DIE, LOG_INFO, "get_mode()\n");
#endif #endif
@ -1274,15 +1255,14 @@ static mode_t get_mode (const char *string)
if (strlen (string) != 9) if (strlen (string) != 9)
msg_logger( DIE, LOG_ERR, "bad mode: %s\n", string); msg_logger( DIE, LOG_ERR, "bad mode: %s\n", string);
mode = 0; mode = 0;
if (string[0] == 'r') mode |= S_IRUSR; i= S_IRUSR;
if (string[1] == 'w') mode |= S_IWUSR; while(i>0)
if (string[2] == 'x') mode |= S_IXUSR; {
if (string[3] == 'r') mode |= S_IRGRP; if(string[0]=='r'||string[0]=='w'||string[0]=='x')
if (string[4] == 'w') mode |= S_IWGRP; mode+=i;
if (string[5] == 'x') mode |= S_IXGRP; i=i/2;
if (string[6] == 'r') mode |= S_IROTH; string++;
if (string[7] == 'w') mode |= S_IWOTH; }
if (string[8] == 'x') mode |= S_IXOTH;
return (mode); return (mode);
} /* End Function get_mode */ } /* End Function get_mode */
@ -1341,10 +1321,34 @@ static const char *get_variable (const char *variable, void *info)
return (NULL); return (NULL);
} /* End Function get_variable */ } /* End Function get_variable */
static void do_scan_and_service (const char *dir_name) static void service(struct stat statbuf, char *path)
{
struct devfsd_notify_struct info;
#ifdef CONFIG_DEVFSD_DEBUG
msg_logger( NO_DIE, LOG_INFO, "service()\n");
#endif
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. /* [SUMMARY] Scan a directory tree and generate register events on leaf nodes.
<dp> The directory pointer. This is closed upon completion. <flag> To choose which function to perform
<dp> The directory pointer. This is closed upon completion.
<dir_name> The name of the directory. <dir_name> The name of the directory.
<rootlen> string length parameter.
[RETURNS] Nothing. [RETURNS] Nothing.
*/ */
{ {
@ -1353,20 +1357,24 @@ static void do_scan_and_service (const char *dir_name)
struct dirent *de; struct dirent *de;
char path[STRING_LENGTH]; char path[STRING_LENGTH];
#ifdef CONFIG_DEVFSD_DEBUG #ifdef CONFIG_DEVFSD_DEBUG
msg_logger( NO_DIE, LOG_INFO, "do_scan_and_service ()\n"); msg_logger( NO_DIE, LOG_INFO, "dir_operation()\n");
#endif #endif
if((dp = xopendir(NO_DIE, dir_name))==NULL) if((dp = opendir( dir_name))==NULL)
{
msg_logger( NO_DIE, LOG_ERR, "opendir(): %s: %m\n", dir_name);
return; return;
}
while ( (de = readdir (dp) ) != NULL ) while ( (de = readdir (dp) ) != NULL )
{ {
struct devfsd_notify_struct info;
if ( (strcmp (de->d_name, ".") == 0) || (strcmp (de->d_name, "..") == 0) ) if ( (strcmp (de->d_name, ".") == 0) || (strcmp (de->d_name, "..") == 0) )
continue; continue;
snprintf (path, sizeof (path), "%s/%s", dir_name, de->d_name); snprintf (path, sizeof (path), "%s%s%s", dir_name,(last_char_is(dir_name,'/')==NULL)?"/":"", de->d_name);
if (lstat (path, &statbuf) != 0) if (lstat (path, &statbuf) != 0)
{ {
#ifdef CONFIG_DEVFSD_VERBOSE #ifdef CONFIG_DEVFSD_VERBOSE
@ -1374,18 +1382,18 @@ static void do_scan_and_service (const char *dir_name)
#endif #endif
continue; continue;
} }
memset (&info, 0, sizeof info); switch(type)
info.type = DEVFSD_NOTIFY_REGISTERED; {
info.mode = statbuf.st_mode; case SERVICE:
info.major = major (statbuf.st_rdev); service(statbuf,path);
info.minor = minor (statbuf.st_rdev); break;
info.uid = statbuf.st_uid; case RESTORE:
info.gid = statbuf.st_gid; restore(path, statbuf, var);
snprintf (info.devname, sizeof (info.devname), "%s", path + strlen (mount_point) + 1); break;
info.namelen = strlen (info.devname); case READ_CONFIG:
service_name (&info); read_config_file (path, var, event_mask);
if ( S_ISDIR (statbuf.st_mode) ) break;
do_scan_and_service (path); }
} }
closedir (dp); closedir (dp);
} /* End Function do_scan_and_service */ } /* End Function do_scan_and_service */
@ -1408,17 +1416,10 @@ static int mksymlink (const char *oldpath, const char *newpath)
if (symlink (oldpath, newpath) != 0) if (symlink (oldpath, newpath) != 0)
{ {
#ifdef CONFIG_DEVFSD_VERBOSE #ifdef CONFIG_DEVFSD_VERBOSE
if (errno == EEXIST) msg_logger( NO_DIE, LOG_ERR, "symlink(): %s to %s: %m\n", oldpath, newpath);
msg_logger( NO_DIE, LOG_INFO, "symlink(): %s: already exists\n", newpath); #endif
else
{
msg_logger( NO_DIE, LOG_ERR, "symlink(): %s: %m\n", newpath);
return (-1);
}
#else
if (errno != EEXIST) if (errno != EEXIST)
return (-1); return (-1);
#endif
} }
return (0); return (0);
} /* End Function mksymlink */ } /* End Function mksymlink */
@ -1701,7 +1702,6 @@ static char get_old_ide_name (unsigned int major, unsigned int minor)
char c='a'; /* 97 */ char c='a'; /* 97 */
int i=IDE0_MAJOR; int i=IDE0_MAJOR;
#ifdef CONFIG_DEVFSD_DEBUG #ifdef CONFIG_DEVFSD_DEBUG
msg_logger( NO_DIE, LOG_INFO, "get_old_ide_name()\n"); msg_logger( NO_DIE, LOG_INFO, "get_old_ide_name()\n");
#endif #endif