📄 misc.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*//*misc.c - this module implements stp, context sensitivity, samples, html from ftsoutput.It was written by Pabs.*//* System headers */#include <stdio.h>#include <errno.h>#include <dirent.h>#include <sys/stat.h>#include <sys/types.h>#include <stdlib.h>#include <string.h>#include <unistd.h>/* Local headers */#include "chmdeco.h"#include "common.h"#include "sitemap.h"#include "strings.h"#include "misc.h"bool stp_success = false;/* FIXME: output the stp 1 word per line, all on one line or a limited number of chars/words per line? */#define STP_SEPARATOR "\r\n"/* FIXME: search for .stp files too? *//* FIXME: that many indentations are just fugly */void recreate_fts_stop_list_file( void ){ FILE* objinst = fopen("$OBJINST","rb"); stp_success = false; if(objinst){ DWORD num; fseek(objinst,4,SEEK_SET); if( read_DWORD(objinst,&num) ){ DWORD i, offset, length; off_t cur_off = ftell(objinst); /* {4662DAAF-D393-11D0-9A56-00C04FB68BF7} */ BYTE guid[16]; BYTE need[16] = "\xaf\xda\x62\x46\x93\xd3\xd0\x11\x9a\x56\0\xc0\x4f\xb6\x8b\xf7"; for( i = 0; i < num; i++ ){ fseek(objinst,cur_off,SEEK_SET); if( read_DWORD(objinst,&offset) && read_DWORD(objinst,&length) ){ cur_off = ftell(objinst); fseek(objinst,offset,SEEK_SET); if( fread(guid,16,1,objinst) ){ if( !memcmp(guid,need,16) ){ DWORD flags; fseek(objinst,4,SEEK_CUR); if( read_DWORD(objinst,&flags) ){ if( flags&4 ){ fseek(objinst,2631+4,SEEK_CUR); if( read_DWORD(objinst,&length) ){ if( length ){ BYTE* buf = (BYTE*)malloc(length+2); if( buf ){ fseek(objinst,32,SEEK_CUR); if( fread(buf,length,1,objinst) ){ FILE* stp = recreate(FTS_STOP_LIST_FILE_NAME); if(stp){ WORD len; char* s = (char*)buf; buf[length+1] = buf[length] = 0; while( (len = get_WORD(s)) ){ s+=2; fwrite(s,len,1,stp); s+=len; fputs( STP_SEPARATOR, stp ); } if( ferror(stp) ) fprintf( stderr, "%s: %s/%s/%s: %s\n", PROGNAME, input, "#recreated", FTS_STOP_LIST_FILE_NAME, strerror(errno) ); else stp_success = true; FCLOSE(stp); /* We're done */ break; } else fprintf( stderr, "%s: %s/%s/%s: %s\n", PROGNAME, input, "#recreated", FTS_STOP_LIST_FILE_NAME, strerror(errno) ); } else fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "$OBJINST", strerror(errno) ); FREE(buf); } else goto MERROR; } } else goto FERROR; } } else goto FERROR; } } else goto FERROR; } else goto FERROR; } } else goto FERROR; FCLOSE(objinst); } return;FERROR: fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "$OBJINST", strerror(errno) ); FCLOSE(objinst); return;MERROR: fprintf( stderr, "%s: %s %s: %s\n", PROGNAME, input, "stp buffer", strerror(errno) ); FCLOSE(objinst);}bool alias_map_success = false;void recreate_alias_map( void ){ FILE* ivb; errno = 0; alias_map_success = false; if( !open_strings() ) return; ivb = fopen("#IVB","rb"); if( ivb ){ FILE* alias = recreate(ALIAS_FILE_NAME); if(alias){ FILE* map = recreate(MAP_FILE_NAME); if(map){ DWORD tmp; fseek( ivb, 4, SEEK_SET ); for(;;){ if( read_DWORD( ivb, &tmp ) ){ fprintf( map, "#define IDH_%u %u\r\n", tmp, tmp ); fprintf( alias, "IDH_%u=", tmp ); if( read_DWORD( ivb, &tmp ) ) print_string( alias, tmp ); fputs( "\r\n", alias ); } else if( ferror(ivb) ){ fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#IVB", strerror(errno) ); break; } if( feof(ivb) ) break; } alias_map_success = true; if( ferror(map) ){ alias_map_success =false; fprintf( stderr, "%s: %s/%s/%s: %s\n", PROGNAME, input, "#recreated", MAP_FILE_NAME, strerror(errno) ); } if( ferror(alias) ){ alias_map_success =false; fprintf( stderr, "%s: %s/%s/%s: %s\n", PROGNAME, input, "#recreated", ALIAS_FILE_NAME, strerror(errno) ); } FCLOSE(map); } else fprintf( stderr, "%s: %s/%s/%s: %s\n", PROGNAME, input, "#recreated", MAP_FILE_NAME, strerror(errno) ); FCLOSE(alias); } else fprintf( stderr, "%s: %s/%s/%s: %s\n", PROGNAME, input, "#recreated", ALIAS_FILE_NAME, strerror(errno) ); FCLOSE(ivb); } else if( errno && errno != ENOENT ) fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#IVB", strerror(errno) );}bool samples_success = false;char Sample_Staging_Path[8] = "samples";void recreate_samples( void ){ samples_success = false; fprintf( stderr, "%s: warning: %s: %s\n", PROGNAME, input, "samples decompilation not yet implemented" ); /* FIXME: Implement this bit DIR* dir = opendir( "." ); if( dir ){ struct stat st; struct dirent* de; while( (de = readdir( dir )) ){ if( !strcasecmp( de->d_name, "samples" ){ if( !stat( de->d_name, &st ) && S_ISDIR( st.st_mode ) ){ if a folder named samples has any *.sfl in it and a html file has a sample obj in it then write those files out to the hhs strcpy( sample_staging_path, de->d_name ); chdir( sample_staging_path ); if( find( "*.sfl" ) && grep( "*.html", Samples_Object) ){ write out crap to sample-list-file.hhs } } } } closedir( dir ); } */}/*This reads the full text search information, gathering words and locations.It then dumps all the words back into html files*/typedef struct _document_t { char** words; size_t words_len; size_t words_size; SRINT latest_title; SRINT earliest_non_title;} document_t;void recreate_html_from_fts( void ){ long fts_size; FILE* fiftimain = fopen( "$FIftiMain", "rb" ); if( fiftimain ){ if( !fseek( fiftimain, 0, SEEK_END ) && 0 < (fts_size = ftell( fiftimain )) && !fseek( fiftimain, 0, SEEK_SET ) ){ chdir( "#recreated" ); if( !mkdir( "#from-fts" MKDIR_PERM ) || errno == EEXIST ){#define FTS_HEADER_LEN 0x32 BYTE header[FTS_HEADER_LEN] = { 0 }; DWORD node_offset = 0; WORD tree_depth; /* _s = scale, _r = root */ BYTE doc_index_s, doc_index_r; BYTE code_count_s, code_count_r; BYTE loc_codes_s, loc_codes_r; BYTE* leaf_node = NULL; BYTE* offset = NULL; BYTE old_len, new_len; DWORD node_len; DWORD tmp; WORD free_space; size_t current_word_grow = 50; char* current_word = NULL; size_t current_word_len = 0; size_t current_word_size = 0; size_t words_grow = 25000; char** words = NULL; size_t words_len = 0; size_t words_size = 0; size_t words_i = 0; SRINT document_index; SRINT code_count; SRINT location_code; size_t word_location_codes_grow = 5000; BYTE* word_location_codes = NULL; size_t word_location_codes_len = 0; size_t word_location_codes_size = 0; DWORD num_topics; uint word_i; BYTE context; ENCINT wlc_count; DWORD wlc_offset; ENCINT wlc_length; int wlc_bit; BYTE* wlc_p; uint di_i; uint lc_i; FILE* f; size_t docs_grow = 5000; document_t* docs = NULL; size_t docs_len = 0; size_t docs_size = 0; size_t docs_i = 0; size_t doc_words_grow = 500; chdir( ".." ); /* Read the header */ if( !fread( header, FTS_HEADER_LEN, 1, fiftimain ) ){ fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "$FIftiMain", feof( fiftimain ) ? "unexpected end of file" : strerror(errno) ); goto E_MALLOC; } tmp = get_DWORD( header + 8 ); node_offset = get_DWORD( header + 0x14 ); if( tmp != node_offset ){ fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "$FIftiMain", "the two root index offsets are not equal, dunno which to trust" ); EMAIL_CHM; goto E_FCLOSE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -