- ret = sha1sum(lte->staging_file_name, hash);
- if (ret != 0)
- return ret;
- lookup_table_unlink(table, lte);
- duplicate_lte = __lookup_resource(table, hash);
- if (duplicate_lte) {
- /* Merge duplicate lookup table entries */
- duplicate_lte->refcnt += lte->refcnt;
- inode_update_lte_ptr(lte->lte_inode, lte, duplicate_lte);
- free_lookup_table_entry(lte);
- } else {
- if (stat(lte->staging_file_name, &stbuf) != 0) {
- ERROR_WITH_ERRNO("Failed to stat `%s'", lte->staging_file_name);
- return WIMLIB_ERR_STAT;
- }
- if (stbuf.st_size == 0) {
- /* Zero-length stream. No lookup table entry needed. */
- inode_update_lte_ptr(lte->lte_inode, lte, NULL);
- free_lookup_table_entry(lte);
- } else {
- BUILD_BUG_ON(<e->file_on_disk != <e->staging_file_name);
- lte->resource_entry.original_size = stbuf.st_size;
- lte->resource_entry.size = stbuf.st_size;
- lte->resource_location = RESOURCE_IN_FILE_ON_DISK;
- lte->file_on_disk_fp = NULL;
- copy_hash(lte->hash, hash);
- lookup_table_insert(table, lte);
- }
- }
- return 0;
-}
-
-static int inode_close_fds(struct wim_inode *inode)
-{
- u16 num_opened_fds = inode->i_num_opened_fds;
- for (u16 i = 0, j = 0; j < num_opened_fds; i++) {
- struct wimfs_fd *fd = inode->i_fds[i];
- if (fd) {
- wimlib_assert(fd->f_inode == inode);
- int ret = close_wimfs_fd(fd);
- if (ret != 0)
- return ret;
- j++;
- }
- }
- return 0;
-}
-
-/* Overwrites the WIM file, with changes saved. */
-static int rebuild_wim(struct wimfs_context *ctx, int write_flags,
- wimlib_progress_func_t progress_func)
-{
- int ret;
- struct wim_lookup_table_entry *lte, *tmp;
- WIMStruct *w = ctx->wim;
-
- DEBUG("Closing all staging file descriptors.");
- list_for_each_entry_safe(lte, tmp, &ctx->staging_list, staging_list) {
- ret = inode_close_fds(lte->lte_inode);
- if (ret != 0)
- return ret;
- }
-
- DEBUG("Calculating SHA1 checksums for all new staging files.");
- list_for_each_entry_safe(lte, tmp, &ctx->staging_list, staging_list) {
- ret = update_lte_of_staging_file(lte, w->lookup_table);
- if (ret != 0)
- return ret;
- }
-
- xml_update_image_info(w, w->current_image);
- ret = wimlib_overwrite(w, write_flags, 0, progress_func);
- if (ret != 0)
- ERROR("Failed to commit changes to mounted WIM image");
- return ret;
-}
-
-
-
-/* Simple function that returns the concatenation of 2 strings. */
-static char *strcat_dup(const char *s1, const char *s2, size_t max_len)
-{
- size_t len = strlen(s1) + strlen(s2);
- if (len > max_len)
- len = max_len;
- char *p = MALLOC(len + 1);
- if (!p)
- return NULL;
- snprintf(p, len + 1, "%s%s", s1, s2);
- return p;
-}
-
-static int set_message_queue_names(struct wimfs_context *ctx,
- const char *mount_dir)
-{
- static const char *u2d_prefix = "/wimlib-unmount-to-daemon-mq";
- static const char *d2u_prefix = "/wimlib-daemon-to-unmount-mq";
- char *dir_path;
- char *p;
- int ret;
-
- dir_path = realpath(mount_dir, NULL);
- if (!dir_path) {
- ERROR_WITH_ERRNO("Failed to resolve path \"%s\"", mount_dir);
- if (errno == ENOMEM)
- return WIMLIB_ERR_NOMEM;
- else
- return WIMLIB_ERR_NOTDIR;
- }
-
- for (p = dir_path; *p; p++)
- if (*p == '/')
- *p = 0xff;
-
- ctx->unmount_to_daemon_mq_name = strcat_dup(u2d_prefix, dir_path,
- NAME_MAX);
- if (!ctx->unmount_to_daemon_mq_name) {
- ret = WIMLIB_ERR_NOMEM;
- goto out_free_dir_path;
- }
- ctx->daemon_to_unmount_mq_name = strcat_dup(d2u_prefix, dir_path,
- NAME_MAX);
- if (!ctx->daemon_to_unmount_mq_name) {
- ret = WIMLIB_ERR_NOMEM;
- goto out_free_unmount_to_daemon_mq_name;