2 * Some usage & version related functions.
4 * Copyright (C) 2002-2022 Wayne Davison
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, visit the http://fsf.org website.
22 #include "latest-year.h"
23 #include "git-version.h"
24 #include "default-cvsignore.h"
27 extern struct name_num_obj valid_checksums
, valid_compressions
, valid_auth_checksums
;
29 static char *istring(const char *fmt
, int val
)
32 if (asprintf(&str
, fmt
, val
) < 0)
33 out_of_memory("istring");
37 static void print_info_flags(enum logcode f
)
40 BOOL as_json
= f
== FNONE
? 1 : 0; /* We use 1 == first attribute, 2 == need closing array */
41 char line_buf
[75], item_buf
[32];
43 char *info_flags
[] = {
47 istring("%d-bit files", (int)(sizeof (OFF_T
) * 8)),
48 istring("%d-bit inums", (int)(sizeof dumstat
->st_ino
* 8)), /* Don't check ino_t! */
49 istring("%d-bit timestamps", (int)(sizeof (time_t) * 8)),
50 istring("%d-bit long ints", (int)(sizeof (int64
) * 8)),
52 #ifndef HAVE_SOCKETPAIR
62 #ifndef CAN_SET_SYMLINK_TIMES
67 #ifndef SUPPORT_HARD_LINKS
72 #ifndef CAN_HARDLINK_SPECIAL
77 #ifndef CAN_HARDLINK_SYMLINK
87 #ifndef SUPPORT_ATIMES
94 #ifndef HAVE_FTRUNCATE
99 #ifndef HAVE_FTRUNCATE
109 #ifndef SUPPORT_XATTRS
114 #ifdef RSYNC_USE_SECLUDED_ARGS
126 #ifndef SUPPORT_PREALLOCATION
136 #ifndef SUPPORT_CRTIMES
143 #ifndef USE_ROLL_SIMD
166 for (line_len
= 0, j
= 0; ; j
++) {
167 char *str
= info_flags
[j
], *next_nfo
= str
? info_flags
[j
+1] : NULL
;
168 int need_comma
= next_nfo
&& *next_nfo
!= '*' ? 1 : 0;
170 if (!str
|| *str
== '*')
173 char *space
= strchr(str
, ' ');
174 int is_no
= space
&& strncmp(str
, "no ", 3) == 0;
175 int is_bits
= space
&& isDigit(str
);
176 char *quot
= space
&& !is_no
&& !is_bits
? "\"" : "";
177 char *item
= space
? space
+ 1 : str
;
178 char *val
= !space
? "true" : is_no
? "false" : str
;
179 int val_len
= !space
? 4 : is_no
? 5 : space
- str
;
180 if (is_bits
&& (space
= strchr(val
, '-')) != NULL
)
181 val_len
= space
- str
;
182 item_len
= snprintf(item_buf
, sizeof item_buf
,
183 " \"%s%s\": %s%.*s%s%s", item
, is_bits
? "bits" : "",
184 quot
, val_len
, val
, quot
, need_comma
? "," : "");
186 item_buf
[strlen(item
)+2-1] = '_'; /* Turn the 's' into a '_' */
187 for (space
= item
; (space
= strpbrk(space
, " -")) != NULL
; space
++)
188 item_buf
[space
- item
+ 2] = '_';
190 item_len
= snprintf(item_buf
, sizeof item_buf
, " %s%s", str
, need_comma
? "," : "");
191 if (line_len
&& line_len
+ item_len
>= (int)sizeof line_buf
) {
193 printf(" %s\n", line_buf
);
195 rprintf(f
, " %s\n", line_buf
);
206 printf(",\n \"%c%s\": {\n", toLower(str
+1), str
+2);
208 rprintf(f
, "%s:\n", str
+1);
210 strlcpy(line_buf
+ line_len
, item_buf
, sizeof line_buf
- line_len
);
211 line_len
+= item_len
;
218 static void output_nno_list(enum logcode f
, const char *name
, struct name_num_obj
*nno
)
220 char namebuf
[64], tmpbuf
[256];
221 char *tok
, *next_tok
, *comma
= ",";
224 /* Using '(' ensures that we get a trailing "none" but also includes aliases. */
225 get_default_nno_list(nno
, tmpbuf
, sizeof tmpbuf
- 1, '(');
227 rprintf(f
, "%s:\n", name
);
228 rprintf(f
, " %s\n", tmpbuf
);
232 strlcpy(namebuf
, name
, sizeof namebuf
);
233 for (cp
= namebuf
; *cp
; cp
++) {
236 else if (isUpper(cp
))
240 printf(",\n \"%s\": [\n ", namebuf
);
242 for (tok
= strtok(tmpbuf
, " "); tok
; tok
= next_tok
) {
243 next_tok
= strtok(NULL
, " ");
244 if (*tok
!= '(') /* Ignore the alises in the JSON output */
245 printf(" \"%s\"%s", tok
, comma
+ (next_tok
? 0 : 1));
251 /* A request of f == FNONE wants json on stdout. */
252 void print_rsync_version(enum logcode f
)
254 char copyright
[] = "(C) 1996-" LATEST_YEAR
" by Andrew Tridgell, Wayne Davison, and others.";
255 char url
[] = "https://rsync.samba.org/";
258 #define json_line(name, value) \
260 printf("%c\n \"%s\": \"%s\"", first_line ? '{' : ',', name, value); \
266 json_line("program", RSYNC_NAME
);
267 json_line("version", rsync_version());
268 (void)snprintf(verbuf
, sizeof verbuf
, "%d.%d", PROTOCOL_VERSION
, SUBPROTOCOL_VERSION
);
269 json_line("protocol", verbuf
);
270 json_line("copyright", copyright
);
271 json_line("url", url
);
273 #if SUBPROTOCOL_VERSION != 0
274 char *subprotocol
= istring(".PR%d", SUBPROTOCOL_VERSION
);
276 char *subprotocol
= "";
278 rprintf(f
, "%s version %s protocol version %d%s\n",
279 RSYNC_NAME
, rsync_version(), PROTOCOL_VERSION
, subprotocol
);
280 rprintf(f
, "Copyright %s\n", copyright
);
281 rprintf(f
, "Web site: %s\n", url
);
286 init_checksum_choices();
288 output_nno_list(f
, "Checksum list", &valid_checksums
);
289 output_nno_list(f
, "Compress list", &valid_compressions
);
290 output_nno_list(f
, "Daemon auth list", &valid_auth_checksums
);
293 json_line("license", "GPLv3");
294 json_line("caveat", "rsync comes with ABSOLUTELY NO WARRANTY");
300 #ifdef MAINTAINER_MODE
301 rprintf(f
, "Panic Action: \"%s\"\n", get_panic_action());
305 rprintf(f
, "WARNING: no 64-bit integers on this platform!\n");
307 if (sizeof (int64
) != SIZEOF_INT64
) {
309 "WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
310 (int) SIZEOF_INT64
, (int) sizeof (int64
));
314 rprintf(f
,"rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n");
315 rprintf(f
,"are welcome to redistribute it under certain conditions. See the GNU\n");
316 rprintf(f
,"General Public Licence for details.\n");
319 void usage(enum logcode F
)
321 print_rsync_version(F
);
324 rprintf(F
,"rsync is a file transfer program capable of efficient remote update\n");
325 rprintf(F
,"via a fast differencing algorithm.\n");
328 rprintf(F
,"Usage: rsync [OPTION]... SRC [SRC]... DEST\n");
329 rprintf(F
," or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
330 rprintf(F
," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
331 rprintf(F
," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
332 rprintf(F
," or rsync [OPTION]... [USER@]HOST:SRC [DEST]\n");
333 rprintf(F
," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
334 rprintf(F
," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
335 rprintf(F
,"The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect\n");
336 rprintf(F
,"to an rsync daemon, and require SRC or DEST to start with a module name.\n");
338 rprintf(F
,"Options\n");
339 #include "help-rsync.h"
341 rprintf(F
,"Use \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
342 rprintf(F
,"Please see the rsync(1) and rsyncd.conf(5) manpages for full documentation.\n");
343 rprintf(F
,"See https://rsync.samba.org/ for updates, bug reports, and answers\n");
346 void daemon_usage(enum logcode F
)
348 print_rsync_version(F
);
351 rprintf(F
,"Usage: rsync --daemon [OPTION]...\n");
352 #include "help-rsyncd.h"
354 rprintf(F
,"If you were not trying to invoke rsync as a daemon, avoid using any of the\n");
355 rprintf(F
,"daemon-specific rsync options. See also the rsyncd.conf(5) manpage.\n");
358 const char *rsync_version(void)
366 return *ver
== 'v' ? ver
+1 : ver
;
369 const char *default_cvsignore(void)
371 return DEFAULT_CVSIGNORE
;