]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blob - debugfs/xattrs.c
Merge branch 'maint' into next
[thirdparty/e2fsprogs.git] / debugfs / xattrs.c
1 /*
2 * xattrs.c --- Modify extended attributes via debugfs.
3 *
4 * Copyright (C) 2014 Oracle. This file may be redistributed
5 * under the terms of the GNU Public License.
6 */
7
8 #include "config.h"
9 #include <stdio.h>
10 #ifdef HAVE_GETOPT_H
11 #include <getopt.h>
12 #else
13 extern int optind;
14 extern char *optarg;
15 #endif
16 #include <ctype.h>
17
18 #include "debugfs.h"
19
20 /* Dump extended attributes */
21 static void dump_xattr_string(FILE *out, const char *str, int len)
22 {
23 int printable = 0;
24 int i;
25
26 /* check: is string "printable enough?" */
27 for (i = 0; i < len; i++)
28 if (isprint(str[i]))
29 printable++;
30
31 if (printable <= len*7/8)
32 printable = 0;
33
34 for (i = 0; i < len; i++)
35 if (printable)
36 fprintf(out, isprint(str[i]) ? "%c" : "\\%03o",
37 (unsigned char)str[i]);
38 else
39 fprintf(out, "%02x ", (unsigned char)str[i]);
40 }
41
42 static int dump_attr(char *name, char *value, size_t value_len, void *data)
43 {
44 FILE *out = data;
45
46 fprintf(out, " ");
47 dump_xattr_string(out, name, strlen(name));
48 if (strcmp(name, "system.data") != 0) {
49 fprintf(out, " = \"");
50 dump_xattr_string(out, value, value_len);
51 fprintf(out, "\"");
52 }
53 fprintf(out, " (%zu)\n", value_len);
54
55 return 0;
56 }
57
58 void dump_inode_attributes(FILE *out, ext2_ino_t ino)
59 {
60 struct ext2_xattr_handle *h;
61 size_t sz;
62 errcode_t err;
63
64 err = ext2fs_xattrs_open(current_fs, ino, &h);
65 if (err)
66 return;
67
68 err = ext2fs_xattrs_read(h);
69 if (err)
70 goto out;
71
72 err = ext2fs_xattrs_count(h, &sz);
73 if (err || sz == 0)
74 goto out;
75
76 fprintf(out, "Extended attributes:\n");
77 err = ext2fs_xattrs_iterate(h, dump_attr, out);
78 if (err)
79 goto out;
80
81 out:
82 err = ext2fs_xattrs_close(&h);
83 }
84
85 void do_list_xattr(int argc, char **argv)
86 {
87 ext2_ino_t ino;
88
89 if (argc != 2) {
90 printf("%s: Usage: %s <file>\n", argv[0],
91 argv[0]);
92 return;
93 }
94
95 if (check_fs_open(argv[0]))
96 return;
97
98 ino = string_to_inode(argv[1]);
99 if (!ino)
100 return;
101
102 dump_inode_attributes(stdout, ino);
103 }
104
105 void do_get_xattr(int argc, char **argv)
106 {
107 ext2_ino_t ino;
108 struct ext2_xattr_handle *h;
109 FILE *fp = NULL;
110 char *buf = NULL;
111 size_t buflen;
112 int i;
113 errcode_t err;
114
115 reset_getopt();
116 while ((i = getopt(argc, argv, "f:")) != -1) {
117 switch (i) {
118 case 'f':
119 if (fp)
120 fclose(fp);
121 fp = fopen(optarg, "w");
122 if (fp == NULL) {
123 perror(optarg);
124 return;
125 }
126 break;
127 default:
128 printf("%s: Usage: %s <file> <attr> [-f outfile]\n",
129 argv[0], argv[0]);
130 goto out2;
131 }
132 }
133
134 if (optind != argc - 2) {
135 printf("%s: Usage: %s <file> <attr> [-f outfile]\n", argv[0],
136 argv[0]);
137 goto out2;
138 }
139
140 if (check_fs_open(argv[0]))
141 goto out2;
142
143 ino = string_to_inode(argv[optind]);
144 if (!ino)
145 goto out2;
146
147 err = ext2fs_xattrs_open(current_fs, ino, &h);
148 if (err)
149 goto out2;
150
151 err = ext2fs_xattrs_read(h);
152 if (err)
153 goto out;
154
155 err = ext2fs_xattr_get(h, argv[optind + 1], (void **)&buf, &buflen);
156 if (err)
157 goto out;
158
159 if (fp) {
160 fwrite(buf, buflen, 1, fp);
161 } else {
162 dump_xattr_string(stdout, buf, buflen);
163 printf("\n");
164 }
165
166 ext2fs_free_mem(&buf);
167 out:
168 ext2fs_xattrs_close(&h);
169 if (err)
170 com_err(argv[0], err, "while getting extended attribute");
171 out2:
172 if (fp)
173 fclose(fp);
174 }
175
176 void do_set_xattr(int argc, char **argv)
177 {
178 ext2_ino_t ino;
179 struct ext2_xattr_handle *h;
180 FILE *fp = NULL;
181 char *buf = NULL;
182 size_t buflen;
183 int i;
184 errcode_t err;
185
186 reset_getopt();
187 while ((i = getopt(argc, argv, "f:")) != -1) {
188 switch (i) {
189 case 'f':
190 if (fp)
191 fclose(fp);
192 fp = fopen(optarg, "r");
193 if (fp == NULL) {
194 perror(optarg);
195 return;
196 }
197 break;
198 default:
199 printf("%s: Usage: %s <file> <attr> [-f infile | "
200 "value]\n", argv[0], argv[0]);
201 goto out2;
202 }
203 }
204
205 if (!(fp && optind == argc - 2) && !(!fp && optind == argc - 3)) {
206 printf("%s: Usage: %s <file> <attr> [-f infile | value>]\n",
207 argv[0], argv[0]);
208 goto out2;
209 }
210
211 if (check_fs_open(argv[0]))
212 goto out2;
213 if (check_fs_read_write(argv[0]))
214 goto out2;
215 if (check_fs_bitmaps(argv[0]))
216 goto out2;
217
218 ino = string_to_inode(argv[optind]);
219 if (!ino)
220 goto out2;
221
222 err = ext2fs_xattrs_open(current_fs, ino, &h);
223 if (err)
224 goto out2;
225
226 err = ext2fs_xattrs_read(h);
227 if (err)
228 goto out;
229
230 if (fp) {
231 err = ext2fs_get_mem(current_fs->blocksize, &buf);
232 if (err)
233 goto out;
234 buflen = fread(buf, 1, current_fs->blocksize, fp);
235 } else {
236 buf = argv[optind + 2];
237 buflen = strlen(argv[optind + 2]);
238 }
239
240 err = ext2fs_xattr_set(h, argv[optind + 1], buf, buflen);
241 if (err)
242 goto out;
243
244 err = ext2fs_xattrs_write(h);
245 if (err)
246 goto out;
247
248 out:
249 ext2fs_xattrs_close(&h);
250 if (err)
251 com_err(argv[0], err, "while setting extended attribute");
252 out2:
253 if (fp) {
254 fclose(fp);
255 ext2fs_free_mem(&buf);
256 }
257 }
258
259 void do_rm_xattr(int argc, char **argv)
260 {
261 ext2_ino_t ino;
262 struct ext2_xattr_handle *h;
263 int i;
264 errcode_t err;
265
266 if (argc < 3) {
267 printf("%s: Usage: %s <file> <attrs>...\n", argv[0], argv[0]);
268 return;
269 }
270
271 if (check_fs_open(argv[0]))
272 return;
273 if (check_fs_read_write(argv[0]))
274 return;
275 if (check_fs_bitmaps(argv[0]))
276 return;
277
278 ino = string_to_inode(argv[1]);
279 if (!ino)
280 return;
281
282 err = ext2fs_xattrs_open(current_fs, ino, &h);
283 if (err)
284 return;
285
286 err = ext2fs_xattrs_read(h);
287 if (err)
288 goto out;
289
290 for (i = 2; i < argc; i++) {
291 err = ext2fs_xattr_remove(h, argv[i]);
292 if (err)
293 goto out;
294 }
295
296 err = ext2fs_xattrs_write(h);
297 if (err)
298 goto out;
299 out:
300 ext2fs_xattrs_close(&h);
301 if (err)
302 com_err(argv[0], err, "while removing extended attribute");
303 }