]> 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 fprintf(out, " = \"");
49 dump_xattr_string(out, value, value_len);
50 fprintf(out, "\" (%zu)\n", value_len);
51
52 return 0;
53 }
54
55 void dump_inode_attributes(FILE *out, ext2_ino_t ino)
56 {
57 struct ext2_xattr_handle *h;
58 size_t sz;
59 errcode_t err;
60
61 err = ext2fs_xattrs_open(current_fs, ino, &h);
62 if (err)
63 return;
64
65 err = ext2fs_xattrs_read(h);
66 if (err)
67 goto out;
68
69 err = ext2fs_xattrs_count(h, &sz);
70 if (err || sz == 0)
71 goto out;
72
73 fprintf(out, "Extended attributes:\n");
74 err = ext2fs_xattrs_iterate(h, dump_attr, out);
75 if (err)
76 goto out;
77
78 out:
79 err = ext2fs_xattrs_close(&h);
80 }
81
82 void do_list_xattr(int argc, char **argv)
83 {
84 ext2_ino_t ino;
85
86 if (argc != 2) {
87 printf("%s: Usage: %s <file>\n", argv[0],
88 argv[0]);
89 return;
90 }
91
92 if (check_fs_open(argv[0]))
93 return;
94
95 ino = string_to_inode(argv[1]);
96 if (!ino)
97 return;
98
99 dump_inode_attributes(stdout, ino);
100 }
101
102 void do_get_xattr(int argc, char **argv)
103 {
104 ext2_ino_t ino;
105 struct ext2_xattr_handle *h;
106 FILE *fp = NULL;
107 char *buf = NULL;
108 size_t buflen;
109 int i;
110 errcode_t err;
111
112 reset_getopt();
113 while ((i = getopt(argc, argv, "f:")) != -1) {
114 switch (i) {
115 case 'f':
116 if (fp)
117 fclose(fp);
118 fp = fopen(optarg, "w");
119 if (fp == NULL) {
120 perror(optarg);
121 return;
122 }
123 break;
124 default:
125 printf("%s: Usage: %s <file> <attr> [-f outfile]\n",
126 argv[0], argv[0]);
127 goto out2;
128 }
129 }
130
131 if (optind != argc - 2) {
132 printf("%s: Usage: %s <file> <attr> [-f outfile]\n", argv[0],
133 argv[0]);
134 goto out2;
135 }
136
137 if (check_fs_open(argv[0]))
138 goto out2;
139
140 ino = string_to_inode(argv[optind]);
141 if (!ino)
142 goto out2;
143
144 err = ext2fs_xattrs_open(current_fs, ino, &h);
145 if (err)
146 goto out2;
147
148 err = ext2fs_xattrs_read(h);
149 if (err)
150 goto out;
151
152 err = ext2fs_xattr_get(h, argv[optind + 1], (void **)&buf, &buflen);
153 if (err)
154 goto out;
155
156 if (fp) {
157 fwrite(buf, buflen, 1, fp);
158 } else {
159 dump_xattr_string(stdout, buf, buflen);
160 printf("\n");
161 }
162
163 ext2fs_free_mem(&buf);
164 out:
165 ext2fs_xattrs_close(&h);
166 if (err)
167 com_err(argv[0], err, "while getting extended attribute");
168 out2:
169 if (fp)
170 fclose(fp);
171 }
172
173 void do_set_xattr(int argc, char **argv)
174 {
175 ext2_ino_t ino;
176 struct ext2_xattr_handle *h;
177 FILE *fp = NULL;
178 char *buf = NULL;
179 size_t buflen;
180 int i;
181 errcode_t err;
182
183 reset_getopt();
184 while ((i = getopt(argc, argv, "f:")) != -1) {
185 switch (i) {
186 case 'f':
187 if (fp)
188 fclose(fp);
189 fp = fopen(optarg, "r");
190 if (fp == NULL) {
191 perror(optarg);
192 return;
193 }
194 break;
195 default:
196 printf("%s: Usage: %s <file> <attr> [-f infile | "
197 "value]\n", argv[0], argv[0]);
198 goto out2;
199 }
200 }
201
202 if (optind != argc - 2 && optind != argc - 3) {
203 printf("%s: Usage: %s <file> <attr> [-f infile | value>]\n",
204 argv[0], argv[0]);
205 goto out2;
206 }
207
208 if (check_fs_open(argv[0]))
209 goto out2;
210 if (check_fs_read_write(argv[0]))
211 goto out2;
212 if (check_fs_bitmaps(argv[0]))
213 goto out2;
214
215 ino = string_to_inode(argv[optind]);
216 if (!ino)
217 goto out2;
218
219 err = ext2fs_xattrs_open(current_fs, ino, &h);
220 if (err)
221 goto out2;
222
223 err = ext2fs_xattrs_read(h);
224 if (err)
225 goto out;
226
227 if (fp) {
228 err = ext2fs_get_mem(current_fs->blocksize, &buf);
229 if (err)
230 goto out;
231 buflen = fread(buf, 1, current_fs->blocksize, fp);
232 } else {
233 buf = argv[optind + 2];
234 buflen = strlen(argv[optind + 2]);
235 }
236
237 err = ext2fs_xattr_set(h, argv[optind + 1], buf, buflen);
238 if (err)
239 goto out;
240
241 err = ext2fs_xattrs_write(h);
242 if (err)
243 goto out;
244
245 out:
246 ext2fs_xattrs_close(&h);
247 if (err)
248 com_err(argv[0], err, "while setting extended attribute");
249 out2:
250 if (fp) {
251 fclose(fp);
252 ext2fs_free_mem(&buf);
253 }
254 }
255
256 void do_rm_xattr(int argc, char **argv)
257 {
258 ext2_ino_t ino;
259 struct ext2_xattr_handle *h;
260 int i;
261 errcode_t err;
262
263 if (argc < 3) {
264 printf("%s: Usage: %s <file> <attrs>...\n", argv[0], argv[0]);
265 return;
266 }
267
268 if (check_fs_open(argv[0]))
269 return;
270 if (check_fs_read_write(argv[0]))
271 return;
272 if (check_fs_bitmaps(argv[0]))
273 return;
274
275 ino = string_to_inode(argv[1]);
276 if (!ino)
277 return;
278
279 err = ext2fs_xattrs_open(current_fs, ino, &h);
280 if (err)
281 return;
282
283 err = ext2fs_xattrs_read(h);
284 if (err)
285 goto out;
286
287 for (i = 2; i < argc; i++) {
288 size_t buflen;
289 char *buf;
290
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 }