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 + -
显示快捷键?