void Ext4Extents::read_indexes(ext4_extents_header * header, uint8_t * block) { ext4_extents_index * idx; uint64_t addr; uint8_t * current_block; ext4_extents_header * current_header; if (!header) return ; if (header->magic != 0xF30A) return ; for (int i = 0; i < header->entries; ++i) { idx = (ext4_extents_index *)(block + i * sizeof(ext4_extents_index)); addr = concat_uint16_32(idx->next_level_high, idx->next_level_low) * ((uint64_t)__block_size); if (!(current_block = read_block(addr))) return ; current_header = (ext4_extents_header *)current_block; if (current_header->depth) read_indexes(current_header, current_block + sizeof(ext4_extents_header)); else read_extents(current_header, current_block + sizeof(ext4_extents_header)); delete current_block; } }
void Ext4Extents::push_extended_blocks(Inode * inode) throw (vfsError) { if (!inode) throw vfsError("Ext4Extents::push_extended_blocks() : inode is NULL."); __inode = inode; __size = inode->lower_size(); __block_size = inode->SB()->block_size(); __node = inode->extfs()->node(); __extfs = inode->extfs(); if (!inode->extent_header()->depth) read_extents(inode->extent_header(), (uint8_t *)&inode->block_pointers()[3]); else read_indexes(inode->extent_header(), (uint8_t *)&inode->block_pointers()[3]); }
int main(int argc, char **argv) { char *fname; unsigned char *buf; // EBLOCKSIZE FILE *infile; long i; off_t insize; int readlen; int skip; if (argc < 6) { fprintf(stderr, "%s: zblocksize hashname signed_file_name spec_file_name zdata_file_name [ #blocks ]\n", argv[0]); return EXIT_FAILURE; } if (argc == 7) eblocks = strtol(argv[6], 0, 0); zblocksize = strtol(argv[1], 0, 0); buf = malloc(zblocksize); LTC_ARGCHK(buf != 0); /* * For zlib compress, the destination buffer needs to be 1.001 x the * src buffer size plus 12 bytes */ zbufsize = ((zblocksize * 102) / 100) + 12; zbuf = malloc(zbufsize); LTC_ARGCHK(zbuf != 0); LTC_ARGCHK(register_hash(&sha256_desc) != -1); LTC_ARGCHK(register_hash(&rmd160_desc) != -1); LTC_ARGCHK(register_hash(&md5_desc) != -1); hashname = argv[2]; hashid = find_hash(hashname); LTC_ARGCHK(hashid >= 0); /* open filesystem image file */ infile = fopen(argv[3], "rb"); LTC_ARGCHK(infile != NULL); /* open output file */ outfile = fopen(argv[4], "wb"); LTC_ARGCHK(outfile != NULL); LTC_ARGCHK(fputs("[ifndef] #eblocks-written\n", outfile) >= 0); LTC_ARGCHK(fputs("[ifdef] last-eblock#\n", outfile) >= 0); LTC_ARGCHK(fputs(": pdup ( n -- n' ) dup last-eblock# max ;\n", outfile) >= 0); LTC_ARGCHK(fputs("also nand-commands patch pdup dup zblock: previous\n", outfile) >= 0); LTC_ARGCHK(fputs("[then]\n", outfile) >= 0); LTC_ARGCHK(fputs("[then]\n", outfile) >= 0); /* open zdata file */ zfile = fopen(argv[5], "wb"); LTC_ARGCHK(zfile != NULL); if (eblocks == -1) { (void)fseek(infile, 0L, SEEK_END); insize = ftello(infile); (void)fseek(infile, 0L, SEEK_SET); eblocks = (insize + zblocksize - 1) / zblocksize; // LTC_ARGCHK((eblocks * zblocksize) == insize); } eblocks = read_extents(infile) + 1; /* Remove possible path prefix */ fname = strrchr(argv[5], '/'); if (fname == NULL) fname = argv[5]; else ++fname; fprintf(outfile, "data: %s\n", fname); fprintf(outfile, "zblocks: %lx %lx\n", zblocksize, eblocks); fprintf(zfile, "zblocks: %lx %lx\n", zblocksize, eblocks); fprintf(stdout, "Total blocks: %ld\n", eblocks); /* wipe the partition table first in case of partial completion */ memset(buf, 0, zblocksize); write_block(0, buf); /* make a hash of the file */ for (i=1; i < eblocks; i++) { if (!eblocks_used[i]) continue; fseeko(infile, (uint64_t) i * zblocksize, SEEK_SET); readlen = read_block(buf, infile, i == eblocks-1); LTC_ARGCHK(readlen == zblocksize); write_block(i, buf); fprintf(stdout, "\r%ld", i); fflush(stdout); } fseek(infile, 0L, SEEK_SET); readlen = read_block(buf, infile, 0 == eblocks-1); LTC_ARGCHK(readlen == zblocksize); write_block(0, buf); fprintf(outfile, "zblocks-end:\n"); fprintf(zfile, "zblocks-end:\n"); fclose(infile); fclose(outfile); putchar('\n'); return EXIT_SUCCESS; }