📄 session.c
字号:
} else if (remote & SES_REMOTE_NEW_TAB) { /* FIXME: This is not perfect. Doing multiple -remote * with no URLs will make the goto dialogs * inaccessible. Maybe we should not support this kind * of thing or make the window focus detecting code * more intelligent. --jonas */ open_uri_in_new_tab(ses, uri, 0, 1); if (remote & SES_REMOTE_PROMPT_URL) { dialog_goto_url_open(ses); } } else if (remote & SES_REMOTE_NEW_WINDOW) { /* FIXME: It is quite rude because we just take the first * possibility and should maybe make it possible to specify * new-screen etc via -remote "openURL(..., new-*)" --jonas */ if (!can_open_in_new(ses->tab->term)) return; open_uri_in_new_window(ses, uri, ses->tab->term->environment); } else if (remote & SES_REMOTE_ADD_BOOKMARK) {#ifdef CONFIG_BOOKMARKS if (!uri) return; add_bookmark(NULL, 1, struri(uri), struri(uri));#endif } else if (remote & SES_REMOTE_PROMPT_URL) { dialog_goto_url_open(ses); }}struct string *encode_session_info(struct string *info, struct list_head *url_list){ struct string_list_item *url; if (!init_string(info)) return NULL; foreach (url, *url_list) { struct string *str = &url->string; add_bytes_to_string(info, str->source, str->length + 1); } return info;}/* Older elinks versions (up to and including 0.9.1) sends no magic variable and if * this is detected we fallback to the old session info format. For this format * the magic member of terminal_info hold the length of the URI string. The * old format is handled by the default label in the switch. * * The new session info format supports extraction of multiple URIS from the * terminal_info data member. The magic variable controls how to interpret * the fields: * * INTERLINK_NORMAL_MAGIC means use the terminal_info session_info * variable as an id for a saved session. * * INTERLINK_REMOTE_MAGIC means use the terminal_info session_info * variable as the remote session flags. */intdecode_session_info(struct terminal *term, struct terminal_info *info){ int len = info->length; struct session *base_session = NULL; enum remote_session_flags remote = 0; unsigned char *str; switch (info->magic) { case INTERLINK_NORMAL_MAGIC: /* Lookup if there are any saved sessions that should be * resumed using the session_info as an id. The id is derived * from the value of -base-session command line option in the * connecting instance. * * At the moment it is only used when opening instances in new * window to figure out how to initialize it when the new * instance connects to the master. * * We don't need to handle it for the old format since new * instances connecting this way will always be of the same * origin as the master. */ if (init_saved_session(term, info->session_info)) return 1; break; case INTERLINK_REMOTE_MAGIC: /* This could mean some fatal bug but I am unsure if we can * actually assert it since people could pour all kinds of crap * down the socket. */ if (!info->session_info) { INTERNAL("Remote magic with no remote flags"); return 0; } remote = info->session_info; /* If processing session info from a -remote instance we want * to hook up with the master so we can handle request for * stuff in current tab. */ base_session = get_master_session(); if (!base_session) return 0; break; default: /* The old format calculates the session_info and magic members * as part of the data that should be decoded so we have to * substract it to get the size of the actual URI data. */ len -= sizeof(info->session_info) + sizeof(info->magic); /* Extract URI containing @magic bytes */ if (info->magic <= 0 || info->magic > len) len = 0; else len = info->magic; } if (len <= 0) { if (!remote) return !!init_session(base_session, term, NULL, 0); /* Even though there are no URIs we still have to * handle remote stuff. */ init_remote_session(base_session, &remote, NULL); return 0; } str = info->data; /* Extract multiple (possible) NUL terminated URIs */ while (len > 0) { unsigned char *end = memchr(str, 0, len); int urilength = end ? end - str : len; struct uri *uri = NULL; unsigned char *uristring = memacpy(str, urilength); if (uristring) { uri = get_hooked_uri(uristring, base_session, term->cwd); mem_free(uristring); } len -= urilength + 1; str += urilength + 1; if (remote) { if (!uri) continue; init_remote_session(base_session, &remote, uri); } else { int backgrounded = !list_empty(term->windows); int bad_url = !uri; struct session *ses; if (!uri) uri = get_uri("about:blank", 0); ses = init_session(base_session, term, uri, backgrounded); if (!ses) { /* End loop if initialization fails */ len = 0; } else if (bad_url) { print_error_dialog(ses, S_BAD_URL, NULL, PRI_MAIN); } } if (uri) done_uri(uri); } /* If we only initialized remote sessions or didn't manage to add any * new tabs return zero so the terminal will be destroyed ASAP. */ return remote ? 0 : !list_empty(term->windows);}voidabort_loading(struct session *ses, int interrupt){ if (have_location(ses)) { struct location *loc = cur_loc(ses); if (is_in_progress_state(loc->download.state)) change_connection(&loc->download, NULL, PRI_CANCEL, interrupt); abort_files_load(ses, interrupt); } abort_preloading(ses, interrupt);}static voiddestroy_session(struct session *ses){ struct document_view *doc_view; assert(ses); if_assert_failed return; destroy_downloads(ses); abort_loading(ses, 0); free_files(ses); if (ses->doc_view) { detach_formatted(ses->doc_view); mem_free(ses->doc_view); } foreach (doc_view, ses->scrn_frames) detach_formatted(doc_view); free_list(ses->scrn_frames); destroy_history(&ses->history); set_session_referrer(ses, NULL); if (ses->loading_uri) done_uri(ses->loading_uri); if (ses->display_timer != -1) kill_timer(ses->display_timer); while (!list_empty(ses->type_queries)) done_type_query(ses->type_queries.next); if (ses->download_uri) done_uri(ses->download_uri); mem_free_if(ses->search_word); mem_free_if(ses->last_search_word); mem_free_if(ses->status.last_title); del_from_list(ses);}voidreload(struct session *ses, enum cache_mode cache_mode){ abort_loading(ses, 0); if (cache_mode == CACHE_MODE_INCREMENT) { cache_mode = CACHE_MODE_NEVER; if (ses->reloadlevel < CACHE_MODE_NEVER) cache_mode = ++ses->reloadlevel; } else { ses->reloadlevel = cache_mode; } if (have_location(ses)) { struct location *loc = cur_loc(ses); struct file_to_load *ftl; struct document_view *doc_view = current_frame(ses);#ifdef CONFIG_ECMASCRIPT loc->vs.ecmascript_fragile = 1;#endif /* FIXME: When reloading use loading_callback and set up a * session task so that the reloading will work even when the * reloaded document contains redirects. This is needed atleast * when reloading HTTP auth document after the user has entered * credentials. */ loc->download.data = ses; loc->download.callback = (void *) doc_loading_callback; load_uri(loc->vs.uri, ses->referrer, &loc->download, PRI_MAIN, cache_mode, -1); foreach (ftl, ses->more_files) { if (file_to_load_is_active(ftl)) continue; ftl->download.data = ftl; ftl->download.callback = (void *) file_loading_callback; load_additional_file(ftl, doc_view, cache_mode); } }}struct frame *ses_find_frame(struct session *ses, unsigned char *name){ struct location *loc = cur_loc(ses); struct frame *frame; assertm(have_location(ses), "ses_request_frame: no location yet"); if_assert_failed return NULL; foreachback (frame, loc->frames) if (!strcasecmp(frame->name, name)) return frame; return NULL;}voidset_session_referrer(struct session *ses, struct uri *referrer){ if (ses->referrer) done_uri(ses->referrer); ses->referrer = referrer ? get_uri_reference(referrer) : NULL;}static voidtabwin_func(struct window *tab, struct term_event *ev){ struct session *ses = tab->data; switch (ev->ev) { case EVENT_ABORT: if (ses) destroy_session(ses); if (!list_empty(sessions)) update_status(); break; case EVENT_INIT: case EVENT_RESIZE: tab->resize = 1; /* fall-through */ case EVENT_REDRAW: if (!ses || ses->tab != get_current_tab(ses->tab->term)) break; draw_formatted(ses, tab->resize); if (tab->resize) { load_frames(ses, ses->doc_view); process_file_requests(ses); tab->resize = 0; } print_screen_status(ses); break; case EVENT_KBD: case EVENT_MOUSE: if (!ses) break; /* This check is related to bug 296 */ assert(ses->tab == get_current_tab(ses->tab->term)); send_event(ses, ev); break; }}/* * Gets the url being viewed by this session. Writes it into str. * A maximum of str_size bytes (including null) will be written. */unsigned char *get_current_url(struct session *ses, unsigned char *str, size_t str_size){ struct uri *uri; int length; assert(str && str_size > 0); uri = have_location(ses) ? cur_loc(ses)->vs.uri : ses->loading_uri; /* Not looking or loading anything */ if (!uri) return NULL; /* Ensure that the url size is not greater than str_size. * We can't just happily strncpy(str, here, str_size) * because we have to stop at POST_CHAR, not only at NULL. */ length = int_min(get_real_uri_length(uri), str_size - 1); return safe_strncpy(str, struri(uri), length + 1);}/* * Gets the title of the page being viewed by this session. Writes it into str. * A maximum of str_size bytes (including null) will be written. */unsigned char *get_current_title(struct session *ses, unsigned char *str, size_t str_size){ struct document_view *doc_view = current_frame(ses); assert(str && str_size > 0); /* Ensure that the title is defined */ /* TODO: Try globhist --jonas */ if (doc_view && doc_view->document->title) return safe_strncpy(str, doc_view->document->title, str_size); return NULL;}/* * Gets the url of the link currently selected. Writes it into str. * A maximum of str_size bytes (including null) will be written. */unsigned char *get_current_link_url(struct session *ses, unsigned char *str, size_t str_size){ struct link *link = get_current_session_link(ses); assert(str && str_size > 0); if (!link) return NULL; return safe_strncpy(str, link->where ? link->where : link->where_img, str_size);}/* get_current_link_name: returns the name of the current link * (the text between <A> and </A>), str is a preallocated string, * str_size includes the null char. */unsigned char *get_current_link_name(struct session *ses, unsigned char *str, size_t str_size){ struct link *link = get_current_session_link(ses); unsigned char *where, *name = NULL; assert(str && str_size > 0); if (!link) return NULL; where = link->where ? link->where : link->where_img;#ifdef CONFIG_GLOBHIST { struct global_history_item *item; item = get_global_history_item(where); if (item) name = item->title; }#endif if (!name) name = get_link_name(link); if (!name) name = where; return safe_strncpy(str, name, str_size);}struct link *get_current_link_in_view(struct document_view *doc_view){ struct link *link = get_current_link(doc_view); return link && !link_is_form(link) ? link : NULL;}struct link *get_current_session_link(struct session *ses){ return get_current_link_in_view(current_frame(ses));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -