Exemple #1
0
int wiiso_get_file_id(wiiso_t disc, unsigned int partition_number, const char *full_path, unsigned int *file_id) {
    struct partition_data *p = &disc->partitions[partition_number];
    unsigned int i, fullname_len;
    char *ref_name;

    fail_if_closed();

    if(partition_number >= disc->num_partitions) {
	log_error(disc->log_level, "wiiso_get_file_id: bad partition number\n");
	return 1;
    }

    fullname_len = strlen(full_path);
    ref_name = strrchr(full_path, '/');
    if(!ref_name || *full_path!='/' || fullname_len < 1) {
	log_error(disc->log_level, "wiiso_get_file_id: not invoked with a full path name\n");
	return 1;
    }
    ref_name++;

    for(i=0; i<p->fst_files; i++) {
	unsigned int file_parent;
	char *file_name, *curpath;

	if(get_file_by_id(disc, partition_number, i, &file_name, NULL, NULL, &file_parent)) {
	    log_error(disc->log_level, "wiiso_get_file_id: bad FST tree\n");
	    return 1;
	}
	/* if(!file_offset) continue; */
	if(strcmp(file_name, ref_name)) continue;
	curpath = ref_name;
	do {
	    unsigned int parent_len;
	    if(!file_parent && curpath == full_path + 1) {
		*file_id = i;
		return 0;
	    }
	    get_file_by_id(disc, partition_number, file_parent, &file_name, NULL, NULL, &file_parent);

	    parent_len = strlen(file_name);
	    curpath -= 2 + parent_len;
	    if(curpath < full_path || *curpath != '/')
		break;
	    curpath++;
	    if(memcmp(curpath, file_name, parent_len))
		break;
	} while(1);
	
    }
    log_debug(disc->log_level, "wiiso_get_file_id: file '%s' not found in partition %u\n", full_path, partition_number);
    return 1;
}
Exemple #2
0
char* get_path_by_id(int id) {
    const char *path = global_path_get(RESOURCE_PATH);
    const char *filename = get_file_by_id(id);
    if(filename != NULL && path != NULL) {
        int len = strlen(path) + strlen(filename) + 1;
        char *out = malloc(len);
        sprintf(out, "%s%s", path, filename);
        return out;
    }
    return NULL;
}
Exemple #3
0
int wiiso_extract_file(wiiso_t disc, unsigned int partition_number, unsigned int file_id, const char *output_file) {
    unsigned int file_size;
    off_t file_offset;
    char buf[4096];
    FILE *of;

    fail_if_closed();

    if(partition_number >= disc->num_partitions) {
	log_error(disc->log_level, "wiiso_extract_file: bad partition number\n");
	return 1;
    }

    if(get_file_by_id(disc, partition_number, file_id, NULL, &file_offset, &file_size, NULL)) {
	log_error(disc->log_level, "wiiso_extract_file: bad file id\n");
	return 1;
    }

    if(!file_offset) {
	log_error(disc->log_level, "wiiso_extract_file: file %u is a directory\n", file_id);
	return 1;
    }

    of = fopen(output_file, "w");
    if(!of) {
	strerror_r(errno, buf, sizeof(buf));
	log_error(disc->log_level, "wiiso_extract_file: failed to open file %s for writing: %s\n", output_file, buf);
	return 1;
    }

    while(file_size) {
	unsigned int todo = MIN(file_size, sizeof(buf));
	if(read_data(disc, partition_number, file_offset, todo, buf, NULL)) {
	    log_error(disc->log_level, "wiiso_extract_file: read failed\n");
	    fclose(of);
	    unlink(output_file);
	    return 1;
	}
	if(fwrite(buf, todo, 1, of) != 1) {
	    strerror_r(errno, buf, sizeof(buf));
	    log_error(disc->log_level, "wiiso_extract_file: write failed: %s\n", buf);
	    fclose(of);
	    unlink(output_file);
	    return 1;
	}
	file_size -= todo;
	file_offset += todo;
    }

    fclose(of);
    return 0;
}
Exemple #4
0
int wiiso_get_file_name(wiiso_t disc, unsigned int partition_number, unsigned int file_id, char *buf, unsigned int buf_len) {
    unsigned int file_len, file_parent, avail_len = buf_len;
    off_t file_offset;
    char *file_name;
    int len;

    fail_if_closed();

    if(partition_number >= disc->num_partitions) {
	log_error(disc->log_level, "wiiso_get_file_name: bad partition number\n");
	return 1;
    }

    if(get_file_by_id(disc, partition_number, file_id, &file_name, &file_offset, &file_len, &file_parent)) {
	log_error(disc->log_level, "wiiso_get_file_name: bad file id\n");
	return 1;
    }

    do {
	len = strlen(file_name);
	if(len + 1 >= avail_len) {
	    log_error(disc->log_level, "wiiso_get_file_name: buffer too small\n");
	    return 1;
	}
	memcpy(buf + avail_len - len, file_name, len);
	buf[avail_len - len - 1] = '/';
	avail_len -= len + 1;
	file_id = file_parent;
	if(get_file_by_id(disc, partition_number, file_id, &file_name, NULL, NULL, &file_parent)) {
	    log_error(disc->log_level, "wiiso_get_file_name: bad FST tree\n");
	    return 1;
	}
    } while(file_id);

    memmove(buf, &buf[avail_len], buf_len - avail_len);
    buf[buf_len - avail_len] = '\0';

    return 0;
}
Exemple #5
0
int wiiso_get_file_size(wiiso_t disc, unsigned int partition_number, unsigned int file_id, unsigned int *file_size) {

    fail_if_closed();

    if(partition_number >= disc->num_partitions) {
	log_error(disc->log_level, "wiiso_get_file_size: bad partition number\n");
	return 1;
    }

    if(get_file_by_id(disc, partition_number, file_id, NULL, NULL, file_size, NULL)) {
	log_error(disc->log_level, "wiiso_get_file_size: bad file id\n");
	return 1;
    }

    return 0;
}