summaryrefslogtreecommitdiff
path: root/examples/copyattr.c
blob: 0f6928e07b84096f5e887632ac6dd1885d9a7954 (plain)
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 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;
}