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