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 : static int start_restore_file(struct asfd *asfd,
17 : struct BFILE *bfd,
18 : struct sbuf *sb,
19 : const char *fname,
20 : enum action act,
21 : int vss_restore,
22 : struct cntr *cntr)
23 : {
24 14 : int ret=-1;
25 14 : char *rpath=NULL;
26 :
27 14 : if(act==ACTION_VERIFY)
28 : {
29 0 : cntr_add(cntr, sb->path.cmd, 1);
30 0 : goto end;
31 : }
32 :
33 14 : if(build_path(fname, "", &rpath, NULL))
34 : {
35 0 : char msg[256]="";
36 : // Failed - do a warning.
37 : snprintf(msg, sizeof(msg), "build path failed: %s", fname);
38 0 : if(restore_interrupt(asfd, sb, msg, cntr, PROTO_2))
39 : goto error;
40 0 : goto end; // Try to carry on with other files.
41 : }
42 :
43 14 : switch(open_for_restore(asfd, bfd, rpath, sb, vss_restore, cntr,
44 : PROTO_2))
45 : {
46 : case OFR_OK: break;
47 : case OFR_CONTINUE: goto end;
48 : default: goto error;
49 : }
50 :
51 14 : cntr_add(cntr, sb->path.cmd, 1);
52 :
53 : end:
54 : ret=0;
55 : error:
56 14 : free_w(&rpath);
57 14 : return ret;
58 : }
59 :
60 0 : static int get_meta(
61 : struct asfd *asfd,
62 : struct cntr *cntr,
63 : char **metadata,
64 : size_t *metalen)
65 : {
66 0 : int ret=-1;
67 0 : struct iobuf *rbuf=asfd->rbuf;
68 :
69 : while(1)
70 : {
71 0 : iobuf_free_content(rbuf);
72 0 : if(asfd->read(asfd))
73 : goto end;
74 :
75 0 : switch(rbuf->cmd)
76 : {
77 : case CMD_DATA:
78 0 : if(!(*metadata=(char *)realloc_w(*metadata,
79 0 : (*metalen)+rbuf->len, __func__)))
80 : goto end;
81 0 : memcpy((*metadata)+(*metalen),
82 0 : rbuf->buf, rbuf->len);
83 0 : *metalen+=rbuf->len;
84 0 : break;
85 : case CMD_END_FILE:
86 : ret=0;
87 : goto end;
88 : case CMD_MESSAGE:
89 : case CMD_WARNING:
90 0 : log_recvd(rbuf, cntr, 0);
91 0 : break;
92 : default:
93 0 : iobuf_log_unexpected(rbuf, __func__);
94 0 : goto end;
95 : }
96 : }
97 :
98 : end:
99 0 : iobuf_free_content(rbuf);
100 0 : return ret;
101 : }
102 :
103 0 : static int restore_metadata(
104 : struct asfd *asfd,
105 : struct sbuf *sb,
106 : const char *fname,
107 : enum action act,
108 : struct cntr *cntr)
109 : {
110 : // If it is directory metadata, try to make sure the directory
111 : // exists. Pass in NULL as the cntr, so no counting is done.
112 : // The actual directory entry will be coming after the metadata,
113 : // annoyingly. This is because of the way that the server is queuing
114 : // up directories to send after file data, so that the stat info on
115 : // them gets set correctly.
116 0 : if(act==ACTION_RESTORE)
117 : {
118 0 : size_t metalen=0;
119 0 : char *metadata=NULL;
120 0 : if(S_ISDIR(sb->statp.st_mode)
121 0 : && restore_dir(asfd, sb, fname, act, cntr, PROTO_2))
122 0 : return -1;
123 :
124 : // Read in the metadata...
125 0 : if(get_meta(asfd, cntr, &metadata, &metalen))
126 : return -1;
127 0 : if(metadata)
128 : {
129 0 : if(set_extrameta(asfd,
130 : #ifdef HAVE_WIN32
131 : NULL,
132 : #endif
133 : fname,
134 : metadata, metalen, cntr))
135 : {
136 0 : free_w(&metadata);
137 : // carry on if we could not do it
138 0 : 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 0 : attribs_set(asfd, fname, &(sb->statp),
145 : 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 : struct 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 : vss_restore, cntr))
169 : {
170 0 : logp("restore_file error\n");
171 0 : goto error;
172 : }
173 : break;
174 : /* FIX THIS: Encryption currently not working in protocol2
175 : case CMD_ENC_FILE:
176 : if(start_restore_file(asfd,
177 : bfd, sb, fullpath, act,
178 : vss_restore, confs))
179 : {
180 : logp("restore_file error\n");
181 : goto error;
182 : }
183 : break;
184 : */
185 : case CMD_METADATA:
186 0 : if(restore_metadata(asfd,
187 : sb, fullpath, act, cntr))
188 : goto error;
189 : break;
190 : /* FIX THIS: Encryption and EFS not supported yet.
191 : case CMD_ENC_METADATA:
192 : if(restore_metadata(
193 : bfd, sb, fullpath, act, confs))
194 : goto error;
195 : break;
196 : case CMD_EFS_FILE:
197 : if(start_restore_file(asfd,
198 : bfd, sb,
199 : fullpath, act,
200 : vss_restore, confs))
201 : {
202 : logp("restore_file error\n");
203 : goto error;
204 : }
205 : break;
206 : */
207 : default:
208 0 : logp("unknown cmd: %c\n", sb->path.cmd);
209 0 : goto error;
210 : }
211 : return 0;
212 : error:
213 : return -1;
214 : }
|