38 #include <sys/types.h>
69 static int my_fseek(FILE *
f, off_t offset,
int whence)
72 if (whence == SEEK_SET) {
77 fseek(
f, 0, SEEK_SET);
78 while (curoff < offset) {
80 cur_step = offset - curoff;
81 if (cur_step > 2000000000)
82 cur_step = 2000000000;
83 res = fseek(
f, cur_step, SEEK_CUR);
90 return fseek(
f, offset, whence);
92 return fseeko(
f, offset, whence);
136 if (overlay.
f_data == NULL) {
144 fprintf(stderr,
"Please create the map file first.\n");
171 res = stat(d->
fname, &st);
173 fprintf(stderr,
"[ diskimage_recalc_size(): could not stat "
174 "'%s' ]\n", d->
fname);
255 fatal(
"diskimage_set_baseoffset(): disk id %i (type %i) not found?\n",
256 id, diskimage_types[
type]);
267 int *c,
int *h,
int *s)
280 fatal(
"diskimage_getchs(): disk id %i (type %i) not found?\n",
281 id, diskimage_types[
type]);
301 #define CDROM_SECTOR_SIZE 2048
302 static size_t diskimage_access__cdrom(
struct diskimage *d, off_t offset,
303 unsigned char *buf,
size_t len)
305 off_t aligned_offset;
306 size_t bytes_read, total_copied = 0;
308 off_t buf_ofs, i = 0;
314 my_fseek(d->
f, aligned_offset, SEEK_SET);
322 buf_ofs = offset - aligned_offset;
324 buf[i ++] = cdrom_buf[buf_ofs ++];
330 offset = aligned_offset;
338 static void overlay_set_block_in_use(
struct diskimage *d,
339 int overlay_nr, off_t ofs)
342 off_t bitmap_file_offset = bit_nr / 8;
347 bitmap_file_offset, SEEK_SET);
350 fprintf(stderr,
"Could not seek in bitmap file?"
351 " offset = %lli, read\n", (
long long)bitmap_file_offset);
360 data |= (1 << (bit_nr & 7));
364 bitmap_file_offset, SEEK_SET);
367 fprintf(stderr,
"Could not seek in bitmap file?"
368 " offset = %lli, write\n", (
long long)bitmap_file_offset);
373 fprintf(stderr,
"Could not write to bitmap file. Aborting.\n");
383 static int overlay_has_block(
struct diskimage *d,
int overlay_nr, off_t ofs)
386 off_t bitmap_file_offset = bit_nr / 8;
391 bitmap_file_offset, SEEK_SET);
400 if (
data & (1 << (bit_nr & 7)))
413 static size_t fwrite_helper(off_t offset,
unsigned char *buf,
420 int res = my_fseek(d->
f, offset, SEEK_SET);
422 fatal(
"[ diskimage__internal_access(): fseek() failed"
423 " on disk id %i \n", d->
id);
427 size_t written = fwrite(buf, 1, len, d->
f);
436 fatal(
"TODO: overlay access (write), len not multiple of "
437 "overlay block size. not yet implemented.\n");
438 fatal(
"len = %lli\n", (
long long) len);
442 fatal(
"TODO: unaligned overlay access\n");
443 fatal(
"offset = %lli\n", (
long long) offset);
448 for (curofs = offset; curofs < (off_t) (offset+len);
456 fatal(
"[ diskimage__internal_access(): fseek()"
457 " failed on disk id %i \n", d->
id);
469 overlay_set_block_in_use(d, overlay_nr, curofs);
483 static size_t fread_helper(off_t offset,
unsigned char *buf,
487 size_t totallenread = 0;
491 int res = my_fseek(d->
f, offset, SEEK_SET);
493 fatal(
"[ diskimage__internal_access(): fseek() failed"
494 " on disk id %i \n", d->
id);
498 return fread(buf, 1, len, d->
f);
502 for (curofs=offset; len != 0;
505 off_t lenread, lentoread;
508 overlay_nr >= 0; overlay_nr --) {
509 if (overlay_has_block(d, overlay_nr, curofs))
515 if (overlay_nr >= 0) {
520 fatal(
"[ diskimage__internal_access(): fseek()"
521 " failed on disk id %i \n", d->
id);
524 lenread = fread(buf, 1, lentoread,
528 int res = my_fseek(d->
f, curofs, SEEK_SET);
530 fatal(
"[ diskimage__internal_access(): fseek()"
531 " failed on disk id %i \n", d->
id);
534 lenread = fread(buf, 1, lentoread, d->
f);
537 if (lenread != lentoread) {
538 fatal(
"[ INCOMPLETE READ from disk id %i, offset"
539 " %lli ]\n", d->
id, (
long long)curofs);
543 totallenread += lenread;
559 off_t offset,
unsigned char *buf,
size_t len)
564 fprintf(stderr,
"diskimage__internal_access(): buf = NULL\n");
576 lendone = fwrite_helper(offset, buf, len, d);
584 lendone = diskimage_access__cdrom(d, offset, buf, len);
586 lendone = fread_helper(offset, buf, len, d);
588 if (lendone >= 0 && lendone < (ssize_t)len)
589 memset(buf + lendone, 0, len - lendone);
600 fatal(
"[ diskimage__internal_access(): disk_id %i, offset %lli"
601 ", transfer not completed. len=%i, len_done=%i ]\n",
602 d->
id, (
long long)offset, (
int)len, (
int)lendone);
618 off_t offset,
unsigned char *buf,
size_t len)
629 fatal(
"[ diskimage_access(): ERROR: trying to access a "
630 "non-existant %s disk image (id %i)\n",
631 diskimage_types[
type],
id);
637 debug(
"[ reading before start of disk image ]\n");
674 int id = 0, override_heads=0, override_spt=0;
677 int prefix_b=0, prefix_c=0, prefix_d=0, prefix_f=0, prefix_g=0;
678 int prefix_i=0, prefix_r=0, prefix_s=0, prefix_t=0, prefix_id=-1;
679 int prefix_o=0, prefix_V=0;
682 fprintf(stderr,
"diskimage_add(): NULL ptr\n");
687 cp = strchr(
fname,
':');
689 while (
fname <= cp) {
716 override_heads = atoi(
fname);
721 override_spt = atoi(
fname);
727 if (override_heads < 1 ||
729 fatal(
"Bad geometry: heads=%i "
730 "spt=%i\n", override_heads,
747 fatal(
"Bad base offset: %" PRIi64
767 fprintf(stderr,
"diskimage_add(): invalid "
768 "prefix char '%c'\n", c);
788 if (prefix_i + prefix_f + prefix_s > 1) {
789 fprintf(stderr,
"Invalid disk image prefix(es). You can"
790 "only use one of i, f, and s\nfor each disk image.\n");
806 fprintf(stderr,
"The 'V' disk image prefix requires"
807 " a disk ID to also be supplied.\n");
812 if (d->
type == dx->
type && prefix_id == dx->
id)
818 fprintf(stderr,
"Bad ID supplied for overlay?\n");
836 while (d2->
next != NULL)
891 && !prefix_i && !prefix_s)
897 fatal(
"\nTODO: small (non-80-cylinder) floppies?\n\n");
910 d->
heads = override_heads;
930 debug(
"NOTE: '%s' is read-only in the host file system, but 'r:' was not used.\n\n", d->
fname);
936 char *errmsg = (
char *) malloc(200 +
strlen(
fname));
938 "could not fopen %s for reading%s",
fname,
945 if (prefix_id == -1) {
946 int free = 0, collision = 1;
978 fprintf(stderr,
"disk image id %i "
979 "already in use\n",
id);
1032 char *buf,
size_t bufsize)
1041 char *p = strrchr(d->
fname,
'/');
1046 snprintf(buf, bufsize,
"%s", p);
1136 debug(
" (%lli sectors)", (
long long)
1144 debug(
"overlay %i: %s\n",