| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. |
| * All Rights Reserved. |
| */ |
| |
| #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); |
| } |