[[[
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);
Received on 2015-01-27 11:17:35 CET