summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>2004-12-20 07:38:33 +0100
committerGreg KH <gregkh@suse.de>2005-04-26 23:19:09 -0700
commit9f8dfa19cfd2b502bf794f39a421cbb7c4cc0404 (patch)
treeb91b9ebebd7a08a722d60495af2a2b594dd50d0e
parenta07dc29e602440541ce531e03737bc1f926a0ef3 (diff)
[PATCH] allow multiline rules by backslash at the end of the line
On Sun, 2004-12-19 at 18:31 +0100, Marco d'Itri wrote: > > On Dec 19, Kay Sievers <kay.sievers@vrfy.org> wrote: > > > (Feature request: would it be possible to extend the rules files parser > > to support continuation lines? I'd like it to consider lines starting > > with white space as part of the previous line.) > > How about the usual backslash at the end of the line. Here is a simple > patch.
-rw-r--r--namedev_parse.c15
-rw-r--r--test/udev-test.pl30
-rw-r--r--udev.8.in6
-rw-r--r--udev.h3
-rw-r--r--udev_config.c54
-rw-r--r--udev_utils.c52
-rw-r--r--udev_utils.h3
7 files changed, 102 insertions, 61 deletions
diff --git a/namedev_parse.c b/namedev_parse.c
index 7190cdd1a8..3b14a6a500 100644
--- a/namedev_parse.c
+++ b/namedev_parse.c
@@ -126,14 +126,15 @@ static int namedev_parse(const char *filename, void *data)
cur = 0;
lineno = 0;
while (cur < bufsize) {
+ int i, j;
+
count = buf_get_line(buf, bufsize, cur);
bufline = &buf[cur];
cur += count+1;
lineno++;
if (count >= LINE_SIZE) {
- info("line too long, rule skipped %s, line %d",
- filename, lineno);
+ info("line too long, rule skipped %s, line %d", filename, lineno);
continue;
}
@@ -149,8 +150,14 @@ static int namedev_parse(const char *filename, void *data)
if (bufline[0] == COMMENT_CHARACTER)
continue;
- strncpy(line, bufline, count);
- line[count] = '\0';
+ /* skip backslash and newline from multi line rules */
+ for (i = j = 0; i < count; i++) {
+ if (bufline[i] == '\\' || bufline[i] == '\n')
+ continue;
+
+ line[j++] = bufline[i];
+ }
+ line[j] = '\0';
dbg_parse("read '%s'", line);
/* get all known keys */
diff --git a/test/udev-test.pl b/test/udev-test.pl
index 9a581ce527..53eee35457 100644
--- a/test/udev-test.pl
+++ b/test/udev-test.pl
@@ -190,6 +190,36 @@ KERNEL="ttyUSB0", NAME="visor"
EOF
},
{
+ desc => "Handle backslashed multi lines in config file (and replace kernel name)",
+ subsys => "tty",
+ devpath => "/class/tty/ttyUSB0",
+ exp_name => "visor" ,
+ conf => <<EOF
+KERNEL="ttyUSB0", \\
+NAME="visor"
+
+EOF
+ },
+ {
+ desc => "Handle stupid backslashed multi lines in config file (and replace kernel name)",
+ subsys => "tty",
+ devpath => "/class/tty/ttyUSB0",
+ exp_name => "visor" ,
+ conf => <<EOF
+
+#
+\\
+
+\\\\
+
+#\\
+
+KERNEL="ttyUSB0", \\
+NAME="visor"
+
+EOF
+ },
+ {
desc => "subdirectory handling",
subsys => "tty",
devpath => "/class/tty/ttyUSB0",
diff --git a/udev.8.in b/udev.8.in
index 5d55b3282c..0cc2f939e3 100644
--- a/udev.8.in
+++ b/udev.8.in
@@ -203,10 +203,10 @@ separate rules file, while the device nodes are maintained by the
distribution provided rules file.
.TP
.B OWNER, GROUP, MODE
-The permissions for this device. Every specified value overwrites the default
-value specified in the config file.
+The permissions for the device node. Every specified value overwrites the
+default value specified in the config file.
.P
-.RB "The " NAME " ," SYMLINK " and " PROGRAM
+.RB "The " NAME ", " SYMLINK ", " PROGRAM ", " OWNER " and " GROUP
fields support simple printf-like string substitutions:
.TP
.B %n
diff --git a/udev.h b/udev.h
index 0111644eff..80eafb0d46 100644
--- a/udev.h
+++ b/udev.h
@@ -37,7 +37,7 @@
#define SUBSYSTEM_SIZE 32
#define SEQNUM_SIZE 32
-#define LINE_SIZE 256
+#define LINE_SIZE 512
#define DEVD_DIR "/etc/dev.d"
#define DEVD_SUFFIX ".dev"
@@ -74,7 +74,6 @@ extern int udev_add_device(struct udevice *udev, struct sysfs_class_device *clas
extern int udev_remove_device(struct udevice *udev);
extern void udev_init_config(void);
extern int udev_start(void);
-extern int parse_get_pair(char **orig_string, char **left, char **right);
extern void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix);
extern char sysfs_path[SYSFS_PATH_MAX];
diff --git a/udev_config.c b/udev_config.c
index 31c2a86ed1..da8c676d04 100644
--- a/udev_config.c
+++ b/udev_config.c
@@ -91,41 +91,6 @@ static void init_variables(void)
udev_hotplug_d = 0;
}
-int parse_get_pair(char **orig_string, char **left, char **right)
-{
- char *temp;
- char *string = *orig_string;
-
- if (!string)
- return -ENODEV;
-
- /* eat any whitespace */
- while (isspace(*string) || *string == ',')
- ++string;
-
- /* split based on '=' */
- temp = strsep(&string, "=");
- *left = temp;
- if (!string)
- return -ENODEV;
-
- /* take the right side and strip off the '"' */
- while (isspace(*string))
- ++string;
- if (*string == '"')
- ++string;
- else
- return -ENODEV;
-
- temp = strsep(&string, "\"");
- if (!string || *temp == '\0')
- return -ENODEV;
- *right = temp;
- *orig_string = string;
-
- return 0;
-}
-
static int parse_config_file(void)
{
char line[LINE_SIZE];
@@ -254,20 +219,13 @@ static void get_dirs(void)
strfieldcpy(udev_config_filename, temp);
}
- dbg("sysfs_path='%s'", sysfs_path);
- dbg_parse("udev_root = %s", udev_root);
- dbg_parse("udev_config_filename = %s", udev_config_filename);
- dbg_parse("udev_db_path = %s", udev_db_path);
- dbg_parse("udev_rules_filename = %s", udev_rules_filename);
- dbg_parse("udev_log = %d", udev_log);
-
parse_config_file();
-
- dbg("udev_root = %s", udev_root);
- dbg("udev_config_filename = %s", udev_config_filename);
- dbg("udev_db_path = %s", udev_db_path);
- dbg("udev_rules_filename = %s", udev_rules_filename);
- dbg("udev_log = %d", udev_log);
+ dbg("sysfs_path='%s'", sysfs_path);
+ dbg("udev_root='%s'", udev_root);
+ dbg("udev_config_filename='%s'", udev_config_filename);
+ dbg("udev_db_path='%s'", udev_db_path);
+ dbg("udev_rules_filename='%s'", udev_rules_filename);
+ dbg("udev_log=%d", udev_log);
}
void udev_init_config(void)
diff --git a/udev_utils.c b/udev_utils.c
index 0b730d565b..fe18892de1 100644
--- a/udev_utils.c
+++ b/udev_utils.c
@@ -25,6 +25,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <ctype.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
@@ -111,6 +112,41 @@ int create_path(const char *path)
return mkdir(p, 0755);
}
+int parse_get_pair(char **orig_string, char **left, char **right)
+{
+ char *temp;
+ char *string = *orig_string;
+
+ if (!string)
+ return -ENODEV;
+
+ /* eat any whitespace */
+ while (isspace(*string) || *string == ',')
+ ++string;
+
+ /* split based on '=' */
+ temp = strsep(&string, "=");
+ *left = temp;
+ if (!string)
+ return -ENODEV;
+
+ /* take the right side and strip off the '"' */
+ while (isspace(*string))
+ ++string;
+ if (*string == '"')
+ ++string;
+ else
+ return -ENODEV;
+
+ temp = strsep(&string, "\"");
+ if (!string || *temp == '\0')
+ return -ENODEV;
+ *right = temp;
+ *orig_string = string;
+
+ return 0;
+}
+
int file_map(const char *filename, char **buf, size_t *bufsize)
{
struct stat stats;
@@ -143,11 +179,21 @@ void file_unmap(char *buf, size_t bufsize)
munmap(buf, bufsize);
}
-size_t buf_get_line(char *buf, size_t buflen, size_t cur)
+/* return number of chars until the next newline, skip escaped newline */
+size_t buf_get_line(const char *buf, size_t buflen, size_t cur)
{
- size_t count = 0;
+ int escape = 0;
+ size_t count;
+
+ for (count = cur; count < buflen; count++) {
+ if (!escape && buf[count] == '\n')
+ break;
- for (count = cur; count < buflen && buf[count] != '\n'; count++);
+ if (buf[count] == '\\')
+ escape = 1;
+ else
+ escape = 0;
+ }
return count - cur;
}
diff --git a/udev_utils.h b/udev_utils.h
index e36255f526..cc9dd704de 100644
--- a/udev_utils.h
+++ b/udev_utils.h
@@ -79,9 +79,10 @@ do { \
extern void udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem);
extern int kernel_release_satisfactory(int version, int patchlevel, int sublevel);
extern int create_path(const char *path);
+extern int parse_get_pair(char **orig_string, char **left, char **right);
extern int file_map(const char *filename, char **buf, size_t *bufsize);
extern void file_unmap(char *buf, size_t bufsize);
-extern size_t buf_get_line(char *buf, size_t buflen, size_t cur);
+extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur);
extern void no_trailing_slash(char *path);
typedef int (*file_fnct_t)(const char *filename, void *data);
extern int call_foreach_file(file_fnct_t fnct, const char *dirname,