-static int wimfs_rename(const char *from, const char *to)
-{
- struct dentry *src;
- struct dentry *dst;
- struct dentry *parent_of_dst;
- char *file_name_utf16 = NULL, *file_name_utf8 = NULL;
- u16 file_name_utf16_len, file_name_utf8_len;
- WIMStruct *w = wimfs_get_WIMStruct();
- int ret;
-
- /* This rename() implementation currently only supports actual files
- * (not alternate data streams) */
-
- src = get_dentry(w, from);
- if (!src)
- return -ENOENT;
-
- dst = get_dentry(w, to);
-
-
- ret = get_names(&file_name_utf16, &file_name_utf8,
- &file_name_utf16_len, &file_name_utf8_len,
- path_basename(to));
- if (ret != 0)
- return -ENOMEM;
-
- if (dst) {
- /* Destination file exists */
-
- if (src == dst) /* Same file */
- return 0;
-
- if (!dentry_is_directory(src)) {
- /* Cannot rename non-directory to directory. */
- if (dentry_is_directory(dst))
- return -EISDIR;
- } else {
- /* Cannot rename directory to a non-directory or a non-empty
- * directory */
- if (!dentry_is_directory(dst))
- return -ENOTDIR;
- if (inode_has_children(dst->d_inode))
- return -ENOTEMPTY;
- }
- parent_of_dst = dst->parent;
- remove_dentry(dst, w->lookup_table);
- } else {
- /* Destination does not exist */
- parent_of_dst = get_parent_dentry(w, to);
- if (!parent_of_dst)
- return -ENOENT;
-
- if (!dentry_is_directory(parent_of_dst))
- return -ENOTDIR;
- }
-
- FREE(src->file_name);
- FREE(src->file_name_utf8);
- src->file_name = file_name_utf16;
- src->file_name_utf8 = file_name_utf8;
- src->file_name_len = file_name_utf16_len;
- src->file_name_utf8_len = file_name_utf8_len;
-
- unlink_dentry(src);
- dentry_add_child(parent_of_dst, src);
- return 0;