Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/linux-sunxi/sunxi-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Nordstrom <henrik@henriknordstrom.net>2012-07-02 12:02:32 +0400
committerHenrik Nordstrom <henrik@henriknordstrom.net>2012-07-02 12:02:32 +0400
commit455babd738454a469727089cbf759d9f3bee94f5 (patch)
treeabb3487508660e4dc72a64af26acd3a848472725 /phoenix_info.c
parent75005abcff260679c1aca73bf0bab5d7d1db8986 (diff)
Add save/extract capability to phoenix_info
Diffstat (limited to 'phoenix_info.c')
-rw-r--r--phoenix_info.c138
1 files changed, 123 insertions, 15 deletions
diff --git a/phoenix_info.c b/phoenix_info.c
index fcf6879..5264c3f 100644
--- a/phoenix_info.c
+++ b/phoenix_info.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <endian.h>
+#include <unistd.h>
struct phoenix_ptable {
char signature[16]; /* "PHOENIX_CARD_IMG" */
@@ -37,31 +38,138 @@ struct phoenix_ptable {
} part[62];
} ptable;
+static int save_part(struct phoenix_ptable *ptable, int part, const char *dest, FILE *in)
+{
+ int l = strlen(dest) + 16;
+ char outname[l];
+ FILE *out;
+ char *buf = NULL;
+ int ret = 0;
+ snprintf(outname, l, dest, part);
+ if (part > ptable->parts) {
+ fprintf(stderr, "ERROR: Part index out of range\n");
+ return -1;
+ }
+ buf = malloc(ptable->part[part].size);
+ if (!buf)
+ goto err;
+ if (strcmp(outname, "-") != 0)
+ out = fopen(outname, "wb");
+ else
+ out = stdout;
+ if (!out)
+ goto err;
+ if (fseek(in, ptable->part[part].start * 0x200, SEEK_SET) == -1)
+ goto err;
+ if (fread(buf, ptable->part[part].size, 1, in) != 1)
+ goto err;
+ if (fwrite(buf, ptable->part[part].size, 1, out) != 1)
+ goto err;
+ ret = 0;
+_exit:
+ if (buf)
+ free(buf);
+ if (out != stdout)
+ fclose(out);
+ return ret;
+err:
+ perror(NULL);
+ ret = -1;
+ goto _exit;
+}
+
+static void usage(char **argv)
+{
+ printf("Usage: %s [options] [phoenix_image]\n"
+ " -v verbose\n"
+ " -q quiet\n"
+ " -p N part number\n"
+ " -o X destination directory, file or pattern (%%d for part number)\n"
+ " -s save all parts\n"
+ , argv[0]
+ );
+}
+
int main(int argc, char **argv)
{
int i;
FILE *in = stdin;
- if (argc > 1) {
- in = fopen(argv[1], "r");
+ int verbose = 1;
+ int save_parts = 0;
+ int part = -1;
+ int opt;
+ const char *dest = "%d.img";
+
+ while ((opt = getopt(argc, argv, "vqso:p:?")) != -1) {
+ switch(opt) {
+ case 'v':
+ verbose++;
+ break;
+ case 'q':
+ if (verbose)
+ verbose--;
+ break;
+ case 'o':
+ dest = optarg;
+ save_parts = 1;
+ break;
+ case 'p':
+ save_parts = 1;
+ part = atoi(optarg);
+ break;
+ case 's':
+ save_parts = 1;
+ break;
+ default:
+ usage(argv);
+ exit(1);
+ break;
+ }
+ }
+ if (save_parts && !strchr(dest, '%')) {
+ const char *t = dest;
+ if (!*t)
+ t = "./";
+ if (t[strlen(t)-1] == '/' || !part) {
+ int l = strlen(t) + strlen("/%d.img") + 1;
+ char *tmp = malloc(l);
+ snprintf(tmp, l, "%s/%%d.img", optarg);
+ t = tmp;
+ }
+ dest = t;
+ }
+ if (argc > optind + 1) {
+ usage(argv);
+ exit(1);
+ }
+ if (optind < argc ) {
+ in = fopen(argv[optind], "rb");
}
fseek(in, 0x1C00, SEEK_CUR);
fread(&ptable, 1, 0x400, in);
if (strncmp(ptable.signature, "PHOENIX_CARD_IMG", 16) != 0) {
- printf("ERROR: Not a phoenix image\n");
+ fprintf(stderr, "ERROR: Not a phoenix image\n");
exit(1);
}
- printf("???? : %08x\n", le32toh(ptable.unknown1));
- printf("Parts : %d\n", le16toh(ptable.parts));
- printf("???? : %08x\n", le16toh(ptable.unknown2));
- printf("pad : %02x%02x%02x%02x%02x%02x%02x%02x\n", ptable.pad[0], ptable.pad[1], ptable.pad[2], ptable.pad[3], ptable.pad[4], ptable.pad[5], ptable.pad[6], ptable.pad[7]);
- printf("\n");
- for (i = 0; i < le16toh(ptable.parts); i++) {
- printf("part %d:\n", i);
- printf("\tstart: 0x%08x (%u / 0x%08x)\n", le32toh(ptable.part[i].start)*512, le32toh(ptable.part[i].start), le32toh(ptable.part[i].start));
- printf("\tsize : %u\n", le32toh(ptable.part[i].size));
- printf("\t?????: %08x\n", le32toh(ptable.part[i].unknown));
- if (le32toh(ptable.part[i].sig) != 0x00646461)
- printf("\tsig??: %08x\n", le32toh(ptable.part[i].sig));
+ if (verbose > 1) {
+ printf("???? : %08x\n", le32toh(ptable.unknown1));
+ printf("Parts : %d\n", le16toh(ptable.parts));
+ printf("???? : %08x\n", le16toh(ptable.unknown2));
+ printf("pad : %02x%02x%02x%02x%02x%02x%02x%02x\n", ptable.pad[0], ptable.pad[1], ptable.pad[2], ptable.pad[3], ptable.pad[4], ptable.pad[5], ptable.pad[6], ptable.pad[7]);
printf("\n");
}
+ for (i = 0; i < le16toh(ptable.parts); i++) {
+ if (verbose && (part == -1 || part == i)) {
+ printf("part %d:\n", i);
+ printf("\tstart: 0x%08x (%u / 0x%08x)\n", le32toh(ptable.part[i].start)*512, le32toh(ptable.part[i].start), le32toh(ptable.part[i].start));
+ printf("\tsize : %u\n", le32toh(ptable.part[i].size));
+ printf("\t?????: %08x\n", le32toh(ptable.part[i].unknown));
+ if (verbose > 1 || le32toh(ptable.part[i].sig) != 0x00646461)
+ printf("\tsig??: %08x\n", le32toh(ptable.part[i].sig));
+ printf("\n");
+ }
+ if (save_parts && (part == -1 || part == i)) {
+ save_part(&ptable, i, dest, in);
+ }
+ }
}