1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/*
Copyright (C) 2009 Andreas Gruenbacher <agruen@suse.de>
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 2 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/>.
*/
/*
* Example how to preserve Extended Attributes in file manager style
* applications. This does NOT also copy Access Control Lists!
*
* Andreas Gruenbacher, SuSE Labs, SuSE Linux AG
* 23 January 2003
*/
#include "config.h"
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <locale.h>
/* #include <libintl.h> */
#ifdef HAVE_ATTR_ERROR_CONTEXT_H
# include <attr/error_context.h>
#endif
#ifdef HAVE_ATTR_LIBATTR_H
# include <attr/libattr.h>
#endif
/*
* We don't fully internationalize this example!
*/
#define _(msg) (msg)
/*
* Optional error handler for attr_copy_file(). CTX is the error
* context passed to attr_copy_file(), ERR is the errno value
* that occurred. FMT and the rest are printf style arguments.
*/
static void
error(struct error_context *ctx, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (vfprintf(stderr, fmt, ap))
fprintf(stderr, ": ");
fprintf(stderr, "%s\n", strerror(errno));
va_end(ap);
}
/*
* Optional handler for quoting path names in error messages.
* (This is a very stupid example!)
*/
static const char *
quote(struct error_context *ctx, const char *pathname)
{
char *pn = strdup(pathname), *p;
pathname = strdup(pathname);
for (p = pn; *p != '\0'; p++)
if (*p & 0x80)
*p='?';
return pn;
}
static void
quote_free(struct error_context *ctx, const char *name)
{
free((void *)name);
}
/*
* The error context we pass to attr_copy_file().
*/
struct error_context ctx = { error, quote, quote_free };
/*
* Optional attribute filter for attr_copy_file(). This example
* excludes all attributes other than extended user attributes.
*/
static int is_user_attr(const char *name, struct error_context *ctx)
{
return strncmp(name, "user.", 5) == 0;
}
int
main(int argc, char *argv[])
{
int ret;
/*
* Set the locale to enable message translation
*/
setlocale(LC_MESSAGES, "");
setlocale(LC_CTYPE, "");
if (argc != 3) {
fprintf(stderr, _("Usage: %s from to\n"), argv[0]);
exit(1);
}
#if defined(HAVE_ATTR_COPY_FILE)
/*
* If the third parameter is NULL, all extended attributes
* except those that define Access Control Lists are copied.
* ACLs are excluded by default because copying them between
* file systems with and without ACL support needs some
* additional logic so that no unexpected permissions result.
*
* For copying ACLs, please use perm_copy_file() from libacl.
*
* The CTX parameter could also be NULL, in which case attr_copy_file
* would print no error messages.
*/
ret = attr_copy_file(argv[1], argv[2], is_user_attr, &ctx);
#else
fprintf(stderr, _("No support for copying extended attributes\n"));
ret = -1;
#endif
if (ret != 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
|