diff options
-rw-r--r-- | jffsX-utils/jffs-dump.c | 359 |
1 files changed, 0 insertions, 359 deletions
diff --git a/jffsX-utils/jffs-dump.c b/jffsX-utils/jffs-dump.c deleted file mode 100644 index 3176469..0000000 --- a/jffsX-utils/jffs-dump.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Dump JFFS filesystem. - * Useful when it buggers up. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#include <unistd.h> -#include <linux/types.h> -#include <asm/byteorder.h> - -#include "common.h" - -#define BLOCK_SIZE 1024 -#define JFFS_MAGIC 0x34383931 /* "1984" */ -#define JFFS_MAX_NAME_LEN 256 -#define JFFS_MIN_INO 1 -#define JFFS_TRACE_INDENT 4 -#define JFFS_ALIGN_SIZE 4 -#define MAX_CHUNK_SIZE 32768 - -/* How many padding bytes should be inserted between two chunks of data - on the flash? */ -#define JFFS_GET_PAD_BYTES(size) ((JFFS_ALIGN_SIZE \ - - ((uint32_t)(size) % JFFS_ALIGN_SIZE)) \ - % JFFS_ALIGN_SIZE) - -#define JFFS_EMPTY_BITMASK 0xffffffff -#define JFFS_MAGIC_BITMASK 0x34383931 -#define JFFS_DIRTY_BITMASK 0x00000000 - -struct jffs_raw_inode -{ - uint32_t magic; /* A constant magic number. */ - uint32_t ino; /* Inode number. */ - uint32_t pino; /* Parent's inode number. */ - uint32_t version; /* Version number. */ - uint32_t mode; /* file_type, mode */ - uint16_t uid; - uint16_t gid; - uint32_t atime; - uint32_t mtime; - uint32_t ctime; - uint32_t offset; /* Where to begin to write. */ - uint32_t dsize; /* Size of the file data. */ - uint32_t rsize; /* How much are going to be replaced? */ - uint8_t nsize; /* Name length. */ - uint8_t nlink; /* Number of links. */ - uint8_t spare : 6; /* For future use. */ - uint8_t rename : 1; /* Is this a special rename? */ - uint8_t deleted : 1; /* Has this file been deleted? */ - uint8_t accurate; /* The inode is obsolete if accurate == 0. */ - uint32_t dchksum; /* Checksum for the data. */ - uint16_t nchksum; /* Checksum for the name. */ - uint16_t chksum; /* Checksum for the raw_inode. */ -}; - - -struct jffs_file -{ - struct jffs_raw_inode inode; - char *name; - unsigned char *data; -}; - - -char *root_directory_name = NULL; -int fs_pos = 0; -int verbose = 0; - -#define ENDIAN_HOST 0 -#define ENDIAN_BIG 1 -#define ENDIAN_LITTLE 2 -int endian = ENDIAN_HOST; - -static uint32_t jffs_checksum(void *data, int size); -void jffs_print_trace(const char *path, int depth); -int make_root_dir(FILE *fs, int first_ino, const char *root_dir_path, - int depth); -void write_file(struct jffs_file *f, FILE *fs, struct stat st); -void read_data(struct jffs_file *f, const char *path, int offset); -int mkfs(FILE *fs, const char *path, int ino, int parent, int depth); - - - static uint32_t -jffs_checksum(void *data, int size) -{ - uint32_t sum = 0; - uint8_t *ptr = (uint8_t *)data; - - while (size-- > 0) - { - sum += *ptr++; - } - - return sum; -} - - - void -jffs_print_trace(const char *path, int depth) -{ - int path_len = strlen(path); - int out_pos = depth * JFFS_TRACE_INDENT; - int pos = path_len - 1; - char *out = (char *)alloca(depth * JFFS_TRACE_INDENT + path_len + 1); - - if (verbose >= 2) - { - fprintf(stderr, "jffs_print_trace(): path: \"%s\"\n", path); - } - - if (!out) { - fprintf(stderr, "jffs_print_trace(): Allocation failed.\n"); - fprintf(stderr, " path: \"%s\"\n", path); - fprintf(stderr, "depth: %d\n", depth); - exit(1); - } - - memset(out, ' ', depth * JFFS_TRACE_INDENT); - - if (path[pos] == '/') - { - pos--; - } - while (path[pos] && (path[pos] != '/')) - { - pos--; - } - for (pos++; path[pos] && (path[pos] != '/'); pos++) - { - out[out_pos++] = path[pos]; - } - out[out_pos] = '\0'; - fprintf(stderr, "%s\n", out); -} - - -/* Print the contents of a raw inode. */ - void -jffs_print_raw_inode(struct jffs_raw_inode *raw_inode) -{ - fprintf(stdout, "jffs_raw_inode: inode number: %u, version %u\n", raw_inode->ino, raw_inode->version); - fprintf(stdout, "{\n"); - fprintf(stdout, " 0x%08x, /* magic */\n", raw_inode->magic); - fprintf(stdout, " 0x%08x, /* ino */\n", raw_inode->ino); - fprintf(stdout, " 0x%08x, /* pino */\n", raw_inode->pino); - fprintf(stdout, " 0x%08x, /* version */\n", raw_inode->version); - fprintf(stdout, " 0x%08x, /* mode */\n", raw_inode->mode); - fprintf(stdout, " 0x%04x, /* uid */\n", raw_inode->uid); - fprintf(stdout, " 0x%04x, /* gid */\n", raw_inode->gid); - fprintf(stdout, " 0x%08x, /* atime */\n", raw_inode->atime); - fprintf(stdout, " 0x%08x, /* mtime */\n", raw_inode->mtime); - fprintf(stdout, " 0x%08x, /* ctime */\n", raw_inode->ctime); - fprintf(stdout, " 0x%08x, /* offset */\n", raw_inode->offset); - fprintf(stdout, " 0x%08x, /* dsize */\n", raw_inode->dsize); - fprintf(stdout, " 0x%08x, /* rsize */\n", raw_inode->rsize); - fprintf(stdout, " 0x%02x, /* nsize */\n", raw_inode->nsize); - fprintf(stdout, " 0x%02x, /* nlink */\n", raw_inode->nlink); - fprintf(stdout, " 0x%02x, /* spare */\n", - raw_inode->spare); - fprintf(stdout, " %u, /* rename */\n", - raw_inode->rename); - fprintf(stdout, " %u, /* deleted */\n", - raw_inode->deleted); - fprintf(stdout, " 0x%02x, /* accurate */\n", - raw_inode->accurate); - fprintf(stdout, " 0x%08x, /* dchksum */\n", raw_inode->dchksum); - fprintf(stdout, " 0x%04x, /* nchksum */\n", raw_inode->nchksum); - fprintf(stdout, " 0x%04x, /* chksum */\n", raw_inode->chksum); - fprintf(stdout, "}\n"); -} - -static void write_val32(uint32_t *adr, uint32_t val) -{ - switch(endian) { - case ENDIAN_HOST: - *adr = val; - break; - case ENDIAN_LITTLE: - *adr = __cpu_to_le32(val); - break; - case ENDIAN_BIG: - *adr = __cpu_to_be32(val); - break; - } -} - -static void write_val16(uint16_t *adr, uint16_t val) -{ - switch(endian) { - case ENDIAN_HOST: - *adr = val; - break; - case ENDIAN_LITTLE: - *adr = __cpu_to_le16(val); - break; - case ENDIAN_BIG: - *adr = __cpu_to_be16(val); - break; - } -} - -static uint32_t read_val32(uint32_t *adr) -{ - uint32_t val; - - switch(endian) { - case ENDIAN_HOST: - val = *adr; - break; - case ENDIAN_LITTLE: - val = __le32_to_cpu(*adr); - break; - case ENDIAN_BIG: - val = __be32_to_cpu(*adr); - break; - } - return val; -} - -static uint16_t read_val16(uint16_t *adr) -{ - uint16_t val; - - switch(endian) { - case ENDIAN_HOST: - val = *adr; - break; - case ENDIAN_LITTLE: - val = __le16_to_cpu(*adr); - break; - case ENDIAN_BIG: - val = __be16_to_cpu(*adr); - break; - } - return val; -} - - int -main(int argc, char **argv) -{ - int fs; - struct stat sb; - uint32_t wordbuf; - off_t pos = 0; - off_t end; - struct jffs_raw_inode ino; - unsigned char namebuf[4096]; - int myino = -1; - - if (argc < 2) { - printf("no filesystem given\n"); - exit(1); - } - - fs = open(argv[1], O_RDONLY); - if (fs < 0) { - perror("open"); - exit(1); - } - - if (argc > 2) { - myino = atol(argv[2]); - printf("Printing ino #%d\n" , myino); - } - - if (fstat(fs, &sb) < 0) { - perror("stat"); - close(fs); - exit(1); - } - end = sb.st_size; - - while (pos < end) { - if (pread(fs, &wordbuf, 4, pos) < 0) { - perror("pread"); - exit(1); - } - - switch(wordbuf) { - case JFFS_EMPTY_BITMASK: - // printf("0xff started at 0x%lx\n", pos); - for (; pos < end && wordbuf == JFFS_EMPTY_BITMASK; pos += 4) { - if (pread(fs, &wordbuf, 4, pos) < 0) { - perror("pread"); - exit(1); - } - } - if (pos < end) - pos -= 4; - // printf("0xff ended at 0x%lx\n", pos); - continue; - - case JFFS_DIRTY_BITMASK: - // printf("0x00 started at 0x%lx\n", pos); - for (; pos < end && wordbuf == JFFS_DIRTY_BITMASK; pos += 4) { - if (pread(fs, &wordbuf, 4, pos) < 0) { - perror("pread"); - exit(1); - } - } - if (pos < end) - pos -=4; - // printf("0x00 ended at 0x%lx\n", pos); - continue; - - default: - printf("Argh. Dirty memory at 0x%lx\n", pos); - // file_hexdump(fs, pos, 128); - for (pos += 4; pos < end; pos += 4) { - if (pread(fs, &wordbuf, 4, pos) < 0) { - perror("pread"); - exit(1); - } - if (wordbuf == JFFS_MAGIC_BITMASK) - break; - } - - case JFFS_MAGIC_BITMASK: - if (pread(fs, &ino, sizeof(ino), pos) < 0) { - perror("pread"); - exit(1); - } - if (myino == -1 || ino.ino == myino) { - printf("Magic found at 0x%lx\n", pos); - jffs_print_raw_inode(&ino); - } - pos += sizeof(ino); - - if (myino == -1 || ino.ino == myino) { - if (ino.nsize) { - if (pread(fs, namebuf, min(ino.nsize, 4095), pos) < 0) { - perror("pread"); - exit(1); - } - if (ino.nsize < 4095) - namebuf[ino.nsize] = 0; - else - namebuf[4095] = 0; - printf("Name: \"%s\"\n", namebuf); - } else { - printf("No Name\n"); - } - } - pos += (ino.nsize + 3) & ~3; - - pos += (ino.dsize + 3) & ~3; - } - - - - } -} |