Line data Source code
1 : #include "../../burp.h"
2 : #include "../../action.h"
3 : #include "../../alloc.h"
4 : #include "../../asfd.h"
5 : #include "../../async.h"
6 : #include "../../attribs.h"
7 : #include "../../bfile.h"
8 : #include "../../cmd.h"
9 : #include "../../cntr.h"
10 : #include "../../fsops.h"
11 : #include "../../handy.h"
12 : #include "../../log.h"
13 : #include "../../protocol1/msg.h"
14 : #include "../extrameta.h"
15 : #include "../restore.h"
16 : #include "restore.h"
17 :
18 4 : static int do_restore_file_or_get_meta(struct asfd *asfd, struct BFILE *bfd,
19 : struct sbuf *sb, const char *fname,
20 : char **metadata, size_t *metalen,
21 : struct cntr *cntr, const char *rpath,
22 : const char *encryption_password)
23 : {
24 4 : int ret=-1;
25 4 : int enccompressed=0;
26 4 : uint64_t rcvdbytes=0;
27 4 : uint64_t sentbytes=0;
28 4 : const char *encpassword=NULL;
29 4 : int key_deriv=0;
30 :
31 4 : if(sbuf_is_encrypted(sb))
32 : {
33 2 : encpassword=encryption_password;
34 2 : if(sb->encryption==ENCRYPTION_KEY_DERIVED)
35 0 : key_deriv=1;
36 : }
37 4 : enccompressed=dpth_protocol1_is_compressed(sb->compression,
38 4 : sb->protocol1->datapth.buf);
39 : /*
40 : printf("%s \n", fname);
41 : if(encpassword && !enccompressed)
42 : printf("encrypted and not compressed\n");
43 : else if(!encpassword && enccompressed)
44 : printf("not encrypted and compressed\n");
45 : else if(!encpassword && !enccompressed)
46 : printf("not encrypted and not compressed\n");
47 : else if(encpassword && enccompressed)
48 : printf("encrypted and compressed\n");
49 : */
50 :
51 4 : if(metadata)
52 : {
53 0 : ret=transfer_gzfile_inl(asfd,
54 : #ifdef HAVE_WIN32
55 : sb,
56 : #endif
57 : NULL,
58 : &rcvdbytes, &sentbytes, encpassword,
59 : enccompressed, cntr, metadata,
60 0 : key_deriv, sb->protocol1->salt);
61 0 : *metalen=sentbytes;
62 : // skip setting cntr, as we do not actually
63 : // restore until a bit later
64 : }
65 : else
66 : {
67 4 : ret=transfer_gzfile_inl(asfd,
68 : #ifdef HAVE_WIN32
69 : sb,
70 : #endif
71 : bfd,
72 : &rcvdbytes, &sentbytes,
73 : encpassword, enccompressed,
74 4 : cntr, NULL, key_deriv, sb->protocol1->salt);
75 : #ifndef HAVE_WIN32
76 4 : if(bfd && bfd->close(bfd, asfd))
77 : {
78 0 : logp("error closing %s in %s\n",
79 : fname, __func__);
80 0 : ret=-1;
81 : }
82 : #endif
83 4 : if(!ret) attribs_set(asfd, rpath,
84 : &sb->statp, sb->winattr, cntr);
85 : }
86 4 : if(ret)
87 : {
88 0 : char msg[256]="";
89 : snprintf(msg, sizeof(msg),
90 : "Could not transfer file in: %s", rpath);
91 0 : if(restore_interrupt(asfd, sb, msg, cntr, PROTO_1))
92 : ret=-1;
93 0 : ret=0;
94 : }
95 4 : return ret;
96 : }
97 :
98 4 : static int restore_file_or_get_meta(struct asfd *asfd, struct BFILE *bfd,
99 : struct sbuf *sb, const char *fname, enum action act,
100 : char **metadata, size_t *metalen, int vss_restore,
101 : struct cntr *cntr, const char *encyption_password)
102 : {
103 4 : int ret=0;
104 4 : char *rpath=NULL;
105 :
106 4 : if(act==ACTION_VERIFY)
107 : {
108 0 : cntr_add(cntr, sb->path.cmd, 1);
109 0 : goto end;
110 : }
111 :
112 4 : if(build_path(fname, "", &rpath, NULL))
113 : {
114 0 : char msg[256]="";
115 : // failed - do a warning
116 : snprintf(msg, sizeof(msg), "build path failed: %s", fname);
117 0 : if(restore_interrupt(asfd, sb, msg, cntr, PROTO_1))
118 0 : ret=-1;
119 : goto end;
120 : }
121 :
122 : #ifndef HAVE_WIN32
123 : // We always want to open the file if it is on Windows. Otherwise,
124 : // only open it if we are not doing metadata.
125 4 : if(!metadata)
126 : {
127 : #endif
128 4 : switch(open_for_restore(asfd,
129 : bfd, rpath, sb, vss_restore, cntr, PROTO_1))
130 : {
131 : case OFR_OK: break;
132 : case OFR_CONTINUE: goto end;
133 0 : default: ret=-1; goto end;
134 : }
135 : #ifndef HAVE_WIN32
136 : }
137 : #endif
138 :
139 4 : if(!(ret=do_restore_file_or_get_meta(asfd, bfd, sb, fname,
140 : metadata, metalen, cntr, rpath, encyption_password)))
141 4 : cntr_add(cntr, sb->path.cmd, 1);
142 : end:
143 4 : free_w(&rpath);
144 4 : if(ret) logp("restore_file error\n");
145 4 : return ret;
146 : }
147 :
148 0 : static int restore_metadata(struct asfd *asfd,
149 : struct BFILE *bfd, struct sbuf *sb,
150 : const char *fname, enum action act,
151 : int vss_restore, struct cntr *cntr, const char *encryption_password)
152 : {
153 0 : int ret=-1;
154 0 : size_t metalen=0;
155 0 : char *metadata=NULL;
156 :
157 : // If it is directory metadata, try to make sure the directory
158 : // exists. Pass in NULL as the cntr, so no counting is done.
159 : // The actual directory entry will be coming after the metadata,
160 : // annoyingly. This is because of the way that the server is queuing
161 : // up directories to send after file data, so that the stat info on
162 : // them gets set correctly.
163 0 : if(act==ACTION_VERIFY)
164 : {
165 0 : cntr_add(cntr, sb->path.cmd, 1);
166 0 : ret=0;
167 0 : goto end;
168 : }
169 :
170 0 : if(S_ISDIR(sb->statp.st_mode)
171 0 : && restore_dir(asfd, sb, fname, act, cntr, PROTO_1))
172 : goto end;
173 :
174 : // Read in the metadata...
175 0 : if(restore_file_or_get_meta(asfd, bfd, sb, fname, act,
176 : &metadata, &metalen, vss_restore, cntr, encryption_password))
177 : goto end;
178 0 : if(metadata)
179 : {
180 0 : if(!set_extrameta(asfd,
181 : #ifdef HAVE_WIN32
182 : bfd,
183 : #endif
184 : fname,
185 : metadata, metalen, cntr))
186 : {
187 : #ifndef HAVE_WIN32
188 : // Set file times again, since we just diddled with the
189 : // file. Do not set all attributes, as it will wipe
190 : // out any security attributes (eg getcap /usr/bin/ping)
191 0 : if(attribs_set_file_times(asfd, fname,
192 : &sb->statp, cntr))
193 : return -1;
194 0 : cntr_add(cntr, sb->path.cmd, 1);
195 : #endif
196 : }
197 : // Carry on if we could not set_extrameta.
198 : }
199 : ret=0;
200 : end:
201 0 : free_w(&metadata);
202 0 : return ret;
203 : }
204 :
205 5 : int restore_switch_protocol1(struct asfd *asfd, struct sbuf *sb,
206 : const char *fullpath, enum action act,
207 : struct BFILE *bfd, int vss_restore, struct cntr *cntr,
208 : const char *encryption_password)
209 : {
210 5 : switch(sb->path.cmd)
211 : {
212 : case CMD_FILE:
213 : case CMD_VSS_T:
214 : case CMD_ENC_FILE:
215 : case CMD_ENC_VSS_T:
216 : case CMD_EFS_FILE:
217 5 : if(!sb->protocol1->datapth.buf)
218 : {
219 : char msg[256];
220 1 : snprintf(msg, sizeof(msg),
221 : "datapth not supplied for %s in %s\n",
222 : iobuf_to_printable(&sb->path),
223 : __func__);
224 1 : log_and_send(asfd, msg);
225 : return -1;
226 : }
227 4 : return restore_file_or_get_meta(asfd, bfd, sb,
228 : fullpath, act,
229 : NULL, NULL, vss_restore, cntr,
230 : encryption_password);
231 : case CMD_METADATA:
232 : case CMD_VSS:
233 : case CMD_ENC_METADATA:
234 : case CMD_ENC_VSS:
235 0 : return restore_metadata(asfd, bfd, sb,
236 : fullpath, act,
237 : vss_restore, cntr, encryption_password);
238 : default:
239 : // Other cases (dir/links/etc) are handled in the
240 : // calling function.
241 0 : logp("unknown cmd: %c\n", sb->path.cmd);
242 0 : return -1;
243 : }
244 : }
|