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 "../../bfile.h"
7 : #include "../../cmd.h"
8 : #include "../../cntr.h"
9 : #include "../../fsops.h"
10 : #include "../../log.h"
11 : #include "../../sbuf.h"
12 : #include "../extrameta.h"
13 : #include "../restore.h"
14 : #include "restore.h"
15 :
16 14 : int write_protocol2_data(struct asfd *asfd,
17 : struct BFILE *bfd, struct blk *blk, enum vss_restore vss_restore)
18 : {
19 14 : if(bfd->mode==BF_CLOSED)
20 0 : logp("Got data without an open file\n");
21 : else
22 : {
23 : int w;
24 14 : if((w=bfd->write(bfd, blk->data, blk->length))<=0)
25 : {
26 0 : logp("%s(): error when appending %d: %d\n",
27 : __func__, blk->length, w);
28 0 : asfd->write_str(asfd, CMD_ERROR, "write failed");
29 0 : return -1;
30 : }
31 : }
32 : return 0;
33 : }
34 :
35 14 : static int start_restore_file(struct asfd *asfd,
36 : struct BFILE *bfd,
37 : struct sbuf *sb,
38 : const char *fname,
39 : enum action act,
40 : enum vss_restore vss_restore,
41 : struct cntr *cntr)
42 : {
43 14 : int ret=-1;
44 14 : char *rpath=NULL;
45 :
46 14 : if(act==ACTION_VERIFY)
47 : {
48 0 : cntr_add(cntr, sb->path.cmd, 1);
49 0 : goto end;
50 : }
51 :
52 14 : if(build_path(fname, "", &rpath, NULL))
53 : {
54 0 : char msg[256]="";
55 : // Failed - do a warning.
56 0 : snprintf(msg, sizeof(msg), "build path failed: %s", fname);
57 0 : if(restore_interrupt(asfd, sb, msg, cntr, PROTO_2))
58 : goto error;
59 0 : goto end; // Try to carry on with other files.
60 : }
61 :
62 14 : switch(open_for_restore(asfd, bfd, rpath, sb, vss_restore, cntr,
63 : PROTO_2))
64 : {
65 : case OFR_OK: break;
66 : case OFR_CONTINUE: goto end;
67 : default: goto error;
68 : }
69 :
70 14 : cntr_add(cntr, sb->path.cmd, 1);
71 :
72 : end:
73 : ret=0;
74 : error:
75 14 : free_w(&rpath);
76 14 : return ret;
77 : }
78 :
79 0 : static int get_meta(
80 : struct asfd *asfd,
81 : struct cntr *cntr,
82 : char **metadata,
83 : size_t *metalen)
84 : {
85 0 : int ret=-1;
86 0 : struct iobuf *rbuf=asfd->rbuf;
87 :
88 : while(1)
89 : {
90 0 : iobuf_free_content(rbuf);
91 0 : if(asfd->read(asfd))
92 : goto end;
93 :
94 0 : switch(rbuf->cmd)
95 : {
96 : case CMD_DATA:
97 0 : if(!(*metadata=(char *)realloc_w(*metadata,
98 0 : (*metalen)+rbuf->len, __func__)))
99 : goto end;
100 0 : memcpy((*metadata)+(*metalen),
101 0 : rbuf->buf, rbuf->len);
102 0 : *metalen+=rbuf->len;
103 0 : break;
104 : case CMD_END_FILE:
105 : ret=0;
106 : goto end;
107 : case CMD_MESSAGE:
108 : case CMD_WARNING:
109 0 : log_recvd(rbuf, cntr, 0);
110 0 : break;
111 : default:
112 0 : iobuf_log_unexpected(rbuf, __func__);
113 0 : goto end;
114 : }
115 : }
116 :
117 : end:
118 0 : iobuf_free_content(rbuf);
119 0 : return ret;
120 : }
121 :
122 0 : static int restore_metadata(
123 : struct asfd *asfd,
124 : struct sbuf *sb,
125 : const char *fname,
126 : enum action act,
127 : struct cntr *cntr)
128 : {
129 : // If it is directory metadata, try to make sure the directory
130 : // exists. Pass in NULL as the cntr, so no counting is done.
131 : // The actual directory entry will be coming after the metadata,
132 : // annoyingly. This is because of the way that the server is queuing
133 : // up directories to send after file data, so that the stat info on
134 : // them gets set correctly.
135 0 : if(act==ACTION_RESTORE)
136 : {
137 0 : size_t metalen=0;
138 0 : char *metadata=NULL;
139 0 : if(S_ISDIR(sb->statp.st_mode)
140 0 : && restore_dir(asfd, sb, fname, act, /*cntr*/NULL, PROTO_2))
141 0 : return -1;
142 :
143 : // Read in the metadata...
144 0 : if(get_meta(asfd, cntr, &metadata, &metalen))
145 : return -1;
146 0 : if(metadata)
147 : {
148 0 : if(set_extrameta(asfd,
149 : #ifdef HAVE_WIN32
150 : NULL,
151 : #endif
152 : fname,
153 : metadata, metalen, cntr))
154 : {
155 0 : free_w(&metadata);
156 : // carry on if we could not do it
157 0 : return 0;
158 : }
159 0 : free_w(&metadata);
160 : #ifndef HAVE_WIN32
161 : // Set file times again, since we just diddled with the
162 : // file. Do not set all attributes, as it will wipe
163 : // out any security attributes (eg getcap /usr/bin/ping)
164 0 : if(attribs_set_file_times(asfd, fname,
165 : &sb->statp, cntr))
166 : return -1;
167 : #endif
168 0 : cntr_add(cntr, sb->path.cmd, 1);
169 : }
170 : }
171 : else
172 0 : cntr_add(cntr, sb->path.cmd, 1);
173 : return 0;
174 : }
175 :
176 0 : static int unsupported_interrupt_and_warn(
177 : struct asfd *asfd,
178 : struct sbuf *sb,
179 : struct cntr *cntr,
180 : const char *fname,
181 : enum action act
182 : ) {
183 0 : char msg[256]="";
184 0 : snprintf(msg, sizeof(msg),
185 : "restore not yet supported for %s: %s",
186 : cmd_to_text(sb->path.cmd), fname);
187 0 : switch(act)
188 : {
189 : case ACTION_RESTORE:
190 0 : if(restore_interrupt(asfd, sb, msg, cntr, PROTO_2))
191 : return -1;
192 : break;
193 : default:
194 0 : if(cntr)
195 : {
196 0 : cntr_add(cntr, CMD_WARNING, 1);
197 0 : logp("WARNING: %s\n", msg);
198 0 : if(asfd->write_str(asfd, CMD_WARNING, msg))
199 : return -1;
200 : }
201 : break;
202 : }
203 : return 0; // Try to carry on with other files.
204 : }
205 :
206 14 : int restore_switch_protocol2(struct asfd *asfd, struct sbuf *sb,
207 : const char *fullpath, enum action act,
208 : struct BFILE *bfd, enum vss_restore vss_restore, struct cntr *cntr)
209 : {
210 14 : switch(sb->path.cmd)
211 : {
212 : case CMD_FILE:
213 : // Have it a separate statement to the
214 : // encrypted version so that encrypted and not
215 : // encrypted files can be restored at the
216 : // same time.
217 14 : if(start_restore_file(asfd,
218 : bfd, sb, fullpath, act,
219 : vss_restore, cntr))
220 : {
221 0 : logp("restore_file error\n");
222 0 : goto error;
223 : }
224 : break;
225 : case CMD_ENC_FILE:
226 : /* FIX THIS: Encryption currently not working in protocol2
227 : if(start_restore_file(asfd,
228 : bfd, sb, fullpath, act,
229 : vss_restore, confs))
230 : {
231 : logp("restore_file error\n");
232 : goto error;
233 : }
234 : */
235 0 : if(unsupported_interrupt_and_warn(
236 : asfd, sb, cntr, fullpath, act))
237 : return -1;
238 : break;
239 : case CMD_METADATA:
240 0 : if(restore_metadata(asfd,
241 : sb, fullpath, act, cntr))
242 : goto error;
243 : break;
244 : case CMD_ENC_METADATA:
245 : /* FIX THIS: Encryption not supported yet.
246 : if(restore_metadata(
247 : bfd, sb, fullpath, act, confs))
248 : goto error;
249 : */
250 0 : if(unsupported_interrupt_and_warn(
251 : asfd, sb, cntr, fullpath, act))
252 : return -1;
253 : break;
254 : case CMD_EFS_FILE:
255 : /* FIX THIS: EFS not supported yet.
256 : if(start_restore_file(asfd,
257 : bfd, sb,
258 : fullpath, act,
259 : vss_restore, confs))
260 : {
261 : logp("restore_file error\n");
262 : goto error;
263 : }
264 : */
265 0 : if(unsupported_interrupt_and_warn(
266 : asfd, sb, cntr, fullpath, act))
267 : return -1;
268 : break;
269 : default:
270 0 : logp("unknown cmd: %c\n", sb->path.cmd);
271 0 : goto error;
272 : }
273 : return 0;
274 : error:
275 : return -1;
276 : }
|