📄 devfsd.c
字号:
/* devfsd.c Main file for devfsd (devfs daemon for Linux). Copyright (C) 1998-2002 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.*//* This programme will manage the devfs filesystem. Written by Richard Gooch 9-AUG-1998 Updated by Richard Gooch 11-AUG-1998 Updated by Richard Gooch 10-SEP-1998: Added support for asynchronous open and close events. Updated by Richard Gooch 11-SEP-1998: Fixed bug in <read_config> where <<line>> pointer was dereferenced before being initialised. Updated by Richard Gooch 9-JUN-1999: Added variable expansion support. Updated by Richard Gooch 10-JUN-1999: Added "devname" variable and renamed "device" variable name to "devpath". Fixed bug in argument handling. Added "-d" switch. Updated by Richard Gooch 13-JUN-1999: Added compile-time check of protocol revision. Updated by Richard Gooch 14-JUN-1999: Stat inode instead of using device entry information (which may be out of date). Updated by Richard Gooch 15-JUN-1999: Added tracing output. Thanks to Piete Brooks <Piete.Brooks@cl.cam.ac.uk>. Updated by Richard Gooch 16-JUN-1999: Added action structure. Updated by Richard Gooch 17-JUN-1999: Added "hostname" and "mntpnt" variables. Added nesting of include files. Added "CLEAR_CONFIG" key. Updated by Richard Gooch 18-JUN-1999: Added "OPTIONAL_INCLUDE" key. Added ignore actions. Added event mask. Updated by Richard Gooch 24-JUN-1999: Switched to separated event and action config file specifiers. Updated by Richard Gooch 20-OCT-1999: Fixed typo in debugging output Updated by Richard Gooch 24-OCT-1999: Added "-fg" switch and redefined tracing levels. Delay opening syslog until /dev/log appears. Scan mounted FS and generate synthetic REGISTER events. Updated by Richard Gooch 25-OCT-1999: Added compatibility actions. Added compatibility entries for sound, printer, video4linux, parallel port and frame buffer drivers. Updated by Richard Gooch 26-OCT-1999: Incremented protocol revision to 5. Extract major and minor number in <do_scan_and_service>. Added compatibility entries for SoundBlaster CD-ROM, netlink, SCSI generic and SCSI tape drivers. Updated by Richard Gooch 30-OCT-1999: Added entries for /dev/st, /dev/sg and /dev/sr hierarchies. Added compatibility entries for loop, IDE tape and SCSI CD-ROM drivers. Updated by Richard Gooch 31-OCT-1999: Added compatibility entries for floppy, RAMDISC, meta-device, SCSI disc, IDE disc and IDE CD-ROM drivers. Added entries for /dev/sd, /dev/ide/hd and /dev/ide/cd hierarchies. Updated by Richard Gooch 3-NOV-1999: Created <make_symlink> which will create intermediate directories as required. Updated compatibility code for IDE tapes. Added entries for /dev/ide/mt hierarchy. Updated by Richard Gooch 4-NOV-1999: Added compatibility entries for virtual console capture, serial and console devices. Updated by Richard Gooch 5-NOV-1999: Added compatibility entries for BSD pty devices. Updated by Richard Gooch 11-NOV-1999: Only show messages about compatibility entries being created or destroyed when in trace mode. Updated by Richard Gooch 21-NOV-1999: Added compatibility entries for joystick devices. Updated by Richard Gooch 6-DEC-1999: Change directory to devfs FS. Updated by Richard Gooch 9-DEC-1999: Support compiling with 2.2.x kernels. Updated by Richard Gooch 15-DEC-1999: Added compatibility entries for miscellaneous character devices. Updated by Richard Gooch 17-DEC-1999: Do not grab event queue when just setting devfs debug mask. Updated by Richard Gooch 20-DEC-1999: Swap pathname and action fields in config file. Updated by Richard Gooch 25-DEC-1999: Discard lookups on "/dev/log" and "/dev/initctl". Added "MODLOAD" action. Updated by Richard Gooch 3-FEB-2000: Bitch and moan if modprobe(8) is used with "EXECUTE" action. Updated by Richard Gooch 3-MAR-2000: Bug fix with inclusion directives. Updated by Richard Gooch 6-MAR-2000: Support negative UID and GID in config file. Thanks to Chris Richards <crichard@wso.williams.edu>. Updated by Richard Gooch 12-APR-2000: More efficient discarding of lookups on "/dev/log" and "/dev/initctl". Updated by Richard Gooch 16-APR-2000: Added "MFUNCTION" and "CFUNCTION" actions. Added compatibility entries for Computone Multiport serial devices. Updated by Richard Gooch 17-APR-2000: Added "COPY" action. Updated by Richard Gooch 18-APR-2000: Moved some things to header "devfsd.h". Removed special argument "ENTRY" and renamed "INFO" to "EVENT" for "CFUNCTION" action. Bug fix in debug mode with shared objects. Updated by Richard Gooch 20-APR-2000: Changed version macro. Updated by Richard Gooch 24-APR-2000: Created a table of rules for simple compatibility translations. Split part of <read_config> into <process_config_line>, in preparation for NIS support. Updated by Richard Gooch 26-APR-2000: Added NIS configuration support. Updated by Richard Gooch 27-APR-2000: Fixed DIR leak. Generate synthetic REGISTER events on SIGHUP. Silently ignore NIS attempts when no NIS domain set. Updated by Richard Gooch 30-APR-2000: Moved parts of <action_compat> to <get_old_name> in compat_name.c. Simplified <action_compat> for SCSI and IDE new compatibilty entries. Updated by Richard Gooch 10-JUN-2000: Moved version string to version.h Updated by Richard Gooch 3-JUL-2000: Added "-C /etc/modules.devfs" when calling modprobe(8). Fail if a configuration line has EXECUTE modprobe. Updated by Richard Gooch 4-JUL-2000: Added #define __USE_GNU. Thanks to Adam J. Richter <adam@yggdrasil.com>. Updated by Chris Rankin 21-JAN-2001: Allow the daemon to substitute regular expressions, similarly to sed. E.g. the expression ^foo\([0-9]\)$ has a subexpression within the \(, \) markers. The string foo4 matches this expression: the tag \0 would be replaced by "foo4", its first subexpression \1 by "4", etc. Updated by Richard Gooch 5-FEB-2001: Switched from __USE_GNU to _GNU_SOURCE, according to recommendation from Ulrich. Do dummy opens of /dev/null so that fds [0:2] are open (and thus may be safely closed later). Updated by Richard Gooch 21-FEB-2001: Bug fix in function <action_call_function>: a failed MFUNCTION would result in a bogus CFUNCTION being called. Updated by Richard Gooch 27-JUL-2001: Bug fixes when execvp(3) fails (child did not exit). Updated by Richard Gooch 30-JUL-2001: Applied and cleaned up patch by Chris Rankin (regular subexpression support). Fixed potential buffer overrun problems by using <snprintf>. Thanks to Sebastian Krahmer <krahmer@suse.de>. Added "-np" switch. Thanks to John Fremlin. Updated by Richard Gooch 31-JUL-2001: Added support for DELETE event. Added debug trace to <action_modload>. Updated by Richard Gooch 8-AUG-2001: Added support for recursively reading config directories. Updated by Richard Gooch 10-AUG-2001: Fixed support for recursively reading config directories. Updated by Richard Gooch 14-AUG-2001: Move opendir(3) call to <do_scan_and_service>. Be more tolerant of some system errors. Fixed file descriptor leak in <action_copy>. Updated by Richard Gooch 18-AUG-2001: Dynamically load libnsl at run-time as needed, rather than linking. Based on patch from Adam J. Richter. Updated by Richard Gooch 19-AUG-2001: Switched to stat(2) in <action_permissions> to avoid harmless false positives. Return 0 instead of exiting if passwd or group entry not found in database. Do not exit in <action_execute> if fork(2) fails. Updated by Richard Gooch 16-SEP-2001: Set environment to "safe mode" when invoking modprobe. Generate error message if /lib/modutils.so doesn't contain "modprobe" symbol. Add debugging message if /lib/modutils.so missing. Based on patch from Russell Coker. Updated by Richard Gooch 6-NOV-2001: Called setsid(2) when closing fds[0:2] so that hangups from the old controlling terminal are ignored. Updated by Richard Gooch 22-NOV-2001: Moved call to setsid(2) to immediately after forking child/daemon. Added call to setpgid(2) if running in the foreground. These changes are in anticipation of a kernel switch from ancestor process checking to process group checking. Updated by Richard Gooch 25-NOV-2001: Created <<event_types>> table. Generate synthetic REGISTER event for directories in <do_scan_and_service>. Updated by Richard Gooch 28-NOV-2001: Renamed <make_symlink> to <mksymlink> and made it global. Changed to return 0 on "success". Updated by Richard Gooch 29-NOV-2001: Changed <action_copy> to set sticky bit as required. Added "RESTORE" key. Updated by Richard Gooch 1-JAN-2002: Changed to extended regular expressions. Updated by Richard Gooch 14-JAN-2002: Fixed dummy opens of /dev/null so that fds [0:2] are open (was only doing fds [0:1]) and prevent infinite loop if /dev/null cannot be opened. Updated by Richard Gooch 20-JAN-2002: Fixed <action_compat> to ignore new compatibility names for IDE devices. Updated by Richard Gooch 14-FEB-2002: Do not re-read config file if signals other than SIGHUP are caught. Updated by Richard Gooch 6-MAR-2002: Catch SIGUSR1. Updated by Richard Gooch 8-MAR-2002: Make /lib/devfsd the default directory for shared objects. Updated by Richard Gooch 14-MAR-2002: Set close-on-exec flag for .devfsd control file. Last updated by Richard Gooch 21-MAR-2002: Set umask so that mknod(2), open(2) and mkdir(2) have complete control over permissions.*/#define _GNU_SOURCE#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <pwd.h>#include <grp.h>#include <sys/time.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 <linux/devfs_fs.h>#include <linux/kdev_t.h>#include <syslog.h>#include <signal.h>#include <regex.h>#include <errno.h>#include <dlfcn.h>#include <rpcsvc/ypclnt.h>#include <rpcsvc/yp_prot.h>#include <karma.h>#include "devfsd.h"#include "version.h"#ifndef RTLD_DEFAULT /* Libc 5 doesn't define it, but it works */# define RTLD_DEFAULT NULL#endif#define CONFIG_FILE "/etc/devfsd.conf"#define MAX_ARGS (6 + 1)#define MAX_SUBEXPR 10/* 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 MKACTION(what,when) (struct action_type) {what, when}#define AC_PERMISSIONS 0#define AC_MODLOAD 1#define AC_EXECUTE 2#define AC_MFUNCTION 3#define AC_CFUNCTION 4#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 11struct 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 call_function_type{ struct shared_object *so; union { int (*m) (int argc, char **argv); int (*c) (void *arg1, void *arg2, void *arg3, void *arg4, void *arg5); } func; char *argv[MAX_ARGS + 1]; /* argv[0] is the function name */};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 call_function_type function; 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];};struct shared_object{ CONST char *name; void *handle; struct shared_object *next;};/* External functions */EXTERN_FUNCTION (flag st_expr_expand, (char *output, unsigned int length, CONST char *input, CONST char *(*get_variable) (CONST char *variable, void *info), void *info, FILE *errfp) );EXTERN_FUNCTION (const char *get_old_name, (const char *devname, unsigned int namelen, char *buffer, unsigned int major, unsigned int minor) );/* Public data */flag syslog_is_open = FALSE;/* Public functions */int mksymlink (const char *oldpath, const char *newpath);/* Private functions */static void setup_initial_entries ();static void read_config (CONST char *location, flag optional, unsigned long *event_mask);static void read_config_file (CONST char *path, flag optional,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -