Line data Source code
1 : #include "../burp.h"
2 : #include "../alloc.h"
3 : #include "../cntr.h"
4 : #include "../conf.h"
5 : #include "../fsops.h"
6 : #include "../handy.h"
7 : #include "../log.h"
8 : #include "../protocol2/blk.h"
9 : #include "../sbuf.h"
10 : #include "compress.h"
11 : #include "manio.h"
12 : #include "sdirs.h"
13 : #include "child.h"
14 :
15 3 : static const char *get_rmanifest_relative(struct sdirs *sdirs,
16 : struct conf **confs)
17 : {
18 : const char *cp;
19 3 : cp=sdirs->rmanifest+strlen(get_string(confs[OPT_DIRECTORY]));
20 0 : while(cp && *cp=='/') cp++;
21 3 : return cp;
22 : }
23 :
24 : // Combine the phase1 and phase2 files into a new manifest.
25 8 : int backup_phase3_server_all(struct sdirs *sdirs, struct conf **confs)
26 : {
27 5 : int ret=-1;
28 5 : int pcmp=0;
29 5 : struct blk *blk=NULL;
30 5 : struct sbuf *usb=NULL;
31 5 : struct sbuf *csb=NULL;
32 5 : char *manifesttmp=NULL;
33 5 : struct manio *newmanio=NULL;
34 5 : struct manio *chmanio=NULL;
35 5 : struct manio *unmanio=NULL;
36 5 : enum protocol protocol=get_protocol(confs);
37 5 : struct cntr *cntr=get_cntr(confs);
38 5 : const char *rmanifest_relative=NULL;
39 :
40 5 : logp("Begin phase3 (merge manifests)\n");
41 :
42 5 : if(protocol==PROTO_2)
43 3 : rmanifest_relative=get_rmanifest_relative(sdirs, confs);
44 :
45 10 : if(!(manifesttmp=get_tmp_filename(sdirs->manifest))
46 5 : || !(newmanio=manio_open_phase3(manifesttmp,
47 5 : comp_level(get_int(confs[OPT_COMPRESSION])),
48 5 : protocol, rmanifest_relative))
49 5 : || !(chmanio=manio_open_phase2(sdirs->changed, "rb", protocol))
50 5 : || !(unmanio=manio_open_phase2(sdirs->unchanged, "rb", protocol))
51 5 : || !(usb=sbuf_alloc(protocol))
52 10 : || !(csb=sbuf_alloc(protocol)))
53 : goto end;
54 :
55 25 : while(chmanio || unmanio)
56 : {
57 20 : if(!blk && !(blk=blk_alloc())) goto end;
58 :
59 20 : if(unmanio
60 17 : && !usb->path.buf)
61 : {
62 9 : switch(manio_read(unmanio, usb))
63 : {
64 : case -1: goto end;
65 3 : case 1: manio_close(&unmanio);
66 : }
67 : }
68 :
69 20 : if(chmanio
70 18 : && !csb->path.buf)
71 : {
72 9 : switch(manio_read(chmanio, csb))
73 : {
74 : case -1: goto end;
75 2 : case 1: manio_close(&chmanio);
76 : }
77 : }
78 :
79 20 : if(usb->path.buf && !csb->path.buf)
80 : {
81 2 : if(write_status(CNTR_STATUS_MERGING,
82 2 : usb->path.buf, cntr)) goto end;
83 2 : switch(manio_copy_entry(
84 2 : usb, usb, &blk, unmanio, newmanio))
85 : {
86 : case -1: goto end;
87 1 : case 1: manio_close(&unmanio);
88 : }
89 : }
90 18 : else if(!usb->path.buf && csb->path.buf)
91 : {
92 4 : if(write_status(CNTR_STATUS_MERGING,
93 4 : csb->path.buf, cntr)) goto end;
94 4 : switch(manio_copy_entry(
95 4 : csb, csb, &blk, chmanio, newmanio))
96 : {
97 : case -1: goto end;
98 2 : case 1: manio_close(&chmanio);
99 : }
100 : }
101 14 : else if(!usb->path.buf && !csb->path.buf)
102 : {
103 : continue;
104 : }
105 12 : else if(!(pcmp=sbuf_pathcmp(usb, csb)))
106 : {
107 : // They were the same - write one.
108 0 : if(write_status(CNTR_STATUS_MERGING,
109 0 : csb->path.buf, cntr)) goto end;
110 0 : switch(manio_copy_entry(
111 0 : csb, csb, &blk, chmanio, newmanio))
112 : {
113 : case -1: goto end;
114 0 : case 1: manio_close(&chmanio);
115 : }
116 : }
117 12 : else if(pcmp<0)
118 : {
119 6 : if(write_status(CNTR_STATUS_MERGING,
120 6 : usb->path.buf, cntr)) goto end;
121 6 : switch(manio_copy_entry(
122 6 : usb, usb, &blk, unmanio, newmanio))
123 : {
124 : case -1: goto end;
125 1 : case 1: manio_close(&unmanio);
126 : }
127 : }
128 : else
129 : {
130 6 : if(write_status(CNTR_STATUS_MERGING,
131 6 : csb->path.buf, cntr)) goto end;
132 6 : switch(manio_copy_entry(
133 6 : csb, csb, &blk, chmanio, newmanio))
134 : {
135 : case -1: goto end;
136 1 : case 1: manio_close(&chmanio);
137 : }
138 : }
139 : }
140 :
141 : // Flush to disk.
142 5 : if(manio_close(&newmanio))
143 : {
144 : logp("error gzclosing %s in backup_phase3_server\n",
145 0 : manifesttmp);
146 0 : goto end;
147 : }
148 :
149 : // Rename race condition should be of no consequence here, as the
150 : // manifest should just get recreated automatically.
151 5 : if(do_rename(manifesttmp, sdirs->manifest))
152 : goto end;
153 : else
154 : {
155 5 : recursive_delete(sdirs->changed);
156 5 : recursive_delete(sdirs->unchanged);
157 : }
158 :
159 5 : logp("End phase3 (merge manifests)\n");
160 5 : ret=0;
161 : end:
162 5 : manio_close(&newmanio);
163 5 : manio_close(&chmanio);
164 5 : manio_close(&unmanio);
165 5 : sbuf_free(&csb);
166 5 : sbuf_free(&usb);
167 5 : blk_free(&blk);
168 5 : free_w(&manifesttmp);
169 5 : return ret;
170 : }
|