2 * udev_utils.c - generic stuff used by udev
4 * Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation version 2 of the License.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 #include <sys/utsname.h>
33 #include "udev_libc_wrapper.h"
36 #include "udev_utils.h"
39 /* compare string with pattern (supports * ? [0-9] [!A-Z]) */
40 int strcmp_pattern(const char *p, const char *s)
45 return (p[0] != '\0');
56 while ((p[0] != '\0') && (p[0] != ']')) {
59 if ((s[0] >= p[0]) && (s[0] <= p[2]))
63 match = (p[0] == s[0]);
67 while ((p[0] != '\0') && (p[0] != ']'))
70 return strcmp_pattern(p+1, s+1);
76 if (strcmp_pattern(p, s+1))
77 return strcmp_pattern(p+1, s);
85 if ((p[0] == s[0]) || (p[0] == '?'))
86 return strcmp_pattern(p+1, s+1);
92 int string_is_true(const char *str)
94 if (strcasecmp(str, "true") == 0)
96 if (strcasecmp(str, "yes") == 0)
98 if (strcasecmp(str, "1") == 0)
103 int log_priority(const char *priority)
108 prio = strtol(priority, &endptr, 10);
109 if (endptr[0] == '\0')
111 if (strncasecmp(priority, "err", 3) == 0)
113 if (strcasecmp(priority, "info") == 0)
115 if (strcasecmp(priority, "debug") == 0)
117 if (string_is_true(priority))
123 int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel)
125 static unsigned int kversion = 0;
126 static unsigned int kpatchlevel;
127 static unsigned int ksublevel;
131 if (uname(&uts) != 0)
134 if (sscanf (uts.release, "%u.%u.%u", &kversion, &kpatchlevel, &ksublevel) != 3) {
140 if (kversion >= version && kpatchlevel >= patchlevel && ksublevel >= sublevel)
146 void replace_untrusted_chars(char *string)
150 for (len = 0; string[len] != '\0'; len++) {
151 if (strchr(";,~\\()\'", string[len])) {
152 info("replace '%c' in '%s'", string[len], string);
158 void remove_trailing_char(char *path, char c)
163 while (len > 0 && path[len-1] == c)
167 int name_list_add(struct list_head *name_list, const char *name, int sort)
169 struct name_entry *loop_name;
170 struct name_entry *new_name;
172 list_for_each_entry(loop_name, name_list, node) {
174 if (strcmp(loop_name->name, name) == 0) {
175 dbg("'%s' is already in the list", name);
181 list_for_each_entry(loop_name, name_list, node) {
182 if (sort && strcmp(loop_name->name, name) > 0)
186 new_name = malloc(sizeof(struct name_entry));
187 if (new_name == NULL) {
192 strlcpy(new_name->name, name, sizeof(new_name->name));
193 dbg("adding '%s'", new_name->name);
194 list_add_tail(&new_name->node, &loop_name->node);
199 int name_list_key_add(struct list_head *name_list, const char *key, const char *value)
201 struct name_entry *loop_name;
202 struct name_entry *new_name;
204 list_for_each_entry(loop_name, name_list, node) {
205 if (strncmp(loop_name->name, key, strlen(key)) == 0) {
206 dbg("key already present '%s', replace it", loop_name->name);
207 snprintf(loop_name->name, sizeof(loop_name->name), "%s=%s", key, value);
208 loop_name->name[sizeof(loop_name->name)-1] = '\0';
213 new_name = malloc(sizeof(struct name_entry));
214 if (new_name == NULL) {
219 snprintf(new_name->name, sizeof(new_name->name), "%s=%s", key, value);
220 new_name->name[sizeof(new_name->name)-1] = '\0';
221 dbg("adding '%s'", new_name->name);
222 list_add_tail(&new_name->node, &loop_name->node);
227 /* calls function for every file found in specified directory */
228 int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix)
233 char filename[PATH_SIZE];
235 dbg("open directory '%s'", dirname);
236 dir = opendir(dirname);
238 dbg("unable to open '%s'", dirname);
244 if (ent == NULL || ent->d_name[0] == '\0')
247 if ((ent->d_name[0] == '.') || (ent->d_name[0] == COMMENT_CHARACTER))
250 /* look for file matching with specified suffix */
251 ext = strrchr(ent->d_name, '.');
255 if (strcmp(ext, suffix) != 0)
258 dbg("put file '%s/%s' in list", dirname, ent->d_name);
260 snprintf(filename, sizeof(filename), "%s/%s", dirname, ent->d_name);
261 filename[sizeof(filename)-1] = '\0';
262 name_list_add(name_list, filename, 1);