|
|
|
@ -44,6 +44,8 @@ |
|
|
|
|
#include "fis.h" |
|
|
|
|
#include "mtd.h" |
|
|
|
|
|
|
|
|
|
#include <libubox/md5.h> |
|
|
|
|
|
|
|
|
|
#define MAX_ARGS 8 |
|
|
|
|
#define JFFS2_DEFAULT_DIR "" /* directory name without /, empty means root dir */ |
|
|
|
|
|
|
|
|
@ -245,6 +247,63 @@ mtd_erase(const char *mtd) |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
mtd_verify(const char *mtd, char *file) |
|
|
|
|
{ |
|
|
|
|
uint32_t f_md5[4], m_md5[4]; |
|
|
|
|
struct stat s; |
|
|
|
|
md5_ctx_t ctx; |
|
|
|
|
int ret = 0; |
|
|
|
|
int fd; |
|
|
|
|
|
|
|
|
|
if (quiet < 2) |
|
|
|
|
fprintf(stderr, "Verifying %s against %s ...\n", mtd, file); |
|
|
|
|
|
|
|
|
|
if (stat(file, &s) || md5sum(file, f_md5)) { |
|
|
|
|
fprintf(stderr, "Failed to hash %s\n", file); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fd = mtd_check_open(mtd); |
|
|
|
|
if(fd < 0) { |
|
|
|
|
fprintf(stderr, "Could not open mtd device: %s\n", mtd); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
md5_begin(&ctx); |
|
|
|
|
do { |
|
|
|
|
char buf[256]; |
|
|
|
|
int len = (s.st_size > sizeof(buf)) ? (sizeof(buf)) : (s.st_size); |
|
|
|
|
int rlen = read(fd, buf, len); |
|
|
|
|
|
|
|
|
|
if (rlen < 0) { |
|
|
|
|
if (errno == EINTR) |
|
|
|
|
continue; |
|
|
|
|
ret = -1; |
|
|
|
|
goto out; |
|
|
|
|
} |
|
|
|
|
if (!rlen) |
|
|
|
|
break; |
|
|
|
|
md5_hash(buf, rlen, &ctx); |
|
|
|
|
s.st_size -= rlen; |
|
|
|
|
} while (s.st_size > 0); |
|
|
|
|
|
|
|
|
|
md5_end(m_md5, &ctx); |
|
|
|
|
|
|
|
|
|
fprintf(stderr, "%08x%08x%08x%08x - %s\n", m_md5[0], m_md5[1], m_md5[2], m_md5[3], mtd); |
|
|
|
|
fprintf(stderr, "%08x%08x%08x%08x - %s\n", f_md5[0], f_md5[1], f_md5[2], f_md5[3], file); |
|
|
|
|
|
|
|
|
|
ret = memcmp(f_md5, m_md5, sizeof(m_md5)); |
|
|
|
|
if (!ret) |
|
|
|
|
fprintf(stderr, "Success\n"); |
|
|
|
|
else |
|
|
|
|
fprintf(stderr, "Failed\n"); |
|
|
|
|
|
|
|
|
|
out: |
|
|
|
|
close(fd); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
indicate_writing(const char *mtd) |
|
|
|
|
{ |
|
|
|
@ -341,7 +400,7 @@ resume: |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
if (part_offset > 0) { |
|
|
|
|
fprintf(stderr, "Seeking on mtd device '%s' to: %u\n", mtd, part_offset); |
|
|
|
|
fprintf(stderr, "Seeking on mtd device '%s' to: %zu\n", mtd, part_offset); |
|
|
|
|
lseek(fd, part_offset, SEEK_SET); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -483,6 +542,7 @@ static void usage(void) |
|
|
|
|
" unlock unlock the device\n" |
|
|
|
|
" refresh refresh mtd partition\n" |
|
|
|
|
" erase erase all data on device\n" |
|
|
|
|
" verify <imagefile>|- verify <imagefile> (use - for stdin) to device\n" |
|
|
|
|
" write <imagefile>|- write <imagefile> (use - for stdin) to device\n" |
|
|
|
|
" jffs2write <file> append <file> to the jffs2 partition on the device\n"); |
|
|
|
|
if (mtd_fixtrx) { |
|
|
|
@ -548,6 +608,7 @@ int main (int argc, char **argv) |
|
|
|
|
CMD_JFFS2WRITE, |
|
|
|
|
CMD_FIXTRX, |
|
|
|
|
CMD_FIXSEAMA, |
|
|
|
|
CMD_VERIFY, |
|
|
|
|
} cmd = -1; |
|
|
|
|
|
|
|
|
|
erase[0] = NULL; |
|
|
|
@ -644,6 +705,10 @@ int main (int argc, char **argv) |
|
|
|
|
} else if (((strcmp(argv[0], "fixseama") == 0) && (argc == 2)) && mtd_fixseama) { |
|
|
|
|
cmd = CMD_FIXSEAMA; |
|
|
|
|
device = argv[1]; |
|
|
|
|
} else if ((strcmp(argv[0], "verify") == 0) && (argc == 3)) { |
|
|
|
|
cmd = CMD_VERIFY; |
|
|
|
|
imagefile = argv[1]; |
|
|
|
|
device = argv[2]; |
|
|
|
|
} else if ((strcmp(argv[0], "write") == 0) && (argc == 3)) { |
|
|
|
|
cmd = CMD_WRITE; |
|
|
|
|
device = argv[2]; |
|
|
|
@ -698,6 +763,9 @@ int main (int argc, char **argv) |
|
|
|
|
if (!unlocked) |
|
|
|
|
mtd_unlock(device); |
|
|
|
|
break; |
|
|
|
|
case CMD_VERIFY: |
|
|
|
|
mtd_verify(device, imagefile); |
|
|
|
|
break; |
|
|
|
|
case CMD_ERASE: |
|
|
|
|
if (!unlocked) |
|
|
|
|
mtd_unlock(device); |
|
|
|
|