Line data Source code
1 : /*
2 : Bacula® - The Network Backup Solution
3 :
4 : Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
5 :
6 : The main author of Bacula is Kern Sibbald, with contributions from
7 : many others, a complete list can be found in the file AUTHORS.
8 : This program is Free Software; you can redistribute it and/or
9 : modify it under the terms of version three of the GNU Affero General Public
10 : License as published by the Free Software Foundation and included
11 : in the file LICENSE.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU Affero General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : Bacula® is a registered trademark of Kern Sibbald.
24 : The licensor of Bacula is the Free Software Foundation Europe
25 : (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 : Switzerland, email:ftf@fsfeurope.org.
27 : */
28 : /*
29 : * Traces of * bacula-5.0.3:src/filed/backup.c still exist in this file, hence
30 : * the copyright notice above. Specifically, FF_PKT and the FF_* types. At
31 : * some point, these will be removed in favour of the burp sbuf code.
32 : * Graham Keeling, 2014.
33 : */
34 :
35 : #include "../burp.h"
36 : #include "../alloc.h"
37 : #include "../asfd.h"
38 : #include "../async.h"
39 : #include "../attribs.h"
40 : #include "../cmd.h"
41 : #include "../cntr.h"
42 : #include "../linkhash.h"
43 : #include "../log.h"
44 : #include "../strlist.h"
45 : #include "extrameta.h"
46 : #include "find.h"
47 : #include "backup_phase1.h"
48 :
49 : static int encryption=ENCRYPTION_NONE;
50 : static enum cmd filesymbol=CMD_FILE;
51 : static enum cmd dirsymbol=CMD_DIRECTORY;
52 : #ifdef HAVE_WIN32
53 : static enum cmd metasymbol=CMD_VSS;
54 : static enum cmd vss_trail_symbol=CMD_VSS_T;
55 : #else
56 : static enum cmd metasymbol=CMD_METADATA;
57 : #endif
58 :
59 : static int enable_acl=0;
60 : static int enable_xattr=0;
61 :
62 0 : static int usual_stuff(struct asfd *asfd,
63 : struct cntr *cntr, const char *path, const char *link,
64 : struct sbuf *sb, enum cmd cmd)
65 : {
66 : // When run with ACTION_ESTIMATE, asfd is NULL.
67 0 : if(asfd)
68 : {
69 0 : if(asfd->write_str(asfd, CMD_ATTRIBS, sb->attr.buf)
70 0 : || asfd->write_str(asfd, cmd, path)
71 0 : || ((cmd==CMD_HARD_LINK || cmd==CMD_SOFT_LINK)
72 0 : && asfd->write_str(asfd, cmd, link)))
73 : return -1;
74 : }
75 0 : cntr_add_phase1(cntr, cmd, 1);
76 : return 0;
77 : }
78 :
79 0 : static int maybe_send_extrameta(struct asfd *asfd,
80 : const char *path, enum cmd cmd,
81 : struct sbuf *sb,
82 : struct cntr *cntr, enum cmd symbol)
83 : {
84 : // FIX THIS: should probably initialise extrameta with the desired
85 : // conf parameters so that they do not need to be passed in all the
86 : // time.
87 0 : if(!has_extrameta(path, cmd, enable_acl, enable_xattr))
88 : return 0;
89 0 : return usual_stuff(asfd, cntr, path, NULL, sb, symbol);
90 : }
91 :
92 0 : static int ft_err(struct asfd *asfd,
93 : struct conf **confs, struct FF_PKT *ff, const char *msg)
94 : {
95 : int raise_error;
96 0 : const char *prefix="";
97 0 : raise_error=get_int(confs[OPT_SCAN_PROBLEM_RAISES_ERROR]);
98 0 : if(raise_error) prefix="Err: ";
99 0 : if(logw(asfd, get_cntr(confs), "%s%s %s: %s\n", prefix, msg,
100 0 : ff->fname, strerror(errno))) return -1;
101 0 : if(raise_error) return -1;
102 : return 0;
103 : }
104 :
105 0 : static int do_to_server(struct asfd *asfd,
106 : struct conf **confs, struct FF_PKT *ff, struct sbuf *sb,
107 : enum cmd cmd, int compression)
108 : {
109 : #ifdef HAVE_WIN32
110 : int split_vss=0;
111 : int strip_vss=0;
112 : if(get_protocol(confs)==PROTO_1)
113 : {
114 : split_vss=get_int(confs[OPT_SPLIT_VSS]);
115 : strip_vss=get_int(confs[OPT_STRIP_VSS]);
116 : }
117 : #endif
118 0 : struct cntr *cntr=get_cntr(confs);
119 0 : sb->compression=compression;
120 0 : sb->encryption=encryption;
121 0 : sb->statp=ff->statp;
122 0 : attribs_encode(sb);
123 :
124 : #ifdef HAVE_WIN32
125 : if(split_vss
126 : && !strip_vss
127 : && cmd!=CMD_EFS_FILE
128 : && maybe_send_extrameta(asfd, ff->fname,
129 : cmd, sb, cntr, metasymbol))
130 : return -1;
131 : #endif
132 :
133 0 : if(usual_stuff(asfd, cntr, ff->fname, ff->link, sb, cmd)) return -1;
134 :
135 0 : if(ff->type==FT_REG)
136 0 : cntr_add_val(cntr, CMD_BYTES_ESTIMATED,
137 0 : (uint64_t)ff->statp.st_size);
138 : #ifdef HAVE_WIN32
139 : if(split_vss
140 : && !strip_vss
141 : && cmd!=CMD_EFS_FILE
142 : // FIX THIS: May have to check that it is not a directory here.
143 : && !S_ISDIR(sb->statp.st_mode) // does this work?
144 : && maybe_send_extrameta(asfd,
145 : ff->fname, cmd, sb, cntr, vss_trail_symbol))
146 : return -1;
147 : return 0;
148 : #else
149 0 : return maybe_send_extrameta(asfd, ff->fname, cmd, sb,
150 : cntr, metasymbol);
151 : #endif
152 : }
153 :
154 0 : static int to_server(struct asfd *asfd, struct conf **confs, struct FF_PKT *ff,
155 : struct sbuf *sb, enum cmd cmd)
156 : {
157 0 : return do_to_server(asfd, confs,
158 : ff, sb, cmd, get_int(confs[OPT_COMPRESSION]));
159 : }
160 :
161 0 : static int my_send_file(struct asfd *asfd, struct FF_PKT *ff, struct conf **confs)
162 : {
163 : static struct sbuf *sb=NULL;
164 0 : struct cntr *cntr=get_cntr(confs);
165 :
166 0 : if(!sb && !(sb=sbuf_alloc(get_protocol(confs)))) return -1;
167 :
168 : #ifdef HAVE_WIN32
169 : if(ff->winattr & FILE_ATTRIBUTE_ENCRYPTED)
170 : {
171 : if(ff->type==FT_REG
172 : || ff->type==FT_DIR)
173 : return to_server(asfd, confs, ff, sb, CMD_EFS_FILE);
174 : return logw(asfd, cntr,
175 : "EFS type %d not yet supported: %s\n",
176 : ff->type, ff->fname);
177 : }
178 : #endif
179 :
180 0 : switch(ff->type)
181 : {
182 : case FT_REG:
183 : case FT_RAW:
184 : case FT_FIFO:
185 0 : return do_to_server(asfd, confs, ff, sb, filesymbol,
186 : in_exclude_comp(get_strlist(confs[OPT_EXCOM]),
187 0 : ff->fname, get_int(confs[OPT_COMPRESSION])));
188 : case FT_DIR:
189 : case FT_REPARSE:
190 : case FT_JUNCTION:
191 0 : return to_server(asfd, confs, ff, sb, dirsymbol);
192 : case FT_LNK_S:
193 0 : return to_server(asfd, confs, ff, sb, CMD_SOFT_LINK);
194 : case FT_LNK_H:
195 0 : return to_server(asfd, confs, ff, sb, CMD_HARD_LINK);
196 : case FT_SPEC:
197 0 : return to_server(asfd, confs, ff, sb, CMD_SPECIAL);
198 : case FT_NOFSCHG:
199 0 : return ft_err(asfd, confs, ff, "Will not descend: "
200 : "file system change not allowed");
201 : case FT_NOFOLLOW:
202 0 : return ft_err(asfd, confs, ff, "Could not follow link");
203 : case FT_NOSTAT:
204 0 : return ft_err(asfd, confs, ff, "Could not stat");
205 : case FT_NOOPEN:
206 0 : return ft_err(asfd, confs, ff, "Could not open directory");
207 : default:
208 0 : return logw(asfd, cntr,
209 : "Err: Unknown file type %d: %s\n",
210 : ff->type, ff->fname);
211 : }
212 : }
213 :
214 0 : int backup_phase1_client(struct asfd *asfd, struct conf **confs)
215 : {
216 0 : int ret=-1;
217 0 : struct FF_PKT *ff=NULL;
218 0 : struct strlist *l=NULL;
219 0 : enable_acl=get_int(confs[OPT_ACL]);
220 0 : enable_xattr=get_int(confs[OPT_XATTR]);
221 :
222 : // First, tell the server about everything that needs to be backed up.
223 :
224 0 : logp("Phase 1 begin (file system scan)\n");
225 :
226 : // Encryption not yet supported in protocol2.
227 0 : if(get_protocol(confs)==PROTO_1
228 0 : && get_string(confs[OPT_ENCRYPTION_PASSWORD]))
229 : {
230 0 : encryption=ENCRYPTION_KEY_DERIVED;
231 0 : filesymbol=CMD_ENC_FILE;
232 0 : metasymbol=CMD_ENC_METADATA;
233 : #ifdef HAVE_WIN32
234 : metasymbol=CMD_ENC_VSS;
235 : vss_trail_symbol=CMD_ENC_VSS_T;
236 : #endif
237 : }
238 : #ifdef HAVE_WIN32
239 : dirsymbol=filesymbol;
240 : if(get_protocol(confs)==PROTO_1
241 : && get_int(confs[OPT_STRIP_VSS]))
242 : dirsymbol=CMD_DIRECTORY;
243 : #endif
244 :
245 0 : if(!(ff=find_files_init(my_send_file))) goto end;
246 0 : for(l=get_strlist(confs[OPT_STARTDIR]); l; l=l->next) if(l->flag)
247 0 : if(find_files_begin(asfd, ff, confs, l->path)) goto end;
248 : ret=0;
249 : end:
250 0 : cntr_print_end_phase1(get_cntr(confs));
251 0 : if(ret) logp("Error in phase 1\n");
252 0 : logp("Phase 1 end (file system scan)\n");
253 0 : find_files_free(&ff);
254 :
255 0 : return ret;
256 : }
|