From: Ralph Boehme Date: Fri, 3 Feb 2017 13:57:45 +0000 (+0100) Subject: s3/util: mvxattr, a tool to rename extended attributes X-Git-Tag: talloc-2.1.9~208 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=32116e015b14cfa697569fce01daf8cde3285970;p=thirdparty%2Fsamba.git s3/util: mvxattr, a tool to rename extended attributes Usage: mvxattr -s STRING -d STRING PATH [PATH ...] -s, --from=STRING xattr source name -d, --to=STRING xattr destination name -l, --follow-symlinks follow symlinks, the default is to ignore them -p, --print print files where the xattr got renamed -v, --verbose print files as they are checked -f, --force force overwriting of destination xattr Help options: -?, --help Show this help message --usage Display brief usage message Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Fri Feb 10 22:24:59 CET 2017 on sn-devel-144 --- diff --git a/docs-xml/manpages/mvxattr.1.xml b/docs-xml/manpages/mvxattr.1.xml new file mode 100644 index 00000000000..034dc3adc70 --- /dev/null +++ b/docs-xml/manpages/mvxattr.1.xml @@ -0,0 +1,100 @@ + + + + + + mvxattr + 1 + Samba + User Commands + 4.7 + + + + + mvxattr + Recursively rename extended attributes + + + + + mvxattr + -s STRING, --from=STRING + -d STRING, --to=STRING + -l, --follow-symlinks + -p, --print + -v, --verbose + -f, --force + PATH [PATH ...] + + + + + DESCRIPTION + + This tool is part of the samba + 1 suite. + + mvxattr is a simple utility to recursively rename extended + attributes. + + By default all symlinks are ignored, use to + follow them. + + + + OPTIONS + + + + -s STRING, --from=STRING + Source xattr name + + + + -d STRING, --to=STRING + Destination xattr name + + + + -l, --follow-symlinks + Follow symlinks, the default is to ignore + them. + + + + -p, --print + Print files where the xattr got renamed. + + + + -v, --verbose + Print files as they are checked. + + + + -f, --force + Force overwriting of destination xattr. + + + + + + + VERSION + + This man page is correct for version 4 of the Samba suite. + + + + AUTHOR + + The original Samba software and related utilities were created by + Andrew Tridgell. Samba is now developed by the Samba Team as an Open + Source project similar to the way the Linux kernel is developed. + + The mvxattr manpage was written by Ralph Boehme. + + + + diff --git a/docs-xml/wscript_build b/docs-xml/wscript_build index 2b3a18003f8..0b690a878ff 100644 --- a/docs-xml/wscript_build +++ b/docs-xml/wscript_build @@ -18,6 +18,7 @@ manpages=''' manpages/idmap_script.8 manpages/idmap_tdb.8 manpages/idmap_tdb2.8 + manpages/mvxattr.1 manpages/net.8 manpages/nmbd.8 manpages/nmblookup.1 diff --git a/source3/utils/mvxattr.c b/source3/utils/mvxattr.c new file mode 100644 index 00000000000..9cc2ec0d781 --- /dev/null +++ b/source3/utils/mvxattr.c @@ -0,0 +1,178 @@ +/* + Unix SMB/CIFS implementation. + xattr renaming + Copyright (C) Ralph Boehme 2017 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "popt_common.h" +#include + +static struct rename_xattr_state { + int follow_symlink; + int print; + int force; + int verbose; + char *xattr_from; + char *xattr_to; +} state; + +static int rename_xattr(const char *path, + const struct stat *sb, + int typeflag, + struct FTW *ftwbuf) +{ + ssize_t len; + int ret; + + if (typeflag == FTW_SL) { + d_printf("Ignoring symlink %s\n", path); + return 0; + } + + if (state.verbose) { + d_printf("%s\n", path); + } + + len = getxattr(path, state.xattr_from, NULL, 0); + if (len < 0) { + if (errno == ENOATTR) { + return 0; + } + d_printf("getxattr [%s] failed [%s]\n", + path, strerror(errno)); + return -1; + } + + { + uint8_t buf[len]; + + len = getxattr(path, state.xattr_from, &buf[0], len); + if (len == -1) { + d_printf("getxattr [%s] failed [%s]\n", + path, strerror(errno)); + return -1; + } + + ret = setxattr(path, state.xattr_to, &buf[0], len, XATTR_CREATE); + if (ret != 0) { + if (errno != EEXIST) { + d_printf("setxattr [%s] failed [%s]\n", + path, strerror(errno)); + return -1; + } + if (!state.force) { + d_printf("destination [%s:%s] exists, use -f to force\n", + path, state.xattr_to); + return -1; + } + ret = setxattr(path, state.xattr_to, &buf[0], len, XATTR_REPLACE); + if (ret != 0) { + d_printf("setxattr [%s:%s] failed [%s]\n", + path, state.xattr_to, strerror(errno)); + return -1; + } + } + + ret = removexattr(path, state.xattr_from); + if (ret != 0) { + d_printf("removexattr [%s:%s] failed [%s]\n", + path, state.xattr_from, strerror(errno)); + return -1; + } + + if (state.print) { + d_printf("Renamed %s to %s on %s\n", + state.xattr_from, state.xattr_to, path); + } + } + + return 0; +} + +int main(int argc, const char *argv[]) +{ + int c; + const char *path = NULL; + poptContext pc; + struct poptOption long_options[] = { + POPT_AUTOHELP + {"from", 's', POPT_ARG_STRING, &state.xattr_from, 's', "xattr source name" }, + {"to", 'd', POPT_ARG_STRING, &state.xattr_to, 'd', "xattr destination name" }, + {"follow-symlinks", 'l', POPT_ARG_NONE, &state.follow_symlink, 'l', "follow symlinks, the default is to ignore them" }, + {"print", 'p', POPT_ARG_NONE, &state.print, 'p', "print files where the xattr got renamed" }, + {"verbose", 'v', POPT_ARG_NONE, &state.verbose, 'v', "print files as they are checked" }, + {"force", 'f', POPT_ARG_NONE, &state.force, 'f', "force overwriting of destination xattr" }, + POPT_TABLEEND + }; + TALLOC_CTX *frame = talloc_stackframe(); + const char *s = NULL; + int ret = 0; + + if (getuid() != 0) { + d_printf("%s only works as root!\n", argv[0]); + ret = 1; + goto done; + } + + pc = poptGetContext(NULL, argc, argv, long_options, 0); + poptSetOtherOptionHelp(pc, "-s STRING -d STRING PATH [PATH ...]"); + + while ((c = poptGetNextOpt(pc)) != -1) { + switch (c) { + case 's': + s = poptGetOptArg(pc); + state.xattr_from = talloc_strdup(frame, s); + if (state.xattr_from == NULL) { + ret = 1; + goto done; + } + break; + case 'd': + s = poptGetOptArg(pc); + state.xattr_to = talloc_strdup(frame, s); + if (state.xattr_to == NULL) { + ret = 1; + goto done; + } + break; + } + } + + if (state.xattr_from == NULL || state.xattr_to == NULL) { + poptPrintUsage(pc, stderr, 0); + ret = 1; + goto done; + } + + if (poptPeekArg(pc) == NULL) { + poptPrintUsage(pc, stderr, 0); + ret = 1; + goto done; + } + + while ((path = poptGetArg(pc)) != NULL) { + ret = nftw(path, rename_xattr, 256, + state.follow_symlink ? 0 : FTW_PHYS); + } + + poptFreeContext(pc); + +done: + TALLOC_FREE(frame); + return ret; +} diff --git a/source3/utils/wscript_build b/source3/utils/wscript_build index 0b9356a7980..4295f859249 100644 --- a/source3/utils/wscript_build +++ b/source3/utils/wscript_build @@ -249,3 +249,11 @@ bld.SAMBA3_BINARY('net', trusts_util IDMAP_AUTORID_TDB ''') + +bld.SAMBA3_BINARY('mvxattr', + source='mvxattr.c', + deps=''' + talloc + popt_samba3 + ''', + enabled=bld.env.build_mvxattr) diff --git a/source3/wscript b/source3/wscript index 821d4ed114f..b886e1b69e4 100644 --- a/source3/wscript +++ b/source3/wscript @@ -1625,6 +1625,9 @@ main() { else: Logs.info("ncurses not available, not building regedit") + if conf.CHECK_HEADERS('ftw.h') and conf.CHECK_FUNCS('nftw'): + conf.env.build_mvxattr = True + conf.CHECK_FUNCS_IN('DES_pcbc_encrypt', 'crypto') if Options.options.with_fake_kaserver == True: conf.CHECK_HEADERS('afs/param.h afs/stds.h', together=True)