--- /dev/null
+This patch changes a repeated `--version` (`-V`) to output the
+version, capabilities, etc. in json format.
+
+To use this patch, run these commands for a successful build:
+
+ patch -p1 <patches/json-version.diff
+ ./configure (optional if already run)
+ make
+
+diff --git a/options.c b/options.c
+index 3f8d5d08..6c8534c3 100644
+--- a/options.c
++++ b/options.c
+@@ -1926,7 +1926,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
+ saw_stderr_opt = 1;
+
+ if (version_opt_cnt) {
+- print_rsync_version(FINFO);
++ print_rsync_version(FINFO, version_opt_cnt > 1);
+ exit_cleanup(0);
+ }
+
+diff --git a/usage.c b/usage.c
+index 048fd4cb..615049eb 100644
+--- a/usage.c
++++ b/usage.c
+@@ -22,6 +22,7 @@
+ #include "latest-year.h"
+ #include "git-version.h"
+ #include "default-cvsignore.h"
++#include "itypes.h"
+
+ extern struct name_num_obj valid_checksums;
+ extern struct name_num_obj valid_compressions;
+@@ -34,10 +35,10 @@ static char *istring(const char *fmt, int val)
+ return str;
+ }
+
+-static void print_info_flags(enum logcode f)
++static void print_info_flags(enum logcode f, BOOL as_json)
+ {
+ STRUCT_STAT *dumstat;
+- char line_buf[75];
++ char line_buf[75], *quot = as_json ? "\"" : "";
+ int line_len, j;
+ char *info_flags[] = {
+
+@@ -161,10 +162,12 @@ static void print_info_flags(enum logcode f)
+
+ NULL
+ };
++ if (as_json)
++ as_json = 1; /* We use 1 == first attribute, 2 == need closing array */
+
+ for (line_len = 0, j = 0; ; j++) {
+ char *str = info_flags[j], *next_nfo = str ? info_flags[j+1] : NULL;
+- int str_len = str && *str != '*' ? strlen(str) : 1000;
++ int str_len = str && *str != '*' ? strlen(str) + (as_json ? 2 : 0) : 1000;
+ int need_comma = next_nfo && *next_nfo != '*' ? 1 : 0;
+ if (line_len && line_len + 1 + str_len + need_comma >= (int)sizeof line_buf) {
+ rprintf(f, " %s\n", line_buf);
+@@ -173,37 +176,88 @@ static void print_info_flags(enum logcode f)
+ if (!str)
+ break;
+ if (*str == '*') {
+- rprintf(f, "%s:\n", str+1);
++ if (as_json) {
++ if (as_json == 2)
++ printf(" ],\n");
++ else
++ as_json = 2;
++ printf(" \"%c%s\": [\n", toLower(str+1), str+2);
++ } else
++ rprintf(f, "%s:\n", str+1);
+ continue;
+ }
+- line_len += snprintf(line_buf+line_len, sizeof line_buf - line_len, " %s%s", str, need_comma ? "," : "");
++ line_len += snprintf(line_buf+line_len, sizeof line_buf - line_len,
++ " %s%s%s%s", quot, str, quot, need_comma ? "," : "");
+ }
++ if (as_json == 2)
++ printf(" ],\n");
+ }
+
+-void print_rsync_version(enum logcode f)
++void output_json_list(const char *name, char *tmpbuf)
++{
++ char *comma = ",";
++ char *tok = strtok(tmpbuf, " ");
++ char *next_tok = tok ? strtok(NULL, " ") : NULL;
++
++ printf(" \"%s\": [\n ", name);
++
++ while (tok) {
++ printf(" \"%s\"%s", tok, comma + (next_tok ? 0 : 1));
++ if ((tok = next_tok) != NULL)
++ next_tok = strtok(NULL, " ");
++ }
++ printf("\n ],\n");
++}
++
++void print_rsync_version(enum logcode f, BOOL as_json)
+ {
+ char tmpbuf[256], *subprotocol = "";
+
+ #if SUBPROTOCOL_VERSION != 0
+ subprotocol = istring(".PR%d", SUBPROTOCOL_VERSION);
+ #endif
+- rprintf(f, "%s version %s protocol version %d%s\n",
+- RSYNC_NAME, rsync_version(), PROTOCOL_VERSION, subprotocol);
+
+- rprintf(f, "Copyright (C) 1996-" LATEST_YEAR " by Andrew Tridgell, Wayne Davison, and others.\n");
+- rprintf(f, "Web site: https://rsync.samba.org/\n");
++ if (as_json) {
++ printf("{\n \"program\": \"%s\",\n \"version\": \"%s\",\n \"protocol\": \"%d%s\",\n",
++ RSYNC_NAME, rsync_version(), PROTOCOL_VERSION, subprotocol);
++ } else {
++ rprintf(f, "%s version %s protocol version %d%s\n",
++ RSYNC_NAME, rsync_version(), PROTOCOL_VERSION, subprotocol);
++ }
+
+- print_info_flags(f);
++#define vinfo(name, pre, msg, suf) \
++ if (as_json) \
++ printf(" \"%s\": \"%s\",\n", name, msg); \
++ else \
++ rprintf(f, "%s%s%s", pre ? pre : name, msg, suf);
++
++ vinfo("copyright", "Copyright ", "(C) 1996-" LATEST_YEAR " by Andrew Tridgell, Wayne Davison, and others.", "\n");
++ vinfo("url", "Web site: ", "https://rsync.samba.org/", "\n");
++
++ print_info_flags(f, as_json);
+
+ init_checksum_choices();
+
+- rprintf(f, "Checksum list:\n");
+- get_default_nno_list(&valid_checksums, tmpbuf, sizeof tmpbuf, '(');
+- rprintf(f, " %s\n", tmpbuf);
++ get_default_nno_list(&valid_checksums, tmpbuf, sizeof tmpbuf, as_json ? '\0' : '(');
++ if (as_json)
++ output_json_list("checksum_list", tmpbuf);
++ else {
++ rprintf(f, "Checksum list:\n");
++ rprintf(f, " %s\n", tmpbuf);
++ }
+
+- rprintf(f, "Compress list:\n");
+- get_default_nno_list(&valid_compressions, tmpbuf, sizeof tmpbuf, '(');
+- rprintf(f, " %s\n", tmpbuf);
++ get_default_nno_list(&valid_compressions, tmpbuf, sizeof tmpbuf, as_json ? '\0' : '(');
++ if (as_json)
++ output_json_list("compress_list", tmpbuf);
++ else {
++ rprintf(f, "Compress list:\n");
++ rprintf(f, " %s\n", tmpbuf);
++ }
++
++ if (as_json) {
++ printf(" \"caveat\": \"rsync comes with ABSOLUTELY NO WARRANTY\"\n}\n");
++ return;
++ }
+
+ #ifdef MAINTAINER_MODE
+ rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
+@@ -226,7 +280,7 @@ void print_rsync_version(enum logcode f)
+
+ void usage(enum logcode F)
+ {
+- print_rsync_version(F);
++ print_rsync_version(F, 0);
+
+ rprintf(F,"\n");
+ rprintf(F,"rsync is a file transfer program capable of efficient remote update\n");
+@@ -253,7 +307,7 @@ void usage(enum logcode F)
+
+ void daemon_usage(enum logcode F)
+ {
+- print_rsync_version(F);
++ print_rsync_version(F, 0);
+
+ rprintf(F,"\n");
+ rprintf(F,"Usage: rsync --daemon [OPTION]...\n");