--- a/src/rc/mountinfo.c 2011-09-09 00:09:45.000000000 +0400 +++ b/src/rc/mountinfo.c 2011-09-11 00:42:00.000000000 +0400 @@ -326,14 +326,64 @@ # error "Operating system not supported!" #endif +/* + * Done to fix bug #381783 in Gentoo Bugzilla, by i.Dark_Templar + * This function resolves symlinks in paths inside regexp + * Returns new string (should be freed later by free()) or NULL on errors + * Paramaters: + * 1. char *string - starting regexp + * 2. const char *delimiter - used delimiter (i've seen '|' used in OpenRC scripts) + */ + +char* regexp_resolve_symlinks(char* string, const char* delimiter) { + char *oldstr, *newstr = NULL, *tmp, *token, *saveptr; + char real_path[PATH_MAX + 1]; + + oldstr = strdup(string); + if (!oldstr) return NULL; /* not enough memory? abort */ + + for (token = strtok_r(oldstr, delimiter, &saveptr); token != NULL; token = strtok_r(NULL, delimiter, &saveptr)) { + + if (realpath(token, real_path) != NULL) { + token = real_path; /* could resolve path, add resolved to new string, otherwise use unresolved, probably it should be so */ + } + + tmp = realloc(newstr, ((newstr) ? (strlen(newstr) + strlen(delimiter)) : (0)) + strlen(token) + 1); + if (!tmp) { /* not enough memory? abort */ + free(oldstr); + if (newstr) free(newstr); + return NULL; + } + + if (newstr) strcat(tmp, delimiter); /* not first item, add delimiter */ + newstr = tmp; + strcat(newstr, token); + } + + free(oldstr); + + return newstr; +} + static regex_t * get_regex(const char *string) { regex_t *reg = xmalloc(sizeof (*reg)); int result; char buffer[256]; - - if ((result = regcomp(reg, string, REG_EXTENDED | REG_NOSUB)) != 0) + char *resolved_regexp; + + if ((resolved_regexp = regexp_resolve_symlinks(string, "|")) == NULL) + { + eerrorx("%s: couldn't resolve regexp", applet); /* I don't mind changing it for something more informative error */ + + result = regcomp(reg, string, REG_EXTENDED | REG_NOSUB); /* Fallback to starting string */ + } else { + result = regcomp(reg, resolved_regexp, REG_EXTENDED | REG_NOSUB); + free(resolved_regexp); + } + + if (result != 0) { regerror(result, reg, buffer, sizeof(buffer)); eerrorx("%s: invalid regex `%s'", applet, buffer);