00001
00002
00003
00004
00005
00006
00007
00008 #include "rsync.h"
00009 #include <time.h>
00010
00011 extern char *batch_prefix;
00012
00013 struct file_list *batch_flist;
00014
00015 static char rsync_flist_file[] = ".rsync_flist";
00016 static char rsync_csums_file[] = ".rsync_csums";
00017 static char rsync_delta_file[] = ".rsync_delta";
00018 static char rsync_argvs_file[] = ".rsync_argvs";
00019
00020 static int fdb;
00021 static int fdb_delta;
00022 static int fdb_open;
00023 static int fdb_close;
00024
00025 void write_batch_flist_file(char *buff, int bytes_to_write)
00026 {
00027 char filename[MAXPATHLEN];
00028
00029 if (fdb_open) {
00030
00031 strlcpy(filename, batch_prefix, sizeof(filename));
00032 strlcat(filename, rsync_flist_file, sizeof(filename));
00033
00034
00035
00036
00037
00038 fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
00039 S_IREAD | S_IWRITE);
00040 if (fdb == -1) {
00041 rprintf(FERROR, "Batch file %s open error: %s\n",
00042 filename, strerror(errno));
00043 close(fdb);
00044 exit_cleanup(1);
00045 }
00046 fdb_open = 0;
00047 }
00048
00049
00050
00051 if (write(fdb, buff, bytes_to_write) == -1) {
00052 rprintf(FERROR, "Batch file %s write error: %s\n",
00053 filename, strerror(errno));
00054 close(fdb);
00055 exit_cleanup(1);
00056 }
00057
00058 if (fdb_close) {
00059 close(fdb);
00060 }
00061 }
00062
00063 void write_batch_flist_info(int flist_count, struct file_struct **fptr)
00064 {
00065 int i;
00066 int bytes_to_write;
00067
00068
00069
00070 bytes_to_write =
00071 sizeof(unsigned) +
00072 sizeof(time_t) +
00073 sizeof(OFF_T) +
00074 sizeof(mode_t) +
00075 sizeof(INO64_T) +
00076 sizeof(DEV64_T) +
00077 sizeof(DEV64_T) +
00078 sizeof(uid_t) +
00079 sizeof(gid_t);
00080
00081 fdb_open = 1;
00082 fdb_close = 0;
00083
00084 for (i = 0; i < flist_count; i++) {
00085 write_batch_flist_file((char *) fptr[i], bytes_to_write);
00086 write_char_bufs(fptr[i]->basename);
00087 write_char_bufs(fptr[i]->dirname);
00088 write_char_bufs(fptr[i]->basedir);
00089 write_char_bufs(fptr[i]->link);
00090 if (i == flist_count - 1) {
00091 fdb_close = 1;
00092 }
00093 write_char_bufs(fptr[i]->sum);
00094 }
00095 }
00096
00097 void write_char_bufs(char *buf)
00098 {
00099
00100
00101 char b[4];
00102
00103 SIVAL(b, 0, buf != NULL ? strlen(buf) : 0);
00104
00105 write_batch_flist_file(b, sizeof(int));
00106
00107
00108
00109 if (buf != NULL) {
00110 write_batch_flist_file(buf, strlen(buf));
00111 }
00112 }
00113
00114 void write_batch_argvs_file(int argc, char *argv[])
00115 {
00116 int fdb;
00117 int i;
00118 char buff[256];
00119 char buff2[MAXPATHLEN + 6];
00120 char filename[MAXPATHLEN];
00121
00122
00123 strlcpy(filename, batch_prefix, sizeof(filename));
00124 strlcat(filename, rsync_argvs_file, sizeof(filename));
00125
00126
00127
00128
00129
00130 fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
00131 S_IREAD | S_IWRITE | S_IEXEC);
00132 if (fdb == -1) {
00133 rprintf(FERROR, "Batch file %s open error: %s\n",
00134 filename, strerror(errno));
00135 close(fdb);
00136 exit_cleanup(1);
00137 }
00138 buff[0] = '\0';
00139
00140
00141
00142 for (i = 0; i < argc; ++i) {
00143 if (i == argc - 2)
00144 continue;
00145
00146
00147
00148
00149 if (!strncmp(argv[i], "--write-batch",
00150 strlen("--write-batch"))) {
00151
00152
00153
00154
00155
00156 strlcat(buff, "--read-batch=", sizeof(buff));
00157 strlcat(buff, batch_prefix, sizeof(buff));
00158 } else
00159 if (i == argc - 1) {
00160 snprintf(buff2, sizeof(buff2), "${1:-%s}", argv[i]);
00161 strlcat(buff, buff2, sizeof(buff));
00162 }
00163 else {
00164 strlcat(buff, argv[i], sizeof(buff));
00165 }
00166
00167 if (i < (argc - 1)) {
00168 strlcat(buff, " ", sizeof(buff));
00169 }
00170 }
00171 strlcat(buff, "\n", sizeof(buff));
00172 if (!write(fdb, buff, strlen(buff))) {
00173 rprintf(FERROR, "Batch file %s write error: %s\n",
00174 filename, strerror(errno));
00175 close(fdb);
00176 exit_cleanup(1);
00177 }
00178 close(fdb);
00179 }
00180
00181 struct file_list *create_flist_from_batch(void)
00182 {
00183 unsigned char flags;
00184
00185 fdb_open = 1;
00186 fdb_close = 0;
00187
00188 batch_flist = (struct file_list *) malloc(sizeof(batch_flist[0]));
00189 if (!batch_flist) {
00190 out_of_memory("create_flist_from_batch");
00191 }
00192 batch_flist->count = 0;
00193 batch_flist->malloced = 1000;
00194 batch_flist->files =
00195 (struct file_struct **) malloc(sizeof(batch_flist->files[0]) *
00196 batch_flist->malloced);
00197 if (!batch_flist->files) {
00198 out_of_memory("create_flist_from_batch");
00199 }
00200
00201 for (flags = read_batch_flags(); flags; flags = read_batch_flags()) {
00202
00203 int i = batch_flist->count;
00204
00205 if (i >= batch_flist->malloced) {
00206 if (batch_flist->malloced < 1000)
00207 batch_flist->malloced += 1000;
00208 else
00209 batch_flist->malloced *= 2;
00210 batch_flist->files =
00211 (struct file_struct **) realloc(batch_flist->
00212 files,
00213 sizeof
00214 (batch_flist->
00215 files[0]) *
00216 batch_flist->
00217 malloced);
00218 if (!batch_flist->files)
00219 out_of_memory("create_flist_from_batch");
00220 }
00221 read_batch_flist_info(&batch_flist->files[i]);
00222 batch_flist->files[i]->flags = flags;
00223
00224 batch_flist->count++;
00225 }
00226
00227 return batch_flist;
00228 }
00229
00230 int read_batch_flist_file(char *buff, int len)
00231 {
00232 int bytes_read;
00233 char filename[MAXPATHLEN];
00234
00235 if (fdb_open) {
00236
00237 strlcpy(filename, batch_prefix, sizeof(filename));
00238 strlcat(filename, rsync_flist_file, sizeof(filename));
00239
00240
00241 fdb = do_open(filename, O_RDONLY, 0);
00242 if (fdb == -1) {
00243 rprintf(FERROR, "Batch file %s open error: %s\n",
00244 filename, strerror(errno));
00245 close(fdb);
00246 exit_cleanup(1);
00247 }
00248 fdb_open = 0;
00249 }
00250
00251
00252
00253 switch (bytes_read = read(fdb, buff, len)) {
00254 case -1:
00255 rprintf(FERROR, "Batch file %s read error: %s\n",
00256 filename, strerror(errno));
00257 close(fdb);
00258 exit_cleanup(1);
00259 break;
00260 case 0:
00261 close(fdb);
00262 }
00263
00264 return bytes_read;
00265 }
00266
00267 unsigned char read_batch_flags()
00268 {
00269 int flags;
00270
00271 if (read_batch_flist_file((char *) &flags, 4)) {
00272 return 1;
00273 } else {
00274 return 0;
00275 }
00276 }
00277
00278 void read_batch_flist_info(struct file_struct **fptr)
00279 {
00280 int int_str_len;
00281 char char_str_len[4];
00282 char buff[256];
00283 struct file_struct *file;
00284
00285 file = (struct file_struct *) malloc(sizeof(*file));
00286 if (!file)
00287 out_of_memory("read_batch_flist_info");
00288 memset((char *) file, 0, sizeof(*file));
00289
00290 *fptr = file;
00291
00292
00293
00294
00295
00296 read_batch_flist_file((char *) &file->modtime, sizeof(time_t));
00297 read_batch_flist_file((char *) &file->length, sizeof(OFF_T));
00298 read_batch_flist_file((char *) &file->mode, sizeof(mode_t));
00299 read_batch_flist_file((char *) &file->inode, sizeof(INO64_T));
00300 read_batch_flist_file((char *) &file->dev, sizeof(DEV64_T));
00301 read_batch_flist_file((char *) &file->rdev, sizeof(DEV64_T));
00302 read_batch_flist_file((char *) &file->uid, sizeof(uid_t));
00303 read_batch_flist_file((char *) &file->gid, sizeof(gid_t));
00304 read_batch_flist_file(char_str_len, sizeof(char_str_len));
00305 int_str_len = IVAL(char_str_len, 0);
00306 if (int_str_len > 0) {
00307 read_batch_flist_file(buff, int_str_len);
00308 buff[int_str_len] = '\0';
00309 file->basename = strdup(buff);
00310 } else {
00311 file->basename = NULL;
00312 }
00313
00314 read_batch_flist_file(char_str_len, sizeof(char_str_len));
00315 int_str_len = IVAL(char_str_len, 0);
00316 if (int_str_len > 0) {
00317 read_batch_flist_file(buff, int_str_len);
00318 buff[int_str_len] = '\0';
00319 file[0].dirname = strdup(buff);
00320 } else {
00321 file[0].dirname = NULL;
00322 }
00323
00324 read_batch_flist_file(char_str_len, sizeof(char_str_len));
00325 int_str_len = IVAL(char_str_len, 0);
00326 if (int_str_len > 0) {
00327 read_batch_flist_file(buff, int_str_len);
00328 buff[int_str_len] = '\0';
00329 file[0].basedir = strdup(buff);
00330 } else {
00331 file[0].basedir = NULL;
00332 }
00333
00334 read_batch_flist_file(char_str_len, sizeof(char_str_len));
00335 int_str_len = IVAL(char_str_len, 0);
00336 if (int_str_len > 0) {
00337 read_batch_flist_file(buff, int_str_len);
00338 buff[int_str_len] = '\0';
00339 file[0].link = strdup(buff);
00340 } else {
00341 file[0].link = NULL;
00342 }
00343
00344 read_batch_flist_file(char_str_len, sizeof(char_str_len));
00345 int_str_len = IVAL(char_str_len, 0);
00346 if (int_str_len > 0) {
00347 read_batch_flist_file(buff, int_str_len);
00348 buff[int_str_len] = '\0';
00349 file[0].sum = strdup(buff);
00350 } else {
00351 file[0].sum = NULL;
00352 }
00353 }
00354
00355 void write_batch_csums_file(void *buff, int bytes_to_write)
00356 {
00357 static int fdb_open = 1;
00358 char filename[MAXPATHLEN];
00359
00360 if (fdb_open) {
00361
00362 strlcpy(filename, batch_prefix, sizeof(filename));
00363 strlcat(filename, rsync_csums_file, sizeof(filename));
00364
00365
00366
00367
00368
00369 fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
00370 S_IREAD | S_IWRITE);
00371 if (fdb == -1) {
00372 rprintf(FERROR, "Batch file %s open error: %s\n",
00373 filename, strerror(errno));
00374 close(fdb);
00375 exit_cleanup(1);
00376 }
00377 fdb_open = 0;
00378 }
00379
00380
00381
00382 if (write(fdb, buff, bytes_to_write) == -1) {
00383 rprintf(FERROR, "Batch file %s write error: %s\n",
00384 filename, strerror(errno));
00385 close(fdb);
00386 exit_cleanup(1);
00387 }
00388 }
00389
00390 void close_batch_csums_file(void)
00391 {
00392 close(fdb);
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 void write_batch_csum_info(int *flist_entry, int flist_count,
00405 struct sum_struct *s)
00406 {
00407 size_t i;
00408 int int_count;
00409 extern int csum_length;
00410
00411 fdb_open = 1;
00412
00413 write_batch_csums_file(flist_entry, sizeof(int));
00414 int_count = s ? (int) s->count : 0;
00415 write_batch_csums_file(&int_count, sizeof int_count);
00416
00417 if (s) {
00418 for (i = 0; i < s->count; i++) {
00419 write_batch_csums_file(&s->sums[i].sum1, sizeof(uint32));
00420 if ((*flist_entry == flist_count - 1)
00421 && (i == s->count - 1)) {
00422 fdb_close = 1;
00423 }
00424 write_batch_csums_file(s->sums[i].sum2, csum_length);
00425 }
00426 }
00427 }
00428
00429 int read_batch_csums_file(char *buff, int len)
00430 {
00431 static int fdb_open = 1;
00432 int bytes_read;
00433 char filename[MAXPATHLEN];
00434
00435 if (fdb_open) {
00436
00437 strlcpy(filename, batch_prefix, sizeof(filename));
00438 strlcat(filename, rsync_csums_file, sizeof(filename));
00439
00440
00441 fdb = do_open(filename, O_RDONLY, 0);
00442 if (fdb == -1) {
00443 rprintf(FERROR, "Batch file %s open error: %s\n",
00444 filename, strerror(errno));
00445 close(fdb);
00446 exit_cleanup(1);
00447 }
00448 fdb_open = 0;
00449 }
00450
00451
00452
00453 bytes_read = read(fdb, buff, len);
00454
00455 if (bytes_read == -1) {
00456 rprintf(FERROR, "Batch file %s read error: %s\n",
00457 filename, strerror(errno));
00458 close(fdb);
00459 exit_cleanup(1);
00460 }
00461
00462 return bytes_read;
00463 }
00464
00465 void read_batch_csum_info(int flist_entry, struct sum_struct *s,
00466 int *checksums_match)
00467 {
00468 int i;
00469 int file_flist_entry;
00470 int file_chunk_ct;
00471 uint32 file_sum1;
00472 char file_sum2[SUM_LENGTH];
00473 extern int csum_length;
00474
00475 read_batch_csums_file((char *) &file_flist_entry, sizeof(int));
00476 if (file_flist_entry != flist_entry) {
00477 rprintf(FINFO, "file_flist_entry (%d) != flist_entry (%d)\n",
00478 file_flist_entry, flist_entry);
00479 close(fdb);
00480 exit_cleanup(1);
00481
00482 } else {
00483 read_batch_csums_file((char *) &file_chunk_ct,
00484 sizeof(int));
00485 *checksums_match = 1;
00486 for (i = 0; i < file_chunk_ct; i++) {
00487
00488 read_batch_csums_file((char *) &file_sum1,
00489 sizeof(uint32));
00490 read_batch_csums_file(file_sum2, csum_length);
00491
00492 if ((s->sums[i].sum1 != file_sum1) ||
00493 (memcmp(s->sums[i].sum2, file_sum2, csum_length)
00494 != 0)) {
00495 *checksums_match = 0;
00496 }
00497 }
00498 }
00499 }
00500
00501 void write_batch_delta_file(char *buff, int bytes_to_write)
00502 {
00503 static int fdb_delta_open = 1;
00504 char filename[MAXPATHLEN];
00505
00506 if (fdb_delta_open) {
00507
00508 strlcpy(filename, batch_prefix, sizeof(filename));
00509 strlcat(filename, rsync_delta_file, sizeof(filename));
00510
00511
00512
00513
00514
00515 fdb_delta = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
00516 S_IREAD | S_IWRITE);
00517 if (fdb_delta == -1) {
00518 rprintf(FERROR, "Batch file %s open error: %s\n",
00519 filename, strerror(errno));
00520 close(fdb_delta);
00521 exit_cleanup(1);
00522 }
00523 fdb_delta_open = 0;
00524 }
00525
00526
00527
00528 if (write(fdb_delta, buff, bytes_to_write) == -1) {
00529 rprintf(FERROR, "Batch file %s write error: %s\n",
00530 filename, strerror(errno));
00531 close(fdb_delta);
00532 exit_cleanup(1);
00533 }
00534 }
00535
00536 void close_batch_delta_file(void)
00537 {
00538 close(fdb_delta);
00539 }
00540
00541 int read_batch_delta_file(char *buff, int len)
00542 {
00543 static int fdb_delta_open = 1;
00544 int bytes_read;
00545 char filename[MAXPATHLEN];
00546
00547 if (fdb_delta_open) {
00548
00549 strlcpy(filename, batch_prefix, sizeof(filename));
00550 strlcat(filename, rsync_delta_file, sizeof(filename));
00551
00552
00553 fdb_delta = do_open(filename, O_RDONLY, 0);
00554 if (fdb_delta == -1) {
00555 rprintf(FERROR, "Batch file %s open error: %s\n",
00556 filename, strerror(errno));
00557 close(fdb_delta);
00558 exit_cleanup(1);
00559 }
00560 fdb_delta_open = 0;
00561 }
00562
00563
00564
00565 bytes_read = read(fdb_delta, buff, len);
00566
00567 if (bytes_read == -1) {
00568 rprintf(FERROR, "Batch file %s read error: %s\n",
00569 filename, strerror(errno));
00570 close(fdb_delta);
00571 exit_cleanup(1);
00572 }
00573
00574 return bytes_read;
00575 }
00576
00577 void show_flist(int index, struct file_struct **fptr)
00578 {
00579
00580
00581 int i;
00582 for (i = 0; i < index; i++) {
00583 rprintf(FINFO, "flist->flags=%#x\n", fptr[i]->flags);
00584 rprintf(FINFO, "flist->modtime=%#lx\n",
00585 (long unsigned) fptr[i]->modtime);
00586 rprintf(FINFO, "flist->length=%.0f\n",
00587 (double) fptr[i]->length);
00588 rprintf(FINFO, "flist->mode=%#o\n", (int) fptr[i]->mode);
00589 rprintf(FINFO, "flist->basename=%s\n", fptr[i]->basename);
00590 if (fptr[i]->dirname)
00591 rprintf(FINFO, "flist->dirname=%s\n",
00592 fptr[i]->dirname);
00593 if (fptr[i]->basedir)
00594 rprintf(FINFO, "flist->basedir=%s\n",
00595 fptr[i]->basedir);
00596 }
00597 }
00598
00599 void show_argvs(int argc, char *argv[])
00600 {
00601
00602
00603 int i;
00604 rprintf(FINFO, "BATCH.C:show_argvs,argc=%d\n", argc);
00605 for (i = 0; i < argc; i++) {
00606
00607 rprintf(FINFO, "i=%d,argv[i]=%s\n", i, argv[i]);
00608
00609 }
00610 }