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

📄 sitemap.c

📁 CHM decompiler is a program that converts the internal files of CHM files back into the HHP, HHC, an
💻 C
字号:
/*chmdeco -- extract files from ITS/CHM files and decompile CHM filesCopyright (C) 2003 PabsThis program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free Software Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307, USA or visit:http://www.gnu.org*//*sitemap.c - this module implements an interface to the #TOPICS, #URLTBL & #URLSTR files.It was written by Pabs.*//* System headers */#include <stdio.h>#include <sys/types.h>#include <stdlib.h>#include <string.h>#include <errno.h>/* Local headers */#include "chmdeco.h"#include "common.h"#include "convert.h"#include "sitemap.h"#include "strings.h"FILE* topics = NULL;FILE* urltbl = NULL;FILE* urlstr = NULL;uint depth = 0;bool open_sitemap(){	if( open_strings() ){		errno = 0;		topics = fopen( "#TOPICS", "rb" );		if( !topics && errno && errno != ENOENT )			fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#TOPICS", strerror(errno) );		errno = 0;		urltbl = fopen( "#URLTBL", "rb" );		if( !urltbl && errno && errno != ENOENT )			fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#URLTBL", strerror(errno) );		errno = 0;		urlstr = fopen( "#URLSTR", "rb" );		if( !urlstr && errno && errno != ENOENT )			fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#URLSTR", strerror(errno) );		if( topics && urltbl && urlstr ){			return true;		} else {			FCLOSE(topics);			FCLOSE(urltbl);			FCLOSE(urlstr);		}		/* Don't close_strings(); - needed elsewhere */	}	return false;}/* Should fit most #URLSTR strings in one go */#define GROW 100/* No buffering for now, just seek n read */char* get_urlstr(off_t off){	char* t; char* start;	char* ret = NULL;	uint ret_len = 0;	fseek(urlstr,off,SEEK_SET);	do{		/* Get more space */		t = (char*)realloc(ret,ret_len+GROW);		if( !t ){			fprintf( stderr, "%s: %s %s: %s\n", PROGNAME, input, "#URLSTR buffer", strerror(errno) );			FREE(ret);			return NULL;		}		ret = t; start = ret + ret_len; ret_len += GROW;		/* Get more bytes */		if( !fread(start,1,GROW,urlstr) || ferror(urlstr) ){			fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#URLSTR", strerror(errno) );			FREE(ret);			return NULL;		}	}while(!memchr(start,0,GROW));	return ret;}BYTE entry[4*4];/* Print out the Name, Local, FrameName, URL of a topic */bool print_topics_entry( FILE* f, size_t index ){	fseek(topics, index*16, SEEK_SET);	if( fread(entry,16,1,topics) ){		DWORD urlstr_offset;		char* Name = get_string(get_DWORD(entry+4));		if(Name){			DEPTHPUT(f);			if( print_entity_refs ){				fputs( "\t<param name=\"Name\" value=\"", f );				print_with_entity_refs( f, Name );				fputs( "\">\r\n", f );			} else fprintf( f, "\t<param name=\"Name\" value=\"%s\">\r\n", Name );			FREE(Name);		}		fseek( urltbl, get_DWORD(entry+8)+8, SEEK_SET);		if( read_DWORD(urltbl,&urlstr_offset) ){			fseek(urlstr, urlstr_offset, SEEK_SET);			if( fread(entry,8,1,urlstr) ){				DWORD URL, FrameName;				char* URL_s = NULL;				char* FrameName_s = NULL;				char* Local = get_urlstr(urlstr_offset+8);				if(Local){					DEPTHPUT(f);					if( print_entity_refs ){						fputs( "\t<param name=\"Local\" value=\"", f );						print_with_entity_refs( f, Local );						fputs( "\">\r\n", f );					} else fprintf( f, "\t<param name=\"Local\" value=\"%s\">\r\n", Local );					FREE(Local);				}				URL = get_DWORD(entry);				if(URL) URL_s = get_urlstr(URL);				if(URL_s){					DEPTHPUT(f);					if( print_entity_refs ){						fputs( "\t<param name=\"URL\" value=\"", f );						print_with_entity_refs( f, URL_s );						fputs( "\">\r\n", f );					} else fprintf( f, "\t<param name=\"URL\" value=\"%s\">\r\n", URL_s );					FREE(URL_s);				}				FrameName = get_DWORD(entry+4);				if(FrameName) FrameName_s = get_urlstr(FrameName);				if(FrameName_s){					DEPTHPUT(f);					if( print_entity_refs ){						fputs( "\t<param name=\"FrameName\" value=\"", f );						print_with_entity_refs( f, FrameName_s );						fputs( "\">\r\n", f );					} else fprintf( f, "\t<param name=\"FrameName\" value=\"%s\">\r\n", FrameName_s );					FREE(FrameName_s);				}				return true;			} else fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#URLSTR", strerror(errno) );		} else fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#URLTBL", strerror(errno) );	} else fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#TOPICS", strerror(errno) );	return false;}/* FIXME: When we know its meaning rename majik to something descriptive *//* Search for an url with the specified majik number */DWORD find_in_urltbl( DWORD majik ){	/* Can't choose how to do this cause of that damn 4096 DWORD at the end */	BYTE buf[4096]; size_t len; DWORD tmp = 0; BYTE* i;	fseek( urltbl, 0, SEEK_SET );	do{		errno = 0;		len = fread( buf, 1, 4096, urltbl );		if( len < 4096 && len%12 )			fprintf( stderr, "%s: warning: %s/%s: %s\n", PROGNAME, input, "#URLTBL", "partial entry found" );		if( ferror(urltbl) || errno )			fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#URLTBL", strerror(errno) );		/* We only want complete entries */		len = len/12*12;		for(i=buf;i<&buf[len];i+=12){			tmp = get_DWORD(i);			if( tmp == majik ) return get_DWORD(i+8);		}	}while( len >= 4092 );	return 0;}void close_sitemap(){	/* Don't close_strings(); - needed elsewhere */	FCLOSE(topics);	FCLOSE(urltbl);	FCLOSE(urlstr);}

⌨️ 快捷键说明

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