From 67fa6273cfe4d03358afa1ae12e8022112a9604e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Wed, 3 Oct 2012 11:23:58 +0200 Subject: [PATCH] Disabled getting/setting DOS names on hardlinked files As the path passed to ntfs-3g for getxattr(2)/setxattr(2) are not guaranteed to be the one mentioned by the caller when there are hard links, getting/setting DOS names have to be discontinued in that situation. Getting/setting DOS names is still possible when there is a single non-DOS name. --- libntfs-3g/dir.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/libntfs-3g/dir.c b/libntfs-3g/dir.c index 2ebca235..9068c604 100644 --- a/libntfs-3g/dir.c +++ b/libntfs-3g/dir.c @@ -2277,6 +2277,8 @@ ntfs_inode *ntfs_dir_parent_inode(ntfs_inode *ni) /* * Get a DOS name for a file in designated directory * + * Not allowed if there are several non-dos names (EMLINK) + * * Returns size if found * 0 if not found * -1 if there was an error (described by errno) @@ -2285,6 +2287,7 @@ ntfs_inode *ntfs_dir_parent_inode(ntfs_inode *ni) static int get_dos_name(ntfs_inode *ni, u64 dnum, ntfschar *dosname) { size_t outsize = 0; + int namecount = 0; FILE_NAME_ATTR *fn; ntfs_attr_search_ctx *ctx; @@ -2299,6 +2302,8 @@ static int get_dos_name(ntfs_inode *ni, u64 dnum, ntfschar *dosname) fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + le16_to_cpu(ctx->attr->value_offset)); + if (fn->file_name_type != FILE_NAME_DOS) + namecount++; if ((fn->file_name_type & FILE_NAME_DOS) && (MREF_LE(fn->parent_directory) == dnum)) { /* @@ -2313,6 +2318,10 @@ static int get_dos_name(ntfs_inode *ni, u64 dnum, ntfschar *dosname) } } ntfs_attr_put_search_ctx(ctx); + if ((outsize > 0) && (namecount > 1)) { + outsize = -1; + errno = EMLINK; /* this error implies there is a dos name */ + } return (outsize); } @@ -2320,6 +2329,8 @@ static int get_dos_name(ntfs_inode *ni, u64 dnum, ntfschar *dosname) /* * Get a long name for a file in designated directory * + * Not allowed if there are several non-dos names (EMLINK) + * * Returns size if found * 0 if not found * -1 if there was an error (described by errno) @@ -2328,6 +2339,7 @@ static int get_dos_name(ntfs_inode *ni, u64 dnum, ntfschar *dosname) static int get_long_name(ntfs_inode *ni, u64 dnum, ntfschar *longname) { size_t outsize = 0; + int namecount = 0; FILE_NAME_ATTR *fn; ntfs_attr_search_ctx *ctx; @@ -2343,6 +2355,8 @@ static int get_long_name(ntfs_inode *ni, u64 dnum, ntfschar *longname) fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + le16_to_cpu(ctx->attr->value_offset)); + if (fn->file_name_type != FILE_NAME_DOS) + namecount++; if ((fn->file_name_type & FILE_NAME_WIN32) && (MREF_LE(fn->parent_directory) == dnum)) { /* @@ -2352,6 +2366,10 @@ static int get_long_name(ntfs_inode *ni, u64 dnum, ntfschar *longname) outsize = fn->file_name_length; memcpy(longname,fn->file_name,outsize*sizeof(ntfschar)); } + } + if (namecount > 1) { + errno = EMLINK; + return -1; } /* if not found search for POSIX names */ if (!outsize) { @@ -2673,7 +2691,8 @@ int ntfs_set_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni, res = -1; } else { res = -1; - errno = ENOENT; + if (!longlen) + errno = ENOENT; } free(shortname); if (!closed) { @@ -2749,7 +2768,8 @@ int ntfs_remove_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni) } } } else { - errno = ENOENT; + if (!longlen) + errno = ENOENT; res = -1; } if (!deleted) {