📄 exchm.c
字号:
/* $Id: extract_chmLib.c,v 1.4 2002/10/10 03:24:51 jedwin Exp $ *//*************************************************************************** * extract_chmLib.c - CHM archive extractor * * ------------------- * * * * author: Jed Wing <jedwin@ugcs.caltech.edu> * * notes: This is a quick-and-dirty chm archive extractor. * ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation; either version 2.1 of the * * License, or (at your option) any later version. * * * ***************************************************************************/#include "chm_lib.h"#include <stdio.h>#include <stdlib.h>#include <gtk/gtk.h>#include <string.h>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include "interface.h"#include "exchm.h"struct extract_context{ const char *base_path; const char *get_hhc_name;};static int dir_exists(const char *path){ struct stat statbuf; if (stat(path, &statbuf) != -1) return 1; else return 0;}static int rmkdir(char *path){ /* * strip off trailing components unless we can stat the directory, or we * have run out of components */ char *i = rindex(path, '/'); if(path[0] == '\0' || dir_exists(path)) return 0; if (i != NULL) { *i = '\0'; rmkdir(path); *i = '/'; mkdir(path, 0777); } if (dir_exists(path)) return 0; else return -1;}/* * callback function for enumerate API */int _extract_callback(struct chmFile *h, struct chmUnitInfo *ui, void *context){ unsigned char buffer[32768]; struct extract_context *ctx = (struct extract_context *)context; char *i; gchar *name_utf8; gchar *hhc_name; if (ui->path[0] != '/') { return CHM_ENUMERATOR_CONTINUE; } name_utf8 = g_convert(g_strdown(ui->path), -1, "GB18030", "UTF-8", NULL, NULL, NULL);// if (snprintf(buffer, sizeof(buffer), "%s%s", ctx->base_path, ui->path) > 1024) if (snprintf(buffer, sizeof(buffer), "%s%s", ctx->base_path, name_utf8) > 1024) return CHM_ENUMERATOR_FAILURE; if (ui->length != 0) { FILE *fout; LONGINT64 len, remain=ui->length; LONGUINT64 offset = 0; hhc_name = g_strdup(g_strrstr ( g_path_get_basename( name_utf8 ), ".")); if (hhc_name) { if (g_strcasecmp( ".hhc", hhc_name ) == 0) { ctx->get_hhc_name = g_strdup_printf("%s%s", ctx->base_path, name_utf8); } } if ((fout = fopen(buffer, "wb")) == NULL) { /* make sure that it isn't just a missing directory before we abort */ unsigned char newbuf[32768]; strcpy(newbuf, buffer); i = rindex(newbuf, '/'); *i = '\0'; rmkdir(newbuf); if ((fout = fopen(buffer, "wb")) == NULL) return CHM_ENUMERATOR_FAILURE; } while (remain != 0) { len = chm_retrieve_object(h, ui, buffer, offset, 32768); if (len > 0) { fwrite(buffer, 1, (size_t)len, fout); offset += len; remain -= len; } else { break; } } fclose(fout); } else { if (rmkdir(buffer) == -1) return CHM_ENUMERATOR_FAILURE; } return CHM_ENUMERATOR_CONTINUE;}int ex_chm_file ( ChmSee *window, const gchar *filename ) { struct chmFile *h; struct extract_context ec; h = chm_open(filename); if (h == NULL) { return 1; } ec.base_path = (const char *) window->tmpdir; ec.get_hhc_name = NULL; if (! chm_enumerate(h, CHM_ENUMERATE_ALL, _extract_callback, (void *)&ec)) { return 1; } chm_close(h); window->hhc_name = ec.get_hhc_name; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -