1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by William Poetra Yoga Hadisoeseno
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
27 #include <sys/types.h>
34 fprintf(stderr
, "usage: IHFSsplit <ihfs_img> <output_dir>\n");
49 #define MAX_FILES 2048
50 #define MAX_IHFS_PATH 56
54 char fullpath
[MAX_IHFS_PATH
];
60 #define SECTOR_SIZE 512
62 int ihfs_sanity(const int ihfs_img
)
65 ihfs_header_t ihfs_hdr
;
67 printf("starting sanity check for IHFS image...\n");
69 lseek(ihfs_img
, 0, SEEK_SET
);
70 read(ihfs_img
, &ihfs_hdr
, sizeof (ihfs_hdr
));
72 printf(" checking for IHFS signature...\n");
73 if (ihfs_hdr
.signature
!= 0x49484653)
76 printf(" checking for FS length...\n");
77 fstat(ihfs_img
, &statbuf
);
78 if (ihfs_hdr
.fslen
* SECTOR_SIZE
!= statbuf
.st_size
)
81 printf(" checking for unknown value 1...\n");
82 if (ihfs_hdr
.unknown1
!= 0x00000004)
85 printf(" checking for unknown value 2...\n");
86 if (ihfs_hdr
.unknown2
!= 0xfffff000)
89 printf(" checking for number of files...\n");
90 if (ihfs_hdr
.numfiles
> MAX_FILES
)
93 printf(" checking for marker...\n");
94 if (ihfs_hdr
.marker
!= 0x55aa55aa)
100 void mkdir_p(const char *path
)
104 dir
= dirname(strdup(path
));
105 if (strchr(dir
, '/'))
115 #define BUF_SIZE 4096
117 void outputfile(const char *outpath
, const int ihfs_img
, const int offset
, const int length
)
123 lseek(ihfs_img
, offset
, SEEK_SET
);
125 outfd
= creat(outpath
, 0644);
127 for (i
= 0; i
< length
/ BUF_SIZE
; ++i
) {
128 read(ihfs_img
, buf
, BUF_SIZE
);
129 write(outfd
, buf
, BUF_SIZE
);
131 rem
= length
- i
* BUF_SIZE
;
133 read(ihfs_img
, buf
, rem
);
134 write(outfd
, buf
, rem
);
140 int main(int argc
, char **argv
)
144 ihfs_header_t ihfs_hdr
;
145 ihfs_file_table_t ihfs_ftbl
;
147 char *outpath
, *base_path
, ihfs_path
[MAX_IHFS_PATH
+1];
149 /* check the arguments */
154 stat(argv
[1], &statbuf
);
155 if (!S_ISREG(statbuf
.st_mode
))
158 stat(argv
[2], &statbuf
);
159 if (!S_ISDIR(statbuf
.st_mode
))
162 /* check the file, then split */
164 ihfs_img
= open(argv
[1], O_RDONLY
);
166 if (ihfs_sanity(ihfs_img
)) {
167 printf("Non-IHFS format!\n");
170 printf("sanity check OK\n");
172 lseek(ihfs_img
, 0, SEEK_SET
);
173 read(ihfs_img
, &ihfs_hdr
, sizeof (ihfs_hdr
));
174 lseek(ihfs_img
, 4 * SECTOR_SIZE
, SEEK_SET
);
175 read(ihfs_img
, &ihfs_ftbl
, sizeof (ihfs_ftbl
));
177 base_path
= strdup(argv
[2]);
178 outpath
= malloc(strlen(base_path
) + 1 + MAX_IHFS_PATH
+ 1);
179 for (i
= 0; i
< ihfs_hdr
.numfiles
; ++i
) {
181 printf("pathname: %s\n", ihfs_ftbl
.files
[i
].fullpath
);
182 printf("starts at sector %d, length is %d bytes\n", ihfs_ftbl
.files
[i
].sector
, ihfs_ftbl
.files
[i
].length
);
184 strncpy(ihfs_path
, ihfs_ftbl
.files
[i
].fullpath
, MAX_IHFS_PATH
);
185 ihfs_path
[MAX_IHFS_PATH
] = '\0';
186 for (j
= 0; j
< strlen(ihfs_path
); ++j
)
187 if (ihfs_path
[j
] == '\\')
190 sprintf(outpath
, "%s/%s", base_path
, ihfs_path
);
192 outputfile(outpath
, ihfs_img
, ihfs_ftbl
.files
[i
].sector
* SECTOR_SIZE
, ihfs_ftbl
.files
[i
].length
);