⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 module.c

📁 Red-Button
💻 C
字号:
/* * module.c *//* * Copyright (C) 2005, Simon Kilvington * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA */#include <stdio.h>#include <string.h>#include <stdbool.h>#include <zlib.h>#include <netinet/in.h>#include "dsmcc.h"#include "carousel.h"#include "biop.h"#include "utils.h"/* * returns NULL if the module does not exist * if this is an update to a module we already have, the old one is deleted */struct module *find_module(struct carousel *car, uint16_t module_id, uint8_t version, uint32_t download_id){	unsigned int i;	for(i=0; i<car->nmodules; i++)	{		if(car->modules[i].module_id == module_id		&& car->modules[i].download_id == download_id)		{			/* spot on */			if(car->modules[i].version == version)			{				return &car->modules[i];			}			/* is it an update to one we already have */			else if(car->modules[i].version < version)			{				delete_module(car, i);				return NULL;			}		}	}	return NULL;}struct module *add_module(struct carousel *car, struct DownloadInfoIndication *dii, struct DIIModule *diimod){	struct module *mod;	car->nmodules ++;	car->modules = safe_realloc(car->modules, car->nmodules * sizeof(struct module));	mod = &car->modules[car->nmodules - 1];	mod->module_id = ntohs(diimod->moduleId);	mod->download_id = ntohl(dii->downloadId);	mod->version = diimod->moduleVersion;	mod->block_size = ntohs(dii->blockSize);	mod->nblocks = (ntohl(diimod->moduleSize) + mod->block_size - 1) / mod->block_size;	mod->blocks_left = mod->nblocks;	mod->got_block = safe_malloc(mod->nblocks * sizeof(bool));	bzero(mod->got_block, mod->nblocks * sizeof(bool));	mod->size = ntohl(diimod->moduleSize);	mod->data = safe_malloc(mod->size);	verbose("add_module: nmodules=%u module=%u size=%u", car->nmodules, mod->module_id, mod->size);	return mod;}voiddelete_module(struct carousel *car, uint32_t num){	uint32_t size;	free_module(&car->modules[num]);	size = ((car->nmodules - 1) - num) * sizeof(struct module);	if(size > 0)		memmove(&car->modules[num], &car->modules[num + 1], size);	car->nmodules --;	return;}voidfree_module(struct module *mod){	safe_free(mod->data);	safe_free(mod->got_block);	return;}voiddownload_block(struct carousel *car, struct module *mod, uint16_t block, unsigned char *data, uint32_t length){	/* assert */	if(block >= mod->nblocks)	{		error("download_block: moduleId=%u block=%u nblocks=%u", mod->module_id, block, mod->nblocks);		return;	}	/* have we already got it */	if(mod->got_block[block])		return;	mod->got_block[block] = true;	memcpy(mod->data + (block * mod->block_size), data, length);	mod->blocks_left --;	verbose("download_block: module=%u block=%u left=%u", mod->module_id, block, mod->blocks_left);	/* have we got it all yet */	if(mod->blocks_left == 0)	{		verbose("got module %u (size=%u)", mod->module_id, mod->size);		/* if it doesn't start with 'BIOP' assume it is compressed */		if(strncmp(mod->data, BIOP_MAGIC_STR, BIOP_MAGIC_LEN) != 0)		{			vhexdump(mod->data, mod->size);			uncompress_module(mod);			verbose("uncompressed size=%u", mod->size);		}		process_biop(car, mod, (struct BIOPMessageHeader *) mod->data, mod->size);		/* we can free the data now, keep got_block so we don't download it again */		safe_free(mod->data);		/* delete_module may safe_free it again */		mod->data = NULL;	}	return;}/* * uncompress in blocks of this size * this is also the minimum size of an uncompressed file */#define CHUNK_SIZE	(4 * 1024)intuncompress_module(struct module *mod){	int ret;	z_stream strm;	unsigned char *out = NULL;	unsigned int out_size = 0;	/* init zlib state */	strm.zalloc = Z_NULL;	strm.zfree = Z_NULL;	strm.opaque = Z_NULL;	strm.avail_in = 0;	strm.next_in = Z_NULL;	ret = inflateInit(&strm);	if(ret != Z_OK)		return ret;	strm.avail_in = mod->size;	strm.next_in = mod->data;	/* decompress until ouput buffer not full */	do	{		out = safe_realloc(out, out_size + CHUNK_SIZE);		strm.avail_out = CHUNK_SIZE;		strm.next_out = out + out_size;		ret = inflate(&strm, Z_NO_FLUSH);		if(ret != Z_OK && ret != Z_STREAM_END)		{			inflateEnd(&strm);			safe_free(out);			return ret;		}		out_size += CHUNK_SIZE - strm.avail_out;	}	while(strm.avail_out == 0);	/* clean up */	inflateEnd(&strm);	/* swap compressed with uncompressed data */	safe_free(mod->data);	mod->data = out;	mod->size = out_size;	return Z_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -