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;
}
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 */
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
},
{
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
#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"
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];
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];
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)
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <ctype.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
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;
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;
}
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,