Whamcloud - gitweb
Misc coverity fixes
[tools/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 }