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 0 : static const char *get_rmanifest_relative(struct sdirs *sdirs,
16 : struct conf **confs)
17 : {
18 : const char *cp;
19 0 : cp=sdirs->rmanifest+strlen(get_string(confs[OPT_DIRECTORY]));
20 0 : while(cp && *cp=='/') cp++;
21 0 : return cp;
22 : }
23 :
24 : // Combine the phase1 and phase2 files into a new manifest.
25 0 : int backup_phase3_server_all(struct sdirs *sdirs, struct conf **confs)
26 : {
27 0 : int ret=-1;
28 0 : int pcmp=0;
29 0 : struct blk *blk=NULL;
30 0 : struct sbuf *usb=NULL;
31 0 : struct sbuf *csb=NULL;
32 0 : char *manifesttmp=NULL;
33 0 : struct manio *newmanio=NULL;
34 0 : struct manio *chmanio=NULL;
35 0 : struct manio *unmanio=NULL;
36 0 : enum protocol protocol=get_protocol(confs);
37 0 : struct cntr *cntr=get_cntr(confs);
38 0 : const char *rmanifest_relative=NULL;
39 :
40 0 : logp("Begin phase3 (merge manifests)\n");
41 :
42 0 : if(protocol==PROTO_2)
43 0 : rmanifest_relative=get_rmanifest_relative(sdirs, confs);
44 :
45 0 : if(!(manifesttmp=get_tmp_filename(sdirs->manifest))
46 0 : || !(newmanio=manio_open_phase3(manifesttmp,
47 0 : comp_level(get_int(confs[OPT_COMPRESSION])),
48 0 : protocol, rmanifest_relative))
49 0 : || !(chmanio=manio_open_phase2(sdirs->changed, "rb", protocol))
50 0 : || !(unmanio=manio_open_phase2(sdirs->unchanged, "rb", protocol))
51 0 : || !(usb=sbuf_alloc(protocol))
52 0 : || !(csb=sbuf_alloc(protocol)))
53 0 : goto end;
54 :
55 0 : while(chmanio || unmanio)
56 : {
57 0 : if(!blk && !(blk=blk_alloc())) goto end;
58 :
59 0 : if(unmanio
60 0 : && !usb->path.buf)
61 : {
62 0 : switch(manio_read(unmanio, usb))
63 : {
64 0 : case -1: goto end;
65 0 : case 1: manio_close(&unmanio);
66 : }
67 : }
68 :
69 0 : if(chmanio
70 0 : && !csb->path.buf)
71 : {
72 0 : switch(manio_read(chmanio, csb))
73 : {
74 0 : case -1: goto end;
75 0 : case 1: manio_close(&chmanio);
76 : }
77 : }
78 :
79 0 : if(usb->path.buf && !csb->path.buf)
80 : {
81 0 : if(write_status(CNTR_STATUS_MERGING,
82 0 : usb->path.buf, cntr)) goto end;
83 0 : switch(manio_copy_entry(
84 0 : usb, usb, &blk, unmanio, newmanio))
85 : {
86 0 : case -1: goto end;
87 0 : case 1: manio_close(&unmanio);
88 : }
89 : }
90 0 : else if(!usb->path.buf && csb->path.buf)
91 : {
92 0 : if(write_status(CNTR_STATUS_MERGING,
93 0 : csb->path.buf, cntr)) goto end;
94 0 : switch(manio_copy_entry(
95 0 : csb, csb, &blk, chmanio, newmanio))
96 : {
97 0 : case -1: goto end;
98 0 : case 1: manio_close(&chmanio);
99 : }
100 : }
101 0 : else if(!usb->path.buf && !csb->path.buf)
102 : {
103 0 : continue;
104 : }
105 0 : 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 0 : case -1: goto end;
114 0 : case 1: manio_close(&chmanio);
115 : }
116 : }
117 0 : else if(pcmp<0)
118 : {
119 0 : if(write_status(CNTR_STATUS_MERGING,
120 0 : usb->path.buf, cntr)) goto end;
121 0 : switch(manio_copy_entry(
122 0 : usb, usb, &blk, unmanio, newmanio))
123 : {
124 0 : case -1: goto end;
125 0 : case 1: manio_close(&unmanio);
126 : }
127 : }
128 : else
129 : {
130 0 : if(write_status(CNTR_STATUS_MERGING,
131 0 : csb->path.buf, cntr)) goto end;
132 0 : switch(manio_copy_entry(
133 0 : csb, csb, &blk, chmanio, newmanio))
134 : {
135 0 : case -1: goto end;
136 0 : case 1: manio_close(&chmanio);
137 : }
138 : }
139 : }
140 :
141 : // Flush to disk.
142 0 : 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 0 : if(do_rename(manifesttmp, sdirs->manifest))
152 0 : goto end;
153 : else
154 : {
155 0 : recursive_delete(sdirs->changed);
156 0 : recursive_delete(sdirs->unchanged);
157 : }
158 :
159 0 : logp("End phase3 (merge manifests)\n");
160 0 : ret=0;
161 : end:
162 0 : manio_close(&newmanio);
163 0 : manio_close(&chmanio);
164 0 : manio_close(&unmanio);
165 0 : sbuf_free(&csb);
166 0 : sbuf_free(&usb);
167 0 : blk_free(&blk);
168 0 : free_w(&manifesttmp);
169 0 : return ret;
170 : }
|