예제 #1
0
static int disk_image_check_for_d1m(disk_image_t *image)
{
    unsigned int blk = 0;
    char *ext;
    size_t len;
    BYTE block[256];
    fsimage_t *fsimage;

    fsimage = image->media.fsimage;

    /* reject files with unknown size */
    if (!(IS_D1M_LEN(util_file_length(fsimage->fd)))) {
        return 0;
    }

    /* .d81 images share the same sizes with .d1m, so we reject based on the
       file extension what is likely a .d81 image */
    ext = util_get_extension(fsimage->name);
    if ((ext[0]) && (ext[1] == '8') && (ext[2] == '1')) {
        return 0;
    }

    image->type = DISK_IMAGE_TYPE_D1M;
    image->tracks = NUM_TRACKS_1000;
    image->max_half_tracks = MAX_TRACKS_1000 * 2;

    rewind(fsimage->fd);

    while ((len = fread(block, 1, 256, fsimage->fd)) == 256) {
        if (++blk > NUM_BLOCKS_1000 + 13) {
            log_error(disk_image_probe_log, "Disk image too large.");
            break;
        }
    }

    if (disk_image_check_min_block(blk, NUM_BLOCKS_1000) < 0) {
        return 0;
    }

    switch (blk) {
        case NUM_BLOCKS_1000:
        case NUM_BLOCKS_1000 + 12: /* with errors */
            image->tracks = NUM_TRACKS_1000;
            image->max_half_tracks = MAX_TRACKS_1000 * 2;
            break;
        default:
            return 0;
    }
    disk_image_check_log(image, "D1M");
    return 1;
}
예제 #2
0
static int disk_image_check_for_d71(disk_image_t *image)
{
    unsigned int blk = 0;
    size_t len;
    BYTE block[256];
    fsimage_t *fsimage;
    size_t checkimage_realsize;
    int checkimage_errorinfo;

    fsimage = image->media.fsimage;
    checkimage_realsize = util_file_length(fsimage->fd);
    checkimage_errorinfo = 0;

    if (!(IS_D71_LEN(checkimage_realsize))) {
        return 0;
    }

    checkimage_errorinfo = (checkimage_realsize == D71_FILE_SIZE_E) ? 1 : 0;

    image->type = DISK_IMAGE_TYPE_D71;
    image->tracks = NUM_TRACKS_1571;
    image->max_half_tracks = MAX_TRACKS_1571 * 2;

    rewind(fsimage->fd);

    while ((len = fread(block, 1, 256, fsimage->fd)) == 256) {
        if (++blk == NUM_BLOCKS_1571) {
            break;
        }
    }

    if (disk_image_check_min_block(blk, NUM_BLOCKS_1571) < 0) {
        return 0;
    }

    if (checkimage_errorinfo) {
        fsimage->error_info.map = lib_calloc(1, blk);
        fsimage->error_info.len = blk;
        if (util_fpread(fsimage->fd, fsimage->error_info.map, blk, 256 * blk) < 0) {
            return 0;
        }
    }

    disk_image_check_log(image, "D71");
    return 1;
}
예제 #3
0
static int disk_image_check_for_d4m(disk_image_t *image)
{
    unsigned int blk = 0;
    size_t len;
    BYTE block[256];
    fsimage_t *fsimage;

    fsimage = image->media.fsimage;
    image->tracks = NUM_TRACKS_2000;

    if (!(IS_D4M_LEN(util_file_length(fsimage->fd)))) {
        return 0;
    }

    image->type = DISK_IMAGE_TYPE_D4M;
    image->tracks = NUM_TRACKS_4000;
    image->max_half_tracks = MAX_TRACKS_4000 * 2;

    rewind(fsimage->fd);

    while ((len = fread(block, 1, 256, fsimage->fd)) == 256) {
        if (++blk > NUM_BLOCKS_4000 + 51) {
            log_error(disk_image_probe_log, "Disk image too large.");
            break;
        }
    }

    if (disk_image_check_min_block(blk, NUM_BLOCKS_4000) < 0) {
        return 0;
    }

    switch (blk) {
        case NUM_BLOCKS_4000:
        case NUM_BLOCKS_4000 + 50: /* with errors */
            image->tracks = NUM_TRACKS_4000;
            image->max_half_tracks = MAX_TRACKS_4000 * 2;
            break;
        default:
            return 0;
    }
    disk_image_check_log(image, "D4M");
    return 1;
}
예제 #4
0
static int zfile_load(const char *filename, BYTE *dest, size_t size)
{
    FILE *fd;

    fd = zfile_fopen(filename, MODE_READ);
    if (!fd) {
        return -1;
    }
    if (util_file_length(fd) != size) {
        zfile_fclose(fd);
        return -1;
    }
    if (fread(dest, size, 1, fd) < 1) {
        zfile_fclose(fd);
        return -1;
    }
    zfile_fclose(fd);
    return 0;
}
예제 #5
0
파일: event.c 프로젝트: martinpiper/VICE
void event_record_attach_in_list(event_list_state_t *list, unsigned int unit,
                                 const char *filename, unsigned int read_only)
{
    char *event_data;
    unsigned int size;

    list->current->type = EVENT_ATTACHIMAGE;
    list->current->clk = maincpu_clk;
    list->current->next
        = (event_list_t *)lib_calloc(1, sizeof(event_list_t));

    size = strlen(filename) + 3;

    event_data = lib_malloc(size);
    event_data[0] = unit;
    event_data[1] = read_only;
    strcpy(&event_data[2], filename);

    if (event_image_append(filename, NULL, 0) == 1) {
        FILE *fd;
        size_t file_len = 0;
        
        fd = fopen(filename, MODE_READ);

        if (fd != NULL) {
            file_len = util_file_length(fd);
            event_data = lib_realloc(event_data, size + file_len);

            if (fread(&event_data[size], file_len, 1, fd) != 1)
                log_error(event_log, "Cannot load image file %s", filename);

            fclose(fd);
        } else {
            log_error(event_log, "Cannot open image file %s", filename);
        }
        size += file_len;
    }

    list->current->size = size;
    list->current->data = event_data;
    list->current = list->current->next;
}
예제 #6
0
static int zfile_load(const char *filename, BYTE *dest)
{
    FILE *fd;
    size_t fsize;

    fd = zfile_fopen(filename, MODE_READ);
    if (!fd) {
        log_message(fe_log, "Failed to open image `%s'!",
                    filename);
        return -1;
    }
    fsize = util_file_length(fd);

    if (fsize < 0x8000) {
        size_t tsize;
        size_t offs;
        tsize = (fsize + 0x0fff) & 0xfffff000;
        offs = 0x8000 - tsize;
        dest += offs;
        log_message(fe_log, "Size less than 32kB.  Aligning as close as possible to the 32kB boundary in 4kB blocks. (0x%06X-0x%06X)", (unsigned int)offs, (unsigned int)(offs + tsize));
    } else if (fsize < (size_t)CART_ROM_SIZE) {
        log_message(fe_log, "Size less than 512kB, padding.");
    } else if (fsize > (size_t)CART_ROM_SIZE) {
        fsize = CART_ROM_SIZE;
        log_message(fe_log, "Size larger than 512kB, truncating.");
    }
    if (fread(dest, fsize, 1, fd) < 1) {
        log_message(fe_log, "Failed to read image `%s'!", filename);
        zfile_fclose(fd);
        return -1;
    }
    zfile_fclose(fd);
    log_message(fe_log, "Read image `%s'.",
                filename);
    return 0;
}
예제 #7
0
static int disk_image_check_for_d64(disk_image_t *image)
{
    /*** detect 35..42 track d64 image, determine image parameters.
         Walk from 35 to 42, calculate expected image file size for each track,
         and compare this with the size of the given image. */

    int checkimage_tracks, checkimage_errorinfo;
    size_t countbytes, checkimage_blocks, checkimage_realsize;
    fsimage_t *fsimage;

    fsimage = image->media.fsimage;

    checkimage_errorinfo = 0;
    checkimage_realsize = util_file_length(fsimage->fd);
    checkimage_tracks = NUM_TRACKS_1541; /* start at track 35 */
    checkimage_blocks = D64_FILE_SIZE_35 / 256;

    while (1) {
        /* check if image matches "checkimage_tracks" */
        if (checkimage_realsize == checkimage_blocks * 256) {
            /* image file matches size-with-no-error-info */
            checkimage_errorinfo = 0;
            break;
        } else if (checkimage_realsize == checkimage_blocks * 256 + checkimage_blocks) {
            /* image file matches size-with-error-info */
            checkimage_errorinfo = 1;
            break;
        }

        /* try next track (all tracks from 35 to 42 have 17 blocks) */
        checkimage_tracks++;
        checkimage_blocks += 17;

        /* we tried them all up to 42, none worked, image must be corrupt */
        if (checkimage_tracks > MAX_TRACKS_1541) {
            return 0;
        }
    }

    /*** test image file: read it (fgetc is pretty fast).
         further size checks are no longer necessary (done during detection) */
    rewind(fsimage->fd);
    for (countbytes = 0; countbytes < checkimage_realsize; countbytes++) {
        if (fgetc(fsimage->fd) == EOF) {
            log_error(disk_image_probe_log, "Cannot read D64 image.");
            return 0;
        }
    }

    /*** set parameters in image structure, read error info */
    image->type = DISK_IMAGE_TYPE_D64;
    image->tracks = checkimage_tracks;
    image->max_half_tracks = MAX_TRACKS_1541 * 2;

    if (checkimage_errorinfo) {
        fsimage->error_info.map = lib_calloc(1, checkimage_blocks);
        fsimage->error_info.len = checkimage_blocks;
        if (util_fpread(fsimage->fd, fsimage->error_info.map, checkimage_blocks, 256 * checkimage_blocks) < 0) {
            return 0;
        }
    }

    /*** log and return successfully */
    disk_image_check_log(image, "D64");
    return 1;
}
예제 #8
0
static int disk_image_check_for_d81(disk_image_t *image)
{
    unsigned int blk = 0;
    char *ext;
    size_t len;
    BYTE block[256];
    fsimage_t *fsimage;
    int checkimage_errorinfo;
    unsigned int checkimage_blocks;

    fsimage = image->media.fsimage;

    if (!(IS_D81_LEN(util_file_length(fsimage->fd)))) {
        return 0;
    }

    /* .d1m images share the same sizes with .d81, so we reject based on the
       file extension what is likely a .d1m image */
    ext = util_get_extension(fsimage->name);
    if ((ext[0]) && (ext[1] == '1') && (ext[2])) {
        return 0;
    }

    rewind(fsimage->fd);

    while ((len = fread(block, 1, 256, fsimage->fd)) == 256) {
        if (++blk > (MAX_BLOCKS_1581 + 13)) {
            log_error(disk_image_probe_log, "Disk image too large.");
            break;
        }
    }

    if (disk_image_check_min_block(blk, NUM_BLOCKS_1581) < 0) {
        return 0;
    }

    switch (blk) {
        case NUM_BLOCKS_1581:          /* 80 tracks */
        case NUM_BLOCKS_1581 + 12:     /* 80 tracks, with errors */
            image->tracks = NUM_TRACKS_1581;
            break;
        case NUM_BLOCKS_1581 + 40:     /* 81 tracks */
        case NUM_BLOCKS_1581 + 40 + 12: /* 81 tracks, with errors */
            image->tracks = NUM_TRACKS_1581 + 1;
            break;
        case NUM_BLOCKS_1581 + 80:     /* 82 tracks */
        case NUM_BLOCKS_1581 + 80 + 12: /* 82 tracks, with errors */
            image->tracks = NUM_TRACKS_1581 + 2;
            break;
        case NUM_BLOCKS_1581 + 120:    /* 83 tracks */
        case NUM_BLOCKS_1581 + 120 + 12: /* 83 tracks, with errors */
            image->tracks = NUM_TRACKS_1581 + 3;
            break;
        default:
            return 0;
    }

    image->type = DISK_IMAGE_TYPE_D81;
    image->max_half_tracks = MAX_TRACKS_1581 * 2;

    switch (blk) {
        case NUM_BLOCKS_1581 + 12:     /* 80 tracks, with errors */
        case NUM_BLOCKS_1581 + 40 + 12: /* 81 tracks, with errors */
        case NUM_BLOCKS_1581 + 80 + 12: /* 82 tracks, with errors */
        case NUM_BLOCKS_1581 + 120 + 12: /* 83 tracks, with errors */
            checkimage_errorinfo = 1;
            break;
        default:
            checkimage_errorinfo = 0;
            break;
    }

    if (checkimage_errorinfo) {
        checkimage_blocks = image->tracks * 40;
        fsimage->error_info.map = lib_calloc(1, checkimage_blocks);
        fsimage->error_info.len = checkimage_blocks;
        if (util_fpread(fsimage->fd, fsimage->error_info.map, checkimage_blocks, 256 * checkimage_blocks) < 0) {
            return 0;
        }
    }
    disk_image_check_log(image, "D81");
    return 1;
}
예제 #9
0
/*
 * If minsize >= 0, and the file is smaller than maxsize, load the data
 * into the end of the memory range.
 * If minsize < 0, load it at the start.
 */
int sysfile_load(const char *name, BYTE *dest, int minsize, int maxsize)
{
    FILE *fp = NULL;
    size_t rsize = 0;
    char *complete_path = NULL;
    int load_at_end;


/*
 * This feature is only active when --enable-embedded is given to the
 * configure script, its main use is to make developing new ports easier
 * and to allow ports for platforms which don't have a filesystem, or a
 * filesystem which is hard/impossible to load data files from.
 *
 * when USE_EMBEDDED is defined this will check if a
 * default system file is loaded, when USE_EMBEDDED
 * is not defined the function is just 0 and will
 * be optimized away.
 */

    if ((rsize = embedded_check_file(name, dest, minsize, maxsize)) != 0) {
        return rsize;
    }

    fp = sysfile_open(name, &complete_path, MODE_READ);

    if (fp == NULL) {
        /* Try to open the file from the current directory. */
        const char working_dir_prefix[3] = {
            '.', FSDEV_DIR_SEP_CHR, '\0'
        };
        char *local_name = NULL;

        local_name = util_concat(working_dir_prefix, name, NULL);
        fp = sysfile_open((const char *)local_name, &complete_path, MODE_READ);
        lib_free(local_name);
        local_name = NULL;

        if (fp == NULL) {
            goto fail;
        }
    }

    log_message(LOG_DEFAULT, "Loading system file `%s'.", complete_path);

    rsize = util_file_length(fp);
    if (minsize < 0) {
        minsize = -minsize;
        load_at_end = 0;
    } else {
        load_at_end = 1;
    }

    if (rsize < ((size_t)minsize)) {
        log_error(LOG_DEFAULT, "ROM %s: short file.", complete_path);
        goto fail;
    }
    if (rsize == ((size_t)maxsize + 2)) {
        log_warning(LOG_DEFAULT,
                    "ROM `%s': two bytes too large - removing assumed "
                    "start address.", complete_path);
        if (fread((char *)dest, 1, 2, fp) < 2) {
            goto fail;
        }
        rsize -= 2;
    }
    if (load_at_end && rsize < ((size_t)maxsize)) {
        dest += maxsize - rsize;
    } else if (rsize > ((size_t)maxsize)) {
        log_warning(LOG_DEFAULT, "ROM `%s': long file, discarding end.",
                    complete_path);
        rsize = maxsize;
    }
    if ((rsize = fread((char *)dest, 1, rsize, fp)) < ((size_t)minsize)) {
        goto fail;
    }

    fclose(fp);
    lib_free(complete_path);
    return (int)rsize;  /* return ok */

fail:
    lib_free(complete_path);
    return -1;
}
예제 #10
0
파일: network.c 프로젝트: martinpiper/VICE
static void network_server_connect_trap(WORD addr, void *data)
{
    FILE *f;
    BYTE *buf;
    size_t buf_size;
    BYTE send_size4[4];
    long i;
    event_list_state_t settings_list;

    vsync_suspend_speed_eval();

    /* Create snapshot and send it */
    snapshotfilename = archdep_tmpnam();
    if (machine_write_snapshot(snapshotfilename, 1, 1, 0) == 0) {
        f = fopen(snapshotfilename, MODE_READ);
        if (f == NULL) {
#ifdef HAS_TRANSLATION
            ui_error(translate_text(IDGS_CANNOT_LOAD_SNAPSHOT_TRANSFER));
#else
            ui_error(_("Cannot load snapshot file for transfer"));
#endif
            lib_free(snapshotfilename);
            return;
        }
        buf_size = util_file_length(f);
        buf = lib_malloc(buf_size);
        fread(buf, 1, buf_size, f);
        fclose(f);

#ifdef HAS_TRANSLATION
        ui_display_statustext(translate_text(IDGS_SENDING_SNAPSHOT_TO_CLIENT), 0);
#else
        ui_display_statustext(_("Sending snapshot to client..."), 0);
#endif
        util_int_to_le_buf4(send_size4, (int)buf_size);
        network_send_buffer(network_socket, send_size4, 4);
        i = network_send_buffer(network_socket, buf, (int)buf_size);
        lib_free(buf);
        if (i < 0) {
#ifdef HAS_TRANSLATION
            ui_error(translate_text(IDGS_CANNOT_SEND_SNAPSHOT_TO_CLIENT));
#else
            ui_error(_("Cannot send snapshot to client"));
#endif
            ui_display_statustext("", 0);
            lib_free(snapshotfilename);
            return;
        }

        network_mode = NETWORK_SERVER_CONNECTED;

        /* Send settings that need to be the same */
        event_register_event_list(&settings_list);
        resources_get_event_safe_list(&settings_list);

        buf_size = (size_t)network_create_event_buffer(&buf, &(settings_list));
        util_int_to_le_buf4(send_size4, (int)buf_size);

        network_send_buffer(network_socket, send_size4, 4);
        network_send_buffer(network_socket, buf, (int)buf_size);

        event_clear_list(&settings_list);
        lib_free(buf);

        current_send_frame = 0;
        last_received_frame = 0;

        network_test_delay();
    } else {
#ifdef HAS_TRANSLATION
        ui_error(translate_text(IDGS_CANNOT_CREATE_SNAPSHOT_FILE_S), snapshotfilename);
#else
        ui_error(_("Cannot create snapshot file %s"), snapshotfilename);
#endif
    }
    lib_free(snapshotfilename);
}