⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devfsd.c

📁 devfsd 驱动对linux的补丁支持
💻 C
📖 第 1 页 / 共 5 页
字号:
	free_config ();	*event_mask = 0;	return;    }    if (num_args < 2)    {	SYSLOG (LOG_ERR, "bad config line: \"%s\"\n", line);	SYSLOG (LOG_ERR, "exiting\n");	exit (1);    }    if ( (strcasecmp (when, "INCLUDE") == 0) ||	 (strcasecmp (when, "OPTIONAL_INCLUDE") == 0) )    {	st_expr_expand (name, STRING_LENGTH, name, get_variable, NULL,			NULL);	read_config (name, (toupper (when[0]) == 'I') ? FALSE : TRUE,		     event_mask);	return;    }    if (strcasecmp (when, "RESTORE") == 0)    {	do_restore ( name, strlen (name) );	return;    }    if (num_args < 3)    {	SYSLOG (LOG_ERR, "bad config line: \"%s\"\n", line);	SYSLOG (LOG_ERR, "exiting\n");	exit (1);    }    if ( ( new = malloc (sizeof *new) ) == NULL )    {	SYSLOG (LOG_ERR, "error allocating\n");	SYSLOG (LOG_ERR, "exiting\n");	exit (1);    }    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)    {	SYSLOG (LOG_ERR, "bad WHEN in config line: \"%s\"\n", line);	SYSLOG (LOG_ERR, "exiting\n");	exit (1);    }    if (strcasecmp (what, "PERMISSIONS") == 0)    {	char *ptr;	new->action.what = AC_PERMISSIONS;	/*  Get user and group  */	if ( ( ptr = strchr (p[0], '.') ) == NULL )	{	    SYSLOG (LOG_ERR, "missing '.' character in: \"%s\"\n", p[0]);	    SYSLOG (LOG_ERR, "exiting\n");	    exit (1);	}	*ptr++ = '\0';	new->u.permissions.uid = get_uid (p[0]);	new->u.permissions.gid = get_gid (ptr);	/*  Get mode  */	new->u.permissions.mode = get_mode (p[1]);    }    else if (strcasecmp (what, "MODLOAD") == 0) new->action.what = AC_MODLOAD;    else if (strcasecmp (what, "EXECUTE") == 0)    {	new->action.what = AC_EXECUTE;	num_args -= 3;	if (strstr (p[0], "modprobe") != NULL)	{   /*  Bitch and moan  */	    SYSLOG (LOG_NOTICE,		    "Use MODLOAD action instead of EXECUTE modprobe!\n");	    exit (1);	}	for (count = 0; count < num_args; ++count)	{	    if ( ( new->u.execute.argv[count] = strdup (p[count]) ) == NULL )	    {		SYSLOG (LOG_ERR, "error allocating\n");		SYSLOG (LOG_ERR, "exiting\n");		exit (1);	    }	}	new->u.execute.argv[num_args] = NULL;    }    else if ( (strcasecmp (what, "MFUNCTION") == 0) ||	      (strcasecmp (what, "CFUNCTION") == 0) )    {	new->action.what = (strcasecmp (what, "MFUNCTION") == 0) ?	    AC_MFUNCTION : AC_CFUNCTION;	num_args -= 3;	if (num_args < 2)	{	    SYSLOG (LOG_ERR, "missing path and function in \"%s\"\n",line);	    exit (1);	}	if ( ( new->u.function.so = get_shared_object (p[0]) ) == NULL )	{	    SYSLOG (LOG_ERR, "error loading: \"%s\"\t%s\n", p[0], dlerror () );	    exit (1);	}	new->u.function.func.m =	    dlsym_nofail (p[0], new->u.function.so->handle, p[1]);	--num_args;	for (count = 0; count < num_args; ++count)	{	    if ( ( new->u.function.argv[count] = strdup (p[count + 1]) )		 == NULL )	    {		SYSLOG (LOG_ERR, "error allocating\n");		SYSLOG (LOG_ERR, "exiting\n");		exit (1);	    }	}	new->u.function.argv[num_args] = NULL;    }    else if (strcasecmp (what, "COPY") == 0)    {	new->action.what = AC_COPY;	num_args -= 3;	if (num_args != 2)	{	    SYSLOG (LOG_ERR, "missing path and function in \"%s\"\n", line);	    exit (1);	}	if ( ( new->u.copy.source = strdup (p[0]) ) == NULL )	{	    SYSLOG (LOG_ERR, "error allocating source string\n");	    SYSLOG (LOG_ERR, "exiting\n");	    exit (1);	}	if ( ( new->u.copy.destination = strdup (p[1]) ) == NULL )	{	    SYSLOG (LOG_ERR, "error allocating destination string\n");	    SYSLOG (LOG_ERR, "exiting\n");	    exit (1);	}    }    else if (strcasecmp (what, "IGNORE") == 0) new->action.what = AC_IGNORE;    else if (strcasecmp (what, "MKOLDCOMPAT") == 0)	new->action.what = AC_MKOLDCOMPAT;    else if (strcasecmp (what, "MKNEWCOMPAT") == 0)	new->action.what = AC_MKNEWCOMPAT;    else if (strcasecmp (what, "RMOLDCOMPAT") == 0)	new->action.what = AC_RMOLDCOMPAT;    else if (strcasecmp (what, "RMNEWCOMPAT") == 0)	new->action.what = AC_RMNEWCOMPAT;    else    {	SYSLOG (LOG_ERR, "bad WHAT in config line: \"%s\"\n", line);	SYSLOG (LOG_ERR, "exiting\n");	exit (1);    }    if ( ( err = regcomp (&new->preg, name, REG_EXTENDED) ) != 0 )    {	regerror (err, &new->preg, tmp, STRING_LENGTH);	SYSLOG (LOG_ERR, "error compiling regexp: \"%s\"\t%s\n", name,tmp);	SYSLOG (LOG_ERR, "exiting\n");	exit (1);    }    *event_mask |= 1 << new->action.when;    new->next = NULL;    if (first_config == NULL) first_config = new;    else last_config->next = new;    last_config = new;}   /*  End Function process_config_line   */static void *dlsym_nofail (const char *file, void *handle, char *symbol){    void *result = dlsym (handle, symbol);    if (result == NULL)    {	SYSLOG (LOG_ERR, "symbol: \"%s\" not found in %s\n", symbol, file);	exit (1);    }    return (result);}   /*  End Function dlsym_nofail  */static void load_libnsl (void){#ifdef LIBNSL  /*  It comes from a shared object  */    void *libnsl_handle;    libnsl_handle = dlopen (LIBNSL, RTLD_LAZY);    if (libnsl_handle == NULL)    {        SYSLOG ( LOG_ERR, "read map: unable to open %s: %s",		 LIBNSL, dlerror() );	exit (1);    }    my_yp_all = dlsym_nofail (LIBNSL, libnsl_handle, "yp_all");    my_yp_get_default_domain =        dlsym_nofail (LIBNSL, libnsl_handle, "yp_get_default_domain");#else  /*  It's built-in the C library  */    my_yp_all = yp_all;    my_yp_get_default_domain = yp_get_default_domain;#endif}   /*  End Function load_libnsl  */static int process_yp_line (int instatus, char *inkey, int inkeylen,			    char *inval, int invallen, char *indata){    if (instatus != YP_TRUE) return (instatus);    if (invallen > 0) process_config_line (inval, (unsigned long *) indata);    return (0);}   /*  End Function process_yp_line  */static flag 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;    /*  Tell devfs what events we care about  */    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;    }    if (ioctl (fd, DEVFSDIOC_SET_EVENT_MASK, tmp_event_mask) != 0)    {	SYSLOG (LOG_ERR, "error setting event mask\t%s\n", ERRSTRING);	exit (1);    }    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;	/*  Special trap for "/dev/log" creation  */	if (!syslog_is_open && !no_syslog &&	    (info.type == DEVFSD_NOTIFY_CREATE) &&	    (strcmp (info.devname, "log") == 0) )	{	    /*  Open syslog, now that "/dev/log" exists  */	    do_open_syslog ();	    if (ioctl (fd, DEVFSDIOC_SET_EVENT_MASK, event_mask) != 0)	    {		SYSLOG (LOG_ERR, "error setting event mask\t%s\n", ERRSTRING);		exit (1);	    }	}	service_name (&info);    }    if (caught_signal)    {	flag c_sighup = caught_sighup;	caught_signal = FALSE;	caught_sighup = FALSE;	return (c_sighup);    }    SYSLOG (LOG_ERR, "Error reading control file\t%s\n", ERRSTRING);    exit (1);}   /*  End Function do_servicing  */static void service_name (const struct devfsd_notify_struct *info)/*  [SUMMARY] Service a single devfs change.    <info> The devfs change.    [RETURNS] Nothing.*/{    unsigned int n;    regmatch_t mbuf[MAX_SUBEXPR];    struct config_entry_struct *entry;    if (info->overrun_count > 0)	SYSLOG (LOG_ERR, "%u events have been lost!\n", info->overrun_count);    if (trace_level > 2) fprintf (stderr, "Looking for \"%s\" (%d)\n",				  info->devname, info->type);    /*  Discard lookups on "/dev/log" and "/dev/initctl"  */    if (info->type == DEVFSD_NOTIFY_LOOKUP)    {	if ( (strcmp (info->devname, "log") == 0) ||	     (strcmp (info->devname, "initctl") == 0) ) return;    }    for (entry = first_config; entry != NULL; entry = entry->next)    {	if (trace_level > 3) fprintf (stderr, "\t\tProcess \"%s\" (%d)\n",				      info->devname, entry->action.when);	/*  First check if action matches the type, then check if name matches	 */	if (info->type != entry->action.when) continue;	if (regexec (&entry->preg, info->devname, MAX_SUBEXPR, mbuf, 0) != 0)	    continue;	for (n = 0; (n < MAX_SUBEXPR) && (mbuf[n].rm_so != -1); ++n);	switch (entry->action.what)	{	  case AC_PERMISSIONS:	    action_permissions (info, entry);	    break;	  case AC_MODLOAD:	    action_modload (info, entry);	    break;	  case AC_EXECUTE:	    action_execute (info, entry, mbuf, n);	    break;	  case AC_MFUNCTION:	  case AC_CFUNCTION:	    action_call_function (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:	    SYSLOG (LOG_ERR, "Unknown action type: %u\n", entry->action.what);	    exit (1);	    /*break;*/	}    }}   /*  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.*/{    mode_t new_mode;    struct stat statbuf;    if (stat (info->devname, &statbuf) != 0)    {	SYSLOG (LOG_ERR, "error stat(2)ing: \"%s\"\t%s\n",		info->devname, ERRSTRING);	return;    }    new_mode = (statbuf.st_mode & S_IFMT) |	(entry->u.permissions.mode & ~S_IFMT);    if (trace_level > 2)	fprintf (stderr,		 "\tupdate permissions for \"%s\" from %05o to %05o, user.group from %d.%d to %d.%d\n",		 info->devname, info->mode, new_mode, info->uid, info->gid,		 entry->u.permissions.uid, entry->u.permissions.gid);    if (new_mode != statbuf.st_mode)    {	if (chmod (info->devname, new_mode) != 0)	{	    SYSLOG (LOG_ERR, "error changing mode for: \"%s\"\t%s\n",		    info->devname, ERRSTRING);	    return;	}	if (trace_level > 2) fprintf (stderr,"Set permission %05o on \"%s\"\n",				      new_mode, info->devname);    }    if ( (entry->u.permissions.uid != statbuf.st_uid) ||	 (entry->u.permissions.gid != statbuf.st_gid) )    {	if (chown (info->devname, entry->u.permissions.uid,		   entry->u.permissions.gid) != 0)	{	    SYSLOG (LOG_ERR, "error changing owner for: \"%s\"\t%s\n",		    info->devname, ERRSTRING);	    return;	}	if (trace_level > 2)	    fprintf (stderr, "Set user.group %d.%d on \"%s\"\n",		     entry->u.permissions.uid, entry->u.permissions.gid,		     info->devname);    }}   /*  End Function action_permissions  */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];    char *env[4] = {"HOME=/", "TERM=linux",  /*  Safe mode environment  */		    "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL};    static int (*modprobe) (int argc, char **argv) = NULL;    static flag first_time = TRUE;    if (first_time)    {	void *lib;	first_time = FALSE;	if ( ( lib = dlopen ("/lib/modutils.so", RTLD_NOW) ) != NULL )	{	    if ( ( modprobe = dlsym (lib, "modprobe") ) == NULL )		SYSLOG(LOG_ERR, "/lib/modutils.so doesn't contain modprobe()");	}	else if (trace_level > 1)	    fprintf (stderr, "/lib/modutils.so load failure: %s\n",dlerror() );    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -