]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/attrset.c
Add xfs_db expert mode commands for set/remove of extended attributes.
[thirdparty/xfsprogs-dev.git] / db / attrset.c
CommitLineData
57c9fccb
NS
1/*
2 * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33#include <xfs/libxfs.h>
34#include "command.h"
35#include "attrset.h"
36#include "io.h"
37#include "output.h"
38#include "type.h"
39#include "init.h"
40#include "inode.h"
41#include "malloc.h"
42
43static int attr_set_f(int argc, char **argv);
44static int attr_remove_f(int argc, char **argv);
45static void attrset_help(void);
46
47static const cmdinfo_t attr_set_cmd =
48 { "attr_set", "aset", attr_set_f, 1, -1, 0,
49 "[-r|-s|-p|-u] [-R|-C] [-v n] name",
50 "set the named attribute on the current inode", attrset_help };
51static const cmdinfo_t attr_remove_cmd =
52 { "attr_remove", "aremove", attr_remove_f, 1, -1, 0,
53 "[-r|-s|-p|-u] name",
54 "remove the named attribute from the current inode", attrset_help };
55
56static void
57attrset_help(void)
58{
59 dbprintf(
60"\n"
61" The 'attr_set' and 'attr_remove' commands provide interfaces for debugging\n"
62" the extended attribute allocation and removal code.\n"
63" Both commands require an attribute name to be specified, and the attr_set\n"
64" command allows an optional value length (-v) to be provided as well.\n"
65" There are 4 namespace flags:\n"
66" -r -- 'root'\n"
67" -u -- 'user' (default)\n"
68" -s -- 'secure'\n"
69"\n"
70" For attr_set, these options further define the type of set:\n"
71" -C -- 'create' - create attribute, fail if it already exists\n"
72" -R -- 'replace' - replace attribute, fail if it does not exist\n"
73"\n");
74}
75
76void
77attrset_init(void)
78{
79 if (!expert_mode)
80 return;
81
82 add_command(&attr_set_cmd);
83 add_command(&attr_remove_cmd);
84}
85
86static int
87attr_set_f(
88 int argc,
89 char **argv)
90{
91 xfs_inode_t *ip = NULL;
92 char *name, *value, *sp;
93 int c, namelen, valuelen = 0, flags = 0;
94
95 if (cur_typ == NULL) {
96 dbprintf("no current type\n");
97 return 0;
98 }
99 if (cur_typ->typnm != TYP_INODE) {
100 dbprintf("current type is not inode\n");
101 return 0;
102 }
103
104 while ((c = getopt(argc, argv, "rusCRv:")) != EOF) {
105 switch (c) {
106 /* namespaces */
107 case 'r':
108 flags |= LIBXFS_ATTR_ROOT;
109 flags &= ~LIBXFS_ATTR_SECURE;
110 break;
111 case 'u':
112 flags &= ~(LIBXFS_ATTR_ROOT | LIBXFS_ATTR_SECURE);
113 break;
114 case 's':
115 flags |= LIBXFS_ATTR_SECURE;
116 flags &= ~LIBXFS_ATTR_ROOT;
117 break;
118
119 /* modifiers */
120 case 'C':
121 flags |= LIBXFS_ATTR_CREATE;
122 break;
123 case 'R':
124 flags |= LIBXFS_ATTR_REPLACE;
125 break;
126
127 /* value length */
128 case 'v':
129 valuelen = (int)strtol(optarg, &sp, 0);
130 if (*sp != '\0' || valuelen < 0 || valuelen > 64*1024) {
131 dbprintf("bad attr_set valuelen %s\n", optarg);
132 return 0;
133 }
134 break;
135
136 default:
137 dbprintf("bad option for attr_set command\n");
138 return 0;
139 }
140 }
141
142 if (optind != argc - 1) {
143 dbprintf("too few options for attr_set (no name given)\n");
144 return 0;
145 }
146
147 name = argv[optind];
148 namelen = strlen(name);
149
150 if (valuelen) {
151 value = (char *)memalign(getpagesize(), valuelen);
152 if (!value) {
153 dbprintf("cannot allocate buffer (%d)\n", valuelen);
154 goto out;
155 }
156 memset(value, 0xfeedface, valuelen);
157 } else {
158 value = NULL;
159 }
160
161 if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip, 0)) {
162 dbprintf(_("failed to iget inode %llu\n"),
163 (unsigned long long)iocur_top->ino);
164 goto out;
165 }
166
167 if (libxfs_attr_set_int(ip, name, namelen, value, valuelen, flags)) {
168 dbprintf(_("failed to set attr %s on inode %llu\n"),
169 name, (unsigned long long)iocur_top->ino);
170 goto out;
171 }
172
173 /* refresh with updated inode contents */
174 set_cur_inode(iocur_top->ino);
175
176out:
177 if (ip)
178 libxfs_iput(ip, 0);
179 if (value)
180 free(value);
181 return 0;
182}
183
184static int
185attr_remove_f(
186 int argc,
187 char **argv)
188{
189 xfs_inode_t *ip = NULL;
190 char *name;
191 int c, namelen, flags = 0;
192
193 if (cur_typ == NULL) {
194 dbprintf("no current type\n");
195 return 0;
196 }
197 if (cur_typ->typnm != TYP_INODE) {
198 dbprintf("current type is not inode\n");
199 return 0;
200 }
201
202 while ((c = getopt(argc, argv, "rus")) != EOF) {
203 switch (c) {
204 /* namespaces */
205 case 'r':
206 flags |= LIBXFS_ATTR_ROOT;
207 flags &= ~LIBXFS_ATTR_SECURE;
208 break;
209 case 'u':
210 flags &= ~(LIBXFS_ATTR_ROOT | LIBXFS_ATTR_SECURE);
211 break;
212 case 's':
213 flags |= LIBXFS_ATTR_SECURE;
214 flags &= ~LIBXFS_ATTR_ROOT;
215 break;
216
217 default:
218 dbprintf("bad option for attr_remove command\n");
219 return 0;
220 }
221 }
222
223 if (optind != argc - 1) {
224 dbprintf("too few options for attr_remove (no name given)\n");
225 return 0;
226 }
227
228 name = argv[optind];
229 namelen = strlen(name);
230
231 if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip, 0)) {
232 dbprintf(_("failed to iget inode %llu\n"),
233 (unsigned long long)iocur_top->ino);
234 goto out;
235 }
236
237 if (libxfs_attr_remove_int(ip, name, namelen, flags)) {
238 dbprintf(_("failed to remove attr %s from inode %llu\n"),
239 name, (unsigned long long)iocur_top->ino);
240 goto out;
241 }
242
243 /* refresh with updated inode contents */
244 set_cur_inode(iocur_top->ino);
245
246out:
247 if (ip)
248 libxfs_iput(ip, 0);
249 return 0;
250}