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