version 1.1.1.3, 2016/11/01 09:54:32
|
version 1.1.1.4, 2021/03/17 00:32:36
|
Line 3
|
Line 3
|
* |
* |
* Copyright (C) 1999 Weiss |
* Copyright (C) 1999 Weiss |
* Copyright (C) 2004 Chris Shoemaker |
* Copyright (C) 2004 Chris Shoemaker |
* Copyright (C) 2004-2015 Wayne Davison | * Copyright (C) 2004-2020 Wayne Davison |
* |
* |
* This program is free software; you can redistribute it and/or modify |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
Line 37 extern int always_checksum;
|
Line 37 extern int always_checksum;
|
extern int do_compression; |
extern int do_compression; |
extern int inplace; |
extern int inplace; |
extern int append_mode; |
extern int append_mode; |
|
extern int write_batch; |
extern int protocol_version; |
extern int protocol_version; |
|
extern int raw_argc, cooked_argc; |
|
extern char **raw_argv, **cooked_argv; |
extern char *batch_name; |
extern char *batch_name; |
#ifdef ICONV_OPTION |
#ifdef ICONV_OPTION |
extern char *iconv_opt; |
extern char *iconv_opt; |
Line 45 extern char *iconv_opt;
|
Line 48 extern char *iconv_opt;
|
|
|
extern filter_rule_list filter_list; |
extern filter_rule_list filter_list; |
|
|
|
int batch_fd = -1; |
|
int batch_sh_fd = -1; |
int batch_stream_flags; |
int batch_stream_flags; |
|
|
static int tweaked_append; |
static int tweaked_append; |
Line 156 void check_batch_flags(void)
|
Line 161 void check_batch_flags(void)
|
append_mode = 2; |
append_mode = 2; |
} |
} |
|
|
static int write_arg(int fd, char *arg) | static int write_arg(const char *arg) |
{ |
{ |
char *x, *s; | const char *x, *s; |
int len, ret = 0; | int len, err = 0; |
|
|
if (*arg == '-' && (x = strchr(arg, '=')) != NULL) { |
if (*arg == '-' && (x = strchr(arg, '=')) != NULL) { |
if (write(fd, arg, x - arg + 1) != x - arg + 1) | err |= write(batch_sh_fd, arg, x - arg + 1) != x - arg + 1; |
ret = -1; | |
arg += x - arg + 1; |
arg += x - arg + 1; |
} |
} |
|
|
if (strpbrk(arg, " \"'&;|[]()$#!*?^\\") != NULL) { |
if (strpbrk(arg, " \"'&;|[]()$#!*?^\\") != NULL) { |
if (write(fd, "'", 1) != 1) | err |= write(batch_sh_fd, "'", 1) != 1; |
ret = -1; | |
for (s = arg; (x = strchr(s, '\'')) != NULL; s = x + 1) { |
for (s = arg; (x = strchr(s, '\'')) != NULL; s = x + 1) { |
if (write(fd, s, x - s + 1) != x - s + 1 | err |= write(batch_sh_fd, s, x - s + 1) != x - s + 1; |
|| write(fd, "'", 1) != 1) | err |= write(batch_sh_fd, "'", 1) != 1; |
ret = -1; | |
} |
} |
len = strlen(s); |
len = strlen(s); |
if (write(fd, s, len) != len | err |= write(batch_sh_fd, s, len) != len; |
|| write(fd, "'", 1) != 1) | err |= write(batch_sh_fd, "'", 1) != 1; |
ret = -1; | return err; |
return ret; | |
} |
} |
|
|
len = strlen(arg); |
len = strlen(arg); |
if (write(fd, arg, len) != len) | err |= write(batch_sh_fd, arg, len) != len; |
ret = -1; | |
|
|
return ret; | return err; |
} |
} |
|
|
|
/* Writes out a space and then an option (or other string) with an optional "=" + arg suffix. */ |
|
static int write_opt(const char *opt, const char *arg) |
|
{ |
|
int len = strlen(opt); |
|
int err = write(batch_sh_fd, " ", 1) != 1; |
|
err = write(batch_sh_fd, opt, len) != len ? 1 : 0; |
|
if (arg) { |
|
err |= write(batch_sh_fd, "=", 1) != 1; |
|
err |= write_arg(arg); |
|
} |
|
return err; |
|
} |
|
|
static void write_filter_rules(int fd) |
static void write_filter_rules(int fd) |
{ |
{ |
filter_rule *ent; |
filter_rule *ent; |
Line 208 static void write_filter_rules(int fd)
|
Line 221 static void write_filter_rules(int fd)
|
write_sbuf(fd, "#E#"); |
write_sbuf(fd, "#E#"); |
} |
} |
|
|
|
/* This sets batch_fd and (for --write-batch) batch_sh_fd. */ |
|
void open_batch_files(void) |
|
{ |
|
if (write_batch) { |
|
char filename[MAXPATHLEN]; |
|
|
|
stringjoin(filename, sizeof filename, batch_name, ".sh", NULL); |
|
|
|
batch_sh_fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR); |
|
if (batch_sh_fd < 0) { |
|
rsyserr(FERROR, errno, "Batch file %s open error", full_fname(filename)); |
|
exit_cleanup(RERR_FILESELECT); |
|
} |
|
|
|
batch_fd = do_open(batch_name, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); |
|
} else if (strcmp(batch_name, "-") == 0) |
|
batch_fd = STDIN_FILENO; |
|
else |
|
batch_fd = do_open(batch_name, O_RDONLY, S_IRUSR | S_IWUSR); |
|
|
|
if (batch_fd < 0) { |
|
rsyserr(FERROR, errno, "Batch file %s open error", full_fname(batch_name)); |
|
exit_cleanup(RERR_FILEIO); |
|
} |
|
} |
|
|
/* This routine tries to write out an equivalent --read-batch command |
/* This routine tries to write out an equivalent --read-batch command |
* given the user's --write-batch args. However, it doesn't really |
* given the user's --write-batch args. However, it doesn't really |
* understand most of the options, so it uses some overly simple |
* understand most of the options, so it uses some overly simple |
* heuristics to munge the command line into something that will |
* heuristics to munge the command line into something that will |
* (hopefully) work. */ |
* (hopefully) work. */ |
void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt) | void write_batch_shell_file(void) |
{ |
{ |
int fd, i, len, err = 0; | int i, j, len, err = 0; |
char *p, filename[MAXPATHLEN]; | char *p, *p2; |
|
|
stringjoin(filename, sizeof filename, |
|
batch_name, ".sh", NULL); |
|
fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC, |
|
S_IRUSR | S_IWUSR | S_IXUSR); |
|
if (fd < 0) { |
|
rsyserr(FERROR, errno, "Batch file %s open error", |
|
filename); |
|
exit_cleanup(RERR_FILESELECT); |
|
} |
|
|
|
/* Write argvs info to BATCH.sh file */ |
/* Write argvs info to BATCH.sh file */ |
if (write_arg(fd, argv[0]) < 0) | err |= write_arg(raw_argv[0]); |
err = 1; | |
if (filter_list.head) { |
if (filter_list.head) { |
if (protocol_version >= 29) |
if (protocol_version >= 29) |
write_sbuf(fd, " --filter=._-"); | err |= write_opt("--filter", "._-"); |
else |
else |
write_sbuf(fd, " --exclude-from=-"); | err |= write_opt("--exclude-from", "-"); |
} |
} |
for (i = 1; i < argc - file_arg_cnt; i++) { | |
p = argv[i]; | /* Elide the filename args from the option list, but scan for them in reverse. */ |
| for (i = raw_argc-1, j = cooked_argc-1; i > 0 && j >= 0; i--) { |
| if (strcmp(raw_argv[i], cooked_argv[j]) == 0) { |
| raw_argv[i] = NULL; |
| j--; |
| } |
| } |
| |
| for (i = 1; i < raw_argc; i++) { |
| if (!(p = raw_argv[i])) |
| continue; |
if (strncmp(p, "--files-from", 12) == 0 |
if (strncmp(p, "--files-from", 12) == 0 |
|| strncmp(p, "--filter", 8) == 0 | || strncmp(p, "--filter", 8) == 0 |
|| strncmp(p, "--include", 9) == 0 | || strncmp(p, "--include", 9) == 0 |
|| strncmp(p, "--exclude", 9) == 0) { | || strncmp(p, "--exclude", 9) == 0) { |
if (strchr(p, '=') == NULL) |
if (strchr(p, '=') == NULL) |
i++; |
i++; |
continue; |
continue; |
Line 251 void write_batch_shell_file(int argc, char *argv[], in
|
Line 289 void write_batch_shell_file(int argc, char *argv[], in
|
i++; |
i++; |
continue; |
continue; |
} |
} |
if (write(fd, " ", 1) != 1) |
|
err = 1; |
|
if (strncmp(p, "--write-batch", len = 13) == 0 |
if (strncmp(p, "--write-batch", len = 13) == 0 |
|| strncmp(p, "--only-write-batch", len = 18) == 0) { | || strncmp(p, "--only-write-batch", len = 18) == 0) |
if (write(fd, "--read-batch", 12) != 12) | err |= write_opt("--read-batch", p[len] == '=' ? p + len + 1 : NULL); |
err = 1; | else { |
if (p[len] == '=') { | err |= write(batch_sh_fd, " ", 1) != 1; |
if (write(fd, "=", 1) != 1 | err |= write_arg(p); |
|| write_arg(fd, p + len + 1) < 0) | |
err = 1; | |
} | |
} else { | |
if (write_arg(fd, p) < 0) | |
err = 1; | |
} |
} |
} |
} |
if (!(p = check_for_hostspec(argv[argc - 1], &p, &i))) | if (!(p = check_for_hostspec(cooked_argv[cooked_argc - 1], &p2, &i))) |
p = argv[argc - 1]; | p = cooked_argv[cooked_argc - 1]; |
if (write(fd, " ${1:-", 6) != 6 | err |= write_opt("${1:-", NULL); |
|| write_arg(fd, p) < 0) | err |= write_arg(p); |
err = 1; | err |= write(batch_sh_fd, "}", 1) != 1; |
write_byte(fd, '}'); | |
if (filter_list.head) |
if (filter_list.head) |
write_filter_rules(fd); | write_filter_rules(batch_sh_fd); |
if (write(fd, "\n", 1) != 1 || close(fd) < 0 || err) { | if (write(batch_sh_fd, "\n", 1) != 1 || close(batch_sh_fd) < 0 || err) { |
rsyserr(FERROR, errno, "Batch file %s write error", | rsyserr(FERROR, errno, "Batch file %s.sh write error", batch_name); |
filename); | |
exit_cleanup(RERR_FILEIO); |
exit_cleanup(RERR_FILEIO); |
} |
} |
|
batch_sh_fd = -1; |
} |
} |