1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-27 22:50:26 +03:00

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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>

Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Fri Feb 10 22:24:59 CET 2017 on sn-devel-144
This commit is contained in:
Ralph Boehme 2017-02-03 14:57:45 +01:00 committed by Jeremy Allison
parent 738797d8ad
commit 32116e015b
5 changed files with 290 additions and 0 deletions

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
<refentry id="mvxattr.1">
<refmeta>
<refentrytitle>mvxattr</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Samba</refmiscinfo>
<refmiscinfo class="manual">User Commands</refmiscinfo>
<refmiscinfo class="version">4.7</refmiscinfo>
</refmeta>
<refnamediv>
<refname>mvxattr</refname>
<refpurpose>Recursively rename extended attributes</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>mvxattr</command>
<arg choice="req">-s STRING, --from=STRING</arg>
<arg choice="req">-d STRING, --to=STRING</arg>
<arg choice="opt">-l, --follow-symlinks</arg>
<arg choice="opt">-p, --print</arg>
<arg choice="opt">-v, --verbose</arg>
<arg choice="opt">-f, --force</arg>
<arg choice="req">PATH [PATH ...]</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>DESCRIPTION</title>
<para>This tool is part of the <citerefentry><refentrytitle>samba</refentrytitle>
<manvolnum>1</manvolnum></citerefentry> suite.</para>
<para>mvxattr is a simple utility to recursively rename extended
attributes.</para>
<para>By default all symlinks are ignored, use <option>-l</option> to
follow them.</para>
</refsect1>
<refsect1>
<title>OPTIONS</title>
<variablelist>
<varlistentry>
<term>-s STRING, --from=STRING</term>
<listitem><para>Source xattr name</para></listitem>
</varlistentry>
<varlistentry>
<term>-d STRING, --to=STRING</term>
<listitem><para>Destination xattr name</para></listitem>
</varlistentry>
<varlistentry>
<term>-l, --follow-symlinks</term>
<listitem><para>Follow symlinks, the default is to ignore
them.</para></listitem>
</varlistentry>
<varlistentry>
<term>-p, --print</term>
<listitem><para>Print files where the xattr got renamed.</para></listitem>
</varlistentry>
<varlistentry>
<term>-v, --verbose</term>
<listitem><para>Print files as they are checked.</para></listitem>
</varlistentry>
<varlistentry>
<term>-f, --force</term>
<listitem><para>Force overwriting of destination xattr.</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>VERSION</title>
<para>This man page is correct for version 4 of the Samba suite.</para>
</refsect1>
<refsect1>
<title>AUTHOR</title>
<para>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.</para>
<para>The mvxattr manpage was written by Ralph Boehme.</para>
</refsect1>
</refentry>

View File

@ -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

178
source3/utils/mvxattr.c Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "system/filesys.h"
#include "popt_common.h"
#include <ftw.h>
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;
}

View File

@ -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)

View File

@ -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)