summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2008-10-16 22:41:52 +0200
committerKay Sievers <kay.sievers@vrfy.org>2008-10-16 22:41:52 +0200
commitbb144ed14d34716435f18ea6a0ea0ee899f809e9 (patch)
tree63a716386020ccf29bab480af4486f902420be24
parentc28c4486af3fd970aef599be65e9c2d424765329 (diff)
update IMPORT= file/stdout property parsing
-rw-r--r--udev/udev-rules.c216
1 files changed, 101 insertions, 115 deletions
diff --git a/udev/udev-rules.c b/udev/udev-rules.c
index 0bad2171fa..6f53b6a88b 100644
--- a/udev/udev-rules.c
+++ b/udev/udev-rules.c
@@ -76,46 +76,6 @@ static int get_format_len(struct udev *udev, char **str)
return -1;
}
-static int get_key(char **line, char **key, char **value)
-{
- char *linepos;
- char *temp;
-
- linepos = *line;
- if (linepos == NULL)
- return -1;
-
- /* skip whitespace */
- while (isspace(linepos[0]))
- linepos++;
-
- /* get the key */
- temp = strchr(linepos, '=');
- if (temp == NULL || temp == linepos)
- return -1;
- temp[0] = '\0';
- *key = linepos;
- linepos = &temp[1];
-
- /* get a quoted value */
- if (linepos[0] == '"' || linepos[0] == '\'') {
- temp = strchr(&linepos[1], linepos[0]);
- if (temp != NULL) {
- temp[0] = '\0';
- *value = &linepos[1];
- goto out;
- }
- }
-
- /* get the value*/
- temp = strchr(linepos, '\n');
- if (temp != NULL)
- temp[0] = '\0';
- *value = linepos;
-out:
- return 0;
-}
-
static int run_program(struct udev_device *dev, const char *command,
char *result, size_t ressize, size_t *reslen)
{
@@ -333,106 +293,132 @@ static int run_program(struct udev_device *dev, const char *command,
return err;
}
-static int import_keys_into_env(struct udev_event *event, const char *buf, size_t bufsize)
+static int import_property_from_string(struct udev_device *dev, char *line)
{
- struct udev_device *dev = event->dev;
- char line[UTIL_LINE_SIZE];
- const char *bufline;
- char *linepos;
- char *variable;
- char *value;
- size_t cur;
- size_t count;
- int lineno;
-
- /* loop through the whole buffer */
- lineno = 0;
- cur = 0;
- while (cur < bufsize) {
- count = buf_get_line(buf, bufsize, cur);
- bufline = &buf[cur];
- cur += count+1;
- lineno++;
-
- /* eat the whitespace */
- while ((count > 0) && isspace(bufline[0])) {
- bufline++;
- count--;
- }
- if (count == 0)
- continue;
+ struct udev *udev = udev_device_get_udev(dev);
+ char *key;
+ char *val;
+ size_t len;
- /* see if this is a comment */
- if (bufline[0] == '#')
- continue;
+ /* find key */
+ key = line;
+ while (isspace(key[0]))
+ key++;
- if (count >= sizeof(line)) {
- err(event->udev, "line too long, skipped\n");
- continue;
- }
+ /* comment or empty line */
+ if (key[0] == '#' || key[0] == '\0')
+ return -1;
- memcpy(line, bufline, count);
- line[count] = '\0';
-
- linepos = line;
- if (get_key(&linepos, &variable, &value) == 0) {
- char syspath[UTIL_PATH_SIZE];
-
- dbg(event->udev, "import '%s=%s'\n", variable, value);
- /* handle device, renamed by external tool, returning new path */
- if (strcmp(variable, "DEVPATH") == 0) {
- info(event->udev, "updating devpath from '%s' to '%s'\n",
- udev_device_get_devpath(dev), value);
- util_strlcpy(syspath, udev_get_sys_path(event->udev), sizeof(syspath));
- util_strlcat(syspath, value, sizeof(syspath));
- udev_device_set_syspath(dev, syspath);
- } else {
- struct udev_list_entry *entry;
+ /* split key/value */
+ val = strchr(key, '=');
+ if (val == NULL)
+ return -1;
+ val[0] = '\0';
+ val++;
- entry = udev_device_add_property(dev, variable, value);
- /* store in db */
- udev_list_entry_set_flag(entry, 1);
- }
+ /* find value */
+ while (isspace(val[0]))
+ val++;
+
+ /* terminate key */
+ len = strlen(key);
+ if (len == 0)
+ return -1;
+ while (isspace(key[len-1]))
+ len--;
+ key[len] = '\0';
+
+ /* terminate value */
+ len = strlen(val);
+ if (len == 0)
+ return -1;
+ while (isspace(val[len-1]))
+ len--;
+ val[len] = '\0';
+
+ if (len == 0)
+ return -1;
+
+ /* unquote */
+ if (val[0] == '"' || val[0] == '\'') {
+ if (val[len-1] != val[0]) {
+ info(udev, "inconsistent quoting: '%s', skip\n", line);
+ return -1;
}
+ val[len-1] = '\0';
+ val++;
+ }
+
+ info(udev, "adding '%s'='%s'\n", key, val);
+
+ /* handle device, renamed by external tool, returning new path */
+ if (strcmp(key, "DEVPATH") == 0) {
+ char syspath[UTIL_PATH_SIZE];
+
+ info(udev, "updating devpath from '%s' to '%s'\n",
+ udev_device_get_devpath(dev), val);
+ util_strlcpy(syspath, udev_get_sys_path(udev), sizeof(syspath));
+ util_strlcat(syspath, val, sizeof(syspath));
+ udev_device_set_syspath(dev, syspath);
+ } else {
+ struct udev_list_entry *entry;
+
+ entry = udev_device_add_property(dev, key, val);
+ /* store in db */
+ udev_list_entry_set_flag(entry, 1);
}
return 0;
}
-static int import_file_into_env(struct udev_event *event, const char *filename)
+static int import_file_into_env(struct udev_device *dev, const char *filename)
{
- char *buf;
- size_t bufsize;
+ FILE *f;
+ char line[UTIL_LINE_SIZE];
- if (file_map(filename, &buf, &bufsize) != 0) {
- err(event->udev, "can't open '%s': %m\n", filename);
+ f = fopen(filename, "r");
+ if (f == NULL)
return -1;
- }
- import_keys_into_env(event, buf, bufsize);
- file_unmap(buf, bufsize);
-
+ while (fgets(line, sizeof(line), f))
+ import_property_from_string(dev, line);
+ fclose(f);
return 0;
}
-static int import_program_into_env(struct udev_event *event, const char *program)
+static int import_program_into_env(struct udev_device *dev, const char *program)
{
char result[2048];
size_t reslen;
+ char *line;
- if (run_program(event->dev, program, result, sizeof(result), &reslen) != 0)
+ if (run_program(dev, program, result, sizeof(result), &reslen) != 0)
return -1;
- return import_keys_into_env(event, result, reslen);
+
+ line = result;
+ while (line != NULL) {
+ char *pos;
+
+ pos = strchr(line, '\n');
+ if (pos != NULL) {
+ pos[0] = '\0';
+ pos = &pos[1];
+ }
+ import_property_from_string(dev, line);
+ line = pos;
+ }
+ return 0;
}
-static int import_parent_into_env(struct udev_event *event, const char *filter)
+static int import_parent_into_env(struct udev_device *dev, const char *filter)
{
+ struct udev *udev = udev_device_get_udev(dev);
struct udev_device *dev_parent;
struct udev_list_entry *list_entry;
- dev_parent = udev_device_get_parent(event->dev);
+ dev_parent = udev_device_get_parent(dev);
if (dev_parent == NULL)
return -1;
- dbg(event->udev, "found parent '%s', get the node name\n", udev_device_get_syspath(dev_parent));
+ dbg(udev, "found parent '%s', get the node name\n", udev_device_get_syspath(dev_parent));
udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(dev_parent)) {
const char *key = udev_list_entry_get_name(list_entry);
const char *val = udev_list_entry_get_value(list_entry);
@@ -440,8 +426,8 @@ static int import_parent_into_env(struct udev_event *event, const char *filter)
if (fnmatch(filter, key, 0) == 0) {
struct udev_list_entry *entry;
- dbg(event->udev, "import key '%s=%s'\n", key, val);
- entry = udev_device_add_property(event->dev, key, val);
+ dbg(udev, "import key '%s=%s'\n", key, val);
+ entry = udev_device_add_property(dev, key, val);
/* store in db */
udev_list_entry_set_flag(entry, 1);
}
@@ -1270,13 +1256,13 @@ try_parent:
udev_rules_apply_format(event, import, sizeof(import));
dbg(event->udev, "check for IMPORT import='%s'\n", import);
if (rule->import_type == IMPORT_PROGRAM) {
- rc = import_program_into_env(event, import);
+ rc = import_program_into_env(event->dev, import);
} else if (rule->import_type == IMPORT_FILE) {
dbg(event->udev, "import file import='%s'\n", import);
- rc = import_file_into_env(event, import);
+ rc = import_file_into_env(event->dev, import);
} else if (rule->import_type == IMPORT_PARENT) {
dbg(event->udev, "import parent import='%s'\n", import);
- rc = import_parent_into_env(event, import);
+ rc = import_parent_into_env(event->dev, import);
}
if (rc != 0) {
dbg(event->udev, "IMPORT failed\n");