2 * Main routine for finding files on a file system.
3 * The heart of the work is done in find_one.c
8 Copyright (C) 2000-2004 Kern Sibbald and John Walker
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2 of
13 the License, or (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public
21 License along with this program; if not, write to the Free
22 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
31 int32_t name_max; /* filename max length */
32 int32_t path_max; /* path name max length */
35 /* ****FIXME**** debug until stable */
37 #define bmalloc(x) sm_malloc(__FILE__, __LINE__, x)
38 static int our_callback(FF_PKT *ff, void *hpkt);
39 static bool accept_file(FF_PKT *ff);
43 * Initialize the find files "global" variables
45 FF_PKT *init_find_files()
49 ff = (FF_PKT *)bmalloc(sizeof(FF_PKT));
50 memset(ff, 0, sizeof(FF_PKT));
52 ff->sys_fname = get_pool_memory(PM_FNAME);
54 init_include_exclude_files(ff); /* init lists */
56 /* Get system path and filename maximum lengths */
57 path_max = pathconf(".", _PC_PATH_MAX);
58 if (path_max < 1024) {
62 name_max = pathconf(".", _PC_NAME_MAX);
63 if (name_max < 1024) {
66 path_max++; /* add for EOS */
67 name_max++; /* add for EOS */
69 Dmsg1(100, "init_find_files ff=%p\n", ff);
74 * Set find_files options. For the moment, we only
75 * provide for full/incremental saves, and setting
76 * of save_time. For additional options, see above
79 set_find_options(FF_PKT *ff, int incremental, time_t save_time)
81 Dmsg0(100, "Enter set_find_options()\n");
82 ff->incremental = incremental;
83 ff->save_time = save_time;
84 Dmsg0(100, "Leave set_find_options()\n");
89 * Find all specified files (determined by calls to name_add()
90 * This routine calls the (handle_file) subroutine with all
91 * sorts of good information for the final disposition of
94 * Call this subroutine with a callback subroutine as the first
95 * argument and a packet as the second argument, this packet
96 * will be passed back to the callback subroutine as the last
99 * The callback subroutine gets called with:
100 * arg1 -- the FF_PKT containing filename, link, stat, ftype, flags, etc
101 * arg2 -- the user supplied packet
105 find_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt), void *his_pkt)
107 ff->callback = callback;
109 /* This is the new way */
110 findFILESET *fileset = ff->fileset;
114 ff->VerifyOpts[0] = 0;
115 for (i=0; i<fileset->include_list.size(); i++) {
116 findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
117 fileset->incexe = incexe;
119 * By setting all options, we in effect or the global options
120 * which is what we want.
122 for (j=0; j<incexe->opts_list.size(); j++) {
123 findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
124 ff->flags |= fo->flags;
125 ff->GZIP_level = fo->GZIP_level;
126 bstrncpy(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts));
128 for (j=0; j<incexe->name_list.size(); j++) {
129 Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j));
130 char *fname = (char *)incexe->name_list.get(j);
131 if (find_one_file(jcr, ff, our_callback, his_pkt, fname, (dev_t)-1, 1) == 0) {
132 return 0; /* error return */
137 struct s_included_file *inc = NULL;
139 /* This is the old deprecated way */
140 while (!job_canceled(jcr) && (inc = get_next_included_file(ff, inc))) {
141 /* Copy options for this file */
142 bstrncpy(ff->VerifyOpts, inc->VerifyOpts, sizeof(ff->VerifyOpts));
143 Dmsg1(50, "find_files: file=%s\n", inc->fname);
144 if (!file_is_excluded(ff, inc->fname)) {
145 if (find_one_file(jcr, ff, callback, his_pkt, inc->fname, (dev_t)-1, 1) ==0) {
146 return 0; /* error return */
154 static bool accept_file(FF_PKT *ff)
157 findFILESET *fileset = ff->fileset;
158 findINCEXE *incexe = fileset->incexe;
160 for (j=0; j<incexe->opts_list.size(); j++) {
161 findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
162 for (k=0; k<fo->wild.size(); k++) {
163 if (fnmatch((char *)fo->wild.get(k), ff->fname, 0) == 0) {
164 ff->flags = fo->flags;
165 ff->GZIP_level = fo->GZIP_level;
166 if (ff->flags & FO_EXCLUDE) {
167 return false; /* reject file */
169 return true; /* accept file */
173 for (k=0; k<fo->regex.size(); k++) {
174 const int nmatch = 30;
175 regmatch_t pmatch[nmatch];
176 if (regexec((regex_t *)fo->regex.get(k), ff->fname, nmatch, pmatch, 0) == 0) {
177 ff->flags = fo->flags;
178 ff->GZIP_level = fo->GZIP_level;
179 if (ff->flags & FO_EXCLUDE) {
180 return false; /* reject file */
182 return true; /* accept file */
188 for (i=0; i<fileset->exclude_list.size(); i++) {
189 findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i);
190 for (j=0; j<incexe->opts_list.size(); j++) {
191 findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
192 for (k=0; k<fo->wild.size(); k++) {
193 if (fnmatch((char *)fo->wild.get(k), ff->fname, 0) == 0) {
194 Dmsg1(400, "Reject wild1: %s\n", ff->fname);
195 return false; /* reject file */
199 for (j=0; j<incexe->name_list.size(); j++) {
200 if (fnmatch((char *)incexe->name_list.get(j), ff->fname, 0) == 0) {
201 Dmsg1(400, "Reject wild2: %s\n", ff->fname);
202 return false; /* reject file */
210 * The code comes here for each file examined.
211 * We filter the files, then call the user's callback if
212 * the file is included.
214 static int our_callback(FF_PKT *ff, void *hpkt)
225 return ff->callback(ff, hpkt);
227 /* These items can be filtered */
238 if (accept_file(ff)) {
239 return ff->callback(ff, hpkt);
241 Dmsg1(100, "Skip file %s\n", ff->fname);
242 return -1; /* ignore this file */
246 Dmsg1(000, "Unknown FT code %d\n", ff->type);
253 * Terminate find_files() and release
254 * all allocated memory
257 term_find_files(FF_PKT *ff)
261 term_include_exclude_files(ff);
262 free_pool_memory(ff->sys_fname);
263 hard_links = term_find_one(ff);