📄 directory.c
字号:
/* * Copyright (c) International Business Machines Corp., 2000-2002 * * 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; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will 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 to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * FUNCTION: Display/modify directory/dtree and file/xtree */#include <config.h>#include <limits.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include "xpeek.h"#include "jfs_dtree.h"#include "jfs_xtree.h"#include "jfs_filsys.h"#include "unicode_to_utf8.h"#include "jfs_endian.h"#include "jfs_unicode.h"/* libfs includes */#include <inode.h>extern unsigned type_jfs;void print_direntry(struct dtslot *, uint8_t);char display_leaf_slots(struct dtslot *, int8_t *, int8_t, int *);char display_internal_slots(struct dtslot *, int8_t *, int8_t, int *);char display_leaf_xads(xad_t *, short, int *);char display_internal_xads(xad_t *, short, int *);char display_internal_xtpage(xad_t);char display_slot(struct dtslot *, int8_t, int, int *);char display_slot(struct dtslot *, int8_t, int, int *);char display_extent_page(int64_t);void display_xtpage(xtpage_t *);void strToUcs(UniChar *, char *, int);char UTF8_Buffer[8 * JFS_PATH_MAX];void directory(){ char cmd_line[80]; dtpage_t dtree; int i; struct dinode inode; int64_t inode_address; unsigned inum; int64_t node_address; struct idtentry *node_entry; dtroot_t *root; uint8_t *stbl; char *token; unsigned which_table = FILESYSTEM_I; token = strtok(0, " \n"); if (token == 0) { fputs("directory: Please enter: inum [fileset]\ndirectory> ", stdout); fgets(cmd_line, 80, stdin); token = strtok(cmd_line, " \n"); if (token == 0) return; } errno = 0; inum = strtoul(token, 0, 0); if (inum == 0 && errno) { fputs("directory: invalid inum\n\n", stderr); return; } token = strtok(0, " \n"); if (token) { if (token[0] != '0') { fputs("directory: invalid fileset\n\n", stderr); return; } } if (strtok(0, " \n")) { fputs("directory: Too many arguments\n\n", stderr); return; } if (find_inode(inum, which_table, &inode_address) || xRead(inode_address, sizeof (struct dinode), (char *) &inode)) { fputs("directory: error reading inode\n\n", stderr); return; } /* swap if on big endian machine */ ujfs_swap_dinode(&inode, GET, type_jfs); if ((inode.di_mode & IFMT) != IFDIR) { fputs("directory: Not a directory!\n", stderr); return; } root = (dtroot_t *) & (inode.di_btroot); printf("idotdot = %d\n\n", root->header.idotdot); if (root->header.flag & BT_LEAF) { if (root->header.nextindex == 0) { fputs("Empty directory.\n", stdout); return; } for (i = 0; i < root->header.nextindex; i++) { print_direntry(root->slot, root->header.stbl[i]); } return; } /* Root is not a leaf node, we must descend to the leftmost leaf */ node_entry = (struct idtentry *) & (root->slot[root->header.stbl[0]]); descend: node_address = addressPXD(&(node_entry->xd)) << l2bsize; if (xRead(node_address, sizeof (dtpage_t), (char *) &dtree)) { fputs("Directory: Error reading dtree node\n", stderr); return; } /* swap if on big endian machine */ ujfs_swap_dtpage_t(&dtree, type_jfs); stbl = (uint8_t *) & (dtree.slot[dtree.header.stblindex]); if (!(dtree.header.flag & BT_LEAF)) { node_entry = (struct idtentry *) & (dtree.slot[stbl[0]]); goto descend; } /* dtree (contained in node) is the left-most leaf node */ next_leaf: for (i = 0; i < dtree.header.nextindex; i++) { print_direntry(dtree.slot, stbl[i]); } if (dtree.header.next) { if (xRead(dtree.header.next << l2bsize, sizeof (dtpage_t), (char *) &dtree)) { fputs("directory: Error reading leaf node\n", stderr); return; } /* swap if on big endian machine */ ujfs_swap_dtpage_t(&dtree, type_jfs); stbl = (uint8_t *) & (dtree.slot[dtree.header.stblindex]); goto next_leaf; } return;}void print_direntry(struct dtslot *slot, uint8_t head_index){ struct ldtentry *entry; int len; UniChar *n; UniChar *name; int namlen; int next; struct dtslot *s; entry = (struct ldtentry *) & (slot[head_index]); namlen = entry->namlen; name = (UniChar *) malloc(sizeof (UniChar) * (namlen + 1)); if (name == 0) { fputs("dirname: malloc error!\n", stderr); return; } name[namlen] = 0; len = MIN(namlen, DTLHDRDATALEN); UniStrncpy(name, entry->name, len); next = entry->next; n = name + len; while (next >= 0) { s = &(slot[next]); namlen -= len; len = MIN(namlen, DTSLOTDATALEN); UniStrncpy(n, s->name, len); next = s->next; n += len; } /* Clear the UTF8 conversion buffer. */ memset(UTF8_Buffer, 0, sizeof (UTF8_Buffer)); /* Convert the name into UTF8 */ Unicode_String_to_UTF8_String(UTF8_Buffer, name, entry->namlen); printf("%d\t%s\n", entry->inumber, UTF8_Buffer); free(name);}void dtree(){ int changed = 0; char cmd_line[80]; dtpage_t *dtree; int field; char flag_names[64]; struct dinode inode; int64_t inode_address; unsigned inum; char result; dtroot_t *root; char *token; unsigned which_table = FILESYSTEM_I; token = strtok(0, " \n"); if (token == 0) { fputs("dtree: Please enter: inum [fileset]\ndtree> ", stdout); fgets(cmd_line, 80, stdin); token = strtok(cmd_line, " \n"); if (token == 0) return; } errno = 0; inum = strtoul(token, 0, 0); if (inum == 0 && errno) { fputs("dtree: invalid inum\n\n", stderr); return; } token = strtok(0, " \n"); if (token) { if (token[0] != '0') { fputs("dtree: invalide fileset\n\n", stderr); return; } } if (strtok(0, " \n")) { fputs("dtree: Too many arguments\n\n", stderr); return; } if (find_inode(inum, which_table, &inode_address) || xRead(inode_address, sizeof (struct dinode), (char *) &inode)) { fputs("dtree: error reading inode\n\n", stderr); return; } /* swap if on big endian machine */ ujfs_swap_dinode(&inode, GET, type_jfs); if ((inode.di_mode & IFMT) != IFDIR) { fputs("dtree: Not a directory!\n", stderr); return; } dtree = (dtpage_t *) & (inode.di_btroot); redisplay: if (!(dtree->header.flag & BT_ROOT)) fputs("dtree: Should be at root of dtree, but BTROOT not set!\n", stderr); root = (dtroot_t *) dtree; *flag_names = 0; if (root->header.flag & BT_ROOT) strcat(flag_names, "BT_ROOT "); if (root->header.flag & BT_LEAF) strcat(flag_names, "BT_LEAF "); if (root->header.flag & BT_INTERNAL) strcat(flag_names, "BT_INTERNAL "); if (root->header.flag & BT_RIGHTMOST) strcat(flag_names, "BT_RIGHTMOST "); if (root->header.flag & BT_LEFTMOST) strcat(flag_names, "BT_LEFTMOST "); printf("Root D-Tree Node of inode %d\n\n", inode.di_number); printf("[1] DASDlimit\t%lld\n", (long long) DASDLIMIT(&(root->header.DASD))); printf("[2] DASDused\t%lld\n", (long long) DASDUSED(&(root->header.DASD))); printf("[3] thresh (%%)\t%d\n", root->header.DASD.thresh); printf("[4] delta (%%)\t%d\n", root->header.DASD.delta); printf("\n"); printf("[5] flag\t0x%02x\t\t%s\n", root->header.flag, flag_names); printf("[6] nextindex\t%d\n", root->header.nextindex); printf("[7] freecnt\t%d\n", root->header.freecnt); printf("[8] freelist\t%d\n", root->header.freelist); printf("[9] idotdot\t%d\n", root->header.idotdot); printf("[10] stbl\t{%d,%d,%d,%d,%d,%d,%d,%d}\n", root->header.stbl[0], root->header.stbl[1], root->header.stbl[2], root->header.stbl[3], root->header.stbl[4], root->header.stbl[5], root->header.stbl[6], root->header.stbl[7]); retry: if (root->header.nextindex) { fputs("dtree: Hit enter to see entries, [m]odify, or e[x]it: ", stdout); } else { fputs("dtree: [m]odify, or e[x]it: ", stdout); } fgets(cmd_line, 80, stdin); token = strtok(cmd_line, " \n"); if (token) { if (*token == 'x') return; if (*token == 'm') { field = m_parse(cmd_line, 9, &token); if (field == 0) goto retry; switch (field) { case 1: setDASDLIMIT(&(root->header.DASD), strtoll(token, 0, 0)); break; case 2: setDASDUSED(&(root->header.DASD), strtoll(token, 0, 0)); break; case 3: root->header.DASD.thresh = strtoul(token, 0, 0); break; case 4: root->header.DASD.delta = strtoul(token, 0, 0); break; case 5: root->header.flag = strtoul(token, 0, 16); break; case 6: root->header.nextindex = strtoul(token, 0, 0); break; case 7: root->header.freecnt = strtoul(token, 0, 0); break; case 8: root->header.freelist = strtoul(token, 0, 0); break; case 9: root->header.idotdot = strtoul(token, 0, 0); break; } /* swap if on big endian machine */ ujfs_swap_dinode(&inode, PUT, type_jfs); if (xWrite(inode_address, sizeof (struct dinode), (char *) &inode)) { fputs("dtree: error writing inode\n\n", stderr); /* swap back if on big endian machine */ ujfs_swap_dinode(&inode, GET, type_jfs); return; } /* swap back if on big endian machine */ ujfs_swap_dinode(&inode, GET, type_jfs); goto redisplay; } } if (root->header.nextindex == 0) return; if (root->header.flag & BT_LEAF) result = display_leaf_slots(root->slot, root->header.stbl, root->header.nextindex, &changed); else result = display_internal_slots(root->slot, root->header.stbl, root->header.nextindex, &changed); if (changed) { /* swap if on big endian machine */ ujfs_swap_dinode(&inode, PUT, type_jfs); if (xWrite(inode_address, sizeof (struct dinode), (char *) &inode)) { fputs("dtree: error writing inode\n\n", stderr); /* swap back if on big endian machine */ ujfs_swap_dinode(&inode, GET, type_jfs); return; } /* swap back if on big endian machine */ ujfs_swap_dinode(&inode, GET, type_jfs); changed = 0; } if (result == 'u') goto redisplay; return;}void xtree(){ int changed = 0; char cmd_line[80]; xtpage_t *xtree; int field; struct dinode inode; int64_t inode_address; unsigned inum; char result; char *token; unsigned which_table = FILESYSTEM_I; token = strtok(0, " \n"); if (token == 0) { fputs("xtree: Please enter: inum [fileset]\ndtree> ", stdout); fgets(cmd_line, 80, stdin); token = strtok(cmd_line, " \n"); if (token == 0) return; } errno = 0; inum = strtoul(token, 0, 0); if (inum == 0 && errno) { fputs("xtree: invalid inum\n\n", stderr); return; } token = strtok(0, " \n"); if (token) { if (token[0] == 'a') which_table = AGGREGATE_I; else if (token[0] == 's') which_table = AGGREGATE_2ND_I; else if (token[0] != '0') { fputs("inode: invalide fileset\n\n", stderr); return; } } if (strtok(0, " \n")) { fputs("xtree: Too many arguments\n\n", stderr); return; } if (find_inode(inum, which_table, &inode_address) || xRead(inode_address, sizeof (struct dinode), (char *) &inode)) { fputs("xtree: error reading inode\n\n", stderr); return; } /* swap if on big endian machine */ ujfs_swap_dinode(&inode, GET, type_jfs); if ((inode.di_mode & IFMT) == IFDIR) xtree = (xtpage_t *) & (inode.di_dirtable); else xtree = (xtpage_t *) & (inode.di_btroot); redisplay: printf("Root X-Tree Node of inode %d\n\n", inode.di_number); display_xtpage(xtree); retry: if (xtree->header.nextindex > 2) { fputs("xtree: Hit enter to see entries, [m]odify, or e[x]it: ", stdout); } else { fputs("xtree: [m]odify, or e[x]it: ", stdout); } fgets(cmd_line, 80, stdin); token = strtok(cmd_line, " \n"); if (token) { if (*token == 'x') return; if (*token == 'm') { field = m_parse(cmd_line, 6, &token); if (field == 0) goto retry; switch (field) { case 1: xtree->header.flag = strtoul(token, 0, 16); break; case 2: xtree->header.nextindex = strtoul(token, 0, 0); break; case 3: xtree->header.maxentry = strtoul(token, 0, 0); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -