]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/convert.c
apply gettext translation to more strings
[thirdparty/xfsprogs-dev.git] / db / convert.c
CommitLineData
2bd0ea18 1/*
da23017d
NS
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
dfc130f3 4 *
da23017d
NS
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
2bd0ea18 7 * published by the Free Software Foundation.
dfc130f3 8 *
da23017d
NS
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
dfc130f3 13 *
da23017d
NS
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2bd0ea18
NS
17 */
18
1d7e80ee 19#include <xfs/libxfs.h>
2bd0ea18 20#include "command.h"
2bd0ea18
NS
21#include "convert.h"
22#include "output.h"
4ca431fc 23#include "init.h"
2bd0ea18
NS
24
25#define M(A) (1 << CT_ ## A)
26#define agblock_to_bytes(x) \
27 ((__uint64_t)(x) << mp->m_sb.sb_blocklog)
28#define agino_to_bytes(x) \
29 ((__uint64_t)(x) << mp->m_sb.sb_inodelog)
30#define agnumber_to_bytes(x) \
31 agblock_to_bytes((__uint64_t)(x) * mp->m_sb.sb_agblocks)
32#define daddr_to_bytes(x) \
33 ((__uint64_t)(x) << BBSHIFT)
34#define fsblock_to_bytes(x) \
35 (agnumber_to_bytes(XFS_FSB_TO_AGNO(mp, (x))) + \
36 agblock_to_bytes(XFS_FSB_TO_AGBNO(mp, (x))))
37#define ino_to_bytes(x) \
38 (agnumber_to_bytes(XFS_INO_TO_AGNO(mp, (x))) + \
39 agino_to_bytes(XFS_INO_TO_AGINO(mp, (x))))
40#define inoidx_to_bytes(x) \
41 ((__uint64_t)(x) << mp->m_sb.sb_inodelog)
42
43typedef enum {
dfc130f3 44 CT_NONE = -1,
2bd0ea18
NS
45 CT_AGBLOCK, /* xfs_agblock_t */
46 CT_AGINO, /* xfs_agino_t */
47 CT_AGNUMBER, /* xfs_agno_t */
48 CT_BBOFF, /* byte offset in daddr */
49 CT_BLKOFF, /* byte offset in fsb/agb */
50 CT_BYTE, /* byte in filesystem */
51 CT_DADDR, /* daddr_t */
52 CT_FSBLOCK, /* xfs_fsblock_t */
53 CT_INO, /* xfs_ino_t */
54 CT_INOIDX, /* index of inode in fsblock */
55 CT_INOOFF, /* byte offset in inode */
56 NCTS
57} ctype_t;
58
59typedef struct ctydesc {
60 ctype_t ctype;
61 int allowed;
62 const char **names;
63} ctydesc_t;
64
65typedef union {
66 xfs_agblock_t agblock;
67 xfs_agino_t agino;
68 xfs_agnumber_t agnumber;
69 int bboff;
70 int blkoff;
71 __uint64_t byte;
72 xfs_daddr_t daddr;
73 xfs_fsblock_t fsblock;
74 xfs_ino_t ino;
75 int inoidx;
76 int inooff;
77} cval_t;
78
79static __uint64_t bytevalue(ctype_t ctype, cval_t *val);
80static int convert_f(int argc, char **argv);
81static int getvalue(char *s, ctype_t ctype, cval_t *val);
82static ctype_t lookupcty(char *ctyname);
83
84static const char *agblock_names[] = { "agblock", "agbno", NULL };
85static const char *agino_names[] = { "agino", "aginode", NULL };
86static const char *agnumber_names[] = { "agnumber", "agno", NULL };
87static const char *bboff_names[] = { "bboff", "daddroff", NULL };
88static const char *blkoff_names[] = { "blkoff", "fsboff", "agboff",
89 NULL };
90static const char *byte_names[] = { "byte", "fsbyte", NULL };
91static const char *daddr_names[] = { "daddr", "bb", NULL };
92static const char *fsblock_names[] = { "fsblock", "fsb", "fsbno", NULL };
93static const char *ino_names[] = { "ino", "inode", NULL };
94static const char *inoidx_names[] = { "inoidx", "offset", NULL };
95static const char *inooff_names[] = { "inooff", "inodeoff", NULL };
96
97static const ctydesc_t ctydescs[NCTS] = {
98 { CT_AGBLOCK, M(AGNUMBER)|M(BBOFF)|M(BLKOFF)|M(INOIDX)|M(INOOFF),
99 agblock_names },
100 { CT_AGINO, M(AGNUMBER)|M(INOOFF), agino_names },
101 { CT_AGNUMBER,
102 M(AGBLOCK)|M(AGINO)|M(BBOFF)|M(BLKOFF)|M(INOIDX)|M(INOOFF),
103 agnumber_names },
104 { CT_BBOFF, M(AGBLOCK)|M(AGNUMBER)|M(DADDR)|M(FSBLOCK), bboff_names },
105 { CT_BLKOFF, M(AGBLOCK)|M(AGNUMBER)|M(FSBLOCK), blkoff_names },
106 { CT_BYTE, 0, byte_names },
107 { CT_DADDR, M(BBOFF), daddr_names },
108 { CT_FSBLOCK, M(BBOFF)|M(BLKOFF)|M(INOIDX), fsblock_names },
109 { CT_INO, M(INOOFF), ino_names },
110 { CT_INOIDX, M(AGBLOCK)|M(AGNUMBER)|M(FSBLOCK)|M(INOOFF),
111 inoidx_names },
112 { CT_INOOFF,
113 M(AGBLOCK)|M(AGINO)|M(AGNUMBER)|M(FSBLOCK)|M(INO)|M(INOIDX),
114 inooff_names },
115};
116
117static const cmdinfo_t convert_cmd =
118 { "convert", NULL, convert_f, 3, 9, 0, "type num [type num]... type",
119 "convert from one address form to another", NULL };
120
121static __uint64_t
122bytevalue(ctype_t ctype, cval_t *val)
123{
124 switch (ctype) {
125 case CT_AGBLOCK:
126 return agblock_to_bytes(val->agblock);
127 case CT_AGINO:
128 return agino_to_bytes(val->agino);
129 case CT_AGNUMBER:
130 return agnumber_to_bytes(val->agnumber);
131 case CT_BBOFF:
132 return (__uint64_t)val->bboff;
133 case CT_BLKOFF:
134 return (__uint64_t)val->blkoff;
135 case CT_BYTE:
136 return val->byte;
137 case CT_DADDR:
138 return daddr_to_bytes(val->daddr);
139 case CT_FSBLOCK:
140 return fsblock_to_bytes(val->fsblock);
141 case CT_INO:
142 return ino_to_bytes(val->ino);
143 case CT_INOIDX:
144 return inoidx_to_bytes(val->inoidx);
145 case CT_INOOFF:
146 return (__uint64_t)val->inooff;
147 case CT_NONE:
148 case NCTS:
6bef826c 149 break;
2bd0ea18
NS
150 }
151 /* NOTREACHED */
152 return 0;
153}
154
155static int
156convert_f(int argc, char **argv)
157{
158 ctype_t c;
159 int conmask;
160 cval_t cvals[NCTS];
161 int i;
162 int mask;
163 __uint64_t v;
164 ctype_t wtype;
165
166 /* move past the "convert" command */
167 argc--;
168 argv++;
169
170 if ((argc % 2) != 1) {
9ee7055c
AM
171 dbprintf(_("bad argument count %d to convert, expected 3,5,7,9 "
172 "arguments\n"), argc);
2bd0ea18
NS
173 return 0;
174 }
175 if ((wtype = lookupcty(argv[argc - 1])) == CT_NONE) {
9ee7055c 176 dbprintf(_("unknown conversion type %s\n"), argv[argc - 1]);
2bd0ea18
NS
177 return 0;
178 }
179
180 for (i = mask = conmask = 0; i < (argc - 1) / 2; i++) {
181 c = lookupcty(argv[i * 2]);
182 if (c == CT_NONE) {
9ee7055c 183 dbprintf(_("unknown conversion type %s\n"), argv[i * 2]);
2bd0ea18
NS
184 return 0;
185 }
186 if (c == wtype) {
9ee7055c 187 dbprintf(_("result type same as argument\n"));
2bd0ea18
NS
188 return 0;
189 }
190 if (conmask & (1 << c)) {
9ee7055c 191 dbprintf(_("conflicting conversion type %s\n"),
2bd0ea18
NS
192 argv[i * 2]);
193 return 0;
194 }
195 if (!getvalue(argv[i * 2 + 1], c, &cvals[c]))
196 return 0;
197 mask |= 1 << c;
198 conmask |= ~ctydescs[c].allowed;
199 }
200 if (cur_agno != NULLAGNUMBER && (conmask & M(AGNUMBER)) == 0) {
201 cvals[CT_AGNUMBER].agnumber = cur_agno;
202 mask |= M(AGNUMBER);
203 conmask |= ~ctydescs[CT_AGNUMBER].allowed;
204 }
205 v = 0;
206 for (c = (ctype_t)0; c < NCTS; c++) {
207 if (!(mask & (1 << c)))
208 continue;
209 v += bytevalue(c, &cvals[c]);
210 }
211 switch (wtype) {
212 case CT_AGBLOCK:
213 v = XFS_DADDR_TO_AGBNO(mp, v >> BBSHIFT);
214 break;
215 case CT_AGINO:
216 v = (v >> mp->m_sb.sb_inodelog) %
217 (mp->m_sb.sb_agblocks << mp->m_sb.sb_inopblog);
218 break;
219 case CT_AGNUMBER:
220 v = XFS_DADDR_TO_AGNO(mp, v >> BBSHIFT);
221 break;
222 case CT_BBOFF:
223 v &= BBMASK;
224 break;
225 case CT_BLKOFF:
226 v &= mp->m_blockmask;
227 break;
228 case CT_BYTE:
229 break;
230 case CT_DADDR:
231 v >>= BBSHIFT;
232 break;
233 case CT_FSBLOCK:
234 v = XFS_DADDR_TO_FSB(mp, v >> BBSHIFT);
235 break;
236 case CT_INO:
237 v = XFS_AGINO_TO_INO(mp, XFS_DADDR_TO_AGNO(mp, v >> BBSHIFT),
238 (v >> mp->m_sb.sb_inodelog) %
239 (mp->m_sb.sb_agblocks << mp->m_sb.sb_inopblog));
240 break;
241 case CT_INOIDX:
242 v = (v >> mp->m_sb.sb_inodelog) & (mp->m_sb.sb_inopblock - 1);
243 break;
244 case CT_INOOFF:
245 v &= mp->m_sb.sb_inodesize - 1;
246 break;
247 case CT_NONE:
248 case NCTS:
249 /* NOTREACHED */
6bef826c 250 break;
2bd0ea18
NS
251 }
252 dbprintf("0x%llx (%llu)\n", v, v);
253 return 0;
254}
255
256void
257convert_init(void)
258{
259 add_command(&convert_cmd);
260}
261
262static int
263getvalue(char *s, ctype_t ctype, cval_t *val)
264{
265 char *p;
266 __uint64_t v;
267
268 v = strtoull(s, &p, 0);
269 if (*p != '\0') {
9ee7055c 270 dbprintf(_("%s is not a number\n"), s);
2bd0ea18
NS
271 return 0;
272 }
273 switch (ctype) {
274 case CT_AGBLOCK:
275 val->agblock = (xfs_agblock_t)v;
276 break;
277 case CT_AGINO:
278 val->agino = (xfs_agino_t)v;
279 break;
280 case CT_AGNUMBER:
281 val->agnumber = (xfs_agnumber_t)v;
282 break;
283 case CT_BBOFF:
284 val->bboff = (int)v;
285 break;
286 case CT_BLKOFF:
287 val->blkoff = (int)v;
288 break;
289 case CT_BYTE:
290 val->byte = (__uint64_t)v;
291 break;
292 case CT_DADDR:
293 val->daddr = (xfs_daddr_t)v;
294 break;
295 case CT_FSBLOCK:
296 val->fsblock = (xfs_fsblock_t)v;
297 break;
298 case CT_INO:
299 val->ino = (xfs_ino_t)v;
300 break;
301 case CT_INOIDX:
302 val->inoidx = (int)v;
303 break;
304 case CT_INOOFF:
305 val->inooff = (int)v;
306 break;
307 case CT_NONE:
308 case NCTS:
309 /* NOTREACHED */
6bef826c 310 break;
2bd0ea18
NS
311 }
312 return 1;
313}
314
315static ctype_t
316lookupcty(char *ctyname)
317{
318 ctype_t cty;
319 const char **name;
320
321 for (cty = (ctype_t)0; cty < NCTS; cty++) {
322 for (name = ctydescs[cty].names; *name; name++) {
323 if (strcmp(ctyname, *name) == 0)
324 return cty;
325 }
326 }
327 return CT_NONE;
328}