blob: e835dbbf6ffaeee2dbdc3b9464c98d7b9d280f16 [file] [log] [blame]
/*
* Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libxfs.h"
#include "addr.h"
#include "command.h"
#include "type.h"
#include "faddr.h"
#include "fprint.h"
#include "field.h"
#include "io.h"
#include "flist.h"
#include "inode.h"
#include "output.h"
static int addr_f(int argc, char **argv);
static void addr_help(void);
static const cmdinfo_t addr_cmd =
{ "addr", "a", addr_f, 0, 1, 1, N_("[field-expression]"),
N_("set current address"), addr_help };
static void
addr_help(void)
{
dbprintf(_(
"\n"
" 'addr' uses the given field to set the filesystem address and type\n"
"\n"
" Examples:\n"
"\n"
" sb\n"
" a rootino - set the type to inode and set position to the root inode\n"
" a u.bmx[0].startblock (for inode with blockmap)\n"
"\n"
));
}
static int
addr_f(
int argc,
char **argv)
{
adfnc_t adf;
const ftattr_t *fa;
flist_t *fl;
const field_t *fld;
typnm_t next;
flist_t *tfl;
if (argc == 1) {
print_iocur("current", iocur_top);
return 0;
}
if (cur_typ == NULL) {
dbprintf(_("no current type\n"));
return 0;
}
fld = cur_typ->fields;
if (fld != NULL && fld->name[0] == '\0') {
fa = &ftattrtab[fld->ftyp];
ASSERT(fa->ftyp == fld->ftyp);
fld = fa->subfld;
}
if (fld == NULL) {
dbprintf(_("no fields for type %s\n"), cur_typ->name);
return 0;
}
fl = flist_scan(argv[1]);
if (fl == NULL)
return 0;
if (!flist_parse(fld, fl, iocur_top->data, 0))
goto out;
flist_print(fl);
for (tfl = fl; tfl->child != NULL; tfl = tfl->child) {
if ((tfl->flags & FL_OKLOW) && tfl->low < tfl->high) {
dbprintf(_("array not allowed for addr command\n"));
goto out;
}
}
fld = tfl->fld;
next = fld->next;
if (next == TYP_INODATA)
next = inode_next_type();
if (next == TYP_NONE) {
dbprintf(_("no next type for field %s\n"), fld->name);
goto out;
}
fa = &ftattrtab[fld->ftyp];
ASSERT(fa->ftyp == fld->ftyp);
adf = fa->adfunc;
if (adf == NULL) {
dbprintf(_("no addr function for field %s (type %s)\n"),
fld->name, fa->name);
goto out;
}
(*adf)(iocur_top->data, tfl->offset, next);
out:
flist_free(fl);
return 0;
}
void
addr_init(void)
{
add_command(&addr_cmd);
}