Line data Source code
1 : #include "../../burp.h"
2 : #include "../../alloc.h"
3 : #include "../../asfd.h"
4 : #include "../../async.h"
5 : #include "../../attribs.h"
6 : #include "../../cmd.h"
7 : #include "../../cntr.h"
8 : #include "../../conf.h"
9 : #include "../../conffile.h"
10 : #include "../../cstat.h"
11 : #include "../../fsops.h"
12 : #include "../../handy.h"
13 : #include "../../iobuf.h"
14 : #include "../../log.h"
15 : #include "../../sbuf.h"
16 : #include "../child.h"
17 : #include "../compress.h"
18 : #include "../resume.h"
19 : #include "blocklen.h"
20 : #include "dpth.h"
21 : #include "backup_phase2.h"
22 : #include "link.h"
23 :
24 : static size_t treepathlen=0;
25 :
26 0 : static int path_length_warn(struct iobuf *path, struct conf **cconfs)
27 : {
28 0 : if(get_int(cconfs[OPT_PATH_LENGTH_WARN]))
29 0 : logw(NULL, get_cntr(cconfs), "Path too long for tree - will save in data structure instead: %s\n", path->buf);
30 0 : return 1;
31 : }
32 :
33 4 : static int path_too_long(struct iobuf *path, struct conf **cconfs)
34 : {
35 : const char *cp;
36 : const char *cp1;
37 : size_t len;
38 :
39 4 : if(treepathlen+path->len+1>fs_full_path_max)
40 : {
41 : // FIX THIS:
42 : // Cannot warn down the asfd to the client, because it can
43 : // arrive after the client has disconnected, which causes
44 : // an error on the server side.
45 : // Would need to change the way that "backupphase2end" works
46 : // to be able to fix it.
47 0 : return path_length_warn(path, cconfs);
48 : }
49 : // We have to check every part in the path to ensure it less then fs_name_max
50 : // minimum windows case is c:/a, nix case is /
51 : // usual: c:/users, /home
52 4 : cp = strchr(path->buf, '/');
53 4 : if( !cp ) // very strange
54 0 : return strlen(path->buf) > fs_name_max ? path_length_warn(path, cconfs):0;
55 18 : while(cp && *cp)
56 : {
57 14 : cp++;
58 14 : cp1 = strchr(cp, '/');
59 14 : len = cp1? cp1-cp : strlen(cp);
60 14 : if( len > fs_name_max )
61 0 : return path_length_warn(path, cconfs);
62 : cp = cp1;
63 : }
64 : return 0;
65 : }
66 :
67 4 : static int treedata(struct sbuf *sb, struct conf **cconfs)
68 : {
69 : // Windows is sending directory data as if it is file data - this
70 : // cannot be saved in a tree structure.
71 4 : if(S_ISDIR(sb->statp.st_mode)) return 0;
72 :
73 8 : if(sb->path.cmd!=CMD_FILE
74 4 : && sb->path.cmd!=CMD_ENC_FILE
75 0 : && sb->path.cmd!=CMD_EFS_FILE)
76 : return 0;
77 :
78 4 : return !path_too_long(&sb->path, cconfs);
79 : }
80 :
81 4 : static char *set_new_datapth(struct sdirs *sdirs, struct conf **cconfs,
82 : struct sbuf *sb, struct dpth *dpth, int *istreedata)
83 : {
84 4 : char *tmp=NULL;
85 4 : char *rpath=NULL;
86 4 : if(get_int(cconfs[OPT_DIRECTORY_TREE]))
87 4 : *istreedata=treedata(sb, cconfs);
88 :
89 4 : if(*istreedata)
90 : {
91 : // We want to place this file in a directory structure like
92 : // the directory structure on the original client.
93 4 : if(!(tmp=prepend_s(TREE_DIR, sb->path.buf)))
94 : {
95 0 : log_out_of_memory(__func__);
96 : return NULL;
97 : }
98 : }
99 : else
100 : {
101 0 : if(!(tmp=strdup_w(dpth_protocol1_mk(dpth, sb->compression,
102 : sb->path.cmd), __func__))) return NULL;
103 : }
104 4 : iobuf_from_str(&sb->protocol1->datapth, CMD_DATAPTH, tmp);
105 4 : if(build_path(sdirs->datadirtmp,
106 4 : sb->protocol1->datapth.buf, &rpath, sdirs->datadirtmp))
107 : {
108 0 : logp("build path failed");
109 : return NULL;
110 : }
111 4 : return rpath;
112 : }
113 :
114 4 : static int start_to_receive_new_file(struct asfd *asfd,
115 : struct sdirs *sdirs, struct conf **cconfs,
116 : struct sbuf *sb, struct dpth *dpth)
117 : {
118 4 : int ret=-1;
119 4 : char *rpath=NULL;
120 4 : int istreedata=0;
121 :
122 : //logp("start to receive: %s\n", iobuf_to_printable(&sb->path));
123 :
124 4 : if(!(rpath=set_new_datapth(sdirs, cconfs, sb, dpth, &istreedata)))
125 : goto end;
126 :
127 4 : if(!(sb->protocol1->fzp=fzp_open(rpath, "wb")))
128 : {
129 0 : log_and_send(asfd, "make file failed");
130 0 : goto end;
131 : }
132 4 : if(!istreedata) dpth_incr(dpth);
133 : ret=0;
134 : end:
135 4 : free_w(&rpath);
136 4 : return ret;
137 : }
138 :
139 : enum processed_e
140 : {
141 : P_ERROR=-1,
142 : P_DONE_NEW=0,
143 : P_DONE_CHANGED=1,
144 : P_DONE_UNCHANGED=2,
145 : P_DONE_DELETED=3,
146 : P_NEW=4,
147 : P_CHANGED=5
148 : };
149 :
150 : #include <librsync.h>
151 :
152 2 : static enum processed_e process_changed_file(struct asfd *asfd,
153 : struct conf **cconfs,
154 : struct sbuf *cb, struct sbuf *p1b,
155 : const char *adir)
156 : {
157 2 : int ret=P_ERROR;
158 2 : size_t blocklen=0;
159 2 : char *curpath=NULL;
160 : //logp("need to process changed file: %s (%s)\n",
161 : // cb->path, cb->datapth);
162 :
163 : // Move datapth onto p1b.
164 2 : iobuf_move(&p1b->protocol1->datapth, &cb->protocol1->datapth);
165 :
166 2 : if(!(curpath=prepend_s(adir, p1b->protocol1->datapth.buf)))
167 : {
168 0 : log_out_of_memory(__func__);
169 : goto end;
170 : }
171 2 : if(dpth_protocol1_is_compressed(cb->compression, curpath))
172 0 : p1b->protocol1->sigfzp=fzp_gzopen(curpath, "rb");
173 : else
174 2 : p1b->protocol1->sigfzp=fzp_open(curpath, "rb");
175 2 : if(!p1b->protocol1->sigfzp)
176 : {
177 0 : logp("could not open %s: %s\n", curpath, strerror(errno));
178 : goto end;
179 : }
180 :
181 2 : blocklen=get_librsync_block_len(cb->endfile.buf);
182 4 : if(!(p1b->protocol1->sigjob=
183 2 : rs_sig_begin(blocklen, PROTO1_RS_STRONG_LEN
184 : #ifndef RS_DEFAULT_STRONG_LEN
185 : , rshash_to_magic_number(get_e_rshash(cconfs[OPT_RSHASH]))
186 : #endif
187 : )
188 : ))
189 : {
190 0 : logp("could not start signature job.\n");
191 : goto end;
192 : }
193 : //logp("sig begin: %s\n", iobuf_to_printable(7p1b->protocol1->datapth));
194 2 : if(!(p1b->protocol1->infb=rs_filebuf_new(NULL,
195 : p1b->protocol1->sigfzp,
196 : NULL, blocklen, -1)))
197 : {
198 0 : logp("could not rs_filebuf_new for infb.\n");
199 : goto end;
200 : }
201 2 : if(!(p1b->protocol1->outfb=rs_filebuf_new(NULL, NULL,
202 : asfd, ASYNC_BUF_LEN, -1)))
203 : {
204 0 : logp("could not rs_filebuf_new for in_outfb.\n");
205 : goto end;
206 : }
207 :
208 : // Flag the things that need to be sent (to the client)
209 2 : p1b->flags |= SBUF_SEND_DATAPTH;
210 2 : p1b->flags |= SBUF_SEND_STAT;
211 2 : p1b->flags |= SBUF_SEND_PATH;
212 :
213 : //logp("sending sig for %s\n", p1b->path);
214 : //logp("(%s)\n", p1b->datapth);
215 :
216 2 : ret=P_CHANGED;
217 : end:
218 2 : free_w(&curpath);
219 2 : return ret;
220 : }
221 :
222 68 : static enum processed_e new_non_file(struct sbuf *p1b,
223 : struct manio *ucmanio, struct conf **cconfs)
224 : {
225 : // Is something that does not need more data backed up.
226 : // Like a directory or a link or something like that.
227 : // Goes into the unchanged file, so that it does not end up out of
228 : // order with normal files, which has to wait around for their data
229 : // to turn up.
230 68 : if(manio_write_sbuf(ucmanio, p1b))
231 : return P_ERROR;
232 68 : cntr_add(get_cntr(cconfs), p1b->path.cmd, 0);
233 68 : return P_DONE_NEW;
234 : }
235 :
236 0 : static enum processed_e changed_non_file(struct sbuf *p1b,
237 : struct manio *ucmanio, enum cmd cmd, struct conf **cconfs)
238 : {
239 : // As new_non_file.
240 0 : if(manio_write_sbuf(ucmanio, p1b))
241 : return P_ERROR;
242 0 : cntr_add_changed(get_cntr(cconfs), cmd);
243 0 : return P_DONE_CHANGED;
244 : }
245 :
246 122 : static enum processed_e process_new(struct conf **cconfs,
247 : struct sbuf *p1b, struct manio *ucmanio)
248 : {
249 122 : if(sbuf_is_filedata(p1b)
250 68 : || sbuf_is_vssdata(p1b))
251 : {
252 : //logp("need to process new file: %s\n", p1b->path);
253 : // Flag the things that need to be sent (to the client)
254 54 : p1b->flags |= SBUF_SEND_STAT;
255 54 : p1b->flags |= SBUF_SEND_PATH;
256 54 : return P_NEW;
257 : }
258 68 : return new_non_file(p1b, ucmanio, cconfs);
259 : }
260 :
261 6 : static enum processed_e process_unchanged_file(struct sbuf *p1b, struct sbuf *cb,
262 : struct manio *ucmanio, struct conf **cconfs)
263 : {
264 : // Need to re-encode the p1b attribs to include compression and
265 : // other bits and pieces that are recorded on cb.
266 6 : iobuf_move(&p1b->protocol1->datapth, &cb->protocol1->datapth);
267 6 : iobuf_move(&p1b->endfile, &cb->endfile);
268 6 : p1b->protocol1->salt=cb->protocol1->salt;
269 6 : p1b->compression=cb->compression;
270 6 : p1b->encryption=cb->encryption;
271 : // Need to free attr so that it is reallocated, because it may get
272 : // longer than what the client told us in phase1.
273 6 : iobuf_free_content(&p1b->attr);
274 6 : if(attribs_encode(p1b))
275 : return P_ERROR;
276 6 : if(manio_write_sbuf(ucmanio, p1b))
277 : return P_ERROR;
278 6 : cntr_add_same(get_cntr(cconfs), p1b->path.cmd);
279 6 : if(p1b->endfile.buf) cntr_add_bytes(get_cntr(cconfs),
280 0 : strtoull(p1b->endfile.buf, NULL, 10));
281 : return P_DONE_UNCHANGED;
282 : }
283 :
284 10 : static int open_previous_manifest(struct manio **manio, struct sdirs *sdirs)
285 : {
286 : struct stat statp;
287 20 : if(!lstat(sdirs->cmanifest, &statp)
288 2 : && !(*manio=manio_open(sdirs->cmanifest, "rb", PROTO_1)))
289 : {
290 0 : logp("could not open old manifest %s\n", sdirs->cmanifest);
291 : return -1;
292 : }
293 : return 0;
294 : }
295 :
296 0 : static int get_hardlink_master_from_hmanio(
297 : struct manio **hmanio,
298 : struct sdirs *sdirs,
299 : struct sbuf *cb,
300 : struct sbuf *hb
301 : ) {
302 : int passes=0;
303 : while(1)
304 : {
305 0 : sbuf_free_content(hb);
306 0 : switch(manio_read(*hmanio, hb))
307 : {
308 : case 0: // Keep going.
309 : break;
310 : case 1: // Finished OK.
311 0 : manio_close(hmanio);
312 : // Might have already been part way down the
313 : // manifest when we started. If we get to the
314 : // end, go back to the beginning once.
315 0 : if(!passes)
316 : {
317 0 : if(open_previous_manifest(hmanio,
318 : sdirs)) return -1;
319 0 : passes++;
320 0 : continue;
321 : }
322 : return 0;
323 : default: // Error;
324 : return -1;
325 : }
326 0 : if(hb->path.cmd!=CMD_FILE
327 0 : && hb->path.cmd!=CMD_ENC_FILE)
328 0 : continue;
329 0 : if(!strcmp(hb->path.buf, cb->link.buf)
330 0 : && hb->protocol1->datapth.buf)
331 : return 1; // Found it.
332 : }
333 : return -1;
334 : }
335 :
336 0 : static int relink_deleted_hardlink_master(
337 : struct dpth *dpth,
338 : struct manio **hmanio,
339 : struct sdirs *sdirs,
340 : struct sbuf *p1b,
341 : struct sbuf *cb,
342 : struct conf **cconfs
343 : ) {
344 0 : int ret=-1;
345 0 : char *newdatapth_full=NULL;
346 0 : char *olddatapth_full=NULL;
347 0 : char *newdatapth=NULL;
348 0 : char *relinkpath_full=NULL;
349 : struct stat statp;
350 0 : struct sbuf *hb=NULL;
351 0 : int istreedata=0;
352 :
353 0 : if(!(hb=sbuf_alloc(PROTO_1)))
354 : goto end;
355 :
356 0 : switch(get_hardlink_master_from_hmanio(hmanio, sdirs, cb, hb))
357 : {
358 : case 0: // Did not find it.
359 : return 0;
360 : case 1: // Found it.
361 : break;
362 : default: // Error.
363 : goto end;
364 : }
365 :
366 : // Protect against the old file being encrypted, and the new file not
367 : // being encrypted - and vice versa.
368 0 : if(p1b->path.cmd!=hb->path.cmd)
369 : return 0;
370 :
371 0 : if(!(newdatapth_full=set_new_datapth(sdirs,
372 : cconfs, p1b, dpth, &istreedata)))
373 : goto end;
374 0 : if(!istreedata) dpth_incr(dpth);
375 0 : if(!(relinkpath_full=prepend_s(sdirs->relink,
376 0 : p1b->protocol1->datapth.buf)))
377 : goto end;
378 0 : if(!(newdatapth=strdup_w(p1b->protocol1->datapth.buf, __func__)))
379 : goto end;
380 : /*
381 : printf("newdatapth_full: %s\n", newdatapth_full);
382 : printf("relinkpath_full: %s\n", relinkpath_full);
383 : printf("newdatapth: %s\n", newdatapth);
384 : printf("hbdatapth: %s\n", iobuf_to_printable(&hb->protocol1->datapth));
385 : printf("sdirs->currentdata: %s\n", sdirs->currentdata);
386 : */
387 :
388 0 : if(!(olddatapth_full=prepend_s(sdirs->currentdata,
389 0 : hb->protocol1->datapth.buf)))
390 : goto end;
391 0 : if(lstat(olddatapth_full, &statp) || !S_ISREG(statp.st_mode))
392 : {
393 0 : logw(NULL, get_cntr(cconfs),
394 : "Did not find path for relink: %s\n", olddatapth_full);
395 0 : ret=0;
396 0 : goto end;
397 : }
398 0 : if(build_path_w(relinkpath_full))
399 : goto end;
400 0 : if(do_link(olddatapth_full, relinkpath_full,
401 : &statp, cconfs, /*overwrite*/0))
402 : goto end;
403 :
404 0 : iobuf_free_content(&cb->protocol1->datapth);
405 :
406 0 : iobuf_from_str(&hb->protocol1->datapth, CMD_DATAPTH,
407 0 : p1b->protocol1->datapth.buf);
408 0 : p1b->protocol1->datapth.buf=NULL;
409 0 : iobuf_from_str(&cb->protocol1->datapth, CMD_DATAPTH, newdatapth);
410 0 : newdatapth=NULL;
411 0 : iobuf_move(&cb->endfile, &hb->endfile);
412 :
413 0 : ret=1;
414 : end:
415 0 : free_w(&newdatapth_full);
416 0 : free_w(&olddatapth_full);
417 0 : free_w(&newdatapth);
418 0 : free_w(&relinkpath_full);
419 0 : sbuf_free(&hb);
420 0 : return ret;
421 : }
422 :
423 4 : static int librsync_enabled(struct sbuf *p1b,
424 : struct sbuf *cb,
425 : struct conf **cconfs)
426 : {
427 : off_t max_size;
428 4 : if(!get_int(cconfs[OPT_LIBRSYNC]))
429 : return 0;
430 4 : max_size=(off_t)get_uint64_t(cconfs[OPT_LIBRSYNC_MAX_SIZE]);
431 4 : if(!max_size)
432 : return 1;
433 0 : return max_size >= cb->statp.st_size && max_size >= p1b->statp.st_size;
434 : }
435 :
436 10 : static enum processed_e maybe_do_delta_stuff(struct asfd *asfd,
437 : struct dpth *dpth,
438 : struct sdirs *sdirs, struct sbuf *cb, struct sbuf *p1b,
439 : struct manio *ucmanio, struct manio **hmanio, struct conf **cconfs)
440 : {
441 10 : int oldcompressed=0;
442 10 : int compression=p1b->compression;
443 :
444 : // If the file type changed, I think it is time to back it up again
445 : // (for example, EFS changing to normal file, or back again).
446 10 : if(cb->path.cmd!=p1b->path.cmd)
447 : {
448 0 : if(hmanio && *hmanio
449 0 : && cb->path.cmd==CMD_HARD_LINK
450 0 : && (p1b->path.cmd==CMD_FILE
451 0 : || p1b->path.cmd==CMD_ENC_FILE))
452 : {
453 0 : struct stat *p1statp=&p1b->statp;
454 0 : struct stat *cstatp=&cb->statp;
455 : // A hardlink changed into a file. It is possible that
456 : // The file that the hardlink was pointing to got
457 : // deleted. Maybe we can reuse the previous file.
458 0 : if(p1statp->st_dev==cstatp->st_dev
459 0 : && p1statp->st_ino==cstatp->st_ino
460 0 : && p1statp->st_mtime==cstatp->st_mtime)
461 : {
462 0 : switch(relink_deleted_hardlink_master(
463 : dpth, hmanio, sdirs,
464 : p1b, cb, cconfs))
465 : {
466 : case 0:
467 : break;
468 : case 1:
469 0 : return process_unchanged_file(
470 : p1b, cb,
471 : ucmanio, cconfs);
472 : default:
473 : return P_ERROR;
474 : }
475 : }
476 : }
477 0 : return process_new(cconfs, p1b, ucmanio);
478 : }
479 :
480 : // mtime is the actual file data.
481 : // ctime is the attributes or meta data.
482 10 : if(cb->statp.st_mtime==p1b->statp.st_mtime
483 6 : && cb->statp.st_ctime==p1b->statp.st_ctime)
484 : {
485 : // got an unchanged file
486 : //logp("got unchanged file: %s %c\n",
487 : // iobuf_to_printable(&cb->path), p1b->path.cmd);
488 6 : return process_unchanged_file(p1b, cb, ucmanio, cconfs);
489 : }
490 :
491 4 : if(cb->statp.st_mtime==p1b->statp.st_mtime
492 0 : && cb->statp.st_ctime!=p1b->statp.st_ctime)
493 : {
494 : // File data stayed the same, but attributes or meta data
495 : // changed. We already have the attributes, but may need to get
496 : // extra meta data.
497 : // FIX THIS horrible mess.
498 0 : if(cb->path.cmd==CMD_ENC_METADATA
499 0 : || p1b->path.cmd==CMD_ENC_METADATA
500 0 : || cb->path.cmd==CMD_EFS_FILE
501 0 : || p1b->path.cmd==CMD_EFS_FILE
502 : // FIX THIS: make unencrypted metadata use the librsync
503 0 : || cb->path.cmd==CMD_METADATA
504 0 : || p1b->path.cmd==CMD_METADATA
505 0 : || sbuf_is_vssdata(cb)
506 0 : || sbuf_is_vssdata(p1b))
507 0 : return process_new(cconfs, p1b, ucmanio);
508 : // On Windows, we have to back up the whole file if ctime
509 : // changed, otherwise things like permission changes do not get
510 : // noticed. So, in that case, fall through to the changed stuff
511 : // below.
512 : // Non-Windows clients finish here.
513 0 : else if(!get_int(cconfs[OPT_CLIENT_IS_WINDOWS]))
514 0 : return process_unchanged_file(p1b,
515 : cb, ucmanio, cconfs);
516 : }
517 :
518 : // Got a changed file.
519 : //logp("got changed file: %s\n", iobuf_to_printable(&p1b->path));
520 :
521 : // If either old or new is encrypted, or librsync is off, we need to
522 : // get a new file.
523 : // FIX THIS horrible mess.
524 4 : if(!librsync_enabled(p1b, cb, cconfs)
525 : // FIX THIS: make unencrypted metadata use the librsync
526 4 : || cb->path.cmd==CMD_METADATA
527 4 : || p1b->path.cmd==CMD_METADATA
528 4 : || sbuf_is_encrypted(cb)
529 2 : || sbuf_is_encrypted(p1b)
530 2 : || sbuf_is_vssdata(cb)
531 2 : || sbuf_is_vssdata(p1b))
532 2 : return process_new(cconfs, p1b, ucmanio);
533 :
534 : // Get new files if they have switched between compression on or off.
535 2 : if(cb->protocol1->datapth.buf
536 2 : && dpth_protocol1_is_compressed(cb->compression,
537 : cb->protocol1->datapth.buf))
538 0 : oldcompressed=1;
539 4 : if( ( oldcompressed && !compression)
540 2 : || (!oldcompressed && compression))
541 0 : return process_new(cconfs, p1b, ucmanio);
542 :
543 : // Otherwise, do the delta stuff (if possible).
544 2 : if(sbuf_is_filedata(p1b)
545 0 : || sbuf_is_vssdata(p1b))
546 2 : return process_changed_file(asfd, cconfs, cb, p1b,
547 2 : sdirs->currentdata);
548 0 : return changed_non_file(p1b, ucmanio, p1b->path.cmd, cconfs);
549 : }
550 :
551 : static enum processed_e process_deleted_file(struct sbuf *cb,
552 : struct conf **cconfs)
553 : {
554 2 : cntr_add_deleted(get_cntr(cconfs), cb->path.cmd);
555 : return P_DONE_DELETED;
556 : }
557 :
558 : // return 1 to say that a file was processed
559 12 : static enum processed_e maybe_process_file(struct asfd *asfd,
560 : struct dpth *dpth,
561 : struct sdirs *sdirs, struct sbuf *cb, struct sbuf *p1b,
562 : struct manio *ucmanio, struct manio **hmanio, struct conf **cconfs)
563 : {
564 : int pcmp;
565 12 : if(p1b)
566 : {
567 11 : if(!(pcmp=sbuf_pathcmp(cb, p1b)))
568 10 : return maybe_do_delta_stuff(asfd, dpth,sdirs, cb, p1b,
569 : ucmanio, hmanio, cconfs);
570 1 : else if(pcmp>0)
571 : {
572 : //logp("ahead: %s\n", iobuf_to_printable(&p1b->path));
573 : // ahead - need to get the whole file
574 0 : return process_new(cconfs, p1b, ucmanio);
575 : }
576 : }
577 : //logp("behind: %s\n", iobuf_to_printable(&p1b->path));
578 : // Behind - need to read more from the old manifest.
579 : // Count a deleted file - it was in the old manifest
580 : // but not the new.
581 4 : return process_deleted_file(cb, cconfs);
582 : }
583 :
584 : enum sts_e
585 : {
586 : STS_ERROR=-1,
587 : STS_OK=0,
588 : STS_BLOCKED=1
589 : };
590 :
591 : // Return 1 if there is still stuff needing to be sent.
592 : // FIX THIS: lots of repeated code.
593 63 : static enum sts_e do_stuff_to_send(struct asfd *asfd,
594 : struct sbuf *p1b, char **last_requested)
595 : {
596 : static struct iobuf wbuf;
597 63 : if(p1b->flags & SBUF_SEND_DATAPTH)
598 : {
599 2 : iobuf_copy(&wbuf, &p1b->protocol1->datapth);
600 2 : switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
601 : {
602 : case APPEND_OK: break;
603 : case APPEND_BLOCKED: return STS_BLOCKED;
604 0 : default: return STS_ERROR;
605 : }
606 2 : p1b->flags &= ~SBUF_SEND_DATAPTH;
607 : }
608 63 : if(p1b->flags & SBUF_SEND_STAT)
609 : {
610 56 : iobuf_copy(&wbuf, &p1b->attr);
611 56 : switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
612 : {
613 : case APPEND_OK: break;
614 : case APPEND_BLOCKED: return STS_BLOCKED;
615 0 : default: return STS_ERROR;
616 : }
617 56 : p1b->flags &= ~SBUF_SEND_STAT;
618 : }
619 63 : if(p1b->flags & SBUF_SEND_PATH)
620 : {
621 56 : iobuf_copy(&wbuf, &p1b->path);
622 56 : switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
623 : {
624 : case APPEND_OK: break;
625 : case APPEND_BLOCKED: return STS_BLOCKED;
626 0 : default: return STS_ERROR;
627 : }
628 56 : p1b->flags &= ~SBUF_SEND_PATH;
629 56 : free_w(last_requested);
630 56 : if(!(*last_requested=strdup_w(p1b->path.buf, __func__)))
631 : return STS_ERROR;
632 : }
633 63 : if(p1b->protocol1->sigjob && !(p1b->flags & SBUF_SEND_ENDOFSIG))
634 : {
635 : rs_result sigresult;
636 :
637 4 : switch((sigresult=rs_async(p1b->protocol1->sigjob,
638 : &(p1b->protocol1->rsbuf),
639 : p1b->protocol1->infb, p1b->protocol1->outfb)))
640 : {
641 : case RS_DONE:
642 2 : p1b->flags |= SBUF_SEND_ENDOFSIG;
643 2 : break;
644 : case RS_BLOCKED:
645 : case RS_RUNNING:
646 : // keep going round the loop.
647 : return STS_BLOCKED;
648 : default:
649 0 : logp("error in rs_async: %d %s\n",
650 : sigresult, rs_strerror(sigresult));
651 0 : return STS_ERROR;
652 : }
653 : }
654 61 : if(p1b->flags & SBUF_SEND_ENDOFSIG)
655 : {
656 2 : iobuf_from_str(&wbuf, CMD_END_FILE, (char *)"endfile");
657 2 : switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
658 : {
659 : case APPEND_OK: break;
660 : case APPEND_BLOCKED: return STS_BLOCKED;
661 0 : default: return STS_ERROR;
662 : }
663 2 : p1b->flags &= ~SBUF_SEND_ENDOFSIG;
664 : }
665 : return STS_OK;
666 : }
667 :
668 4 : static int start_to_receive_delta(struct sdirs *sdirs, struct sbuf *rb)
669 : {
670 4 : if(rb->compression)
671 : {
672 0 : if(!(rb->protocol1->fzp=fzp_gzopen(sdirs->deltmppath,
673 0 : comp_level(rb->compression))))
674 : return -1;
675 : }
676 : else
677 : {
678 4 : if(!(rb->protocol1->fzp=fzp_open(sdirs->deltmppath, "wb")))
679 : return -1;
680 : }
681 4 : rb->flags |= SBUF_RECV_DELTA;
682 :
683 : return 0;
684 : }
685 :
686 4 : static int finish_delta(struct sdirs *sdirs, struct sbuf *rb)
687 : {
688 4 : int ret=0;
689 4 : char *deltmp=NULL;
690 4 : char *delpath=NULL;
691 4 : if(!(deltmp=prepend_s("deltas.forward", rb->protocol1->datapth.buf))
692 4 : || !(delpath=prepend_s(sdirs->working, deltmp))
693 4 : || mkpath(&delpath, sdirs->working)
694 : // Rename race condition is of no consequence here, as delpath will
695 : // just get recreated.
696 4 : || do_rename(sdirs->deltmppath, delpath))
697 : ret=-1;
698 4 : free_w(&delpath);
699 4 : free_w(&deltmp);
700 4 : return ret;
701 : }
702 :
703 8 : static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs,
704 : struct sbuf *rb, struct manio *chmanio, struct conf **cconfs,
705 : char **last_requested)
706 : {
707 8 : int ret=-1;
708 : static char *cp=NULL;
709 : static struct iobuf *rbuf;
710 8 : struct cntr *cntr=get_cntr(cconfs);
711 8 : rbuf=asfd->rbuf;
712 : // Finished the file.
713 : // Write it to the phase2 file, and free the buffers.
714 :
715 8 : if(fzp_close(&(rb->protocol1->fzp)))
716 : {
717 0 : logp("error closing delta for %s in receive\n",
718 : iobuf_to_printable(&rb->path));
719 : goto end;
720 : }
721 8 : iobuf_move(&rb->endfile, rbuf);
722 8 : if(rb->flags & SBUF_RECV_DELTA && finish_delta(sdirs, rb))
723 : goto end;
724 :
725 8 : if(manio_write_sbuf(chmanio, rb))
726 : goto end;
727 :
728 8 : if(rb->flags & SBUF_RECV_DELTA)
729 4 : cntr_add_changed(cntr, rb->path.cmd);
730 : else
731 4 : cntr_add(cntr, rb->path.cmd, 0);
732 :
733 8 : if(*last_requested && !strcmp(rb->path.buf, *last_requested))
734 2 : free_w(last_requested);
735 :
736 8 : cp=strchr(rb->endfile.buf, ':');
737 8 : if(rb->endfile.buf)
738 8 : cntr_add_bytes(cntr, strtoull(rb->endfile.buf, NULL, 10));
739 : if(cp)
740 : {
741 : // checksum stuff goes here
742 : }
743 :
744 8 : ret=0;
745 : end:
746 8 : sbuf_free_content(rb);
747 8 : return ret;
748 : }
749 :
750 8 : static int deal_with_receive_append(struct asfd *asfd, struct sbuf *rb)
751 : {
752 8 : int app=0;
753 : static struct iobuf *rbuf;
754 8 : rbuf=asfd->rbuf;
755 : //logp("rbuf->len: %d\n", rbuf->len);
756 :
757 8 : if(rb->protocol1->fzp)
758 8 : app=fzp_write(rb->protocol1->fzp, rbuf->buf, rbuf->len);
759 :
760 8 : if(app>0) return 0;
761 0 : logp("error when appending: %d\n", app);
762 0 : asfd->write_str(asfd, CMD_ERROR, "write failed");
763 : return -1;
764 : }
765 :
766 8 : static int deal_with_filedata(struct asfd *asfd,
767 : struct sdirs *sdirs, struct sbuf *rb,
768 : struct iobuf *rbuf, struct dpth *dpth, struct conf **cconfs)
769 : {
770 8 : iobuf_move(&rb->path, rbuf);
771 :
772 8 : if(rb->protocol1->datapth.buf)
773 : {
774 : // Receiving a delta.
775 4 : if(start_to_receive_delta(sdirs, rb))
776 : {
777 0 : logp("error in start_to_receive_delta\n");
778 0 : return -1;
779 : }
780 : return 0;
781 : }
782 :
783 : // Receiving a whole new file.
784 4 : if(start_to_receive_new_file(asfd, sdirs, cconfs, rb, dpth))
785 : {
786 0 : logp("error in start_to_receive_new_file\n");
787 0 : return -1;
788 : }
789 : return 0;
790 : }
791 :
792 : enum str_e
793 : {
794 : STR_ERROR=-1,
795 : STR_OK=0,
796 : STR_FINISHED=1
797 : };
798 :
799 : // returns 1 for finished ok.
800 85 : static enum str_e do_stuff_to_receive(struct asfd *asfd,
801 : struct sdirs *sdirs, struct conf **cconfs,
802 : struct sbuf *rb, struct manio *chmanio,
803 : struct dpth *dpth, char **last_requested)
804 : {
805 85 : struct iobuf *rbuf=asfd->rbuf;
806 :
807 170 : if(rbuf->cmd==CMD_MESSAGE
808 85 : || rbuf->cmd==CMD_WARNING)
809 : {
810 0 : struct cntr *cntr=NULL;
811 0 : if(cconfs) cntr=get_cntr(cconfs);
812 0 : log_recvd(rbuf, cntr, 0);
813 0 : return STR_OK;
814 : }
815 :
816 85 : if(rb->protocol1->fzp)
817 : {
818 : // Currently writing a file (or meta data)
819 16 : switch(rbuf->cmd)
820 : {
821 : case CMD_APPEND:
822 8 : if(deal_with_receive_append(asfd, rb))
823 : goto error;
824 : return STR_OK;
825 : case CMD_END_FILE:
826 8 : if(deal_with_receive_end_file(asfd, sdirs, rb,
827 : chmanio, cconfs, last_requested))
828 : goto error;
829 : return STR_OK;
830 : case CMD_INTERRUPT:
831 0 : if(*last_requested
832 0 : && !strcmp(rbuf->buf, *last_requested))
833 0 : free_w(last_requested);
834 0 : fzp_close(&(rb->protocol1->fzp));
835 0 : sbuf_free_content(rb);
836 0 : return STR_OK;
837 : default:
838 0 : iobuf_log_unexpected(rbuf, __func__);
839 0 : goto error;
840 : }
841 : }
842 :
843 : // Otherwise, expecting to be told of a file to save.
844 69 : switch(rbuf->cmd)
845 : {
846 : case CMD_DATAPTH:
847 4 : if(iobuf_relative_path_attack(rbuf))
848 : goto error;
849 4 : iobuf_move(&rb->protocol1->datapth, rbuf);
850 4 : return STR_OK;
851 : case CMD_ATTRIBS:
852 8 : iobuf_move(&rb->attr, rbuf);
853 8 : attribs_decode(rb);
854 8 : return STR_OK;
855 : case CMD_GEN:
856 5 : if(!strcmp(rbuf->buf, "okbackupphase2end"))
857 : goto end_phase2;
858 0 : iobuf_log_unexpected(rbuf, __func__);
859 0 : goto error;
860 : case CMD_INTERRUPT:
861 : // Interrupt - forget about the last requested
862 : // file if it matches. Otherwise, we can get
863 : // stuck on the select in the async stuff,
864 : // waiting for something that will never arrive.
865 44 : if(*last_requested
866 44 : && !strcmp(rbuf->buf, *last_requested))
867 1 : free_w(last_requested);
868 : return STR_OK;
869 : default:
870 : break;
871 : }
872 8 : if(iobuf_is_filedata(rbuf)
873 0 : || iobuf_is_vssdata(rbuf))
874 : {
875 8 : if(deal_with_filedata(asfd, sdirs, rb, rbuf, dpth, cconfs))
876 : goto error;
877 : return STR_OK;
878 : }
879 0 : iobuf_log_unexpected(rbuf, __func__);
880 :
881 : error:
882 : return STR_ERROR;
883 : end_phase2:
884 : return STR_FINISHED;
885 : }
886 :
887 5 : static int vss_opts_changed(struct sdirs *sdirs, struct conf **cconfs,
888 : const char *incexc)
889 : {
890 5 : int ret=-1;
891 : struct conf **oldconfs;
892 : struct conf **newconfs;
893 5 : if(!(oldconfs=confs_alloc())
894 5 : || !(newconfs=confs_alloc()))
895 : goto end;
896 5 : confs_init(oldconfs);
897 5 : confs_init(newconfs);
898 :
899 : // Figure out the old config, which is in the incexc file left
900 : // in the current backup directory on the server.
901 5 : if(is_reg_lstat(sdirs->cincexc)<=0
902 1 : || conf_parse_incexcs_path(oldconfs, sdirs->cincexc))
903 : {
904 : // Assume that the file did not exist, and therefore
905 : // the old split_vss setting is 0.
906 4 : set_int(oldconfs[OPT_SPLIT_VSS], 0);
907 4 : set_int(oldconfs[OPT_STRIP_VSS], 0);
908 : }
909 :
910 : // Figure out the new config, which is either in the incexc file from
911 : // the client, or in the cconf on the server.
912 5 : if(incexc)
913 : {
914 0 : if(conf_parse_incexcs_buf(newconfs, incexc))
915 : {
916 : // Should probably not got here.
917 0 : set_int(newconfs[OPT_SPLIT_VSS], 0);
918 0 : set_int(newconfs[OPT_STRIP_VSS], 0);
919 : }
920 : }
921 : else
922 : {
923 5 : set_int(newconfs[OPT_SPLIT_VSS],
924 5 : get_int(cconfs[OPT_SPLIT_VSS]));
925 5 : set_int(newconfs[OPT_STRIP_VSS],
926 5 : get_int(cconfs[OPT_STRIP_VSS]));
927 : }
928 :
929 5 : if(get_int(newconfs[OPT_SPLIT_VSS])!=get_int(oldconfs[OPT_SPLIT_VSS]))
930 : {
931 0 : logp("split_vss=%d (changed since last backup)\n",
932 0 : get_int(newconfs[OPT_SPLIT_VSS]));
933 0 : ret=1; goto end;
934 : }
935 5 : if(get_int(newconfs[OPT_STRIP_VSS])!=get_int(oldconfs[OPT_STRIP_VSS]))
936 : {
937 0 : logp("strip_vss=%d (changed since last backup)\n",
938 0 : get_int(newconfs[OPT_STRIP_VSS]));
939 0 : ret=1; goto end;
940 : }
941 : ret=0;
942 : end:
943 5 : if(ret==1) logp("All files will be treated as new\n");
944 5 : confs_free(&oldconfs);
945 5 : confs_free(&newconfs);
946 5 : return ret;
947 : }
948 :
949 : // Maybe open the previous (current) manifest.
950 : // If the split_vss setting changed between the previous backup and the new
951 : // backup, do not open the previous manifest. This will have the effect of
952 : // making the client back up everything fresh. Need to do this, otherwise
953 : // toggling split_vss on and off will result in backups that do not work.
954 5 : static int maybe_open_previous_manifest(struct manio **manio,
955 : struct sdirs *sdirs, const char *incexc, struct conf **cconfs)
956 : {
957 5 : if(vss_opts_changed(sdirs, cconfs, incexc))
958 : return 0;
959 5 : return open_previous_manifest(manio, sdirs);
960 : }
961 :
962 135 : static int process_next_file_from_manios(struct asfd *asfd,
963 : struct dpth *dpth,
964 : struct sdirs *sdirs,
965 : struct manio **p1manio,
966 : struct manio **cmanio,
967 : struct manio *ucmanio,
968 : struct manio **hmanio,
969 : struct sbuf **p1b,
970 : struct sbuf *cb,
971 : struct conf **cconfs)
972 : {
973 135 : if(!(*p1b=sbuf_alloc(PROTO_1)))
974 : goto error;
975 135 : switch(manio_read(*p1manio, *p1b))
976 : {
977 : case 0:
978 : break;
979 : case 1:
980 5 : manio_close(p1manio);
981 5 : if(asfd->write_str(asfd, CMD_GEN, "backupphase2end"))
982 : goto error;
983 5 : sbuf_free(p1b);
984 5 : break;
985 : case -1:
986 : goto error;
987 : }
988 :
989 135 : if(!*cmanio)
990 : {
991 124 : if(!*p1b) return 0;
992 : // No old manifest, need to ask for a new file.
993 120 : switch(process_new(cconfs, *p1b, ucmanio))
994 : {
995 : case P_NEW:
996 : return 0;
997 : case P_DONE_NEW:
998 : goto p1b_done;
999 : default:
1000 : goto error;
1001 : }
1002 : }
1003 :
1004 : // Have an old manifest, look for it there.
1005 :
1006 : // Might already have it, or be ahead in the old
1007 : // manifest.
1008 11 : if(cb->path.buf)
1009 : {
1010 2 : switch(maybe_process_file(asfd, dpth,
1011 : sdirs, cb, *p1b, ucmanio, hmanio, cconfs))
1012 : {
1013 : case P_NEW:
1014 : return 0;
1015 : case P_CHANGED:
1016 : // Free cb content for things like encrypted
1017 : // files, which we only pretend are new.
1018 0 : sbuf_free_content(cb);
1019 0 : return 0;
1020 : case P_DONE_NEW:
1021 : goto p1b_done;
1022 : case P_DONE_CHANGED:
1023 : case P_DONE_UNCHANGED:
1024 0 : sbuf_free_content(cb);
1025 0 : goto p1b_done;
1026 : case P_DONE_DELETED:
1027 2 : sbuf_free_content(cb);
1028 2 : break;
1029 : case P_ERROR:
1030 : goto error;
1031 : }
1032 : }
1033 :
1034 : while(1)
1035 : {
1036 11 : sbuf_free_content(cb);
1037 11 : switch(manio_read(*cmanio, cb))
1038 : {
1039 : case 0: break;
1040 1 : case 1: manio_close(cmanio);
1041 1 : if(*p1b) switch(process_new(cconfs,
1042 : *p1b, ucmanio))
1043 : {
1044 : case P_NEW:
1045 : return 0;
1046 : case P_DONE_NEW:
1047 : goto p1b_done;
1048 : default:
1049 : goto error;
1050 : }
1051 : return 0;
1052 : case -1: goto error;
1053 : }
1054 10 : switch(maybe_process_file(asfd, dpth, sdirs,
1055 : cb, *p1b, ucmanio, hmanio, cconfs))
1056 : {
1057 : case P_NEW:
1058 : return 0;
1059 : case P_CHANGED:
1060 : // Free cb content for things like encrypted
1061 : // files, which we only pretend are new.
1062 2 : sbuf_free_content(cb);
1063 2 : return 0;
1064 : case P_DONE_NEW:
1065 : goto p1b_done;
1066 : case P_DONE_CHANGED:
1067 : case P_DONE_UNCHANGED:
1068 6 : sbuf_free_content(cb);
1069 6 : goto p1b_done;
1070 : case P_DONE_DELETED:
1071 0 : sbuf_free_content(cb);
1072 0 : continue;
1073 : case P_ERROR:
1074 : goto error;
1075 : }
1076 : }
1077 : error:
1078 : return -1;
1079 : p1b_done:
1080 74 : sbuf_free(p1b);
1081 74 : return 0;
1082 : }
1083 :
1084 10 : static int maybe_move_seed_dir(struct sdirs *sdirs, struct conf **cconfs)
1085 : {
1086 10 : int ret=-1;
1087 10 : char *fullsrc=NULL;
1088 10 : char *fulldst=NULL;
1089 10 : char *seed_src=NULL;
1090 10 : char *seed_dst=NULL;
1091 10 : if(!sdirs || !cconfs)
1092 : return 0;
1093 6 : seed_src=get_string(cconfs[OPT_SEED_SRC]);
1094 6 : seed_dst=get_string(cconfs[OPT_SEED_DST]);
1095 6 : if(!seed_src || !seed_dst)
1096 : return 0;
1097 :
1098 : // Need to move the data from the client to the correct
1099 : // location.
1100 0 : if(!(fullsrc=prepend_s(sdirs->datadirtmp, TREE_DIR))
1101 0 : || !(fulldst=prepend_s(sdirs->datadirtmp, TREE_DIR))
1102 0 : || astrcat(&fullsrc, seed_src, __func__))
1103 : goto end;
1104 0 : if(*seed_dst!='/'
1105 0 : && astrcat(&fulldst, "/", __func__))
1106 : goto end;
1107 0 : if(astrcat(&fulldst, seed_dst, __func__))
1108 : goto end;
1109 0 : if(build_path_w(fulldst))
1110 : goto end;
1111 0 : if(do_rename(fullsrc, fulldst))
1112 : goto end;
1113 :
1114 0 : ret=0;
1115 : end:
1116 0 : free_w(&fullsrc);
1117 0 : free_w(&fulldst);
1118 0 : return ret;
1119 : }
1120 :
1121 10 : int backup_phase2_server_protocol1(struct async *as, struct sdirs *sdirs,
1122 : const char *incexc, int resume, struct conf **cconfs)
1123 : {
1124 10 : int ret=0;
1125 10 : man_off_t *p1pos=NULL;
1126 10 : struct manio *p1manio=NULL;
1127 10 : struct dpth *dpth=NULL;
1128 10 : char *last_requested=NULL;
1129 10 : struct manio *chmanio=NULL; // changed data
1130 10 : struct manio *ucmanio=NULL; // unchanged data
1131 10 : struct manio *cmanio=NULL; // previous (current) manifest
1132 10 : struct manio *hmanio=NULL; // to look up deleted hardlinks
1133 10 : struct sbuf *cb=NULL; // file list in current manifest
1134 10 : struct sbuf *p1b=NULL; // file list from client
1135 10 : struct sbuf *rb=NULL; // receiving file from client
1136 10 : struct asfd *asfd=NULL;
1137 10 : int breaking=0;
1138 10 : int breakcount=0;
1139 10 : struct cntr *cntr=NULL;
1140 10 : struct cntr_ent *warn_ent=NULL;
1141 10 : int fail_on_warning=0;
1142 :
1143 10 : if(!as)
1144 : {
1145 1 : logp("async not provided to %s()\n", __func__);
1146 1 : goto error;
1147 : }
1148 9 : if(!sdirs)
1149 : {
1150 2 : logp("sdirs not provided to %s()\n", __func__);
1151 2 : goto error;
1152 : }
1153 7 : if(!cconfs)
1154 : {
1155 1 : logp("cconfs not provided to %s()\n", __func__);
1156 1 : goto error;
1157 : }
1158 6 : asfd=as->asfd;
1159 6 : if(!asfd)
1160 : {
1161 1 : logp("asfd not provided to %s()\n", __func__);
1162 1 : goto error;
1163 : }
1164 5 : cntr=get_cntr(cconfs);
1165 5 : fail_on_warning=get_int(cconfs[OPT_FAIL_ON_WARNING]);
1166 5 : if(cntr)
1167 0 : warn_ent=cntr->ent[CMD_WARNING];
1168 :
1169 5 : if(get_int(cconfs[OPT_BREAKPOINT])>=2000
1170 0 : && get_int(cconfs[OPT_BREAKPOINT])<3000)
1171 : {
1172 0 : breaking=get_int(cconfs[OPT_BREAKPOINT]);
1173 0 : breakcount=breaking-2000;
1174 : }
1175 :
1176 5 : logp("Begin phase2 (receive file data)\n");
1177 :
1178 5 : if(!(dpth=dpth_alloc())
1179 5 : || dpth_protocol1_init(dpth, sdirs->currentdata,
1180 : get_int(cconfs[OPT_MAX_STORAGE_SUBDIRS])))
1181 : goto error;
1182 :
1183 5 : if(maybe_open_previous_manifest(&cmanio, sdirs, incexc, cconfs))
1184 : goto error;
1185 : // If the first file that others hardlink to has been deleted, we will
1186 : // need to look through the previous manifest to find the information
1187 : // for that original file, in order to not have to copy all the data
1188 : // across again.
1189 5 : if(open_previous_manifest(&hmanio, sdirs))
1190 : goto error;
1191 :
1192 5 : if(get_int(cconfs[OPT_DIRECTORY_TREE]))
1193 : {
1194 : // Need to make sure we do not try to create a path that is
1195 : // too long.
1196 5 : if(build_path_w(sdirs->treepath)) goto error;
1197 5 : mkdir(sdirs->treepath, 0777);
1198 5 : treepathlen=strlen(sdirs->treepath);
1199 5 : if(init_fs_max(sdirs->treepath))
1200 : goto error;
1201 : }
1202 :
1203 5 : if(resume)
1204 : {
1205 0 : if(!(p1pos=do_resume(sdirs, dpth, cconfs)))
1206 : goto error;
1207 0 : if(cntr_send_sdirs(asfd, sdirs, cconfs, CNTR_STATUS_BACKUP))
1208 : goto error;
1209 : }
1210 :
1211 5 : if(!(p1manio=manio_open_phase1(sdirs->phase1data, "rb", PROTO_1))
1212 5 : || (resume && manio_seek(p1manio, p1pos)))
1213 : goto error;
1214 5 : if(!(cb=sbuf_alloc(PROTO_1))
1215 5 : || !(p1b=sbuf_alloc(PROTO_1))
1216 5 : || !(rb=sbuf_alloc(PROTO_1)))
1217 : goto error;
1218 :
1219 : // Unchanged and changed should now be truncated correctly, we just
1220 : // have to open them for appending.
1221 : // Data is not getting written to a compressed file.
1222 : // This is important for recovery if the power goes.
1223 5 : if(!(ucmanio=manio_open_phase2(sdirs->unchanged, "ab", PROTO_1))
1224 5 : || !(chmanio=manio_open_phase2(sdirs->changed, "ab", PROTO_1)))
1225 : goto error;
1226 :
1227 : while(1)
1228 : {
1229 921 : if(check_fail_on_warning(fail_on_warning, warn_ent))
1230 : goto error;
1231 :
1232 921 : if(breaking && breakcount--==0)
1233 0 : return breakpoint(breaking, __func__);
1234 :
1235 921 : if(write_status(CNTR_STATUS_BACKUP,
1236 921 : rb->path.buf?rb->path.buf:"", cntr))
1237 : goto error;
1238 1842 : if(last_requested
1239 921 : || !p1manio
1240 16 : || asfd->writebuflen)
1241 : {
1242 905 : iobuf_free_content(asfd->rbuf);
1243 905 : if(asfd->as->read_write(asfd->as))
1244 : {
1245 0 : logp("error in %s\n", __func__);
1246 0 : goto error;
1247 : }
1248 :
1249 905 : if(asfd->rbuf->buf)
1250 85 : switch(do_stuff_to_receive(asfd, sdirs,
1251 : cconfs, rb, chmanio, dpth, &last_requested))
1252 : {
1253 : case STR_OK:
1254 : break;
1255 : case STR_FINISHED:
1256 5 : if(check_fail_on_warning(
1257 : fail_on_warning, warn_ent))
1258 : goto error;
1259 : goto end;
1260 : case STR_ERROR:
1261 : goto error;
1262 : }
1263 : }
1264 :
1265 916 : if(p1b) switch(do_stuff_to_send(asfd, p1b, &last_requested))
1266 : {
1267 : case STS_OK:
1268 61 : sbuf_free(&p1b);
1269 61 : break;
1270 : case STS_BLOCKED:
1271 2 : continue;
1272 : case STS_ERROR:
1273 : goto error;
1274 : }
1275 :
1276 914 : if(p1manio
1277 135 : && process_next_file_from_manios(asfd, dpth, sdirs,
1278 : &p1manio, &cmanio, ucmanio, &hmanio, &p1b, cb, cconfs))
1279 : goto error;
1280 : }
1281 :
1282 : error:
1283 5 : ret=-1;
1284 5 : if(p1b)
1285 0 : logp(" last tried file: %s\n",
1286 : iobuf_to_printable(&p1b->path));
1287 : end:
1288 10 : if(manio_close(&chmanio))
1289 : {
1290 0 : logp("error closing %s in %s\n", sdirs->changed, __func__);
1291 0 : ret=-1;
1292 : }
1293 10 : if(manio_close(&ucmanio))
1294 : {
1295 0 : logp("error closing %s in %s\n", sdirs->unchanged, __func__);
1296 0 : ret=-1;
1297 : }
1298 10 : if(maybe_move_seed_dir(sdirs, cconfs))
1299 : {
1300 0 : logp("error moving seed dir\n");
1301 0 : ret=-1;
1302 : }
1303 10 : free_w(&last_requested);
1304 10 : sbuf_free(&cb);
1305 10 : sbuf_free(&p1b);
1306 10 : sbuf_free(&rb);
1307 10 : manio_close(&p1manio);
1308 10 : manio_close(&cmanio);
1309 10 : manio_close(&hmanio);
1310 10 : dpth_free(&dpth);
1311 10 : man_off_t_free(&p1pos);
1312 10 : if(!ret && sdirs)
1313 5 : unlink(sdirs->phase1data);
1314 :
1315 10 : logp("End phase2 (receive file data)\n");
1316 :
1317 10 : return ret;
1318 : }
|