Commit 4763256c authored by kay.sievers@vrfy.org's avatar kay.sievers@vrfy.org Committed by Greg KH
Browse files

[PATCH] allow multiple symlinks

Here is a patch to allow the creation of multiple symlinks.
The names must be separated by a space character.


REPLACE, KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n"

results in:

Dec  9 05:28:51 pim udev[12019]: create_node: mknod(udev-root/visor, 020666, 188, 0)
Dec  9 05:28:51 pim udev[12019]: create_node: symlink 'udev-root/first-0' to node 'visor' requested
Dec  9 05:28:51 pim udev[12019]: create_node: symlink(./visor, udev-root/first-0)
Dec  9 05:28:51 pim udev[12019]: create_node: symlink 'udev-root/second-0' to node 'visor' requested
Dec  9 05:28:51 pim udev[12019]: create_node: symlink(./visor, udev-root/second-0)
Dec  9 05:28:51 pim udev[12019]: create_node: symlink 'udev-root/third-0' to node 'visor' requested
Dec  9 05:28:51 pim udev[12019]: create_node: symlink(./visor, udev-root/third-0)
parent 10a479f5
......@@ -215,6 +215,15 @@ EOF
expected => "1/2/c/d/symlink" ,
conf => <<EOF
LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink"
EOF
},
{
desc => "multiple symlinks",
subsys => "tty",
devpath => "class/tty/ttyUSB0",
expected => "second-0" ,
conf => <<EOF
REPLACE, KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n"
EOF
},
);
......
......@@ -102,6 +102,8 @@ static int create_node(struct udevice *dev)
{
char filename[255];
char linktarget[255];
char *linkname;
char *symlinks;
int retval = 0;
uid_t uid = 0;
gid_t gid = 0;
......@@ -186,39 +188,45 @@ static int create_node(struct udevice *dev)
filename, uid, gid, strerror(errno));
}
/* create symlink if requested */
if (*dev->symlink) {
strncpy(filename, udev_root, sizeof(filename));
strncat(filename, dev->symlink, sizeof(filename));
dbg("symlink '%s' to node '%s' requested", filename, dev->name);
if (strrchr(dev->symlink, '/'))
create_path(filename);
/* optimize relative link */
linktarget[0] = '\0';
i = 0;
tail = 0;
while ((dev->name[i] == dev->symlink[i]) && dev->name[i]) {
if (dev->name[i] == '/')
tail = i+1;
i++;
}
while (dev->symlink[i]) {
if (dev->symlink[i] == '/')
strcat(linktarget, "../");
i++;
}
symlinks = dev->symlink;
while (1) {
linkname = strsep(&symlinks, " ");
if (linkname == NULL)
break;
strncpy(filename, udev_root, sizeof(filename));
strncat(filename, linkname, sizeof(filename));
dbg("symlink '%s' to node '%s' requested", filename, dev->name);
if (strrchr(linkname, '/'))
create_path(filename);
/* optimize relative link */
linktarget[0] = '\0';
i = 0;
tail = 0;
while ((dev->name[i] == linkname[i]) && dev->name[i]) {
if (dev->name[i] == '/')
tail = i+1;
i++;
}
while (linkname[i]) {
if (linkname[i] == '/')
strcat(linktarget, "../");
i++;
}
if (*linktarget == '\0')
strcpy(linktarget, "./");
strcat(linktarget, &dev->name[tail]);
if (*linktarget == '\0')
strcpy(linktarget, "./");
strcat(linktarget, &dev->name[tail]);
dbg("symlink(%s, %s)", linktarget, filename);
retval = symlink(linktarget, filename);
if (retval)
dbg("symlink(%s, %s) failed with error '%s'",
linktarget, filename, strerror(errno));
dbg("symlink(%s, %s)", linktarget, filename);
retval = symlink(linktarget, filename);
if (retval)
dbg("symlink(%s, %s) failed with error '%s'",
linktarget, filename, strerror(errno));
}
}
return retval;
......
......@@ -66,6 +66,8 @@ static int delete_path(char *path)
static int delete_node(struct udevice *dev)
{
char filename[255];
char *symlinks;
char *linkname;
int retval;
strncpy(filename, udev_root, sizeof(filename));
......@@ -84,17 +86,25 @@ static int delete_node(struct udevice *dev)
delete_path(filename);
if (*dev->symlink) {
strncpy(filename, udev_root, sizeof(filename));
strncat(filename, dev->symlink, sizeof(filename));
dbg("unlinking symlink '%s'", filename);
retval = unlink(filename);
if (retval) {
dbg("unlink(%s) failed with error '%s'",
filename, strerror(errno));
return retval;
}
if (strchr(dev->symlink, '/')) {
delete_path(filename);
symlinks = dev->symlink;
while (1) {
linkname = strsep(&symlinks, " ");
if (linkname == NULL)
break;
strncpy(filename, udev_root, sizeof(filename));
strncat(filename, linkname, sizeof(filename));
dbg("unlinking symlink '%s'", filename);
retval = unlink(filename);
if (retval) {
dbg("unlink(%s) failed with error '%s'",
filename, strerror(errno));
return retval;
}
if (strchr(dev->symlink, '/')) {
delete_path(filename);
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment