summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--udev.75
-rw-r--r--udev.xml8
-rw-r--r--udev_rules.c30
-rw-r--r--udev_rules.h7
-rw-r--r--udev_rules_parse.c20
-rw-r--r--udevtest.c1
6 files changed, 53 insertions, 18 deletions
diff --git a/udev.7 b/udev.7
index a253581581..d3ed4b71d6 100644
--- a/udev.7
+++ b/udev.7
@@ -290,6 +290,11 @@ Specify the priority of the created symlinks. Devices with higher priorities ove
.RS 4
Create the device nodes for all available partitions of a block device. This may be useful for removable media devices where media changes are not detected.
.RE
+.PP
+\fBstring_escape=\fR\fB\fInone|replace\fR\fR
+.RS 4
+Usually control and other possibly unsafe characters are replaced in strings used for device naming. The mode of replacement can be specified with this option.
+.RE
.RE
.RE
.PP
diff --git a/udev.xml b/udev.xml
index a3658bd548..520c718c7a 100644
--- a/udev.xml
+++ b/udev.xml
@@ -435,6 +435,14 @@
detected.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>string_escape=<replaceable>none|replace</replaceable></option></term>
+ <listitem>
+ <para>Usually control and other possibly unsafe characters are replaced
+ in strings used for device naming. The mode of replacement can be specified
+ with this option.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</listitem>
</varlistentry>
diff --git a/udev_rules.c b/udev_rules.c
index 6ef320dfc7..cb74da56e3 100644
--- a/udev_rules.c
+++ b/udev_rules.c
@@ -837,7 +837,8 @@ try_parent:
strlcpy(program, key_val(rule, &rule->program), sizeof(program));
udev_rules_apply_format(udev, program, sizeof(program));
- if (run_program(program, udev->dev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_INFO)) != 0) {
+ if (run_program(program, udev->dev->subsystem, result, sizeof(result),
+ NULL, (udev_log_priority >= LOG_INFO)) != 0) {
dbg("PROGRAM is false");
udev->program_result[0] = '\0';
if (rule->program.operation != KEY_OP_NOMATCH)
@@ -847,9 +848,12 @@ try_parent:
dbg("PROGRAM matches");
remove_trailing_chars(result, '\n');
- count = replace_chars(result, ALLOWED_CHARS_INPUT);
- if (count)
- info("%i character(s) replaced" , count);
+ if (rule->string_escape == ESCAPE_UNSET ||
+ rule->string_escape == ESCAPE_REPLACE) {
+ count = replace_chars(result, ALLOWED_CHARS_INPUT);
+ if (count > 0)
+ info("%i character(s) replaced" , count);
+ }
dbg("result is '%s'", result);
strlcpy(udev->program_result, result, sizeof(udev->program_result));
dbg("PROGRAM returned successful");
@@ -1047,9 +1051,12 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
/* allow multiple symlinks separated by spaces */
strlcpy(temp, key_val(rule, &rule->symlink), sizeof(temp));
udev_rules_apply_format(udev, temp, sizeof(temp));
- count = replace_chars(temp, ALLOWED_CHARS_FILE " ");
- if (count)
- info("%i character(s) replaced" , count);
+ if (rule->string_escape == ESCAPE_UNSET ||
+ rule->string_escape == ESCAPE_REPLACE) {
+ count = replace_chars(temp, ALLOWED_CHARS_FILE " ");
+ if (count > 0)
+ info("%i character(s) replaced" , count);
+ }
dbg("rule applied, added symlink(s) '%s'", temp);
pos = temp;
while (isspace(pos[0]))
@@ -1079,9 +1086,12 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
name_set = 1;
strlcpy(udev->name, key_val(rule, &rule->name), sizeof(udev->name));
udev_rules_apply_format(udev, udev->name, sizeof(udev->name));
- count = replace_chars(udev->name, ALLOWED_CHARS_FILE);
- if (count)
- info("%i character(s) replaced", count);
+ if (rule->string_escape == ESCAPE_UNSET ||
+ rule->string_escape == ESCAPE_REPLACE) {
+ count = replace_chars(udev->name, ALLOWED_CHARS_FILE);
+ if (count > 0)
+ info("%i character(s) replaced", count);
+ }
info("rule applied, '%s' becomes '%s'", udev->dev->kernel, udev->name);
if (strcmp(udev->dev->subsystem, "net") != 0)
diff --git a/udev_rules.h b/udev_rules.h
index 0e1ff76b42..682bedac01 100644
--- a/udev_rules.h
+++ b/udev_rules.h
@@ -57,6 +57,12 @@ enum import_type {
IMPORT_PARENT,
};
+enum escape_type {
+ ESCAPE_UNSET,
+ ESCAPE_NONE,
+ ESCAPE_REPLACE,
+};
+
struct udev_rule {
struct key action;
struct key devpath;
@@ -88,6 +94,7 @@ struct udev_rule {
struct key group;
mode_t mode;
enum key_operation mode_operation;
+ enum escape_type string_escape;
unsigned int link_priority;
unsigned int partitions;
diff --git a/udev_rules_parse.c b/udev_rules_parse.c
index 4420616903..9a12d53816 100644
--- a/udev_rules_parse.c
+++ b/udev_rules_parse.c
@@ -232,6 +232,7 @@ static int add_rule_key_pair(struct udev_rule *rule, struct key_pairs *pairs,
static int add_to_rules(struct udev_rules *rules, char *line, const char *filename, unsigned int lineno)
{
+ char buf[sizeof(struct udev_rule) + LINE_SIZE];
struct udev_rule *rule;
size_t rule_size;
int valid;
@@ -241,15 +242,12 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
int physdev = 0;
int retval;
- /* get all the keys */
- rule = calloc(1, sizeof (struct udev_rule) + LINE_SIZE);
- if (!rule) {
- err("malloc failed");
- return -1;
- }
+ memset(buf, 0x00, sizeof(buf));
+ rule = (struct udev_rule *) buf;
linepos = line;
valid = 0;
+ /* get all the keys */
while (1) {
char *key;
char *value;
@@ -592,6 +590,14 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
rule->link_priority = atoi(&pos[strlen("link_priority=")]);
info("link priority=%i", rule->link_priority);
}
+ pos = strstr(value, "string_escape=");
+ if (pos != NULL) {
+ pos = &pos[strlen("string_escape=")];
+ if (strncmp(pos, "none", strlen("none")) == 0)
+ rule->string_escape = ESCAPE_NONE;
+ else if (strncmp(pos, "replace", strlen("replace")) == 0)
+ rule->string_escape = ESCAPE_REPLACE;
+ }
if (strstr(value, "all_partitions") != NULL) {
dbg("creation of partition nodes requested");
rule->partitions = DEFAULT_PARTITIONS_COUNT;
@@ -627,11 +633,9 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
memcpy(rules->buf + rules->bufsize, rule, rule_size);
rules->bufsize += rule_size;
exit:
- free(rule);
return 0;
invalid:
- free(rule);
err("invalid rule '%s:%u'", filename, lineno);
return -1;
}
diff --git a/udevtest.c b/udevtest.c
index f230b66628..292a94916e 100644
--- a/udevtest.c
+++ b/udevtest.c
@@ -211,6 +211,7 @@ int main(int argc, char *argv[], char *envp[])
info("run: '%s'", program);
}
}
+ udev_device_cleanup(udev);
exit:
udev_rules_cleanup(&rules);