diff options
Diffstat (limited to 'sumtool.c')
-rw-r--r-- | sumtool.c | 872 |
1 files changed, 0 insertions, 872 deletions
diff --git a/sumtool.c b/sumtool.c deleted file mode 100644 index 886b545..0000000 --- a/sumtool.c +++ /dev/null @@ -1,872 +0,0 @@ -/* - * sumtool.c - * - * Copyright (C) 2004 Zoltan Sogor <weth@inf.u-szeged.hu>, - * Ferenc Havasi <havasi@inf.u-szeged.hu> - * University of Szeged, Hungary - * 2006 KaiGai Kohei <kaigai@ak.jp.nec.com> - * - * 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. - * - * Overview: - * This is a utility insert summary information into JFFS2 image for - * faster mount time - * - */ - -#define PROGRAM_NAME "sumtool" - -#include <errno.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <asm/types.h> -#include <dirent.h> -#include <mtd/jffs2-user.h> -#include <endian.h> -#include <byteswap.h> -#include <getopt.h> -#include <crc32.h> -#include "summary.h" -#include "common.h" - -#define PAD(x) (((x)+3)&~3) - -static struct jffs2_summary *sum_collected = NULL; - -static int verbose = 0; -static int padto = 0; /* pad the output with 0xFF to the end of the final eraseblock */ -static int add_cleanmarkers = 1; /* add cleanmarker to output */ -static int use_input_cleanmarker_size = 1; /* use input file's cleanmarker size (default) */ -static int found_cleanmarkers = 0; /* cleanmarker found in input file */ -static struct jffs2_unknown_node cleanmarker; -static int cleanmarker_size = sizeof(cleanmarker); -static const char *short_options = "o:i:e:hvVblnc:p"; -static int erase_block_size = 65536; -static int out_fd = -1; -static int in_fd = -1; - -static uint8_t *data_buffer = NULL; /* buffer for inodes */ -static unsigned int data_ofs = 0; /* inode buffer offset */ - -static uint8_t *file_buffer = NULL; /* file buffer contains the actual erase block*/ -static unsigned int file_ofs = 0; /* position in the buffer */ - -int target_endian = __BYTE_ORDER; - -static struct option long_options[] = { - {"output", 1, NULL, 'o'}, - {"input", 1, NULL, 'i'}, - {"eraseblock", 1, NULL, 'e'}, - {"help", 0, NULL, 'h'}, - {"verbose", 0, NULL, 'v'}, - {"version", 0, NULL, 'V'}, - {"bigendian", 0, NULL, 'b'}, - {"littleendian", 0, NULL, 'l'}, - {"no-cleanmarkers", 0, NULL, 'n'}, - {"cleanmarker", 1, NULL, 'c'}, - {"pad", 0, NULL, 'p'}, - {NULL, 0, NULL, 0} -}; - -static const char helptext[] = -"Usage: sumtool [OPTIONS] -i inputfile -o outputfile\n\n" -"Convert the input JFFS2 image to a summarized JFFS2 image\n" -"Summary makes mounting faster - if summary support enabled in your kernel\n\n" -"Options:\n" -" -e, --eraseblock=SIZE Use erase block size SIZE (default: 64KiB)\n" -" (usually 16KiB on NAND)\n" -" -c, --cleanmarker=SIZE Size of cleanmarker (default 12).\n" -" (usually 16 bytes on NAND, and will be set to\n" -" this value if left at the default 12). Will be\n" -" stored in OOB after each physical page composing\n" -" a physical eraseblock.\n" -" -n, --no-cleanmarkers Don't add a cleanmarker to every eraseblock\n" -" -o, --output=FILE Output to FILE \n" -" -i, --input=FILE Input from FILE \n" -" -b, --bigendian Image is big endian\n" -" -l --littleendian Image is little endian\n" -" -h, --help Display this help text\n" -" -v, --verbose Verbose operation\n" -" -V, --version Display version information\n" -" -p, --pad Pad the OUTPUT with 0xFF to the end of the final\n" -" eraseblock\n\n"; - - -static const char revtext[] = "$Revision: 1.9 $"; - -static unsigned char ffbuf[16] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; - -static void full_write(void *target_buff, const void *buf, int len); - -void setup_cleanmarker(void) -{ - cleanmarker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - cleanmarker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER); - cleanmarker.totlen = cpu_to_je32(cleanmarker_size); - cleanmarker.hdr_crc = cpu_to_je32(mtd_crc32(0, &cleanmarker, sizeof(struct jffs2_unknown_node)-4)); -} - -void process_options (int argc, char **argv) -{ - int opt,c; - - while ((opt = getopt_long(argc, argv, short_options, long_options, &c)) >= 0) { - switch (opt) { - case 'o': - if (out_fd != -1) - errmsg_die("output filename specified more than once"); - out_fd = open(optarg, O_CREAT | O_TRUNC | O_RDWR, 0644); - if (out_fd == -1) - sys_errmsg_die("open output file"); - break; - - case 'i': - if (in_fd != -1) - errmsg_die("input filename specified more than once"); - in_fd = open(optarg, O_RDONLY); - if (in_fd == -1) - sys_errmsg_die("open input file"); - break; - case 'b': - target_endian = __BIG_ENDIAN; - break; - case 'l': - target_endian = __LITTLE_ENDIAN; - break; - case 'h': - case '?': - errmsg_die("%s", helptext); - case 'v': - verbose = 1; - break; - - case 'V': - errmsg_die("revision %.*s\n", - (int) strlen(revtext) - 13, revtext + 11); - - case 'e': { - char *next; - unsigned units = 0; - erase_block_size = strtol(optarg, &next, 0); - if (!erase_block_size) - errmsg_die("Unrecognisable erase size\n"); - - if (*next) { - if (!strcmp(next, "KiB")) { - units = 1024; - } else if (!strcmp(next, "MiB")) { - units = 1024 * 1024; - } else { - errmsg_die("Unknown units in erasesize\n"); - } - } else { - if (erase_block_size < 0x1000) - units = 1024; - else - units = 1; - } - erase_block_size *= units; - - /* If it's less than 8KiB, they're not allowed */ - if (erase_block_size < 0x2000) { - warnmsg("Erase size 0x%x too small. Increasing to 8KiB minimum\n", - erase_block_size); - erase_block_size = 0x2000; - } - break; - } - - case 'n': - add_cleanmarkers = 0; - break; - case 'c': - cleanmarker_size = strtol(optarg, NULL, 0); - - if (cleanmarker_size < sizeof(cleanmarker)) { - errmsg_die("cleanmarker size must be >= 12"); - } - if (cleanmarker_size >= erase_block_size) { - errmsg_die("cleanmarker size must be < eraseblock size"); - } - - use_input_cleanmarker_size = 0; - found_cleanmarkers = 1; - setup_cleanmarker(); - - break; - case 'p': - padto = 1; - break; - } - } -} - - -void init_buffers(void) -{ - data_buffer = xmalloc(erase_block_size); - file_buffer = xmalloc(erase_block_size); -} - -void init_sumlist(void) -{ - sum_collected = xzalloc(sizeof(*sum_collected)); -} - -void clean_buffers(void) -{ - free(data_buffer); - free(file_buffer); -} - -void clean_sumlist(void) -{ - union jffs2_sum_mem *temp; - - if (sum_collected) { - - while (sum_collected->sum_list_head) { - temp = sum_collected->sum_list_head; - sum_collected->sum_list_head = sum_collected->sum_list_head->u.next; - free(temp); - sum_collected->sum_num--; - } - - if (sum_collected->sum_num != 0) - warnmsg("Ooops, something wrong happened! sum_num != 0, but sum_list = null ???"); - - free(sum_collected); - } -} - -int load_next_block(void) -{ - int ret; - ret = read(in_fd, file_buffer, erase_block_size); - file_ofs = 0; - - bareverbose(verbose, "Load next block : %d bytes read\n", ret); - - return ret; -} - -void write_buff_to_file(void) -{ - int ret; - int len = data_ofs; - - uint8_t *buf = NULL; - - buf = data_buffer; - while (len > 0) { - ret = write(out_fd, buf, len); - - if (ret < 0) - sys_errmsg_die("write"); - - if (ret == 0) - sys_errmsg_die("write returned zero"); - - len -= ret; - buf += ret; - } - - data_ofs = 0; -} - -void dump_sum_records(void) -{ - - struct jffs2_raw_summary isum; - struct jffs2_sum_marker *sm; - union jffs2_sum_mem *temp; - jint32_t offset; - jint32_t *tpage; - void *wpage; - int datasize, infosize, padsize; - jint32_t magic = cpu_to_je32(JFFS2_SUM_MAGIC); - - if (!sum_collected->sum_num || !sum_collected->sum_list_head) - return; - - datasize = sum_collected->sum_size + sizeof(struct jffs2_sum_marker); - infosize = sizeof(struct jffs2_raw_summary) + datasize; - padsize = erase_block_size - data_ofs - infosize; - infosize += padsize; datasize += padsize; - offset = cpu_to_je32(data_ofs); - - tpage = xmalloc(datasize); - - memset(tpage, 0xff, datasize); - memset(&isum, 0, sizeof(isum)); - - isum.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - isum.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY); - isum.totlen = cpu_to_je32(infosize); - isum.hdr_crc = cpu_to_je32(mtd_crc32(0, &isum, sizeof(struct jffs2_unknown_node) - 4)); - isum.padded = cpu_to_je32(0); - - if (add_cleanmarkers && found_cleanmarkers) { - isum.cln_mkr = cpu_to_je32(cleanmarker_size); - } else { - isum.cln_mkr = cpu_to_je32(0); - } - - isum.sum_num = cpu_to_je32(sum_collected->sum_num); - wpage = tpage; - - while (sum_collected->sum_num) { - switch(je16_to_cpu(sum_collected->sum_list_head->u.nodetype)) { - - case JFFS2_NODETYPE_INODE : { - struct jffs2_sum_inode_flash *sino_ptr = wpage; - - sino_ptr->nodetype = sum_collected->sum_list_head->i.nodetype; - sino_ptr->inode = sum_collected->sum_list_head->i.inode; - sino_ptr->version = sum_collected->sum_list_head->i.version; - sino_ptr->offset = sum_collected->sum_list_head->i.offset; - sino_ptr->totlen = sum_collected->sum_list_head->i.totlen; - - wpage += JFFS2_SUMMARY_INODE_SIZE; - break; - } - - case JFFS2_NODETYPE_DIRENT : { - struct jffs2_sum_dirent_flash *sdrnt_ptr = wpage; - - sdrnt_ptr->nodetype = sum_collected->sum_list_head->d.nodetype; - sdrnt_ptr->totlen = sum_collected->sum_list_head->d.totlen; - sdrnt_ptr->offset = sum_collected->sum_list_head->d.offset; - sdrnt_ptr->pino = sum_collected->sum_list_head->d.pino; - sdrnt_ptr->version = sum_collected->sum_list_head->d.version; - sdrnt_ptr->ino = sum_collected->sum_list_head->d.ino; - sdrnt_ptr->nsize = sum_collected->sum_list_head->d.nsize; - sdrnt_ptr->type = sum_collected->sum_list_head->d.type; - - memcpy(sdrnt_ptr->name, sum_collected->sum_list_head->d.name, - sum_collected->sum_list_head->d.nsize); - - wpage += JFFS2_SUMMARY_DIRENT_SIZE(sum_collected->sum_list_head->d.nsize); - break; - } - - case JFFS2_NODETYPE_XATTR: { - struct jffs2_sum_xattr_flash *sxattr_ptr = wpage; - - sxattr_ptr->nodetype = sum_collected->sum_list_head->x.nodetype; - sxattr_ptr->xid = sum_collected->sum_list_head->x.xid; - sxattr_ptr->version = sum_collected->sum_list_head->x.version; - sxattr_ptr->offset = sum_collected->sum_list_head->x.offset; - sxattr_ptr->totlen = sum_collected->sum_list_head->x.totlen; - - wpage += JFFS2_SUMMARY_XATTR_SIZE; - break; - } - - case JFFS2_NODETYPE_XREF: { - struct jffs2_sum_xref_flash *sxref_ptr = wpage; - - sxref_ptr->nodetype = sum_collected->sum_list_head->r.nodetype; - sxref_ptr->offset = sum_collected->sum_list_head->r.offset; - - wpage += JFFS2_SUMMARY_XREF_SIZE; - break; - } - - default : { - warnmsg("Unknown node type!\n"); - } - } - - temp = sum_collected->sum_list_head; - sum_collected->sum_list_head = sum_collected->sum_list_head->u.next; - free(temp); - - sum_collected->sum_num--; - } - - sum_collected->sum_size = 0; - sum_collected->sum_num = 0; - sum_collected->sum_list_tail = NULL; - - wpage += padsize; - - sm = wpage; - sm->offset = offset; - sm->magic = magic; - - isum.sum_crc = cpu_to_je32(mtd_crc32(0, tpage, datasize)); - isum.node_crc = cpu_to_je32(mtd_crc32(0, &isum, sizeof(isum) - 8)); - - full_write(data_buffer + data_ofs, &isum, sizeof(isum)); - full_write(data_buffer + data_ofs, tpage, datasize); - - free(tpage); -} - -static void full_write(void *target_buff, const void *buf, int len) -{ - memcpy(target_buff, buf, len); - data_ofs += len; -} - -static void pad(int req) -{ - while (req) { - if (req > sizeof(ffbuf)) { - full_write(data_buffer + data_ofs, ffbuf, sizeof(ffbuf)); - req -= sizeof(ffbuf); - } else { - full_write(data_buffer + data_ofs, ffbuf, req); - req = 0; - } - } -} - -static inline void padword(void) -{ - if (data_ofs % 4) - full_write(data_buffer + data_ofs, ffbuf, 4 - (data_ofs % 4)); -} - - -static inline void pad_block_if_less_than(int req,int plus) -{ - - int datasize = req + plus + sum_collected->sum_size + sizeof(struct jffs2_raw_summary) + 8; - datasize += (4 - (datasize % 4)) % 4; - - if (data_ofs + req > erase_block_size - datasize) { - dump_sum_records(); - write_buff_to_file(); - } - - if (add_cleanmarkers && found_cleanmarkers) { - if (!data_ofs) { - full_write(data_buffer, &cleanmarker, sizeof(cleanmarker)); - pad(cleanmarker_size - sizeof(cleanmarker)); - padword(); - } - } -} - -void flush_buffers(void) -{ - - if ((add_cleanmarkers == 1) && (found_cleanmarkers == 1)) { /* CLEANMARKER */ - if (data_ofs != cleanmarker_size) { /* INODE BUFFER */ - - int datasize = sum_collected->sum_size + sizeof(struct jffs2_raw_summary) + 8; - datasize += (4 - (datasize % 4)) % 4; - - /* If we have a full inode buffer, then write out inode and summary data */ - if (data_ofs + sizeof(struct jffs2_raw_inode) + 2*JFFS2_MIN_DATA_LEN > erase_block_size - datasize) { - dump_sum_records(); - write_buff_to_file(); - } else { /* else just write out inode data */ - if (padto) - pad(erase_block_size - data_ofs); - write_buff_to_file(); - } - } - } else { /* NO CLEANMARKER */ - if (data_ofs != 0) { /* INODE BUFFER */ - - int datasize = sum_collected->sum_size + sizeof(struct jffs2_raw_summary) + 8; - datasize += (4 - (datasize % 4)) % 4; - - /* If we have a full inode buffer, then write out inode and summary data */ - if (data_ofs + sizeof(struct jffs2_raw_inode) + 2*JFFS2_MIN_DATA_LEN > erase_block_size - datasize) { - dump_sum_records(); - write_buff_to_file(); - } else { /* Else just write out inode data */ - if(padto) - pad(erase_block_size - data_ofs); - write_buff_to_file(); - } - } - } -} - -int add_sum_mem(union jffs2_sum_mem *item) -{ - - if (!sum_collected->sum_list_head) - sum_collected->sum_list_head = (union jffs2_sum_mem *) item; - if (sum_collected->sum_list_tail) - sum_collected->sum_list_tail->u.next = (union jffs2_sum_mem *) item; - sum_collected->sum_list_tail = (union jffs2_sum_mem *) item; - - switch (je16_to_cpu(item->u.nodetype)) { - case JFFS2_NODETYPE_INODE: - sum_collected->sum_size += JFFS2_SUMMARY_INODE_SIZE; - sum_collected->sum_num++; - break; - - case JFFS2_NODETYPE_DIRENT: - sum_collected->sum_size += JFFS2_SUMMARY_DIRENT_SIZE(item->d.nsize); - sum_collected->sum_num++; - break; - - case JFFS2_NODETYPE_XATTR: - sum_collected->sum_size += JFFS2_SUMMARY_XATTR_SIZE; - sum_collected->sum_num++; - break; - - case JFFS2_NODETYPE_XREF: - sum_collected->sum_size += JFFS2_SUMMARY_XREF_SIZE; - sum_collected->sum_num++; - break; - - default: - errmsg_die("__jffs2_add_sum_mem(): UNKNOWN node type %d\n", je16_to_cpu(item->u.nodetype)); - } - return 0; -} - -void add_sum_inode_mem(union jffs2_node_union *node) -{ - struct jffs2_sum_inode_mem *temp = xmalloc(sizeof(*temp)); - - temp->nodetype = node->i.nodetype; - temp->inode = node->i.ino; - temp->version = node->i.version; - temp->offset = cpu_to_je32(data_ofs); - temp->totlen = node->i.totlen; - temp->next = NULL; - - add_sum_mem((union jffs2_sum_mem *) temp); -} - -void add_sum_dirent_mem(union jffs2_node_union *node) -{ - struct jffs2_sum_dirent_mem *temp = xmalloc(sizeof(*temp) + node->d.nsize); - - temp->nodetype = node->d.nodetype; - temp->totlen = node->d.totlen; - temp->offset = cpu_to_je32(data_ofs); - temp->pino = node->d.pino; - temp->version = node->d.version; - temp->ino = node->d.ino; - temp->nsize = node->d.nsize; - temp->type = node->d.type; - temp->next = NULL; - - memcpy(temp->name,node->d.name,node->d.nsize); - add_sum_mem((union jffs2_sum_mem *) temp); -} - -void add_sum_xattr_mem(union jffs2_node_union *node) -{ - struct jffs2_sum_xattr_mem *temp = xmalloc(sizeof(*temp)); - - temp->nodetype = node->x.nodetype; - temp->xid = node->x.xid; - temp->version = node->x.version; - temp->offset = cpu_to_je32(data_ofs); - temp->totlen = node->x.totlen; - temp->next = NULL; - - add_sum_mem((union jffs2_sum_mem *) temp); -} - -void add_sum_xref_mem(union jffs2_node_union *node) -{ - struct jffs2_sum_xref_mem *temp = xmalloc(sizeof(*temp)); - - temp->nodetype = node->r.nodetype; - temp->offset = cpu_to_je32(data_ofs); - temp->next = NULL; - - add_sum_mem((union jffs2_sum_mem *) temp); -} - -void write_dirent_to_buff(union jffs2_node_union *node) -{ - pad_block_if_less_than(je32_to_cpu (node->d.totlen),JFFS2_SUMMARY_DIRENT_SIZE(node->d.nsize)); - add_sum_dirent_mem(node); - full_write(data_buffer + data_ofs, &(node->d), je32_to_cpu (node->d.totlen)); - padword(); -} - - -void write_inode_to_buff(union jffs2_node_union *node) -{ - pad_block_if_less_than(je32_to_cpu (node->i.totlen),JFFS2_SUMMARY_INODE_SIZE); - add_sum_inode_mem(node); /* Add inode summary mem to summary list */ - full_write(data_buffer + data_ofs, &(node->i), je32_to_cpu (node->i.totlen)); /* Write out the inode to inode_buffer */ - padword(); -} - -void write_xattr_to_buff(union jffs2_node_union *node) -{ - pad_block_if_less_than(je32_to_cpu(node->x.totlen), JFFS2_SUMMARY_XATTR_SIZE); - add_sum_xattr_mem(node); /* Add xdatum summary mem to summary list */ - full_write(data_buffer + data_ofs, &(node->x), je32_to_cpu(node->x.totlen)); - padword(); -} - -void write_xref_to_buff(union jffs2_node_union *node) -{ - pad_block_if_less_than(je32_to_cpu(node->r.totlen), JFFS2_SUMMARY_XREF_SIZE); - add_sum_xref_mem(node); /* Add xref summary mem to summary list */ - full_write(data_buffer + data_ofs, &(node->r), je32_to_cpu(node->r.totlen)); - padword(); -} - -void create_summed_image(int inp_size) -{ - uint8_t *p = file_buffer; - union jffs2_node_union *node; - uint32_t crc, length; - uint16_t type; - int bitchbitmask = 0; - int obsolete; - char name[256]; - - while ( p < (file_buffer + inp_size)) { - - node = (union jffs2_node_union *) p; - - /* Skip empty space */ - if (je16_to_cpu (node->u.magic) == 0xFFFF && je16_to_cpu (node->u.nodetype) == 0xFFFF) { - p += 4; - continue; - } - - if (je16_to_cpu (node->u.magic) != JFFS2_MAGIC_BITMASK) { - if (!bitchbitmask++) - warnmsg("Wrong bitmask at 0x%08zx, 0x%04x\n", - p - file_buffer, je16_to_cpu (node->u.magic)); - p += 4; - continue; - } - - bitchbitmask = 0; - - type = je16_to_cpu(node->u.nodetype); - if ((type & JFFS2_NODE_ACCURATE) != JFFS2_NODE_ACCURATE) { - obsolete = 1; - type |= JFFS2_NODE_ACCURATE; - } else { - obsolete = 0; - } - - node->u.nodetype = cpu_to_je16(type); - - crc = mtd_crc32 (0, node, sizeof (struct jffs2_unknown_node) - 4); - if (crc != je32_to_cpu (node->u.hdr_crc)) { - warnmsg("Wrong hdr_crc at 0x%08zx, 0x%08x instead of 0x%08x\n", - p - file_buffer, je32_to_cpu (node->u.hdr_crc), crc); - p += 4; - continue; - } - - switch(je16_to_cpu(node->u.nodetype)) { - case JFFS2_NODETYPE_INODE: - bareverbose(verbose, - "%8s Inode node at 0x%08zx, totlen 0x%08x, #ino %5d, version %5d, isize %8d, csize %8d, dsize %8d, offset %8d\n", - obsolete ? "Obsolete" : "", - p - file_buffer, je32_to_cpu (node->i.totlen), je32_to_cpu (node->i.ino), - je32_to_cpu (node->i.version), je32_to_cpu (node->i.isize), - je32_to_cpu (node->i.csize), je32_to_cpu (node->i.dsize), je32_to_cpu (node->i.offset)); - - crc = mtd_crc32 (0, node, sizeof (struct jffs2_raw_inode) - 8); - if (crc != je32_to_cpu (node->i.node_crc)) { - warnmsg("Wrong node_crc at 0x%08zx, 0x%08x instead of 0x%08x\n", - p - file_buffer, je32_to_cpu (node->i.node_crc), crc); - p += PAD(je32_to_cpu (node->i.totlen)); - continue; - } - - crc = mtd_crc32(0, p + sizeof (struct jffs2_raw_inode), je32_to_cpu(node->i.csize)); - if (crc != je32_to_cpu(node->i.data_crc)) { - warnmsg("Wrong data_crc at 0x%08zx, 0x%08x instead of 0x%08x\n", - p - file_buffer, je32_to_cpu (node->i.data_crc), crc); - p += PAD(je32_to_cpu (node->i.totlen)); - continue; - } - - write_inode_to_buff(node); - - p += PAD(je32_to_cpu (node->i.totlen)); - break; - - case JFFS2_NODETYPE_DIRENT: - memcpy (name, node->d.name, node->d.nsize); - name [node->d.nsize] = 0x0; - - bareverbose(verbose, - "%8s Dirent node at 0x%08zx, totlen 0x%08x, #pino %5d, version %5d, #ino %8d, nsize %8d, name %s\n", - obsolete ? "Obsolete" : "", - p - file_buffer, je32_to_cpu (node->d.totlen), je32_to_cpu (node->d.pino), - je32_to_cpu (node->d.version), je32_to_cpu (node->d.ino), - node->d.nsize, name); - - crc = mtd_crc32 (0, node, sizeof (struct jffs2_raw_dirent) - 8); - if (crc != je32_to_cpu (node->d.node_crc)) { - warnmsg("Wrong node_crc at 0x%08zx, 0x%08x instead of 0x%08x\n", - p - file_buffer, je32_to_cpu (node->d.node_crc), crc); - p += PAD(je32_to_cpu (node->d.totlen)); - continue; - } - - crc = mtd_crc32(0, p + sizeof (struct jffs2_raw_dirent), node->d.nsize); - if (crc != je32_to_cpu(node->d.name_crc)) { - warnmsg("Wrong name_crc at 0x%08zx, 0x%08x instead of 0x%08x\n", - p - file_buffer, je32_to_cpu (node->d.name_crc), crc); - p += PAD(je32_to_cpu (node->d.totlen)); - continue; - } - - write_dirent_to_buff(node); - - p += PAD(je32_to_cpu (node->d.totlen)); - break; - - case JFFS2_NODETYPE_XATTR: - if (je32_to_cpu(node->x.node_crc) == 0xffffffff) - obsolete = 1; - bareverbose(verbose, - "%8s Xdatum node at 0x%08zx, totlen 0x%08x, #xid %5u, version %5u\n", - obsolete ? "Obsolete" : "", - p - file_buffer, je32_to_cpu (node->x.totlen), - je32_to_cpu(node->x.xid), je32_to_cpu(node->x.version)); - crc = mtd_crc32(0, node, sizeof (struct jffs2_raw_xattr) - 4); - if (crc != je32_to_cpu(node->x.node_crc)) { - warnmsg("Wrong node_crc at 0x%08zx, 0x%08x instead of 0x%08x\n", - p - file_buffer, je32_to_cpu(node->x.node_crc), crc); - p += PAD(je32_to_cpu (node->x.totlen)); - continue; - } - length = node->x.name_len + 1 + je16_to_cpu(node->x.value_len); - crc = mtd_crc32(0, node->x.data, length); - if (crc != je32_to_cpu(node->x.data_crc)) { - warnmsg("Wrong data_crc at 0x%08zx, 0x%08x instead of 0x%08x\n", - p - file_buffer, je32_to_cpu(node->x.data_crc), crc); - p += PAD(je32_to_cpu (node->x.totlen)); - continue; - } - - write_xattr_to_buff(node); - p += PAD(je32_to_cpu (node->x.totlen)); - break; - - case JFFS2_NODETYPE_XREF: - if (je32_to_cpu(node->r.node_crc) == 0xffffffff) - obsolete = 1; - bareverbose(verbose, - "%8s Xref node at 0x%08zx, totlen 0x%08x, #ino %5u, xid %5u\n", - obsolete ? "Obsolete" : "", - p - file_buffer, je32_to_cpu(node->r.totlen), - je32_to_cpu(node->r.ino), je32_to_cpu(node->r.xid)); - crc = mtd_crc32(0, node, sizeof (struct jffs2_raw_xref) - 4); - if (crc != je32_to_cpu(node->r.node_crc)) { - warnmsg("Wrong node_crc at 0x%08zx, 0x%08x instead of 0x%08x\n", - p - file_buffer, je32_to_cpu(node->r.node_crc), crc); - p += PAD(je32_to_cpu (node->r.totlen)); - continue; - } - - write_xref_to_buff(node); - p += PAD(je32_to_cpu (node->r.totlen)); - break; - - case JFFS2_NODETYPE_CLEANMARKER: - bareverbose(verbose, - "%8s Cleanmarker at 0x%08zx, totlen 0x%08x\n", - obsolete ? "Obsolete" : "", - p - file_buffer, je32_to_cpu (node->u.totlen)); - - if (!found_cleanmarkers) { - found_cleanmarkers = 1; - - if (add_cleanmarkers == 1 && use_input_cleanmarker_size == 1){ - cleanmarker_size = je32_to_cpu (node->u.totlen); - setup_cleanmarker(); - } - } - - p += PAD(je32_to_cpu (node->u.totlen)); - break; - - case JFFS2_NODETYPE_PADDING: - bareverbose(verbose, - "%8s Padding node at 0x%08zx, totlen 0x%08x\n", - obsolete ? "Obsolete" : "", - p - file_buffer, je32_to_cpu (node->u.totlen)); - p += PAD(je32_to_cpu (node->u.totlen)); - break; - - case 0xffff: - p += 4; - break; - - default: - bareverbose(verbose, - "%8s Unknown node at 0x%08zx, totlen 0x%08x\n", - obsolete ? "Obsolete" : "", - p - file_buffer, je32_to_cpu (node->u.totlen)); - - p += PAD(je32_to_cpu (node->u.totlen)); - } - } -} - -int main(int argc, char **argv) -{ - int ret; - - process_options(argc,argv); - - if ((in_fd == -1) || (out_fd == -1)) { - if(in_fd != -1) - close(in_fd); - if(out_fd != -1) - close(out_fd); - fprintf(stderr, "%s", helptext); - errmsg_die("You must specify input and output files!\n"); - } - - init_buffers(); - init_sumlist(); - - while ((ret = load_next_block())) { - create_summed_image(ret); - } - - flush_buffers(); - clean_buffers(); - clean_sumlist(); - - if (in_fd != -1) - close(in_fd); - if (out_fd != -1) - close(out_fd); - - return 0; -} |