+/*
+ * capture_common.c - Mostly code to handle excluding paths from capture.
+ */
+
/*
* Copyright (C) 2013 Eric Biggers
*
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "wimlib_internal.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
-#include <string.h>
+#include "wimlib/assert.h"
+#include "wimlib/capture.h"
+#include "wimlib/dentry.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/paths.h"
+#include "wimlib/wildcard.h"
-#ifdef __WIN32__
-# include "win32.h"
-#else
-# include <fnmatch.h>
-#endif
+#include <string.h>
static int
-canonicalize_pat(tchar **pat_p)
+canonicalize_pattern(const tchar *pat, tchar **canonical_pat_ret)
{
- tchar *pat = *pat_p;
-
- /* Turn all backslashes in the pattern into forward slashes. */
- zap_backslashes(pat);
+ tchar *canonical_pat;
- if (*pat != T('/') && *pat != T('\0') && *(pat + 1) == T(':')) {
+ if (!is_any_path_separator(pat[0]) &&
+ pat[0] != T('\0') && pat[1] == T(':'))
+ {
/* Pattern begins with drive letter */
- if (*(pat + 2) != T('/')) {
+ if (!is_any_path_separator(pat[2])) {
/* Something like c:file, which is actually a path
* relative to the current working directory on the c:
* drive. We require paths with drive letters to be
* absolute. */
ERROR("Invalid path \"%"TS"\"; paths including drive letters "
"must be absolute!", pat);
- ERROR("Maybe try \"%"TC":/%"TS"\"?",
- *pat, pat + 2);
+ ERROR("Maybe try \"%"TC":\\%"TS"\"?",
+ pat[0], pat + 2);
return WIMLIB_ERR_INVALID_CAPTURE_CONFIG;
}
"being removed.", pat);
/* Strip the drive letter */
pat += 2;
- *pat_p = pat;
}
+ canonical_pat = canonicalize_fs_path(pat);
+ if (!canonical_pat)
+ return WIMLIB_ERR_NOMEM;
+
+ /* Translate all possible path separators into the operating system's
+ * preferred path separator. */
+ for (tchar *p = canonical_pat; *p; p++)
+ if (is_any_path_separator(*p))
+ *p = OS_PREFERRED_PATH_SEPARATOR;
+ *canonical_pat_ret = canonical_pat;
return 0;
}
static int
-canonicalize_pat_list(struct wimlib_pattern_list *pat_list)
+copy_and_canonicalize_pattern_list(const struct wimlib_pattern_list *list,
+ struct wimlib_pattern_list *copy)
{
int ret = 0;
- for (size_t i = 0; i < pat_list->num_pats; i++) {
- ret = canonicalize_pat(&pat_list->pats[i]);
+
+ copy->pats = CALLOC(list->num_pats, sizeof(list->pats[0]));
+ if (!copy->pats)
+ return WIMLIB_ERR_NOMEM;
+ copy->num_pats = list->num_pats;
+ for (size_t i = 0; i < list->num_pats; i++) {
+ ret = canonicalize_pattern(list->pats[i], ©->pats[i]);
if (ret)
break;
}
}
int
-canonicalize_capture_config(struct wimlib_capture_config *config)
+copy_and_canonicalize_capture_config(const struct wimlib_capture_config *config,
+ struct wimlib_capture_config **config_copy_ret)
{
- int ret = canonicalize_pat_list(&config->exclusion_pats);
- if (ret)
- return ret;
- return canonicalize_pat_list(&config->exclusion_exception_pats);
-}
+ struct wimlib_capture_config *config_copy;
+ int ret;
-static bool
-copy_pattern_list(struct wimlib_pattern_list *copy,
- const struct wimlib_pattern_list *list)
-{
- copy->pats = CALLOC(list->num_pats, sizeof(list->pats[0]));
- if (!copy->pats)
- return false;
- copy->num_pats = list->num_pats;
- for (size_t i = 0; i < list->num_pats; i++) {
- copy->pats[i] = TSTRDUP(list->pats[i]);
- if (!copy->pats[i])
- return false;
+ config_copy = CALLOC(1, sizeof(struct wimlib_capture_config));
+ if (!config_copy) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out_free_capture_config;
}
- return true;
-}
-
-struct wimlib_capture_config *
-copy_capture_config(const struct wimlib_capture_config *config)
-{
- struct wimlib_capture_config *copy;
-
- copy = CALLOC(1, sizeof(struct wimlib_capture_config));
- if (!copy)
- goto oom;
- if (!copy_pattern_list(©->exclusion_pats, &config->exclusion_pats))
- goto oom;
- if (!copy_pattern_list(©->exclusion_exception_pats,
- &config->exclusion_exception_pats))
- goto oom;
+ ret = copy_and_canonicalize_pattern_list(&config->exclusion_pats,
+ &config_copy->exclusion_pats);
+ if (ret)
+ goto out_free_capture_config;
+ ret = copy_and_canonicalize_pattern_list(&config->exclusion_exception_pats,
+ &config_copy->exclusion_exception_pats);
+ if (ret)
+ goto out_free_capture_config;
+ *config_copy_ret = config_copy;
goto out;
-oom:
- free_capture_config(copy);
- copy = NULL;
+out_free_capture_config:
+ free_capture_config(config_copy);
out:
- return copy;
+ return ret;
}
static void
const tchar *pat = list->pats[i];
const tchar *string;
- if (*pat == T('/')) {
+ if (*pat == OS_PREFERRED_PATH_SEPARATOR) {
/* Absolute path from root of capture */
string = path;
} else {
- if (tstrchr(pat, T('/')))
+ if (tstrchr(pat, OS_PREFERRED_PATH_SEPARATOR))
/* Relative path from root of capture */
string = path + 1;
else
* replacement function in win32.c. */
if (fnmatch(pat, string, FNM_PATHNAME | FNM_NOESCAPE
#ifdef FNM_CASEFOLD
- | FNM_CASEFOLD
+ | FNM_CASEFOLD
#endif
) == 0)
{
string, pat);
return true;
} else {
- DEBUG2("\"%"TS"\" does not match the pattern \"%"TS"\"",
- string, pat);
+ DEBUG("\"%"TS"\" does not match the pattern \"%"TS"\"",
+ string, pat);
}
}
return false;
}
+void
+do_capture_progress(struct add_image_params *params, int status,
+ const struct wim_inode *inode)
+{
+ switch (status) {
+ case WIMLIB_SCAN_DENTRY_OK:
+ if (!(params->add_flags & WIMLIB_ADD_FLAG_VERBOSE))
+ return;
+ case WIMLIB_SCAN_DENTRY_UNSUPPORTED:
+ case WIMLIB_SCAN_DENTRY_EXCLUDED:
+ case WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK:
+ if (!(params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE))
+ return;
+ }
+ params->progress.scan.status = status;
+ if (status == WIMLIB_SCAN_DENTRY_OK && inode->i_nlink == 1) {
+ const struct wim_lookup_table_entry *lte;
+ for (unsigned i = 0; i <= inode->i_num_ads; i++) {
+ lte = inode_stream_lte_resolved(inode, i);
+ if (lte != NULL)
+ params->progress.scan.num_bytes_scanned += lte->size;
+ }
+ if (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY)
+ params->progress.scan.num_dirs_scanned++;
+ else
+ params->progress.scan.num_nondirs_scanned++;
+ }
+ if (params->progress_func) {
+ params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY,
+ ¶ms->progress);
+ }
+}
+
/* Return true if the image capture configuration file indicates we should
* exclude the filename @path from capture.
*
exclude_path(const tchar *path, size_t path_len,
const struct wimlib_capture_config *config, bool exclude_prefix)
{
+ if (!config)
+ return false;
const tchar *basename = path_basename_with_len(path, path_len);
if (exclude_prefix) {
wimlib_assert(path_len >= config->_prefix_num_tchars);
if (!tmemcmp(config->_prefix, path, config->_prefix_num_tchars) &&
- path[config->_prefix_num_tchars] == T('/'))
+ path[config->_prefix_num_tchars] == OS_PREFERRED_PATH_SEPARATOR)
{
path += config->_prefix_num_tchars;
}