diff options
Diffstat (limited to 'examples/copyattr.c')
-rw-r--r-- | examples/copyattr.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/examples/copyattr.c b/examples/copyattr.c new file mode 100644 index 0000000..1013206 --- /dev/null +++ b/examples/copyattr.c @@ -0,0 +1,122 @@ +/* + * 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 strcmp(name, "user.") == 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; +} + |