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