[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)
This commit is contained in:
kay.sievers@vrfy.org 2003-12-10 00:47:00 -08:00 committed by Greg KH
parent 10a479f5e6
commit 4763256c65
3 changed files with 67 additions and 40 deletions

View File

@ -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
},
);

View File

@ -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);
symlinks = dev->symlink;
while (1) {
linkname = strsep(&symlinks, " ");
if (linkname == NULL)
break;
/* 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++;
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]);
dbg("symlink(%s, %s)", linktarget, filename);
retval = symlink(linktarget, filename);
if (retval)
dbg("symlink(%s, %s) failed with error '%s'",
linktarget, filename, strerror(errno));
}
while (dev->symlink[i]) {
if (dev->symlink[i] == '/')
strcat(linktarget, "../");
i++;
}
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));
}
return retval;

View File

@ -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);
}
}
}