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

📄 devfsd.c

📁 devfsd 驱动对linux的补丁支持
💻 C
📖 第 1 页 / 共 5 页
字号:
    unlink (destpath);    switch (source_stat->st_mode & S_IFMT)    {	int fd, val;	struct sockaddr_un un_addr;	char symlink_val[STRING_LENGTH];      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) break;	if (chmod (destpath, new_mode & ~S_IFMT) != 0) break;	if (chown (destpath, source_stat->st_uid, source_stat->st_gid) == 0)	    return (TRUE);	break;      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;	if (chown (destpath, source_stat->st_uid, source_stat->st_gid) == 0)	    return (TRUE);	break;      case S_IFBLK:      case S_IFCHR:      case S_IFIFO:	if (mknod (destpath, new_mode, source_stat->st_rdev) != 0) break;	if (chown (destpath, source_stat->st_uid, source_stat->st_gid) == 0)	    return (TRUE);	break;      case S_IFDIR:	if (mkdir (destpath, new_mode & ~S_IFMT) != 0) break;	if (chown (destpath, source_stat->st_uid, source_stat->st_gid) == 0)	    return (TRUE);	return (TRUE);	/*break;*/    }    return (FALSE);}   /*  End Function copy_inode  */static void free_config ()/*  [SUMMARY] Free the configuration information.    [RETURNS] Nothing.*/{    struct config_entry_struct *c_entry;    struct shared_object *so_entry;    void *next;    for (c_entry = first_config; c_entry != NULL; c_entry = next)    {	unsigned int count;	next = c_entry->next;	regfree (&c_entry->preg);	if (c_entry->action.what == AC_EXECUTE)	{	    for (count = 0; count < MAX_ARGS; ++count)	    {		if (c_entry->u.execute.argv[count] == NULL) break;		free (c_entry->u.execute.argv[count]);	    }	}	else if ( (c_entry->action.what == AC_MFUNCTION) ||		  (c_entry->action.what == AC_CFUNCTION) )	{	    for (count = 0; count < MAX_ARGS; ++count)	    {		if (c_entry->u.function.argv[count] == NULL) break;		free (c_entry->u.function.argv[count]);	    }	}	free (c_entry);    }    first_config = NULL;    last_config = NULL;    for (so_entry = first_so; so_entry != NULL; so_entry = next)    {	next = so_entry->next;	free ( (char *) so_entry->name );	if (so_entry->handle != RTLD_DEFAULT) dlclose (so_entry->handle);	free (so_entry);    }    first_so = NULL;}   /*  End Function free_config  */static void do_debug (int fd)/*  [SUMMARY] Debug the devfs protocol.    <fd> The open control file.    [RETURNS] Nothing.*/{    ssize_t bytes;    struct devfsd_notify_struct info;    fprintf (stderr, "Running in debug mode: no actions will be taken...\n");    /*  Tell devfs what events we care about  */    if (ioctl (fd, DEVFSDIOC_SET_EVENT_MASK, ~0) != 0)    {	SYSLOG (LOG_ERR, "error setting event mask\t%s\n", ERRSTRING);	exit (1);    }    while ( ( bytes = read (fd, (char *) &info, sizeof info) ) >= 0 )    {	unsigned int count;	CONST char *type = NULL;	if (bytes < 1)	{	    fprintf (stderr, "devfs closed file!\n");	    exit (1);	}	if (info.overrun_count > 0)	    SYSLOG (LOG_ERR, "%u events have been lost!\n",info.overrun_count);	for (count = 0; event_types[count].config_name != NULL; ++count)	{	    if (info.type != event_types[count].type) continue;	    type = event_types[count].debug_name;	    break;	}	if (type == NULL)	{	    fprintf (stderr, "Unknown type: %u\n", info.type);	    exit (1);	    /*break;*/	}	fprintf (stderr, "Entry: \"%s\"(len=%d) %s mode: %o uid: %d gid: %d\n",		 info.devname, (int) strlen (info.devname), type,		 (int) info.mode, (int) info.uid, (int) info.gid);    }    fprintf (stderr, "Error reading control file\t%s\n", ERRSTRING);    exit (1);}   /*  End Function do_debug  */static uid_t get_uid (const char *string)/*  [SUMMARY] Convert a string to a UID value.    <string> The string.    [RETURNS] The UID value.*/{    struct passwd *pw_ent;    if ( isdigit (string[0]) || ( (string[0] == '-') && isdigit (string[1]) ) )	return atoi (string);    if ( ( pw_ent = getpwnam (string) ) == NULL )    {	SYSLOG (LOG_ERR, "unknown user: \"%s\", defaulting to UID=0\n",		string);	return (0);    }    return (pw_ent->pw_uid);}   /*  End Function get_uid  */static gid_t get_gid (const char *string)/*  [SUMMARY] Convert a string to a GID value.    <string> The string.    [RETURNS] The GID value.*/{    struct group *grp_ent;    if ( isdigit (string[0]) || ( (string[0] == '-') && isdigit (string[1]) ) )	return atoi (string);    if ( ( grp_ent = getgrnam (string) ) == NULL )    {	SYSLOG (LOG_ERR, "unknown group: \"%s\", defaulting to GID=0\n",		string);	return (0);    }    return (grp_ent->gr_gid);}   /*  End Function get_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;    if ( isdigit (string[0]) ) return strtoul (string, NULL, 8);    if (strlen (string) != 9)    {	SYSLOG (LOG_ERR, "bad symbolic mode: \"%s\"\n", string);	SYSLOG (LOG_ERR, "exiting\n");	exit (1);    }    mode = 0;    if (string[0] == 'r') mode |= S_IRUSR;    if (string[1] == 'w') mode |= S_IWUSR;    if (string[2] == 'x') mode |= S_IXUSR;    if (string[3] == 'r') mode |= S_IRGRP;    if (string[4] == 'w') mode |= S_IWGRP;    if (string[5] == 'x') mode |= S_IXGRP;    if (string[6] == 'r') mode |= S_IROTH;    if (string[7] == 'w') mode |= S_IWOTH;    if (string[8] == 'x') mode |= S_IXOTH;    if (trace_level > 3) fprintf (stderr, "\tMode \"%s\" gives %05o\n",				  string, mode);    return (mode);}   /*  End Function get_mode  */static void signal_handler (int sig){    caught_signal = TRUE;    if (sig == SIGHUP)    {	caught_sighup = TRUE;	SYSLOG (LOG_INFO, "Caught SIGHUP\n");    }    else if (sig == SIGUSR1)	SYSLOG (LOG_INFO, "Caught SIGUSR1\n");}   /*  End Function signal_handler  */static CONST char *get_variable (CONST char *variable, void *info){    struct get_variable_info *gv_info = info;    static flag first_time = TRUE;    static char hostname[STRING_LENGTH], sbuf[STRING_LENGTH];    if (first_time)    {	first_time = FALSE;	if (gethostname (hostname, STRING_LENGTH - 1) != 0)	{	    SYSLOG (LOG_ERR, "Error getting hostname\t%s\n", ERRSTRING);	    exit (RV_SYS_ERROR);	}	hostname[STRING_LENGTH - 1] = '\0';    }    if (strcmp (variable, "hostname") == 0) return (hostname);    if (strcmp (variable, "mntpnt") == 0) return (mount_point);    if (gv_info == NULL) return (NULL);    if (strcmp (variable, "devpath") == 0) return (gv_info->devpath);    if (strcmp (variable, "devname") == 0) return (gv_info->devname);    if (strcmp (variable, "mode") == 0)    {	sprintf (sbuf, "%o", gv_info->info->mode);	return (sbuf);    }    if (strcmp (variable, "uid") == 0)    {	sprintf (sbuf, "%u", gv_info->info->uid);	return (sbuf);    }    if (strcmp (variable, "gid") == 0)    {	sprintf (sbuf, "%u", gv_info->info->gid);	return (sbuf);    }    return (NULL);}   /*  End Function get_variable  */static void do_open_syslog ()/*  [SUMMARY] Open syslog(3) connection if appropriate.    [RETURNS] Nothing.*/{    if (syslog_is_open || no_syslog) return;    if (access ("/dev/log", F_OK) != 0) return;    openlog ("devfsd", LOG_PID, LOG_DAEMON);    close (0);    close (1);    close (2);    syslog_is_open = TRUE;}   /*  End Function do_open_syslog  */static void do_scan_and_service (CONST char *dirname)/*  [SUMMARY] Scan a directory tree and generate register events on leaf nodes.    <dp> The directory pointer. This is closed upon completion.    <dirname> The name of the directory.    [RETURNS] Nothing.*/{    struct stat statbuf;    DIR *dp;    struct dirent *de;    char path[STRING_LENGTH];    if ( ( dp = opendir (dirname) ) == NULL )    {	SYSLOG (LOG_ERR, "Error opening directory \"%s\"\t%s\n",		dirname, ERRSTRING);	return;    }    while ( (de = readdir (dp) ) != NULL )    {	struct devfsd_notify_struct info;	if ( (strcmp (de->d_name, ".") == 0) ||	     (strcmp (de->d_name, "..") == 0) ) continue;	snprintf (path, sizeof (path), "%s/%s", dirname, de->d_name);	if (lstat (path, &statbuf) != 0)	{	    SYSLOG (LOG_ERR, "Error lstat(2)ing file \"%s\"\t%s\n",		    path, ERRSTRING);	    continue;	}	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) ) do_scan_and_service (path);    }    closedir (dp);}   /*  End Function do_scan_and_service  */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.*/{    static char function_name[] = "mksymlink";    if ( !make_dir_tree (newpath) ) return (-1);    if (symlink (oldpath, newpath) != 0)    {	if (errno == EEXIST)	{	    if (trace_level > 1)		fprintf (stderr, "symlink: \"%s\" already exists\n", newpath);	}	else	{	    SYSLOG (LOG_ERR, "%s: error creating symlink: \"%s\"\t%s\n",		    function_name, newpath, ERRSTRING);	    return (-1);	}    }    return (0);}   /*  End Function mksymlink  */static flag make_dir_tree (const char *path)/*  [SUMMARY] Creating intervening directories for a path as required.    <path> The full pathname (including he leaf node).    [RETURNS] TRUE on success, else FALSE.*/{    char ch;    char *ptr1, *ptr2;    char path_copy[STRING_LENGTH];    /*static char function_name[] = "make_dir_tree";*/    snprintf (path_copy, sizeof (path_copy), "%s", path);    ptr1 = path_copy;    while (TRUE)    {	if ( ( ptr2 = strchr (ptr1 + 1, '/') ) == NULL ) break;	ch = *ptr2;	*ptr2 = '\0';	if (access (path_copy, F_OK) == 0)	{	    *ptr2 = ch;	    ptr1 = ptr2;	    continue;	}	if (mkdir (path_copy,		   S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0)	{	    SYSLOG (LOG_ERR, "Error making directory \"%s\"\t%s\n",		    path_copy, ERRSTRING);	    *ptr2 = ch;	    return (FALSE);	}	*ptr2 = ch;	ptr1 = ptr2;    }    return (TRUE);}   /*  End Function make_dir_tree  */static struct shared_object *get_shared_object (CONST char *name)/*  [SUMMARY] Load a shared object if possible.    <name> The shared object.    [RETURNS] A pointer to the object on success, else NULL.*/{    struct shared_object *so;    for (so = first_so; so != NULL; so = so->next)	if (strcmp (so->name, name) == 0) return (so);    if ( ( so = malloc (sizeof *so) ) == NULL ) return (NULL);    if ( ( so->name = strdup (name) ) == NULL )    {	free (so);	return (NULL);    }    if (strcmp (name, "GLOBAL") == 0) so->handle = RTLD_DEFAULT;    else    {	char pathname[STRING_LENGTH + 12];	if (name[0] != '/')	{   /*  Default directory is /lib/devfsd  */	    snprintf (pathname, sizeof pathname, "/lib/devfsd/%s"

⌨️ 快捷键说明

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