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 file times again, since we just diddled with the
143 : // file. Do not set all attributes, as it will wipe
144 : // out any security attributes (eg getcap /usr/bin/ping)
145 0 : if(attribs_set_file_times(asfd, fname,
146 : &sb->statp, cntr))
147 : return -1;
148 : #endif
149 0 : cntr_add(cntr, sb->path.cmd, 1);
150 : }
151 : }
152 : else
153 0 : cntr_add(cntr, sb->path.cmd, 1);
154 : return 0;
155 : }
156 :
157 14 : int restore_switch_protocol2(struct asfd *asfd, struct sbuf *sb,
158 : const char *fullpath, enum action act,
159 : struct BFILE *bfd, int vss_restore, struct cntr *cntr)
160 : {
161 14 : switch(sb->path.cmd)
162 : {
163 : case CMD_FILE:
164 : // Have it a separate statement to the
165 : // encrypted version so that encrypted and not
166 : // encrypted files can be restored at the
167 : // same time.
168 14 : if(start_restore_file(asfd,
169 : bfd, sb, fullpath, act,
170 : vss_restore, cntr))
171 : {
172 0 : logp("restore_file error\n");
173 0 : goto error;
174 : }
175 : break;
176 : /* FIX THIS: Encryption currently not working in protocol2
177 : case CMD_ENC_FILE:
178 : if(start_restore_file(asfd,
179 : bfd, sb, fullpath, act,
180 : 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, cntr))
190 : goto error;
191 : break;
192 : /* FIX THIS: Encryption and EFS not supported yet.
193 : case CMD_ENC_METADATA:
194 : if(restore_metadata(
195 : bfd, sb, fullpath, act, confs))
196 : goto error;
197 : break;
198 : case CMD_EFS_FILE:
199 : if(start_restore_file(asfd,
200 : bfd, sb,
201 : fullpath, act,
202 : vss_restore, confs))
203 : {
204 : logp("restore_file error\n");
205 : goto error;
206 : }
207 : break;
208 : */
209 : default:
210 0 : logp("unknown cmd: %c\n", sb->path.cmd);
211 0 : goto error;
212 : }
213 : return 0;
214 : error:
215 : return -1;
216 : }
|