[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" , expected => "1/2/c/d/symlink" ,
conf => <<EOF conf => <<EOF
LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink" 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 EOF
}, },
); );

View File

@ -102,6 +102,8 @@ static int create_node(struct udevice *dev)
{ {
char filename[255]; char filename[255];
char linktarget[255]; char linktarget[255];
char *linkname;
char *symlinks;
int retval = 0; int retval = 0;
uid_t uid = 0; uid_t uid = 0;
gid_t gid = 0; gid_t gid = 0;
@ -186,39 +188,45 @@ static int create_node(struct udevice *dev)
filename, uid, gid, strerror(errno)); filename, uid, gid, strerror(errno));
} }
/* create symlink if requested */ /* create symlink if requested */
if (*dev->symlink) { if (*dev->symlink) {
strncpy(filename, udev_root, sizeof(filename)); symlinks = dev->symlink;
strncat(filename, dev->symlink, sizeof(filename)); while (1) {
dbg("symlink '%s' to node '%s' requested", filename, dev->name); linkname = strsep(&symlinks, " ");
if (strrchr(dev->symlink, '/')) if (linkname == NULL)
create_path(filename); break;
/* optimize relative link */ strncpy(filename, udev_root, sizeof(filename));
linktarget[0] = '\0'; strncat(filename, linkname, sizeof(filename));
i = 0; dbg("symlink '%s' to node '%s' requested", filename, dev->name);
tail = 0; if (strrchr(linkname, '/'))
while ((dev->name[i] == dev->symlink[i]) && dev->name[i]) { create_path(filename);
if (dev->name[i] == '/')
tail = i+1; /* optimize relative link */
i++; 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; return retval;

View File

@ -66,6 +66,8 @@ static int delete_path(char *path)
static int delete_node(struct udevice *dev) static int delete_node(struct udevice *dev)
{ {
char filename[255]; char filename[255];
char *symlinks;
char *linkname;
int retval; int retval;
strncpy(filename, udev_root, sizeof(filename)); strncpy(filename, udev_root, sizeof(filename));
@ -84,17 +86,25 @@ static int delete_node(struct udevice *dev)
delete_path(filename); delete_path(filename);
if (*dev->symlink) { if (*dev->symlink) {
strncpy(filename, udev_root, sizeof(filename)); symlinks = dev->symlink;
strncat(filename, dev->symlink, sizeof(filename)); while (1) {
dbg("unlinking symlink '%s'", filename); linkname = strsep(&symlinks, " ");
retval = unlink(filename); if (linkname == NULL)
if (retval) { break;
dbg("unlink(%s) failed with error '%s'",
filename, strerror(errno)); strncpy(filename, udev_root, sizeof(filename));
return retval; strncat(filename, linkname, sizeof(filename));
}
if (strchr(dev->symlink, '/')) { dbg("unlinking symlink '%s'", filename);
delete_path(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);
}
} }
} }