mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-11-23 10:04:00 +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
|
||||
*
|
||||
* 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,
|
||||
s64 *pos, void *fillctx, ntfs_filldir_t filldir,
|
||||
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;
|
||||
|
||||
|
||||
|
@ -1509,11 +1509,6 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||
errno = EOPNOTSUPP;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ni = ntfs_mft_record_alloc(dir_ni->vol, NULL);
|
||||
if (!ni)
|
||||
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 Yuval Fledel
|
||||
* 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
|
||||
*
|
||||
* This file is originated from the Linux-NTFS project.
|
||||
@ -261,7 +261,7 @@ static const char *usage_msg =
|
||||
"\n"
|
||||
"Copyright (C) 2005-2007 Yura Pakhuchiy\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"
|
||||
"\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));
|
||||
#endif
|
||||
/* Create object specified in @type. */
|
||||
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 (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||
#ifndef DISABLE_PLUGINS
|
||||
const plugin_operations_t *ops;
|
||||
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 */
|
||||
ni = (ntfs_inode*)NULL;
|
||||
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);
|
||||
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) {
|
||||
/*
|
||||
@ -2525,10 +2549,25 @@ static int ntfs_fuse_newlink(fuse_req_t req __attribute__((unused)),
|
||||
#else
|
||||
ntfs_fuse_fill_security_context(req, &security);
|
||||
#endif
|
||||
{
|
||||
if (ntfs_link(ni, dir_ni, uname, uname_len)) {
|
||||
res = -errno;
|
||||
{
|
||||
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||
#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;
|
||||
#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);
|
||||
if (e) {
|
||||
@ -2712,9 +2751,20 @@ static int ntfs_fuse_rm(fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
if (ntfs_delete(ctx->vol, (char*)NULL, ni, dir_ni,
|
||||
uname, uname_len))
|
||||
res = -errno;
|
||||
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||
#ifndef DISABLE_PLUGINS
|
||||
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 */
|
||||
ni = dir_ni = NULL;
|
||||
exit:
|
||||
|
100
src/ntfs-3g.c
100
src/ntfs-3g.c
@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2005-2007 Yura Pakhuchiy
|
||||
* Copyright (c) 2005 Yuval Fledel
|
||||
* 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
|
||||
*
|
||||
* This file is originated from the Linux-NTFS project.
|
||||
@ -196,7 +196,7 @@ static const char *usage_msg =
|
||||
"\n"
|
||||
"Copyright (C) 2005-2007 Yura Pakhuchiy\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"
|
||||
"\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));
|
||||
#endif
|
||||
/* Create object specified in @type. */
|
||||
switch (type) {
|
||||
case S_IFCHR:
|
||||
case S_IFBLK:
|
||||
ni = ntfs_create_device(dir_ni, securid,
|
||||
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||
#ifndef DISABLE_PLUGINS
|
||||
const plugin_operations_t *ops;
|
||||
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);
|
||||
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,
|
||||
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;
|
||||
break;
|
||||
default:
|
||||
ni = ntfs_create(dir_ni, securid,
|
||||
uname, uname_len, type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ni) {
|
||||
/*
|
||||
@ -2309,10 +2330,24 @@ static int ntfs_fuse_link(const char *old_path, const char *new_path)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (ntfs_link(ni, dir_ni, uname, uname_len)) {
|
||||
res = -errno;
|
||||
goto exit;
|
||||
}
|
||||
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||
#ifndef DISABLE_PLUGINS
|
||||
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);
|
||||
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,
|
||||
S_IEXEC + S_IWRITE + S_ISVTX)) {
|
||||
#endif
|
||||
if (ntfs_delete(ctx->vol, org_path, ni, dir_ni,
|
||||
uname, uname_len))
|
||||
res = -errno;
|
||||
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
|
||||
#ifndef DISABLE_PLUGINS
|
||||
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 */
|
||||
ni = dir_ni = NULL;
|
||||
#if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
|
||||
|
Loading…
Reference in New Issue
Block a user