Exemple #1
0
int xmp_load_module(xmp_context opaque, char *path)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct module_data *m = &ctx->m;
	HIO_HANDLE *h;
	struct stat st;
	struct list_head tmpfiles_list;

	D_(D_WARN "path = %s", path);

	if (stat(path, &st) < 0)
		return -XMP_ERROR_SYSTEM;

#ifndef _MSC_VER
	if (S_ISDIR(st.st_mode)) {
		errno = EISDIR;
		return -XMP_ERROR_SYSTEM;
	}
#endif

	if ((h = hio_open_file(path, "rb")) == NULL)
		return -XMP_ERROR_SYSTEM;

	INIT_LIST_HEAD(&tmpfiles_list);

	D_(D_INFO "decrunch");
	if (decrunch(&tmpfiles_list, &h->f, &path, DECRUNCH_MAX) < 0)
		goto err_depack;

	if (hio_stat(h, &st) < 0)
		goto err_depack;

	if (st.st_size < 256) {			/* get size after decrunch */
		hio_close(h);
		unlink_tempfiles(&tmpfiles_list);
		return -XMP_ERROR_FORMAT;
	}

	if (ctx->state > XMP_STATE_UNLOADED)
		xmp_release_module(opaque);

	m->dirname = get_dirname(path);
	if (m->dirname == NULL)
		return -XMP_ERROR_SYSTEM;

	m->basename = get_basename(path);
	if (m->basename == NULL)
		return -XMP_ERROR_SYSTEM;

	m->filename = path;	/* For ALM, SSMT, etc */
	m->size = st.st_size;

	return load_module(opaque, h, &tmpfiles_list);

    err_depack:
	hio_close(h);
	unlink_tempfiles(&tmpfiles_list);
	return -XMP_ERROR_DEPACK;
}
Exemple #2
0
int xmp_load_typed_module_from_memory(xmp_context opaque, void *mem, long size, const struct format_loader* format)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct module_data *m = &ctx->m;
	HIO_HANDLE *h;
	int ret;

	if ((h = hio_open_mem(mem, size)) == NULL)
		return -XMP_ERROR_SYSTEM;

	m->filename = NULL;
	m->basename = NULL;
	m->size = size;

	if (ctx->state > XMP_STATE_UNLOADED)
		xmp_release_module(opaque);

	load_prologue(ctx);

	D_(D_WARN "load");
	ret = -XMP_ERROR_FORMAT;
	if (format->test(h, NULL, 0) == 0) {
	  if ((ret = module_load(h, ctx, format)))
	    xmp_release_module(opaque);
	}
	hio_close(h);
  return ret;
}
Exemple #3
0
int xmp_load_module_from_file(xmp_context opaque, void *file, long size)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct module_data *m = &ctx->m;
	HIO_HANDLE *h;
	FILE *f = fdopen(fileno((FILE *)file), "rb");
	int ret;

	if ((h = hio_open_file(f)) == NULL)
		return -XMP_ERROR_SYSTEM;

	if (ctx->state > XMP_STATE_UNLOADED)
		xmp_release_module(opaque);

	m->filename = NULL;
	m->basename = NULL;
	m->dirname = NULL;
	m->size = hio_size(h);

	ret = load_module(opaque, h);

	hio_close(h);

	return ret;
}
Exemple #4
0
int xmp_load_module_from_memory(xmp_context opaque, void *mem, long size)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct module_data *m = &ctx->m;
	HIO_HANDLE *h;
	int ret;

	/* Use size < 0 for unknown/undetermined size */
	if (size == 0)
		size--;

	if ((h = hio_open_mem(mem, size)) == NULL)
		return -XMP_ERROR_SYSTEM;

	if (ctx->state > XMP_STATE_UNLOADED)
		xmp_release_module(opaque);

	m->filename = NULL;
	m->basename = NULL;
	m->dirname = NULL;
	m->size = size;

	ret = load_module(opaque, h);

	hio_close(h);

	return ret;
}
Exemple #5
0
static int load_module(xmp_context opaque, HIO_HANDLE *h, struct list_head *tmpfiles_list)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct module_data *m = &ctx->m;
	int i, ret;
	int test_result, load_result;

	load_prologue(ctx);

	D_(D_WARN "load");
	test_result = load_result = -1;
	for (i = 0; format_loader[i] != NULL; i++) {
		hio_seek(h, 0, SEEK_SET);
		test_result = format_loader[i]->test(h, NULL, 0);
		if (test_result == 0) {
			hio_seek(h, 0, SEEK_SET);
			D_(D_WARN "load format: %s", format_loader[i]->name);
			load_result = format_loader[i]->loader(m, h, 0);
			break;
		}
	}

	if (test_result == 0 && load_result == 0)
		set_md5sum(h, m->md5);

	hio_close(h);
	if (tmpfiles_list != NULL)
		unlink_tempfiles(tmpfiles_list);

	if (test_result < 0) {
		free(m->basename);
		free(m->dirname);
		return -XMP_ERROR_FORMAT;
	}

	if (load_result < 0) {
		xmp_release_module(opaque);
		return -XMP_ERROR_LOAD;
	}

	str_adj(m->mod.name);
	load_epilogue(ctx);

	ret = prepare_scan(ctx);
	if (ret < 0)
		return ret;

	scan_sequences(ctx);

	ctx->state = XMP_STATE_LOADED;

	return 0;
}
Exemple #6
0
static int mtp_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	int i, j, k;
	uint8 buffer[25];
	int blocksize;

	LOAD_INIT();

	hio_read(buffer, 6, 1, f);

	if (!memcmp(buffer, "SONGOK", 6))
		set_type(m, "IIgs SoundSmith");
	else if (!memcmp(buffer, "IAN92a", 8))
		set_type(m, "IIgs MegaTracker");
	else
		return -1;

	blocksize = hio_read16l(f);
	mod->spd = hio_read16l(f);
	hio_seek(f, 10, SEEK_CUR);		/* skip 10 reserved bytes */
	
	mod->ins = mod->smp = 15;
	if (instrument_init(mod) < 0)
		return -1;

	for (i = 0; i < mod->ins; i++) {
		if (subinstrument_alloc(mod, i, 1) < 0)
			return -1;

		hio_read(buffer, 1, 22, f);
		if (buffer[0]) {
			buffer[buffer[0] + 1] = 0;
			instrument_name(mod, i, buffer + 1, 22);
		}
		hio_read16l(f);		/* skip 2 reserved bytes */
		mod->xxi[i].sub[0].vol = hio_read8(f) >> 2;
		mod->xxi[i].sub[0].pan = 0x80;
		hio_seek(f, 5, SEEK_CUR);	/* skip 5 bytes */
	}

	mod->len = hio_read8(f) & 0x7f;
	hio_read8(f);
	hio_read(mod->xxo, 1, 128, f);

	MODULE_INFO();

	hio_seek(f, start + 600, SEEK_SET);

	mod->chn = 14;
	mod->pat = blocksize / (14 * 64);
	mod->trk = mod->pat * mod->chn;

	if (pattern_init(mod) < 0)
		return -1;

	/* Read and convert patterns */
	D_(D_INFO "Stored patterns: %d", mod->pat);

	/* Load notes */
	for (i = 0; i < mod->pat; i++) {
		if (pattern_tracks_alloc(mod, i, 64) < 0)
			return -1;

		for (j = 0; j < mod->xxp[i]->rows; j++) {
			for (k = 0; k < mod->chn; k++) {
				event = &EVENT(i, k, j);
				event->note = hio_read8(f);;
				if (event->note)
					event->note += 24;
			}
		}
	}

	/* Load fx1 */
	for (i = 0; i < mod->pat; i++) {
		for (j = 0; j < mod->xxp[i]->rows; j++) {
			for (k = 0; k < mod->chn; k++) {
				uint8 x;
				event = &EVENT(i, k, j);
				x = hio_read8(f);;
				event->ins = x >> 4;

				switch (x & 0x0f) {
				case 0x00:
					event->fxt = FX_ARPEGGIO;
					break;
				case 0x03:
					event->fxt = FX_VOLSET;
					break;
				case 0x05:
					event->fxt = FX_VOLSLIDE_DN;
					break;
				case 0x06:
					event->fxt = FX_VOLSLIDE_UP;
					break;
				case 0x0f:
					event->fxt = FX_SPEED;
					break;
				}
			}
		}
	}

	/* Load fx2 */
	for (i = 0; i < mod->pat; i++) {
		for (j = 0; j < mod->xxp[i]->rows; j++) {
			for (k = 0; k < mod->chn; k++) {
				event = &EVENT(i, k, j);
				event->fxp = hio_read8(f);;

				switch (event->fxt) {
				case FX_VOLSET:
				case FX_VOLSLIDE_DN:
				case FX_VOLSLIDE_UP:
					event->fxp >>= 2;
				}
			}
		}
	}

	/* Read instrument data */
	D_(D_INFO "Instruments    : %d ", mod->ins);

	for (i = 0; i < mod->ins; i++) {
		HIO_HANDLE *s;
		char filename[1024];

		if (!mod->xxi[i].name[0])
			continue;

		strncpy(filename, m->dirname, NAME_SIZE);
		if (*filename)
			strncat(filename, "/", NAME_SIZE);
		strncat(filename, (char *)mod->xxi[i].name, NAME_SIZE);

		if ((s = hio_open_file(filename, "rb")) != NULL) {
			asif_load(m, s, i);
			hio_close(s);
		}

#if 0
		mod->xxs[i].lps = 0;
		mod->xxs[i].lpe = 0;
		mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0;
		mod->xxi[i].sub[0].fin = 0;
		mod->xxi[i].sub[0].pan = 0x80;
#endif

		D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x", i,
				mod->xxi[i].name,
				mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
				mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
				mod->xxi[i].sub[0].vol);
	}

	return 0;
}
Exemple #7
0
int 
main(int     argc,
     char ** argv) 
{
    char * pmi_rank = getenv("PMI_RANK");
    char * hio_name = getenv("STUB_NAME");
    int    rank = -1;
    int    status;

    if (argc != 2) {
        printf("Usage: %s <file to open>\n", *argv);
        return -1;
    }

    if (pmi_rank == NULL) {
        printf("No PMI_RANK in env. assuming rank 0\n");
        rank = 0;
    } else {
        rank = atoi(pmi_rank);
    }

    if (hio_name == NULL) {
        printf("No STUB_NAME in env. exiting\n");
        return -1;
    }

    sleep(2);

    status = libhio_client_init(hio_name, rank);
    if (status != 0) { 
        printf("Failed to init HIO client\n");
        return -1;
    }

    /* Open/read/write/close a file */
    {
        char * file_name = argv[1];
        int fd;
        ssize_t bytes;
        off_t offset;
        char buf[PAGE_SIZE * 10];

        fd = hio_open(file_name, O_RDONLY);
        if (hio_status != HIO_SUCCESS || fd < 0) { 
            printf("Could not open file %s (fd=%d)\n", file_name, fd);
            goto out;
        }

        bytes = hio_read(fd, buf, PAGE_SIZE * 10);
        printf("Read %li bytes from fd %d\n", bytes, fd);
        if (bytes> 0)
            printf("%s\n", buf);

        hio_close(fd);

        fd = hio_open(file_name, O_WRONLY | O_TRUNC);
        if (hio_status != HIO_SUCCESS || fd < 0)  {
            printf("Could not open file %s (fd=%d)\n", file_name, fd);
            goto out;
        }

        bytes = hio_write(fd, "Overwrite file\n", 15);
        printf("Wrote %li bytes to fd %d\n", bytes, fd);

        hio_close(fd);
    }

    /* mmap the file */
    {
        char * file_name = argv[1];
        int fd;
        ssize_t bytes;
        off_t offset;
        void * addr;
        void * at_addr;
        hio_segment_t seg;

        fd = hio_open(file_name, O_RDONLY);
        if (hio_status != HIO_SUCCESS || fd < 0) { 
            printf("Could not open file %s (fd=%d)\n", file_name, fd);
            goto out;
        }

        addr = hio_mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0, &seg);
        if (hio_status != HIO_SUCCESS || addr == MAP_FAILED) {
            printf("failed to issue mmap to fd: %d\n", fd);
            goto out;
        }

        /* Linux mapped new memory to'addr'. We do not have this region
         * mapped in our aspace, so we need to map it in now
         */
        status = __map_hio_segment(&seg, MY_ID);
        if (status != 0) {
            printf("Failed to target the mmap to the stub-allocated vaddr\n");
            goto out;
        }

        addr = seg.vaddr;

        printf("at %p: %s\n", addr, (char *)addr);

        hio_close(fd);
    }

out:
    libhio_client_deinit();

    return 0;
} 
Exemple #8
0
int xmp_load_module(xmp_context opaque, char *path)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct module_data *m = &ctx->m;
	HIO_HANDLE *h;
	struct stat st;
	struct list_head tmpfiles_list;
	int test_result, load_result;
	int i, ret;

	D_(D_WARN "path = %s", path);

	if (stat(path, &st) < 0)
		return -XMP_ERROR_SYSTEM;

#ifndef _MSC_VER
	if (S_ISDIR(st.st_mode)) {
		errno = EISDIR;
		return -XMP_ERROR_SYSTEM;
	}
#endif

	if ((h = hio_open_file(path, "rb")) == NULL)
		return -XMP_ERROR_SYSTEM;

	INIT_LIST_HEAD(&tmpfiles_list);

	D_(D_INFO "decrunch");
	if (decrunch(&tmpfiles_list, &h->f, &path, DECRUNCH_MAX) < 0)
		goto err_depack;

	if (hio_stat(h, &st) < 0)
		goto err_depack;

	if (st.st_size < 256) {			/* get size after decrunch */
		hio_close(h);
		unlink_tempfiles(&tmpfiles_list);
		return -XMP_ERROR_FORMAT;
	}

	if (ctx->state > XMP_STATE_UNLOADED)
		xmp_release_module(opaque);

	m->dirname = get_dirname(path);
	if (m->dirname == NULL)
		return -XMP_ERROR_SYSTEM;

	m->basename = get_basename(path);
	if (m->basename == NULL)
		return -XMP_ERROR_SYSTEM;

	m->filename = path;	/* For ALM, SSMT, etc */
	m->size = st.st_size;

	load_prologue(ctx);

	D_(D_WARN "load");
	test_result = load_result = -1;
	for (i = 0; format_loader[i] != NULL; i++) {
		hio_seek(h, 0, SEEK_SET);
		test_result = format_loader[i]->test(h, NULL, 0);
		if (test_result == 0) {
			hio_seek(h, 0, SEEK_SET);
			D_(D_WARN "load format: %s", format_loader[i]->name);
			load_result = format_loader[i]->loader(m, h, 0);
			break;
		}
	}

	set_md5sum(h, m->md5);

	hio_close(h);
	unlink_tempfiles(&tmpfiles_list);

	if (test_result < 0) {
		free(m->basename);
		free(m->dirname);
		return -XMP_ERROR_FORMAT;
	}

	if (load_result < 0) {
		xmp_release_module(opaque);
		return -XMP_ERROR_LOAD;
	}

	str_adj(m->mod.name);
	if (!*m->mod.name) {
		strncpy(m->mod.name, m->basename, XMP_NAME_SIZE);
	}

	load_epilogue(ctx);

	ret = prepare_scan(ctx);
	if (ret < 0)
		return ret;

	scan_sequences(ctx);

	ctx->state = XMP_STATE_LOADED;

	return 0;

    err_depack:
	hio_close(h);
	unlink_tempfiles(&tmpfiles_list);
	return -XMP_ERROR_DEPACK;
}
Exemple #9
0
static int decrunch(struct list_head *head, FILE **f, char **s, int ttl)
{
    unsigned char b[1024];
    char *cmd;
    FILE *t;
    int fd, builtin, res;
    char *temp2, tmp[PATH_MAX];
    struct tmpfilename *temp;
    int headersize;

    cmd = NULL;
    builtin = res = 0;

    if (get_temp_dir(tmp, PATH_MAX) < 0)
	return 0;

    strncat(tmp, "xmp_XXXXXX", PATH_MAX);

    fseek(*f, 0, SEEK_SET);
    if ((headersize = fread(b, 1, 1024, *f)) < 100)	/* minimum valid file size */
	return 0;

#if defined __AMIGA__ && !defined __AROS__
    if (test_xfd(b, 1024)) {
	builtin = BUILTIN_XFD;
    } else
#endif

    if (b[0] == 'P' && b[1] == 'K' &&
	((b[2] == 3 && b[3] == 4) || (b[2] == '0' && b[3] == '0' &&
	b[4] == 'P' && b[5] == 'K' && b[6] == 3 && b[7] == 4))) {

	/* Zip */
	builtin = BUILTIN_ZIP;
    } else if (b[2] == '-' && b[3] == 'l' && b[4] == 'h') {
	/* LHa */
	builtin = BUILTIN_LHA;
    } else if (b[0] == 31 && b[1] == 139) {
	/* gzip */
	builtin = BUILTIN_GZIP;
    } else if (b[0] == 'B' && b[1] == 'Z' && b[2] == 'h') {
	/* bzip2 */
	builtin = BUILTIN_BZIP2;
    } else if (b[0] == 0xfd && b[3] == 'X' && b[4] == 'Z' && b[5] == 0x00) {
	/* xz */
	builtin = BUILTIN_XZ;
#if 0
    } else if (b[0] == 'Z' && b[1] == 'O' && b[2] == 'O' && b[3] == ' ') {
	/* zoo */
	builtin = BUILTIN_ZOO;
#endif
    } else if (b[0] == 'M' && b[1] == 'O' && b[2] == '3') {
	/* MO3 */
	cmd = "unmo3 -s \"%s\" STDOUT";
    } else if (b[0] == 31 && b[1] == 157) {
	/* compress */
	builtin = BUILTIN_COMPRESS;
    } else if (memcmp(b, "PP20", 4) == 0) {
	/* PowerPack */
	builtin = BUILTIN_PP;
    } else if (memcmp(b, "XPKF", 4) == 0 && memcmp(b + 8, "SQSH", 4) == 0) {
	/* SQSH */
	builtin = BUILTIN_SQSH;
    } else if (!memcmp(b, "Archive\0", 8)) {
	/* ArcFS */
	builtin = BUILTIN_ARCFS;
    } else if (memcmp(b, "ziRCONia", 8) == 0) {
	/* MMCMP */
	builtin = BUILTIN_MMCMP;
    } else if (memcmp(b, "MUSE", 4) == 0 && readmem32b(b + 4) == 0xdeadbeaf) {
	/* J2B MUSE */
	builtin = BUILTIN_MUSE;
    } else if (memcmp(b, "MUSE", 4) == 0 && readmem32b(b + 4) == 0xdeadbabe) {
	/* MOD2J2B MUSE */
	builtin = BUILTIN_MUSE;
    } else if (memcmp(b, "LZX", 3) == 0) {
	/* LZX */
	builtin = BUILTIN_LZX;
    } else if (memcmp(b, "Rar", 3) == 0) {
	/* rar */
	cmd = "unrar p -inul -xreadme -x*.diz -x*.nfo -x*.txt "
	    "-x*.exe -x*.com \"%s\"";
    } else if (memcmp(b, "S404", 4) == 0) {
	/* Stonecracker */
	builtin = BUILTIN_S404;
    } else if (test_oxm(*f) == 0) {
	/* oggmod */
	builtin = BUILTIN_OXM;
    }

    if (builtin == 0 && cmd == NULL && b[0] == 0x1a) {
	int x = b[1] & 0x7f;
	int i, flag = 0;
	long size;
	
	/* check file name */
	for (i = 0; i < 13; i++) {
	    if (b[2 + i] == 0) {
		if (i == 0)		/* name can't be empty */
		    flag = 1;
		break;
	    }
	    if (!isprint(b[2 + i])) {	/* name must be printable */
		flag = 1;
		break;
	    }
	}

	size = readmem32l(b + 15);	/* max file size is 512KB */
	if (size < 0 || size > 512 * 1024)
		flag = 1;

        if (flag == 0) {
	    if (x >= 1 && x <= 9 && x != 7) {
		/* Arc */
		builtin = BUILTIN_ARC;
	    } else if (x == 0x7f) {
		/* !Spark */
		builtin = BUILTIN_ARC;
	    }
	}
    }

    fseek(*f, 0, SEEK_SET);

    if (builtin == 0 && cmd == NULL)
	return 0;

#if defined ANDROID || defined __native_client__
    /* Don't use external helpers in android */
    if (cmd)
	return 0;
#endif

    D_(D_WARN "Depacking file... ");

    temp = calloc(sizeof (struct tmpfilename), 1);
    if (!temp) {
	D_(D_CRIT "calloc failed");
	return -1;
    }

    temp->name = strdup(tmp);
    if (temp->name == NULL || (fd = mkstemp(temp->name)) < 0) {
	D_(D_CRIT "failed");
	return -1;
    }

    list_add_tail(&temp->list, head);

    if ((t = fdopen(fd, "w+b")) == NULL) {
	D_(D_CRIT "failed");
	return -1;
    }

    if (cmd) {
#define BSIZE 0x4000
	int n;
	char line[1024], buf[BSIZE];
	FILE *p;

	snprintf(line, 1024, cmd, *s);

#ifdef WIN32
	/* Note: The _popen function returns an invalid file opaque, if
	 * used in a Windows program, that will cause the program to hang
	 * indefinitely. _popen works properly in a Console application.
	 * To create a Windows application that redirects input and output,
	 * read the section "Creating a Child Process with Redirected Input
	 * and Output" in the Win32 SDK. -- Mirko 
	 */
	if ((p = popen(line, "rb")) == NULL) {
#else
	/* Linux popen fails with "rb" */
	if ((p = popen(line, "r")) == NULL) {
#endif
	    D_(D_CRIT "failed");
	    fclose(t);
	    return -1;
	}
	while ((n = fread(buf, 1, BSIZE, p)) > 0)
	    fwrite(buf, 1, n, t);
	pclose (p);
    } else {
	switch (builtin) {
	case BUILTIN_PP:    
	    res = decrunch_pp(*f, t);
	    break;
	case BUILTIN_ARC:
	    res = decrunch_arc(*f, t);
	    break;
	case BUILTIN_ARCFS:
	    res = decrunch_arcfs(*f, t);
	    break;
	case BUILTIN_SQSH:    
	    res = decrunch_sqsh(*f, t);
	    break;
	case BUILTIN_MMCMP:    
	    res = decrunch_mmcmp(*f, t);
	    break;
	case BUILTIN_MUSE:    
	    res = decrunch_muse(*f, t);
	    break;
	case BUILTIN_LZX:    
	    res = decrunch_lzx(*f, t);
	    break;
	case BUILTIN_S404:
	    res = decrunch_s404(*f, t);
	    break;
	case BUILTIN_ZIP:
	    res = decrunch_zip(*f, t);
	    break;
	case BUILTIN_GZIP:
	    res = decrunch_gzip(*f, t);
	    break;
	case BUILTIN_COMPRESS:
	    res = decrunch_compress(*f, t);
	    break;
	case BUILTIN_BZIP2:
	    res = decrunch_bzip2(*f, t);
	    break;
	case BUILTIN_XZ:
	    res = decrunch_xz(*f, t);
	    break;
	case BUILTIN_LHA:
	    res = decrunch_lha(*f, t);
	    break;
#if 0
	case BUILTIN_ZOO:
	    res = decrunch_zoo(*f, t);
	    break;
#endif
	case BUILTIN_OXM:
	    res = decrunch_oxm(*f, t);
	    break;
#ifdef AMIGA
	case BUILTIN_XFD:
	    res = decrunch_xfd(*f, t);
	    break;
#endif
	}
    }

    if (res < 0) {
	D_(D_CRIT "failed");
	fclose(t);
	return -1;
    }

    D_(D_INFO "done");

    fclose(*f);
    *f = t;
 
    if (!--ttl) {
	    return -1;
    }
    
    temp2 = strdup(temp->name);
    res = decrunch(head, f, &temp->name, ttl);
    free(temp2);
    /* Mirko: temp is now deallocated in unlink_tempfiles()
     * not a problem, since unlink_tempfiles() is called after decrunch
     * in loader routines
     *
     * free(temp);
     */

    return res;
}


/*
 * Windows doesn't allow you to unlink an open file, so we changed the
 * temp file cleanup system to remove temporary files after we close it
 */
static void unlink_tempfiles(struct list_head *head)
{
	struct tmpfilename *li;
	struct list_head *tmp;

	/* can't use list_for_each when freeing the node! */
	for (tmp = head->next; tmp != head; ) {
		li = list_entry(tmp, struct tmpfilename, list);
		D_(D_INFO "unlink tmpfile %s", li->name);
		unlink(li->name);
		free(li->name);
		list_del(&li->list);
		tmp = tmp->next;
		free(li);
	}
}


int xmp_test_module(char *path, struct xmp_test_info *info)
{
	HIO_HANDLE *h;
	struct stat st;
	char buf[XMP_NAME_SIZE];
	int i;
	struct list_head tmpfiles_list;
	int ret = -XMP_ERROR_FORMAT;;

	if (stat(path, &st) < 0)
		return -XMP_ERROR_SYSTEM;

#ifndef _MSC_VER
	if (S_ISDIR(st.st_mode)) {
		errno = EISDIR;
		return -XMP_ERROR_SYSTEM;
	}
#endif

	if ((h = hio_open_file(path, "rb")) == NULL)
		return -XMP_ERROR_SYSTEM;

	INIT_LIST_HEAD(&tmpfiles_list);

	if (decrunch(&tmpfiles_list, &h->f, &path, DECRUNCH_MAX) < 0) {
		ret = -XMP_ERROR_DEPACK;
		goto err;
	}

	if (hio_stat(h, &st) < 0) {/* get size after decrunch */
		ret = -XMP_ERROR_DEPACK;
		goto err;
	}

	if (st.st_size < 256) {		/* set minimum valid module size */
		ret = -XMP_ERROR_FORMAT;
		goto err;
	}

	if (info != NULL) {
		*info->name = 0;	/* reset name prior to testing */
		*info->type = 0;	/* reset type prior to testing */
	}

	for (i = 0; format_loader[i] != NULL; i++) {
		fseek(h->f, 0, SEEK_SET);
		if (format_loader[i]->test(h, buf, 0) == 0) {
			int is_prowizard = 0;

			if (strcmp(format_loader[i]->name, "prowizard") == 0) {
				fseek(h->f, 0, SEEK_SET);
				pw_test_format(h->f, buf, 0, info);
				is_prowizard = 1;
			}

			fclose(h->f);

			unlink_tempfiles(&tmpfiles_list);
			if (info != NULL && !is_prowizard) {
				strncpy(info->name, buf, XMP_NAME_SIZE);
				strncpy(info->type, format_loader[i]->name,
							XMP_NAME_SIZE);
			}
			return 0;
		}
	}

    err:
	hio_close(h);
	unlink_tempfiles(&tmpfiles_list);
	return ret;
}
Exemple #10
0
static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
    struct xmp_module *mod = &m->mod;
    int i, j;
    int smp_size, pat_size, wow, ptsong = 0;
    struct xmp_event *event;
    struct mod_header mh;
    uint8 mod_event[4];
    char *x, pathname[PATH_MAX] = "", *tracker = "";
    int detected = 0;
    char magic[8], idbuffer[32];
    int ptkloop = 0;			/* Protracker loop */
    int tracker_id = TRACKER_PROTRACKER;

    LOAD_INIT();

    mod->ins = 31;
    mod->smp = mod->ins;
    mod->chn = 0;
    smp_size = 0;
    pat_size = 0;

    m->quirk |= QUIRK_MODRNG;

    hio_read(&mh.name, 20, 1, f);
    for (i = 0; i < 31; i++) {
	hio_read(&mh.ins[i].name, 22, 1, f);	/* Instrument name */
	mh.ins[i].size = hio_read16b(f);	/* Length in 16-bit words */
	mh.ins[i].finetune = hio_read8(f);	/* Finetune (signed nibble) */
	mh.ins[i].volume = hio_read8(f);	/* Linear playback volume */
	mh.ins[i].loop_start = hio_read16b(f);	/* Loop start in 16-bit words */
	mh.ins[i].loop_size = hio_read16b(f);	/* Loop size in 16-bit words */

	smp_size += 2 * mh.ins[i].size;
    }
    mh.len = hio_read8(f);
    mh.restart = hio_read8(f);
    hio_read(&mh.order, 128, 1, f);
    memset(magic, 0, 8);
    hio_read(magic, 4, 1, f);

    for (i = 0; mod_magic[i].ch; i++) {
	if (!(strncmp (magic, mod_magic[i].magic, 4))) {
	    mod->chn = mod_magic[i].ch;
	    tracker_id = mod_magic[i].id;
	    detected = mod_magic[i].flag;
	    break;
	}
    }

    if (!mod->chn) {
	if (!strncmp(magic + 2, "CH", 2) &&
	    isdigit((int)magic[0]) && isdigit((int)magic[1])) {
	    mod->chn = (*magic - '0') * 10 + magic[1] - '0';
	} else if (!strncmp(magic + 1, "CHN", 3) && isdigit((int)*magic)) {
	    mod->chn = *magic - '0';
	} else {
	    return -1;
	}
	tracker_id = mod->chn & 1 ? TRACKER_TAKETRACKER : TRACKER_FASTTRACKER2;
	detected = 1;
	m->quirk &= ~QUIRK_MODRNG;
    }

    strncpy(mod->name, (char *) mh.name, 20);

    mod->len = mh.len;
    /* mod->rst = mh.restart; */

    if (mod->rst >= mod->len)
	mod->rst = 0;
    memcpy(mod->xxo, mh.order, 128);

    for (i = 0; i < 128; i++) {
	/* This fixes dragnet.mod (garbage in the order list) */
	if (mod->xxo[i] > 0x7f)
		break;
	if (mod->xxo[i] > mod->pat)
	    mod->pat = mod->xxo[i];
    }
    mod->pat++;

    pat_size = 256 * mod->chn * mod->pat;

    if (instrument_init(mod) < 0)
	return -1;

    for (i = 0; i < mod->ins; i++) {
	if (subinstrument_alloc(mod, i, 1) < 0)
	    return -1;

	mod->xxs[i].len = 2 * mh.ins[i].size;
	mod->xxs[i].lps = 2 * mh.ins[i].loop_start;
	mod->xxs[i].lpe = mod->xxs[i].lps + 2 * mh.ins[i].loop_size;
	if (mod->xxs[i].lpe > mod->xxs[i].len)
		mod->xxs[i].lpe = mod->xxs[i].len;
	mod->xxs[i].flg = (mh.ins[i].loop_size > 1 && mod->xxs[i].lpe >= 4) ?
		XMP_SAMPLE_LOOP : 0;
	mod->xxi[i].sub[0].fin = (int8)(mh.ins[i].finetune << 4);
	mod->xxi[i].sub[0].vol = mh.ins[i].volume;
	mod->xxi[i].sub[0].pan = 0x80;
	mod->xxi[i].sub[0].sid = i;
	instrument_name(mod, i, mh.ins[i].name, 22);

	if (mod->xxs[i].len > 0)
		mod->xxi[i].nsm = 1;
    }

    /*
     * Experimental tracker-detection routine
     */ 

    if (detected)
	goto skip_test;

    /* Test for Flextrax modules
     *
     * FlexTrax is a soundtracker for Atari Falcon030 compatible computers.
     * FlexTrax supports the standard MOD file format (up to eight channels)
     * for compatibility reasons but also features a new enhanced module
     * format FLX. The FLX format is an extended version of the standard
     * MOD file format with support for real-time sound effects like reverb
     * and delay.
     */

    if (0x43c + mod->pat * 4 * mod->chn * 0x40 + smp_size < m->size) {
	int pos = hio_tell(f);
	hio_seek(f, start + 0x43c + mod->pat * 4 * mod->chn * 0x40 + smp_size, SEEK_SET);
	hio_read(idbuffer, 1, 4, f);
	hio_seek(f, start + pos, SEEK_SET);

	if (!memcmp(idbuffer, "FLEX", 4)) {
	    tracker_id = TRACKER_FLEXTRAX;
	    goto skip_test;
	}
    }

    /* Test for Mod's Grave WOW modules
     *
     * Stefan Danes <*****@*****.**> said:
     * This weird format is identical to '8CHN' but still uses the 'M.K.' ID.
     * You can only test for WOW by calculating the size of the module for 8 
     * channels and comparing this to the actual module length. If it's equal, 
     * the module is an 8 channel WOW.
     */

    if ((wow = (!strncmp(magic, "M.K.", 4) &&
		(0x43c + mod->pat * 32 * 0x40 + smp_size == m->size)))) {
	mod->chn = 8;
	tracker_id = TRACKER_MODSGRAVE;
	goto skip_test;
    }

    /* Test for Protracker song files
     */
    else if ((ptsong = (!strncmp((char *)magic, "M.K.", 4) &&
		(0x43c + mod->pat * 0x400 == m->size)))) {
	tracker_id = TRACKER_PROTRACKER;
	goto skip_test;
    }

    /* Test Protracker-like files
     */
    if (mod->chn == 4 && mh.restart == mod->pat) {
	tracker_id = TRACKER_SOUNDTRACKER;
    } else if (mod->chn == 4 && mh.restart == 0x78) {
        tracker_id = TRACKER_NOISETRACKER;
    } else if (mh.restart < 0x7f) {
	if (mod->chn == 4) {
	    tracker_id = TRACKER_NOISETRACKER;
	} else {
	    tracker_id = TRACKER_UNKNOWN;
	}
	mod->rst = mh.restart;
    }

    if (mod->chn != 4 && mh.restart == 0x7f) {
	tracker_id = TRACKER_SCREAMTRACKER3;
	m->quirk &= ~QUIRK_MODRNG;
	m->read_event_type = READ_EVENT_ST3;
    }

    if (mod->chn == 4 && mh.restart == 0x7f) {
	for (i = 0; i < 31; i++) {
	    if (mh.ins[i].loop_size == 0)
		break;
	}
	if (i < 31) {
	    tracker_id = TRACKER_CLONE;
	}
    }

    if (mh.restart != 0x78 && mh.restart < 0x7f) {
	for (i = 0; i < 31; i++) {
	    if (mh.ins[i].loop_size == 0)
		break;
	}
	if (i == 31) {	/* All loops are size 2 or greater */
	    for (i = 0; i < 31; i++) {
		if (mh.ins[i].size == 1 && mh.ins[i].volume == 0) {
		    tracker_id = TRACKER_CONVERTED;
		    goto skip_test;
		}
	    }

	    for (i = 0; i < 31; i++) {
	        if (is_st_ins((char *)mh.ins[i].name))
		    break;
	    }
	    if (i == 31) {	/* No st- instruments */
	        for (i = 0; i < 31; i++) {
		    if (mh.ins[i].size == 0 && mh.ins[i].loop_size == 1) {
			switch (mod->chn) {
			case 4:
			    tracker_id = TRACKER_NOISETRACKER;	/* or Octalyser */
			    break;
			case 6:
			case 8:
		            tracker_id = TRACKER_OCTALYSER;
			    break;
			default:
		            tracker_id = TRACKER_UNKNOWN;
			}
		        goto skip_test;
		    }
	        }

		if (mod->chn == 4) {
	    	    tracker_id = TRACKER_PROTRACKER;
		} else if (mod->chn == 6 || mod->chn == 8) {
	    	    tracker_id = TRACKER_FASTTRACKER;	/* FastTracker 1.01? */
		    m->quirk &= ~QUIRK_MODRNG;
		} else {
	    	    tracker_id = TRACKER_UNKNOWN;
		}
	    }
	} else {	/* Has loops with 0 size */
	    for (i = 15; i < 31; i++) {
	        if (strlen((char *)mh.ins[i].name) || mh.ins[i].size > 0)
		    break;
	    }
	    if (i == 31 && is_st_ins((char *)mh.ins[14].name)) {
		tracker_id = TRACKER_CONVERTEDST;
		goto skip_test;
	    }

	    /* Assume that Fast Tracker modules won't have ST- instruments */
	    for (i = 0; i < 31; i++) {
	        if (is_st_ins((char *)mh.ins[i].name))
		    break;
	    }
	    if (i < 31) {
		tracker_id = TRACKER_UNKNOWN_CONV;
		goto skip_test;
	    }

	    if (mod->chn == 4 || mod->chn == 6 || mod->chn == 8) {
	    	tracker_id = TRACKER_FASTTRACKER;
	        m->quirk &= ~QUIRK_MODRNG;
		goto skip_test;
	    }

	    tracker_id = TRACKER_UNKNOWN;	/* ??!? */
	}
    }

skip_test:

    switch (tracker_id) {
    case TRACKER_PROTRACKER:
	tracker = "Protracker";
	ptkloop = 1;
	break;
    case TRACKER_NOISETRACKER:
	tracker = "Noisetracker";
	ptkloop = 1;
	break;
    case TRACKER_SOUNDTRACKER:
	tracker = "Soundtracker";
	ptkloop = 1;
	break;
    case TRACKER_FASTTRACKER:
	tracker = "Fast Tracker";
	break;
    case TRACKER_FASTTRACKER2:
	tracker = "FastTracker 2";
	break;
    case TRACKER_OCTALYSER:
	tracker = "Octalyser";
	break;
    case TRACKER_TAKETRACKER:
	tracker = "TakeTracker";
	break;
    case TRACKER_DIGITALTRACKER:
	tracker = "Digital Tracker";
	break;
    case TRACKER_FLEXTRAX:
	tracker = "Flextrax";
	break;
    case TRACKER_MODSGRAVE:
	tracker = "Mod's Grave";
	break;
    case TRACKER_SCREAMTRACKER3:
	tracker = "Scream Tracker III";
	break;
    case TRACKER_UNKNOWN_CONV:
	tracker = "unknown or converted";
	break;
    case TRACKER_CONVERTEDST:
	tracker = "converted ST2.2 or earlier";
	break;
    case TRACKER_CONVERTED:
	tracker = "converted";
	break;
    case TRACKER_CLONE:
	tracker = "Protracker clone";
	break;
    default:
    case TRACKER_UNKNOWN:
	tracker = "unknown";
	break;
    }

    mod->trk = mod->chn * mod->pat;

    snprintf(mod->type, XMP_NAME_SIZE, "%s (%s)", tracker, magic);
    MODULE_INFO();

    for (i = 0; i < mod->ins; i++) {
	D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d %c\n",
		i, mod->xxi[i].name,
		mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
		(mh.ins[i].loop_size > 1 && mod->xxs[i].lpe > 8) ?
			'L' : ' ', mod->xxi[i].sub[0].vol,
		mod->xxi[i].sub[0].fin >> 4,
		ptkloop && mod->xxs[i].lps == 0 && mh.ins[i].loop_size > 1 &&
			mod->xxs[i].len > mod->xxs[i].lpe ? '!' : ' ');
    }

    if (pattern_init(mod) < 0)
	return -1;

    /* Load and convert patterns */
    D_(D_INFO "Stored patterns: %d", mod->pat);

    for (i = 0; i < mod->pat; i++) {
	if (pattern_tracks_alloc(mod, i, 64) < 0)
	    return -1;

	for (j = 0; j < (64 * mod->chn); j++) {
	    event = &EVENT (i, j % mod->chn, j / mod->chn);
	    hio_read (mod_event, 1, 4, f);

	    switch (tracker_id) {
	    case TRACKER_NOISETRACKER:
		decode_noisetracker_event(event, mod_event);
		break;
	    case TRACKER_PROTRACKER:
	    default:
		decode_protracker_event(event, mod_event);
		break;
	    }
	}
    }

    /* Load samples */

    if (m->filename && (x = strrchr(m->filename, '/')))
	strncpy(pathname, m->filename, x - m->filename);

    D_(D_INFO "Stored samples: %d", mod->smp);

    for (i = 0; i < mod->smp; i++) {
	int flags;

	if (!mod->xxs[i].len)
	    continue;

	flags = ptkloop ? SAMPLE_FLAG_FULLREP : 0;

	if (ptsong) {
	    HIO_HANDLE *s;
	    char sn[256];
	    snprintf(sn, XMP_NAME_SIZE, "%s%s", pathname, mod->xxi[i].name);
	
	    if ((s = hio_open_file(sn, "rb"))) {
	        if (load_sample(m, s, flags, &mod->xxs[i], NULL) < 0) {
		    hio_close(s);
		    return -1;
		}
		hio_close(s);
	    }
	} else {
	    if (load_sample(m, f, flags, &mod->xxs[i], NULL) < 0)
		return -1;
	}
    }

    if (mod->chn > 4) {
	m->quirk &= ~QUIRK_MODRNG;
	m->quirk |= QUIRKS_FT2;
	m->read_event_type = READ_EVENT_FT2;
    } else if (strcmp(tracker, "Protracker") == 0) {
	m->quirk |= QUIRK_INVLOOP;
    }

    return 0;
}
Exemple #11
0
int xmp_smix_load_sample(xmp_context opaque, int num, char *path)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct smix_data *smix = &ctx->smix;
	struct module_data *m = &ctx->m;
	struct xmp_instrument *xxi;
	struct xmp_sample *xxs;
	HIO_HANDLE *h;
	uint32 magic;
	int chn, rate, bits, size;
	int retval = -XMP_ERROR_INTERNAL;

	if (num >= smix->ins) {
		retval = -XMP_ERROR_INVALID;
		goto err;
	}

	xxi = &smix->xxi[num];
	xxs = &smix->xxs[num];

	h = hio_open_file(path, "rb");
	if (h == NULL) {
		retval = -XMP_ERROR_SYSTEM;
		goto err;
	}
		
	/* Init instrument */

	xxi->sub = calloc(sizeof(struct xmp_subinstrument), 1);
	if (xxi->sub == NULL) {
		retval = -XMP_ERROR_SYSTEM;
		goto err1;
	}

	xxi->vol = m->volbase;
	xxi->nsm = 1;
	xxi->sub[0].sid = num;
	xxi->sub[0].vol = xxi->vol;
	xxi->sub[0].pan = 0x80;

	/* Load sample */

	magic = hio_read32b(h);
	if (magic != 0x52494646) {	/* RIFF */
		retval = -XMP_ERROR_FORMAT;
		goto err2;
	}

	hio_seek(h, 22, SEEK_SET);
	chn = hio_read16l(h);
	if (chn != 1) {
		retval = -XMP_ERROR_FORMAT;
		goto err2;
	}

	rate = hio_read32l(h);

	hio_seek(h, 34, SEEK_SET);
	bits = hio_read16l(h);

	hio_seek(h, 40, SEEK_SET);
	size = hio_read32l(h) / (bits / 8);

	c2spd_to_note(rate, &xxi->sub[0].xpo, &xxi->sub[0].fin);

	xxs->len = 8 * size / bits;
	xxs->lps = 0;
	xxs->lpe = 0;
	xxs->flg = bits == 16 ? XMP_SAMPLE_16BIT : 0;

	xxs->data = malloc(size);
	if (xxs->data == NULL) {
		retval = -XMP_ERROR_SYSTEM;
		goto err2;
	}

	hio_seek(h, 44, SEEK_SET);
	hio_read(xxs->data, 1, size, h);
	hio_close(h);

	return 0;
	
    err2:
	free(xxi->sub);
	xxi->sub = NULL;
    err1:
	hio_close(h);
    err:
	return retval;
}
Exemple #12
0
int xmp_load_module(xmp_context opaque, char *path)
{
	struct context_data *ctx = (struct context_data *)opaque;
#ifndef LIBXMP_CORE_PLAYER
	struct module_data *m = &ctx->m;
	long size;
	char *temp_name;
#endif
	HIO_HANDLE *h;
	struct stat st;
	int ret;

	D_(D_WARN "path = %s", path);
/*
	if (stat(path, &st) < 0)
		return -XMP_ERROR_SYSTEM;
*/
#ifndef _MSC_VER
	if (S_ISDIR(st.st_mode)) {
		errno = EISDIR;
		return -XMP_ERROR_SYSTEM;
	}
#endif

	if ((h = hio_open(path, "rb")) == NULL)
		return -XMP_ERROR_SYSTEM;

#ifndef LIBXMP_CORE_PLAYER
	D_(D_INFO "decrunch");
	if (decrunch(&h, path, &temp_name) < 0)
		goto err_depack;

	size = hio_size(h);
	if (size < 256) {		/* get size after decrunch */
		hio_close(h);
		unlink_temp_file(temp_name);
		return -XMP_ERROR_FORMAT;
	}
#endif

	if (ctx->state > XMP_STATE_UNLOADED)
		xmp_release_module(opaque);

#ifndef LIBXMP_CORE_PLAYER
	m->dirname = get_dirname(path);
	if (m->dirname == NULL)
		return -XMP_ERROR_SYSTEM;

	m->basename = get_basename(path);
	if (m->basename == NULL)
		return -XMP_ERROR_SYSTEM;

	m->filename = path;	/* For ALM, SSMT, etc */
	m->size = size;
#endif

	ret = load_module(opaque, h);
	hio_close(h);

#ifndef LIBXMP_CORE_PLAYER
	unlink_temp_file(temp_name);
#endif

	return ret;

#ifndef LIBXMP_CORE_PLAYER
    err_depack:
	hio_close(h);
	unlink_temp_file(temp_name);
	return -XMP_ERROR_DEPACK;
#endif
}
Exemple #13
0
int xmp_test_module(char *path, struct xmp_test_info *info)
{
	HIO_HANDLE *h;
	struct stat st;
	char buf[XMP_NAME_SIZE];
	int i;
	int ret = -XMP_ERROR_FORMAT;
#ifndef LIBXMP_CORE_PLAYER
	char *temp = NULL;
#endif

	if (stat(path, &st) < 0)
		return -XMP_ERROR_SYSTEM;

#ifndef _MSC_VER
	if (S_ISDIR(st.st_mode)) {
		errno = EISDIR;
		return -XMP_ERROR_SYSTEM;
	}
#endif

	if ((h = hio_open(path, "rb")) == NULL)
		return -XMP_ERROR_SYSTEM;

#ifndef LIBXMP_CORE_PLAYER
	if (decrunch(&h, path, &temp) < 0) {
		ret = -XMP_ERROR_DEPACK;
		goto err;
	}

	/* get size after decrunch */
	if (hio_size(h) < 256) {	/* set minimum valid module size */
		ret = -XMP_ERROR_FORMAT;
		goto err;
	}
#endif

	if (info != NULL) {
		*info->name = 0;	/* reset name prior to testing */
		*info->type = 0;	/* reset type prior to testing */
	}

	for (i = 0; format_loader[i] != NULL; i++) {
		hio_seek(h, 0, SEEK_SET);
		if (format_loader[i]->test(h, buf, 0) == 0) {
			int is_prowizard = 0;

#ifndef LIBXMP_CORE_PLAYER
			if (strcmp(format_loader[i]->name, "prowizard") == 0) {
				hio_seek(h, 0, SEEK_SET);
				pw_test_format(h, buf, 0, info);
				is_prowizard = 1;
			}
#endif

			fclose(h->handle.file);

#ifndef LIBXMP_CORE_PLAYER
			unlink_temp_file(temp);
#endif

			if (info != NULL && !is_prowizard) {
				strncpy(info->name, buf, XMP_NAME_SIZE);
				strncpy(info->type, format_loader[i]->name,
							XMP_NAME_SIZE);
			}
			return 0;
		}
	}

#ifndef LIBXMP_CORE_PLAYER
    err:
	hio_close(h);
	unlink_temp_file(temp);
#else
	hio_close(h);
#endif
	return ret;
}
Exemple #14
0
static int decrunch(HIO_HANDLE **h, char *filename, char **temp)
{
	unsigned char b[1024];
	char *cmd;
	FILE *f, *t;
	int res;
	int headersize;
	int i;
	struct depacker *depacker = NULL;

	cmd = NULL;
	res = 0;
	*temp = NULL;
	f = (*h)->handle.file;

	fseek(f, 0, SEEK_SET);
	headersize = fread(b, 1, 1024, f);
	if (headersize < 100)	/* minimum valid file size */
		return 0;

	/* Check built-in depackers */
	for (i = 0; depacker_list[i] != NULL; i++) {
		if (depacker_list[i]->test(b)) {
			depacker = depacker_list[i];
			D_(D_INFO "Use depacker %d", i);
			break;
		}
	}

	/* Check external commands */
	if (depacker == NULL) {
		if (b[0] == 'M' && b[1] == 'O' && b[2] == '3') {
			/* MO3 */
			D_(D_INFO "mo3");
			cmd = "unmo3 -s \"%s\" STDOUT";
		} else if (memcmp(b, "Rar", 3) == 0) {
			/* rar */
			D_(D_INFO "rar");
			cmd = "unrar p -inul -xreadme -x*.diz -x*.nfo -x*.txt "
			    "-x*.exe -x*.com \"%s\"";
		} else if (test_oxm(f) == 0) {
			/* oggmod */
			D_(D_INFO "oggmod");
			depacker = &oxm_depacker;
		}
	}

	fseek(f, 0, SEEK_SET);

	if (depacker == NULL && cmd == NULL) {
		D_(D_INFO "Not packed");
		return 0;
	}

#if defined ANDROID || defined __native_client__
	/* Don't use external helpers in android */
	if (cmd) {
		return 0;
	}
#endif

	D_(D_WARN "Depacking file... ");

	if ((t = make_temp_file(temp)) == NULL)
		return -1;

	/* Depack file */
	if (cmd) {
		D_(D_INFO "External depacker: %s", cmd);
		if (execute_command(cmd, filename, t) < 0) {
			D_(D_CRIT "failed");
			fclose(t);
			return -1;
		}
	} else if (depacker) {
		D_(D_INFO "Internal depacker");
		if (depacker->depack(f, t) < 0) {
			D_(D_CRIT "failed");
			fclose(t);
			return -1;
		}
	}

	D_(D_INFO "done");

	fseek(t, 0, SEEK_SET);
	hio_close(*h);
	*h = hio_open_file(t);

	return res;
}
Exemple #15
0
static int alm_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
    struct xmp_module *mod = &m->mod;
    int i, j;
    struct alm_file_header afh;
    struct xmp_event *event;
    struct stat stat;
    uint8 b;
    char *basename;
    char filename[NAME_SIZE];
    char modulename[NAME_SIZE];

    LOAD_INIT();

    hio_read(&afh.id, 7, 1, f);

    if (!strncmp((char *)afh.id, "ALEYMOD", 7))		/* Version 1.0 */
	mod->spd = afh.speed / 2;

    strncpy(modulename, m->filename, NAME_SIZE);
    basename = strtok (modulename, ".");

    afh.speed = hio_read8(f);
    afh.length = hio_read8(f);
    afh.restart = hio_read8(f);
    hio_read(&afh.order, 128, 1, f);

    mod->len = afh.length;
    mod->rst = afh.restart;
    memcpy (mod->xxo, afh.order, mod->len);

    for (mod->pat = i = 0; i < mod->len; i++)
	if (mod->pat < afh.order[i])
	    mod->pat = afh.order[i];
    mod->pat++;

    mod->ins = 31;
    mod->trk = mod->pat * mod->chn;
    mod->smp = mod->ins;
    m->c4rate = C4_NTSC_RATE;

    set_type(m, "Aley's Module");

    MODULE_INFO();

    if (pattern_init(mod) < 0)
	return -1;

    /* Read and convert patterns */
    D_(D_INFO "Stored patterns: %d", mod->pat);

    for (i = 0; i < mod->pat; i++) {
	if (pattern_tracks_alloc(mod, i, 64) < 0)
		return -1;

	for (j = 0; j < 64 * mod->chn; j++) {
	    event = &EVENT (i, j % mod->chn, j / mod->chn);
	    b = hio_read8(f);
	    if (b)
		event->note = (b == 37) ? 0x61 : b + 48;
	    event->ins = hio_read8(f);
	}
    }

    if (instrument_init(mod) < 0)
	return -1;

    /* Read and convert instruments and samples */

    D_(D_INFO "Loading samples: %d", mod->ins);

    for (i = 0; i < mod->ins; i++) {
	HIO_HANDLE *s;

	if (subinstrument_alloc(mod, i, 1) < 0)
	    return -1;

	mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1);
	snprintf(filename, NAME_SIZE, "%s.%d", basename, i + 1);
	s = hio_open(filename, "rb");

	if (s == NULL)
	    continue;

	mod->xxi[i].nsm = 1;

	hio_stat(s, &stat);
	b = hio_read8(s);		/* Get first octet */
	mod->xxs[i].len = stat.st_size - 5 * !b;

	if (!b) {		/* Instrument with header */
	    mod->xxs[i].lps = hio_read16l(f);
	    mod->xxs[i].lpe = hio_read16l(f);
	    mod->xxs[i].flg = mod->xxs[i].lpe > mod->xxs[i].lps ? XMP_SAMPLE_LOOP : 0;
	} else {
	    hio_seek(s, 0, SEEK_SET);
	}

	mod->xxi[i].sub[0].pan = 0x80;
	mod->xxi[i].sub[0].vol = 0x40;
	mod->xxi[i].sub[0].sid = i;

	D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x", i,
		filename, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
		mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol);

	if (load_sample(m, s, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
	    return -1;

	hio_close(s);
    }

    /* ALM is LRLR, not LRRL */
    for (i = 0; i < mod->chn; i++)
	mod->xxc[i].pan = DEFPAN((i % 2) * 0xff);

    return 0;
}
Exemple #16
0
static int pw_load(struct module_data *m, HIO_HANDLE *h, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	struct mod_header mh;
	uint8 mod_event[4];
	HIO_HANDLE *f;
	FILE *temp;
	char *name;
	char *temp_name;
	int i, j;

	/* Prowizard depacking */

	if ((temp = make_temp_file(&temp_name)) == NULL) {
		goto err;
	}

	if (pw_wizardry(h, temp, &name) < 0) {
		fclose(temp);
		goto err2;
	}
	
	/* Module loading */

	if ((f = hio_open_file(temp)) == NULL) {
		goto err2;
	}

	if (hio_seek(f, 0, start) < 0) {
		goto err3;
	}

	hio_read(&mh.name, 20, 1, f);
	for (i = 0; i < 31; i++) {
		hio_read(&mh.ins[i].name, 22, 1, f);
		mh.ins[i].size = hio_read16b(f);
		mh.ins[i].finetune = hio_read8(f);
		mh.ins[i].volume = hio_read8(f);
		mh.ins[i].loop_start = hio_read16b(f);
		mh.ins[i].loop_size = hio_read16b(f);
	}
	mh.len = hio_read8(f);
	mh.restart = hio_read8(f);
	hio_read(&mh.order, 128, 1, f);
	hio_read(&mh.magic, 4, 1, f);

	if (memcmp(mh.magic, "M.K.", 4)) {
		goto err3;
	}
		
	mod->ins = 31;
	mod->smp = mod->ins;
	mod->chn = 4;
	mod->len = mh.len;
	mod->rst = mh.restart;
	memcpy(mod->xxo, mh.order, 128);

	for (i = 0; i < 128; i++) {
		if (mod->xxo[i] > mod->pat)
			mod->pat = mod->xxo[i];
	}

	mod->pat++;

	mod->trk = mod->chn * mod->pat;

	snprintf(mod->name, XMP_NAME_SIZE, "%s", (char *)mh.name);
	snprintf(mod->type, XMP_NAME_SIZE, "%s", name);
	MODULE_INFO();

	if (libxmp_init_instrument(m) < 0) {
		goto err3;
	}

	for (i = 0; i < mod->ins; i++) {
		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			goto err3;

		mod->xxs[i].len = 2 * mh.ins[i].size;
		mod->xxs[i].lps = 2 * mh.ins[i].loop_start;
		mod->xxs[i].lpe = mod->xxs[i].lps + 2 * mh.ins[i].loop_size;
		mod->xxs[i].flg = mh.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0;
		mod->xxi[i].sub[0].fin = (int8) (mh.ins[i].finetune << 4);
		mod->xxi[i].sub[0].vol = mh.ins[i].volume;
		mod->xxi[i].sub[0].pan = 0x80;
		mod->xxi[i].sub[0].sid = i;
		mod->xxi[i].rls = 0xfff;

		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

		libxmp_instrument_name(mod, i, mh.ins[i].name, 22);

		D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d",
			     i, mod->xxi[i].name, mod->xxs[i].len,
			     mod->xxs[i].lps, mod->xxs[i].lpe,
			     mh.ins[i].loop_size > 1 ? 'L' : ' ',
			     mod->xxi[i].sub[0].vol,
			     mod->xxi[i].sub[0].fin >> 4);
	}

	if (libxmp_init_pattern(mod) < 0) {
		goto err3;
	}

	/* Load and convert patterns */
	D_(D_INFO "Stored patterns: %d", mod->pat);

	for (i = 0; i < mod->pat; i++) {
		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
			goto err3;

		for (j = 0; j < (64 * 4); j++) {
			event = &EVENT(i, j % 4, j / 4);
			hio_read(mod_event, 1, 4, f);
			libxmp_decode_protracker_event(event, mod_event);
		}
	}

	m->period_type = PERIOD_MODRNG;

	/* Load samples */

	D_(D_INFO "Stored samples: %d", mod->smp);
	for (i = 0; i < mod->smp; i++) {
		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
			goto err3;
	}

	hio_close(f);
	unlink_temp_file(temp_name);
	return 0;

    err3:
	hio_close(f);
    err2:
	unlink_temp_file(temp_name);
    err:
	return -1;
}
Exemple #17
0
static int mfp_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	int i, j, k, x, y;
	struct xmp_event *event;
	struct stat st;
	char smp_filename[PATH_MAX];
	HIO_HANDLE *s;
	int size1, size2;
	int pat_addr, pat_table[128][4];
	uint8 buf[1024], mod_event[4];
	int row;

	LOAD_INIT();

	set_type(m, "Magnetic Fields Packer");
	MODULE_INFO();

	mod->chn = 4;
	mod->ins = mod->smp = 31;

	if (instrument_init(mod) < 0)
		return -1;

	for (i = 0; i < 31; i++) {
		int loop_size;

		if (subinstrument_alloc(mod, i, 1) < 0)
			return -1;
		
		mod->xxs[i].len = 2 * hio_read16b(f);
		mod->xxi[i].sub[0].fin = (int8)(hio_read8(f) << 4);
		mod->xxi[i].sub[0].vol = hio_read8(f);
		mod->xxs[i].lps = 2 * hio_read16b(f);
		loop_size = hio_read16b(f);

		mod->xxs[i].lpe = mod->xxs[i].lps + 2 * loop_size;
		mod->xxs[i].flg = loop_size > 1 ? XMP_SAMPLE_LOOP : 0;
		mod->xxi[i].sub[0].pan = 0x80;
		mod->xxi[i].sub[0].sid = i;
		mod->xxi[i].rls = 0xfff;

		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

               	D_(D_INFO "[%2X] %04x %04x %04x %c V%02x %+d",
                       	i, mod->xxs[i].len, mod->xxs[i].lps,
                       	mod->xxs[i].lpe,
			loop_size > 1 ? 'L' : ' ',
                       	mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4);
	}

	mod->len = mod->pat = hio_read8(f);
	hio_read8(f);		/* restart */

	for (i = 0; i < 128; i++)
		mod->xxo[i] = hio_read8(f);

#if 0
	for (i = 0; i < 128; i++) {
		mod->xxo[i] = hio_read8(f);
		if (mod->xxo[i] > mod->pat)
			mod->pat = mod->xxo[i];
	}
	mod->pat++;
#endif

	mod->trk = mod->pat * mod->chn;

	/* Read and convert patterns */

	if (pattern_init(mod) < 0)
		return -1;

	size1 = hio_read16b(f);
	size2 = hio_read16b(f);

	for (i = 0; i < size1; i++) {		/* Read pattern table */
		for (j = 0; j < 4; j++) {
			pat_table[i][j] = hio_read16b(f);
		}
	}

	D_(D_INFO "Stored patterns: %d ", mod->pat);

	pat_addr = hio_tell(f);

	for (i = 0; i < mod->pat; i++) {
		if (pattern_tracks_alloc(mod, i, 64) < 0)
			return -1;

		for (j = 0; j < 4; j++) {
			hio_seek(f, pat_addr + pat_table[i][j], SEEK_SET);

			hio_read(buf, 1, 1024, f);

			for (row = k = 0; k < 4; k++) {
				for (x = 0; x < 4; x++) {
					for (y = 0; y < 4; y++, row++) {
						event = &EVENT(i, j, row);
						memcpy(mod_event, &buf[buf[buf[buf[k] + x] + y] * 2], 4);
						decode_protracker_event(event, mod_event);
					}
				}
			}
		}
	}

	/* Read samples */
	D_(D_INFO "Loading samples: %d", mod->ins);

	/* first check smp.filename */
	if (strlen(m->basename) < 5 || m->basename[3] != '.') {
		fprintf(stderr, "libxmp: invalid filename %s\n", m->basename);
		goto err;
	}

	m->basename[0] = 's';
	m->basename[1] = 'm';
	m->basename[2] = 'p';
	snprintf(smp_filename, sizeof(smp_filename), "%s%s", m->dirname, m->basename);
	if (stat(smp_filename, &st) < 0) {
		/* handle .set filenames like in Kid Chaos*/
		char *x;
		if (strchr(m->basename, '-')) {
			if ((x = strrchr(smp_filename, '-')))
				strcpy(x, ".set");
		}
		if (stat(smp_filename, &st) < 0) {
			fprintf(stderr, "libxmp: missing file %s\n",
								smp_filename);
			goto err;
		}
	}
	if ((s = hio_open_file(smp_filename, "rb")) == NULL) {
		fprintf(stderr, "libxmp: can't open sample file %s\n",
								smp_filename);
		goto err;
	}

	for (i = 0; i < mod->ins; i++) {
		if (load_sample(m, s, SAMPLE_FLAG_FULLREP,
				  &mod->xxs[mod->xxi[i].sub[0].sid], NULL) < 0)
			return -1;
	}

	hio_close(s);

	m->quirk |= QUIRK_MODRNG;

	return 0;

    err:
	for (i = 0; i < mod->ins; i++) {
		mod->xxi[i].nsm = 0;
		memset(&mod->xxs[i], 0, sizeof(struct xmp_sample));
	}

	return 0;
}
Exemple #18
0
int main(void)
{
    fd_set master;    // master file descriptor list
    fd_set read_fds;  // temp file descriptor list for select()
    int fdmax;        // maximum file descriptor number

    int listener;     // listening socket descriptor
    int s;
    int newfd;        // newly accept()ed socket descriptor
    struct sockaddr_storage remoteaddr; // client address
    socklen_t addrlen;

    int nbytes;

    char remoteIP[INET6_ADDRSTRLEN];

    int i;
    int len;
    char *buf = NULL;
#define BUF_SIZE 4096*10
    buf =(char *)malloc(BUF_SIZE);
    int buflen = BUF_SIZE;
    if (buf == NULL) {
	    perror("init malloc");
	    abort();
    }

    listener = create_and_bind();
    if (listener == -1) abort();

    // listen
    s = listen(listener, SOMAXCONN);
    if (s == -1) {
	    perror ("listen");
	    abort ();
    }
    printf("Listening at socket %d port %d\n", listener, PORTNUM);

    FD_ZERO(&master);
    // add the listener to the master set
    FD_SET(listener, &master);

    // keep track of the biggest file descriptor
    fdmax = listener; // so far, it's this one

    // main loop
    for(;;) {
        read_fds = master; // copy it
        if (hio_select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
            perror("select");
            return -1;
        }

        // run through the existing connections looking for data to read
        for(i = 0; i <= fdmax; i++) {
            if (FD_ISSET(i, &read_fds)) { // we got one!!
                if (i == listener) {
                    // handle new connections
                    addrlen = sizeof remoteaddr;
		    newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen);

		    if (newfd == -1) {
                        perror("accept");
                    } else {
                        FD_SET(newfd, &master); // add to master set
                        if (newfd > fdmax) {    // keep track of the max
                            fdmax = newfd;
                        }
			printf("[INFO] new connection from %s on " "socket %d\n",
				inet_ntop(remoteaddr.ss_family,
					&(((struct sockaddr_in*)&remoteaddr)->sin_addr),
					remoteIP,
					INET6_ADDRSTRLEN),
				newfd);
                    }
                } else {
#define HEADER_SIZE 4
			// handle data from a client
			nbytes = recv(i, buf, HEADER_SIZE, 0);
			if (nbytes < HEADER_SIZE) {
				if (nbytes < 0 && errno != ECONNRESET) {
                                    printf("[ERROR] recv header ret %d, errno is not supported by HIO\n", i);
                                    goto out;
                                }
				printf("[INFO] socket hung up in recv header: %d\n", i);
				hio_close(i); // bye!
				FD_CLR(i, &master); // remove from master set
				break;
			}

			len = ntohl(*(int *)buf);
			//printf("len %d\n", len);

			// dynamic heap allocation
			if (len > buflen) {
				if (buf != NULL) free(buf);
				buf = (char *)malloc(len*2);
				buflen = len * 2;
                                printf("resizing buffer to %d\n", buflen);
				if (buf == NULL) {
					perror("malloc");
					abort();
				}
			}

			int left = len;
			nbytes = 0;
			while (left > 0) {
				//printf("%d bytes left\n", left);
				nbytes = recv(i, buf, left, 0);
				if (nbytes <= 0) {
					if (nbytes < 0 && errno != ECONNRESET) {
                                            printf("[ERROR] recv data ret %d, errno is not supported by HIO\n", i);
                                            goto out;
                                        }
					printf("[INFO] socket hung up in recv data: %d\n", i);
					//printf("%d: received %d bytes, nbytes %d\n", i, len+HEADER_SIZE, nbytes);
					hio_close(i); // bye!
					FD_CLR(i, &master); // remove from master set
					break;
				}
				left = len - nbytes;
				//printf("len %d, nbytes %d, %d bytes left\n", len, nbytes, left);
			}
			if (nbytes <= 0) {
				//printf("break %d\n", i);
				break;
			}

			//printf("%d: received %d bytes, nbytes %d\n", i, len+HEADER_SIZE, nbytes);
			nbytes = send(i, "Done", 5, 0);
			if (nbytes <= 0) {
				if (nbytes < 0) {
                                    printf("[ERROR] send ret %d, errno is not supported by HIO\n", i);
                                    goto out;
                                }
				printf("[INFO] socket hung up in send: %d\n", i);
				hio_close(i); // bye!
				FD_CLR(i, &master); // remove from master set
			}
			//printf("write 5 bytes\n");
                } // END handle data from client
            } // END got new incoming connection
        } // END looping through file descriptors
    } // END for(;;)--and you thought it would never end!

out:
    printf("Tearing down Mutilate clint may cause errno 104 (ECONNRESET) to server read/write,\n");
    printf("But the performance numbers measured are still valid.\n");

    return 0;
}