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 0 : snprintf(msg, sizeof(msg),
90 : "Could not transfer file in: %s", rpath);
91 0 : return restore_interrupt(asfd, sb, msg, cntr, PROTO_1);
92 : }
93 : return 0;
94 : }
95 :
96 4 : static int restore_file_or_get_meta(struct asfd *asfd, struct BFILE *bfd,
97 : struct sbuf *sb, const char *fname, enum action act,
98 : char **metadata, size_t *metalen, int vss_restore,
99 : struct cntr *cntr, const char *encyption_password)
100 : {
101 4 : int ret=0;
102 4 : char *rpath=NULL;
103 :
104 4 : if(act==ACTION_VERIFY)
105 : {
106 0 : cntr_add(cntr, sb->path.cmd, 1);
107 0 : goto end;
108 : }
109 :
110 4 : if(build_path(fname, "", &rpath, NULL))
111 : {
112 0 : char msg[256]="";
113 : // failed - do a warning
114 0 : snprintf(msg, sizeof(msg), "build path failed: %s", fname);
115 0 : if(restore_interrupt(asfd, sb, msg, cntr, PROTO_1))
116 0 : ret=-1;
117 : goto end;
118 : }
119 :
120 : #ifndef HAVE_WIN32
121 : // We always want to open the file if it is on Windows. Otherwise,
122 : // only open it if we are not doing metadata.
123 4 : if(!metadata)
124 : {
125 : #endif
126 4 : switch(open_for_restore(asfd,
127 : bfd, rpath, sb, vss_restore, cntr, PROTO_1))
128 : {
129 : case OFR_OK: break;
130 : case OFR_CONTINUE: goto end;
131 0 : default: ret=-1; goto end;
132 : }
133 : #ifndef HAVE_WIN32
134 : }
135 : #endif
136 :
137 4 : if(!(ret=do_restore_file_or_get_meta(asfd, bfd, sb, fname,
138 : metadata, metalen, cntr, rpath, encyption_password)))
139 4 : cntr_add(cntr, sb->path.cmd, 1);
140 : end:
141 4 : free_w(&rpath);
142 4 : if(ret) logp("restore_file error\n");
143 4 : return ret;
144 : }
145 :
146 0 : static int restore_metadata(struct asfd *asfd,
147 : struct BFILE *bfd, struct sbuf *sb,
148 : const char *fname, enum action act,
149 : int vss_restore, struct cntr *cntr, const char *encryption_password)
150 : {
151 0 : int ret=-1;
152 0 : size_t metalen=0;
153 0 : char *metadata=NULL;
154 :
155 : // If it is directory metadata, try to make sure the directory
156 : // exists. Pass in NULL as the cntr, so no counting is done.
157 : // The actual directory entry will be coming after the metadata,
158 : // annoyingly. This is because of the way that the server is queuing
159 : // up directories to send after file data, so that the stat info on
160 : // them gets set correctly.
161 0 : if(act==ACTION_VERIFY)
162 : {
163 0 : cntr_add(cntr, sb->path.cmd, 1);
164 0 : ret=0;
165 0 : goto end;
166 : }
167 :
168 0 : if(S_ISDIR(sb->statp.st_mode)
169 0 : && restore_dir(asfd, sb, fname, act, cntr, PROTO_1))
170 : goto end;
171 :
172 : // Read in the metadata...
173 0 : if(restore_file_or_get_meta(asfd, bfd, sb, fname, act,
174 : &metadata, &metalen, vss_restore, cntr, encryption_password))
175 : goto end;
176 0 : if(metadata)
177 : {
178 0 : if(!set_extrameta(asfd,
179 : #ifdef HAVE_WIN32
180 : bfd,
181 : #endif
182 : fname,
183 : metadata, metalen, cntr))
184 : {
185 : #ifndef HAVE_WIN32
186 : // Set file times again, since we just diddled with the
187 : // file. Do not set all attributes, as it will wipe
188 : // out any security attributes (eg getcap /usr/bin/ping)
189 0 : if(attribs_set_file_times(asfd, fname,
190 : &sb->statp, cntr))
191 : return -1;
192 0 : cntr_add(cntr, sb->path.cmd, 1);
193 : #endif
194 : }
195 : // Carry on if we could not set_extrameta.
196 : }
197 : ret=0;
198 : end:
199 0 : free_w(&metadata);
200 0 : return ret;
201 : }
202 :
203 5 : int restore_switch_protocol1(struct asfd *asfd, struct sbuf *sb,
204 : const char *fullpath, enum action act,
205 : struct BFILE *bfd, int vss_restore, struct cntr *cntr,
206 : const char *encryption_password)
207 : {
208 5 : switch(sb->path.cmd)
209 : {
210 : case CMD_FILE:
211 : case CMD_VSS_T:
212 : case CMD_ENC_FILE:
213 : case CMD_ENC_VSS_T:
214 : case CMD_EFS_FILE:
215 5 : if(!sb->protocol1->datapth.buf)
216 : {
217 : char msg[256];
218 1 : snprintf(msg, sizeof(msg),
219 : "datapth not supplied for %s in %s\n",
220 : iobuf_to_printable(&sb->path),
221 : __func__);
222 1 : log_and_send(asfd, msg);
223 : return -1;
224 : }
225 4 : return restore_file_or_get_meta(asfd, bfd, sb,
226 : fullpath, act,
227 : NULL, NULL, vss_restore, cntr,
228 : encryption_password);
229 : case CMD_METADATA:
230 : case CMD_VSS:
231 : case CMD_ENC_METADATA:
232 : case CMD_ENC_VSS:
233 0 : return restore_metadata(asfd, bfd, sb,
234 : fullpath, act,
235 : vss_restore, cntr, encryption_password);
236 : default:
237 : // Other cases (dir/links/etc) are handled in the
238 : // calling function.
239 0 : logp("unknown cmd: %s\n",
240 : iobuf_to_printable(&sb->path));
241 0 : return -1;
242 : }
243 : }
|