This patch carves out the duplicated code of mktplinfw.c and mktplinkfw2.c and moves it to mktplinkfw-lib.c This change is a semantic NOP (the code is unchanged). To ensure compatibility with gcc-5.x and newer without changing the code, -fgnu89-inline is added to the build flags for these two binaries. Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>master
parent
10832c8e12
commit
10324fcb39
@ -0,0 +1,195 @@ |
||||
/*
|
||||
* Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> |
||||
* |
||||
* This tool was based on: |
||||
* TP-Link WR941 V2 firmware checksum fixing tool. |
||||
* Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify it |
||||
* under the terms of the GNU General Public License version 2 as published |
||||
* by the Free Software Foundation. |
||||
* |
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <stdint.h> |
||||
#include <string.h> |
||||
#include <unistd.h> /* for unlink() */ |
||||
#include <libgen.h> |
||||
#include <getopt.h> /* for getopt() */ |
||||
#include <stdarg.h> |
||||
#include <stdbool.h> |
||||
#include <endian.h> |
||||
#include <errno.h> |
||||
#include <sys/stat.h> |
||||
|
||||
#include <arpa/inet.h> |
||||
#include <netinet/in.h> |
||||
|
||||
#include "mktplinkfw-lib.h" |
||||
#include "md5.h" |
||||
|
||||
extern char *progname; |
||||
static unsigned char jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; |
||||
|
||||
struct flash_layout *find_layout(struct flash_layout *layouts, const char *id) |
||||
{ |
||||
struct flash_layout *ret; |
||||
struct flash_layout *l; |
||||
|
||||
ret = NULL; |
||||
for (l = layouts; l->id != NULL; l++){ |
||||
if (strcasecmp(id, l->id) == 0) { |
||||
ret = l; |
||||
break; |
||||
} |
||||
}; |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
void get_md5(const char *data, int size, uint8_t *md5) |
||||
{ |
||||
MD5_CTX ctx; |
||||
|
||||
MD5_Init(&ctx); |
||||
MD5_Update(&ctx, data, size); |
||||
MD5_Final(md5, &ctx); |
||||
} |
||||
|
||||
int get_file_stat(struct file_info *fdata) |
||||
{ |
||||
struct stat st; |
||||
int res; |
||||
|
||||
if (fdata->file_name == NULL) |
||||
return 0; |
||||
|
||||
res = stat(fdata->file_name, &st); |
||||
if (res){ |
||||
ERRS("stat failed on %s", fdata->file_name); |
||||
return res; |
||||
} |
||||
|
||||
fdata->file_size = st.st_size; |
||||
return 0; |
||||
} |
||||
|
||||
int read_to_buf(const struct file_info *fdata, char *buf) |
||||
{ |
||||
FILE *f; |
||||
int ret = EXIT_FAILURE; |
||||
|
||||
f = fopen(fdata->file_name, "r"); |
||||
if (f == NULL) { |
||||
ERRS("could not open \"%s\" for reading", fdata->file_name); |
||||
goto out; |
||||
} |
||||
|
||||
errno = 0; |
||||
fread(buf, fdata->file_size, 1, f); |
||||
if (errno != 0) { |
||||
ERRS("unable to read from file \"%s\"", fdata->file_name); |
||||
goto out_close; |
||||
} |
||||
|
||||
ret = EXIT_SUCCESS; |
||||
|
||||
out_close: |
||||
fclose(f); |
||||
out: |
||||
return ret; |
||||
} |
||||
|
||||
int pad_jffs2(char *buf, int currlen, int maxlen) |
||||
{ |
||||
int len; |
||||
uint32_t pad_mask; |
||||
|
||||
len = currlen; |
||||
pad_mask = (64 * 1024); |
||||
while ((len < maxlen) && (pad_mask != 0)) { |
||||
uint32_t mask; |
||||
int i; |
||||
|
||||
for (i = 10; i < 32; i++) { |
||||
mask = 1 << i; |
||||
if (pad_mask & mask) |
||||
break; |
||||
} |
||||
|
||||
len = ALIGN(len, mask); |
||||
|
||||
for (i = 10; i < 32; i++) { |
||||
mask = 1 << i; |
||||
if ((len & (mask - 1)) == 0) |
||||
pad_mask &= ~mask; |
||||
} |
||||
|
||||
for (i = 0; i < sizeof(jffs2_eof_mark); i++) |
||||
buf[len + i] = jffs2_eof_mark[i]; |
||||
|
||||
len += sizeof(jffs2_eof_mark); |
||||
} |
||||
|
||||
return len; |
||||
} |
||||
|
||||
int write_fw(const char *ofname, const char *data, int len) |
||||
{ |
||||
FILE *f; |
||||
int ret = EXIT_FAILURE; |
||||
|
||||
f = fopen(ofname, "w"); |
||||
if (f == NULL) { |
||||
ERRS("could not open \"%s\" for writing", ofname); |
||||
goto out; |
||||
} |
||||
|
||||
errno = 0; |
||||
fwrite(data, len, 1, f); |
||||
if (errno) { |
||||
ERRS("unable to write output file"); |
||||
goto out_flush; |
||||
} |
||||
|
||||
DBG("firmware file \"%s\" completed", ofname); |
||||
|
||||
ret = EXIT_SUCCESS; |
||||
|
||||
out_flush: |
||||
fflush(f); |
||||
fclose(f); |
||||
if (ret != EXIT_SUCCESS) { |
||||
unlink(ofname); |
||||
} |
||||
out: |
||||
return ret; |
||||
} |
||||
|
||||
/* Helper functions to inspect_fw() representing different output formats */ |
||||
inline void inspect_fw_pstr(const char *label, const char *str) |
||||
{ |
||||
printf("%-23s: %s\n", label, str); |
||||
} |
||||
|
||||
inline void inspect_fw_phex(const char *label, uint32_t val) |
||||
{ |
||||
printf("%-23s: 0x%08x\n", label, val); |
||||
} |
||||
|
||||
inline void inspect_fw_phexdec(const char *label, uint32_t val) |
||||
{ |
||||
printf("%-23s: 0x%08x / %8u bytes\n", label, val, val); |
||||
} |
||||
|
||||
inline void inspect_fw_pmd5sum(const char *label, const uint8_t *val, const char *text) |
||||
{ |
||||
int i; |
||||
|
||||
printf("%-23s:", label); |
||||
for (i=0; i<MD5SUM_LEN; i++) |
||||
printf(" %02x", val[i]); |
||||
printf(" %s\n", text); |
||||
} |
@ -0,0 +1,68 @@ |
||||
/*
|
||||
* Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> |
||||
* |
||||
* This tool was based on: |
||||
* TP-Link WR941 V2 firmware checksum fixing tool. |
||||
* Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify it |
||||
* under the terms of the GNU General Public License version 2 as published |
||||
* by the Free Software Foundation. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
#ifndef mktplinkfw_lib_h |
||||
#define mktplinkfw_lib_h |
||||
|
||||
#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); }) |
||||
#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0])) |
||||
|
||||
#define MD5SUM_LEN 16 |
||||
|
||||
/*
|
||||
* Message macros |
||||
*/ |
||||
#define ERR(fmt, ...) do { \ |
||||
fflush(0); \
|
||||
fprintf(stderr, "[%s] *** error: " fmt "\n", \
|
||||
progname, ## __VA_ARGS__ ); \
|
||||
} while (0) |
||||
|
||||
#define ERRS(fmt, ...) do { \ |
||||
int save = errno; \
|
||||
fflush(0); \
|
||||
fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
|
||||
progname, ## __VA_ARGS__, strerror(save)); \
|
||||
} while (0) |
||||
|
||||
#define DBG(fmt, ...) do { \ |
||||
fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \
|
||||
} while (0) |
||||
|
||||
|
||||
struct file_info { |
||||
char *file_name; /* name of the file */ |
||||
uint32_t file_size; /* length of the file */ |
||||
}; |
||||
|
||||
struct flash_layout { |
||||
char *id; |
||||
uint32_t fw_max_len; |
||||
uint32_t kernel_la; |
||||
uint32_t kernel_ep; |
||||
uint32_t rootfs_ofs; |
||||
}; |
||||
|
||||
struct flash_layout *find_layout(struct flash_layout *layouts, const char *id); |
||||
void get_md5(const char *data, int size, uint8_t *md5); |
||||
int get_file_stat(struct file_info *fdata); |
||||
int read_to_buf(const struct file_info *fdata, char *buf); |
||||
int pad_jffs2(char *buf, int currlen, int maxlen); |
||||
int write_fw(const char *ofname, const char *data, int len); |
||||
inline void inspect_fw_pstr(const char *label, const char *str); |
||||
inline void inspect_fw_phex(const char *label, uint32_t val); |
||||
inline void inspect_fw_phexdec(const char *label, uint32_t val); |
||||
inline void inspect_fw_pmd5sum(const char *label, const uint8_t *val, const char *text); |
||||
|
||||
#endif /* mktplinkfw_lib_h */ |
Loading…
Reference in new issue