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");
380 static int overlay_has_block(
struct diskimage *d,
int overlay_nr, off_t ofs)
383 off_t bitmap_file_offset = bit_nr / 8;
388 bitmap_file_offset, SEEK_SET);
397 if (
data & (1 << (bit_nr & 7)))
410 static size_t fwrite_helper(off_t offset,
unsigned char *buf,
417 int res = my_fseek(d->
f, offset, SEEK_SET);
419 fatal(
"[ diskimage__internal_access(): fseek() failed"
420 " on disk id %i \n", d->
id);
424 return fwrite(buf, 1, len, d->
f);
428 fatal(
"TODO: overlay access (write), len not multiple of "
429 "overlay block size. not yet implemented.\n");
430 fatal(
"len = %lli\n", (
long long) len);
434 fatal(
"TODO: unaligned overlay access\n");
435 fatal(
"offset = %lli\n", (
long long) offset);
440 for (curofs = offset; curofs < (off_t) (offset+len);
448 fatal(
"[ diskimage__internal_access(): fseek()"
449 " failed on disk id %i \n", d->
id);
458 overlay_set_block_in_use(d, overlay_nr, curofs);
472 static size_t fread_helper(off_t offset,
unsigned char *buf,
476 size_t totallenread = 0;
480 int res = my_fseek(d->
f, offset, SEEK_SET);
482 fatal(
"[ diskimage__internal_access(): fseek() failed"
483 " on disk id %i \n", d->
id);
487 return fread(buf, 1, len, d->
f);
491 for (curofs=offset; len != 0;
494 off_t lenread, lentoread;
497 overlay_nr >= 0; overlay_nr --) {
498 if (overlay_has_block(d, overlay_nr, curofs))
504 if (overlay_nr >= 0) {
509 fatal(
"[ diskimage__internal_access(): fseek()"
510 " failed on disk id %i \n", d->
id);
513 lenread = fread(buf, 1, lentoread,
517 int res = my_fseek(d->
f, curofs, SEEK_SET);
519 fatal(
"[ diskimage__internal_access(): fseek()"
520 " failed on disk id %i \n", d->
id);
523 lenread = fread(buf, 1, lentoread, d->
f);
526 if (lenread != lentoread) {
527 fatal(
"[ INCOMPLETE READ from disk id %i, offset"
528 " %lli ]\n", d->
id, (
long long)curofs);
532 totallenread += lenread;
548 off_t offset,
unsigned char *buf,
size_t len)
553 fprintf(stderr,
"diskimage__internal_access(): buf = NULL\n");
565 lendone = fwrite_helper(offset, buf, len, d);
573 lendone = diskimage_access__cdrom(d, offset, buf, len);
575 lendone = fread_helper(offset, buf, len, d);
577 if (lendone < (ssize_t)len)
578 memset(buf + lendone, 0, len - lendone);
582 if (lendone != (ssize_t)len) {
583 #ifdef UNSTABLE_DEVEL
588 (
"[ diskimage__internal_access(): disk_id %i, offset %lli"
589 ", transfer not completed. len=%i, len_done=%i ]\n",
590 d->
id, (
long long)offset, (
int)len, (int)lendone);
606 off_t offset,
unsigned char *buf,
size_t len)
617 fatal(
"[ diskimage_access(): ERROR: trying to access a "
618 "non-existant %s disk image (id %i)\n",
619 diskimage_types[
type],
id);
625 debug(
"[ reading before start of disk image ]\n");
662 int id = 0, override_heads=0, override_spt=0;
665 int prefix_b=0, prefix_c=0, prefix_d=0, prefix_f=0, prefix_g=0;
666 int prefix_i=0, prefix_r=0, prefix_s=0, prefix_t=0, prefix_id=-1;
667 int prefix_o=0, prefix_V=0;
670 fprintf(stderr,
"diskimage_add(): NULL ptr\n");
675 cp = strchr(
fname,
':');
677 while (
fname <= cp) {
704 override_heads = atoi(
fname);
709 override_spt = atoi(
fname);
715 if (override_heads < 1 ||
717 fatal(
"Bad geometry: heads=%i "
718 "spt=%i\n", override_heads,
735 fatal(
"Bad base offset: %" PRIi64
755 fprintf(stderr,
"diskimage_add(): invalid "
756 "prefix char '%c'\n", c);
776 if (prefix_i + prefix_f + prefix_s > 1) {
777 fprintf(stderr,
"Invalid disk image prefix(es). You can"
778 "only use one of i, f, and s\nfor each disk image.\n");
794 fprintf(stderr,
"The 'V' disk image prefix requires"
795 " a disk ID to also be supplied.\n");
800 if (d->
type == dx->
type && prefix_id == dx->
id)
806 fprintf(stderr,
"Bad ID supplied for overlay?\n");
824 while (d2->
next != NULL)
879 && !prefix_i && !prefix_s)
885 fatal(
"\nTODO: small (non-80-cylinder) floppies?\n\n");
898 d->
heads = override_heads;
918 debug(
"NOTE: '%s' is read-only in the host file system, but 'r:' was not used.\n\n", d->
fname);
924 char *errmsg = (
char *) malloc(200 +
strlen(
fname));
926 "could not fopen %s for reading%s",
fname,
933 if (prefix_id == -1) {
934 int free = 0, collision = 1;
966 fprintf(stderr,
"disk image id %i "
967 "already in use\n",
id);
1020 char *buf,
size_t bufsize)
1029 char *p = strrchr(d->
fname,
'/');
1034 snprintf(buf, bufsize,
"%s", p);
1124 debug(
" (%lli sectors)", (
long long)
1132 debug(
"overlay %i: %s\n",