📄 unpack.c
字号:
/* * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ #include "debugreiserfs.h"#include <sys/resource.h>#define print_usage_and_exit() die ("Usage: %s [-v] [-b filename] device\n\-v prints blocks number of every block unpacked\n\-b filename saves bitmap of blocks unpacked to filename\n\-j filename stores journal in the filename\n", argv[0]);/* when super block gets unpacked for the first time - create a bitmap and mark in it what have been unpacked. Save that bitmap at the end */reiserfs_bitmap_t * what_unpacked = 0;int leaves, full;int verbose = 0;int Default_journal = 1;static void unpack_offset (struct packed_item * pi, struct item_head * ih, int blocksize){ if (get_pi_mask(pi) & OFFSET_BITS_64) { __u64 v64; if (get_ih_key_format (ih) != KEY_FORMAT_2) die ("unpack_offset: key format is not set or wrong"); fread_le64 (&v64); set_offset (KEY_FORMAT_2, &ih->ih_key, v64); return; } if (get_pi_mask(pi) & OFFSET_BITS_32) { __u32 v32; fread_le32 (&v32); set_offset (get_ih_key_format (ih), &ih->ih_key, v32); return; } if ((get_pi_mask(pi) & DIR_ID) == 0 && (get_pi_mask(pi) & OBJECT_ID) == 0) { /* offset was not sent, as it can be calculated looking at the previous item */ if (is_stat_data_ih (ih - 1)) set_offset (get_ih_key_format (ih), &ih->ih_key, 1); if (is_indirect_ih (ih - 1)) set_offset (get_ih_key_format (ih), &ih->ih_key, get_offset (&(ih - 1)->ih_key) + get_bytes_number (ih - 1, blocksize)); } // offset is 0 return;}static void unpack_type (struct packed_item * pi, struct item_head * ih){ set_type (get_ih_key_format (ih), &ih->ih_key, get_pi_type(pi)); if (type_unknown (&ih->ih_key)) reiserfs_panic ("unpack_type: unknown type %d unpacked for %H\n", get_pi_type(pi), ih);}/* direntry item comes in the following format: for each entry mask - 8 bits entry length - 16 bits entry itself deh_objectid - 32 bits maybe deh_dir_id (32 bits) maybe gencounter (16) maybe deh_state (16)*/static void unpack_direntry (struct packed_item * pi, struct buffer_head * bh, struct item_head * ih, hashf_t hash_func){ __u16 entry_count, namelen, gen_counter, entry_len; __u8 mask; int i; struct reiserfs_de_head * deh; int location; char * item;/* if (!hash_func) die ("unpack_direntry: hash function is not set");*/ if (!(get_pi_mask(pi) & IH_FREE_SPACE)) die ("ih_entry_count must be packed for directory items"); entry_count = get_ih_entry_count (ih);/* if (!entry_count) reiserfs_panic ("unpack_direntry: entry count should be set already");*/ item = bh->b_data + get_ih_location (ih); deh = (struct reiserfs_de_head *)item; location = get_pi_item_len(pi); for (i = 0; i < entry_count; i ++, deh ++) { fread8 (&mask); fread_le16 (&entry_len); location -= entry_len; set_deh_location (deh, location); fread (item + location, entry_len, 1, stdin); /* find name length */ if (*(item + location + entry_len - 1)) namelen = entry_len; else namelen = strlen (item + location); fread32 (&deh->deh2_objectid); if (mask & HAS_DIR_ID) fread32 (&deh->deh2_dir_id); else set_deh_dirid (deh, get_key_objectid (&ih->ih_key)); if (*(item + location) == '.' && namelen == 1) /* old or new "." */ set_deh_offset (deh, DOT_OFFSET); else if (*(item + location) == '.' && *(item + location + 1) == '.' && namelen == 2) /* old or new ".." */ set_deh_offset (deh, DOT_DOT_OFFSET); else if (hash_func) set_deh_offset (deh, hash_value(hash_func, item + location, namelen)); if (mask & HAS_GEN_COUNTER) { fread_le16 (&gen_counter); set_deh_offset (deh, get_deh_offset (deh) | gen_counter); } if (mask & HAS_STATE) fread16 (&deh->deh2_state); else set_deh_state (deh, (1 << DEH_Visible2)); } return;}/* struct packed_item is already unpacked */static void unpack_stat_data (struct packed_item * pi, struct buffer_head * bh, struct item_head * ih){ if (!(get_pi_mask(pi) & IH_FREE_SPACE)) { /* ih_free_space was not packed - set default */ set_ih_entry_count (ih, 0xffff); } if (get_ih_key_format (ih) == KEY_FORMAT_1) { /* stat data comes in the following format: if this is old stat data: mode - 16 bits nlink - 16 bits size - 32 bits blocks/rdev - 32 bits maybe first_direct byte 32 bits */ struct stat_data_v1 * sd; sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih); memset (sd, 0, sizeof (sd)); fread16 (&sd->sd_mode); fread16 (&sd->sd_nlink); fread32 (&sd->sd_size); fread32 (&sd->u.sd_blocks); if (get_pi_mask(pi) & WITH_SD_FIRST_DIRECT_BYTE) { fread32 (&sd->sd_first_direct_byte); } else { sd->sd_first_direct_byte = 0xffffffff; } } else { /* for new stat data mode - 16 bits nlink in either 16 or 32 bits size in either 32 or 64 bits blocks - 32 bits */ struct stat_data * sd; sd = (struct stat_data *)B_I_PITEM (bh, ih); memset (sd, 0, sizeof (sd)); fread16 (&sd->sd_mode); if (get_pi_mask(pi) & NLINK_BITS_32) { fread32 (&sd->sd_nlink); } else { __u16 nlink16; fread16 (&nlink16); set_sd_v2_nlink (sd, le16_to_cpu(nlink16)); } if (get_pi_mask(pi) & SIZE_BITS_64) { fread64 (&sd->sd_size); } else { __u32 size32; /* We need the endian conversions since sd->sd_size is 64 bit */ fread_le32 (&size32); set_sd_v2_size (sd, size32 ); } fread32 (&sd->sd_blocks); } return;}/* indirect item comes either in packed form or as is. ih_free_space can go first */static void unpack_indirect (struct packed_item * pi, struct buffer_head * bh, struct item_head * ih){ __u32 * ind_item, * end; int i; __u16 v16; if (!(get_pi_mask(pi) & IH_FREE_SPACE)) { /* ih_free_space was not packed - set default */ set_ih_entry_count (ih, 0); } ind_item = (__u32 *)B_I_PITEM (bh, ih); if (get_pi_mask(pi) & SAFE_LINK) { d32_put(ind_item, 0, get_key_dirid(&ih->ih_key)); set_key_dirid(&ih->ih_key, (__u32)-1); return; } if (get_pi_mask(pi) & WHOLE_INDIRECT) { fread (ind_item, get_pi_item_len(pi), 1, stdin); return; } end = ind_item + I_UNFM_NUM (ih); while (ind_item < end) { __u32 base; fread32 (ind_item); fread_le16 (&v16); base = d32_get(ind_item, 0); for (i = 1; i < v16; i ++) { if (base != 0) d32_put(ind_item, i, base + i); else d32_put(ind_item, i, 0); } ind_item += i; } return;}// FIXME: we have no way to preserve symlinksstatic void unpack_direct (struct packed_item * pi, struct buffer_head * bh, struct item_head * ih){ __u32 * d_item = (__u32 *)B_I_PITEM (bh, ih); if (!(get_pi_mask(pi) & IH_FREE_SPACE)) /* ih_free_space was not packed - set default */ set_ih_entry_count (ih, 0xffff); if (get_pi_mask(pi) & SAFE_LINK) { d32_put(d_item, 0, get_key_dirid(&ih->ih_key)); set_key_dirid(&ih->ih_key, (__u32)-1); } else { memset (d_item, 'a', get_pi_item_len(pi)); } return;}static void unpack_leaf (int dev, hashf_t hash_func, __u16 blocksize){ static int unpacked_leaves = 0; struct buffer_head * bh; struct packed_item pi; struct item_head * ih; int i; __u16 v16; __u32 v32; /* block number */ fread_le32 (&v32); /* item number */ fread_le16 (&v16); if (verbose) reiserfs_warning (stderr, "leaf %d: %d items\n", v32, v16); bh = getblk (dev, v32, blocksize); if (!bh) die ("unpack_leaf: getblk failed"); set_blkh_nr_items (B_BLK_HEAD (bh), v16); set_blkh_level (B_BLK_HEAD (bh), DISK_LEAF_NODE_LEVEL); set_blkh_free_space (B_BLK_HEAD (bh), MAX_FREE_SPACE (bh->b_size)); ih = B_N_PITEM_HEAD (bh, 0); for (i = 0; i < get_blkh_nr_items (B_BLK_HEAD (bh)); i ++, ih ++) {#if 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -