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 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <errno.h>
37
38 #ifdef _WIN32
39 #include <Windows.h>
40 #endif
41
42 #include "libxattr.h"
43
44 int attrtool_list(
int argc,
char **argv,
int values);
45 int attrtool_get(
int argc,
char **argv,
int raw);
46 int attrtool_set(
int argc,
char **argv);
47 int attrtool_rm(
int argc,
char **argv);
48
49 void print_usage(
char *cmd) {
50 fprintf(stderr,
"usage %s:\n", cmd);
51 fprintf(stderr,
" list <file>\n");
52 fprintf(stderr,
" listvalues <file>\n");
53 fprintf(stderr,
" get <file> <name>\n");
54 fprintf(stderr,
" set <file> <name> <value>\n");
55 fprintf(stderr,
" remove <file> <name>\n");
56 }
57
58 int xattr_tool_main(
int argc,
char **argv);
59
60 #ifdef _WIN32
61 static char* wchar2utf8(
const wchar_t *wstr,
size_t wlen) {
62 size_t maxlen = wlen *
4;
63 char *ret = malloc(maxlen +
1);
64 int ret_len = WideCharToMultiByte(
65 CP_UTF8,
66 0,
67 wstr,
68 wlen,
69 ret,
70 maxlen,
71 NULL,
72 NULL);
73 ret[ret_len] =
0;
74 return ret;
75 }
76
77 int wmain(
int argc,
wchar_t **argv) {
78 char **argv_utf8 = calloc(argc,
sizeof(
char*));
79 for(
int i=
0;i<argc;i++) {
80 argv_utf8[i] = wchar2utf8(argv[i], wcslen(argv[i]));
81 }
82
83 int ret = xattr_tool_main(argc, argv_utf8);
84
85 for(
int i=
0;i<argc;i++) {
86 free(argv_utf8[i]);
87 }
88 free(argv_utf8);
89
90 return ret;
91 }
92 #else
93 int main(
int argc,
char **argv) {
94 return xattr_tool_main(argc, argv);
95 }
96 #endif
97
98 int xattr_tool_main(
int argc,
char **argv) {
99 if(argc <
3) {
100 print_usage(argv[
0]);
101 return 1;
102 }
103
104 if(!strcmp(argv[
1],
"list") || !strcmp(argv[
1],
"ls")) {
105 return attrtool_list(argc, argv,
0);
106 }
else if(!strcmp(argv[
1],
"listvalues") || !strcmp(argv[
1],
"lsv")) {
107 return attrtool_list(argc, argv,
1);
108 }
else if(!strcmp(argv[
1],
"get")) {
109 return attrtool_get(argc, argv,
0);
110 }
else if(!strcmp(argv[
1],
"set")) {
111 return attrtool_set(argc, argv);
112 }
else if(!strcmp(argv[
1],
"rm") || !strcmp(argv[
1],
"remove")) {
113 return attrtool_rm(argc, argv);
114 }
else {
115 fprintf(stderr,
"Unknown command\n");
116 print_usage(argv[
0]);
117 }
118
119 return 1;
120 }
121
122 int attrtool_list(
int argc,
char **argv,
int values) {
123 ssize_t nelm =
0;
124 char **list = xattr_list(argv[
2], &nelm);
125 if(nelm <
0) {
126 perror(
"xattr_list");
127 return 3;
128 }
129
130 for(
int i=
0;i<nelm;i++) {
131 char *attr = list[i];
132 if(values) {
133 ssize_t valuelen =
0;
134 char *value = xattr_get(argv[
2], attr, &valuelen);
135 if(valuelen <
0) {
136 printf(
"%s: #ERROR: %s\n", attr, strerror(errno));
137 }
else {
138 printf(
"%s: %.*s\n", attr, (
int)valuelen, value);
139 }
140
141 if(value) {
142 free(value);
143 }
144 }
else {
145 printf(
"%s\n", attr);
146 }
147
148 free(list[i]);
149 }
150 if(list) {
151 free(list);
152 }
153
154 return 0;
155 }
156
157 int attrtool_get(
int argc,
char **argv,
int raw) {
158 if(argc <
4) {
159 fprintf(stderr,
"Too few arguments\n");
160 print_usage(argv[
1]);
161 return 1;
162 }
163
164 char *file = argv[
2];
165 char *attr = argv[
3];
166 int ret =
0;
167
168 ssize_t valuelen =
0;
169 char *value = xattr_get(file, attr, &valuelen);
170 if(value) {
171 if(raw) {
172 fwrite(value,
1, valuelen, stdout);
173 }
else {
174 printf(
"%.*s\n", (
int)valuelen, value);
175 }
176 free(value);
177 }
else {
178 perror(
"xattr_get");
179 ret =
3;
180 }
181
182 return ret;
183 }
184
185 int attrtool_set(
int argc,
char **argv) {
186 if(argc <
4) {
187 fprintf(stderr,
"Too few arguments\n");
188 print_usage(argv[
1]);
189 return 1;
190 }
191
192 size_t len = strlen(argv[
4]);
193 char *file = argv[
2];
194 char *attr = argv[
3];
195 char *value = argv[
4];
196 int ret =
0;
197
198 if(xattr_set(file, attr, value, len)) {
199 perror(
"xattr_set");
200 ret =
3;
201 }
202
203 return ret;
204 }
205
206 int attrtool_rm(
int argc,
char **argv) {
207 if(argc <
4) {
208 fprintf(stderr,
"Too few arguments\n");
209 print_usage(argv[
1]);
210 return 1;
211 }
212
213 char *file = argv[
2];
214 char *attr = argv[
3];
215 int ret =
0;
216
217 if(xattr_remove(file, attr)) {
218 perror(
"xattr_remove");
219 ret =
1;
220 }
221
222 return ret;
223 }
224