45 #include <sys/types.h> 57 static void debug_print_volume_id_and_filename(
int iso_type,
58 unsigned char *buf,
char *filename)
62 int i, ofs = iso_type == 3? 48 : 40;
64 memcpy(str, buf + ofs,
sizeof(str));
65 str[32] =
'\0'; i = 31;
67 while (i >= 0 && str[i]==
' ')
73 ofs = iso_type == 3? 16 : 8;
74 memcpy(str, buf + ofs,
sizeof(str));
75 str[32] =
'\0'; i = 31;
76 while (i >= 0 && str[i]==
' ')
84 debug(
":%s\n", filename);
100 int disk_id,
int disk_type,
int iso_type,
unsigned char *buf,
101 int *n_loadp,
char ***load_namesp)
104 uint64_t dirofs, fileofs;
106 unsigned char *dirbuf = NULL, *dp, *match_entry = NULL, *filebuf = NULL;
107 char *p, *filename_orig, *filename, *tmpfname = NULL;
109 const char *tmpdir = getenv(
"TMPDIR");
116 filename_orig = filename;
118 debug(
"ISO9660 boot:\n");
121 debug_print_volume_id_and_filename(iso_type, buf, filename);
134 unsigned char tmpbuf[0x800];
136 res2 =
diskimage_access(m, disk_id, disk_type, 0, base_offset + 0x9000, tmpbuf, 0x800);
138 fatal(
"Couldn't read MKI part after the ISO header of the disk image. Aborting.\n");
142 int64_t suggestedBaseOffset = 0;
143 tmpbuf[
sizeof(tmpbuf)-1] =
'\0';
144 char* found = strstr((
char*)tmpbuf,
"MKI ");
146 found = strstr(found,
" -C 0,");
148 suggestedBaseOffset = strtoll(found + 6, NULL, 0);
153 suggestedBaseOffset *= 2048;
154 if (currentBaseOffset == 0 && suggestedBaseOffset != currentBaseOffset)
156 debug(
"NOTE: automagically adjusting to use base offset %lli\n", (
long long)suggestedBaseOffset);
166 dirlen = buf[0x84] + 256*buf[0x85] + 65536*buf[0x86];
167 if (dirlen != buf[0x8b] + 256*buf[0x8a] + 65536*buf[0x89])
168 fatal(
"WARNING: Root directory length mismatch?\n");
170 dirofs = (int64_t)(buf[0x8c] + (buf[0x8d] << 8) + (buf[0x8e] << 16) +
171 ((uint64_t)buf[0x8f] << 24)) * 2048;
174 debug(
"root = %i bytes at 0x%llx\n", dirlen, (
long long)dirofs);
181 fatal(
"Couldn't read the disk image. Aborting.\n");
186 dp = dirbuf; filenr = 1;
188 while (dp < dirbuf + dirlen) {
189 size_t i, nlen = dp[0];
190 int x = dp[2] + (dp[3] << 8) + (dp[4] << 16) +
191 ((uint64_t)dp[5] << 24);
192 int y = dp[6] + (dp[7] << 8);
201 p = strchr(filename,
'/');
203 p = strchr(filename,
'\\');
206 debug(
"%i%s: %i, %i, \"", filenr, filenr == found_dir?
207 " [CURRENT]" :
"", x, y);
209 for (i=0; i<nlen && i<
sizeof(direntry)-1; i++)
223 if ((p != NULL && strncasecmp(filename, direntry, nlen) == 0
224 && nlen == (
size_t)p - (
size_t)filename && found_dir == y)
225 || (p == NULL && direntry[0] ==
'\0') ) {
229 dirofs = 2048 * (int64_t)x;
241 p = strchr(filename,
'/');
243 p = strchr(filename,
'\\');
246 char *blah = filename_orig;
248 fatal(
"could not find '%s' (1) in /", filename);
251 while (blah != filename)
252 fatal(
"%c", *blah++);
268 if ((dirofs & 2047) + 70 > 2047) {
269 dirofs = (dirofs | 2047) + 1;
277 fatal(
"Couldn't read the disk image. Aborting.\n");
296 printf(
"filename = '%s'\n", filename);
299 for (j=32; j<len; j++)
300 printf(
"%c", dp[j] >=
' ' && dp[j] < 128? dp[j] :
'.');
308 for (i=32; i<len; i++) {
309 if (i < len -
strlen(filename))
310 if (strncmp(filename, (
char *)dp + i,
314 if (match_entry != NULL) {
315 fatal(
"TODO: I'm too lazy to" 316 " implement a correct " 317 "directory parser right " 323 memcpy(match_entry, dp, 512);
328 if (match_entry != NULL)
334 if (match_entry == NULL) {
335 char *blah = filename_orig;
337 fatal(
"could not find '%s' (2) in /", filename);
340 while (blah != filename)
341 fatal(
"%c", *blah++);
347 fileofs = match_entry[2] + (match_entry[3] << 8) +
348 (match_entry[4] << 16) + ((uint64_t)match_entry[5] << 24);
349 filelen = match_entry[10] + (match_entry[11] << 8) +
350 (match_entry[12] << 16) + ((uint64_t)match_entry[13] << 24);
359 snprintf(tmpfname, 300,
"%s/gxemul.XXXXXXXXXXXX", tmpdir);
364 fatal(
"could not read the file from the disk image!\n");
368 tmpfile_handle = mkstemp(tmpfname);
369 if (tmpfile_handle < 0) {
370 fatal(
"could not create %s\n", tmpfname);
374 if (write(tmpfile_handle, filebuf, filelen) != filelen) {
375 fatal(
"could not write to %s\n", tmpfname);
380 close(tmpfile_handle);
382 debug(
"extracted %lli bytes into %s\n", (
long long)filelen, tmpfname);
386 CHECK_ALLOCATION(new_array = (
char **) malloc(
sizeof(
char *) * (*n_loadp)));
387 memcpy(new_array, *load_namesp,
sizeof(
char *) * (*n_loadp));
388 *load_namesp = new_array;
394 memmove(tmpfname + 1, tmpfname,
strlen(tmpfname) + 1);
397 (*load_namesp)[*n_loadp - 1] = strdup(tmpfname);
408 if (match_entry != NULL)
411 if (tmpfname != NULL)
void fatal(const char *fmt,...)
#define DEBUG_INDENTATION
int iso_load_bootblock(struct machine *m, struct cpu *cpu, int disk_id, int disk_type, int iso_type, unsigned char *buf, int *n_loadp, char ***load_namesp)
void diskimage_set_baseoffset(struct machine *machine, int id, int type, int64_t offset)
#define CHECK_ALLOCATION(ptr)
char * boot_kernel_filename
int64_t diskimage_get_baseoffset(struct machine *machine, int id, int type)
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
void debug_indentation(int diff)
int diskimage_access(struct machine *machine, int id, int type, int writeflag, off_t offset, unsigned char *buf, size_t len)