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