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;
while (1) {
- pos = strchr(pos, '%');
+ pos = strchr(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;
case 'b':
if (strlen(udev->bus_id) == 0)
break;
- strnfieldcat(pos, udev->bus_id, maxsize);
+ strnfieldcat(string, udev->bus_id, maxsize);
dbg("substitute bus_id '%s'", udev->bus_id);
break;
case 'k':
if (strlen(udev->kernel_name) == 0)
break;
- strnfieldcat(pos, udev->kernel_name, maxsize);
+ strnfieldcat(string, udev->kernel_name, maxsize);
dbg("substitute kernel name '%s'", udev->kernel_name);
break;
case 'n':
if (strlen(udev->kernel_number) == 0)
break;
- strnfieldcat(pos, udev->kernel_number, maxsize);
+ strnfieldcat(string, udev->kernel_number, maxsize);
dbg("substitute kernel number '%s'", udev->kernel_number);
break;
case 'm':
- sprintf(pos, "%u", udev->minor);
+ strnintcat(string, udev->minor, maxsize);
dbg("substitute minor number '%u'", udev->minor);
break;
- case 'M':
- sprintf(pos, "%u", udev->major);
+ case 'M':
+ strnintcat(string, udev->major, maxsize);
dbg("substitute major number '%u'", udev->major);
break;
case 'c':
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(pos, 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(pos, udev->program_result, maxsize);
+ strnfieldcat(string, udev->program_result, maxsize);
dbg("substitute result string '%s'", udev->program_result);
}
break;
dbg("sysfa attribute '%s' not found", attr);
break;
}
- strnfieldcpy(pos, tmpattr->value, maxsize);
+ strnfieldcat(string, tmpattr->value, maxsize);
dbg("substitute sysfs value '%s'", tmpattr->value);
} else {
dbg("missing attribute");
}
break;
case '%':
- strnfieldcat(pos, "%", maxsize);
+ strnfieldcat(string, "%", maxsize);
break;
default:
dbg("unknown substitution type '%%%c'", c);
break;
}
- strnfieldcat(pos, tail, maxsize);
+ /* truncate to specified length */
+ if (len > 0)
+ pos[len] = '\0';
+
+ strnfieldcat(string, tail, maxsize);
}
}
case 0:
/* child */
close(STDOUT_FILENO);
- dup(fds[1]); /* dup write side of pipe to STDOUT */
+
+ /* dup write side of pipe to STDOUT */
+ dup(fds[1]);
+
+ /* copy off our path to use incase we have too many args */
+ strnfieldcpy(buffer, path, sizeof(buffer));
+
if (strchr(path, ' ')) {
/* exec with arguments */
pos = path;
break;
}
if (args[i]) {
- dbg("too many args - %d", i);
- args[i] = NULL;
+ dbg("too many args - %d, using subshell instead '%s'", i, buffer);
+ retval = execl("/bin/sh", "sh", "-c", buffer, NULL);
+ } else {
+ dbg("execute program '%s'", path);
+ retval = execv(args[0], args);
}
- retval = execv(args[0], args);
} else {
retval = execv(path, main_argv);
}
- dbg("child execve failed");
+ info(FIELD_PROGRAM " execution of '%s' failed", path);
exit(1);
case -1:
dbg("fork failed");
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);