session.c

来自「this is the file used to browse web」· C语言 代码 · 共 1,618 行 · 第 1/4 页

C
1,618
字号
#include "links.h"struct list_head downloads = {&downloads, &downloads};int are_there_downloads(){	int d = 0;	struct download *down;	foreach(down, downloads) if (!down->prog) d = 1;	return d;}struct list_head sessions = {&sessions, &sessions};int session_id = 1;struct strerror_val {	struct strerror_val *next;	struct strerror_val *prev;	unsigned char msg[1];};struct list_head strerror_buf = { &strerror_buf, &strerror_buf };void free_strerror_buf(){	free_list(strerror_buf);}unsigned char *get_err_msg(int state){	unsigned char *e;	struct strerror_val *s;	if (state <= S_OK || state >= S_WAIT) {		int i;		for (i = 0; msg_dsc[i].msg; i++)			if (msg_dsc[i].n == state) return msg_dsc[i].msg;		unk:		return TEXT(T_UNKNOWN_ERROR);	}	if (!(e = strerror(-state)) || !*e) goto unk;	foreach(s, strerror_buf) if (!strcmp(s->msg, e)) return s->msg;	s = mem_alloc(sizeof(struct strerror_val) + strlen(e) + 1);	strcpy(s->msg, e);	add_to_list(strerror_buf, s);	return s->msg;}void add_xnum_to_str(unsigned char **s, int *l, off_t n){	unsigned char suff = 0;	int d = -1;	if (n >= 1000000000) suff = 'G', d = (n / 100000000) % 10, n /= 1000000000;	else if (n >= 1000000) suff = 'M', d = (n / 100000) % 10, n /= 1000000;	else if (n >= 1000) suff = 'k', d = (n / 100) % 10, n /= 1000;	add_num_to_str(s, l, n);	if (n < 10 && d != -1) add_chr_to_str(s, l, '.'), add_num_to_str(s, l, d);	add_chr_to_str(s, l, ' ');	if (suff) add_chr_to_str(s, l, suff);	add_chr_to_str(s, l, 'B');}void add_time_to_str(unsigned char **s, int *l, ttime t){	unsigned char q[64];	if (t < 0) t = 0;	t &= 0xffffffff;	if (t >= 86400) sprintf(q, "%dd ", (int)(t / 86400)), add_to_str(s, l, q);	if (t >= 3600) t %= 86400, sprintf(q, "%d:%02d", (int)(t / 3600), (int)(t / 60 % 60)), add_to_str(s, l, q);	else sprintf(q, "%d", (int)(t / 60)), add_to_str(s, l, q);	sprintf(q, ":%02d", (int)(t % 60)), add_to_str(s, l, q);}unsigned char *get_stat_msg(struct status *stat, struct terminal *term){	if (stat->state == S_TRANS && stat->prg->elapsed / 100) {		unsigned char *m = init_str();		int l = 0;		add_to_str(&m, &l, _(TEXT(T_RECEIVED), term));		add_to_str(&m, &l, " ");		add_xnum_to_str(&m, &l, stat->prg->pos);		if (stat->prg->size >= 0)			add_to_str(&m, &l, " "), add_to_str(&m, &l, _(TEXT(T_OF), term)), add_to_str(&m, &l, " "), add_xnum_to_str(&m, &l, stat->prg->size);		add_to_str(&m, &l, ", ");		if (stat->prg->elapsed >= CURRENT_SPD_AFTER * SPD_DISP_TIME)			add_to_str(&m, &l, _(TEXT(T_AVG), term)), add_to_str(&m, &l, " ");		add_xnum_to_str(&m, &l, (longlong)stat->prg->loaded * 10 / (stat->prg->elapsed / 100));		add_to_str(&m, &l, "/s");		if (stat->prg->elapsed >= CURRENT_SPD_AFTER * SPD_DISP_TIME) 			add_to_str(&m, &l, ", "), add_to_str(&m, &l, _(TEXT(T_CUR), term)), add_to_str(&m, &l, " "),			add_xnum_to_str(&m, &l, stat->prg->cur_loaded / (CURRENT_SPD_SEC * SPD_DISP_TIME / 1000)),			add_to_str(&m, &l, "/s");		return m;	}	return stracpy(_(get_err_msg(stat->state), term));}void print_screen_status(struct session *ses){	struct terminal *term = ses->term;	struct status *stat = NULL;	unsigned char *m;	fill_area(term, 0, 0, term->x, 1, COLOR_TITLE_BG);	fill_area(term, 0, term->y - 1, term->x, 1, COLOR_STATUS_BG);	if (ses->wtd) stat = &ses->loading;	else if (!list_empty(ses->history)) stat = &cur_loc(ses)->stat;	if (stat && stat->state == S_OK) {		struct file_to_load *ftl;		foreach(ftl, ses->more_files) {			if (ftl->req_sent && ftl->stat.state >= 0) {				stat = &ftl->stat;				break;			}		}	}	if (stat) {		if (stat->state == S_OK) if ((m = print_current_link(ses))) goto p;		if ((m = get_stat_msg(stat, term))) {			p:			print_text(term, 0, term->y - 1, strlen(m), m, COLOR_STATUS);			mem_free(m);		}		if ((m = print_current_title(ses))) {			int p = term->x - 1 - strlen(m);			if (p < 0) p = 0;			print_text(term, p, 0, strlen(m), m, COLOR_TITLE);			/*set_window_title(0,m);*/			/*set_terminal_title(term, m);*/			mem_free(m);		}		m = stracpy("Links");		if (ses->screen && ses->screen->f_data && ses->screen->f_data->title && ses->screen->f_data->title[0]) add_to_strn(&m, " - "), add_to_strn(&m, ses->screen->f_data->title);		set_terminal_title(term, m);		/* mem_free(m); -- set_terminal_title frees it */	}	redraw_from_window(ses->win);}void print_error_dialog(struct session *ses, struct status *stat, unsigned char *title){	unsigned char *t = get_err_msg(stat->state);	if (!t) return;	msg_box(ses->term, NULL, title, AL_CENTER, t, ses, 1, TEXT(T_CANCEL), NULL, B_ENTER | B_ESC/*, _("Retry"), NULL, 0 !!! FIXME: retry */);}void free_wtd(struct session *ses){	if (!ses->wtd) {		internal("no WTD");		return;	}	if (ses->goto_position) mem_free(ses->goto_position), ses->goto_position = NULL;	mem_free(ses->loading_url);	ses->loading_url = NULL;	ses->wtd = WTD_NO;}void abort_files_load(struct session *ses){	struct file_to_load *ftl;	int q;	do {		q = 0;		foreach(ftl, ses->more_files) {			if (ftl->stat.state >= 0 && ftl->req_sent) {				q = 1;				change_connection(&ftl->stat, NULL, PRI_CANCEL);			}		}	} while (q);}void free_files(struct session *ses){	struct file_to_load *ftl;	abort_files_load(ses);	foreach(ftl, ses->more_files) {		if (ftl->ce) ftl->ce->refcount--;		mem_free(ftl->url);	}	free_list(ses->more_files);}void destroy_location(struct location *loc){	struct frame *frame;	del_from_list(loc);	foreach(frame, loc->frames) {		destroy_vs(&frame->vs);		mem_free(frame->name);	}	free_list(loc->frames);	destroy_vs(&loc->vs);	mem_free(loc);}void ses_forward(struct session *ses){	struct location *l;	size_t len;	free_files(ses);	if (!list_empty(ses->history)) {		l = cur_loc(ses);	}	if (ses->search_word) mem_free(ses->search_word), ses->search_word = NULL;	x:	len = strlen(ses->loading_url);	if (!list_empty(ses->history) && len < strlen(cur_loc(ses)->vs.url))		len = strlen(cur_loc(ses)->vs.url);	l = mem_alloc(sizeof(struct location) + len + 1);	memset(l, 0, sizeof(struct location));	memcpy(&l->stat, &ses->loading, sizeof(struct status));	if (ses->wtd_target && *ses->wtd_target) {		struct frame *frm;		if (list_empty(ses->history)) {			internal("no history");			return;		}		copy_location(l, cur_loc(ses));		add_to_list(ses->history, l);		frm = ses_change_frame_url(ses, ses->wtd_target, ses->loading_url);		if (!frm) {			destroy_location(l);			ses->wtd_target = NULL;			goto x;		}		destroy_vs(&frm->vs);		init_vs(&frm->vs, ses->loading_url);		if (ses->goto_position) {			if (frm->vs.goto_position) mem_free(frm->vs.goto_position);			frm->vs.goto_position = ses->goto_position;			ses->goto_position = NULL;		}		/*request_additional_loading_file(ses, ses->loading_url, &ses->loading, PRI_FRAME);*/	} else {		init_list(l->frames);		init_vs(&l->vs, ses->loading_url);		add_to_list(ses->history, l);		if (ses->goto_position) {			l->vs.goto_position = ses->goto_position;			ses->goto_position = NULL;		}	}}void ses_imgmap(struct session *ses){	struct cache_entry *ce;	struct fragment *fr;	struct memory_list *ml;	struct menu_item *menu;	struct f_data_c *fd;	if (find_in_cache(ses->loading_url, &ce) || !ce) {		internal("can't find cache entry");		return;	}	defrag_entry(ce);	fr = ce->frag.next;	if ((void *)fr == &ce->frag) return;	if (!(fd = current_frame(ses)) || !fd->f_data) return;	d_opt = &fd->f_data->opt;	if (get_image_map(ce->head, fr->data, fr->data + fr->length, ses->goto_position, &menu, &ml, ses->imgmap_href_base, ses->imgmap_target_base, ses->term->spec->charset, ses->ds.assume_cp, ses->ds.hard_assume))		return;	add_empty_window(ses->term, (void (*)(void *))freeml, ml);	do_menu(ses->term, menu, ses);}void map_selected(struct terminal *term, struct link_def *ld, struct session *ses){	goto_url_f(ses, ld->link, ld->target);}void ses_back(struct session *ses){	struct location *loc;	free_files(ses);	loc = ses->history.next;	if (ses->search_word) mem_free(ses->search_word), ses->search_word = NULL;	if ((void *)loc == &ses->history) return;	destroy_location(loc);	loc = ses->history.next;	if ((void *)loc == &ses->history) return;	if (!strcmp(loc->vs.url, ses->loading_url)) return;	destroy_location(loc);	ses_forward(ses);}void end_load(struct status *, struct session *);void doc_end_load(struct status *, struct session *);void file_end_load(struct status *, struct file_to_load *);void abort_loading(struct session *);void abort_preloading(struct session *);struct session *get_download_ses(struct download *down){	struct session *ses;	foreach(ses, sessions) if (ses == down->ses) return ses;	if (!list_empty(sessions)) return sessions.next;	return NULL;}void abort_download(struct download *down){	if (down->win) delete_window(down->win);	if (down->ask) delete_window(down->ask);	if (down->stat.state >= 0) change_connection(&down->stat, NULL, PRI_CANCEL);	mem_free(down->url);	if (down->handle != -1) prealloc_truncate(down->handle, down->last_pos), close(down->handle);	if (down->prog) {		unlink(down->file);		mem_free(down->prog);	}	mem_free(down->file);	del_from_list(down);	mem_free(down);}void kill_downloads_to_file(unsigned char *file){	struct download *down;	foreach(down, downloads) if (!strcmp(down->file, file)) down = down->prev, abort_download(down->next);}void undisplay_download(struct download *down){	if (down->win) delete_window(down->win);}int dlg_abort_download(struct dialog_data *dlg, struct dialog_item_data *di){	register_bottom_half((void (*)(void *))abort_download, dlg->dlg->udata);	return 0;}int dlg_undisplay_download(struct dialog_data *dlg, struct dialog_item_data *di){	register_bottom_half((void (*)(void *))undisplay_download, dlg->dlg->udata);	return 0;}void download_abort_function(struct dialog_data *dlg){	struct download *down = dlg->dlg->udata;	down->win = NULL;}void download_window_function(struct dialog_data *dlg){	struct download *down = dlg->dlg->udata;	struct terminal *term = dlg->win->term;	int max = 0, min = 0;	int w, x, y;	int t = 0;	unsigned char *m, *u;	struct status *stat = &down->stat;	redraw_below_window(dlg->win);	down->win = dlg->win;	if (stat->state == S_TRANS && stat->prg->elapsed / 100) {		int l = 0;		m = init_str();		t = 1;		add_to_str(&m, &l, _(TEXT(T_RECEIVED), term));		add_to_str(&m, &l, " ");		add_xnum_to_str(&m, &l, stat->prg->pos);		if (stat->prg->size >= 0)			add_to_str(&m, &l, " "), add_to_str(&m, &l, _(TEXT(T_OF),term)), add_to_str(&m, &l, " "), add_xnum_to_str(&m, &l, stat->prg->size), add_to_str(&m, &l, " ");		add_to_str(&m, &l, "\n");		if (stat->prg->elapsed >= CURRENT_SPD_AFTER * SPD_DISP_TIME)			add_to_str(&m, &l, _(TEXT(T_AVERAGE_SPEED), term));		else add_to_str(&m, &l, _(TEXT(T_SPEED), term));		add_to_str(&m, &l, " ");		add_xnum_to_str(&m, &l, (longlong)stat->prg->loaded * 10 / (stat->prg->elapsed / 100));		add_to_str(&m, &l, "/s");		if (stat->prg->elapsed >= CURRENT_SPD_AFTER * SPD_DISP_TIME) 			add_to_str(&m, &l, ", "), add_to_str(&m, &l, _(TEXT(T_CURRENT_SPEED), term)), add_to_str(&m, &l, " "),			add_xnum_to_str(&m, &l, stat->prg->cur_loaded / (CURRENT_SPD_SEC * SPD_DISP_TIME / 1000)),			add_to_str(&m, &l, "/s");		add_to_str(&m, &l, "\n");		add_to_str(&m, &l, _(TEXT(T_ELAPSED_TIME), term));		add_to_str(&m, &l, " ");		add_time_to_str(&m, &l, stat->prg->elapsed / 1000);		if (stat->prg->size >= 0 && stat->prg->loaded > 0) {			add_to_str(&m, &l, ", ");			add_to_str(&m, &l, _(TEXT(T_ESTIMATED_TIME), term));			add_to_str(&m, &l, " ");			/*add_time_to_str(&m, &l, stat->prg->elapsed / 1000 * stat->prg->size / stat->prg->loaded * 1000 - stat->prg->elapsed);*/			add_time_to_str(&m, &l, (stat->prg->size - stat->prg->pos) / ((longlong)stat->prg->loaded * 10 / (stat->prg->elapsed / 100)));		}	} else m = stracpy(_(get_err_msg(stat->state), term));	u = stracpy(down->url);	if (strchr(u, POST_CHAR)) *strchr(u, POST_CHAR) = 0;	max_text_width(term, u, &max);	min_text_width(term, u, &min);	max_text_width(term, m, &max);	min_text_width(term, m, &min);	max_buttons_width(term, dlg->items, dlg->n, &max);	min_buttons_width(term, dlg->items, dlg->n, &min);	w = dlg->win->term->x * 9 / 10 - 2 * DIALOG_LB;	if (w < min) w = min;	if (w > dlg->win->term->x - 2 * DIALOG_LB) w = dlg->win->term->x - 2 * DIALOG_LB;	if (t && stat->prg->size >= 0) {		if (w < DOWN_DLG_MIN) w = DOWN_DLG_MIN;	} else {		if (w > max) w = max;	}

⌨️ 快捷键说明

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