]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/attrset.c
xfsprogs: Release v4.18.0
[thirdparty/xfsprogs-dev.git] / db / attrset.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6
7 #include "libxfs.h"
8 #include "command.h"
9 #include "attrset.h"
10 #include "io.h"
11 #include "output.h"
12 #include "type.h"
13 #include "init.h"
14 #include "fprint.h"
15 #include "faddr.h"
16 #include "field.h"
17 #include "inode.h"
18 #include "malloc.h"
19
20 static int attr_set_f(int argc, char **argv);
21 static int attr_remove_f(int argc, char **argv);
22 static void attrset_help(void);
23
24 static const cmdinfo_t attr_set_cmd =
25 { "attr_set", "aset", attr_set_f, 1, -1, 0,
26 N_("[-r|-s|-p|-u] [-n] [-R|-C] [-v n] name"),
27 N_("set the named attribute on the current inode"), attrset_help };
28 static const cmdinfo_t attr_remove_cmd =
29 { "attr_remove", "aremove", attr_remove_f, 1, -1, 0,
30 N_("[-r|-s|-p|-u] [-n] name"),
31 N_("remove the named attribute from the current inode"), attrset_help };
32
33 static void
34 attrset_help(void)
35 {
36 dbprintf(_(
37 "\n"
38 " The 'attr_set' and 'attr_remove' commands provide interfaces for debugging\n"
39 " the extended attribute allocation and removal code.\n"
40 " Both commands require an attribute name to be specified, and the attr_set\n"
41 " command allows an optional value length (-v) to be provided as well.\n"
42 " There are 4 namespace flags:\n"
43 " -r -- 'root'\n"
44 " -u -- 'user' (default)\n"
45 " -s -- 'secure'\n"
46 "\n"
47 " For attr_set, these options further define the type of set operation:\n"
48 " -C -- 'create' - create attribute, fail if it already exists\n"
49 " -R -- 'replace' - replace attribute, fail if it does not exist\n"
50 " The backward compatibility mode 'noattr2' can be emulated (-n) also.\n"
51 "\n"));
52 }
53
54 void
55 attrset_init(void)
56 {
57 if (!expert_mode)
58 return;
59
60 add_command(&attr_set_cmd);
61 add_command(&attr_remove_cmd);
62 }
63
64 static int
65 attr_set_f(
66 int argc,
67 char **argv)
68 {
69 xfs_inode_t *ip = NULL;
70 char *name, *value, *sp;
71 int c, valuelen = 0, flags = 0;
72
73 if (cur_typ == NULL) {
74 dbprintf(_("no current type\n"));
75 return 0;
76 }
77 if (cur_typ->typnm != TYP_INODE) {
78 dbprintf(_("current type is not inode\n"));
79 return 0;
80 }
81
82 while ((c = getopt(argc, argv, "rusCRnv:")) != EOF) {
83 switch (c) {
84 /* namespaces */
85 case 'r':
86 flags |= LIBXFS_ATTR_ROOT;
87 flags &= ~LIBXFS_ATTR_SECURE;
88 break;
89 case 'u':
90 flags &= ~(LIBXFS_ATTR_ROOT | LIBXFS_ATTR_SECURE);
91 break;
92 case 's':
93 flags |= LIBXFS_ATTR_SECURE;
94 flags &= ~LIBXFS_ATTR_ROOT;
95 break;
96
97 /* modifiers */
98 case 'C':
99 flags |= LIBXFS_ATTR_CREATE;
100 break;
101 case 'R':
102 flags |= LIBXFS_ATTR_REPLACE;
103 break;
104
105 case 'n':
106 mp->m_flags |= LIBXFS_MOUNT_COMPAT_ATTR;
107 break;
108
109 /* value length */
110 case 'v':
111 valuelen = (int)strtol(optarg, &sp, 0);
112 if (*sp != '\0' || valuelen < 0 || valuelen > 64*1024) {
113 dbprintf(_("bad attr_set valuelen %s\n"), optarg);
114 return 0;
115 }
116 break;
117
118 default:
119 dbprintf(_("bad option for attr_set command\n"));
120 return 0;
121 }
122 }
123
124 if (optind != argc - 1) {
125 dbprintf(_("too few options for attr_set (no name given)\n"));
126 return 0;
127 }
128
129 name = argv[optind];
130
131 if (valuelen) {
132 value = (char *)memalign(getpagesize(), valuelen);
133 if (!value) {
134 dbprintf(_("cannot allocate buffer (%d)\n"), valuelen);
135 goto out;
136 }
137 memset(value, 'v', valuelen);
138 } else {
139 value = NULL;
140 }
141
142 if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip,
143 &xfs_default_ifork_ops)) {
144 dbprintf(_("failed to iget inode %llu\n"),
145 (unsigned long long)iocur_top->ino);
146 goto out;
147 }
148
149 if (libxfs_attr_set(ip, (unsigned char *)name,
150 (unsigned char *)value, valuelen, flags)) {
151 dbprintf(_("failed to set attr %s on inode %llu\n"),
152 name, (unsigned long long)iocur_top->ino);
153 goto out;
154 }
155
156 /* refresh with updated inode contents */
157 set_cur_inode(iocur_top->ino);
158
159 out:
160 mp->m_flags &= ~LIBXFS_MOUNT_COMPAT_ATTR;
161 if (ip)
162 IRELE(ip);
163 if (value)
164 free(value);
165 return 0;
166 }
167
168 static int
169 attr_remove_f(
170 int argc,
171 char **argv)
172 {
173 xfs_inode_t *ip = NULL;
174 char *name;
175 int c, flags = 0;
176
177 if (cur_typ == NULL) {
178 dbprintf(_("no current type\n"));
179 return 0;
180 }
181 if (cur_typ->typnm != TYP_INODE) {
182 dbprintf(_("current type is not inode\n"));
183 return 0;
184 }
185
186 while ((c = getopt(argc, argv, "rusn")) != EOF) {
187 switch (c) {
188 /* namespaces */
189 case 'r':
190 flags |= LIBXFS_ATTR_ROOT;
191 flags &= ~LIBXFS_ATTR_SECURE;
192 break;
193 case 'u':
194 flags &= ~(LIBXFS_ATTR_ROOT | LIBXFS_ATTR_SECURE);
195 break;
196 case 's':
197 flags |= LIBXFS_ATTR_SECURE;
198 flags &= ~LIBXFS_ATTR_ROOT;
199 break;
200
201 case 'n':
202 mp->m_flags |= LIBXFS_MOUNT_COMPAT_ATTR;
203 break;
204
205 default:
206 dbprintf(_("bad option for attr_remove command\n"));
207 return 0;
208 }
209 }
210
211 if (optind != argc - 1) {
212 dbprintf(_("too few options for attr_remove (no name given)\n"));
213 return 0;
214 }
215
216 name = argv[optind];
217
218 if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip,
219 &xfs_default_ifork_ops)) {
220 dbprintf(_("failed to iget inode %llu\n"),
221 (unsigned long long)iocur_top->ino);
222 goto out;
223 }
224
225 if (libxfs_attr_remove(ip, (unsigned char *)name, flags)) {
226 dbprintf(_("failed to remove attr %s from inode %llu\n"),
227 name, (unsigned long long)iocur_top->ino);
228 goto out;
229 }
230
231 /* refresh with updated inode contents */
232 set_cur_inode(iocur_top->ino);
233
234 out:
235 mp->m_flags &= ~LIBXFS_MOUNT_COMPAT_ATTR;
236 if (ip)
237 IRELE(ip);
238 return 0;
239 }