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