Line data Source code
1 : #include "../../burp.h"
2 : #include "../../alloc.h"
3 : #include "../../asfd.h"
4 : #include "../../async.h"
5 : #include "../../attribs.h"
6 : #include "../../bfile.h"
7 : #include "../../cmd.h"
8 : #include "../../cntr.h"
9 : #include "../../fsops.h"
10 : #include "../../log.h"
11 : #include "../../sbuf.h"
12 : #include "../extrameta.h"
13 : #include "../restore.h"
14 :
15 14 : static int start_restore_file(struct asfd *asfd,
16 : BFILE *bfd,
17 : struct sbuf *sb,
18 : const char *fname,
19 : enum action act,
20 : const char *encpassword,
21 : char **metadata,
22 : size_t *metalen,
23 : int vss_restore,
24 : struct cntr *cntr)
25 : {
26 14 : int ret=-1;
27 14 : char *rpath=NULL;
28 :
29 14 : if(act==ACTION_VERIFY)
30 : {
31 0 : cntr_add(cntr, sb->path.cmd, 1);
32 : goto end;
33 : }
34 :
35 14 : if(build_path(fname, "", &rpath, NULL))
36 : {
37 0 : char msg[256]="";
38 : // Failed - do a warning.
39 : snprintf(msg, sizeof(msg), "build path failed: %s", fname);
40 0 : if(restore_interrupt(asfd, sb, msg, cntr, PROTO_2))
41 : goto error;
42 0 : goto end; // Try to carry on with other files.
43 : }
44 :
45 14 : switch(open_for_restore(asfd, bfd, rpath, sb, vss_restore, cntr,
46 14 : PROTO_2))
47 : {
48 : case OFR_OK: break;
49 : case OFR_CONTINUE: goto end;
50 : default: goto error;
51 : }
52 :
53 14 : cntr_add(cntr, sb->path.cmd, 1);
54 :
55 : end:
56 : ret=0;
57 : error:
58 14 : free_w(&rpath);
59 14 : return ret;
60 : }
61 :
62 0 : static int get_meta(
63 : struct asfd *asfd,
64 : struct cntr *cntr,
65 : char **metadata,
66 : size_t *metalen)
67 : {
68 0 : int ret=-1;
69 0 : struct iobuf *rbuf=asfd->rbuf;
70 :
71 : while(1)
72 : {
73 0 : iobuf_free_content(rbuf);
74 0 : if(asfd->read(asfd))
75 : goto end;
76 :
77 0 : switch(rbuf->cmd)
78 : {
79 : case CMD_DATA:
80 0 : if(!(*metadata=(char *)realloc_w(*metadata,
81 0 : (*metalen)+rbuf->len, __func__)))
82 : goto end;
83 0 : memcpy((*metadata)+(*metalen),
84 0 : rbuf->buf, rbuf->len);
85 0 : *metalen+=rbuf->len;
86 0 : break;
87 : case CMD_END_FILE:
88 : ret=0;
89 : goto end;
90 : case CMD_MESSAGE:
91 : case CMD_WARNING:
92 0 : log_recvd(rbuf, cntr, 0);
93 0 : break;
94 : default:
95 0 : iobuf_log_unexpected(rbuf, __func__);
96 0 : goto end;
97 : }
98 : }
99 :
100 : end:
101 0 : iobuf_free_content(rbuf);
102 0 : return ret;
103 : }
104 :
105 0 : static int restore_metadata(
106 : struct asfd *asfd,
107 : struct sbuf *sb,
108 : const char *fname,
109 : enum action act,
110 : const char *encpassword,
111 : int vss_restore,
112 : struct cntr *cntr)
113 : {
114 : // If it is directory metadata, try to make sure the directory
115 : // exists. Pass in NULL as the cntr, so no counting is done.
116 : // The actual directory entry will be coming after the metadata,
117 : // annoyingly. This is because of the way that the server is queuing
118 : // up directories to send after file data, so that the stat info on
119 : // them gets set correctly.
120 0 : if(act==ACTION_RESTORE)
121 : {
122 0 : size_t metalen=0;
123 0 : char *metadata=NULL;
124 0 : if(S_ISDIR(sb->statp.st_mode)
125 0 : && restore_dir(asfd, sb, fname, act, cntr, PROTO_2))
126 0 : return -1;
127 :
128 : // Read in the metadata...
129 0 : if(get_meta(asfd, cntr, &metadata, &metalen))
130 : return -1;
131 0 : if(metadata)
132 : {
133 0 : if(set_extrameta(asfd, NULL, fname,
134 0 : metadata, metalen, cntr))
135 : {
136 0 : free_w(&metadata);
137 : // carry on if we could not do it
138 : return 0;
139 : }
140 0 : free_w(&metadata);
141 : #ifndef HAVE_WIN32
142 : // set attributes again, since we just diddled with
143 : // the file
144 : attribs_set(asfd, fname, &(sb->statp),
145 0 : sb->winattr, cntr);
146 : #endif
147 0 : cntr_add(cntr, sb->path.cmd, 1);
148 : }
149 : }
150 : else
151 0 : cntr_add(cntr, sb->path.cmd, 1);
152 : return 0;
153 : }
154 :
155 14 : int restore_switch_protocol2(struct asfd *asfd, struct sbuf *sb,
156 : const char *fullpath, enum action act,
157 : BFILE *bfd, int vss_restore, struct cntr *cntr)
158 : {
159 14 : switch(sb->path.cmd)
160 : {
161 : case CMD_FILE:
162 : // Have it a separate statement to the
163 : // encrypted version so that encrypted and not
164 : // encrypted files can be restored at the
165 : // same time.
166 14 : if(start_restore_file(asfd,
167 : bfd, sb, fullpath, act,
168 : NULL, NULL, NULL,
169 14 : vss_restore, cntr))
170 : {
171 0 : logp("restore_file error\n");
172 0 : goto error;
173 : }
174 : break;
175 : /* FIX THIS: Encryption currently not working in protocol2
176 : case CMD_ENC_FILE:
177 : if(start_restore_file(asfd,
178 : bfd, sb, fullpath, act,
179 : get_string(confs[OPT_ENCRYPTION_PASSWORD]),
180 : NULL, NULL, vss_restore, confs))
181 : {
182 : logp("restore_file error\n");
183 : goto error;
184 : }
185 : break;
186 : */
187 : case CMD_METADATA:
188 0 : if(restore_metadata(asfd,
189 : sb, fullpath, act,
190 0 : NULL, vss_restore, cntr))
191 : goto error;
192 : break;
193 : /* FIX THIS: Encryption and EFS not supported yet.
194 : case CMD_ENC_METADATA:
195 : if(restore_metadata(
196 : bfd, sb, fullpath, act,
197 : get_string(confs[OPT_ENCRYPTION_PASSWORD]),
198 : vss_restore, confs))
199 : goto error;
200 : break;
201 : case CMD_EFS_FILE:
202 : if(start_restore_file(asfd,
203 : bfd, sb,
204 : fullpath, act,
205 : NULL,
206 : NULL, NULL, vss_restore, confs))
207 : {
208 : logp("restore_file error\n");
209 : goto error;
210 : }
211 : break;
212 : */
213 : default:
214 0 : logp("unknown cmd: %c\n", sb->path.cmd);
215 0 : goto error;
216 : }
217 : return 0;
218 : error:
219 : return -1;
220 : }
|