[RFC] vfs_fruit uses wrong xattr name for Mac metadata on FreeBSD
Jeremy Allison
jra at samba.org
Fri Feb 10 00:53:42 UTC 2017
On Sat, Feb 04, 2017 at 10:17:17AM +0100, Ralph Böhme wrote:
> On Sun, Jan 22, 2017 at 05:08:08PM +0100, Ralph Böhme wrote:
> > On Sun, Jan 22, 2017 at 06:48:03AM +0800, Evan Champion wrote:
> > > Another way would be to change the default xattr name in 4.6.0 and provide a
> > > conversion tool.
> >
> > hm...
>
> and here's the patchset that does this.
>
> 1. It renames the Netatalk metadata xattr name.
>
> 2. Adds a tool mvxattr to rename xattrs. The name seems not to be in use, so
> hopefully it doesn't clash with anything. It uses nftw under the hood for the
> directory traversal, it's in POSIX.1-2001, available on FreeBSD (which this is
> all about, Linux has it as well) and I'd like to avoid reinventing the wheel.
>
> 3. Fixes our libreplace xattr implementation on FreeBSD to validata xattr
> names. This is a prerequisite for 2, otherwise users might call the mvxattr tool
> with xattr name like "org.netatalk.Metadata" without a namespace prefix leading
> to unexpected results: the xattr name on the fs would be "netatalk.Metadata" as
> the "org" part gets stripped.
>
> Once this is in master, I'll prepare a backport for 4.6 with an update for
> WHATSNEW.
>
> Please review & push if happy. Thanks!
That's a really nice patchset Ralph, I really like the mvxattr
utility !
RB+
Pushed.
> From e661ceb3f27582b0c699584f116d51787db3e2b2 Mon Sep 17 00:00:00 2001
> From: Ralph Boehme <slow at samba.org>
> Date: Fri, 3 Feb 2017 16:33:00 +0100
> Subject: [PATCH 1/4] vfs_fruit: correct Netatalk metadata xattr on FreeBSD
>
> Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
>
> Signed-off-by: Ralph Boehme <slow at samba.org>
> ---
> source3/modules/vfs_fruit.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
> index 3599dcb..828d6d1 100644
> --- a/source3/modules/vfs_fruit.c
> +++ b/source3/modules/vfs_fruit.c
> @@ -105,7 +105,7 @@ static int vfs_fruit_debug_level = DBGC_VFS;
> * This is hokey, but what else can we do?
> */
> #define NETATALK_META_XATTR "org.netatalk.Metadata"
> -#if defined(HAVE_ATTROPEN) || defined(FREEBSD)
> +#if defined(HAVE_ATTROPEN)
> #define AFPINFO_EA_NETATALK NETATALK_META_XATTR
> #define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork"
> #else
> --
> 2.9.3
>
>
> From 1fe44e3f5b2bdff92e4c7267e07b69733fbf4758 Mon Sep 17 00:00:00 2001
> From: Ralph Boehme <slow at samba.org>
> Date: Fri, 3 Feb 2017 16:43:26 +0100
> Subject: [PATCH 2/4] vfs_fruit: cleanup metadata and resource xattr name
> defines
>
> Just some cleanup, no change in behaviour. This also removes the hokey
> tag. :)
>
> Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
>
> Signed-off-by: Ralph Boehme <slow at samba.org>
> ---
> source3/modules/vfs_fruit.c | 10 ++++------
> 1 file changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
> index 828d6d1..4387447 100644
> --- a/source3/modules/vfs_fruit.c
> +++ b/source3/modules/vfs_fruit.c
> @@ -100,17 +100,15 @@ static int vfs_fruit_debug_level = DBGC_VFS;
> #define FRUIT_PARAM_TYPE_NAME "fruit"
> #define ADOUBLE_NAME_PREFIX "._"
>
> -/*
> - * REVIEW:
> - * This is hokey, but what else can we do?
> - */
> #define NETATALK_META_XATTR "org.netatalk.Metadata"
> +#define NETATALK_RSRC_XATTR "org.netatalk.Metadata"
> +
> #if defined(HAVE_ATTROPEN)
> #define AFPINFO_EA_NETATALK NETATALK_META_XATTR
> -#define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork"
> +#define AFPRESOURCE_EA_NETATALK NETATALK_RSRC_XATTR
> #else
> #define AFPINFO_EA_NETATALK "user." NETATALK_META_XATTR
> -#define AFPRESOURCE_EA_NETATALK "user.org.netatalk.ResourceFork"
> +#define AFPRESOURCE_EA_NETATALK "user." NETATALK_RSRC_XATTR
> #endif
>
> enum apple_fork {APPLE_FORK_DATA, APPLE_FORK_RSRC};
> --
> 2.9.3
>
>
> From 03d73c0da1955aa703c11e79ff23fd97246d3e79 Mon Sep 17 00:00:00 2001
> From: Ralph Boehme <slow at samba.org>
> Date: Fri, 3 Feb 2017 18:08:12 +0100
> Subject: [PATCH 3/4] lib/replace: validate xattr namespace prefix on FreeBSD
>
> We should validate the xattr name string ensuring it either begins with
> "sytem." or "user.". If it doesn't, we should fail the request with
> EINVAL.
>
> The FreeBSD xattr API uses namespaces but doesn't put the namespace name
> as a string prefix at the beginning of the xattr name. It gets passed as
> an additional int arg instead.
>
> On the other hand, our libreplace xattr API expects the caller to put a
> namespace prefix into the xattr name.
>
> Unfortunately the conversion and stripping of the namespae string prefix
> from the xattr name gives the following unexpected result on FreeBSD:
>
> rep_setxattr("foo.bar", ...) => xattr with name "bar"
>
> The code checks if the name begins with "system.", if it doesn't find
> it, it defaults to the user namespace and then does a strchr(name, '.')
> which skips *any* leading string before the first dot.
>
> Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
>
> Signed-off-by: Ralph Boehme <slow at samba.org>
> ---
> lib/replace/xattr.c | 105 ++++++++++++++++++++++++++++++++++++++++------------
> 1 file changed, 81 insertions(+), 24 deletions(-)
>
> diff --git a/lib/replace/xattr.c b/lib/replace/xattr.c
> index ce52d1a..2479c21 100644
> --- a/lib/replace/xattr.c
> +++ b/lib/replace/xattr.c
> @@ -61,11 +61,21 @@ ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t si
> #elif defined(HAVE_GETEA)
> return getea(path, name, value, size);
> #elif defined(HAVE_EXTATTR_GET_FILE)
> - char *s;
> ssize_t retval;
> - int attrnamespace = (strncmp(name, "system", 6) == 0) ?
> - EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
> - const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
> + int attrnamespace;
> + const char *attrname;
> +
> + if (strncmp(name, "system.", 7) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
> + attrname = name + 7;
> + } else if (strncmp(name, "user.", 5) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_USER;
> + attrname = name + 5;
> + } else {
> + errno = EINVAL;
> + return -1;
> + }
> +
> /*
> * The BSD implementation has a nasty habit of silently truncating
> * the returned value to the size of the buffer, so we have to check
> @@ -125,11 +135,20 @@ ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size)
> #elif defined(HAVE_FGETEA)
> return fgetea(filedes, name, value, size);
> #elif defined(HAVE_EXTATTR_GET_FD)
> - char *s;
> ssize_t retval;
> - int attrnamespace = (strncmp(name, "system", 6) == 0) ?
> - EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
> - const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
> + int attrnamespace;
> + const char *attrname;
> +
> + if (strncmp(name, "system.", 7) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
> + attrname = name + 7;
> + } else if (strncmp(name, "user.", 5) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_USER;
> + attrname = name + 5;
> + } else {
> + errno = EINVAL;
> + return -1;
> + }
>
> if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
> if (size == 0) {
> @@ -414,10 +433,19 @@ int rep_removexattr (const char *path, const char *name)
> #elif defined(HAVE_REMOVEEA)
> return removeea(path, name);
> #elif defined(HAVE_EXTATTR_DELETE_FILE)
> - char *s;
> - int attrnamespace = (strncmp(name, "system", 6) == 0) ?
> - EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
> - const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
> + int attrnamespace;
> + const char *attrname;
> +
> + if (strncmp(name, "system.", 7) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
> + attrname = name + 7;
> + } else if (strncmp(name, "user.", 5) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_USER;
> + attrname = name + 5;
> + } else {
> + errno = EINVAL;
> + return -1;
> + }
>
> return extattr_delete_file(path, attrnamespace, attrname);
> #elif defined(HAVE_ATTR_REMOVE)
> @@ -455,10 +483,19 @@ int rep_fremovexattr (int filedes, const char *name)
> #elif defined(HAVE_FREMOVEEA)
> return fremoveea(filedes, name);
> #elif defined(HAVE_EXTATTR_DELETE_FD)
> - char *s;
> - int attrnamespace = (strncmp(name, "system", 6) == 0) ?
> - EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
> - const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
> + int attrnamespace;
> + const char *attrname;
> +
> + if (strncmp(name, "system.", 7) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
> + attrname = name + 7;
> + } else if (strncmp(name, "user.", 5) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_USER;
> + attrname = name + 5;
> + } else {
> + errno = EINVAL;
> + return -1;
> + }
>
> return extattr_delete_fd(filedes, attrnamespace, attrname);
> #elif defined(HAVE_ATTR_REMOVEF)
> @@ -496,11 +533,21 @@ int rep_setxattr (const char *path, const char *name, const void *value, size_t
> #elif defined(HAVE_SETEA)
> return setea(path, name, value, size, flags);
> #elif defined(HAVE_EXTATTR_SET_FILE)
> - char *s;
> int retval = 0;
> - int attrnamespace = (strncmp(name, "system", 6) == 0) ?
> - EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
> - const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
> + int attrnamespace;
> + const char *attrname;
> +
> + if (strncmp(name, "system.", 7) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
> + attrname = name + 7;
> + } else if (strncmp(name, "user.", 5) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_USER;
> + attrname = name + 5;
> + } else {
> + errno = EINVAL;
> + return -1;
> + }
> +
> if (flags) {
> /* Check attribute existence */
> retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0);
> @@ -563,11 +610,21 @@ int rep_fsetxattr (int filedes, const char *name, const void *value, size_t size
> #elif defined(HAVE_FSETEA)
> return fsetea(filedes, name, value, size, flags);
> #elif defined(HAVE_EXTATTR_SET_FD)
> - char *s;
> int retval = 0;
> - int attrnamespace = (strncmp(name, "system", 6) == 0) ?
> - EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
> - const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
> + int attrnamespace;
> + const char *attrname;
> +
> + if (strncmp(name, "system.", 7) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
> + attrname = name + 7;
> + } else if (strncmp(name, "user.", 5) == 0) {
> + attrnamespace = EXTATTR_NAMESPACE_USER;
> + attrname = name + 5;
> + } else {
> + errno = EINVAL;
> + return -1;
> + }
> +
> if (flags) {
> /* Check attribute existence */
> retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0);
> --
> 2.9.3
>
>
> From 6a5867a6938926e355ff3bfba566af227e6c5c92 Mon Sep 17 00:00:00 2001
> From: Ralph Boehme <slow at samba.org>
> Date: Fri, 3 Feb 2017 14:57:45 +0100
> Subject: [PATCH 4/4] 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 at samba.org>
> ---
> docs-xml/manpages/mvxattr.1.xml | 100 ++++++++++++++++++++++
> docs-xml/wscript_build | 1 +
> source3/utils/mvxattr.c | 178 ++++++++++++++++++++++++++++++++++++++++
> source3/utils/wscript_build | 8 ++
> source3/wscript | 3 +
> 5 files changed, 290 insertions(+)
> create mode 100644 docs-xml/manpages/mvxattr.1.xml
> create mode 100644 source3/utils/mvxattr.c
>
> diff --git a/docs-xml/manpages/mvxattr.1.xml b/docs-xml/manpages/mvxattr.1.xml
> new file mode 100644
> index 0000000..034dc3a
> --- /dev/null
> +++ b/docs-xml/manpages/mvxattr.1.xml
> @@ -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>
> diff --git a/docs-xml/wscript_build b/docs-xml/wscript_build
> index 2b3a180..0b690a8 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 0000000..9cc2ec0
> --- /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 <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;
> +}
> diff --git a/source3/utils/wscript_build b/source3/utils/wscript_build
> index 0b9356a..4295f85 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 443affd..907e400 100644
> --- a/source3/wscript
> +++ b/source3/wscript
> @@ -1633,6 +1633,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)
> --
> 2.9.3
>
More information about the samba-technical
mailing list