/*
* Copyright (C) 2013 Eric Biggers
*
- * This file is part of wimlib, a library for working with WIM files.
+ * This file is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option) any
+ * later version.
*
- * wimlib is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version.
- *
- * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * This file is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
- * You should have received a copy of the GNU General Public License
- * along with wimlib; if not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this file; if not, see http://www.gnu.org/licenses/.
*/
#ifdef HAVE_CONFIG_H
#define WIMLIB_REF_MASK_PUBLIC (WIMLIB_REF_FLAG_GLOB_ENABLE | \
WIMLIB_REF_FLAG_GLOB_ERR_ON_NOMATCH)
+#define WIMLIB_REF_FLAG_GIFT 0x80000000
+
+struct lookup_tables {
+ struct wim_lookup_table *src_table;
+ struct wim_lookup_table *dest_table;
+};
+
+static int
+lte_gift(struct wim_lookup_table_entry *lte, void *_tables)
+{
+ struct lookup_tables *tables = _tables;
+ struct wim_lookup_table *src_table = tables->src_table;
+ struct wim_lookup_table *dest_table = tables->dest_table;
+
+ lookup_table_unlink(src_table, lte);
+ if (lookup_stream(dest_table, lte->hash)) {
+ free_lookup_table_entry(lte);
+ } else {
+ lte->out_refcnt = 1;
+ lookup_table_insert(dest_table, lte);
+ }
+ return 0;
+}
+
static int
lte_clone_if_new(struct wim_lookup_table_entry *lte, void *_lookup_table)
{
return 0;
}
+static int
+do_wimlib_reference_resources(WIMStruct *wim, WIMStruct **resource_wims,
+ unsigned num_resource_wims, int ref_flags)
+{
+ unsigned i;
+ int ret;
+
+ if (ref_flags & WIMLIB_REF_FLAG_GIFT) {
+ struct lookup_tables tables;
+
+ tables.dest_table = wim->lookup_table;
+
+ for (i = 0; i < num_resource_wims; i++) {
+
+ tables.src_table = resource_wims[i]->lookup_table;
+
+ ret = for_lookup_table_entry(resource_wims[i]->lookup_table,
+ lte_gift, &tables);
+ if (ret)
+ goto out_rollback;
+ }
+ } else {
+ for (i = 0; i < num_resource_wims; i++) {
+ ret = for_lookup_table_entry(resource_wims[i]->lookup_table,
+ lte_clone_if_new, wim->lookup_table);
+ if (ret)
+ goto out_rollback;
+ }
+ }
+ return 0;
+
+out_rollback:
+ for_lookup_table_entry(wim->lookup_table, lte_delete_if_new,
+ wim->lookup_table);
+ return ret;
+}
+
/* API function documented in wimlib.h */
WIMLIBAPI int
wimlib_reference_resources(WIMStruct *wim,
WIMStruct **resource_wims, unsigned num_resource_wims,
int ref_flags)
{
- int ret;
unsigned i;
if (wim == NULL)
if (resource_wims[i] == NULL)
return WIMLIB_ERR_INVALID_PARAM;
- for_lookup_table_entry(wim->lookup_table, lte_zero_out_refcnt, NULL);
-
- for (i = 0; i < num_resource_wims; i++) {
- ret = for_lookup_table_entry(resource_wims[i]->lookup_table,
- lte_clone_if_new,
- wim->lookup_table);
- if (ret)
- goto out_rollback;
- }
- return 0;
-
-out_rollback:
- for_lookup_table_entry(wim->lookup_table, lte_delete_if_new,
- wim->lookup_table);
- return ret;
+ return do_wimlib_reference_resources(wim, resource_wims,
+ num_resource_wims, ref_flags);
}
static int
const tchar * const *resource_wimfiles,
unsigned num_resource_wimfiles,
int ref_flags,
- int open_flags,
- wimlib_progress_func_t progress_func)
+ int open_flags)
{
WIMStruct **resource_wims;
unsigned i;
for (i = 0; i < num_resource_wimfiles; i++) {
DEBUG("Referencing resources from path \"%"TS"\"",
resource_wimfiles[i]);
- ret = wimlib_open_wim(resource_wimfiles[i], open_flags,
- &resource_wims[i], progress_func);
+ ret = wimlib_open_wim_with_progress(resource_wimfiles[i],
+ open_flags,
+ &resource_wims[i],
+ wim->progfunc,
+ wim->progctx);
if (ret)
goto out_free_resource_wims;
}
- ret = wimlib_reference_resources(wim, resource_wims,
- num_resource_wimfiles, ref_flags);
+ ret = do_wimlib_reference_resources(wim, resource_wims,
+ num_resource_wimfiles,
+ ref_flags | WIMLIB_REF_FLAG_GIFT);
if (ret)
goto out_free_resource_wims;
static int
reference_resource_glob(WIMStruct *wim, const tchar *refglob,
- int ref_flags, int open_flags,
- wimlib_progress_func_t progress_func)
+ int ref_flags, int open_flags)
{
glob_t globbuf;
int ret;
&refglob,
1,
ref_flags,
- open_flags,
- progress_func);
+ open_flags);
}
} else {
ERROR_WITH_ERRNO("Failed to process glob \"%"TS"\"", refglob);
(const tchar * const *)globbuf.gl_pathv,
globbuf.gl_pathc,
ref_flags,
- open_flags,
- progress_func);
+ open_flags);
globfree(&globbuf);
return ret;
}
const tchar * const * resource_wimfiles_or_globs,
unsigned count,
int ref_flags,
- int open_flags,
- wimlib_progress_func_t progress_func)
+ int open_flags)
{
unsigned i;
int ret;
ret = reference_resource_glob(wim,
resource_wimfiles_or_globs[i],
ref_flags,
- open_flags,
- progress_func);
+ open_flags);
if (ret)
return ret;
}
return 0;
} else {
return reference_resource_paths(wim, resource_wimfiles_or_globs,
- count, ref_flags,
- open_flags, progress_func);
+ count, ref_flags, open_flags);
}
}