if (isdigit(*str[0])) {
num = (int) strtoul(*str, &tail, 10);
- if (tail != NULL) {
+ if (num > 0) {
*str = tail;
dbg("format length=%i", num);
return num;
struct sysfs_device *sysfs_device)
{
char temp[NAME_SIZE];
- char temp1[NAME_SIZE];
+ char temp2[NAME_SIZE];
char *tail;
char *pos;
- char *pos2;
- char *pos3;
char *attr;
- int num;
+ int len;
int i;
char c;
+ char *spos;
+ int slen;
struct sysfs_attribute *tmpattr;
pos = string;
if (pos != NULL) {
pos[0] = '\0';
tail = pos+1;
- num = get_format_len(&tail);
+ len = get_format_len(&tail);
c = tail[0];
strfieldcpy(temp, tail+1);
tail = temp;
if (strlen(udev->program_result) == 0)
break;
/* get part part of the result string */
- i = num; /* num syntax is deprecated and will be removed */
+ i = 0;
if (attr != NULL)
i = atoi(attr);
if (i > 0) {
- strfieldcpy(temp1, udev->program_result);
- pos2 = temp1;
- while (i) {
+ foreach_strpart(udev->program_result, " \n\r", spos, slen) {
i--;
- pos3 = strsep(&pos2, " ");
- if (pos3 == NULL) {
- dbg("requested part of result string not found");
+ if (i == 0)
break;
- }
}
- if (pos3) {
- strnfieldcat(string, pos3, maxsize);
- dbg("substitute part of result string '%s'", pos3);
+ if (i > 0) {
+ dbg("requested part of result string not found");
+ break;
}
+ strnfieldcpy(temp2, spos, slen+1);
+ strnfieldcat(string, temp2, maxsize);
+ dbg("substitute part of result string '%s'", temp2);
} else {
strnfieldcat(string, udev->program_result, maxsize);
dbg("substitute result string '%s'", udev->program_result);
dbg("unknown substitution type '%%%c'", c);
break;
}
+ /* truncate to specified length */
+ if (len > 0)
+ pos[len] = '\0';
+
strnfieldcat(string, tail, maxsize);
}
}
static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair)
{
struct sysfs_attribute *tmpattr;
+ int i;
+ int len;
if ((pair == NULL) || (pair->file[0] == '\0') || (pair->value == '\0'))
return -ENODEV;
if (tmpattr == NULL)
return -ENODEV;
+ /* strip trailing whitespace of value, if not asked to match for it */
+ if (! isspace(pair->value[strlen(pair->value)-1])) {
+ i = len = strlen(tmpattr->value);
+ while (i > 0 && isspace(tmpattr->value[i-1]))
+ i--;
+ if (i < len) {
+ tmpattr->value[i] = '\0';
+ dbg("remove %i trailing whitespace chars from '%s'",
+ len - i, tmpattr->value);
+ }
+ }
+
dbg("compare attribute '%s' value '%s' with '%s'",
pair->file, tmpattr->value, pair->value);
if (strcmp_pattern(pair->value, tmpattr->value) != 0)
list_for_each_entry(dev, &config_device_list, node) {
dbg("process rule");
if (match_rule(dev, class_dev, udev, sysfs_device) == 0) {
- if (dev->name[0] == '\0') {
+ if (dev->name[0] == '\0' && dev->symlink[0] == '\0') {
info("configured rule in '%s' at line %i applied, '%s' is ignored",
- udev_rules_filename, dev->config_line, udev->kernel_name);
+ dev->config_file, dev->config_line, udev->kernel_name);
return -1;
}
- info("configured rule in '%s' at line %i applied, '%s' becomes '%s'",
- udev_rules_filename, dev->config_line, udev->kernel_name, dev->name);
- strfieldcpy(udev->name, dev->name);
- strfieldcpy(udev->symlink, dev->symlink);
- goto found;
+ if (dev->symlink[0] != '\0') {
+ char temp[NAME_MAX];
+
+ info("configured rule in '%s' at line %i applied, added symlink '%s'",
+ dev->config_file, dev->config_line, dev->symlink);
+ /* do not clobber dev */
+ strfieldcpy(temp, dev->symlink);
+ apply_format(udev, temp, sizeof(temp),
+ class_dev, sysfs_device);
+ strfieldcat(udev->symlink, temp);
+ strfieldcat(udev->symlink, " ");
+ }
+
+ if (dev->name[0] != '\0') {
+ info("configured rule in '%s' at line %i applied, '%s' becomes '%s'",
+ dev->config_file, dev->config_line, udev->kernel_name, dev->name);
+ strfieldcpy(udev->name, dev->name);
+ goto found;
+ }
}
}
/* substitute placeholder */
apply_format(udev, udev->name, sizeof(udev->name),
class_dev, sysfs_device);
- apply_format(udev, udev->symlink, sizeof(udev->symlink),
- class_dev, sysfs_device);
udev->partitions = dev->partitions;
done:
perm = find_perm(udev->name);