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