sysctl: fix bug 3894 _for real_.
authorDenis Vlasenko <vda.linux@googlemail.com>
Wed, 15 Oct 2008 09:43:35 +0000 (09:43 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Wed, 15 Oct 2008 09:43:35 +0000 (09:43 -0000)
procps/sysctl.c

index 90e47ea9ab7816e1b10679f4e0f7bd634479adf0..0876a73deec43645e5f7645d2df8b4c017ca46b3 100644 (file)
@@ -234,19 +234,30 @@ static int sysctl_display_all(const char *path)
 
 static void sysctl_dots_to_slashes(char *name)
 {
-       char *cptr = name;
+       char *cptr, *last_good;
+       char *end = name + strlen(name) - 1;
 
        /* Example from bug 3894:
         * net.ipv4.conf.eth0.100.mc_forwarding ->
-        * net/ipv4/conf/eth0.100/mc_forwarding */
-       while (*cptr != '\0') {
+        * net/ipv4/conf/eth0.100/mc_forwarding. NB:
+        * net/ipv4/conf/eth0/mc_forwarding *also exists*,
+        * therefore we must start from the end, and if
+        * we replaced even one . -> /, start over again,
+        * but never replace dots before the position
+        * where replacement occurred. */
+       last_good = name - 1;
+ again:
+       cptr = end;
+       while (cptr > last_good) {
                if (*cptr == '.') {
                        *cptr = '\0';
-                       if (access(name, F_OK) == 0)
+                       if (access(name, F_OK) == 0) {
                                *cptr = '/';
-                       else
-                               *cptr = '.';
+                               last_good = cptr;
+                               goto again;
+                       }
+                       *cptr = '.';
                }
-               cptr++;
+               cptr--;
        }
 } /* end sysctl_dots_to_slashes() */