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