[[[ svn --version --verbose: Support /etc/os-release, the systemd "what distro am I running" API.
* subversion/libsvn_subr/sysinfo.c (linux_release_name): Try /etc/os-release if /usr/bin/lsb_release fails. (systemd_release): New helper for linux_release_name(). (remove_shell_quoting): New helper function. ]]] --- subversion/libsvn_subr/sysinfo.c +++ subversion/libsvn_subr/sysinfo.c @@ -410,6 +410,78 @@ lsb_release(apr_pool_t *pool) return NULL; } +/* Attempt to strip double quotes from a string. + * + * The string considered is (STR->DATA + OFFSET). If it starts + * and ends with double quotes, and has no escape sequences, return + * the string delimited by the double quotes. Otherwise, return + * the original string verbatim. + */ +static const char * +remove_shell_quoting(svn_stringbuf_t *buf, + int offset, + apr_pool_t *result_pool) +{ + const char *str = buf->data + offset; + const char *second_double_quote; + + /* Are there exactly two double quotes, at the first and last positions? */ + if (str[0] == '"' && (second_double_quote = strchr(str+1, '"')) + && second_double_quote[1] == '\0') + /* Are there any backslashes? */ + if (!strchr(str, '\\')) + /* Return whatever is between the quotes. */ + return apr_pstrndup(result_pool, str+1, second_double_quote - (str+1)); + + /* There are no double quotes, or there is a backslash and we punted. + * Either way, we'll return the string verbatim. */ + return str; +} + +/* Read /etc/os-release, as documented here: + * http://www.freedesktop.org/software/systemd/man/os-release.html + */ +static const char * +systemd_release(apr_pool_t *pool) +{ + svn_error_t *err; + svn_stream_t *stream; + + err = svn_stream_open_readonly(&stream, "/etc/os-release", pool, pool); + if (err && APR_STATUS_IS_ENOENT(err->apr_err)) + { + svn_error_clear(err); + err = svn_stream_open_readonly(&stream, "/usr/lib/os-release", pool, + pool); + } + if (err) + { + svn_error_clear(err); + return NULL; + } + + while (TRUE) + { + svn_stringbuf_t *line; + svn_boolean_t eof; + + err = svn_stream_readline(stream, &line, "\n", &eof, pool); + if (err) + { + svn_error_clear(err); + return NULL; + } + + if (!strncmp(line->data, "PRETTY_NAME=", 12)) + return remove_shell_quoting(line, 12, pool); + + if (eof) + break; + } + + return NULL; +} + /* Read the whole contents of a file. */ static svn_stringbuf_t * read_file_contents(const char *filename, apr_pool_t *pool) @@ -527,6 +599,10 @@ linux_release_name(apr_pool_t *pool) Covers, for example, Debian, Ubuntu and SuSE. */ const char *release_name = lsb_release(pool); + /* Try the systemd way (covers Arch). */ + if (!release_name) + release_name = systemd_release(pool); + /* Try RHEL/Fedora/CentOS */ if (!release_name) release_name = redhat_release(pool);