stbuf->st_gid = getgid();
/* Use the size of the unnamed (default) file stream. */
- if ((lte = dentry_lte(dentry))) {
+ lte = dentry_first_lte_resolved(dentry);
+ if (lte) {
if (lte->staging_file_name) {
struct stat native_stat;
- if (stat(lte->staging_file_name, &native_stat) != 0)
+ if (stat(lte->staging_file_name, &native_stat) != 0) {
+ DEBUG("Failed to stat `%s': %m",
+ lte->staging_file_name);
return -errno;
+ }
stbuf->st_size = native_stat.st_size;
} else {
stbuf->st_size = lte->resource_entry.original_size;
stbuf->st_size = 0;
}
- stbuf->st_atime = ms_timestamp_to_unix(dentry->last_access_time);
- stbuf->st_mtime = ms_timestamp_to_unix(dentry->last_write_time);
- stbuf->st_ctime = ms_timestamp_to_unix(dentry->creation_time);
+ stbuf->st_atime = wim_timestamp_to_unix(dentry->last_access_time);
+ stbuf->st_mtime = wim_timestamp_to_unix(dentry->last_write_time);
+ stbuf->st_ctime = wim_timestamp_to_unix(dentry->creation_time);
stbuf->st_blocks = (stbuf->st_size + 511) / 512;
return 0;
}
int fd;
int errno_save;
- name_len = staging_dir_name_len + 1 + WIM_HASH_SIZE;
+ name_len = staging_dir_name_len + 1 + SHA1_HASH_SIZE;
name = MALLOC(name_len + 1);
if (!name) {
errno = ENOMEM;
memcpy(name, staging_dir_name, staging_dir_name_len);
name[staging_dir_name_len] = '/';
randomize_char_array_with_alnum(name + staging_dir_name_len + 1,
- WIM_HASH_SIZE);
+ SHA1_HASH_SIZE);
name[name_len] = '\0';
}
new_lte->resource_entry.original_size = size;
new_lte->refcnt = link_group_size;
- randomize_byte_array(new_lte->hash, WIM_HASH_SIZE);
+ random_hash(new_lte->hash);
new_lte->staging_file_name = staging_file_name;
lookup_table_insert(w->lookup_table, new_lte);
}
-static int calculate_sha1sum_of_staging_file(struct lookup_table_entry *lte,
- struct lookup_table *table)
+static int update_lte_of_staging_file(struct lookup_table_entry *lte,
+ struct lookup_table *table)
{
struct lookup_table_entry *duplicate_lte;
int ret;
- u8 hash[WIM_HASH_SIZE];
+ u8 hash[SHA1_HASH_SIZE];
+ struct stat stbuf;
+
+ wimlib_assert(lte->staging_file_name);
ret = sha1sum(lte->staging_file_name, hash);
if (ret != 0)
return ret;
+
lookup_table_unlink(table, lte);
- memcpy(lte->hash, hash, WIM_HASH_SIZE);
duplicate_lte = __lookup_resource(table, hash);
lte_list_change_lte_ptr(lte, duplicate_lte);
duplicate_lte->refcnt += lte->refcnt;
- list_splice(&duplicate_lte->lte_group_list,
- <e->lte_group_list);
+ list_splice(<e->lte_group_list,
+ &duplicate_lte->lte_group_list);
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;
+ }
+ copy_hash(lte->hash, hash);
+ lte->resource_entry.original_size = stbuf.st_size;
lookup_table_insert(table, lte);
}
* lookup table entries. */
DEBUG("Calculating SHA1 checksums for all new staging files.");
list_for_each_entry_safe(lte, tmp, &staging_list, staging_list) {
- ret = calculate_sha1sum_of_staging_file(lte, w->lookup_table);
+ ret = update_lte_of_staging_file(lte, w->lookup_table);
if (ret != 0)
return ret;
}
}
if (flags_writable(fi->flags) && fd->dentry) {
- u64 now = get_timestamp();
+ u64 now = get_wim_timestamp();
fd->dentry->last_access_time = now;
fd->dentry->last_write_time = now;
}
dentry->ads_entries[1].lte_group_list.type = STREAM_TYPE_ADS;
list_add(&dentry->ads_entries[1].lte_group_list.list,
<e->lte_group_list);
- dentry->ads_entries[1].lte = lte;
- dentry->resolved = true;
+ wimlib_assert(dentry->resolved);
link_dentry(dentry, dentry_parent);
return 0;
return 0;
}
-/* Change the timestamp on a file dentry.
+/*
+ * Change the timestamp on a file dentry.
*
- * There is no distinction between a file and its alternate data streams here. */
+ * Note that alternate data streams do not have their own timestamps.
+ */
static int wimfs_utimens(const char *path, const struct timespec tv[2])
{
struct dentry *dentry = get_dentry(w, path);
if (!dentry)
return -ENOENT;
- time_t last_access_t = (tv[0].tv_nsec == UTIME_NOW) ?
- time(NULL) : tv[0].tv_sec;
- dentry->last_access_time = unix_timestamp_to_ms(last_access_t);
- time_t last_mod_t = (tv[1].tv_nsec == UTIME_NOW) ?
- time(NULL) : tv[1].tv_sec;
- dentry->last_write_time = unix_timestamp_to_ms(last_mod_t);
+ if (tv[0].tv_nsec != UTIME_OMIT) {
+ if (tv[0].tv_nsec == UTIME_NOW)
+ dentry->last_access_time = get_wim_timestamp();
+ else
+ dentry->last_access_time = timespec_to_wim_timestamp(&tv[0]);
+ }
+ if (tv[1].tv_nsec != UTIME_OMIT) {
+ if (tv[1].tv_nsec == UTIME_NOW)
+ dentry->last_write_time = get_wim_timestamp();
+ else
+ dentry->last_write_time = timespec_to_wim_timestamp(&tv[1]);
+ }
return 0;
}
ERROR("The following lookup table entry has a reference count "
"of %u, but", lte->refcnt);
ERROR("We found %u references to it", lte_group_size);
- print_lookup_table_entry(lte, NULL);
+ print_lookup_table_entry(lte);
#endif
return WIMLIB_ERR_INVALID_DENTRY;
}
if (!p)
return WIMLIB_ERR_NOMEM;
- argv[argc++] = "mount";
+ argv[argc++] = "imagex";
argv[argc++] = p;
argv[argc++] = "-s"; /* disable multi-threaded operation */