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