コード例 #1
0
ファイル: ntfs-3g_apply.c プロジェクト: APBaltic/wimlib
/* Recursively creates all the subdirectories of @dir, which has been created as
 * the NTFS inode @dir_ni.  */
static int
ntfs_3g_create_dirs_recursive(ntfs_inode *dir_ni, struct wim_dentry *dir,
			      struct ntfs_3g_apply_ctx *ctx)
{
	struct wim_dentry *child;

	for_dentry_child(child, dir) {
		ntfs_inode *ni;
		int ret;

		if (!(child->d_inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY))
			continue;
		if (!will_extract_dentry(child))
			continue;

		ni = ntfs_create(dir_ni, 0, child->d_extraction_name,
				 child->d_extraction_name_nchars, S_IFDIR);
		if (!ni) {
			ERROR_WITH_ERRNO("Error creating \"%s\" in NTFS volume",
					 dentry_full_path(child));
			return WIMLIB_ERR_NTFS_3G;
		}

		child->d_inode->i_mft_no = ni->mft_no;

		ret = report_file_created(&ctx->common);
		if (!ret)
			ret = ntfs_3g_set_metadata(ni, child->d_inode, ctx);
		if (!ret)
			ret = ntfs_3g_create_any_empty_ads(ni, child->d_inode, ctx);
		if (!ret)
			ret = ntfs_3g_create_dirs_recursive(ni, child, ctx);

		if (ntfs_inode_close_in_dir(ni, dir_ni) && !ret) {
			ERROR_WITH_ERRNO("Error closing \"%s\" in NTFS volume",
					 dentry_full_path(child));
			ret = WIMLIB_ERR_NTFS_3G;
		}
		if (ret)
			return ret;
	}
コード例 #2
0
ファイル: ntfsinternal.c プロジェクト: siz-/ntfs-xenon
ntfs_inode *ntfsCreate (ntfs_vd *vd, const char *path, mode_t type, const char *target)
{
    ntfs_inode *dir_ni = NULL, *ni = NULL;
    char *dir = NULL;
    char *name = NULL;
    ntfschar *uname = NULL, *utarget = NULL;
    int uname_len, utarget_len;

    // Sanity check
    if (!vd) {
        errno = ENODEV;
        return NULL;
    }

    // You cannot link between devices
    if(target) {
        if(vd != ntfsGetVolume(target)) {
            errno = EXDEV;
            return NULL;
        }
    }

    // Get the actual paths of the entry
    path = ntfsRealPath(path);
    target = ntfsRealPath(target);
    if (!path) {
        errno = EINVAL;
        return NULL;
    }

    // Lock
    ntfsLock(vd);

    // Get the unicode name for the entry and find its parent directory
    // TODO: This looks horrible, clean it up
    dir = strdup(path);
    if (!dir) {
        errno = EINVAL;
        goto cleanup;
    }
    name = strrchr(dir, '/');
    if (name)
        name++;
    else
        name = dir;
    uname_len = ntfsLocalToUnicode(name, &uname);
    if (uname_len < 0) {
        errno = EINVAL;
        goto cleanup;
    }
    name = strrchr(dir, '/');
    if(name)
    {
        name++;
        name[0] = 0;
    }

    // Open the entries parent directory
    dir_ni = ntfsOpenEntry(vd, dir);
    if (!dir_ni) {
        goto cleanup;
    }

    // Create the entry
    switch (type) {

        // Symbolic link
        case S_IFLNK:
            if (!target) {
                errno = EINVAL;
                goto cleanup;
            }
            utarget_len = ntfsLocalToUnicode(target, &utarget);
            if (utarget_len < 0) {
                errno = EINVAL;
                goto cleanup;
            }
            ni = ntfs_create_symlink(dir_ni, 0, uname, uname_len,  utarget, utarget_len);
            break;

        // Directory or file
        case S_IFDIR:
        case S_IFREG:
            ni = ntfs_create(dir_ni, 0, uname, uname_len, type);
            break;

    }

    // If the entry was created
    if (ni) {

        // Mark the entry for archiving
        ni->flags |= FILE_ATTR_ARCHIVE;

        // Mark the entry as dirty
        NInoSetDirty(ni);

        // Sync the entry to disc
        ntfsSync(vd, ni);

        // Update parent directories times
        ntfsUpdateTimes(vd, dir_ni, NTFS_UPDATE_MCTIME);

    }

cleanup:

    if(dir_ni)
        ntfsCloseEntry(vd, dir_ni);

    // use free because the value was not allocated with ntfs_alloc
    if(utarget)
        free(utarget);

    if(uname)
        free(uname);

    if(dir)
        ntfs_free(dir);

    // Unlock
    ntfsUnlock(vd);

    return ni;
}