diff options
author | Dave Chapman <dave@dchapman.com> | 2007-02-08 23:57:41 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2007-02-08 23:57:41 +0000 |
commit | 79a1fb1b29b79c2b100a8021bc397879d69c69c3 (patch) | |
tree | 0628570c5af8b1e907b7f4aef6fc9751d7b0dcf4 | |
parent | eca5222cadbc6595470bb9c3a295d7fcb7d1e99b (diff) | |
download | rockbox-79a1fb1b29b79c2b100a8021bc397879d69c69c3.tar.gz rockbox-79a1fb1b29b79c2b100a8021bc397879d69c69c3.zip |
Move the command-line specific code into main.c, leaving the firmware manipulation code in ipodpatcher.c. No functional changes.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12238 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | tools/ipodpatcher/Makefile | 8 | ||||
-rw-r--r-- | tools/ipodpatcher/ipodpatcher.c | 401 | ||||
-rw-r--r-- | tools/ipodpatcher/ipodpatcher.h | 51 | ||||
-rw-r--r-- | tools/ipodpatcher/main.c | 415 |
4 files changed, 473 insertions, 402 deletions
diff --git a/tools/ipodpatcher/Makefile b/tools/ipodpatcher/Makefile index afbb9f155a..f5a4d7cfb3 100644 --- a/tools/ipodpatcher/Makefile +++ b/tools/ipodpatcher/Makefile @@ -24,12 +24,12 @@ CC = $(CROSS)gcc all: $(OUTPUT) -ipodpatcher: ipodpatcher.c ipodio-posix.c parttypes.h $(BOOTSRC) - gcc $(CFLAGS) -o ipodpatcher ipodpatcher.c ipodio-posix.c $(BOOTSRC) +ipodpatcher: main.c ipodpatcher.c ipodio-posix.c parttypes.h $(BOOTSRC) + gcc $(CFLAGS) -o ipodpatcher main.c ipodpatcher.c ipodio-posix.c $(BOOTSRC) strip ipodpatcher -ipodpatcher.exe: ipodpatcher.c ipodio-win32.c parttypes.h $(BOOTSRC) - $(CC) $(CFLAGS) -o ipodpatcher.exe ipodpatcher.c ipodio-win32.c $(BOOTSRC) +ipodpatcher.exe: main.c ipodpatcher.c ipodio-win32.c parttypes.h $(BOOTSRC) + $(CC) $(CFLAGS) -o ipodpatcher.exe main.c ipodpatcher.c ipodio-win32.c $(BOOTSRC) $(CROSS)strip ipodpatcher.exe ipod2c: ipod2c.c diff --git a/tools/ipodpatcher/ipodpatcher.c b/tools/ipodpatcher/ipodpatcher.c index 93fd8c16ad..6c60bae38d 100644 --- a/tools/ipodpatcher/ipodpatcher.c +++ b/tools/ipodpatcher/ipodpatcher.c @@ -28,6 +28,7 @@ #include "parttypes.h" #include "ipodio.h" +#include "ipodpatcher.h" #ifdef WITH_BOOTOBJS #include "ipod3g.h" @@ -39,9 +40,9 @@ #include "ipodvideo.h" #endif -#define VERSION "0.8svn" +extern int verbose; -int verbose = 0; +unsigned char* sectorbuf; /* The following string appears at the start of the firmware partition */ static const char *apple_stop_sign = "{{~~ /-----\\ "\ @@ -66,11 +67,6 @@ static const char *apple_stop_sign = "{{~~ /-----\\ "\ and initialise it with ipod_alloc_buf() */ -/* Size of buffer for disk I/O - 8MB is large enough for any version - of the Apple firmware, but not the Nano's RSRC image. */ -#define BUFFER_SIZE 8*1024*1024 -unsigned char* sectorbuf; - char* get_parttype(int pt) { int i; @@ -397,81 +393,6 @@ int write_partition(struct ipod_t* ipod, int infile) return 0; } -void print_macpod_warning(void) -{ - printf("[INFO] ************************************************************************\n"); - printf("[INFO] *** WARNING FOR ROCKBOX USERS\n"); - printf("[INFO] *** You must convert this ipod to FAT32 format (aka a \"winpod\")\n"); - printf("[INFO] *** if you want to run Rockbox. Rockbox WILL NOT work on this ipod.\n"); - printf("[INFO] *** See http://www.rockbox.org/twiki/bin/view/Main/IpodConversionToFAT32\n"); - printf("[INFO] ************************************************************************\n"); -} - -void print_usage(void) -{ - fprintf(stderr,"Usage: ipodpatcher --scan\n"); -#ifdef __WIN32__ - fprintf(stderr," or ipodpatcher [DISKNO] [action]\n"); -#else - fprintf(stderr," or ipodpatcher [device] [action]\n"); -#endif - fprintf(stderr,"\n"); - fprintf(stderr,"Where [action] is one of the following options:\n"); -#ifdef WITH_BOOTOBJS - fprintf(stderr," --install\n"); -#endif - fprintf(stderr," -l, --list\n"); - fprintf(stderr," -r, --read-partition bootpartition.bin\n"); - fprintf(stderr," -w, --write-partition bootpartition.bin\n"); - fprintf(stderr," -rf, --read-firmware filename.ipod\n"); - fprintf(stderr," -wf, --write-firmware filename.ipod\n"); - fprintf(stderr," -wfb, --write-firmware-bin filename.bin\n"); - fprintf(stderr," -a, --add-bootloader filename.ipod\n"); - fprintf(stderr," -ab, --add-bootloader-bin filename.bin\n"); - fprintf(stderr," -d, --delete-bootloader\n"); - fprintf(stderr,"\n"); - -#ifdef __WIN32__ - fprintf(stderr,"DISKNO is the number (e.g. 2) Windows has assigned to your ipod's hard disk.\n"); - fprintf(stderr,"The first hard disk in your computer (i.e. C:\\) will be disk 0, the next disk\n"); - fprintf(stderr,"will be disk 1 etc. ipodpatcher will refuse to access a disk unless it\n"); - fprintf(stderr,"can identify it as being an ipod.\n"); - fprintf(stderr,"\n"); -#else -#if defined(linux) || defined (__linux) - fprintf(stderr,"\"device\" is the device node (e.g. /dev/sda) assigned to your ipod.\n"); -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) - fprintf(stderr,"\"device\" is the device node (e.g. /dev/da1) assigned to your ipod.\n"); -#elif defined(__APPLE__) && defined(__MACH__) - fprintf(stderr,"\"device\" is the device node (e.g. /dev/disk1) assigned to your ipod.\n"); -#endif - fprintf(stderr,"ipodpatcher will refuse to access a disk unless it can identify it as being\n"); - fprintf(stderr,"an ipod.\n"); -#endif -} - -enum { - NONE, -#ifdef WITH_BOOTOBJS - INSTALL, -#endif - INTERACTIVE, - SHOW_INFO, - LIST_IMAGES, - DELETE_BOOTLOADER, - ADD_BOOTLOADER, - READ_FIRMWARE, - WRITE_FIRMWARE, - READ_PARTITION, - WRITE_PARTITION -}; - -#define FILETYPE_DOT_IPOD 0 -#define FILETYPE_DOT_BIN 1 -#ifdef WITH_BOOTOBJS - #define FILETYPE_INTERNAL 2 -#endif - char* ftypename[] = { "OSOS", "RSRC", "AUPD", "HIBE" }; int diskmove(struct ipod_t* ipod, int delta) @@ -1327,10 +1248,6 @@ int ipod_scan(struct ipod_t* ipod) printf("[INFO] Ipod found - %s (\"%s\") - %s\n", ipod->modelstr,ipod->macpod ? "macpod" : "winpod",ipod->diskname); #endif - - if (ipod->macpod) { - print_macpod_warning(); - } n++; strcpy(last_ipod,ipod->diskname); ipod_close(ipod); @@ -1342,315 +1259,3 @@ int ipod_scan(struct ipod_t* ipod) } return n; } - -int main(int argc, char* argv[]) -{ -#ifdef WITH_BOOTOBJS - char yesno[4]; -#endif - int i; - int n; - int infile, outfile; - unsigned int inputsize; - char* filename; - int action = SHOW_INFO; - int type; - struct ipod_t ipod; - - fprintf(stderr,"ipodpatcher v" VERSION " - (C) Dave Chapman 2006-2007\n"); - fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); - fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); - - if ((argc > 1) && ((strcmp(argv[1],"-h")==0) || (strcmp(argv[1],"--help")==0))) { - print_usage(); - return 1; - } - - if (ipod_alloc_buffer(§orbuf,BUFFER_SIZE) < 0) { - fprintf(stderr,"Failed to allocate memory buffer\n"); - } - - if ((argc > 1) && (strcmp(argv[1],"--scan")==0)) { - if (ipod_scan(&ipod) == 0) - fprintf(stderr,"[ERR] No ipods found.\n"); - return 0; - } - - /* If the first parameter doesn't start with -, then we interpret it as a device */ - if ((argc > 1) && (argv[1][0] != '-')) { - ipod.diskname[0]=0; -#ifdef __WIN32__ - snprintf(ipod.diskname,sizeof(ipod.diskname),"\\\\.\\PhysicalDrive%s",argv[1]); -#else - strncpy(ipod.diskname,argv[1],sizeof(ipod.diskname)); -#endif - i = 2; - } else { - /* Autoscan for ipods */ - n = ipod_scan(&ipod); - if (n==0) { - fprintf(stderr,"[ERR] No ipods found, aborting\n"); - fprintf(stderr,"[ERR] Please connect your ipod and ensure it is in disk mode\n"); - } else if (n > 1) { - fprintf(stderr,"[ERR] %d ipods found, aborting\n",n); - fprintf(stderr,"[ERR] Please connect only one ipod.\n"); - } - - if (n != 1) { -#ifdef WITH_BOOTOBJS - if (argc==1) { - printf("\nPress ENTER to exit ipodpatcher :"); - fgets(yesno,4,stdin); - } -#endif - return 0; - } - - i = 1; - } - -#ifdef WITH_BOOTOBJS - action = INTERACTIVE; -#else - action = NONE; -#endif - - while (i < argc) { - if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) { - action = LIST_IMAGES; - i++; -#ifdef WITH_BOOTOBJS - } else if (strcmp(argv[i],"--install")==0) { - action = INSTALL; - i++; -#endif - } else if ((strcmp(argv[i],"-d")==0) || - (strcmp(argv[i],"--delete-bootloader")==0)) { - action = DELETE_BOOTLOADER; - i++; - } else if ((strcmp(argv[i],"-a")==0) || - (strcmp(argv[i],"--add-bootloader")==0)) { - action = ADD_BOOTLOADER; - type = FILETYPE_DOT_IPOD; - i++; - if (i == argc) { print_usage(); return 1; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-ab")==0) || - (strcmp(argv[i],"--add-bootloader-bin")==0)) { - action = ADD_BOOTLOADER; - type = FILETYPE_DOT_BIN; - i++; - if (i == argc) { print_usage(); return 1; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-rf")==0) || - (strcmp(argv[i],"--read-firmware")==0)) { - action = READ_FIRMWARE; - i++; - if (i == argc) { print_usage(); return 1; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-wf")==0) || - (strcmp(argv[i],"--write-firmware")==0)) { - action = WRITE_FIRMWARE; - type = FILETYPE_DOT_IPOD; - i++; - if (i == argc) { print_usage(); return 1; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-wfb")==0) || - (strcmp(argv[i],"--write-firmware-bin")==0)) { - action = WRITE_FIRMWARE; - type = FILETYPE_DOT_BIN; - i++; - if (i == argc) { print_usage(); return 1; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-r")==0) || - (strcmp(argv[i],"--read-partition")==0)) { - action = READ_PARTITION; - i++; - if (i == argc) { print_usage(); return 1; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-w")==0) || - (strcmp(argv[i],"--write-partition")==0)) { - action = WRITE_PARTITION; - i++; - if (i == argc) { print_usage(); return 1; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-v")==0) || - (strcmp(argv[i],"--verbose")==0)) { - verbose++; - i++; - } else { - print_usage(); return 1; - } - } - - if (ipod.diskname[0]==0) { - print_usage(); - return 1; - } - - if (ipod_open(&ipod, 0) < 0) { - return 1; - } - - fprintf(stderr,"[INFO] Reading partition table from %s\n",ipod.diskname); - fprintf(stderr,"[INFO] Sector size is %d bytes\n",ipod.sector_size); - - if (read_partinfo(&ipod,0) < 0) { - return 2; - } - - display_partinfo(&ipod); - - if (ipod.pinfo[0].start==0) { - fprintf(stderr,"[ERR] No partition 0 on disk:\n"); - display_partinfo(&ipod); - return 3; - } - - read_directory(&ipod); - - if (ipod.nimages <= 0) { - fprintf(stderr,"[ERR] Failed to read firmware directory - nimages=%d\n",ipod.nimages); - return 1; - } - - if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) { - fprintf(stderr,"[ERR] Unknown version number in firmware (%08x)\n", - ipod.ipod_directory[0].vers); - return -1; - } - - printf("[INFO] Ipod model: %s (\"%s\")\n",ipod.modelstr, - ipod.macpod ? "macpod" : "winpod"); - - if (ipod.macpod) { - print_macpod_warning(); - } - - if (action==LIST_IMAGES) { - list_images(&ipod); -#ifdef WITH_BOOTOBJS - } else if (action==INTERACTIVE) { - - printf("Do you wish to install the rockbox bootloader? (y/n) :"); - if (fgets(yesno,4,stdin)) { - if (yesno[0]=='y') { - if (ipod_reopen_rw(&ipod) < 0) { - return 5; - } - - if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) { - fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); - } else { - fprintf(stderr,"[ERR] --install failed.\n"); - } - printf("Press ENTER to exit ipodpatcher :"); - fgets(yesno,4,stdin); - } - } -#endif - } else if (action==DELETE_BOOTLOADER) { - if (ipod_reopen_rw(&ipod) < 0) { - return 5; - } - - if (ipod.ipod_directory[0].entryOffset==0) { - fprintf(stderr,"[ERR] No bootloader detected.\n"); - } else { - if (delete_bootloader(&ipod)==0) { - fprintf(stderr,"[INFO] Bootloader removed.\n"); - } else { - fprintf(stderr,"[ERR] --delete-bootloader failed.\n"); - } - } - } else if (action==ADD_BOOTLOADER) { - if (ipod_reopen_rw(&ipod) < 0) { - return 5; - } - - if (add_bootloader(&ipod, filename, type)==0) { - fprintf(stderr,"[INFO] Bootloader %s written to device.\n",filename); - } else { - fprintf(stderr,"[ERR] --add-bootloader failed.\n"); - } -#ifdef WITH_BOOTOBJS - } else if (action==INSTALL) { - if (ipod_reopen_rw(&ipod) < 0) { - return 5; - } - - if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) { - fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); - } else { - fprintf(stderr,"[ERR] --install failed.\n"); - } -#endif - } else if (action==WRITE_FIRMWARE) { - if (ipod_reopen_rw(&ipod) < 0) { - return 5; - } - - if (write_firmware(&ipod, filename,type)==0) { - fprintf(stderr,"[INFO] Firmware %s written to device.\n",filename); - } else { - fprintf(stderr,"[ERR] --write-firmware failed.\n"); - } - } else if (action==READ_FIRMWARE) { - if (read_firmware(&ipod, filename)==0) { - fprintf(stderr,"[INFO] Firmware read to file %s.\n",filename); - } else { - fprintf(stderr,"[ERR] --read-firmware failed.\n"); - } - } else if (action==READ_PARTITION) { - outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IREAD|S_IWRITE); - if (outfile < 0) { - perror(filename); - return 4; - } - - if (read_partition(&ipod, outfile) < 0) { - fprintf(stderr,"[ERR] --read-partition failed.\n"); - } else { - fprintf(stderr,"[INFO] Partition extracted to %s.\n",filename); - } - close(outfile); - } else if (action==WRITE_PARTITION) { - if (ipod_reopen_rw(&ipod) < 0) { - return 5; - } - - infile = open(filename,O_RDONLY|O_BINARY); - if (infile < 0) { - perror(filename); - return 2; - } - - /* Check filesize is <= partition size */ - inputsize=filesize(infile); - if (inputsize > 0) { - if (inputsize <= (ipod.pinfo[0].size*ipod.sector_size)) { - fprintf(stderr,"[INFO] Input file is %u bytes\n",inputsize); - if (write_partition(&ipod,infile) < 0) { - fprintf(stderr,"[ERR] --write-partition failed.\n"); - } else { - fprintf(stderr,"[INFO] %s restored to partition\n",filename); - } - } else { - fprintf(stderr,"[ERR] File is too large for firmware partition, aborting.\n"); - } - } - - close(infile); - } - - ipod_close(&ipod); - - return 0; -} diff --git a/tools/ipodpatcher/ipodpatcher.h b/tools/ipodpatcher/ipodpatcher.h new file mode 100644 index 0000000000..c533f4c2dc --- /dev/null +++ b/tools/ipodpatcher/ipodpatcher.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: ipodpatcher.c 12237 2007-02-08 21:31:38Z dave $ + * + * Copyright (C) 2006-2007 Dave Chapman + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef _IPODPATCHER_H +#define _IPODPATCHER_H + +#include "ipodio.h" + +/* Size of buffer for disk I/O - 8MB is large enough for any version + of the Apple firmware, but not the Nano's RSRC image. */ +#define BUFFER_SIZE 8*1024*1024 +extern unsigned char* sectorbuf; + +#define FILETYPE_DOT_IPOD 0 +#define FILETYPE_DOT_BIN 1 +#ifdef WITH_BOOTOBJS + #define FILETYPE_INTERNAL 2 +#endif + +void display_partinfo(struct ipod_t* ipod); +int read_partinfo(struct ipod_t* ipod, int silent); +int read_partition(struct ipod_t* ipod, int outfile); +int write_partition(struct ipod_t* ipod, int infile); +int diskmove(struct ipod_t* ipod, int delta); +int add_bootloader(struct ipod_t* ipod, char* filename, int type); +int delete_bootloader(struct ipod_t* ipod); +int write_firmware(struct ipod_t* ipod, char* filename, int type); +int read_firmware(struct ipod_t* ipod, char* filename); +int read_directory(struct ipod_t* ipod); +int list_images(struct ipod_t* ipod); +int getmodel(struct ipod_t* ipod, int ipod_version); +int ipod_scan(struct ipod_t* ipod); +off_t filesize(int fd); + +#endif diff --git a/tools/ipodpatcher/main.c b/tools/ipodpatcher/main.c new file mode 100644 index 0000000000..3c3c0c860a --- /dev/null +++ b/tools/ipodpatcher/main.c @@ -0,0 +1,415 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: ipodpatcher.c 12237 2007-02-08 21:31:38Z dave $ + * + * Copyright (C) 2006-2007 Dave Chapman + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> +#include <inttypes.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "ipodpatcher.h" +#include "ipodio.h" + +#define VERSION "0.8svn" + +int verbose = 0; + +enum { + NONE, +#ifdef WITH_BOOTOBJS + INSTALL, +#endif + INTERACTIVE, + SHOW_INFO, + LIST_IMAGES, + DELETE_BOOTLOADER, + ADD_BOOTLOADER, + READ_FIRMWARE, + WRITE_FIRMWARE, + READ_PARTITION, + WRITE_PARTITION +}; + +void print_macpod_warning(void) +{ + printf("[INFO] ************************************************************************\n"); + printf("[INFO] *** WARNING FOR ROCKBOX USERS\n"); + printf("[INFO] *** You must convert this ipod to FAT32 format (aka a \"winpod\")\n"); + printf("[INFO] *** if you want to run Rockbox. Rockbox WILL NOT work on this ipod.\n"); + printf("[INFO] *** See http://www.rockbox.org/twiki/bin/view/Main/IpodConversionToFAT32\n"); + printf("[INFO] ************************************************************************\n"); +} + +void print_usage(void) +{ + fprintf(stderr,"Usage: ipodpatcher --scan\n"); +#ifdef __WIN32__ + fprintf(stderr," or ipodpatcher [DISKNO] [action]\n"); +#else + fprintf(stderr," or ipodpatcher [device] [action]\n"); +#endif + fprintf(stderr,"\n"); + fprintf(stderr,"Where [action] is one of the following options:\n"); +#ifdef WITH_BOOTOBJS + fprintf(stderr," --install\n"); +#endif + fprintf(stderr," -l, --list\n"); + fprintf(stderr," -r, --read-partition bootpartition.bin\n"); + fprintf(stderr," -w, --write-partition bootpartition.bin\n"); + fprintf(stderr," -rf, --read-firmware filename.ipod\n"); + fprintf(stderr," -wf, --write-firmware filename.ipod\n"); + fprintf(stderr," -wfb, --write-firmware-bin filename.bin\n"); + fprintf(stderr," -a, --add-bootloader filename.ipod\n"); + fprintf(stderr," -ab, --add-bootloader-bin filename.bin\n"); + fprintf(stderr," -d, --delete-bootloader\n"); + fprintf(stderr,"\n"); + +#ifdef __WIN32__ + fprintf(stderr,"DISKNO is the number (e.g. 2) Windows has assigned to your ipod's hard disk.\n"); + fprintf(stderr,"The first hard disk in your computer (i.e. C:\\) will be disk 0, the next disk\n"); + fprintf(stderr,"will be disk 1 etc. ipodpatcher will refuse to access a disk unless it\n"); + fprintf(stderr,"can identify it as being an ipod.\n"); + fprintf(stderr,"\n"); +#else +#if defined(linux) || defined (__linux) + fprintf(stderr,"\"device\" is the device node (e.g. /dev/sda) assigned to your ipod.\n"); +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + fprintf(stderr,"\"device\" is the device node (e.g. /dev/da1) assigned to your ipod.\n"); +#elif defined(__APPLE__) && defined(__MACH__) + fprintf(stderr,"\"device\" is the device node (e.g. /dev/disk1) assigned to your ipod.\n"); +#endif + fprintf(stderr,"ipodpatcher will refuse to access a disk unless it can identify it as being\n"); + fprintf(stderr,"an ipod.\n"); +#endif +} + +int main(int argc, char* argv[]) +{ +#ifdef WITH_BOOTOBJS + char yesno[4]; +#endif + int i; + int n; + int infile, outfile; + unsigned int inputsize; + char* filename; + int action = SHOW_INFO; + int type; + struct ipod_t ipod; + + fprintf(stderr,"ipodpatcher v" VERSION " - (C) Dave Chapman 2006-2007\n"); + fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); + fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); + + if ((argc > 1) && ((strcmp(argv[1],"-h")==0) || (strcmp(argv[1],"--help")==0))) { + print_usage(); + return 1; + } + + if (ipod_alloc_buffer(§orbuf,BUFFER_SIZE) < 0) { + fprintf(stderr,"Failed to allocate memory buffer\n"); + } + + if ((argc > 1) && (strcmp(argv[1],"--scan")==0)) { + if (ipod_scan(&ipod) == 0) + fprintf(stderr,"[ERR] No ipods found.\n"); + return 0; + } + + /* If the first parameter doesn't start with -, then we interpret it as a device */ + if ((argc > 1) && (argv[1][0] != '-')) { + ipod.diskname[0]=0; +#ifdef __WIN32__ + snprintf(ipod.diskname,sizeof(ipod.diskname),"\\\\.\\PhysicalDrive%s",argv[1]); +#else + strncpy(ipod.diskname,argv[1],sizeof(ipod.diskname)); +#endif + i = 2; + } else { + /* Autoscan for ipods */ + n = ipod_scan(&ipod); + if (n==0) { + fprintf(stderr,"[ERR] No ipods found, aborting\n"); + fprintf(stderr,"[ERR] Please connect your ipod and ensure it is in disk mode\n"); + } else if (n > 1) { + fprintf(stderr,"[ERR] %d ipods found, aborting\n",n); + fprintf(stderr,"[ERR] Please connect only one ipod.\n"); + } + + if (n != 1) { +#ifdef WITH_BOOTOBJS + if (argc==1) { + printf("\nPress ENTER to exit ipodpatcher :"); + fgets(yesno,4,stdin); + } +#endif + return 0; + } + + i = 1; + } + +#ifdef WITH_BOOTOBJS + action = INTERACTIVE; +#else + action = NONE; +#endif + + while (i < argc) { + if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) { + action = LIST_IMAGES; + i++; +#ifdef WITH_BOOTOBJS + } else if (strcmp(argv[i],"--install")==0) { + action = INSTALL; + i++; +#endif + } else if ((strcmp(argv[i],"-d")==0) || + (strcmp(argv[i],"--delete-bootloader")==0)) { + action = DELETE_BOOTLOADER; + i++; + } else if ((strcmp(argv[i],"-a")==0) || + (strcmp(argv[i],"--add-bootloader")==0)) { + action = ADD_BOOTLOADER; + type = FILETYPE_DOT_IPOD; + i++; + if (i == argc) { print_usage(); return 1; } + filename=argv[i]; + i++; + } else if ((strcmp(argv[i],"-ab")==0) || + (strcmp(argv[i],"--add-bootloader-bin")==0)) { + action = ADD_BOOTLOADER; + type = FILETYPE_DOT_BIN; + i++; + if (i == argc) { print_usage(); return 1; } + filename=argv[i]; + i++; + } else if ((strcmp(argv[i],"-rf")==0) || + (strcmp(argv[i],"--read-firmware")==0)) { + action = READ_FIRMWARE; + i++; + if (i == argc) { print_usage(); return 1; } + filename=argv[i]; + i++; + } else if ((strcmp(argv[i],"-wf")==0) || + (strcmp(argv[i],"--write-firmware")==0)) { + action = WRITE_FIRMWARE; + type = FILETYPE_DOT_IPOD; + i++; + if (i == argc) { print_usage(); return 1; } + filename=argv[i]; + i++; + } else if ((strcmp(argv[i],"-wfb")==0) || + (strcmp(argv[i],"--write-firmware-bin")==0)) { + action = WRITE_FIRMWARE; + type = FILETYPE_DOT_BIN; + i++; + if (i == argc) { print_usage(); return 1; } + filename=argv[i]; + i++; + } else if ((strcmp(argv[i],"-r")==0) || + (strcmp(argv[i],"--read-partition")==0)) { + action = READ_PARTITION; + i++; + if (i == argc) { print_usage(); return 1; } + filename=argv[i]; + i++; + } else if ((strcmp(argv[i],"-w")==0) || + (strcmp(argv[i],"--write-partition")==0)) { + action = WRITE_PARTITION; + i++; + if (i == argc) { print_usage(); return 1; } + filename=argv[i]; + i++; + } else if ((strcmp(argv[i],"-v")==0) || + (strcmp(argv[i],"--verbose")==0)) { + verbose++; + i++; + } else { + print_usage(); return 1; + } + } + + if (ipod.diskname[0]==0) { + print_usage(); + return 1; + } + + if (ipod_open(&ipod, 0) < 0) { + return 1; + } + + fprintf(stderr,"[INFO] Reading partition table from %s\n",ipod.diskname); + fprintf(stderr,"[INFO] Sector size is %d bytes\n",ipod.sector_size); + + if (read_partinfo(&ipod,0) < 0) { + return 2; + } + + display_partinfo(&ipod); + + if (ipod.pinfo[0].start==0) { + fprintf(stderr,"[ERR] No partition 0 on disk:\n"); + display_partinfo(&ipod); + return 3; + } + + read_directory(&ipod); + + if (ipod.nimages <= 0) { + fprintf(stderr,"[ERR] Failed to read firmware directory - nimages=%d\n",ipod.nimages); + return 1; + } + + if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) { + fprintf(stderr,"[ERR] Unknown version number in firmware (%08x)\n", + ipod.ipod_directory[0].vers); + return -1; + } + + printf("[INFO] Ipod model: %s (\"%s\")\n",ipod.modelstr, + ipod.macpod ? "macpod" : "winpod"); + + if (ipod.macpod) { + print_macpod_warning(); + } + + if (action==LIST_IMAGES) { + list_images(&ipod); +#ifdef WITH_BOOTOBJS + } else if (action==INTERACTIVE) { + + printf("Do you wish to install the rockbox bootloader? (y/n) :"); + if (fgets(yesno,4,stdin)) { + if (yesno[0]=='y') { + if (ipod_reopen_rw(&ipod) < 0) { + return 5; + } + + if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) { + fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); + } else { + fprintf(stderr,"[ERR] --install failed.\n"); + } + printf("Press ENTER to exit ipodpatcher :"); + fgets(yesno,4,stdin); + } + } +#endif + } else if (action==DELETE_BOOTLOADER) { + if (ipod_reopen_rw(&ipod) < 0) { + return 5; + } + + if (ipod.ipod_directory[0].entryOffset==0) { + fprintf(stderr,"[ERR] No bootloader detected.\n"); + } else { + if (delete_bootloader(&ipod)==0) { + fprintf(stderr,"[INFO] Bootloader removed.\n"); + } else { + fprintf(stderr,"[ERR] --delete-bootloader failed.\n"); + } + } + } else if (action==ADD_BOOTLOADER) { + if (ipod_reopen_rw(&ipod) < 0) { + return 5; + } + + if (add_bootloader(&ipod, filename, type)==0) { + fprintf(stderr,"[INFO] Bootloader %s written to device.\n",filename); + } else { + fprintf(stderr,"[ERR] --add-bootloader failed.\n"); + } +#ifdef WITH_BOOTOBJS + } else if (action==INSTALL) { + if (ipod_reopen_rw(&ipod) < 0) { + return 5; + } + + if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) { + fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); + } else { + fprintf(stderr,"[ERR] --install failed.\n"); + } +#endif + } else if (action==WRITE_FIRMWARE) { + if (ipod_reopen_rw(&ipod) < 0) { + return 5; + } + + if (write_firmware(&ipod, filename,type)==0) { + fprintf(stderr,"[INFO] Firmware %s written to device.\n",filename); + } else { + fprintf(stderr,"[ERR] --write-firmware failed.\n"); + } + } else if (action==READ_FIRMWARE) { + if (read_firmware(&ipod, filename)==0) { + fprintf(stderr,"[INFO] Firmware read to file %s.\n",filename); + } else { + fprintf(stderr,"[ERR] --read-firmware failed.\n"); + } + } else if (action==READ_PARTITION) { + outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IREAD|S_IWRITE); + if (outfile < 0) { + perror(filename); + return 4; + } + + if (read_partition(&ipod, outfile) < 0) { + fprintf(stderr,"[ERR] --read-partition failed.\n"); + } else { + fprintf(stderr,"[INFO] Partition extracted to %s.\n",filename); + } + close(outfile); + } else if (action==WRITE_PARTITION) { + if (ipod_reopen_rw(&ipod) < 0) { + return 5; + } + + infile = open(filename,O_RDONLY|O_BINARY); + if (infile < 0) { + perror(filename); + return 2; + } + + /* Check filesize is <= partition size */ + inputsize=filesize(infile); + if (inputsize > 0) { + if (inputsize <= (ipod.pinfo[0].size*ipod.sector_size)) { + fprintf(stderr,"[INFO] Input file is %u bytes\n",inputsize); + if (write_partition(&ipod,infile) < 0) { + fprintf(stderr,"[ERR] --write-partition failed.\n"); + } else { + fprintf(stderr,"[INFO] %s restored to partition\n",filename); + } + } else { + fprintf(stderr,"[ERR] File is too large for firmware partition, aborting.\n"); + } + } + + close(infile); + } + + ipod_close(&ipod); + + return 0; +} |