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