1 This patch changes a repeated `--version` (`-V`) to output the
2 version, capabilities, etc. in json format.
4 To use this patch, run these commands for a successful build:
6 patch -p1 <patches/json-version.diff
7 ./configure (optional if already run)
10 based-on: db5bfe67a5d022f9ad25340db6bc2cca2cbbdb65
11 diff --git a/options.c b/options.c
14 @@ -1926,7 +1926,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
17 if (version_opt_cnt) {
18 - print_rsync_version(FINFO);
19 + print_rsync_version(FINFO, version_opt_cnt > 1);
23 diff --git a/usage.c b/usage.c
27 #include "latest-year.h"
28 #include "git-version.h"
29 #include "default-cvsignore.h"
32 extern struct name_num_obj valid_checksums;
33 extern struct name_num_obj valid_compressions;
34 @@ -34,10 +35,10 @@ static char *istring(const char *fmt, int val)
38 -static void print_info_flags(enum logcode f)
39 +static void print_info_flags(enum logcode f, BOOL as_json)
43 + char line_buf[75], *quot = as_json ? "\"" : "";
45 char *info_flags[] = {
47 @@ -161,10 +162,12 @@ static void print_info_flags(enum logcode f)
52 + as_json = 1; /* We use 1 == first attribute, 2 == need closing array */
54 for (line_len = 0, j = 0; ; j++) {
55 char *str = info_flags[j], *next_nfo = str ? info_flags[j+1] : NULL;
56 - int str_len = str && *str != '*' ? strlen(str) : 1000;
57 + int str_len = str && *str != '*' ? strlen(str) + (as_json ? 2 : 0) : 1000;
58 int need_comma = next_nfo && *next_nfo != '*' ? 1 : 0;
59 if (line_len && line_len + 1 + str_len + need_comma >= (int)sizeof line_buf) {
60 rprintf(f, " %s\n", line_buf);
61 @@ -173,37 +176,88 @@ static void print_info_flags(enum logcode f)
65 - rprintf(f, "%s:\n", str+1);
71 + printf(" \"%c%s\": [\n", toLower(str+1), str+2);
73 + rprintf(f, "%s:\n", str+1);
76 - line_len += snprintf(line_buf+line_len, sizeof line_buf - line_len, " %s%s", str, need_comma ? "," : "");
77 + line_len += snprintf(line_buf+line_len, sizeof line_buf - line_len,
78 + " %s%s%s%s", quot, str, quot, need_comma ? "," : "");
84 -void print_rsync_version(enum logcode f)
85 +void output_json_list(const char *name, char *tmpbuf)
88 + char *tok = strtok(tmpbuf, " ");
89 + char *next_tok = tok ? strtok(NULL, " ") : NULL;
91 + printf(" \"%s\": [\n ", name);
94 + printf(" \"%s\"%s", tok, comma + (next_tok ? 0 : 1));
95 + if ((tok = next_tok) != NULL)
96 + next_tok = strtok(NULL, " ");
101 +void print_rsync_version(enum logcode f, BOOL as_json)
103 char tmpbuf[256], *subprotocol = "";
105 #if SUBPROTOCOL_VERSION != 0
106 subprotocol = istring(".PR%d", SUBPROTOCOL_VERSION);
108 - rprintf(f, "%s version %s protocol version %d%s\n",
109 - RSYNC_NAME, rsync_version(), PROTOCOL_VERSION, subprotocol);
111 - rprintf(f, "Copyright (C) 1996-" LATEST_YEAR " by Andrew Tridgell, Wayne Davison, and others.\n");
112 - rprintf(f, "Web site: https://rsync.samba.org/\n");
114 + printf("{\n \"program\": \"%s\",\n \"version\": \"%s\",\n \"protocol\": \"%d%s\",\n",
115 + RSYNC_NAME, rsync_version(), PROTOCOL_VERSION, subprotocol);
117 + rprintf(f, "%s version %s protocol version %d%s\n",
118 + RSYNC_NAME, rsync_version(), PROTOCOL_VERSION, subprotocol);
121 - print_info_flags(f);
122 +#define vinfo(name, pre, msg, suf) \
124 + printf(" \"%s\": \"%s\",\n", name, msg); \
126 + rprintf(f, "%s%s%s", pre ? pre : name, msg, suf);
128 + vinfo("copyright", "Copyright ", "(C) 1996-" LATEST_YEAR " by Andrew Tridgell, Wayne Davison, and others.", "\n");
129 + vinfo("url", "Web site: ", "https://rsync.samba.org/", "\n");
131 + print_info_flags(f, as_json);
133 init_checksum_choices();
135 - rprintf(f, "Checksum list:\n");
136 - get_default_nno_list(&valid_checksums, tmpbuf, sizeof tmpbuf, '(');
137 - rprintf(f, " %s\n", tmpbuf);
138 + get_default_nno_list(&valid_checksums, tmpbuf, sizeof tmpbuf, as_json ? '\0' : '(');
140 + output_json_list("checksum_list", tmpbuf);
142 + rprintf(f, "Checksum list:\n");
143 + rprintf(f, " %s\n", tmpbuf);
146 - rprintf(f, "Compress list:\n");
147 - get_default_nno_list(&valid_compressions, tmpbuf, sizeof tmpbuf, '(');
148 - rprintf(f, " %s\n", tmpbuf);
149 + get_default_nno_list(&valid_compressions, tmpbuf, sizeof tmpbuf, as_json ? '\0' : '(');
151 + output_json_list("compress_list", tmpbuf);
153 + rprintf(f, "Compress list:\n");
154 + rprintf(f, " %s\n", tmpbuf);
158 + printf(" \"caveat\": \"rsync comes with ABSOLUTELY NO WARRANTY\"\n}\n");
162 #ifdef MAINTAINER_MODE
163 rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
164 @@ -226,7 +280,7 @@ void print_rsync_version(enum logcode f)
166 void usage(enum logcode F)
168 - print_rsync_version(F);
169 + print_rsync_version(F, 0);
172 rprintf(F,"rsync is a file transfer program capable of efficient remote update\n");
173 @@ -253,7 +307,7 @@ void usage(enum logcode F)
175 void daemon_usage(enum logcode F)
177 - print_rsync_version(F);
178 + print_rsync_version(F, 0);
181 rprintf(F,"Usage: rsync --daemon [OPTION]...\n");