mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-11-23 18:14:24 +08:00
Enabled actions on directories in reparse plugins
The plugins triggered by reparse points can now act on a directory through link(2) unlink(2) and creat(2).
This commit is contained in:
parent
4b8a660006
commit
02673bd04a
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* plugin.h : define interface for plugin development
|
* plugin.h : define interface for plugin development
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015 Jean-Pierre Andre
|
* Copyright (c) 2015-2021 Jean-Pierre Andre
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -151,6 +151,34 @@ typedef struct plugin_operations {
|
|||||||
int (*readdir)(ntfs_inode *ni, const REPARSE_POINT *reparse,
|
int (*readdir)(ntfs_inode *ni, const REPARSE_POINT *reparse,
|
||||||
s64 *pos, void *fillctx, ntfs_filldir_t filldir,
|
s64 *pos, void *fillctx, ntfs_filldir_t filldir,
|
||||||
struct fuse_file_info *fi);
|
struct fuse_file_info *fi);
|
||||||
|
/*
|
||||||
|
* Create a new file of any type
|
||||||
|
*
|
||||||
|
* The returned value is a pointer to the inode created, or
|
||||||
|
* NULL if failed, with errno telling why.
|
||||||
|
*/
|
||||||
|
ntfs_inode *(*create)(ntfs_inode *dir_ni, const REPARSE_POINT *reparse,
|
||||||
|
le32 securid, ntfschar *name, int name_len,
|
||||||
|
mode_t type);
|
||||||
|
/*
|
||||||
|
* Link a new name to a file or directory
|
||||||
|
* Linking a directory is needed for renaming a directory
|
||||||
|
* The returned value is zero for success or a negative errno
|
||||||
|
* value for failure.
|
||||||
|
* If the returned value is zero, the modified time stamp
|
||||||
|
* will be updated after the call.
|
||||||
|
*/
|
||||||
|
int (*link)(ntfs_inode *dir_ni, const REPARSE_POINT *reparse,
|
||||||
|
ntfs_inode *ni, ntfschar *name, int name_len);
|
||||||
|
/*
|
||||||
|
* Unlink a name from a directory
|
||||||
|
* The argument pathname may be NULL
|
||||||
|
* The returned value is zero for success or a negative errno
|
||||||
|
* value for failure.
|
||||||
|
*/
|
||||||
|
int (*unlink)(ntfs_inode *dir_ni, const REPARSE_POINT *reparse,
|
||||||
|
const char *pathname,
|
||||||
|
ntfs_inode *ni, ntfschar *name, int name_len);
|
||||||
} plugin_operations_t;
|
} plugin_operations_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1509,11 +1509,6 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
|
||||||
errno = EOPNOTSUPP;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ni = ntfs_mft_record_alloc(dir_ni->vol, NULL);
|
ni = ntfs_mft_record_alloc(dir_ni->vol, NULL);
|
||||||
if (!ni)
|
if (!ni)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
106
src/lowntfs-3g.c
106
src/lowntfs-3g.c
@ -4,7 +4,7 @@
|
|||||||
* Copyright (c) 2005-2007 Yura Pakhuchiy
|
* Copyright (c) 2005-2007 Yura Pakhuchiy
|
||||||
* Copyright (c) 2005 Yuval Fledel
|
* Copyright (c) 2005 Yuval Fledel
|
||||||
* Copyright (c) 2006-2009 Szabolcs Szakacsits
|
* Copyright (c) 2006-2009 Szabolcs Szakacsits
|
||||||
* Copyright (c) 2007-2020 Jean-Pierre Andre
|
* Copyright (c) 2007-2021 Jean-Pierre Andre
|
||||||
* Copyright (c) 2009 Erik Larsson
|
* Copyright (c) 2009 Erik Larsson
|
||||||
*
|
*
|
||||||
* This file is originated from the Linux-NTFS project.
|
* This file is originated from the Linux-NTFS project.
|
||||||
@ -261,7 +261,7 @@ static const char *usage_msg =
|
|||||||
"\n"
|
"\n"
|
||||||
"Copyright (C) 2005-2007 Yura Pakhuchiy\n"
|
"Copyright (C) 2005-2007 Yura Pakhuchiy\n"
|
||||||
"Copyright (C) 2006-2009 Szabolcs Szakacsits\n"
|
"Copyright (C) 2006-2009 Szabolcs Szakacsits\n"
|
||||||
"Copyright (C) 2007-2020 Jean-Pierre Andre\n"
|
"Copyright (C) 2007-2021 Jean-Pierre Andre\n"
|
||||||
"Copyright (C) 2009 Erik Larsson\n"
|
"Copyright (C) 2009 Erik Larsson\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage: %s [-o option[,...]] <device|image_file> <mount_point>\n"
|
"Usage: %s [-o option[,...]] <device|image_file> <mount_point>\n"
|
||||||
@ -2336,26 +2336,50 @@ static int ntfs_fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name,
|
|||||||
perm & ~security.umask, S_ISDIR(type));
|
perm & ~security.umask, S_ISDIR(type));
|
||||||
#endif
|
#endif
|
||||||
/* Create object specified in @type. */
|
/* Create object specified in @type. */
|
||||||
switch (type) {
|
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||||
case S_IFCHR:
|
#ifndef DISABLE_PLUGINS
|
||||||
case S_IFBLK:
|
const plugin_operations_t *ops;
|
||||||
ni = ntfs_create_device(dir_ni, securid,
|
REPARSE_POINT *reparse;
|
||||||
uname, uname_len, type, dev);
|
|
||||||
break;
|
reparse = (REPARSE_POINT*)NULL;
|
||||||
case S_IFLNK:
|
ops = select_reparse_plugin(ctx, dir_ni, &reparse);
|
||||||
utarget_len = ntfs_mbstoucs(target, &utarget);
|
if (ops && ops->create) {
|
||||||
if (utarget_len < 0) {
|
ni = (*ops->create)(dir_ni, reparse,
|
||||||
res = -errno;
|
securid, uname, uname_len, type);
|
||||||
goto exit;
|
} else {
|
||||||
}
|
ni = (ntfs_inode*)NULL;
|
||||||
ni = ntfs_create_symlink(dir_ni, securid,
|
errno = EOPNOTSUPP;
|
||||||
uname, uname_len,
|
}
|
||||||
utarget, utarget_len);
|
free(reparse);
|
||||||
break;
|
#else /* DISABLE_PLUGINS */
|
||||||
default:
|
ni = (ntfs_inode*)NULL;
|
||||||
ni = ntfs_create(dir_ni, securid, uname,
|
errno = EOPNOTSUPP;
|
||||||
uname_len, type);
|
#endif /* DISABLE_PLUGINS */
|
||||||
break;
|
} else {
|
||||||
|
switch (type) {
|
||||||
|
case S_IFCHR:
|
||||||
|
case S_IFBLK:
|
||||||
|
ni = ntfs_create_device(dir_ni, securid,
|
||||||
|
uname, uname_len,
|
||||||
|
type, dev);
|
||||||
|
break;
|
||||||
|
case S_IFLNK:
|
||||||
|
utarget_len = ntfs_mbstoucs(target,
|
||||||
|
&utarget);
|
||||||
|
if (utarget_len < 0) {
|
||||||
|
res = -errno;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
ni = ntfs_create_symlink(dir_ni,
|
||||||
|
securid,
|
||||||
|
uname, uname_len,
|
||||||
|
utarget, utarget_len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ni = ntfs_create(dir_ni, securid, uname,
|
||||||
|
uname_len, type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ni) {
|
if (ni) {
|
||||||
/*
|
/*
|
||||||
@ -2525,10 +2549,25 @@ static int ntfs_fuse_newlink(fuse_req_t req __attribute__((unused)),
|
|||||||
#else
|
#else
|
||||||
ntfs_fuse_fill_security_context(req, &security);
|
ntfs_fuse_fill_security_context(req, &security);
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (ntfs_link(ni, dir_ni, uname, uname_len)) {
|
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||||
res = -errno;
|
#ifndef DISABLE_PLUGINS
|
||||||
|
const plugin_operations_t *ops;
|
||||||
|
REPARSE_POINT *reparse;
|
||||||
|
|
||||||
|
res = CALL_REPARSE_PLUGIN(dir_ni, link,
|
||||||
|
ni, uname, uname_len);
|
||||||
|
if (res < 0)
|
||||||
|
goto exit;
|
||||||
|
#else /* DISABLE_PLUGINS */
|
||||||
|
res = -EOPNOTSUPP;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
#endif /* DISABLE_PLUGINS */
|
||||||
|
} else {
|
||||||
|
if (ntfs_link(ni, dir_ni, uname, uname_len)) {
|
||||||
|
res = -errno;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ntfs_inode_update_mbsname(dir_ni, newname, ni->mft_no);
|
ntfs_inode_update_mbsname(dir_ni, newname, ni->mft_no);
|
||||||
if (e) {
|
if (e) {
|
||||||
@ -2712,9 +2751,20 @@ static int ntfs_fuse_rm(fuse_req_t req, fuse_ino_t parent, const char *name,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ntfs_delete(ctx->vol, (char*)NULL, ni, dir_ni,
|
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||||
uname, uname_len))
|
#ifndef DISABLE_PLUGINS
|
||||||
res = -errno;
|
const plugin_operations_t *ops;
|
||||||
|
REPARSE_POINT *reparse;
|
||||||
|
|
||||||
|
res = CALL_REPARSE_PLUGIN(dir_ni, unlink, (char*)NULL,
|
||||||
|
ni, uname, uname_len);
|
||||||
|
#else /* DISABLE_PLUGINS */
|
||||||
|
res = -EOPNOTSUPP;
|
||||||
|
#endif /* DISABLE_PLUGINS */
|
||||||
|
} else
|
||||||
|
if (ntfs_delete(ctx->vol, (char*)NULL, ni, dir_ni,
|
||||||
|
uname, uname_len))
|
||||||
|
res = -errno;
|
||||||
/* ntfs_delete() always closes ni and dir_ni */
|
/* ntfs_delete() always closes ni and dir_ni */
|
||||||
ni = dir_ni = NULL;
|
ni = dir_ni = NULL;
|
||||||
exit:
|
exit:
|
||||||
|
100
src/ntfs-3g.c
100
src/ntfs-3g.c
@ -4,7 +4,7 @@
|
|||||||
* Copyright (c) 2005-2007 Yura Pakhuchiy
|
* Copyright (c) 2005-2007 Yura Pakhuchiy
|
||||||
* Copyright (c) 2005 Yuval Fledel
|
* Copyright (c) 2005 Yuval Fledel
|
||||||
* Copyright (c) 2006-2009 Szabolcs Szakacsits
|
* Copyright (c) 2006-2009 Szabolcs Szakacsits
|
||||||
* Copyright (c) 2007-2020 Jean-Pierre Andre
|
* Copyright (c) 2007-2021 Jean-Pierre Andre
|
||||||
* Copyright (c) 2009 Erik Larsson
|
* Copyright (c) 2009 Erik Larsson
|
||||||
*
|
*
|
||||||
* This file is originated from the Linux-NTFS project.
|
* This file is originated from the Linux-NTFS project.
|
||||||
@ -196,7 +196,7 @@ static const char *usage_msg =
|
|||||||
"\n"
|
"\n"
|
||||||
"Copyright (C) 2005-2007 Yura Pakhuchiy\n"
|
"Copyright (C) 2005-2007 Yura Pakhuchiy\n"
|
||||||
"Copyright (C) 2006-2009 Szabolcs Szakacsits\n"
|
"Copyright (C) 2006-2009 Szabolcs Szakacsits\n"
|
||||||
"Copyright (C) 2007-2020 Jean-Pierre Andre\n"
|
"Copyright (C) 2007-2021 Jean-Pierre Andre\n"
|
||||||
"Copyright (C) 2009 Erik Larsson\n"
|
"Copyright (C) 2009 Erik Larsson\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage: %s [-o option[,...]] <device|image_file> <mount_point>\n"
|
"Usage: %s [-o option[,...]] <device|image_file> <mount_point>\n"
|
||||||
@ -2067,26 +2067,47 @@ static int ntfs_fuse_create(const char *org_path, mode_t typemode, dev_t dev,
|
|||||||
perm & ~security.umask, S_ISDIR(type));
|
perm & ~security.umask, S_ISDIR(type));
|
||||||
#endif
|
#endif
|
||||||
/* Create object specified in @type. */
|
/* Create object specified in @type. */
|
||||||
switch (type) {
|
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||||
case S_IFCHR:
|
#ifndef DISABLE_PLUGINS
|
||||||
case S_IFBLK:
|
const plugin_operations_t *ops;
|
||||||
ni = ntfs_create_device(dir_ni, securid,
|
REPARSE_POINT *reparse;
|
||||||
|
|
||||||
|
reparse = (REPARSE_POINT*)NULL;
|
||||||
|
ops = select_reparse_plugin(ctx, dir_ni, &reparse);
|
||||||
|
if (ops && ops->create) {
|
||||||
|
ni = (*ops->create)(dir_ni, reparse,
|
||||||
|
securid, uname, uname_len, type);
|
||||||
|
} else {
|
||||||
|
ni = (ntfs_inode*)NULL;
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
free(reparse);
|
||||||
|
#else /* DISABLE_PLUGINS */
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
#endif /* DISABLE_PLUGINS */
|
||||||
|
} else {
|
||||||
|
switch (type) {
|
||||||
|
case S_IFCHR:
|
||||||
|
case S_IFBLK:
|
||||||
|
ni = ntfs_create_device(dir_ni, securid,
|
||||||
uname, uname_len, type, dev);
|
uname, uname_len, type, dev);
|
||||||
break;
|
break;
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
utarget_len = ntfs_mbstoucs(target, &utarget);
|
utarget_len = ntfs_mbstoucs(target,
|
||||||
if (utarget_len < 0) {
|
&utarget);
|
||||||
res = -errno;
|
if (utarget_len < 0) {
|
||||||
goto exit;
|
res = -errno;
|
||||||
}
|
goto exit;
|
||||||
ni = ntfs_create_symlink(dir_ni, securid,
|
}
|
||||||
uname, uname_len,
|
ni = ntfs_create_symlink(dir_ni,
|
||||||
|
securid, uname, uname_len,
|
||||||
utarget, utarget_len);
|
utarget, utarget_len);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ni = ntfs_create(dir_ni, securid, uname,
|
ni = ntfs_create(dir_ni, securid,
|
||||||
uname_len, type);
|
uname, uname_len, type);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ni) {
|
if (ni) {
|
||||||
/*
|
/*
|
||||||
@ -2309,10 +2330,24 @@ static int ntfs_fuse_link(const char *old_path, const char *new_path)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (ntfs_link(ni, dir_ni, uname, uname_len)) {
|
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||||
res = -errno;
|
#ifndef DISABLE_PLUGINS
|
||||||
goto exit;
|
const plugin_operations_t *ops;
|
||||||
}
|
REPARSE_POINT *reparse;
|
||||||
|
|
||||||
|
res = CALL_REPARSE_PLUGIN(dir_ni, link,
|
||||||
|
ni, uname, uname_len);
|
||||||
|
#else /* DISABLE_PLUGINS */
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
res = -errno;
|
||||||
|
#endif /* DISABLE_PLUGINS */
|
||||||
|
if (res)
|
||||||
|
goto exit;
|
||||||
|
} else
|
||||||
|
if (ntfs_link(ni, dir_ni, uname, uname_len)) {
|
||||||
|
res = -errno;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
set_archive(ni);
|
set_archive(ni);
|
||||||
ntfs_fuse_update_times(ni, NTFS_UPDATE_CTIME);
|
ntfs_fuse_update_times(ni, NTFS_UPDATE_CTIME);
|
||||||
@ -2384,9 +2419,20 @@ static int ntfs_fuse_rm(const char *org_path)
|
|||||||
|| ntfs_allowed_dir_access(&security, org_path, dir_ni, ni,
|
|| ntfs_allowed_dir_access(&security, org_path, dir_ni, ni,
|
||||||
S_IEXEC + S_IWRITE + S_ISVTX)) {
|
S_IEXEC + S_IWRITE + S_ISVTX)) {
|
||||||
#endif
|
#endif
|
||||||
if (ntfs_delete(ctx->vol, org_path, ni, dir_ni,
|
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||||
uname, uname_len))
|
#ifndef DISABLE_PLUGINS
|
||||||
res = -errno;
|
const plugin_operations_t *ops;
|
||||||
|
REPARSE_POINT *reparse;
|
||||||
|
|
||||||
|
res = CALL_REPARSE_PLUGIN(dir_ni, unlink,
|
||||||
|
org_path, ni, uname, uname_len);
|
||||||
|
#else /* DISABLE_PLUGINS */
|
||||||
|
res = -EOPNOTSUPP;
|
||||||
|
#endif /* DISABLE_PLUGINS */
|
||||||
|
} else
|
||||||
|
if (ntfs_delete(ctx->vol, org_path, ni, dir_ni,
|
||||||
|
uname, uname_len))
|
||||||
|
res = -errno;
|
||||||
/* ntfs_delete() always closes ni and dir_ni */
|
/* ntfs_delete() always closes ni and dir_ni */
|
||||||
ni = dir_ni = NULL;
|
ni = dir_ni = NULL;
|
||||||
#if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
|
#if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
|
||||||
|
Loading…
Reference in New Issue
Block a user