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 : // Why is winattr not getting sent in phase1?
272 6 : p1b->winattr=cb->winattr;
273 : // Need to free attr so that it is reallocated, because it may get
274 : // longer than what the client told us in phase1.
275 6 : iobuf_free_content(&p1b->attr);
276 6 : if(attribs_encode(p1b))
277 : return P_ERROR;
278 6 : if(manio_write_sbuf(ucmanio, p1b))
279 : return P_ERROR;
280 6 : cntr_add_same(get_cntr(cconfs), p1b->path.cmd);
281 6 : if(p1b->endfile.buf) cntr_add_bytes(get_cntr(cconfs),
282 0 : strtoull(p1b->endfile.buf, NULL, 10));
283 : return P_DONE_UNCHANGED;
284 : }
285 :
286 10 : static int open_previous_manifest(struct manio **manio, struct sdirs *sdirs)
287 : {
288 : struct stat statp;
289 20 : if(!lstat(sdirs->cmanifest, &statp)
290 2 : && !(*manio=manio_open(sdirs->cmanifest, "rb", PROTO_1)))
291 : {
292 0 : logp("could not open old manifest %s\n", sdirs->cmanifest);
293 : return -1;
294 : }
295 : return 0;
296 : }
297 :
298 0 : static int get_hardlink_master_from_hmanio(
299 : struct manio **hmanio,
300 : struct sdirs *sdirs,
301 : struct sbuf *cb,
302 : struct sbuf *hb
303 : ) {
304 : int passes=0;
305 : while(1)
306 : {
307 0 : sbuf_free_content(hb);
308 0 : switch(manio_read(*hmanio, hb))
309 : {
310 : case 0: // Keep going.
311 : break;
312 : case 1: // Finished OK.
313 0 : manio_close(hmanio);
314 : // Might have already been part way down the
315 : // manifest when we started. If we get to the
316 : // end, go back to the beginning once.
317 0 : if(!passes)
318 : {
319 0 : if(open_previous_manifest(hmanio,
320 : sdirs)) return -1;
321 0 : passes++;
322 0 : continue;
323 : }
324 : return 0;
325 : default: // Error;
326 : return -1;
327 : }
328 0 : if(hb->path.cmd!=CMD_FILE
329 0 : && hb->path.cmd!=CMD_ENC_FILE)
330 0 : continue;
331 0 : if(!strcmp(hb->path.buf, cb->link.buf)
332 0 : && hb->protocol1->datapth.buf)
333 : return 1; // Found it.
334 : }
335 : return -1;
336 : }
337 :
338 0 : static int relink_deleted_hardlink_master(
339 : struct dpth *dpth,
340 : struct manio **hmanio,
341 : struct sdirs *sdirs,
342 : struct sbuf *p1b,
343 : struct sbuf *cb,
344 : struct conf **cconfs
345 : ) {
346 0 : int ret=-1;
347 0 : char *newdatapth_full=NULL;
348 0 : char *olddatapth_full=NULL;
349 0 : char *newdatapth=NULL;
350 0 : char *relinkpath_full=NULL;
351 : struct stat statp;
352 0 : struct sbuf *hb=NULL;
353 0 : int istreedata=0;
354 :
355 0 : if(!(hb=sbuf_alloc(PROTO_1)))
356 : goto end;
357 :
358 0 : switch(get_hardlink_master_from_hmanio(hmanio, sdirs, cb, hb))
359 : {
360 : case 0: // Did not find it.
361 : return 0;
362 : case 1: // Found it.
363 : break;
364 : default: // Error.
365 : goto end;
366 : }
367 :
368 : // Protect against the old file being encrypted, and the new file not
369 : // being encrypted - and vice versa.
370 0 : if(p1b->path.cmd!=hb->path.cmd)
371 : return 0;
372 :
373 0 : if(!(newdatapth_full=set_new_datapth(sdirs,
374 : cconfs, p1b, dpth, &istreedata)))
375 : goto end;
376 0 : if(!istreedata) dpth_incr(dpth);
377 0 : if(!(relinkpath_full=prepend_s(sdirs->relink,
378 0 : p1b->protocol1->datapth.buf)))
379 : goto end;
380 0 : if(!(newdatapth=strdup_w(p1b->protocol1->datapth.buf, __func__)))
381 : goto end;
382 : /*
383 : printf("newdatapth_full: %s\n", newdatapth_full);
384 : printf("relinkpath_full: %s\n", relinkpath_full);
385 : printf("newdatapth: %s\n", newdatapth);
386 : printf("hbdatapth: %s\n", iobuf_to_printable(&hb->protocol1->datapth));
387 : printf("sdirs->currentdata: %s\n", sdirs->currentdata);
388 : */
389 :
390 0 : if(!(olddatapth_full=prepend_s(sdirs->currentdata,
391 0 : hb->protocol1->datapth.buf)))
392 : goto end;
393 0 : if(lstat(olddatapth_full, &statp) || !S_ISREG(statp.st_mode))
394 : {
395 0 : logw(NULL, get_cntr(cconfs),
396 : "Did not find path for relink: %s\n", olddatapth_full);
397 0 : ret=0;
398 0 : goto end;
399 : }
400 0 : if(build_path_w(relinkpath_full))
401 : goto end;
402 0 : if(do_link(olddatapth_full, relinkpath_full,
403 : &statp, cconfs, /*overwrite*/0))
404 : goto end;
405 :
406 0 : iobuf_free_content(&cb->protocol1->datapth);
407 :
408 0 : iobuf_from_str(&hb->protocol1->datapth, CMD_DATAPTH,
409 0 : p1b->protocol1->datapth.buf);
410 0 : p1b->protocol1->datapth.buf=NULL;
411 0 : iobuf_from_str(&cb->protocol1->datapth, CMD_DATAPTH, newdatapth);
412 0 : newdatapth=NULL;
413 0 : iobuf_move(&cb->endfile, &hb->endfile);
414 :
415 0 : ret=1;
416 : end:
417 0 : free_w(&newdatapth_full);
418 0 : free_w(&olddatapth_full);
419 0 : free_w(&newdatapth);
420 0 : free_w(&relinkpath_full);
421 0 : sbuf_free(&hb);
422 0 : return ret;
423 : }
424 :
425 4 : static int librsync_enabled(struct sbuf *p1b,
426 : struct sbuf *cb,
427 : struct conf **cconfs)
428 : {
429 : off_t max_size;
430 4 : if(!get_int(cconfs[OPT_LIBRSYNC]))
431 : return 0;
432 4 : max_size=(off_t)get_uint64_t(cconfs[OPT_LIBRSYNC_MAX_SIZE]);
433 4 : if(!max_size)
434 : return 1;
435 0 : return max_size >= cb->statp.st_size && max_size >= p1b->statp.st_size;
436 : }
437 :
438 10 : static enum processed_e maybe_do_delta_stuff(struct asfd *asfd,
439 : struct dpth *dpth,
440 : struct sdirs *sdirs, struct sbuf *cb, struct sbuf *p1b,
441 : struct manio *ucmanio, struct manio **hmanio, struct conf **cconfs)
442 : {
443 10 : int oldcompressed=0;
444 10 : int compression=p1b->compression;
445 :
446 : // If the file type changed, I think it is time to back it up again
447 : // (for example, EFS changing to normal file, or back again).
448 10 : if(cb->path.cmd!=p1b->path.cmd)
449 : {
450 0 : if(hmanio && *hmanio
451 0 : && cb->path.cmd==CMD_HARD_LINK
452 0 : && (p1b->path.cmd==CMD_FILE
453 0 : || p1b->path.cmd==CMD_ENC_FILE))
454 : {
455 0 : struct stat *p1statp=&p1b->statp;
456 0 : struct stat *cstatp=&cb->statp;
457 : // A hardlink changed into a file. It is possible that
458 : // The file that the hardlink was pointing to got
459 : // deleted. Maybe we can reuse the previous file.
460 0 : if(p1statp->st_dev==cstatp->st_dev
461 0 : && p1statp->st_ino==cstatp->st_ino
462 0 : && p1statp->st_mtime==cstatp->st_mtime)
463 : {
464 0 : switch(relink_deleted_hardlink_master(
465 : dpth, hmanio, sdirs,
466 : p1b, cb, cconfs))
467 : {
468 : case 0:
469 : break;
470 : case 1:
471 0 : return process_unchanged_file(
472 : p1b, cb,
473 : ucmanio, cconfs);
474 : default:
475 : return P_ERROR;
476 : }
477 : }
478 : }
479 0 : return process_new(cconfs, p1b, ucmanio);
480 : }
481 :
482 : // mtime is the actual file data.
483 : // ctime is the attributes or meta data.
484 10 : if(cb->statp.st_mtime==p1b->statp.st_mtime
485 6 : && cb->statp.st_ctime==p1b->statp.st_ctime)
486 : {
487 : // got an unchanged file
488 : //logp("got unchanged file: %s %c\n",
489 : // iobuf_to_printable(&cb->path), p1b->path.cmd);
490 6 : return process_unchanged_file(p1b, cb, ucmanio, cconfs);
491 : }
492 :
493 4 : if(cb->statp.st_mtime==p1b->statp.st_mtime
494 0 : && cb->statp.st_ctime!=p1b->statp.st_ctime)
495 : {
496 : // File data stayed the same, but attributes or meta data
497 : // changed. We already have the attributes, but may need to get
498 : // extra meta data.
499 : // FIX THIS horrible mess.
500 0 : if(cb->path.cmd==CMD_ENC_METADATA
501 0 : || p1b->path.cmd==CMD_ENC_METADATA
502 0 : || cb->path.cmd==CMD_EFS_FILE
503 0 : || p1b->path.cmd==CMD_EFS_FILE
504 : // FIX THIS: make unencrypted metadata use the librsync
505 0 : || cb->path.cmd==CMD_METADATA
506 0 : || p1b->path.cmd==CMD_METADATA
507 0 : || sbuf_is_vssdata(cb)
508 0 : || sbuf_is_vssdata(p1b))
509 0 : return process_new(cconfs, p1b, ucmanio);
510 : // On Windows, we have to back up the whole file if ctime
511 : // changed, otherwise things like permission changes do not get
512 : // noticed. So, in that case, fall through to the changed stuff
513 : // below.
514 : // Non-Windows clients finish here.
515 0 : else if(!get_int(cconfs[OPT_CLIENT_IS_WINDOWS]))
516 0 : return process_unchanged_file(p1b,
517 : cb, ucmanio, cconfs);
518 : }
519 :
520 : // Got a changed file.
521 : //logp("got changed file: %s\n", iobuf_to_printable(&p1b->path));
522 :
523 : // If either old or new is encrypted, or librsync is off, we need to
524 : // get a new file.
525 : // FIX THIS horrible mess.
526 4 : if(!librsync_enabled(p1b, cb, cconfs)
527 : // FIX THIS: make unencrypted metadata use the librsync
528 4 : || cb->path.cmd==CMD_METADATA
529 4 : || p1b->path.cmd==CMD_METADATA
530 4 : || sbuf_is_encrypted(cb)
531 2 : || sbuf_is_encrypted(p1b)
532 2 : || sbuf_is_vssdata(cb)
533 2 : || sbuf_is_vssdata(p1b))
534 2 : return process_new(cconfs, p1b, ucmanio);
535 :
536 : // Get new files if they have switched between compression on or off.
537 2 : if(cb->protocol1->datapth.buf
538 2 : && dpth_protocol1_is_compressed(cb->compression,
539 : cb->protocol1->datapth.buf))
540 0 : oldcompressed=1;
541 4 : if( ( oldcompressed && !compression)
542 2 : || (!oldcompressed && compression))
543 0 : return process_new(cconfs, p1b, ucmanio);
544 :
545 : // Otherwise, do the delta stuff (if possible).
546 2 : if(sbuf_is_filedata(p1b)
547 0 : || sbuf_is_vssdata(p1b))
548 2 : return process_changed_file(asfd, cconfs, cb, p1b,
549 2 : sdirs->currentdata);
550 0 : return changed_non_file(p1b, ucmanio, p1b->path.cmd, cconfs);
551 : }
552 :
553 : static enum processed_e process_deleted_file(struct sbuf *cb,
554 : struct conf **cconfs)
555 : {
556 2 : cntr_add_deleted(get_cntr(cconfs), cb->path.cmd);
557 : return P_DONE_DELETED;
558 : }
559 :
560 : // return 1 to say that a file was processed
561 12 : static enum processed_e maybe_process_file(struct asfd *asfd,
562 : struct dpth *dpth,
563 : struct sdirs *sdirs, struct sbuf *cb, struct sbuf *p1b,
564 : struct manio *ucmanio, struct manio **hmanio, struct conf **cconfs)
565 : {
566 : int pcmp;
567 12 : if(p1b)
568 : {
569 11 : if(!(pcmp=sbuf_pathcmp(cb, p1b)))
570 10 : return maybe_do_delta_stuff(asfd, dpth,sdirs, cb, p1b,
571 : ucmanio, hmanio, cconfs);
572 1 : else if(pcmp>0)
573 : {
574 : //logp("ahead: %s\n", iobuf_to_printable(&p1b->path));
575 : // ahead - need to get the whole file
576 0 : return process_new(cconfs, p1b, ucmanio);
577 : }
578 : }
579 : //logp("behind: %s\n", iobuf_to_printable(&p1b->path));
580 : // Behind - need to read more from the old manifest.
581 : // Count a deleted file - it was in the old manifest
582 : // but not the new.
583 4 : return process_deleted_file(cb, cconfs);
584 : }
585 :
586 : enum sts_e
587 : {
588 : STS_ERROR=-1,
589 : STS_OK=0,
590 : STS_BLOCKED=1
591 : };
592 :
593 : // Return 1 if there is still stuff needing to be sent.
594 : // FIX THIS: lots of repeated code.
595 63 : static enum sts_e do_stuff_to_send(struct asfd *asfd,
596 : struct sbuf *p1b, char **last_requested)
597 : {
598 : static struct iobuf wbuf;
599 63 : if(p1b->flags & SBUF_SEND_DATAPTH)
600 : {
601 2 : iobuf_copy(&wbuf, &p1b->protocol1->datapth);
602 2 : switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
603 : {
604 : case APPEND_OK: break;
605 : case APPEND_BLOCKED: return STS_BLOCKED;
606 0 : default: return STS_ERROR;
607 : }
608 2 : p1b->flags &= ~SBUF_SEND_DATAPTH;
609 : }
610 63 : if(p1b->flags & SBUF_SEND_STAT)
611 : {
612 56 : iobuf_copy(&wbuf, &p1b->attr);
613 56 : switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
614 : {
615 : case APPEND_OK: break;
616 : case APPEND_BLOCKED: return STS_BLOCKED;
617 0 : default: return STS_ERROR;
618 : }
619 56 : p1b->flags &= ~SBUF_SEND_STAT;
620 : }
621 63 : if(p1b->flags & SBUF_SEND_PATH)
622 : {
623 56 : iobuf_copy(&wbuf, &p1b->path);
624 56 : switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
625 : {
626 : case APPEND_OK: break;
627 : case APPEND_BLOCKED: return STS_BLOCKED;
628 0 : default: return STS_ERROR;
629 : }
630 56 : p1b->flags &= ~SBUF_SEND_PATH;
631 56 : free_w(last_requested);
632 56 : if(!(*last_requested=strdup_w(p1b->path.buf, __func__)))
633 : return STS_ERROR;
634 : }
635 63 : if(p1b->protocol1->sigjob && !(p1b->flags & SBUF_SEND_ENDOFSIG))
636 : {
637 : rs_result sigresult;
638 :
639 4 : switch((sigresult=rs_async(p1b->protocol1->sigjob,
640 : &(p1b->protocol1->rsbuf),
641 : p1b->protocol1->infb, p1b->protocol1->outfb)))
642 : {
643 : case RS_DONE:
644 2 : p1b->flags |= SBUF_SEND_ENDOFSIG;
645 2 : break;
646 : case RS_BLOCKED:
647 : case RS_RUNNING:
648 : // keep going round the loop.
649 : return STS_BLOCKED;
650 : default:
651 0 : logp("error in rs_async: %d %s\n",
652 : sigresult, rs_strerror(sigresult));
653 0 : return STS_ERROR;
654 : }
655 : }
656 61 : if(p1b->flags & SBUF_SEND_ENDOFSIG)
657 : {
658 2 : iobuf_from_str(&wbuf, CMD_END_FILE, (char *)"endfile");
659 2 : switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
660 : {
661 : case APPEND_OK: break;
662 : case APPEND_BLOCKED: return STS_BLOCKED;
663 0 : default: return STS_ERROR;
664 : }
665 2 : p1b->flags &= ~SBUF_SEND_ENDOFSIG;
666 : }
667 : return STS_OK;
668 : }
669 :
670 4 : static int start_to_receive_delta(struct sdirs *sdirs, struct sbuf *rb)
671 : {
672 4 : if(rb->compression)
673 : {
674 0 : if(!(rb->protocol1->fzp=fzp_gzopen(sdirs->deltmppath,
675 0 : comp_level(rb->compression))))
676 : return -1;
677 : }
678 : else
679 : {
680 4 : if(!(rb->protocol1->fzp=fzp_open(sdirs->deltmppath, "wb")))
681 : return -1;
682 : }
683 4 : rb->flags |= SBUF_RECV_DELTA;
684 :
685 : return 0;
686 : }
687 :
688 4 : static int finish_delta(struct sdirs *sdirs, struct sbuf *rb)
689 : {
690 4 : int ret=0;
691 4 : char *deltmp=NULL;
692 4 : char *delpath=NULL;
693 4 : if(!(deltmp=prepend_s("deltas.forward", rb->protocol1->datapth.buf))
694 4 : || !(delpath=prepend_s(sdirs->working, deltmp))
695 4 : || mkpath(&delpath, sdirs->working)
696 : // Rename race condition is of no consequence here, as delpath will
697 : // just get recreated.
698 4 : || do_rename(sdirs->deltmppath, delpath))
699 : ret=-1;
700 4 : free_w(&delpath);
701 4 : free_w(&deltmp);
702 4 : return ret;
703 : }
704 :
705 8 : static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs,
706 : struct sbuf *rb, struct manio *chmanio, struct conf **cconfs,
707 : char **last_requested)
708 : {
709 8 : int ret=-1;
710 : static char *cp=NULL;
711 : static struct iobuf *rbuf;
712 8 : struct cntr *cntr=get_cntr(cconfs);
713 8 : rbuf=asfd->rbuf;
714 : // Finished the file.
715 : // Write it to the phase2 file, and free the buffers.
716 :
717 8 : if(fzp_close(&(rb->protocol1->fzp)))
718 : {
719 0 : logp("error closing delta for %s in receive\n",
720 : iobuf_to_printable(&rb->path));
721 : goto end;
722 : }
723 8 : iobuf_move(&rb->endfile, rbuf);
724 8 : if(rb->flags & SBUF_RECV_DELTA && finish_delta(sdirs, rb))
725 : goto end;
726 :
727 8 : if(manio_write_sbuf(chmanio, rb))
728 : goto end;
729 :
730 8 : if(rb->flags & SBUF_RECV_DELTA)
731 4 : cntr_add_changed(cntr, rb->path.cmd);
732 : else
733 4 : cntr_add(cntr, rb->path.cmd, 0);
734 :
735 8 : if(*last_requested && !strcmp(rb->path.buf, *last_requested))
736 2 : free_w(last_requested);
737 :
738 8 : cp=strchr(rb->endfile.buf, ':');
739 8 : if(rb->endfile.buf)
740 8 : cntr_add_bytes(cntr, strtoull(rb->endfile.buf, NULL, 10));
741 : if(cp)
742 : {
743 : // checksum stuff goes here
744 : }
745 :
746 8 : ret=0;
747 : end:
748 8 : sbuf_free_content(rb);
749 8 : return ret;
750 : }
751 :
752 8 : static int deal_with_receive_append(struct asfd *asfd, struct sbuf *rb)
753 : {
754 8 : int app=0;
755 : static struct iobuf *rbuf;
756 8 : rbuf=asfd->rbuf;
757 : //logp("rbuf->len: %d\n", rbuf->len);
758 :
759 8 : if(rb->protocol1->fzp)
760 8 : app=fzp_write(rb->protocol1->fzp, rbuf->buf, rbuf->len);
761 :
762 8 : if(app>0) return 0;
763 0 : logp("error when appending: %d\n", app);
764 0 : asfd->write_str(asfd, CMD_ERROR, "write failed");
765 : return -1;
766 : }
767 :
768 8 : static int deal_with_filedata(struct asfd *asfd,
769 : struct sdirs *sdirs, struct sbuf *rb,
770 : struct iobuf *rbuf, struct dpth *dpth, struct conf **cconfs)
771 : {
772 8 : iobuf_move(&rb->path, rbuf);
773 :
774 8 : if(rb->protocol1->datapth.buf)
775 : {
776 : // Receiving a delta.
777 4 : if(start_to_receive_delta(sdirs, rb))
778 : {
779 0 : logp("error in start_to_receive_delta\n");
780 0 : return -1;
781 : }
782 : return 0;
783 : }
784 :
785 : // Receiving a whole new file.
786 4 : if(start_to_receive_new_file(asfd, sdirs, cconfs, rb, dpth))
787 : {
788 0 : logp("error in start_to_receive_new_file\n");
789 0 : return -1;
790 : }
791 : return 0;
792 : }
793 :
794 : enum str_e
795 : {
796 : STR_ERROR=-1,
797 : STR_OK=0,
798 : STR_FINISHED=1
799 : };
800 :
801 : // returns 1 for finished ok.
802 85 : static enum str_e do_stuff_to_receive(struct asfd *asfd,
803 : struct sdirs *sdirs, struct conf **cconfs,
804 : struct sbuf *rb, struct manio *chmanio,
805 : struct dpth *dpth, char **last_requested)
806 : {
807 85 : struct iobuf *rbuf=asfd->rbuf;
808 :
809 170 : if(rbuf->cmd==CMD_MESSAGE
810 85 : || rbuf->cmd==CMD_WARNING)
811 : {
812 0 : struct cntr *cntr=NULL;
813 0 : if(cconfs) cntr=get_cntr(cconfs);
814 0 : log_recvd(rbuf, cntr, 0);
815 0 : return STR_OK;
816 : }
817 :
818 85 : if(rb->protocol1->fzp)
819 : {
820 : // Currently writing a file (or meta data)
821 16 : switch(rbuf->cmd)
822 : {
823 : case CMD_APPEND:
824 8 : if(deal_with_receive_append(asfd, rb))
825 : goto error;
826 : return STR_OK;
827 : case CMD_END_FILE:
828 8 : if(deal_with_receive_end_file(asfd, sdirs, rb,
829 : chmanio, cconfs, last_requested))
830 : goto error;
831 : return STR_OK;
832 : case CMD_INTERRUPT:
833 0 : if(*last_requested
834 0 : && !strcmp(rbuf->buf, *last_requested))
835 0 : free_w(last_requested);
836 0 : fzp_close(&(rb->protocol1->fzp));
837 0 : sbuf_free_content(rb);
838 0 : return STR_OK;
839 : default:
840 0 : iobuf_log_unexpected(rbuf, __func__);
841 0 : goto error;
842 : }
843 : }
844 :
845 : // Otherwise, expecting to be told of a file to save.
846 69 : switch(rbuf->cmd)
847 : {
848 : case CMD_DATAPTH:
849 4 : if(iobuf_relative_path_attack(rbuf))
850 : goto error;
851 4 : iobuf_move(&rb->protocol1->datapth, rbuf);
852 4 : return STR_OK;
853 : case CMD_ATTRIBS:
854 8 : iobuf_move(&rb->attr, rbuf);
855 8 : attribs_decode(rb);
856 8 : return STR_OK;
857 : case CMD_GEN:
858 5 : if(!strcmp(rbuf->buf, "okbackupphase2end"))
859 : goto end_phase2;
860 0 : iobuf_log_unexpected(rbuf, __func__);
861 0 : goto error;
862 : case CMD_INTERRUPT:
863 : // Interrupt - forget about the last requested
864 : // file if it matches. Otherwise, we can get
865 : // stuck on the select in the async stuff,
866 : // waiting for something that will never arrive.
867 44 : if(*last_requested
868 44 : && !strcmp(rbuf->buf, *last_requested))
869 1 : free_w(last_requested);
870 : return STR_OK;
871 : default:
872 : break;
873 : }
874 8 : if(iobuf_is_filedata(rbuf)
875 0 : || iobuf_is_vssdata(rbuf))
876 : {
877 8 : if(deal_with_filedata(asfd, sdirs, rb, rbuf, dpth, cconfs))
878 : goto error;
879 : return STR_OK;
880 : }
881 0 : iobuf_log_unexpected(rbuf, __func__);
882 :
883 : error:
884 : return STR_ERROR;
885 : end_phase2:
886 : return STR_FINISHED;
887 : }
888 :
889 5 : static int vss_opts_changed(struct sdirs *sdirs, struct conf **cconfs,
890 : const char *incexc)
891 : {
892 5 : int ret=-1;
893 : struct conf **oldconfs;
894 : struct conf **newconfs;
895 5 : if(!(oldconfs=confs_alloc())
896 5 : || !(newconfs=confs_alloc()))
897 : goto end;
898 5 : confs_init(oldconfs);
899 5 : confs_init(newconfs);
900 :
901 : // Figure out the old config, which is in the incexc file left
902 : // in the current backup directory on the server.
903 5 : if(is_reg_lstat(sdirs->cincexc)<=0
904 1 : || conf_parse_incexcs_path(oldconfs, sdirs->cincexc))
905 : {
906 : // Assume that the file did not exist, and therefore
907 : // the old split_vss setting is 0.
908 4 : set_int(oldconfs[OPT_SPLIT_VSS], 0);
909 4 : set_int(oldconfs[OPT_STRIP_VSS], 0);
910 : }
911 :
912 : // Figure out the new config, which is either in the incexc file from
913 : // the client, or in the cconf on the server.
914 5 : if(incexc)
915 : {
916 0 : if(conf_parse_incexcs_buf(newconfs, incexc))
917 : {
918 : // Should probably not got here.
919 0 : set_int(newconfs[OPT_SPLIT_VSS], 0);
920 0 : set_int(newconfs[OPT_STRIP_VSS], 0);
921 : }
922 : }
923 : else
924 : {
925 5 : set_int(newconfs[OPT_SPLIT_VSS],
926 5 : get_int(cconfs[OPT_SPLIT_VSS]));
927 5 : set_int(newconfs[OPT_STRIP_VSS],
928 5 : get_int(cconfs[OPT_STRIP_VSS]));
929 : }
930 :
931 5 : if(get_int(newconfs[OPT_SPLIT_VSS])!=get_int(oldconfs[OPT_SPLIT_VSS]))
932 : {
933 0 : logp("split_vss=%d (changed since last backup)\n",
934 0 : get_int(newconfs[OPT_SPLIT_VSS]));
935 0 : ret=1; goto end;
936 : }
937 5 : if(get_int(newconfs[OPT_STRIP_VSS])!=get_int(oldconfs[OPT_STRIP_VSS]))
938 : {
939 0 : logp("strip_vss=%d (changed since last backup)\n",
940 0 : get_int(newconfs[OPT_STRIP_VSS]));
941 0 : ret=1; goto end;
942 : }
943 : ret=0;
944 : end:
945 5 : if(ret==1) logp("All files will be treated as new\n");
946 5 : confs_free(&oldconfs);
947 5 : confs_free(&newconfs);
948 5 : return ret;
949 : }
950 :
951 : // Maybe open the previous (current) manifest.
952 : // If the split_vss setting changed between the previous backup and the new
953 : // backup, do not open the previous manifest. This will have the effect of
954 : // making the client back up everything fresh. Need to do this, otherwise
955 : // toggling split_vss on and off will result in backups that do not work.
956 5 : static int maybe_open_previous_manifest(struct manio **manio,
957 : struct sdirs *sdirs, const char *incexc, struct conf **cconfs)
958 : {
959 5 : if(vss_opts_changed(sdirs, cconfs, incexc))
960 : return 0;
961 5 : return open_previous_manifest(manio, sdirs);
962 : }
963 :
964 135 : static int process_next_file_from_manios(struct asfd *asfd,
965 : struct dpth *dpth,
966 : struct sdirs *sdirs,
967 : struct manio **p1manio,
968 : struct manio **cmanio,
969 : struct manio *ucmanio,
970 : struct manio **hmanio,
971 : struct sbuf **p1b,
972 : struct sbuf *cb,
973 : struct conf **cconfs)
974 : {
975 135 : if(!(*p1b=sbuf_alloc(PROTO_1)))
976 : goto error;
977 135 : switch(manio_read(*p1manio, *p1b))
978 : {
979 : case 0:
980 : break;
981 : case 1:
982 5 : manio_close(p1manio);
983 5 : if(asfd->write_str(asfd, CMD_GEN, "backupphase2end"))
984 : goto error;
985 5 : sbuf_free(p1b);
986 5 : break;
987 : case -1:
988 : goto error;
989 : }
990 :
991 135 : if(!*cmanio)
992 : {
993 124 : if(!*p1b) return 0;
994 : // No old manifest, need to ask for a new file.
995 120 : switch(process_new(cconfs, *p1b, ucmanio))
996 : {
997 : case P_NEW:
998 : return 0;
999 : case P_DONE_NEW:
1000 : goto p1b_done;
1001 : default:
1002 : goto error;
1003 : }
1004 : }
1005 :
1006 : // Have an old manifest, look for it there.
1007 :
1008 : // Might already have it, or be ahead in the old
1009 : // manifest.
1010 11 : if(cb->path.buf)
1011 : {
1012 2 : switch(maybe_process_file(asfd, dpth,
1013 : sdirs, cb, *p1b, ucmanio, hmanio, cconfs))
1014 : {
1015 : case P_NEW:
1016 : return 0;
1017 : case P_CHANGED:
1018 : // Free cb content for things like encrypted
1019 : // files, which we only pretend are new.
1020 0 : sbuf_free_content(cb);
1021 0 : return 0;
1022 : case P_DONE_NEW:
1023 : goto p1b_done;
1024 : case P_DONE_CHANGED:
1025 : case P_DONE_UNCHANGED:
1026 0 : sbuf_free_content(cb);
1027 0 : goto p1b_done;
1028 : case P_DONE_DELETED:
1029 2 : sbuf_free_content(cb);
1030 2 : break;
1031 : case P_ERROR:
1032 : goto error;
1033 : }
1034 : }
1035 :
1036 : while(1)
1037 : {
1038 11 : sbuf_free_content(cb);
1039 11 : switch(manio_read(*cmanio, cb))
1040 : {
1041 : case 0: break;
1042 1 : case 1: manio_close(cmanio);
1043 1 : if(*p1b) switch(process_new(cconfs,
1044 : *p1b, ucmanio))
1045 : {
1046 : case P_NEW:
1047 : return 0;
1048 : case P_DONE_NEW:
1049 : goto p1b_done;
1050 : default:
1051 : goto error;
1052 : }
1053 : return 0;
1054 : case -1: goto error;
1055 : }
1056 10 : switch(maybe_process_file(asfd, dpth, sdirs,
1057 : cb, *p1b, ucmanio, hmanio, cconfs))
1058 : {
1059 : case P_NEW:
1060 : return 0;
1061 : case P_CHANGED:
1062 : // Free cb content for things like encrypted
1063 : // files, which we only pretend are new.
1064 2 : sbuf_free_content(cb);
1065 2 : return 0;
1066 : case P_DONE_NEW:
1067 : goto p1b_done;
1068 : case P_DONE_CHANGED:
1069 : case P_DONE_UNCHANGED:
1070 6 : sbuf_free_content(cb);
1071 6 : goto p1b_done;
1072 : case P_DONE_DELETED:
1073 0 : sbuf_free_content(cb);
1074 0 : continue;
1075 : case P_ERROR:
1076 : goto error;
1077 : }
1078 : }
1079 : error:
1080 : return -1;
1081 : p1b_done:
1082 74 : sbuf_free(p1b);
1083 74 : return 0;
1084 : }
1085 :
1086 10 : int backup_phase2_server_protocol1(struct async *as, struct sdirs *sdirs,
1087 : const char *incexc, int resume, struct conf **cconfs)
1088 : {
1089 10 : int ret=0;
1090 10 : man_off_t *p1pos=NULL;
1091 10 : struct manio *p1manio=NULL;
1092 10 : struct dpth *dpth=NULL;
1093 10 : char *deltmppath=NULL;
1094 10 : char *last_requested=NULL;
1095 10 : struct manio *chmanio=NULL; // changed data
1096 10 : struct manio *ucmanio=NULL; // unchanged data
1097 10 : struct manio *cmanio=NULL; // previous (current) manifest
1098 10 : struct manio *hmanio=NULL; // to look up deleted hardlinks
1099 10 : struct sbuf *cb=NULL; // file list in current manifest
1100 10 : struct sbuf *p1b=NULL; // file list from client
1101 10 : struct sbuf *rb=NULL; // receiving file from client
1102 10 : struct asfd *asfd=NULL;
1103 10 : int breaking=0;
1104 10 : int breakcount=0;
1105 10 : struct cntr *cntr=NULL;
1106 10 : struct cntr_ent *warn_ent=NULL;
1107 10 : int fail_on_warning=0;
1108 :
1109 10 : if(!as)
1110 : {
1111 1 : logp("async not provided to %s()\n", __func__);
1112 1 : goto error;
1113 : }
1114 9 : if(!sdirs)
1115 : {
1116 2 : logp("sdirs not provided to %s()\n", __func__);
1117 2 : goto error;
1118 : }
1119 7 : if(!cconfs)
1120 : {
1121 1 : logp("cconfs not provided to %s()\n", __func__);
1122 1 : goto error;
1123 : }
1124 6 : asfd=as->asfd;
1125 6 : if(!asfd)
1126 : {
1127 1 : logp("asfd not provided to %s()\n", __func__);
1128 1 : goto error;
1129 : }
1130 5 : cntr=get_cntr(cconfs);
1131 5 : fail_on_warning=get_int(cconfs[OPT_FAIL_ON_WARNING]);
1132 5 : if(cntr)
1133 0 : warn_ent=cntr->ent[CMD_WARNING];
1134 :
1135 5 : if(get_int(cconfs[OPT_BREAKPOINT])>=2000
1136 0 : && get_int(cconfs[OPT_BREAKPOINT])<3000)
1137 : {
1138 0 : breaking=get_int(cconfs[OPT_BREAKPOINT]);
1139 0 : breakcount=breaking-2000;
1140 : }
1141 :
1142 5 : logp("Begin phase2 (receive file data)\n");
1143 :
1144 5 : if(!(dpth=dpth_alloc())
1145 5 : || dpth_protocol1_init(dpth, sdirs->currentdata,
1146 : get_int(cconfs[OPT_MAX_STORAGE_SUBDIRS])))
1147 : goto error;
1148 :
1149 5 : if(maybe_open_previous_manifest(&cmanio, sdirs, incexc, cconfs))
1150 : goto error;
1151 : // If the first file that others hardlink to has been deleted, we will
1152 : // need to look through the previous manifest to find the information
1153 : // for that original file, in order to not have to copy all the data
1154 : // across again.
1155 5 : if(open_previous_manifest(&hmanio, sdirs))
1156 : goto error;
1157 :
1158 5 : if(get_int(cconfs[OPT_DIRECTORY_TREE]))
1159 : {
1160 : // Need to make sure we do not try to create a path that is
1161 : // too long.
1162 5 : if(build_path_w(sdirs->treepath)) goto error;
1163 5 : mkdir(sdirs->treepath, 0777);
1164 5 : treepathlen=strlen(sdirs->treepath);
1165 5 : if(init_fs_max(sdirs->treepath))
1166 : goto error;
1167 : }
1168 :
1169 5 : if(resume)
1170 : {
1171 0 : if(!(p1pos=do_resume(sdirs, dpth, cconfs)))
1172 : goto error;
1173 0 : if(cntr_send_sdirs(asfd, sdirs, cconfs, CNTR_STATUS_BACKUP))
1174 : goto error;
1175 : }
1176 :
1177 5 : if(!(p1manio=manio_open_phase1(sdirs->phase1data, "rb", PROTO_1))
1178 5 : || (resume && manio_seek(p1manio, p1pos)))
1179 : goto error;
1180 5 : if(!(cb=sbuf_alloc(PROTO_1))
1181 5 : || !(p1b=sbuf_alloc(PROTO_1))
1182 5 : || !(rb=sbuf_alloc(PROTO_1)))
1183 : goto error;
1184 :
1185 : // Unchanged and changed should now be truncated correctly, we just
1186 : // have to open them for appending.
1187 : // Data is not getting written to a compressed file.
1188 : // This is important for recovery if the power goes.
1189 5 : if(!(ucmanio=manio_open_phase2(sdirs->unchanged, "ab", PROTO_1))
1190 5 : || !(chmanio=manio_open_phase2(sdirs->changed, "ab", PROTO_1)))
1191 : goto error;
1192 :
1193 : while(1)
1194 : {
1195 921 : if(check_fail_on_warning(fail_on_warning, warn_ent))
1196 : goto error;
1197 :
1198 921 : if(breaking && breakcount--==0)
1199 0 : return breakpoint(breaking, __func__);
1200 :
1201 921 : if(write_status(CNTR_STATUS_BACKUP,
1202 921 : rb->path.buf?rb->path.buf:"", cntr))
1203 : goto error;
1204 1842 : if(last_requested
1205 921 : || !p1manio
1206 16 : || asfd->writebuflen)
1207 : {
1208 905 : iobuf_free_content(asfd->rbuf);
1209 905 : if(asfd->as->read_write(asfd->as))
1210 : {
1211 0 : logp("error in %s\n", __func__);
1212 0 : goto error;
1213 : }
1214 :
1215 905 : if(asfd->rbuf->buf)
1216 85 : switch(do_stuff_to_receive(asfd, sdirs,
1217 : cconfs, rb, chmanio, dpth, &last_requested))
1218 : {
1219 : case STR_OK:
1220 : break;
1221 : case STR_FINISHED:
1222 5 : if(check_fail_on_warning(
1223 : fail_on_warning, warn_ent))
1224 : goto error;
1225 : goto end;
1226 : case STR_ERROR:
1227 : goto error;
1228 : }
1229 : }
1230 :
1231 916 : if(p1b) switch(do_stuff_to_send(asfd, p1b, &last_requested))
1232 : {
1233 : case STS_OK:
1234 61 : sbuf_free(&p1b);
1235 61 : break;
1236 : case STS_BLOCKED:
1237 2 : continue;
1238 : case STS_ERROR:
1239 : goto error;
1240 : }
1241 :
1242 914 : if(p1manio
1243 135 : && process_next_file_from_manios(asfd, dpth, sdirs,
1244 : &p1manio, &cmanio, ucmanio, &hmanio, &p1b, cb, cconfs))
1245 : goto error;
1246 : }
1247 :
1248 : error:
1249 5 : ret=-1;
1250 5 : if(p1b)
1251 0 : logp(" last tried file: %s\n",
1252 : iobuf_to_printable(&p1b->path));
1253 : end:
1254 10 : if(manio_close(&chmanio))
1255 : {
1256 0 : logp("error closing %s in %s\n", sdirs->changed, __func__);
1257 0 : ret=-1;
1258 : }
1259 10 : if(manio_close(&ucmanio))
1260 : {
1261 0 : logp("error closing %s in %s\n", sdirs->unchanged, __func__);
1262 0 : ret=-1;
1263 : }
1264 10 : free_w(&deltmppath);
1265 10 : free_w(&last_requested);
1266 10 : sbuf_free(&cb);
1267 10 : sbuf_free(&p1b);
1268 10 : sbuf_free(&rb);
1269 10 : manio_close(&p1manio);
1270 10 : manio_close(&cmanio);
1271 10 : manio_close(&hmanio);
1272 10 : dpth_free(&dpth);
1273 10 : man_off_t_free(&p1pos);
1274 10 : if(!ret && sdirs)
1275 5 : unlink(sdirs->phase1data);
1276 :
1277 10 : logp("End phase2 (receive file data)\n");
1278 :
1279 10 : return ret;
1280 : }
|