Commit | Line | Data |
---|---|---|
08a740ff | 1 | /* -*- c-file-style: "linux" -*- |
71020fc3 | 2 | |
6902ed17 | 3 | Weiss 1/1999 |
08a740ff | 4 | Batch utilities for rsync. |
6902ed17 | 5 | |
1cd5beeb | 6 | */ |
6902ed17 MP |
7 | |
8 | #include "rsync.h" | |
9 | #include <time.h> | |
10 | ||
088aac85 | 11 | extern char *batch_prefix; |
e8d3168e WD |
12 | extern int csum_length; |
13 | extern int protocol_version; | |
14 | extern struct stats stats; | |
6902ed17 MP |
15 | |
16 | struct file_list *batch_flist; | |
17 | ||
088aac85 DD |
18 | static char rsync_flist_file[] = ".rsync_flist"; |
19 | static char rsync_csums_file[] = ".rsync_csums"; | |
20 | static char rsync_delta_file[] = ".rsync_delta"; | |
21 | static char rsync_argvs_file[] = ".rsync_argvs"; | |
6902ed17 | 22 | |
e8d3168e WD |
23 | static int f_csums = -1; |
24 | static int f_delta = -1; | |
6902ed17 | 25 | |
e8d3168e | 26 | void write_batch_flist_info(int flist_count, struct file_struct **files) |
6902ed17 | 27 | { |
088aac85 | 28 | char filename[MAXPATHLEN]; |
e8d3168e WD |
29 | int i, f, save_pv; |
30 | int64 save_written; | |
6902ed17 | 31 | |
893c4cc0 | 32 | stringjoin(filename, sizeof filename, |
71020fc3 | 33 | batch_prefix, rsync_flist_file, NULL); |
1cd5beeb | 34 | |
7e5cb909 | 35 | f = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); |
e8d3168e | 36 | if (f < 0) { |
d62bcc17 | 37 | rsyserr(FERROR, errno, "Batch file %s open error", filename); |
1cd5beeb MP |
38 | exit_cleanup(1); |
39 | } | |
40 | ||
e8d3168e WD |
41 | save_written = stats.total_written; |
42 | save_pv = protocol_version; | |
43 | protocol_version = PROTOCOL_VERSION; | |
44 | write_int(f, protocol_version); | |
45 | write_int(f, flist_count); | |
088aac85 | 46 | |
a5342644 | 47 | for (i = 0; i < flist_count; i++) { |
71020fc3 S |
48 | send_file_entry(files[i], f, |
49 | files[i]->flags & FLAG_TOP_DIR ? XMIT_TOP_DIR : 0); | |
a5342644 | 50 | } |
e8d3168e | 51 | send_file_entry(NULL, f, 0); |
6902ed17 | 52 | |
e8d3168e WD |
53 | protocol_version = save_pv; |
54 | stats.total_written = save_written; | |
6902ed17 | 55 | |
e8d3168e | 56 | close(f); |
6902ed17 MP |
57 | } |
58 | ||
e8d3168e | 59 | |
76f79ba7 | 60 | void write_batch_argvs_file(int argc, char *argv[]) |
6902ed17 | 61 | { |
01966df4 | 62 | int fd, i; |
088aac85 DD |
63 | char filename[MAXPATHLEN]; |
64 | ||
893c4cc0 | 65 | stringjoin(filename, sizeof filename, |
01966df4 WD |
66 | batch_prefix, rsync_argvs_file, NULL); |
67 | fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC, | |
68 | S_IRUSR | S_IWUSR | S_IEXEC); | |
69 | if (fd < 0) { | |
d62bcc17 | 70 | rsyserr(FERROR, errno, "Batch file %s open error", filename); |
1cd5beeb MP |
71 | exit_cleanup(1); |
72 | } | |
088aac85 | 73 | |
01966df4 WD |
74 | /* Write argvs info to BATCH.rsync_argvs file */ |
75 | for (i = 0; i < argc; i++) { | |
088aac85 | 76 | if (i == argc - 2) /* Skip source directory on cmdline */ |
71020fc3 | 77 | continue; |
01966df4 WD |
78 | if (i != 0) |
79 | write(fd, " ", 1); | |
80 | if (!strncmp(argv[i], "--write-batch=", 14)) { | |
81 | write(fd, "--read-batch=", 13); | |
82 | write(fd, batch_prefix, strlen(batch_prefix)); | |
83 | } else if (i == argc - 1) { | |
84 | char *p = find_colon(argv[i]); | |
85 | if (p) { | |
86 | if (*++p == ':') | |
87 | p++; | |
88 | } else | |
89 | p = argv[i]; | |
90 | write(fd, "${1:-", 5); | |
91 | write(fd, p, strlen(p)); | |
92 | write(fd, "}", 1); | |
088aac85 | 93 | } else |
01966df4 | 94 | write(fd, argv[i], strlen(argv[i])); |
1cd5beeb | 95 | } |
01966df4 | 96 | if (write(fd, "\n", 1) != 1 || close(fd) < 0) { |
d62bcc17 | 97 | rsyserr(FERROR, errno, "Batch file %s write error", filename); |
1cd5beeb MP |
98 | exit_cleanup(1); |
99 | } | |
6902ed17 MP |
100 | } |
101 | ||
088aac85 | 102 | struct file_list *create_flist_from_batch(void) |
6902ed17 | 103 | { |
088aac85 | 104 | char filename[MAXPATHLEN]; |
e8d3168e WD |
105 | unsigned short flags; |
106 | int i, f, save_pv; | |
107 | int64 save_read; | |
1cd5beeb | 108 | |
893c4cc0 | 109 | stringjoin(filename, sizeof filename, |
71020fc3 | 110 | batch_prefix, rsync_flist_file, NULL); |
1cd5beeb | 111 | |
e8d3168e WD |
112 | f = do_open(filename, O_RDONLY, 0); |
113 | if (f < 0) { | |
d62bcc17 | 114 | rsyserr(FERROR, errno, "Batch file %s open error", filename); |
1cd5beeb | 115 | exit_cleanup(1); |
1cd5beeb | 116 | } |
088aac85 | 117 | |
9935066b | 118 | batch_flist = flist_new(WITH_HLINK, "create_flist_from_batch"); |
6902ed17 | 119 | |
e8d3168e WD |
120 | save_read = stats.total_read; |
121 | save_pv = protocol_version; | |
122 | protocol_version = read_int(f); | |
1cd5beeb | 123 | |
a85906c7 S |
124 | batch_flist->count = read_int(f); |
125 | flist_expand(batch_flist); | |
1cd5beeb | 126 | |
e8d3168e | 127 | for (i = 0; (flags = read_byte(f)) != 0; i++) { |
a5342644 | 128 | if (protocol_version >= 28 && (flags & XMIT_EXTENDED_FLAGS)) |
e8d3168e | 129 | flags |= read_byte(f) << 8; |
9935066b | 130 | receive_file_entry(&batch_flist->files[i], flags, batch_flist, f); |
1cd5beeb | 131 | } |
9935066b | 132 | receive_file_entry(NULL, 0, NULL, 0); /* Signal that we're done. */ |
1cd5beeb | 133 | |
e8d3168e WD |
134 | protocol_version = save_pv; |
135 | stats.total_read = save_read; | |
1cd5beeb | 136 | |
e8d3168e | 137 | return batch_flist; |
6902ed17 MP |
138 | } |
139 | ||
55d9e0fa | 140 | void write_batch_csums_file(void *buff, int bytes_to_write) |
6902ed17 | 141 | { |
e8d3168e | 142 | if (write(f_csums, buff, bytes_to_write) < 0) { |
d62bcc17 | 143 | rsyserr(FERROR, errno, "Batch file write error"); |
e8d3168e | 144 | close(f_csums); |
1cd5beeb MP |
145 | exit_cleanup(1); |
146 | } | |
6902ed17 MP |
147 | } |
148 | ||
088aac85 | 149 | void close_batch_csums_file(void) |
6902ed17 | 150 | { |
e8d3168e WD |
151 | close(f_csums); |
152 | f_csums = -1; | |
6902ed17 MP |
153 | } |
154 | ||
f8f4c862 MP |
155 | |
156 | /** | |
71020fc3 | 157 | * Write csum info to batch file |
f8f4c862 MP |
158 | * |
159 | * @todo This will break if s->count is ever larger than maxint. The | |
160 | * batch code should probably be changed to consistently use the | |
161 | * variable-length integer routines, which is probably a compatible | |
162 | * change. | |
163 | **/ | |
e8d3168e | 164 | void write_batch_csum_info(int *flist_entry, struct sum_struct *s) |
6902ed17 | 165 | { |
5664871e | 166 | size_t i; |
1bc209b4 | 167 | int int_count; |
03979352 WD |
168 | char filename[MAXPATHLEN]; |
169 | ||
170 | if (f_csums < 0) { | |
893c4cc0 | 171 | stringjoin(filename, sizeof filename, |
71020fc3 | 172 | batch_prefix, rsync_csums_file, NULL); |
03979352 WD |
173 | |
174 | f_csums = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC, | |
7e5cb909 | 175 | S_IRUSR | S_IWUSR); |
03979352 | 176 | if (f_csums < 0) { |
d62bcc17 WD |
177 | rsyserr(FERROR, errno, "Batch file %s open error", |
178 | filename); | |
03979352 WD |
179 | close(f_csums); |
180 | exit_cleanup(1); | |
181 | } | |
182 | } | |
1cd5beeb | 183 | |
71020fc3 | 184 | write_batch_csums_file(flist_entry, sizeof (int)); |
1bc209b4 MP |
185 | int_count = s ? (int) s->count : 0; |
186 | write_batch_csums_file(&int_count, sizeof int_count); | |
71020fc3 | 187 | |
1cd5beeb MP |
188 | if (s) { |
189 | for (i = 0; i < s->count; i++) { | |
71020fc3 S |
190 | write_batch_csums_file(&s->sums[i].sum1, |
191 | sizeof (uint32)); | |
088aac85 | 192 | write_batch_csums_file(s->sums[i].sum2, csum_length); |
1cd5beeb MP |
193 | } |
194 | } | |
6902ed17 MP |
195 | } |
196 | ||
197 | int read_batch_csums_file(char *buff, int len) | |
198 | { | |
1cd5beeb | 199 | int bytes_read; |
1cd5beeb | 200 | |
03979352 | 201 | if ((bytes_read = read(f_csums, buff, len)) < 0) { |
d62bcc17 | 202 | rsyserr(FERROR, errno, "Batch file read error"); |
e8d3168e | 203 | close(f_csums); |
1cd5beeb MP |
204 | exit_cleanup(1); |
205 | } | |
206 | return bytes_read; | |
6902ed17 MP |
207 | } |
208 | ||
1cd5beeb MP |
209 | void read_batch_csum_info(int flist_entry, struct sum_struct *s, |
210 | int *checksums_match) | |
6902ed17 | 211 | { |
1cd5beeb MP |
212 | int i; |
213 | int file_flist_entry; | |
214 | int file_chunk_ct; | |
215 | uint32 file_sum1; | |
216 | char file_sum2[SUM_LENGTH]; | |
03979352 WD |
217 | char filename[MAXPATHLEN]; |
218 | ||
219 | if (f_csums < 0) { | |
893c4cc0 | 220 | stringjoin(filename, sizeof filename, |
71020fc3 | 221 | batch_prefix, rsync_csums_file, NULL); |
03979352 WD |
222 | |
223 | f_csums = do_open(filename, O_RDONLY, 0); | |
224 | if (f_csums < 0) { | |
d62bcc17 WD |
225 | rsyserr(FERROR, errno, "Batch file %s open error", |
226 | filename); | |
03979352 WD |
227 | close(f_csums); |
228 | exit_cleanup(1); | |
229 | } | |
230 | } | |
1cd5beeb | 231 | |
71020fc3 | 232 | read_batch_csums_file((char *) &file_flist_entry, sizeof (int)); |
1cd5beeb | 233 | if (file_flist_entry != flist_entry) { |
088aac85 | 234 | rprintf(FINFO, "file_flist_entry (%d) != flist_entry (%d)\n", |
71020fc3 | 235 | file_flist_entry, flist_entry); |
e8d3168e | 236 | close(f_csums); |
1cd5beeb MP |
237 | exit_cleanup(1); |
238 | ||
239 | } else { | |
71020fc3 | 240 | read_batch_csums_file((char *) &file_chunk_ct, sizeof (int)); |
1cd5beeb MP |
241 | *checksums_match = 1; |
242 | for (i = 0; i < file_chunk_ct; i++) { | |
1cd5beeb | 243 | read_batch_csums_file((char *) &file_sum1, |
71020fc3 | 244 | sizeof (uint32)); |
1cd5beeb MP |
245 | read_batch_csums_file(file_sum2, csum_length); |
246 | ||
71020fc3 S |
247 | if ((s->sums[i].sum1 != file_sum1) |
248 | || memcmp(s->sums[i].sum2, file_sum2, csum_length)) | |
1cd5beeb | 249 | *checksums_match = 0; |
1cd5beeb MP |
250 | } /* end for */ |
251 | } | |
6902ed17 MP |
252 | } |
253 | ||
254 | void write_batch_delta_file(char *buff, int bytes_to_write) | |
255 | { | |
088aac85 | 256 | char filename[MAXPATHLEN]; |
1cd5beeb | 257 | |
e8d3168e | 258 | if (f_delta < 0) { |
893c4cc0 | 259 | stringjoin(filename, sizeof filename, |
71020fc3 | 260 | batch_prefix, rsync_delta_file, NULL); |
1cd5beeb | 261 | |
e8d3168e | 262 | f_delta = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC, |
7e5cb909 | 263 | S_IRUSR | S_IWUSR); |
e8d3168e | 264 | if (f_delta < 0) { |
d62bcc17 WD |
265 | rsyserr(FERROR, errno, "Batch file %s open error", |
266 | filename); | |
1cd5beeb MP |
267 | exit_cleanup(1); |
268 | } | |
1cd5beeb MP |
269 | } |
270 | ||
e8d3168e | 271 | if (write(f_delta, buff, bytes_to_write) < 0) { |
d62bcc17 | 272 | rsyserr(FERROR, errno, "Batch file %s write error", filename); |
e8d3168e | 273 | close(f_delta); |
1cd5beeb MP |
274 | exit_cleanup(1); |
275 | } | |
6902ed17 | 276 | } |
088aac85 DD |
277 | |
278 | void close_batch_delta_file(void) | |
6902ed17 | 279 | { |
e8d3168e WD |
280 | close(f_delta); |
281 | f_delta = -1; | |
6902ed17 MP |
282 | } |
283 | ||
284 | int read_batch_delta_file(char *buff, int len) | |
285 | { | |
1cd5beeb | 286 | int bytes_read; |
088aac85 | 287 | char filename[MAXPATHLEN]; |
1cd5beeb | 288 | |
e8d3168e | 289 | if (f_delta < 0) { |
893c4cc0 | 290 | stringjoin(filename, sizeof filename, |
71020fc3 | 291 | batch_prefix, rsync_delta_file, NULL); |
1cd5beeb | 292 | |
e8d3168e WD |
293 | f_delta = do_open(filename, O_RDONLY, 0); |
294 | if (f_delta < 0) { | |
d62bcc17 WD |
295 | rsyserr(FERROR, errno, "Batch file %s open error", |
296 | filename); | |
e8d3168e | 297 | close(f_delta); |
1cd5beeb MP |
298 | exit_cleanup(1); |
299 | } | |
1cd5beeb MP |
300 | } |
301 | ||
e8d3168e WD |
302 | bytes_read = read(f_delta, buff, len); |
303 | if (bytes_read < 0) { | |
d62bcc17 | 304 | rsyserr(FERROR, errno, "Batch file %s read error", filename); |
e8d3168e | 305 | close(f_delta); |
1cd5beeb MP |
306 | exit_cleanup(1); |
307 | } | |
088aac85 | 308 | |
1cd5beeb | 309 | return bytes_read; |
6902ed17 MP |
310 | } |
311 | ||
6902ed17 MP |
312 | void show_flist(int index, struct file_struct **fptr) |
313 | { | |
1cd5beeb MP |
314 | /* for debugging show_flist(flist->count, flist->files * */ |
315 | ||
316 | int i; | |
317 | for (i = 0; i < index; i++) { | |
318 | rprintf(FINFO, "flist->flags=%#x\n", fptr[i]->flags); | |
319 | rprintf(FINFO, "flist->modtime=%#lx\n", | |
320 | (long unsigned) fptr[i]->modtime); | |
321 | rprintf(FINFO, "flist->length=%.0f\n", | |
322 | (double) fptr[i]->length); | |
323 | rprintf(FINFO, "flist->mode=%#o\n", (int) fptr[i]->mode); | |
324 | rprintf(FINFO, "flist->basename=%s\n", fptr[i]->basename); | |
325 | if (fptr[i]->dirname) | |
326 | rprintf(FINFO, "flist->dirname=%s\n", | |
327 | fptr[i]->dirname); | |
328 | if (fptr[i]->basedir) | |
329 | rprintf(FINFO, "flist->basedir=%s\n", | |
330 | fptr[i]->basedir); | |
331 | } | |
6902ed17 MP |
332 | } |
333 | ||
334 | void show_argvs(int argc, char *argv[]) | |
335 | { | |
1cd5beeb | 336 | /* for debugging * */ |
6902ed17 | 337 | |
1cd5beeb MP |
338 | int i; |
339 | rprintf(FINFO, "BATCH.C:show_argvs,argc=%d\n", argc); | |
340 | for (i = 0; i < argc; i++) { | |
341 | /* if (argv[i]) */ | |
342 | rprintf(FINFO, "i=%d,argv[i]=%s\n", i, argv[i]); | |
6902ed17 | 343 | |
1cd5beeb | 344 | } |
6902ed17 | 345 | } |