* wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "buffer_io.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "timestamp.h"
-#include "wimlib_internal.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wimlib.h"
+#include "wimlib/buffer_io.h"
+#include "wimlib/dentry.h"
+#include "wimlib/encoding.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/metadata.h"
+#include "wimlib/resource.h"
+#include "wimlib/timestamp.h"
+
#include <errno.h>
/* Calculates the unaligned length, in bytes, of an on-disk WIM dentry that has
* a file name and short name that take the specified numbers of bytes. This
* excludes any alternate data stream entries that may follow the dentry. */
static u64
-__dentry_correct_length_unaligned(u16 file_name_nbytes, u16 short_name_nbytes)
+_dentry_correct_length_unaligned(u16 file_name_nbytes, u16 short_name_nbytes)
{
u64 length = WIM_DENTRY_DISK_SIZE;
if (file_name_nbytes)
static u64
dentry_correct_length_unaligned(const struct wim_dentry *dentry)
{
- return __dentry_correct_length_unaligned(dentry->file_name_nbytes,
+ return _dentry_correct_length_unaligned(dentry->file_name_nbytes,
dentry->short_name_nbytes);
}
static u64
-__dentry_total_length(const struct wim_dentry *dentry, u64 length)
+_dentry_total_length(const struct wim_dentry *dentry, u64 length)
{
const struct wim_inode *inode = dentry->d_inode;
for (u16 i = 0; i < inode->i_num_ads; i++)
u64
dentry_correct_total_length(const struct wim_dentry *dentry)
{
- return __dentry_total_length(dentry,
+ return _dentry_total_length(dentry,
dentry_correct_length_unaligned(dentry));
}
static u64
dentry_total_length(const struct wim_dentry *dentry)
{
- return __dentry_total_length(dentry, dentry->length);
+ return _dentry_total_length(dentry, dentry->length);
}
int
int ret;
if (node) {
ret = for_dentry_tree_in_rbtree(node->rb_left, visitor, arg);
- if (ret != 0)
+ if (ret)
return ret;
ret = for_dentry_in_tree(rbnode_dentry(node), visitor, arg);
- if (ret != 0)
+ if (ret)
return ret;
ret = for_dentry_tree_in_rbtree(node->rb_right, visitor, arg);
- if (ret != 0)
+ if (ret)
return ret;
}
return 0;
for_dentry_in_tree(struct wim_dentry *root,
int (*visitor)(struct wim_dentry*, void*), void *arg)
{
- int ret = visitor(root, arg);
- if (ret == 0) {
- ret = for_dentry_tree_in_rbtree(root->d_inode->i_children.rb_node,
- visitor,
- arg);
- }
- return ret;
+ int ret;
+
+ if (!root)
+ return 0;
+ ret = (*visitor)(root, arg);
+ if (ret)
+ return ret;
+ return for_dentry_tree_in_rbtree(root->d_inode->i_children.rb_node,
+ visitor,
+ arg);
}
/* Like for_dentry_in_tree(), but the visitor function is always called on a
int (*visitor)(struct wim_dentry*, void*), void *arg)
{
int ret;
+
+ if (!root)
+ return 0;
ret = for_dentry_tree_in_rbtree_depth(root->d_inode->i_children.rb_node,
visitor, arg);
- if (ret == 0)
- ret = visitor(root, arg);
- return ret;
+ if (ret)
+ return ret;
+ return (*visitor)(root, arg);
}
/* Calculate the full path of @dentry. The full path of its parent must have
const utf16lechar *p, *pp;
cur_dentry = parent_dentry = wim_root_dentry(w);
+ if (!cur_dentry) {
+ errno = ENOENT;
+ return NULL;
+ }
p = path;
while (1) {
while (*p == cpu_to_le16('/'))
}
struct wim_inode *
-new_timeless_inode()
+new_timeless_inode(void)
{
struct wim_inode *inode = CALLOC(1, sizeof(struct wim_inode));
if (inode) {
inode->i_nlink = 1;
inode->i_next_stream_id = 1;
inode->i_not_rpfixed = 1;
+ INIT_LIST_HEAD(&inode->i_list);
#ifdef WITH_FUSE
if (pthread_mutex_init(&inode->i_mutex, NULL) != 0) {
ERROR_WITH_ERRNO("Error initializing mutex");
}
static struct wim_inode *
-new_inode()
+new_inode(void)
{
struct wim_inode *inode = new_timeless_inode();
if (inode) {
static int
-__new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret,
+_new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret,
bool timeless)
{
struct wim_dentry *dentry;
int
new_dentry_with_timeless_inode(const tchar *name, struct wim_dentry **dentry_ret)
{
- return __new_dentry_with_inode(name, dentry_ret, true);
+ return _new_dentry_with_inode(name, dentry_ret, true);
}
int
new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret)
{
- return __new_dentry_with_inode(name, dentry_ret, false);
+ return _new_dentry_with_inode(name, dentry_ret, false);
}
+int
+new_filler_directory(const tchar *name, struct wim_dentry **dentry_ret)
+{
+ int ret;
+ struct wim_dentry *dentry;
+
+ DEBUG("Creating filler directory \"%"TS"\"", name);
+ ret = new_dentry_with_inode(name, &dentry);
+ if (ret)
+ goto out;
+ /* Leave the inode number as 0; this is allowed for non
+ * hard-linked files. */
+ dentry->d_inode->i_resolved = 1;
+ dentry->d_inode->i_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ *dentry_ret = dentry;
+ ret = 0;
+out:
+ return ret;
+}
static int
init_ads_entry(struct wim_ads_entry *ads_entry, const void *name,
wimlib_assert(inode->i_num_opened_fds == 0);
FREE(inode->i_fds);
pthread_mutex_destroy(&inode->i_mutex);
- if (inode->i_hlist.pprev)
- hlist_del(&inode->i_hlist);
#endif
+ /* HACK: This may instead delete the inode from i_list, but the
+ * hlist_del() behaves the same as list_del(). */
+ hlist_del(&inode->i_hlist);
FREE(inode->i_extracted_file);
FREE(inode);
}
/* This function is passed as an argument to for_dentry_in_tree_depth() in order
* to free a directory tree. */
static int
-do_free_dentry(struct wim_dentry *dentry, void *__lookup_table)
+do_free_dentry(struct wim_dentry *dentry, void *_lookup_table)
{
- struct wim_lookup_table *lookup_table = __lookup_table;
+ struct wim_lookup_table *lookup_table = _lookup_table;
unsigned i;
if (lookup_table) {
void
free_dentry_tree(struct wim_dentry *root, struct wim_lookup_table *lookup_table)
{
- if (root)
- for_dentry_in_tree_depth(root, do_free_dentry, lookup_table);
+ for_dentry_in_tree_depth(root, do_free_dentry, lookup_table);
}
/*
void *buf;
sha1_buffer(data, len, hash);
-
existing_lte = __lookup_resource(lookup_table, hash);
-
if (existing_lte) {
wimlib_assert(wim_resource_size(existing_lte) == len);
lte = existing_lte;
lte->refcnt++;
} else {
- void *buf;
-
lte = new_lookup_table_entry();
if (!lte)
return WIMLIB_ERR_NOMEM;
if (size != sizeof(struct wimlib_unix_data))
return BAD_UNIX_DATA;
- ret = read_full_resource_into_buf(lte, unix_data, true);
+ ret = read_full_resource_into_buf(lte, unix_data);
if (ret)
return ret;
#ifdef __WIN32__
if (wcschr(L"<>:\"/\\|?*", (wchar_t)*p))
#else
- if (*p == '/')
+ if (*p == cpu_to_le16('/'))
#endif
{
- #ifdef __WIN32__
- *p = cpu_to_le16(0xfffd);
- #else
- *p = '?';
- #endif
if (name) {
WARNING("File, directory, or stream name \"%"WS"\"\n"
" contains forbidden characters; "
name);
name = NULL;
}
+ #ifdef __WIN32__
+ *p = cpu_to_le16(0xfffd);
+ #else
+ *p = cpu_to_le16('?');
+ #endif
}
}
}
* The calculated length here is unaligned to allow for the possibility
* that the dentry->length names an unaligned length, although this
* would be unexpected. */
- calculated_size = __dentry_correct_length_unaligned(file_name_nbytes,
+ calculated_size = _dentry_correct_length_unaligned(file_name_nbytes,
short_name_nbytes);
if (dentry->length < calculated_size) {
}
p = put_zeroes(p, (8 - (p - orig_p) % 8) % 8);
}
- wimlib_assert(p - orig_p == __dentry_total_length(dentry, length));
+ wimlib_assert(p - orig_p == _dentry_total_length(dentry, length));
return p;
}