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

📄 globhist.c

📁 一个很有名的浏览器
💻 C
字号:
/* Global history *//* $Id: globhist.c,v 1.99.2.2 2005/05/01 22:03:23 jonas Exp $ */#ifndef _GNU_SOURCE#define _GNU_SOURCE /* XXX: we _WANT_ strcasestr() ! */#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "elinks.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef HAVE_TIME_H#include <time.h>#endif#include "bfu/dialog.h"#include "config/options.h"#include "globhist/dialogs.h"#include "globhist/globhist.h"#include "intl/gettext/libintl.h"#include "lowlevel/home.h"#include "lowlevel/select.h"#include "modules/module.h"#include "util/conv.h"#include "util/file.h"#include "util/hash.h"#include "util/memory.h"#include "util/secsave.h"#include "util/string.h"#include "util/lists.h"#include "util/object.h"#include "util/ttime.h"#define GLOBAL_HISTORY_FILENAME		"globhist"INIT_INPUT_HISTORY(global_history);/* GUI stuff. Declared here because done_global_history() frees it. */unsigned char *gh_last_searched_title = NULL;unsigned char *gh_last_searched_url = NULL;enum global_history_options {	GLOBHIST_TREE,	GLOBHIST_ENABLE,	GLOBHIST_MAX_ITEMS,	GLOBHIST_DISPLAY_TYPE,	GLOBHIST_OPTIONS,};static struct option_info global_history_options[] = {	INIT_OPT_TREE("document.history", N_("Global history"),		"global", 0,		N_("Global history options.")),	INIT_OPT_BOOL("document.history.global", N_("Enable"),		"enable", 0, 1,		N_("Enable global history (\"history of all pages visited\").")),	INIT_OPT_INT("document.history.global", N_("Maximum number of entries"),		"max_items", 0, 1, INT_MAX, 1024,		N_("Maximum number of entries in the global history.")),	INIT_OPT_INT("document.history.global", N_("Display style"),		"display_type", 0, 0, 1, 0,		N_("What to display in global history dialog:\n"		"0 is URLs\n"		"1 is page titles")),	/* Compatibility alias: added by jonas at 2004-07-16, 0.9.CVS. */	INIT_OPT_ALIAS("document.history.global", "write_interval", "infofiles.save_interval"),	NULL_OPTION_INFO,};#define get_opt_globhist(which)		global_history_options[(which)].option.value#define get_globhist_enable()		get_opt_globhist(GLOBHIST_ENABLE).number#define get_globhist_max_items()	get_opt_globhist(GLOBHIST_MAX_ITEMS).number#define get_globhist_display_type()	get_opt_globhist(GLOBHIST_DISPLAY_TYPE).numberstatic struct hash *globhist_cache = NULL;static int globhist_cache_entries = 0;static voidremove_item_from_global_history(struct global_history_item *history_item){	del_from_history_list(&global_history, history_item);	if (globhist_cache) {		struct hash_item *item;		item = get_hash_item(globhist_cache, history_item->url, strlen(history_item->url));		if (item) {			del_hash_item(globhist_cache, item);			globhist_cache_entries--;		}	}}static voiddone_global_history_item(struct global_history_item *history_item){	done_listbox_item(&globhist_browser, history_item->box_item);	mem_free(history_item->title);	mem_free(history_item->url);	mem_free(history_item);}voiddelete_global_history_item(struct global_history_item *history_item){	remove_item_from_global_history(history_item);	done_global_history_item(history_item);}/* Search global history for item matching url. */struct global_history_item *get_global_history_item(unsigned char *url){	struct hash_item *item;	if (!url || !globhist_cache) return NULL;	/* Search for cached entry. */	item = get_hash_item(globhist_cache, url, strlen(url));	return item ? (struct global_history_item *) item->value : NULL;}#if 0/* Search global history for certain item. There must be full match with the * parameter or the parameter must be NULL/zero. */struct global_history_item *multiget_global_history_item(unsigned char *url, unsigned char *title, ttime time){	struct global_history_item *history_item;	/* Code duplication vs performance, since this function is called most	 * of time for url matching only... Execution time is divided by 2. */	if (url && !title && !time) {		return get_global_history_item(url);	} else {		foreach (history_item, global_history.items) {			if ((!url || !strcmp(history_item->url, url)) &&			    (!title || !strcmp(history_item->title, title)) &&			    (!time || history_item->last_visit == time)) {				return history_item;			}		}	}	return NULL;}#endifstatic struct global_history_item *init_global_history_item(unsigned char *url, unsigned char *title, ttime vtime){	struct global_history_item *history_item;	history_item = mem_calloc(1, sizeof(*history_item));	if (!history_item)		return NULL;	history_item->last_visit = vtime;	history_item->title = stracpy(empty_string_or_(title));	if (!history_item->title) {		mem_free(history_item);		return NULL;	}	sanitize_title(history_item->title);	history_item->url = stracpy(url);	if (!history_item->url || !sanitize_url(history_item->url)) {		mem_free_if(history_item->url);		mem_free(history_item->title);		mem_free(history_item);		return NULL;	}	history_item->box_item = add_listbox_leaf(&globhist_browser, NULL,						  history_item);	object_nolock(history_item, "globhist");	return history_item;}static intcap_global_history(int max_globhist_items){	while (global_history.size >= max_globhist_items) {		struct global_history_item *history_item;		history_item = global_history.entries.prev;		if ((void *) history_item == &global_history.entries) {			INTERNAL("global history is empty");			global_history.size = 0;			return 0;		}		delete_global_history_item(history_item);	}	return 1;}static voidadd_item_to_global_history(struct global_history_item *history_item,			   int max_globhist_items){	add_to_history_list(&global_history, history_item);	/* Hash creation if needed. */	if (!globhist_cache)		globhist_cache = init_hash(8, &strhash);	if (globhist_cache && globhist_cache_entries < max_globhist_items) {		int urllen = strlen(history_item->url);		/* Create a new entry. */		if (add_hash_item(globhist_cache, history_item->url, urllen, history_item)) {			globhist_cache_entries++;		}	}}/* Add a new entry in history list, take care of duplicate, respect history * size limit, and update any open history dialogs. */voidadd_global_history_item(unsigned char *url, unsigned char *title, ttime vtime){	struct global_history_item *history_item;	int max_globhist_items;	if (!url || !get_globhist_enable()) return;	max_globhist_items = get_globhist_max_items();	history_item = get_global_history_item(url);	if (history_item) delete_global_history_item(history_item);	if (!cap_global_history(max_globhist_items)) return;	history_item = init_global_history_item(url, title, vtime);	if (!history_item) return;	add_item_to_global_history(history_item, max_globhist_items);}intglobhist_simple_search(unsigned char *search_url, unsigned char *search_title){	struct global_history_item *history_item;	if (!search_title || !search_url)		return 0;	/* Memorize last searched title */	mem_free_set(&gh_last_searched_title, stracpy(search_title));	if (!gh_last_searched_title) return 0;	/* Memorize last searched url */	mem_free_set(&gh_last_searched_url, stracpy(search_url));	if (!gh_last_searched_url) {		mem_free(gh_last_searched_title);		return 0;	}	if (!*search_title && !*search_url) {		/* No search terms, make all entries visible. */		foreach (history_item, global_history.entries) {			history_item->box_item->visible = 1;		}		return 1;	}	foreach (history_item, global_history.entries) {		/* Make matching entries visible, hide others. */		if ((*search_title		     && strcasestr(history_item->title, search_title))		    || (*search_url			&& strcasestr(history_item->url, search_url))) {			history_item->box_item->visible = 1;		} else {			history_item->box_item->visible = 0;		}	}	return 1;}static voidread_global_history(void){	unsigned char in_buffer[MAX_STR_LEN * 3];	unsigned char *file_name = GLOBAL_HISTORY_FILENAME;	unsigned char *title;	FILE *f;	if (!get_globhist_enable()	    || get_cmd_opt_bool("anonymous"))		return;	if (elinks_home) {		file_name = straconcat(elinks_home, file_name, NULL);		if (!file_name) return;	}	f = fopen(file_name, "rb");	if (elinks_home) mem_free(file_name);	if (!f) return;	title = in_buffer;	global_history.nosave = 1;	while (fgets(in_buffer, sizeof(in_buffer), f)) {		unsigned char *url, *last_visit, *eol;		url = strchr(title, '\t');		if (!url) continue;		*url++ = '\0'; /* Now url points to the character after \t. */		last_visit = strchr(url, '\t');		if (!last_visit) continue;		*last_visit++ = '\0';		eol = strchr(last_visit, '\n');		if (!eol) continue;		*eol = '\0'; /* Drop ending '\n'. */		add_global_history_item(url, title, str_to_ttime(last_visit));	}	global_history.nosave = 0;	fclose(f);}static voidwrite_global_history(void){	struct global_history_item *history_item;	unsigned char *file_name;	struct secure_save_info *ssi;	if (!global_history.dirty || !elinks_home	    || !get_globhist_enable()	    || get_cmd_opt_bool("anonymous"))		return;	file_name = straconcat(elinks_home, GLOBAL_HISTORY_FILENAME, NULL);	if (!file_name) return;	ssi = secure_open(file_name, 0177); /* rw for user only */	mem_free(file_name);	if (!ssi) return;	foreachback (history_item, global_history.entries) {		if (secure_fprintf(ssi, "%s\t%s\t%ld\n",				   history_item->title,				   history_item->url,				   history_item->last_visit) < 0) break;	}	if (!secure_close(ssi)) global_history.dirty = 0;}static voidfree_global_history(void){	if (globhist_cache) {		free_hash(globhist_cache);		globhist_cache = NULL;		globhist_cache_entries = 0;	}	while (!list_empty(global_history.entries))		delete_global_history_item(global_history.entries.next);}static enum evhook_statusglobal_history_write_hook(va_list ap, void *data){	write_global_history();	return EVENT_HOOK_STATUS_NEXT;}struct event_hook_info global_history_hooks[] = {	{ "periodic-saving", global_history_write_hook, NULL },	NULL_EVENT_HOOK_INFO,};static voidinit_global_history(struct module *module){	read_global_history();}static voiddone_global_history(struct module *module){	write_global_history();	free_global_history();	mem_free_if(gh_last_searched_title);	mem_free_if(gh_last_searched_url);}struct module global_history_module = struct_module(	/* name: */		N_("Global History"),	/* options: */		global_history_options,	/* events: */		global_history_hooks,	/* submodules: */	NULL,	/* data: */		NULL,	/* init: */		init_global_history,	/* done: */		done_global_history);

⌨️ 快捷键说明

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