Esempio n. 1
0
void Options::restore_window_position( const QString &name, QWidget *widget_p )
{
    bool maximized ;
    bool restore_pos;
    long  posx, posy, height, width ;

    restore_pos = get_opt_bool( "RESTORE_WINDOW_POSITION", true );
    if ( !restore_pos )
        return ;

    maximized = get_opt_bool( "WIDGET_POS_" + name + "_MAXIMIZED", false );
    posx = get_opt_long( "WIDGET_POS_" + name + "_X", 0 );
    posy = get_opt_long( "WIDGET_POS_" + name + "_Y", 0 );
    width = get_opt_long( "WIDGET_POS_" + name + "_WIDTH", 100 );
    height = get_opt_long( "WIDGET_POS_" + name + "_HEIGHT", 100 );

    if ( maximized )
        widget_p->showMaximized();
    else
    {
        QPoint pos( posx, posy );
        QSize s( width, height );
        widget_p->showNormal();
        widget_p->move( pos );
        widget_p->resize( s );
    }
}
Esempio n. 2
0
void
html_noscript(struct html_context *html_context, unsigned char *a,
              unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	/* We shouldn't throw <noscript> away until our ECMAScript support is
	 * halfway decent. */
#ifdef CONFIG_ECMASCRIPT
	if (get_opt_bool((const unsigned char *)"ecmascript.enable", NULL)
            && get_opt_bool((const unsigned char *)"ecmascript.ignore_noscript", NULL))
		html_skip(html_context, a);
#endif
}
Esempio n. 3
0
File: fsp.c Progetto: Efreak/elinks
static void
fsp_directory(FSP_SESSION *ses, struct uri *uri)
{
	struct string buf;
	FSP_DIR *dir;
	unsigned char *data = get_uri_string(uri, URI_DATA);
	unsigned char dircolor[8] = "";

	if (!data)
		fsp_error(connection_state(S_OUT_OF_MEM));
	decode_uri(data);
	if (!is_in_state(init_directory_listing(&buf, uri), S_OK))
		fsp_error(connection_state(S_OUT_OF_MEM));

	dir = fsp_opendir(ses, data);
	if (!dir) fsp_error(connection_state_for_errno(errno));

	fprintf(stderr, "text/html");
	fclose(stderr);

	puts(buf.source);

	if (get_opt_bool("document.browse.links.color_dirs", NULL)) {
		color_to_string(get_opt_color("document.colors.dirs", NULL),
				dircolor);
	}

	sort_and_display_entries(dir, dircolor);
	fsp_closedir(dir);
	puts("</pre><hr/></body></html>");
	fsp_close_session(ses);
	exit(0);
}
Esempio n. 4
0
/* Returns a connection state. S_OK if all is well. */
static inline struct connection_state
list_directory(struct connection *conn, unsigned char *dirpath,
	       struct string *page)
{
	int show_hidden_files = get_opt_bool((const unsigned char *)"protocol.file.show_hidden_files",
	                                     NULL);
	struct directory_entry *entries;
	struct connection_state state;

	errno = 0;
	entries = get_directory_entries(dirpath, show_hidden_files);
	if (!entries) {
		if (errno) return connection_state_for_errno(errno);
		return connection_state(S_OUT_OF_MEM);
	}

	state = init_directory_listing(page, conn->uri);
	if (!is_in_state(state, S_OK))
		return connection_state(S_OUT_OF_MEM);

	add_dir_entries(entries, dirpath, page);

	if (!add_to_string(page, (const unsigned char *)"</pre>\n<hr/>\n</body>\n</html>\n")) {
		done_string(page);
		return connection_state(S_OUT_OF_MEM);
	}

	return connection_state(S_OK);
}
Esempio n. 5
0
/* First information such as permissions is gathered for each directory entry.
 * Finally the sorted entries are added to the @data->fragment one by one. */
static inline void
add_dir_entries(struct directory_entry *entries, unsigned char *dirpath,
		struct string *page)
{
	unsigned char dircolor[8];
	int dirpathlen = strlen((const char *)dirpath);
	int i;

	/* Setup @dircolor so it's easy to check if we should color dirs. */
	if (get_opt_bool((const unsigned char *)"document.browse.links.color_dirs", NULL)) {
		color_to_string(get_opt_color((const unsigned char *)"document.colors.dirs", NULL),
				(unsigned char *) &dircolor);
	} else {
		dircolor[0] = 0;
	}

	for (i = 0; entries[i].name; i++) {
		add_dir_entry(&entries[i], page, dirpathlen, dircolor);
		mem_free(entries[i].attrib);
		mem_free(entries[i].name);
	}

	/* We may have allocated space for entries but added none. */
	mem_free_if(entries);
}
Esempio n. 6
0
static void
check_bittorrent_peer_blacklisting(struct bittorrent_peer_connection *peer,
				   struct connection_state state)
{
	enum bittorrent_blacklist_flags flags = BITTORRENT_BLACKLIST_NONE;

	if (bittorrent_id_is_empty(peer->id)
	    || !get_opt_bool("protocol.http.bugs.allow_blacklist", NULL))
		return;

	if (is_system_error(state)) {
		switch (state.syserr) {
		case ECONNREFUSED:
		case ENETUNREACH:
			flags |= BITTORRENT_BLACKLIST_PEER_POOL;
			break;
		}
	} else {
		switch (state.basic) {
		case S_CANT_WRITE:
		case S_CANT_READ:
			if (!peer->local.handshake
			    || !peer->remote.handshake)
				flags |= BITTORRENT_BLACKLIST_PEER_POOL;
			break;

		default:
			break;
		}
	}

	if (flags != BITTORRENT_BLACKLIST_NONE) {
		add_bittorrent_blacklist_flags(peer->id, flags);
	}
}
Esempio n. 7
0
static void
ssl_want_read(struct socket *socket)
{
	if (socket->no_tls)
		ssl_set_no_tls(socket);

	switch (ssl_do_connect(socket)) {
		case SSL_ERROR_NONE:
#ifdef CONFIG_GNUTLS
			if (get_opt_bool((const unsigned char *)"connection.ssl.cert_verify", NULL)
			    && verify_certificates(socket)) {
				socket->ops->retry(socket, connection_state(S_SSL_ERROR));
				return;
			}
#endif

			/* Report successful SSL connection setup. */
			complete_connect_socket(socket, NULL, NULL);
			break;

		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_READ2:
			break;

		default:
			socket->no_tls = !socket->no_tls;
			socket->ops->retry(socket, connection_state(S_SSL_ERROR));
	}
}
Esempio n. 8
0
static void
auth_ok(void *data)
{
	struct dialog *dlg = (struct dialog *)data;
	struct auth_entry *entry = (struct auth_entry *)dlg->udata2;
	struct session *ses = (struct session *)dlg->udata;

	entry->blocked = 0;
	entry->valid = auth_entry_has_userinfo(entry);

#ifdef CONFIG_FORMHIST
	if (get_opt_bool((const unsigned char *)"document.browse.forms.show_formhist", ses)) {
		unsigned char *url = get_uri_string(entry->uri, URI_HTTP_AUTH);

		if (url) {
			struct form form = {};

			form.action = url;
			INIT_LIST_OF(struct submitted_value, submit);
			struct submitted_value *user, *password;

			user = init_submitted_value((unsigned char *)"user", entry->user, FC_TEXT, NULL, 0);
			if (user) {
				add_to_list(submit, user);
			}
			password = init_submitted_value((unsigned char *)"password", entry->password, FC_PASSWORD, NULL, 0);
			if (password) {
				add_to_list(submit, password);
			}

			memorize_form(ses, &submit, &form);
			done_submitted_value_list(&submit);
			mem_free(url);
		}
	}
#endif

	if (entry->valid && have_location(ses)) {
		struct location *loc = cur_loc(ses);
		struct uri *uri = loc->vs.uri;

		/* Make a 'fake' redirect to a URI without user/password so that
		 * the user/password from the URI will not override what the
		 * user just entered in the dialog. */
		if ((uri->userlen && strlcmp(entry->user, -1, uri->user, uri->userlen))
		    || (uri->password && strlcmp(entry->password, -1, uri->password, uri->passwordlen))) {

			uri = get_composed_uri(uri, URI_HTTP_AUTH | URI_DATA | URI_POST);
			if (uri) {
				goto_uri_frame(ses, uri, NULL, CACHE_MODE_INCREMENT);
				done_uri(uri);
				return;
			}
		}
	}

	reload(ses, CACHE_MODE_INCREMENT);
}
Esempio n. 9
0
void Options::restore_window_position( const QString &name, QMainWindow *widget_p )
{
    bool restore_pos = get_opt_bool( "RESTORE_WINDOW_POSITION", true );
    if ( !restore_pos )
        return ;

    restore_window_position( name, ( QWidget* )widget_p );
    widget_p->restoreState( get_opt_array( "WIDGET_POS_DOCKPOS" ) );
}
Esempio n. 10
0
void Options::restore_window_position( MainWindow *wmain_p )
{
    bool restore_pos = get_opt_bool( "RESTORE_WINDOW_POSITION", true );
    if ( !restore_pos )
        return ;
    long nb_widget = get_opt_long( "WIDGET_NB_WIDGET", 0 );
    for ( int i = 0; i < nb_widget; i++ )
    {
        QString name = "WORKSPACE" + QString::number( i );
        QString type = get_opt_str( "TYPE_" + name, QString() );
        if ( type == "SOURCEVIEW" )
        {
            QString source = get_opt_str( "SOURCE_" + name, QString::null ).toLatin1();
            bool from_user_loaded = get_opt_bool( "SOURCE_USER_LOADED_" + name, false );
            QMdiSubWindow *widget_p = wmain_p->openOCamlSource( source , from_user_loaded );
            if ( widget_p )
            {
                restore_window_position( name, widget_p );
            }
        }
    }
}
Esempio n. 11
0
static void
error_reporter(JSContext *ctx, const char *message, JSErrorReport *report)
{
	struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
	struct session *ses = interpreter->vs->doc_view->session;
	struct terminal *term;
	unsigned char *strict, *exception, *warning, *error;
	struct string msg;

	assert(interpreter && interpreter->vs && interpreter->vs->doc_view
	       && ses && ses->tab);
	if_assert_failed goto reported;

	term = ses->tab->term;

#ifdef CONFIG_LEDS
	set_led_value(ses->status.ecmascript_led, 'J');
#endif

	if (!get_opt_bool("ecmascript.error_reporting", ses)
	    || !init_string(&msg))
		goto reported;

	strict	  = JSREPORT_IS_STRICT(report->flags) ? " strict" : "";
	exception = JSREPORT_IS_EXCEPTION(report->flags) ? " exception" : "";
	warning   = JSREPORT_IS_WARNING(report->flags) ? " warning" : "";
	error	  = !report->flags ? " error" : "";

	add_format_to_string(&msg, _("A script embedded in the current "
			"document raised the following%s%s%s%s", term),
			strict, exception, warning, error);

	add_to_string(&msg, ":\n\n");
	add_to_string(&msg, message);

	if (report->linebuf && report->tokenptr) {
		int pos = report->tokenptr - report->linebuf;

		add_format_to_string(&msg, "\n\n%s\n.%*s^%*s.",
			       report->linebuf,
			       pos - 2, " ",
			       strlen(report->linebuf) - pos - 1, " ");
	}

	info_box(term, MSGBOX_FREE_TEXT, N_("JavaScript Error"), ALIGN_CENTER,
		 msg.source);

reported:
	/* Im clu'les. --pasky */
	JS_ClearPendingException(ctx);
}
Esempio n. 12
0
static widget_handler_status_T
display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
{
	struct terminal *term = dlg_data->win->term;
	struct color_pair *color, *shortcut_color;
	struct el_box *pos = &widget_data->box;
	int len, x;
	int sel = is_selected_widget(dlg_data, widget_data);

	if (sel) {
		shortcut_color = get_bfu_color(term, "dialog.button-shortcut-selected");
		color =  get_bfu_color(term, "dialog.button-selected");
	} else {
		shortcut_color = get_bfu_color(term, "dialog.button-shortcut");
		color =  get_bfu_color(term, "dialog.button");
	}
	if (!color || !shortcut_color) return EVENT_PROCESSED;

#ifdef CONFIG_UTF8
	if (term->utf8_cp) {
		int button_left_len = utf8_ptr2cells(BUTTON_LEFT, NULL);
		int button_right_len = utf8_ptr2cells(BUTTON_RIGHT, NULL);

		x = pos->x + button_left_len;
		len = widget_data->box.width -
			(button_left_len + button_right_len);

	} else
#endif /* CONFIG_UTF8 */
	{
		x = pos->x + BUTTON_LEFT_LEN;
		len = widget_data->box.width - BUTTON_LR_LEN;
	}


	draw_dlg_text(dlg_data, pos->x, pos->y, BUTTON_LEFT, BUTTON_LEFT_LEN, 0, color);
	if (len > 0) {
		unsigned char *text = widget_data->widget->text;
		int hk_pos = widget_data->widget->info.button.hotkey_pos;
		int attr;

		attr = get_opt_bool("ui.dialogs.underline_button_shortcuts",
		                    NULL)
		     ? SCREEN_ATTR_UNDERLINE : 0;

#ifdef CONFIG_UTF8
		if (term->utf8_cp) {
			if (hk_pos >= 0) {
				int hk_bytes = utf8charlen(&text[hk_pos+1]);
				int cells_to_hk = utf8_ptr2cells(text,
						&text[hk_pos]);
				int right = widget_data->widget->info.button.truetextlen
					- hk_pos
					- hk_bytes;

				int hk_cells = utf8_char2cells(&text[hk_pos
								      + 1],
								NULL);

				if (hk_pos)
					draw_dlg_text(dlg_data, x, pos->y,
						  text, hk_pos, 0, color);

				draw_dlg_text(dlg_data, x + cells_to_hk, pos->y,
					  &text[hk_pos + 1], hk_bytes,
					  attr, shortcut_color);

				if (right > 1)
					draw_dlg_text(dlg_data, x+cells_to_hk+hk_cells,
						  pos->y,
						  &text[hk_pos + hk_bytes + 1],
						  right - 1, 0, color);

			} else {
				int hk_width = utf8_char2cells(text, NULL);
				int hk_len = utf8charlen(text);
				int len_to_display =
					utf8_cells2bytes(&text[hk_len],
							 len - hk_width,
							 NULL);

				draw_dlg_text(dlg_data, x, pos->y,
					  text, hk_len,
					  attr, shortcut_color);

				draw_dlg_text(dlg_data, x + hk_width, pos->y,
					  &text[hk_len], len_to_display,
					  0, color);
			}
		} else
#endif /* CONFIG_UTF8 */
		if (hk_pos >= 0) {
			int right = widget_data->widget->info.button.truetextlen - hk_pos - 1;

			if (hk_pos) {
				draw_dlg_text(dlg_data, x, pos->y, text, hk_pos, 0, color);
			}
			draw_dlg_text(dlg_data, x + hk_pos, pos->y,
				  &text[hk_pos + 1], 1, attr, shortcut_color);
			if (right > 1) {
				draw_dlg_text(dlg_data, x + hk_pos + 1, pos->y,
					  &text[hk_pos + 2], right - 1, 0, color);
			}

		} else {
			draw_dlg_text(dlg_data, x, pos->y, text, 1, attr, shortcut_color);
			draw_dlg_text(dlg_data, x + 1, pos->y, &text[1], len - 1, 0, color);
		}
	}
#ifdef CONFIG_UTF8
	if (term->utf8_cp) {
		int text_cells = utf8_ptr2cells(widget_data->widget->text, NULL);
		int hk = (widget_data->widget->info.button.hotkey_pos >= 0);

		draw_dlg_text(dlg_data, x + text_cells - hk, pos->y,
			  BUTTON_RIGHT, BUTTON_RIGHT_LEN, 0, color);
	} else
#endif /* CONFIG_UTF8 */
		draw_dlg_text(dlg_data, x + len, pos->y, BUTTON_RIGHT,
			  BUTTON_RIGHT_LEN, 0, color);
	if (sel) {
		set_dlg_cursor(term, dlg_data, x, pos->y, 1);
		set_dlg_window_ptr(dlg_data, dlg_data->win, pos->x, pos->y);
	}
	return EVENT_PROCESSED;
}
Esempio n. 13
0
/* Many execution paths may lead to this code so it needs to take appropriate
 * precausions to stuff like doc_view and doc_view->vs being NULL. */
enum frame_event_status
do_action(struct session *ses, enum main_action action_id, int verbose)
{
	enum frame_event_status status = FRAME_EVENT_OK;
	struct terminal *term = ses->tab->term;
	struct document_view *doc_view = current_frame(ses);
	struct link *link = NULL;

	if (action_id == -1) goto unknown_action;

	if (doc_view && doc_view->vs) {
		if (action_prefix_is_link_number(KEYMAP_MAIN, action_id)
		    && !try_jump_to_link_number(ses, doc_view))
			goto ignore_action;

		link = get_current_link(doc_view);

	} else if (action_requires_view_state(KEYMAP_MAIN, action_id)) {
		goto ignore_action;
	}

	if (action_requires_location(KEYMAP_MAIN, action_id)
	    && !have_location(ses))
		return FRAME_EVENT_OK;

	if (action_requires_link(KEYMAP_MAIN, action_id)
	    && !link)
		goto ignore_action;

	if (action_requires_form(KEYMAP_MAIN, action_id)
	    && (!link || !link_is_form(link)))
		goto ignore_action;

	if (!action_is_anonymous_safe(KEYMAP_MAIN, action_id)
	    && get_cmd_opt_bool("anonymous"))
		goto ignore_action;

	/* Please keep in alphabetical order for now. Later we can sort by most
	 * used or something. */
	switch (action_id) {
		case ACT_MAIN_ABORT_CONNECTION:
			abort_loading(ses, 1);
			print_screen_status(ses);
			break;

		case ACT_MAIN_ADD_BOOKMARK:
#ifdef CONFIG_BOOKMARKS
			launch_bm_add_doc_dialog(term, NULL, ses);
#endif
			break;
		case ACT_MAIN_ADD_BOOKMARK_LINK:
#ifdef CONFIG_BOOKMARKS
			launch_bm_add_link_dialog(term, NULL, ses);
#endif
			break;
		case ACT_MAIN_ADD_BOOKMARK_TABS:
#ifdef CONFIG_BOOKMARKS
			bookmark_terminal_tabs_dialog(term);
#endif
			break;

		case ACT_MAIN_AUTH_MANAGER:
			auth_manager(ses);
			break;

		case ACT_MAIN_BACKSPACE_PREFIX:

			if (!ses->kbdprefix.repeat_count) break;

			set_kbd_repeat_count(ses,
			                     ses->kbdprefix.repeat_count / 10);

			/* Keep send_event from resetting repeat_count. */
			status = FRAME_EVENT_SESSION_DESTROYED;

			break;

		case ACT_MAIN_BOOKMARK_MANAGER:
#ifdef CONFIG_BOOKMARKS
			bookmark_manager(ses);
#endif
			break;

		case ACT_MAIN_CACHE_MANAGER:
			cache_manager(ses);
			break;

		case ACT_MAIN_CACHE_MINIMIZE:
			shrink_memory(1);
			break;

		case ACT_MAIN_COOKIES_LOAD:
#ifdef CONFIG_COOKIES
			if (!get_opt_bool("cookies.save", NULL)) break;
			load_cookies();
#endif
			break;

		case ACT_MAIN_COOKIE_MANAGER:
#ifdef CONFIG_COOKIES
			cookie_manager(ses);
#endif
			break;

		case ACT_MAIN_COPY_CLIPBOARD:
			status = copy_current_link_to_clipboard(ses, doc_view, 0);
			break;

		case ACT_MAIN_DOCUMENT_INFO:
			document_info_dialog(ses);
			break;

		case ACT_MAIN_DOWNLOAD_MANAGER:
			download_manager(ses);
			break;

		case ACT_MAIN_EXMODE:
#ifdef CONFIG_EXMODE
			exmode_start(ses);
#endif
			break;

		case ACT_MAIN_FILE_MENU:
			activate_bfu_technology(ses, 0);
			break;

		case ACT_MAIN_FIND_NEXT:
			status = find_next(ses, doc_view, 1);
			break;

		case ACT_MAIN_FIND_NEXT_BACK:
			status = find_next(ses, doc_view, -1);
			break;

		case ACT_MAIN_FORGET_CREDENTIALS:
			free_auth();
			shrink_memory(1); /* flush caches */
			break;

		case ACT_MAIN_FORMHIST_MANAGER:
#ifdef CONFIG_FORMHIST
			formhist_manager(ses);
#endif
			break;

		case ACT_MAIN_FRAME_EXTERNAL_COMMAND:
			status = pass_uri_to_command(ses, doc_view,
			                             PASS_URI_FRAME);
			break;

		case ACT_MAIN_FRAME_NEXT:
			next_frame(ses, 1);
			draw_formatted(ses, 0);
			break;

		case ACT_MAIN_FRAME_MAXIMIZE:
			status = set_frame(ses, doc_view, 0);
			break;

		case ACT_MAIN_FRAME_PREV:
			next_frame(ses, -1);
			draw_formatted(ses, 0);
			break;

		case ACT_MAIN_GOTO_URL:
			goto_url_action(ses, NULL);
			break;

		case ACT_MAIN_GOTO_URL_CURRENT:
			goto_url_action(ses, get_current_url);
			break;

		case ACT_MAIN_GOTO_URL_CURRENT_LINK:
			goto_url_action(ses, get_current_link_url);
			break;

		case ACT_MAIN_GOTO_URL_HOME:
			goto_url_home(ses);
			break;

		case ACT_MAIN_HEADER_INFO:
			protocol_header_dialog(ses);
			break;

		case ACT_MAIN_HISTORY_MANAGER:
#ifdef CONFIG_GLOBHIST
			history_manager(ses);
#endif
			break;

		case ACT_MAIN_HISTORY_MOVE_BACK:
		{
			int count = int_max(1, eat_kbd_repeat_count(ses));

			go_history_by_n(ses, -count);
			break;
		}
		case ACT_MAIN_HISTORY_MOVE_FORWARD:
		{
			int count = int_max(1, eat_kbd_repeat_count(ses));

			go_history_by_n(ses, count);
			break;
		}
		case ACT_MAIN_JUMP_TO_LINK:
			break;

		case ACT_MAIN_KEYBINDING_MANAGER:
			keybinding_manager(ses);
			break;

		case ACT_MAIN_KILL_BACKGROUNDED_CONNECTIONS:
			abort_background_connections();
			break;

		case ACT_MAIN_LINK_DIALOG:
			open_link_dialog(ses);
			break;

		case ACT_MAIN_LINK_DOWNLOAD:
		case ACT_MAIN_LINK_DOWNLOAD_IMAGE:
		case ACT_MAIN_LINK_DOWNLOAD_RESUME:
			status = download_link(ses, doc_view, action_id);
			break;

		case ACT_MAIN_LINK_EXTERNAL_COMMAND:
			status = pass_uri_to_command(ses, doc_view,
			                             PASS_URI_LINK);
			break;

		case ACT_MAIN_LINK_FOLLOW:
			status = enter(ses, doc_view, 0);
			break;

		case ACT_MAIN_LINK_FOLLOW_RELOAD:
			status = enter(ses, doc_view, 1);
			break;

		case ACT_MAIN_LINK_INFO:
			link_info_dialog(ses);
			break;
			
		case ACT_MAIN_LINK_MENU:
			link_menu(term, NULL, ses);
			break;

		case ACT_MAIN_LINK_FORM_MENU:
			link_form_menu(ses);
			break;

		case ACT_MAIN_LUA_CONSOLE:
#ifdef CONFIG_SCRIPTING_LUA
			trigger_event_name("dialog-lua-console", ses);
#endif
			break;

		case ACT_MAIN_MARK_SET:
#ifdef CONFIG_MARKS
			ses->kbdprefix.mark = KP_MARK_SET;
			status = FRAME_EVENT_REFRESH;
#endif
			break;

		case ACT_MAIN_MARK_GOTO:
#ifdef CONFIG_MARKS
			/* TODO: Show promptly a menu (or even listbox?)
			 * with all the marks. But the next letter must
			 * still choose a mark directly! --pasky */
			ses->kbdprefix.mark = KP_MARK_GOTO;
			status = FRAME_EVENT_REFRESH;
#endif
			break;

		case ACT_MAIN_MENU:
			activate_bfu_technology(ses, -1);
			break;

		case ACT_MAIN_MOVE_CURRENT_TOP:
			status = move_current_top(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_CURSOR_UP:
			status = move_cursor_up(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_CURSOR_DOWN:
			status = move_cursor_down(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_CURSOR_LEFT:
			status = move_cursor_left(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_CURSOR_RIGHT:
			status = move_cursor_right(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_CURSOR_LINE_START:
			status = move_cursor_line_start(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_HALF_PAGE_DOWN:
			status = move_half_page_down(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_HALF_PAGE_UP:
			status = move_half_page_up(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_LINK_DOWN:
			status = move_link_down(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_LINK_DOWN_LINE:
			status = move_link_down_line(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_LINK_LEFT:
			status = move_link_left(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_LINK_LEFT_LINE:
			status = move_link_prev_line(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_LINK_NEXT:
			status = move_link_next(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_LINK_PREV:
			status = move_link_prev(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_LINK_RIGHT:
			status = move_link_right(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_LINK_RIGHT_LINE:
			status = move_link_next_line(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_LINK_UP:
			status = move_link_up(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_LINK_UP_LINE:
			status = move_link_up_line(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_PAGE_DOWN:
			status = move_page_down(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_PAGE_UP:
			status = move_page_up(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_DOCUMENT_START:
			status = move_document_start(ses, doc_view);
			break;

		case ACT_MAIN_MOVE_DOCUMENT_END:
			status = move_document_end(ses, doc_view);
			break;

		case ACT_MAIN_OPEN_LINK_IN_NEW_TAB:
			open_current_link_in_new_tab(ses, 0);
			break;

		case ACT_MAIN_OPEN_LINK_IN_NEW_TAB_IN_BACKGROUND:
			open_current_link_in_new_tab(ses, 1);
			break;

		case ACT_MAIN_OPEN_LINK_IN_NEW_WINDOW:
			open_in_new_window(term, send_open_in_new_window, ses);
			break;

		case ACT_MAIN_OPEN_NEW_TAB:
			open_uri_in_new_tab(ses, NULL, 0, 1);
			break;

		case ACT_MAIN_OPEN_NEW_TAB_IN_BACKGROUND:
			open_uri_in_new_tab(ses, NULL, 1, 1);
			break;

		case ACT_MAIN_OPEN_NEW_WINDOW:
			open_in_new_window(term, send_open_new_window, ses);
			break;

		case ACT_MAIN_OPEN_OS_SHELL:
			exec_shell(term);
			break;

		case ACT_MAIN_OPTIONS_MANAGER:
			options_manager(ses);
			break;

		case ACT_MAIN_QUIT:
			exit_prog(ses, 1);
			break;

		case ACT_MAIN_REALLY_QUIT:
			exit_prog(ses, 0);
			break;

		case ACT_MAIN_REDRAW:
			redraw_terminal_cls(term);
			break;

		case ACT_MAIN_RELOAD:
			reload(ses, CACHE_MODE_INCREMENT);
			break;

		case ACT_MAIN_RERENDER:
			draw_formatted(ses, 2);
			break;

		case ACT_MAIN_RESET_FORM:
			status = reset_form(ses, doc_view, 0);
			break;

		case ACT_MAIN_RESOURCE_INFO:
			resource_info(term);
			break;

		case ACT_MAIN_SAVE_AS:
			status = save_as(ses, doc_view, 0);
			break;

		case ACT_MAIN_SAVE_FORMATTED:
			status = save_formatted_dlg(ses, doc_view, 0);
			break;

		case ACT_MAIN_SAVE_OPTIONS:
			write_config(term);
			break;

		case ACT_MAIN_SAVE_URL_AS:
			save_url_as(ses);
			break;

		case ACT_MAIN_SCROLL_DOWN:
			status = scroll_down(ses, doc_view);
			break;

		case ACT_MAIN_SCROLL_LEFT:
			status = scroll_left(ses, doc_view);
			break;

		case ACT_MAIN_SCROLL_RIGHT:
			status = scroll_right(ses, doc_view);
			break;

		case ACT_MAIN_SCROLL_UP:
			status = scroll_up(ses, doc_view);
			break;

		case ACT_MAIN_SEARCH:
			status = search_dlg(ses, doc_view, 1);
			break;

		case ACT_MAIN_SEARCH_BACK:
			status = search_dlg(ses, doc_view, -1);
			break;

		case ACT_MAIN_SEARCH_TYPEAHEAD:
		case ACT_MAIN_SEARCH_TYPEAHEAD_LINK:
		case ACT_MAIN_SEARCH_TYPEAHEAD_TEXT:
		case ACT_MAIN_SEARCH_TYPEAHEAD_TEXT_BACK:
			status = search_typeahead(ses, doc_view, action_id);
			break;

		case ACT_MAIN_SHOW_TERM_OPTIONS:
			terminal_options(term, NULL, ses);
			break;

		case ACT_MAIN_SUBMIT_FORM:
			status = submit_form(ses, doc_view, 0);
			break;

		case ACT_MAIN_SUBMIT_FORM_RELOAD:
			status = submit_form(ses, doc_view, 1);
			break;

		case ACT_MAIN_TAB_CLOSE:
			close_tab(term, ses);
			status = FRAME_EVENT_SESSION_DESTROYED;
			break;

		case ACT_MAIN_TAB_CLOSE_ALL_BUT_CURRENT:
			close_all_tabs_but_current(ses);
			break;

		case ACT_MAIN_TAB_EXTERNAL_COMMAND:
			status = pass_uri_to_command(ses, doc_view,
			                             PASS_URI_TAB);
			break;

		case ACT_MAIN_TAB_MOVE_LEFT:
			move_current_tab(ses, -1);
			break;

		case ACT_MAIN_TAB_MOVE_RIGHT:
			move_current_tab(ses, 1);
			break;

		case ACT_MAIN_TAB_MENU:
			assert(ses->tab == get_current_tab(term));

			if (ses->status.show_tabs_bar)
				tab_menu(ses, ses->tab->xpos,
					 term->height - 1
					  - ses->status.show_status_bar,
					 1);
			else
				tab_menu(ses, 0, 0, 0);

			break;

		case ACT_MAIN_TAB_NEXT:
			switch_current_tab(ses, 1);
			break;

		case ACT_MAIN_TAB_PREV:
			switch_current_tab(ses, -1);
			break;

		case ACT_MAIN_TERMINAL_RESIZE:
			resize_terminal_dialog(term);
			break;

		case ACT_MAIN_TOGGLE_CSS:
#ifdef CONFIG_CSS
			toggle_document_option(ses, "document.css.enable");
#endif
			break;

		case ACT_MAIN_TOGGLE_DISPLAY_IMAGES:
			toggle_document_option(ses, "document.browse.images.show_as_links");
			break;

		case ACT_MAIN_TOGGLE_DISPLAY_TABLES:
			toggle_document_option(ses, "document.html.display_tables");
			break;

		case ACT_MAIN_TOGGLE_DOCUMENT_COLORS:
			toggle_document_option(ses, "document.colors.use_document_colors");
			break;

		case ACT_MAIN_TOGGLE_HTML_PLAIN:
			toggle_plain_html(ses, ses->doc_view, 0);
			break;

		case ACT_MAIN_TOGGLE_MOUSE:
#ifdef CONFIG_MOUSE
			toggle_mouse();
#endif
			break;

		case ACT_MAIN_TOGGLE_NUMBERED_LINKS:
			toggle_document_option(ses, "document.browse.links.numbering");
			break;

		case ACT_MAIN_TOGGLE_PLAIN_COMPRESS_EMPTY_LINES:
			toggle_document_option(ses, "document.plain.compress_empty_lines");
			break;

		case ACT_MAIN_TOGGLE_WRAP_TEXT:
			toggle_wrap_text(ses, ses->doc_view, 0);
			break;

		case ACT_MAIN_VIEW_IMAGE:
			status = view_image(ses, doc_view, 0);
			break;

		case ACT_MAIN_SCRIPTING_FUNCTION:
		case ACT_MAIN_NONE:
		case MAIN_ACTIONS:
		default:
unknown_action:
			if (verbose) {
				INTERNAL("No action handling defined for '%s'.",
					 get_action_name(KEYMAP_MAIN, action_id));
			}

			status = FRAME_EVENT_IGNORED;
	}

ignore_action:
	/* XXX: At this point the session may have been destroyed */

	if (status != FRAME_EVENT_SESSION_DESTROYED
	    && ses->insert_mode == INSERT_MODE_ON
	    && link != get_current_link(doc_view))
		ses->insert_mode = INSERT_MODE_OFF;

	if (status == FRAME_EVENT_REFRESH && doc_view)
		refresh_view(ses, doc_view, 0);

	return status;
}
Esempio n. 14
0
void
init_document_options(struct session *ses, struct document_options *doo)
{
	/* Ensure that any padding bytes are cleared. */
	memset(doo, 0, sizeof(*doo));

	doo->assume_cp = get_opt_codepage("document.codepage.assume", ses);
	doo->hard_assume = get_opt_bool("document.codepage.force_assumed", ses);

	doo->use_document_colors = get_opt_int("document.colors.use_document_colors", ses);
	doo->margin = get_opt_int("document.browse.margin_width", ses);
	doo->num_links_key = get_opt_int("document.browse.links.number_keys_select_link", ses);
	doo->meta_link_display = get_opt_int("document.html.link_display", ses);
	doo->default_form_input_size = get_opt_int("document.browse.forms.input_size", ses);

	/* Color options. */
	doo->default_style.color.foreground = get_opt_color("document.colors.text", ses);
	doo->default_style.color.background = get_opt_color("document.colors.background", ses);
	doo->default_color.link = get_opt_color("document.colors.link", ses);
	doo->default_color.vlink = get_opt_color("document.colors.vlink", ses);
#ifdef CONFIG_BOOKMARKS
	doo->default_color.bookmark_link = get_opt_color("document.colors.bookmark", ses);
#endif
	doo->default_color.image_link = get_opt_color("document.colors.image", ses);

	doo->active_link.color.foreground = get_opt_color("document.browse.links.active_link.colors.text", ses);
	doo->active_link.color.background = get_opt_color("document.browse.links.active_link.colors.background", ses);

	if (get_opt_bool("document.colors.increase_contrast", ses))
		doo->color_flags |= COLOR_INCREASE_CONTRAST;

	if (get_opt_bool("document.colors.ensure_contrast", ses))
		doo->color_flags |= COLOR_ENSURE_CONTRAST;

	/* Boolean options. */
#ifdef CONFIG_CSS
	doo->css_enable = get_opt_bool("document.css.enable", ses);
	doo->css_ignore_display_none = get_opt_bool("document.css.ignore_display_none", ses);
	doo->css_import = get_opt_bool("document.css.import", ses);
#endif

	doo->plain_display_links = get_opt_bool("document.plain.display_links", ses);
	doo->plain_compress_empty_lines = get_opt_bool("document.plain.compress_empty_lines", ses);
	doo->underline_links = get_opt_bool("document.html.underline_links", ses);
	doo->wrap_nbsp = get_opt_bool("document.html.wrap_nbsp", ses);
	doo->use_tabindex = get_opt_bool("document.browse.links.use_tabindex", ses);
	doo->links_numbering = get_opt_bool("document.browse.links.numbering", ses);

	doo->active_link.enable_color = get_opt_bool("document.browse.links.active_link.enable_color", ses);
	doo->active_link.invert = get_opt_bool("document.browse.links.active_link.invert", ses);
	doo->active_link.underline = get_opt_bool("document.browse.links.active_link.underline", ses);
	doo->active_link.bold = get_opt_bool("document.browse.links.active_link.bold", ses);

	doo->table_order = get_opt_bool("document.browse.table_move_order", ses);
	doo->tables = get_opt_bool("document.html.display_tables", ses);
	doo->frames = get_opt_bool("document.html.display_frames", ses);
	doo->images = get_opt_bool("document.browse.images.show_as_links", ses);
	doo->display_subs = get_opt_bool("document.html.display_subs", ses);
	doo->display_sups = get_opt_bool("document.html.display_sups", ses);

	doo->framename = "";

	doo->image_link.prefix = "";
	doo->image_link.suffix = "";
	doo->image_link.filename_maxlen = get_opt_int("document.browse.images.filename_maxlen", ses);
	doo->image_link.label_maxlen = get_opt_int("document.browse.images.label_maxlen", ses);
	doo->image_link.display_style = get_opt_int("document.browse.images.display_style", ses);
	doo->image_link.tagging = get_opt_int("document.browse.images.image_link_tagging", ses);
	doo->image_link.show_any_as_links = get_opt_bool("document.browse.images.show_any_as_links", ses);
}
Esempio n. 15
0
File: task.c Progetto: ezc/elinks
void
ses_goto(struct session *ses, struct uri *uri, unsigned char *target_frame,
	 struct location *target_location, enum cache_mode cache_mode,
	 enum task_type task_type, int redir)
{
	/* [gettext_accelerator_context(ses_goto)] */
	struct task *task;
	int referrer_incomplete = 0;
	int malicious_uri = 0;
	int confirm_submit = uri->form && get_opt_bool("document.browse.forms"
	                                               ".confirm_submit", ses);
	unsigned char *m1 = NULL, *message = NULL;
	struct memory_list *mlist = NULL;

	if (ses->doc_view
	    && ses->doc_view->document
	    && ses->doc_view->document->refresh) {
		kill_document_refresh(ses->doc_view->document->refresh);
	}

	assertm(!ses->loading_uri, "Buggy URI reference counting");

	/* Reset the redirect counter if this is not a redirect. */
	if (!redir) {
		ses->redirect_cnt = 0;
	}

	/* Figure out whether to confirm submit or not */

	/* Only confirm submit if we are posting form data or a misleading URI
	 * was detected. */
	/* Note uri->post might be empty here but we are still supposely
	 * posting form data so this should be more correct. */

	if (uri->user && uri->userlen
	    && get_opt_bool("document.browse.links.warn_malicious", ses)
	    && check_malicious_uri(uri)) {
		malicious_uri = 1;
		confirm_submit = 1;

	} else if (uri->form) {
		/* First check if the referring URI was incomplete. It
		 * indicates that the posted form data might be incomplete too.
		 * See bug 460. */
		if (ses->referrer) {
			struct cache_entry *cached;

			cached = find_in_cache(ses->referrer);
			referrer_incomplete = (cached && cached->incomplete);
		}

		if (referrer_incomplete) {
			confirm_submit = 1;

		} else if (get_validated_cache_entry(uri, cache_mode)) {
			confirm_submit = 0;
		}
	}

	if (!confirm_submit) {
		ses_load(ses, get_uri_reference(uri), target_frame,
		         target_location, cache_mode, task_type);
		return;
	}

	task = mem_alloc(sizeof(*task));
	if (!task) return;

	task->ses = ses;
	task->uri = get_uri_reference(uri);
	task->cache_mode = cache_mode;
	task->session_task.type = task_type;
	task->session_task.target.frame = null_or_stracpy(target_frame);
	task->session_task.target.location = target_location;

	if (malicious_uri) {
		unsigned char *host = memacpy(uri->host, uri->hostlen);
		unsigned char *user = memacpy(uri->user, uri->userlen);
		unsigned char *uristring = get_uri_string(uri, URI_PUBLIC);

		message = msg_text(ses->tab->term,
			N_("The URL you are about to follow might be maliciously "
			"crafted in order to confuse you. By following the URL "
			"you will be connecting to host \"%s\" as user \"%s\".\n\n"
			"Do you want to go to URL %s?"), host, user, uristring);

		mem_free_if(host);
		mem_free_if(user);
		mem_free_if(uristring);

	} else if (redir) {
		m1 = N_("Do you want to follow the redirect and post form data "
			"to URL %s?");

	} else if (referrer_incomplete) {
		m1 = N_("The form data you are about to post might be incomplete.\n"
			"Do you want to post to URL %s?");

	} else if (task_type == TASK_FORWARD) {
		m1 = N_("Do you want to post form data to URL %s?");

	} else {
		m1 = N_("Do you want to repost form data to URL %s?");
	}

	if (!message && m1) {
		unsigned char *uristring = get_uri_string(uri, URI_PUBLIC);

		message = msg_text(ses->tab->term, m1, uristring);
		mem_free_if(uristring);
	}

	add_to_ml(&mlist, task, (void *) NULL);
	if (task->session_task.target.frame)
		add_to_ml(&mlist, task->session_task.target.frame, (void *) NULL);
	msg_box(ses->tab->term, mlist, MSGBOX_FREE_TEXT,
		N_("Warning"), ALIGN_CENTER,
		message,
		task, 2,
		MSG_BOX_BUTTON(N_("~Yes"), post_yes, B_ENTER),
		MSG_BOX_BUTTON(N_("~No"), post_no, B_ESC));
}
Esempio n. 16
0
/* Return -1 on error, 0 or success. */
int
ssl_connect(struct socket *socket)
{
	int ret;
	unsigned char *server_name;
	struct connection *conn = (struct connection *)socket->conn;

	/* TODO: Recode server_name to UTF-8.  */
	server_name = get_uri_string(conn->proxied_uri, URI_HOST);
	if (!server_name) {
		socket->ops->done(socket, connection_state(S_OUT_OF_MEM));
		return -1;
	}

	/* RFC 3546 says literal IPv4 and IPv6 addresses are not allowed.  */
	if (is_ip_address(server_name, strlen((const char *)server_name)))
		mem_free_set(&server_name, NULL);

	if (init_ssl_connection(socket, server_name) == S_SSL_ERROR) {
		mem_free_if(server_name);
		socket->ops->done(socket, connection_state(S_SSL_ERROR));
		return -1;
	}

	mem_free_if(server_name);

	if (socket->no_tls)
		ssl_set_no_tls(socket);

#ifdef USE_OPENSSL
	SSL_set_fd((SSL *)socket->ssl, socket->fd);

	if (get_opt_bool((const unsigned char *)"connection.ssl.cert_verify", NULL))
		SSL_set_verify((SSL *)socket->ssl, SSL_VERIFY_PEER
					  | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
			       verify_callback);

	if (get_opt_bool((const unsigned char *)"connection.ssl.client_cert.enable", NULL)) {
		unsigned char *client_cert;

#ifdef CONFIG_NSS_COMPAT_OSSL
		client_cert = get_opt_str(
				(const unsigned char *)"connection.ssl.client_cert.nickname", NULL);
#else
		client_cert = get_opt_str(
				(const unsigned char *)"connection.ssl.client_cert.file", NULL);
#endif
		if (!*client_cert) {
			client_cert = (unsigned char *)getenv("X509_CLIENT_CERT");
			if (client_cert && !*client_cert)
				client_cert = NULL;
		}

		if (client_cert) {
#ifdef CONFIG_NSS_COMPAT_OSSL
			SSL_CTX_use_certificate_chain_file(
					(SSL *) socket->ssl,
					(const char *)client_cert);
#else
			SSL_CTX *ctx = ((SSL *) socket->ssl)->ctx;

			SSL_CTX_use_certificate_chain_file(ctx, (const char *)client_cert);
			SSL_CTX_use_PrivateKey_file(ctx, (const char *)client_cert,
						    SSL_FILETYPE_PEM);
#endif
		}
	}

#elif defined(CONFIG_GNUTLS)
	/* GnuTLS uses function pointers for network I/O.  The default
	 * functions take a file descriptor, but it must be passed in
	 * as a pointer.  GnuTLS uses the GNUTLS_INT_TO_POINTER and
	 * GNUTLS_POINTER_TO_INT macros for these conversions, but
	 * those are unfortunately not in any public header.  So
	 * ELinks must just cast the pointer the best it can and hope
	 * that the conversions match.  */
	gnutls_transport_set_ptr(*((ssl_t *) socket->ssl),
				 (gnutls_transport_ptr_t) (longptr_T) socket->fd);

	/* TODO: Some certificates fuss. --pasky */
#endif

	ret = ssl_do_connect(socket);

	switch (ret) {
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_READ2:
			socket->ops->set_state(socket, connection_state(S_SSL_NEG));
			set_handlers(socket->fd, (select_handler_T) ssl_want_read,
				     NULL, (select_handler_T) dns_exception, socket);
			return -1;

		case SSL_ERROR_NONE:
#ifdef CONFIG_GNUTLS
			if (!get_opt_bool((const unsigned char *)"connection.ssl.cert_verify", NULL))
				break;

			if (!verify_certificates(socket))
#endif
				break;

		default:
			if (ret != SSL_ERROR_NONE) {
				/* DBG("sslerr %s", gnutls_strerror(ret)); */
				socket->no_tls = !socket->no_tls;
			}

			connect_socket(socket, connection_state(S_SSL_ERROR));
			return -1;
	}

	return 0;
}
Esempio n. 17
0
void
html_script(struct html_context *html_context, unsigned char *a,
            unsigned char *html, unsigned char *eof, unsigned char **end)
{
#ifdef CONFIG_ECMASCRIPT
	/* TODO: <noscript> processing. Well, same considerations apply as to
	 * CSS property display: none processing. */
	/* TODO: Charsets for external scripts. */
	unsigned char *type, *language, *src;
	int in_comment = 0;
#endif

	html_skip(html_context, a);

#ifdef CONFIG_ECMASCRIPT
	/* We try to process nested <script> if we didn't process the parent
	 * one. That's why's all the fuzz. */
	/* Ref:
	 * http://www.ietf.org/internet-drafts/draft-hoehrmann-script-types-03.txt
	 */
	type = get_attr_val(a, (unsigned char *)"type", html_context->doc_cp);
	if (type) {
		unsigned char *pos = type;

		if (!c_strncasecmp((const char *)type, "text/", 5)) {
			pos += 5;

		} else if (!c_strncasecmp((const char *)type, "application/", 12)) {
			pos += 12;

		} else {
			mem_free(type);
not_processed:
			/* Permit nested scripts and retreat. */
			html_top->invisible++;
			return;
		}

		if (!c_strncasecmp((const char *)pos, "javascript", 10)) {
			int len = strlen((const char *)pos);

			if (len > 10 && !isdigit(pos[10])) {
				mem_free(type);
				goto not_processed;
			}

		} else if (c_strcasecmp((const char *)pos, "ecmascript")
		    && c_strcasecmp((const char *)pos, "jscript")
		    && c_strcasecmp((const char *)pos, "livescript")
		    && c_strcasecmp((const char *)pos, "x-javascript")
		    && c_strcasecmp((const char *)pos, "x-ecmascript")) {
			mem_free(type);
			goto not_processed;
		}

		mem_free(type);
	}

	/* Check that the script content is ecmascript. The value of the
	 * language attribute can be JavaScript with optional version digits
	 * postfixed (like: ``JavaScript1.1'').
	 * That attribute is deprecated in favor of type by HTML 4.01 */
	language = get_attr_val(a, (unsigned char *)"language", html_context->doc_cp);
	if (language) {
		int languagelen = strlen((const char *)language);

		if (languagelen < 10
		    || (languagelen > 10 && !isdigit(language[10]))
		    || c_strncasecmp((const char *)language, "javascript", 10)) {
			mem_free(language);
			html_top->invisible++;
			return;
			//goto not_processed;
		}

		mem_free(language);
	}

	if (html_context->part->document
	    && (src = get_attr_val(a, (unsigned char *)"src", html_context->doc_cp))) {
		/* External reference. */

		unsigned char *import_url;
		struct uri *uri;

		if (!get_opt_bool((const unsigned char *)"ecmascript.enable", NULL)) {
			mem_free(src);
			html_top->invisible++;
			return;
			//goto not_processed;
		}

		/* HTML <head> urls should already be fine but we can.t detect them. */
		import_url = join_urls(html_context->base_href, src);
		mem_free(src);
		if (!import_url) goto imported;

		uri = get_uri(import_url, URI_BASE);
		if (!uri) goto imported;

		/* Request the imported script as part of the document ... */
		html_context->special_f(html_context, SP_SCRIPT, uri);
		done_uri(uri);

		/* Create URL reference onload snippet. */
		insert_in_string(&import_url, 0, (const unsigned char *)"^", 1);
		add_to_string_list(&html_context->part->document->onload_snippets,
		                   import_url, -1);

imported:
		/* Retreat. Do not permit nested scripts, tho'. */
		if (import_url) mem_free(import_url);
		return;
	}

	/* Positive, grab the rest and interpret it. */

	/* First position to the real script start. */
	while (html < eof && *html <= ' ') html++;
	if (eof - html > 4 && !strncmp((const char *)html, "<!--", 4)) {
		in_comment = 1;
		/* We either skip to the end of line or to -->. */
		for (; *html != '\n' && *html != '\r' && eof - html >= 3; html++) {
			if (!strncmp((const char *)html, "-->", 3)) {
				/* This means the document is probably broken.
				 * We will now try to process the rest of
				 * <script> contents, which is however likely
				 * to be empty. Should we try to process the
				 * comment too? Currently it seems safer but
				 * less tolerant to broken pages, if there are
				 * any like this. */
				html += 3;
				in_comment = 0;
				break;
			}
		}
	}

	*end = html;

	/* Now look ahead for the script end. The <script> contents is raw
	 * CDATA, so we just look for the ending tag and need not care for
	 * any quote marks counting etc - YET, we are more tolerant and permit
	 * </script> stuff inside of the script if the whole <script> element
	 * contents is wrapped in a comment. See i.e. Mozilla bug 26857 for fun
	 * reading regarding this. */
	for (; *end < eof; (*end)++) {
		unsigned char *name;
		int namelen;

		if (in_comment) {
			/* TODO: If we ever get some standards-quirk mode
			 * distinction, this should be disabled in the
			 * standards mode (and we should just look for CDATA
			 * end, which is "</"). --pasky */
			if (eof - *end >= 3 && !strncmp((const char *)*end, "-->", 3)) {
				/* Next iteration will jump passed the ending '>' */
				(*end) += 2;
				in_comment = 0;
			}
			continue;
			/* XXX: Scan for another comment? That's admittelly
			 * already stretching things a little bit to an
			 * extreme ;-). */
		}

		if (**end != '<')
			continue;
		/* We want to land before the closing element, that's why we
		 * don't pass @end also as the appropriate parse_element()
		 * argument. */
		if (parse_element(*end, eof, &name, &namelen, NULL, NULL))
			continue;
		if (c_strlcasecmp(name, namelen, (const unsigned char *)"/script", 7))
			continue;
		/* We have won! */
		break;
	}
	if (*end >= eof) {
		/* Either the document is not completely loaded yet or it's
		 * broken. At any rate, run away screaming. */
		*end = eof; /* Just for sanity. */
		return;
	}

	if (html_context->part->document && *html != '^') {
		add_to_string_list(&html_context->part->document->onload_snippets,
		                   html, *end - html);
	}
#endif
}
Esempio n. 18
0
void
connect_socket(struct socket *csocket, struct connection_state state)
{
	int sock = -1;
	struct connect_info *connect_info = csocket->connect_info;
	int i;
	int trno = connect_info->triedno;
	int only_local = get_cmd_opt_bool("localhost");
	int saved_errno = 0;
	int at_least_one_remote_ip = 0;
#ifdef CONFIG_IPV6
	int try_ipv6 = get_opt_bool("connection.try_ipv6", NULL);
#endif
	int try_ipv4 = get_opt_bool("connection.try_ipv4", NULL);
	/* We tried something but we failed in such a way that we would rather
	 * prefer the connection to retain the information about previous
	 * failures.  That is, we i.e. decided we are forbidden to even think
	 * about such a connection attempt.
	 * XXX: Unify with @local_only handling? --pasky */
	int silent_fail = 0;

	csocket->ops->set_state(csocket, state);

	/* Clear handlers, the connection to the previous RR really timed
	 * out and doesn't interest us anymore. */
	if (csocket->fd >= 0)
		close_socket(csocket);

	for (i = connect_info->triedno + 1; i < connect_info->addrno; i++) {
#ifdef CONFIG_IPV6
		struct sockaddr_in6 addr = *((struct sockaddr_in6 *) &connect_info->addr[i]);
		int family = addr.sin6_family;
#else
		struct sockaddr_in addr = *((struct sockaddr_in *) &connect_info->addr[i]);
		int family = addr.sin_family;
#endif
		int pf;
		int force_family = connect_info->ip_family;

		connect_info->triedno++;

		if (only_local) {
			int local = 0;
#ifdef CONFIG_IPV6
			if (family == AF_INET6)
				local = check_if_local_address6((struct sockaddr_in6 *) &addr);
			else
#endif
				local = check_if_local_address4((struct sockaddr_in *) &addr);

			/* This forbids connections to anything but local, if option is set. */
			if (!local) {
				at_least_one_remote_ip = 1;
				continue;
			}
		}

#ifdef CONFIG_IPV6
		if (family == AF_INET6) {
			if (!try_ipv6 || (force_family && force_family != 6)) {
				silent_fail = 1;
				continue;
			}
			pf = PF_INET6;

		} else
#endif
		if (family == AF_INET) {
			if (!try_ipv4 || (force_family && force_family != 4)) {
				silent_fail = 1;
				continue;
			}
			pf = PF_INET;

		} else {
			continue;
		}
		silent_fail = 0;

		sock = socket(pf, SOCK_STREAM, IPPROTO_TCP);
		if (sock == -1) {
			if (errno && !saved_errno) saved_errno = errno;
			continue;
		}

		if (set_nonblocking_fd(sock) < 0) {
			if (errno && !saved_errno) saved_errno = errno;
			close(sock);
			continue;
		}
		csocket->fd = sock;

#ifdef CONFIG_IPV6
		addr.sin6_port = htons(connect_info->port);
#else
		addr.sin_port = htons(connect_info->port);
#endif

		/* We can set csocket->protocol_family here even if the connection
		 * will fail, as we will use it only when it will be successfully
		 * established. At least I hope that noone else will want to do
		 * something else ;-). --pasky */
		/* And in fact we must set it early, because of EINPROGRESS.  */

#ifdef CONFIG_IPV6
		if (family == AF_INET6) {
			csocket->protocol_family = EL_PF_INET6;
			if (connect(sock, (struct sockaddr *) &addr,
					sizeof(struct sockaddr_in6)) == 0) {
				/* Success */
				complete_connect_socket(csocket, NULL, NULL);
				return;
			}
		} else
#endif
		{
			csocket->protocol_family = EL_PF_INET;
			if (connect(sock, (struct sockaddr *) &addr,
					sizeof(struct sockaddr_in)) == 0) {
				/* Success */
				complete_connect_socket(csocket, NULL, NULL);
				return;
			}
		}

		if (errno == EALREADY
#ifdef EWOULDBLOCK
		    || errno == EWOULDBLOCK
#endif
		    || errno == EINPROGRESS) {
			/* It will take some more time... */
			set_handlers(sock, NULL, (select_handler_T) connected,
				     (select_handler_T) dns_exception, csocket);
			csocket->ops->set_state(csocket, connection_state(S_CONN));
			return;
		}

		if (errno && !saved_errno) saved_errno = errno;

		close(sock);
	}

	assert(i >= connect_info->addrno);

	/* Tried everything, but it didn't help :(. */

	if (only_local && !saved_errno && at_least_one_remote_ip) {
		/* Yes we might hit a local address and fail in the process, but
		 * what matters is the last one because we do not know the
		 * previous one's errno, and the added complexity wouldn't
		 * really be worth it. */
		csocket->ops->done(csocket, connection_state(S_LOCAL_ONLY));
		return;
	}

	/* Retry reporting the errno state only if we already tried something
	 * new. Else use the S_DNS _progress_ state to make sure that no
	 * download callbacks will report any errors. */
	if (trno != connect_info->triedno && !silent_fail)
		state = connection_state_for_errno(errno);
	else if (trno == -1 && silent_fail)
		/* All failed. */
		state = connection_state(S_NO_FORCED_DNS);

	csocket->ops->retry(csocket, state);
}