- for (size_t i = 0; i < list->num_pats; i++)
- printf(" %s\n", list->pats[i]);
-}
-
-static void print_capture_config(const struct capture_config *config)
-{
- if (config->exclusion_list.num_pats) {
- puts("Files or folders excluded from image capture:");
- print_pattern_list(&config->exclusion_list);
- putchar('\n');
- }
-}
-
-/* Return true if the image capture configuration file indicates we should
- * exclude the filename @path from capture.
- *
- * If @exclude_prefix is %true, the part of the path up and including the name
- * of the directory being captured is not included in the path for matching
- * purposes. This allows, for example, a pattern like /hiberfil.sys to match a
- * file /mnt/windows7/hiberfil.sys if we are capturing the /mnt/windows7
- * directory.
- */
-bool exclude_path(const char *path, const struct capture_config *config,
- bool exclude_prefix)
-{
- const char *basename = path_basename(path);
- if (exclude_prefix) {
- wimlib_assert(strlen(path) >= config->prefix_len);
- if (memcmp(config->prefix, path, config->prefix_len) == 0
- && path[config->prefix_len] == '/')
- path += config->prefix_len;
- }
- return match_pattern(path, basename, &config->exclusion_list) &&
- !match_pattern(path, basename, &config->exclusion_exception);
-
-}
-
-WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *source,
- const char *name, const char *config_str,
- size_t config_len, int add_image_flags,
- wimlib_progress_func_t progress_func)
-{
- int (*capture_tree)(struct wim_dentry **, const char *,
- struct wim_lookup_table *,
- struct wim_security_data *,
- const struct capture_config *,
- int, wimlib_progress_func_t, void *);
- void *extra_arg;
-
- struct wim_dentry *root_dentry = NULL;
- struct wim_security_data *sd;
- struct capture_config config;
- struct image_metadata *imd;
- int ret;
-
- if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_NTFS) {
-#ifdef WITH_NTFS_3G
- if (add_image_flags & (WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE)) {
- ERROR("Cannot dereference files when capturing directly from NTFS");
- return WIMLIB_ERR_INVALID_PARAM;
- }
- capture_tree = build_dentry_tree_ntfs;
- extra_arg = &w->ntfs_vol;
-#else
- ERROR("wimlib was compiled without support for NTFS-3g, so\n"
- " cannot capture a WIM image directly from a NTFS volume!");
- return WIMLIB_ERR_UNSUPPORTED;
-#endif
- } else {
- capture_tree = build_dentry_tree;
- extra_arg = NULL;
- }
-
- DEBUG("Adding dentry tree from directory or NTFS volume `%s'.", source);
-
- if (!name || !*name) {
- ERROR("Must specify a non-empty string for the image name");
- return WIMLIB_ERR_INVALID_PARAM;
- }
- if (!source || !*source) {
- ERROR("Must specify the name of a directory or NTFS volume");
- return WIMLIB_ERR_INVALID_PARAM;
- }
-
- if (w->hdr.total_parts != 1) {
- ERROR("Cannot add an image to a split WIM");
- return WIMLIB_ERR_SPLIT_UNSUPPORTED;
- }
-
- if (wimlib_image_name_in_use(w, name)) {
- ERROR("There is already an image named \"%s\" in `%s'",
- name, w->filename);
- return WIMLIB_ERR_IMAGE_NAME_COLLISION;
- }
-
- DEBUG("Initializing capture configuration");
- if (!config_str) {
- DEBUG("Using default capture configuration");
- config_str = default_config;
- config_len = strlen(default_config);
- }
- ret = init_capture_config(config_str, config_len, source, &config);
- if (ret != 0)
- return ret;
- print_capture_config(&config);
-
- DEBUG("Allocating security data");
-
- sd = CALLOC(1, sizeof(struct wim_security_data));
- if (!sd) {
- ret = WIMLIB_ERR_NOMEM;
- goto out_destroy_config;
- }
- sd->total_length = 8;
- sd->refcnt = 1;
-
- if (progress_func) {
- union wimlib_progress_info progress;
- progress.scan.source = source;
- progress_func(WIMLIB_PROGRESS_MSG_SCAN_BEGIN, &progress);
- }
-
- DEBUG("Building dentry tree.");
- ret = (*capture_tree)(&root_dentry, source, w->lookup_table, sd,
- &config, add_image_flags | WIMLIB_ADD_IMAGE_FLAG_ROOT,
- progress_func, extra_arg);
- destroy_capture_config(&config);
-
- if (ret != 0) {
- ERROR("Failed to build dentry tree for `%s'", source);
- goto out_free_security_data;
- }
-
- if (progress_func) {
- union wimlib_progress_info progress;
- progress.scan.source = source;
- progress_func(WIMLIB_PROGRESS_MSG_SCAN_END, &progress);
- }
-
- DEBUG("Calculating full paths of dentries.");
- ret = for_dentry_in_tree(root_dentry, calculate_dentry_full_path, NULL);
- if (ret != 0)
- goto out_free_dentry_tree;
-
- ret = add_new_dentry_tree(w, root_dentry, sd);
- if (ret != 0)
- goto out_free_dentry_tree;
-
- imd = &w->image_metadata[w->hdr.image_count - 1];
-
- ret = dentry_tree_fix_inodes(root_dentry, &imd->inode_list);
- if (ret != 0)
- goto out_destroy_imd;
-
- DEBUG("Assigning hard link group IDs");
- assign_inode_numbers(&imd->inode_list);
-
- ret = xml_add_image(w, name);
- if (ret != 0)
- goto out_destroy_imd;
-
- if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_BOOT)
- wimlib_set_boot_idx(w, w->hdr.image_count);
- return 0;
-out_destroy_imd:
- destroy_image_metadata(&w->image_metadata[w->hdr.image_count - 1],
- w->lookup_table);
- w->hdr.image_count--;
- return ret;
-out_free_dentry_tree:
- free_dentry_tree(root_dentry, w->lookup_table);
-out_free_security_data:
- free_security_data(sd);
-out_destroy_config:
- destroy_capture_config(&config);
- return ret;