1 /* -*- c-file-style: "linux" -*-
4 Batch utilities for rsync.
15 extern int preserve_links
;
16 extern int preserve_hard_links
;
17 extern int preserve_devices
;
18 extern int preserve_uid
;
19 extern int preserve_gid
;
20 extern int always_checksum
;
21 extern int do_compression
;
22 extern int protocol_version
;
23 extern char *batch_name
;
25 extern struct filter_list_struct filter_list
;
27 static int *flag_ptr
[] = {
29 &preserve_uid
, /* 1 */
30 &preserve_gid
, /* 2 */
31 &preserve_links
, /* 3 */
32 &preserve_devices
, /* 4 */
33 &preserve_hard_links
, /* 5 */
34 &always_checksum
, /* 6 */
35 &xfer_dirs
, /* 7 (protocol 29) */
36 &do_compression
, /* 8 (protocol 29) */
40 static char *flag_name
[] = {
53 void write_stream_flags(int fd
)
57 /* Start the batch file with a bitmap of data-stream-affecting
59 if (protocol_version
< 29)
61 for (i
= 0, flags
= 0; flag_ptr
[i
]; i
++) {
68 void read_stream_flags(int fd
)
72 if (protocol_version
< 29)
74 for (i
= 0, flags
= read_int(fd
); flag_ptr
[i
]; i
++) {
75 int set
= flags
& (1 << i
) ? 1 : 0;
76 if (*flag_ptr
[i
] != set
) {
79 "%sing the %s option to match the batchfile.\n",
80 set
? "Sett" : "Clear", flag_name
[i
]);
85 if (protocol_version
< 29) {
88 else if (xfer_dirs
< 2)
93 static void write_arg(int fd
, char *arg
)
97 if (*arg
== '-' && (x
= strchr(arg
, '=')) != NULL
) {
98 write(fd
, arg
, x
- arg
+ 1);
102 if (strpbrk(arg
, " \"'&;|[]()$#!*?^\\") != NULL
) {
104 for (s
= arg
; (x
= strchr(s
, '\'')) != NULL
; s
= x
+ 1) {
105 write(fd
, s
, x
- s
+ 1);
108 write(fd
, s
, strlen(s
));
113 write(fd
, arg
, strlen(arg
));
116 static void write_filter_rules(int fd
)
118 struct filter_struct
*ent
;
120 write_sbuf(fd
, " <<'#E#'\n");
121 for (ent
= filter_list
.head
; ent
; ent
= ent
->next
) {
123 char *p
= get_rule_prefix(ent
->match_flags
, "- ", 0, &plen
);
124 write_buf(fd
, p
, plen
);
125 write_sbuf(fd
, ent
->pattern
);
126 if (ent
->match_flags
& MATCHFLG_DIRECTORY
)
128 write_byte(fd
, eol_nulls
? 0 : '\n');
131 write_sbuf(fd
, ";\n");
132 write_sbuf(fd
, "#E#");
135 /* This routine tries to write out an equivalent --read-batch command
136 * given the user's --write-batch args. However, it doesn't really
137 * understand most of the options, so it uses some overly simple
138 * heuristics to munge the command line into something that will
139 * (hopefully) work. */
140 void write_batch_shell_file(int argc
, char *argv
[], int file_arg_cnt
)
143 char *p
, filename
[MAXPATHLEN
];
145 stringjoin(filename
, sizeof filename
,
146 batch_name
, ".sh", NULL
);
147 fd
= do_open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
,
148 S_IRUSR
| S_IWUSR
| S_IEXEC
);
150 rsyserr(FERROR
, errno
, "Batch file %s open error",
151 safe_fname(filename
));
155 /* Write argvs info to BATCH.sh file */
156 write_arg(fd
, argv
[0]);
157 if (filter_list
.head
) {
158 if (protocol_version
>= 29)
159 write_sbuf(fd
, " --filter=._-");
161 write_sbuf(fd
, " --exclude-from=-");
163 for (i
= 1; i
< argc
- file_arg_cnt
; i
++) {
165 if (strncmp(p
, "--files-from", 12) == 0
166 || strncmp(p
, "--filter", 8) == 0
167 || strncmp(p
, "--include", 9) == 0
168 || strncmp(p
, "--exclude", 9) == 0) {
169 if (strchr(p
, '=') == NULL
)
173 if (strcmp(p
, "-f") == 0) {
178 if (strncmp(p
, "--write-batch", len
= 13) == 0
179 || strncmp(p
, "--only-write-batch", len
= 18) == 0) {
180 write(fd
, "--read-batch", 12);
183 write_arg(fd
, p
+ len
+ 1);
188 if (!(p
= check_for_hostspec(argv
[argc
- 1], &p
, &i
)))
190 write(fd
, " ${1:-", 6);
193 if (filter_list
.head
)
194 write_filter_rules(fd
);
195 if (write(fd
, "\n", 1) != 1 || close(fd
) < 0) {
196 rsyserr(FERROR
, errno
, "Batch file %s write error",
197 safe_fname(filename
));
202 void show_flist(int index
, struct file_struct
**fptr
)
204 /* for debugging show_flist(flist->count, flist->files * */
207 for (i
= 0; i
< index
; i
++) {
208 rprintf(FINFO
, "flist->flags=%#x\n", fptr
[i
]->flags
);
209 rprintf(FINFO
, "flist->modtime=%#lx\n",
210 (long unsigned) fptr
[i
]->modtime
);
211 rprintf(FINFO
, "flist->length=%.0f\n",
212 (double) fptr
[i
]->length
);
213 rprintf(FINFO
, "flist->mode=%#o\n", (int) fptr
[i
]->mode
);
214 rprintf(FINFO
, "flist->basename=%s\n",
215 safe_fname(fptr
[i
]->basename
));
216 if (fptr
[i
]->dirname
) {
217 rprintf(FINFO
, "flist->dirname=%s\n",
218 safe_fname(fptr
[i
]->dirname
));
220 if (am_sender
&& fptr
[i
]->dir
.root
) {
221 rprintf(FINFO
, "flist->dir.root=%s\n",
222 safe_fname(fptr
[i
]->dir
.root
));
228 void show_argvs(int argc
, char *argv
[])
232 rprintf(FINFO
, "BATCH.C:show_argvs,argc=%d\n", argc
);
233 for (i
= 0; i
< argc
; i
++)
234 rprintf(FINFO
, "i=%d,argv[i]=%s\n", i
, safe_fname(argv
[i
]));