chiark / gitweb /
allow to disable the replacement of unusual characters
authorKay Sievers <kay.sievers@vrfy.org>
Thu, 21 Jun 2007 23:27:02 +0000 (01:27 +0200)
committerKay Sievers <kay.sievers@vrfy.org>
Thu, 21 Jun 2007 23:27:02 +0000 (01:27 +0200)
udev.7
udev.xml
udev_rules.c
udev_rules.h
udev_rules_parse.c
udevtest.c

diff --git a/udev.7 b/udev.7
index a25358158143c3ef63da0178bb738c8c4479cc44..d3ed4b71d680a794c4ff63d8064b4b50a42a611e 100644 (file)
--- 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
index a3658bd548575915ff9705fd1060001c27dac3aa..520c718c7a98a0e0d7a1e6575b05763020609e76 100644 (file)
--- a/udev.xml
+++ b/udev.xml
                       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>
index 6ef320dfc72385983a1d2d6791dcfac87eaecde4..cb74da56e37ae0da284a5f67b1692ce5965b11b0 100644 (file)
@@ -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)
index 0e1ff76b42152439284114842ff32e2cf56bc35d..682bedac01fbfb3e42c0271d6c395693a5303f2c 100644 (file)
@@ -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;
index 4420616903093e532e461fa269e745599626988e..9a12d53816e59f4dfaa50d3add57e4c243f5c925 100644 (file)
@@ -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;
 }
index f230b66628d1f473a04776222793c3d2ff9092ec..292a94916e705e079ab46e33d8a42bea84fe1ff4 100644 (file)
@@ -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);