chiark / gitweb /
[PATCH] allow multiple symlinks
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Wed, 10 Dec 2003 08:47:00 +0000 (00:47 -0800)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:13:07 +0000 (21:13 -0700)
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)

test/udev-test.pl
udev-add.c
udev-remove.c

index 190b7ce..39d8450 100644 (file)
@@ -217,6 +217,15 @@ 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
+       },
 );
 
 # set env
index 17b69ea..e64a845 100644 (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);
-
-               /* 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;
index 02c8437..0886c23 100644 (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);
+                       }
                }
        }