From 88bfb44de205f72acaefac0d509e1e4e604496f1 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 12 May 2014 16:58:21 -0500 Subject: [PATCH] capture_common.c: Cleanup (mostly comments) --- include/wimlib/capture.h | 8 +-- src/capture_common.c | 110 +++++++++++++++++++++++++++++---------- src/ntfs-3g_capture.c | 2 +- src/textfile.c | 23 ++++---- src/unix_capture.c | 6 +-- src/update_image.c | 6 +-- src/win32_capture.c | 6 +-- 7 files changed, 108 insertions(+), 53 deletions(-) diff --git a/include/wimlib/capture.h b/include/wimlib/capture.h index d0c7a324..f7ae1ada 100644 --- a/include/wimlib/capture.h +++ b/include/wimlib/capture.h @@ -69,8 +69,8 @@ extern int mangle_pat(tchar *pat, const tchar *path, unsigned long line_no); extern int -do_read_capture_config_file(const tchar *config_file, const void *buf, - size_t bufsize, struct capture_config *config); +read_capture_config(const tchar *config_file, const void *buf, + size_t bufsize, struct capture_config *config); extern void destroy_capture_config(struct capture_config *config); @@ -80,8 +80,8 @@ match_pattern_list(const tchar *path, size_t path_nchars, const struct string_set *list); extern bool -exclude_path(const tchar *path, size_t path_nchars, - const struct capture_config *config); +should_exclude_path(const tchar *path, size_t path_nchars, + const struct capture_config *config); typedef int (*capture_tree_t)(struct wim_dentry **, const tchar *, struct add_image_params *); diff --git a/src/capture_common.c b/src/capture_common.c index 7db7c5cf..4db070f8 100644 --- a/src/capture_common.c +++ b/src/capture_common.c @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2013 Eric Biggers + * Copyright (C) 2013, 2014 Eric Biggers * * This file is part of wimlib, a library for working with WIM files. * @@ -25,7 +25,6 @@ # include "config.h" #endif -#include "wimlib/assert.h" #include "wimlib/capture.h" #include "wimlib/dentry.h" #include "wimlib/error.h" @@ -36,6 +35,22 @@ #include +/* + * Tally a file (or directory) that has been scanned for a capture operation, + * and possibly call the progress function provided by the library user. + * + * @params + * Flags, optional progress function, and progress data for the capture + * operation. + * @status + * Status of the scanned file (ok, unsupported, excluded, or excluded + * symlink). + * @inode + * If @status is WIMLIB_SCAN_DENTRY_OK, this is a pointer to the WIM inode + * that has been created for the scanned file. The first time the file is + * seen, inode->i_nlink will be 1. On subsequent visits of the same inode + * via additional hard links, inode->i_nlink will be greater than 1. + */ void do_capture_progress(struct add_image_params *params, int status, const struct wim_inode *inode) @@ -52,35 +67,52 @@ do_capture_progress(struct add_image_params *params, int status, } params->progress.scan.status = status; if (status == WIMLIB_SCAN_DENTRY_OK && inode->i_nlink == 1) { + + /* Successful scan, and visiting inode for the first time */ + + /* Tally size of all data streams. */ 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) + if (lte) params->progress.scan.num_bytes_scanned += lte->size; } + + /* Tally the file itself. */ if (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) params->progress.scan.num_dirs_scanned++; else params->progress.scan.num_nondirs_scanned++; } + /* Call the user-provided progress function. */ if (params->progress_func) { params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, ¶ms->progress); } } +/* + * Given a null-terminated pathname pattern @pat that has been read from line + * @line_no of the file @path, validate and canonicalize the pattern. + * + * On success, returns 0. + * On failure, returns WIMLIB_ERR_INVALID_CAPTURE_CONFIG. + * In either case, @pat may have been modified in-place (and possibly + * shortened). + */ int mangle_pat(tchar *pat, const tchar *path, unsigned long line_no) { if (!is_any_path_separator(pat[0]) && pat[0] != T('\0') && pat[1] == T(':')) { - /* Pattern begins with drive letter */ + /* Pattern begins with drive letter. */ + 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. */ + * absolute. */ ERROR("%"TS":%lu: Invalid pattern \"%"TS"\":\n" " Patterns including drive letters must be absolute!\n" " Maybe try \"%"TC":%"TC"%"TS"\"?\n", @@ -97,18 +129,21 @@ mangle_pat(tchar *pat, const tchar *path, unsigned long line_no) tmemmove(pat, pat + 2, tstrlen(pat + 2) + 1); } - /* Collapse and translate path separators. + /* Collapse consecutive path separators, and translate both / and \ into + * / (UNIX) or \ (Windows). * - * Note: we require that this works for filesystem paths and WIM paths, - * so the desired path separators must be the same. */ + * Note: we expect that this function produces patterns that can be used + * for both filesystem paths and WIM paths, so the desired path + * separators must be the same. */ BUILD_BUG_ON(OS_PREFERRED_PATH_SEPARATOR != WIM_PATH_SEPARATOR); do_canonicalize_path(pat, pat); - /* Relative patterns can only match file names. */ + /* Relative patterns can only match file names, so they must be + * single-component only. */ if (pat[0] != OS_PREFERRED_PATH_SEPARATOR && tstrchr(pat, OS_PREFERRED_PATH_SEPARATOR)) { - ERROR("%"TS":%lu: Invalid path \"%"TS"\":\n" + ERROR("%"TS":%lu: Invalid pattern \"%"TS"\":\n" " Relative patterns can only include one path component!\n" " Maybe try \"%"TC"%"TS"\"?", path, line_no, pat, OS_PREFERRED_PATH_SEPARATOR, pat); @@ -118,15 +153,30 @@ mangle_pat(tchar *pat, const tchar *path, unsigned long line_no) return 0; } +/* + * Read, parse, and validate a capture configuration file from either an on-disk + * file or an in-memory buffer. + * + * To read from a file, specify @config_file, and use NULL for @buf. + * To read from a buffer, specify @buf and @bufsize. + * + * @config must be initialized to all 0's. + * + * On success, 0 will be returned, and the resulting capture configuration will + * be stored in @config. + * + * On failure, a positive error code will be returned, and the contents of + * @config will be invalidated. + */ int -do_read_capture_config_file(const tchar *config_file, const void *buf, - size_t bufsize, struct capture_config *config) +read_capture_config(const tchar *config_file, const void *buf, + size_t bufsize, struct capture_config *config) { int ret; /* [PrepopulateList] is used for apply, not capture. But since we do - * understand it, recognize it (avoiding unrecognized section warning) - * and discard the strings. */ + * understand it, recognize it, thereby avoiding the unrecognized + * section warning, but discard the resulting strings. */ STRING_SET(prepopulate_pats); struct text_file_section sections[] = { @@ -159,36 +209,40 @@ destroy_capture_config(struct capture_config *config) FREE(config->buf); } +/* + * Determine whether a path matches any wildcard pattern in a list. + * + * Special rules apply about what form @path must be in; see match_path(). + */ bool -match_pattern_list(const tchar *path, size_t path_len, +match_pattern_list(const tchar *path, size_t path_nchars, const struct string_set *list) { for (size_t i = 0; i < list->num_strings; i++) - if (match_path(path, path_len, list->strings[i], + if (match_path(path, path_nchars, list->strings[i], OS_PREFERRED_PATH_SEPARATOR, true)) return true; return false; } /* - * Return true if the image capture configuration file indicates we should - * exclude the filename @path from capture. + * Determine whether the filesystem @path should be excluded from capture, based + * on the current capture configuration file. * - * The passed in @path must be given relative to the root of the capture, but - * with a leading path separator. For example, if the file "in/file" is being - * tested and the library user ran wimlib_add_image(wim, "in", ...), then the - * directory "in" is the root of the capture and the path should be specified as - * "/file". + * The @path must be given relative to the root of the capture, but with a + * leading path separator. For example, if the file "in/file" is being tested + * and the library user ran wimlib_add_image(wim, "in", ...), then the directory + * "in" is the root of the capture and the path should be specified as "/file". * - * Also, all path separators in @path must be OS_PREFERRED_PATH_SEPARATOR, and - * there cannot be trailing slashes. + * Also, all path separators in @path must be OS_PREFERRED_PATH_SEPARATOR, there + * cannot be trailing slashes, and there cannot be consecutive path separators. * * As a special case, the empty string will be interpreted as a single path - * separator. + * separator (which means the root of capture itself). */ bool -exclude_path(const tchar *path, size_t path_nchars, - const struct capture_config *config) +should_exclude_path(const tchar *path, size_t path_nchars, + const struct capture_config *config) { tchar dummy[2]; diff --git a/src/ntfs-3g_capture.c b/src/ntfs-3g_capture.c index 335eb6d5..228a68d8 100644 --- a/src/ntfs-3g_capture.c +++ b/src/ntfs-3g_capture.c @@ -536,7 +536,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret, struct wim_dentry *root = NULL; struct wim_inode *inode = NULL; - if (exclude_path(path, path_len, params->config)) { + if (should_exclude_path(path, path_len, params->config)) { /* Exclude a file or directory tree based on the capture * configuration file. */ ret = 0; diff --git a/src/textfile.c b/src/textfile.c index a2b630a7..332386dc 100644 --- a/src/textfile.c +++ b/src/textfile.c @@ -298,29 +298,30 @@ parse_text_file(const tchar *path, tchar *buf, size_t buflen, * Path to the file on disk to read, or a dummy name for the buffer. * @buf * If NULL, the data will be read from the @path file. Otherwise the data - * will be read from this buffer, which must be newline-terminated. - * @buflen + * will be read from this buffer. + * @bufsize * Length of buffer in bytes; ignored if @buf is NULL. - * @buf_ret + * @mem_ret * On success, a pointer to a buffer backing the parsed lines is stored - * here. If @buf is not NULL, this will be @buf. Otherwise, this will be - * an allocated buffer that must be freed when finished with the lines. + * here. This must be freed after the parsed lines are done being used. * @pos_sections * Specifications of allowed sections in the file. Each such specification * consists of the name of the section (e.g. [ExclusionList], like in the * INI file format), along with a pointer to the list of lines parsed for * that section. Use an empty name to indicate the destination of lines - * not in any section. + * not in any section. Each list must be initialized to an empty string + * set. * @num_pos_sections - * Length of @pos_sections array. + * Number of entries in the @pos_sections array. * @flags - * LOAD_TEXT_FILE_REMOVE_QUOTES or 0. + * Flags: LOAD_TEXT_FILE_REMOVE_QUOTES, LOAD_TEXT_FILE_NO_WARNINGS. * @mangle_line - * Optional callback to modify each line being read. + * Optional callback to validate and/or modify each line being read. * - * Returns 0 on success or a positive error code on failure. + * Returns 0 on success; nonzero on failure. * - * Unknown sections are ignored (warning printed). + * Unknown sections are ignored, but a warning is printed for each, unless + * LOAD_TEXT_FILE_NO_WARNINGS is specified. */ int do_load_text_file(const tchar *path, diff --git a/src/unix_capture.c b/src/unix_capture.c index c0aa1950..38adb1c5 100644 --- a/src/unix_capture.c +++ b/src/unix_capture.c @@ -209,9 +209,9 @@ unix_build_dentry_tree_recursive(struct wim_dentry **root_ret, struct wim_inode *inode = NULL; struct stat stbuf; - if (exclude_path(path + params->capture_root_nchars, - path_len - params->capture_root_nchars, - params->config)) + if (should_exclude_path(path + params->capture_root_nchars, + path_len - params->capture_root_nchars, + params->config)) { ret = 0; goto out_progress; diff --git a/src/update_image.c b/src/update_image.c index c088c831..81e0e914 100644 --- a/src/update_image.c +++ b/src/update_image.c @@ -768,11 +768,11 @@ get_capture_config(const tchar *config_file, struct capture_config *config, /* Use Windows default. */ if (config_file) return WIMLIB_ERR_INVALID_PARAM; - ret = do_read_capture_config_file(T("wincfg"), wincfg, - sizeof(wincfg) - 1, config); + ret = read_capture_config(T("wincfg"), wincfg, + sizeof(wincfg) - 1, config); } else if (config_file) { /* Use the specified configuration file. */ - ret = do_read_capture_config_file(config_file, NULL, 0, config); + ret = read_capture_config(config_file, NULL, 0, config); } else { /* ... Or don't use any configuration file at all. No files * will be excluded from capture, all files will be compressed, diff --git a/src/win32_capture.c b/src/win32_capture.c index c62abce7..feac7644 100644 --- a/src/win32_capture.c +++ b/src/win32_capture.c @@ -1141,9 +1141,9 @@ win32_build_dentry_tree_recursive(struct wim_dentry **root_ret, DWORD desiredAccess; - if (exclude_path(path + params->capture_root_nchars, - path_num_chars - params->capture_root_nchars, - params->config)) + if (should_exclude_path(path + params->capture_root_nchars, + path_num_chars - params->capture_root_nchars, + params->config)) { ret = 0; goto out_progress; -- 2.43.0