From 8d5906672079765181df1ea6c2eba08e02a58fc9 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Sun, 27 Jul 2014 21:21:18 +0100 Subject: [PATCH] libnfs: Add lchmod Add lchmod which is like chmod but operates on the symbolic link itself if the destination is a symbolic link. Signed-off-by: Ross Lagerwall --- include/nfsc/libnfs.h | 28 ++++++++++++++++++++++++++++ lib/libnfs-sync.c | 16 ++++++++++++++++ lib/libnfs.c | 14 ++++++++++++-- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/include/nfsc/libnfs.h b/include/nfsc/libnfs.h index 27efa46..e39e2e2 100644 --- a/include/nfsc/libnfs.h +++ b/include/nfsc/libnfs.h @@ -1024,6 +1024,34 @@ EXTERN int nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, * -errno : The command failed. */ EXTERN int nfs_chmod(struct nfs_context *nfs, const char *path, int mode); +/* + * Async chmod() + * + * Like chmod except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. + * <0 : An error occured when trying to set up the operation. The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_lchmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); +/* + * Sync chmod() + * + * Like chmod except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The operation was successfull. + * -errno : The command failed. + */ +EXTERN int nfs_lchmod(struct nfs_context *nfs, const char *path, int mode); diff --git a/lib/libnfs-sync.c b/lib/libnfs-sync.c index fe1e063..0fc1094 100644 --- a/lib/libnfs-sync.c +++ b/lib/libnfs-sync.c @@ -1015,6 +1015,22 @@ int nfs_chmod(struct nfs_context *nfs, const char *path, int mode) return cb_data.status; } +int nfs_lchmod(struct nfs_context *nfs, const char *path, int mode) +{ + struct sync_cb_data cb_data; + + cb_data.is_finished = 0; + + if (nfs_lchmod_async(nfs, path, mode, chmod_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_lchmod_async failed"); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + + return cb_data.status; +} + diff --git a/lib/libnfs.c b/lib/libnfs.c index 72d4df4..5692dc3 100644 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -3976,9 +3976,9 @@ static int nfs_chmod_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_ } -int nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) +int nfs_chmod_async_internal(struct nfs_context *nfs, const char *path, int no_follow, int mode, nfs_cb cb, void *private_data) { - if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_chmod_continue_internal, NULL, NULL, mode) != 0) { + if (nfs_lookuppath_async(nfs, path, no_follow, cb, private_data, nfs_chmod_continue_internal, NULL, NULL, mode) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } @@ -3986,6 +3986,16 @@ int nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb return 0; } +int nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) +{ + return nfs_chown_async_internal(nfs, path, 0, mode, cb, private_data); +} + +int nfs_lchmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) +{ + return nfs_chown_async_internal(nfs, path, 1, mode, cb, private_data); +} + /* * Async fchmod() */ -- 2.34.1