diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-15 13:43:35 +0400 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-15 13:43:35 +0400 |
commit | e915a1a410b9852ddfaa0563922920219c2e6ed3 (patch) | |
tree | 2e76a0f67709279af7066532db33d652396f7907 | |
parent | 81944c9e92991eff0d1a9fc289b21cc745f43f9c (diff) |
sysctl: fix bug 3894 _for real_.
-rw-r--r-- | procps/sysctl.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/procps/sysctl.c b/procps/sysctl.c index 90e47ea9a..0876a73de 100644 --- a/procps/sysctl.c +++ b/procps/sysctl.c @@ -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() */ |