예제 #1
0
파일: cab.c 프로젝트: OPSF/uClinux
void cab_free(struct cab_archive *cab)
{
	struct cab_folder *folder;
	struct cab_file *file;


    if(cab->state) {
	if(cab->state->stream) {
	    switch(cab->state->cmethod & 0x000f) {
		case 0x0001:
		    mszip_free(cab->state->stream);
		    break;
		case 0x0002:
		    qtm_free(cab->state->stream);
		    break;
		case 0x0003:
		    lzx_free(cab->state->stream);
	    }
	}
	free(cab->state);
    }

    while(cab->folders) {
	folder = cab->folders;
	cab->folders = cab->folders->next;
	free(folder);
    }

    while(cab->files) {
	file = cab->files;
	cab->files = cab->files->next;
	free(file->name);
	free(file);
    }
}
예제 #2
0
static int chm_decompress_stream(int fd, chm_metadata_t *metadata, const char *dirname, cli_ctx *ctx)
{
	lzx_content_t lzx_content;
	lzx_reset_table_t lzx_reset_table;
	lzx_control_t lzx_control;
	int window_bits, length, tmpfd, retval=-1;
	struct lzx_stream * stream;
	char filename[1024];
	struct cab_file file;
	
	snprintf(filename, 1024, "%s"PATHSEP"clamav-unchm.bin", dirname);
	tmpfd = open(filename, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU);
	if (tmpfd<0) {
		cli_dbgmsg("open failed for %s\n", filename);
		return -1;
	}

	if (!metadata->sys_control.length || !metadata->sys_content.length ||!metadata->sys_reset.length) {
		cli_dbgmsg("Control file missing\n");
		goto abort;
	}

	if (!read_sys_control(metadata, &lzx_control)) {
		goto abort;
	}
	if (!read_sys_content(metadata, &lzx_content)) {
		goto abort;
	}
	if (!read_sys_reset_table(metadata, &lzx_reset_table)) {
		goto abort;
	}
	
	switch (lzx_control.window_size) {
		case 0x008000:
			window_bits = 15;
			break;
		case 0x010000:
			window_bits = 16;
			break;
		case 0x020000:
			window_bits = 17;
			break;
		case 0x040000:
			window_bits = 18;
			break;
		case 0x080000:
			window_bits = 19;
			break;
		case 0x100000:
			window_bits = 20;
			break;
		case 0x200000:
			window_bits = 21;
			break;
		default:
			cli_dbgmsg("bad control window size: 0x%x\n", lzx_control.window_size);
			goto abort;
	}
	
	if (lzx_control.reset_interval % LZX_FRAME_SIZE) {
		cli_dbgmsg("bad reset_interval: 0x%x\n", lzx_control.window_size);
		goto abort;
	}
	
	length = lzx_reset_table.uncom_len;
	length += lzx_control.reset_interval;
	length &= -lzx_control.reset_interval;
	
	cli_dbgmsg("Compressed offset: %lu\n", (unsigned long int) lzx_content.offset);
	if ((uint64_t) lseek(fd, lzx_content.offset, SEEK_SET) != lzx_content.offset) {
		goto abort;
	}

	memset(&file, 0, sizeof(struct cab_file));
	file.max_size = ctx->engine->maxfilesize;
	stream = lzx_init(fd, tmpfd, window_bits,
			lzx_control.reset_interval / LZX_FRAME_SIZE,
			4096, length, &file, NULL);
	if (!stream) {
		cli_dbgmsg("lzx_init failed\n");
		goto abort;
	}
	
	lzx_decompress(stream, length);
	lzx_free(stream);
	
#ifndef _WIN32
	/* Delete the file */
	if(cli_unlink(filename))
		retval = -1;
	else
#endif
		retval = tmpfd;
	
abort:
	if ((retval == -1) && (tmpfd >= 0)) {
		close(tmpfd);
	}
	return retval;
}