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 : #ifdef HAVE_WIN32
52 : static enum cmd metasymbol=CMD_VSS;
53 : static enum cmd vss_trail_symbol=CMD_VSS_T;
54 : #else
55 : static enum cmd metasymbol=CMD_METADATA;
56 : #endif
57 :
58 : static int enable_acl=0;
59 : static int enable_xattr=0;
60 :
61 0 : static int usual_stuff(struct asfd *asfd,
62 : struct cntr *cntr, const char *path, const char *link,
63 : struct sbuf *sb, enum cmd cmd)
64 : {
65 : // When run with ACTION_ESTIMATE, asfd is NULL.
66 0 : if(asfd)
67 : {
68 0 : if(asfd->write_str(asfd, CMD_ATTRIBS, sb->attr.buf)
69 0 : || asfd->write_str(asfd, cmd, path)
70 0 : || ((cmd==CMD_HARD_LINK || cmd==CMD_SOFT_LINK)
71 0 : && asfd->write_str(asfd, cmd, link)))
72 : return -1;
73 : }
74 0 : cntr_add_phase1(cntr, cmd, 1);
75 : return 0;
76 : }
77 :
78 0 : static int maybe_send_extrameta(struct asfd *asfd,
79 : const char *path, enum cmd cmd,
80 : struct sbuf *sb,
81 : struct cntr *cntr, enum cmd symbol)
82 : {
83 : // FIX THIS: should probably initialise extrameta with the desired
84 : // conf parameters so that they do not need to be passed in all the
85 : // time.
86 0 : if(!has_extrameta(path, cmd, enable_acl, enable_xattr))
87 : return 0;
88 0 : return usual_stuff(asfd, cntr, path, NULL, sb, symbol);
89 : }
90 :
91 0 : static int ft_err(struct asfd *asfd,
92 : struct conf **confs, struct FF_PKT *ff, const char *msg)
93 : {
94 : int raise_error;
95 0 : const char *prefix="";
96 0 : raise_error=get_int(confs[OPT_SCAN_PROBLEM_RAISES_ERROR]);
97 0 : if(raise_error) prefix="Err: ";
98 0 : if(logw(asfd, get_cntr(confs), "%s%s %s: %s\n", prefix, msg,
99 0 : ff->fname, strerror(errno))) return -1;
100 0 : if(raise_error) return -1;
101 : return 0;
102 : }
103 :
104 0 : static int do_to_server(struct asfd *asfd,
105 : struct conf **confs, struct FF_PKT *ff, struct sbuf *sb,
106 : enum cmd cmd, int compression)
107 : {
108 : #ifdef HAVE_WIN32
109 : int split_vss=0;
110 : int strip_vss=0;
111 : split_vss=get_int(confs[OPT_SPLIT_VSS]);
112 : strip_vss=get_int(confs[OPT_STRIP_VSS]);
113 : sb->use_winapi=ff->use_winapi;
114 : sb->winattr=ff->winattr;
115 : #endif
116 0 : struct cntr *cntr=get_cntr(confs);
117 0 : sb->compression=compression;
118 0 : sb->encryption=encryption;
119 0 : sb->statp=ff->statp;
120 0 : attribs_encode(sb);
121 :
122 : #ifdef HAVE_WIN32
123 : if(split_vss
124 : && !strip_vss
125 : && cmd!=CMD_EFS_FILE
126 : && maybe_send_extrameta(asfd, ff->fname,
127 : cmd, sb, cntr, metasymbol))
128 : return -1;
129 : #endif
130 :
131 0 : if(usual_stuff(asfd, cntr, ff->fname, ff->link, sb, cmd)) return -1;
132 :
133 0 : if(ff->type==FT_REG)
134 0 : cntr_add_val(cntr, CMD_BYTES_ESTIMATED,
135 0 : (uint64_t)ff->statp.st_size);
136 : #ifdef HAVE_WIN32
137 : if(split_vss
138 : && !strip_vss
139 : && cmd!=CMD_EFS_FILE
140 : // FIX THIS: May have to check that it is not a directory here.
141 : && !S_ISDIR(sb->statp.st_mode) // does this work?
142 : && maybe_send_extrameta(asfd,
143 : ff->fname, cmd, sb, cntr, vss_trail_symbol))
144 : return -1;
145 : return 0;
146 : #else
147 0 : return maybe_send_extrameta(asfd, ff->fname, cmd, sb,
148 : cntr, metasymbol);
149 : #endif
150 : }
151 :
152 0 : static int to_server(struct asfd *asfd, struct conf **confs, struct FF_PKT *ff,
153 : struct sbuf *sb, enum cmd cmd)
154 : {
155 0 : return do_to_server(asfd, confs,
156 : ff, sb, cmd, get_int(confs[OPT_COMPRESSION]));
157 : }
158 :
159 0 : static int my_send_file(struct asfd *asfd, struct FF_PKT *ff, struct conf **confs)
160 : {
161 : static struct sbuf *sb=NULL;
162 0 : struct cntr *cntr=get_cntr(confs);
163 : #ifdef HAVE_WIN32
164 : enum cmd dirsymbol=filesymbol;
165 : #endif
166 :
167 0 : if(!sb && !(sb=sbuf_alloc())) return -1;
168 :
169 : #ifdef HAVE_WIN32
170 : if(ff->winattr & FILE_ATTRIBUTE_ENCRYPTED)
171 : {
172 : if(ff->type==FT_REG
173 : || ff->type==FT_DIR)
174 : return to_server(asfd, confs, ff, sb, CMD_EFS_FILE);
175 : return logw(asfd, cntr,
176 : "EFS type %d not yet supported: %s\n",
177 : ff->type, ff->fname);
178 : }
179 : #endif
180 :
181 0 : switch(ff->type)
182 : {
183 : case FT_REG:
184 : case FT_RAW:
185 : case FT_FIFO:
186 0 : return do_to_server(asfd, confs, ff, sb, filesymbol,
187 : in_exclude_comp(get_strlist(confs[OPT_EXCOM]),
188 0 : ff->fname, get_int(confs[OPT_COMPRESSION])));
189 : case FT_DIR:
190 : case FT_REPARSE:
191 : case FT_JUNCTION:
192 : #ifdef HAVE_WIN32
193 : if (!ff->use_winapi || get_int(confs[OPT_STRIP_VSS]))
194 : dirsymbol=CMD_DIRECTORY;
195 : return to_server(asfd, confs, ff, sb, dirsymbol);
196 : #else
197 0 : return to_server(asfd, confs, ff, sb, CMD_DIRECTORY);
198 : #endif
199 : case FT_LNK_S:
200 0 : return to_server(asfd, confs, ff, sb, CMD_SOFT_LINK);
201 : case FT_LNK_H:
202 0 : return to_server(asfd, confs, ff, sb, CMD_HARD_LINK);
203 : case FT_SPEC:
204 0 : return to_server(asfd, confs, ff, sb, CMD_SPECIAL);
205 : case FT_NOFSCHG:
206 0 : return ft_err(asfd, confs, ff, "Will not descend: "
207 : "file system change not allowed");
208 : case FT_NOFOLLOW:
209 0 : return ft_err(asfd, confs, ff, "Could not follow link");
210 : case FT_NOSTAT:
211 0 : return ft_err(asfd, confs, ff, "Could not stat");
212 : case FT_NOOPEN:
213 0 : return ft_err(asfd, confs, ff, "Could not open directory");
214 : default:
215 0 : return logw(asfd, cntr,
216 : "Err: Unknown file type %d: %s\n",
217 : ff->type, ff->fname);
218 : }
219 : }
220 :
221 0 : int backup_phase1_client(struct asfd *asfd, struct conf **confs)
222 : {
223 0 : int ret=-1;
224 0 : struct FF_PKT *ff=NULL;
225 0 : struct strlist *l=NULL;
226 0 : enable_acl=get_int(confs[OPT_ACL]);
227 0 : enable_xattr=get_int(confs[OPT_XATTR]);
228 :
229 : // First, tell the server about everything that needs to be backed up.
230 :
231 0 : logp("Phase 1 begin (file system scan)\n");
232 :
233 0 : if(get_string(confs[OPT_ENCRYPTION_PASSWORD]))
234 : {
235 0 : encryption=ENCRYPTION_KEY_DERIVED_AES_CBC_256;
236 0 : filesymbol=CMD_ENC_FILE;
237 0 : metasymbol=CMD_ENC_METADATA;
238 : #ifdef HAVE_WIN32
239 : metasymbol=CMD_ENC_VSS;
240 : vss_trail_symbol=CMD_ENC_VSS_T;
241 : #endif
242 : }
243 :
244 0 : if(!(ff=find_files_init(my_send_file))) goto end;
245 0 : for(l=get_strlist(confs[OPT_STARTDIR]); l; l=l->next) {
246 0 : if(l->flag && find_files_begin(asfd, ff, confs, l->path))
247 : goto end;
248 : }
249 : ret=0;
250 : end:
251 0 : cntr_print_end_phase1(get_cntr(confs));
252 0 : if(ret) logp("Error in phase 1\n");
253 0 : logp("Phase 1 end (file system scan)\n");
254 0 : find_files_free(&ff);
255 :
256 0 : return ret;
257 : }
|