mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Merge with http://elinks.cz/elinks.git
This commit is contained in:
commit
0066214b47
@ -7,10 +7,12 @@ AC_DEFUN([AM_ICONV],
|
||||
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
|
||||
dnl those with the standalone portable GNU libiconv installed).
|
||||
|
||||
EL_SAVE_FLAGS
|
||||
|
||||
AC_ARG_WITH([libiconv],
|
||||
[ --with-libiconv=DIR search for libiconv in DIR/include and DIR/lib], [
|
||||
for dir in `echo "$withval" | tr : ' '`; do
|
||||
if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
|
||||
if test -d $dir/include; then CFLAGS="$CFLAGS -I$dir/include"; fi
|
||||
if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi
|
||||
done
|
||||
])
|
||||
@ -64,5 +66,7 @@ size_t iconv();
|
||||
LIBICONV=
|
||||
if test "$am_cv_lib_iconv" = yes; then
|
||||
LIBICONV="-liconv"
|
||||
else
|
||||
EL_RESTORE_FLAGS
|
||||
fi
|
||||
])
|
||||
|
18
configure.in
18
configure.in
@ -99,23 +99,9 @@ AC_SUBST(CONFIG_POD2HTML)
|
||||
AC_SUBST(CONFIG_XMLTO)
|
||||
AC_SUBST(CONFIG_JW)
|
||||
|
||||
EL_CONFIG_DEPENDS(CONFIG_DOC, [CONFIG_ASCIIDOC CONFIG_XMLTO CONFIG_JW CONFIG_POD2HTML], [Documentation])
|
||||
|
||||
if test "$CONFIG_ASCIIDOC" = yes &&
|
||||
test "$CONFIG_XMLTO" = yes &&
|
||||
test "$CONFIG_JW" = yes; then
|
||||
EL_CONFIG_DEPENDS(CONFIG_DOC, [CONFIG_ASCIIDOC CONFIG_XMLTO CONFIG_JW CONFIG_POD2HTML], [Documentation Tools])
|
||||
EL_CONFIG_DEPENDS(CONFIG_MANUAL, [MANUAL_ASCIIDOC MANUAL_XMLTO MANUAL_JW], [Manual Formats])
|
||||
fi
|
||||
|
||||
if test "$CONFIG_ASCIIDOC" = yes &&
|
||||
test "$CONFIG_XMLTO" = yes; then
|
||||
EL_CONFIG_DEPENDS(CONFIG_MANUAL, [MAN_ASCIIDOC MAN_XMLTO], [Man Page Formats])
|
||||
fi
|
||||
|
||||
AC_SUBST(CONFIG_ASCIIDOC)
|
||||
AC_SUBST(CONFIG_POD2HTML)
|
||||
AC_SUBST(CONFIG_XMLTO)
|
||||
AC_SUBST(CONFIG_JW)
|
||||
EL_CONFIG_DEPENDS(CONFIG_MANPAGE, [MAN_ASCIIDOC MAN_XMLTO], [Man Page Formats])
|
||||
|
||||
dnl gcc specific options (to be continued at the bottom of configure)
|
||||
if test "x$ac_cv_prog_gcc" = "xyes"; then
|
||||
|
@ -36,6 +36,9 @@ def pre_format_html_hook(url, html):
|
||||
if re.search("cygwin\.com", url):
|
||||
html2 = re.sub("<body bgcolor=\"#000000\" color=\"#000000\"", "<body bgcolor=\"#ffffff\" color=\"#000000\"", html)
|
||||
return html2
|
||||
if re.search("https://www.mbank.com.pl/ib_navibar_3.asp", url):
|
||||
html2 = re.sub("<td valign=\"top\"><img", "<tr><td valign=\"top\"><img", html)
|
||||
return html2
|
||||
return None
|
||||
|
||||
def proxy_for_hook(url):
|
||||
|
@ -724,7 +724,16 @@ static struct option_info config_options_info[] = {
|
||||
|
||||
INIT_OPT_TREE("document", N_("URI passing"),
|
||||
"uri_passing", OPT_SORT | OPT_AUTOCREATE,
|
||||
N_("Rules for passing URIs to external commands.")),
|
||||
N_("Rules for passing URIs to external commands. When one rule\n"
|
||||
"is defined the link and tab menu will have a menu item that\n"
|
||||
"makes it possible to pass the the link, frame or tab URI to\n"
|
||||
"an external command. If several rules are defined the link and\n"
|
||||
"tab menu will have a submenu of items for each rule. Note, this\n"
|
||||
"is mostly useful for launching graphical viewers, since there\n"
|
||||
"is not support for releasing the terminal while the command runs.\n"
|
||||
"The action and submenus are also available by binding keys to\n"
|
||||
"the frame-external-command, the link-external-command, and\n"
|
||||
"the tab-external-command actions.")),
|
||||
|
||||
INIT_OPT_STRING("document.uri_passing", NULL,
|
||||
"_template_", 0, "",
|
||||
|
@ -859,7 +859,17 @@ form_put(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||
return;
|
||||
|
||||
if (p == s_action) {
|
||||
if (form->action) {
|
||||
struct uri *uri = get_uri(form->action, URI_HTTP_REFERRER_HOST);
|
||||
|
||||
if (uri) {
|
||||
mem_free_set(&form->action, join_urls(uri, string));
|
||||
mem_free(string);
|
||||
done_uri(uri);
|
||||
}
|
||||
} else {
|
||||
mem_free_set(&form->action, string);
|
||||
}
|
||||
} else if (p == s_encoding) {
|
||||
if (!strcasecmp(string, "application/x-www-form-urlencoded")) {
|
||||
form->method = form->method == FORM_METHOD_GET ? FORM_METHOD_GET
|
||||
|
@ -735,6 +735,15 @@ form_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
switch (JSVAL_TO_INT(id)) {
|
||||
case JSP_FORM_ACTION:
|
||||
if (form->action) {
|
||||
struct uri *uri = get_uri(form->action, URI_HTTP_REFERRER_HOST);
|
||||
|
||||
if (uri) {
|
||||
mem_free_set(&form->action, join_urls(uri, jsval_to_string(ctx, vp)));
|
||||
done_uri(uri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mem_free_set(&form->action, stracpy(jsval_to_string(ctx, vp)));
|
||||
break;
|
||||
|
||||
|
@ -724,6 +724,9 @@ abort_connection(struct connection *conn, enum connection_state state)
|
||||
assertm(is_in_result_state(state),
|
||||
"connection didn't end in result state (%d)", state);
|
||||
|
||||
if (state == S_OK && conn->cached)
|
||||
normalize_cache_entry(conn->cached, conn->from);
|
||||
|
||||
set_connection_state(conn, state);
|
||||
|
||||
if (conn->running) interrupt_connection(conn);
|
||||
@ -1021,7 +1024,7 @@ void
|
||||
move_download(struct download *old, struct download *new,
|
||||
enum connection_priority newpri)
|
||||
{
|
||||
struct connection *conn = old->conn;
|
||||
struct connection *conn;
|
||||
|
||||
assert(old);
|
||||
|
||||
@ -1029,7 +1032,9 @@ move_download(struct download *old, struct download *new,
|
||||
* example the file protocol loads it's object immediately. This is
|
||||
* catched by the result state check below. */
|
||||
|
||||
new->conn = old->conn;
|
||||
conn = old->conn;
|
||||
|
||||
new->conn = conn;
|
||||
new->cached = old->cached;
|
||||
new->prev_error = old->prev_error;
|
||||
new->progress = old->progress;
|
||||
@ -1037,8 +1042,13 @@ move_download(struct download *old, struct download *new,
|
||||
new->pri = newpri;
|
||||
|
||||
if (is_in_result_state(old->state)) {
|
||||
if (new->callback)
|
||||
/* Ensure that new->conn is always "valid", that is NULL if the
|
||||
* connection has been detached and non-NULL otherwise. */
|
||||
if (new->callback) {
|
||||
new->conn = NULL;
|
||||
new->progress = NULL;
|
||||
new->callback(new, new->data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -114,8 +114,6 @@ about_protocol_handler(struct connection *conn)
|
||||
}
|
||||
#endif
|
||||
|
||||
normalize_cache_entry(cached, len);
|
||||
|
||||
/* Set content to known type */
|
||||
mem_free_set(&cached->content_type, stracpy("text/html"));
|
||||
}
|
||||
|
@ -157,7 +157,6 @@ data_protocol_handler(struct connection *conn)
|
||||
int datalen = strlen(data);
|
||||
|
||||
add_fragment(cached, conn->from, data, datalen);
|
||||
normalize_cache_entry(cached, datalen);
|
||||
}
|
||||
|
||||
mem_free(data);
|
||||
|
@ -279,6 +279,7 @@ file_protocol_handler(struct connection *connection)
|
||||
|
||||
} else {
|
||||
add_fragment(cached, 0, page.source, page.length);
|
||||
connection->from += page.length;
|
||||
|
||||
if (!cached->content_type) {
|
||||
unsigned char *ctype = null_or_stracpy(type);
|
||||
@ -287,15 +288,10 @@ file_protocol_handler(struct connection *connection)
|
||||
* allocation. */
|
||||
if (type && !ctype)
|
||||
state = S_OUT_OF_MEM;
|
||||
else
|
||||
normalize_cache_entry(cached, page.length);
|
||||
|
||||
/* Setup file read or directory listing for
|
||||
* viewing. */
|
||||
mem_free_set(&cached->content_type, ctype);
|
||||
|
||||
} else {
|
||||
normalize_cache_entry(cached, page.length);
|
||||
}
|
||||
|
||||
done_string(&page);
|
||||
|
@ -27,15 +27,6 @@ struct module finger_protocol_module = struct_module(
|
||||
/* done: */ NULL
|
||||
);
|
||||
|
||||
static void
|
||||
finger_end_request(struct connection *conn, enum connection_state state)
|
||||
{
|
||||
if (state == S_OK && conn->cached)
|
||||
normalize_cache_entry(conn->cached, conn->from);
|
||||
|
||||
abort_connection(conn, state);
|
||||
}
|
||||
|
||||
static void
|
||||
finger_get_response(struct socket *socket, struct read_buffer *rb)
|
||||
{
|
||||
@ -50,7 +41,7 @@ finger_get_response(struct socket *socket, struct read_buffer *rb)
|
||||
conn->cached = cached;
|
||||
|
||||
if (socket->state == SOCKET_CLOSED) {
|
||||
finger_end_request(conn, S_OK);
|
||||
abort_connection(conn, S_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -232,8 +232,6 @@ fsp_got_data(struct socket *socket, struct read_buffer *rb)
|
||||
}
|
||||
|
||||
if (!len) {
|
||||
if (conn->from)
|
||||
normalize_cache_entry(conn->cached, conn->from);
|
||||
abort_connection(conn, S_OK);
|
||||
return;
|
||||
}
|
||||
|
@ -1347,11 +1347,10 @@ out_of_mem:
|
||||
static void
|
||||
ftp_end_request(struct connection *conn, enum connection_state state)
|
||||
{
|
||||
set_connection_state(conn, state);
|
||||
|
||||
if (conn->state == S_OK && conn->cached) {
|
||||
if (state == S_OK && conn->cached) {
|
||||
normalize_cache_entry(conn->cached, conn->from);
|
||||
}
|
||||
|
||||
set_connection_state(conn, state);
|
||||
add_keepalive_connection(conn, FTP_KEEPALIVE_TIMEOUT, NULL);
|
||||
}
|
||||
|
@ -329,30 +329,6 @@ init_gopher_connection_info(struct connection *conn)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
end_gopher_connection(struct connection *conn, enum connection_state state)
|
||||
{
|
||||
if (state == S_OK && conn->cached) {
|
||||
#if 0
|
||||
/* Seeing dots at all files .. trying to remove the end-marker
|
||||
* ".\r\n" */
|
||||
struct gopher_connection_info *gopher = conn->info;
|
||||
|
||||
if (gopher
|
||||
&& gopher->entity
|
||||
&& gopher->entity->type != GOPHER_DIRECTORY
|
||||
&& gopher->entity->type != GOPHER_INDEX
|
||||
&& gopher->entity->type != GOPHER_CSO) {
|
||||
conn->from -= 3;
|
||||
}
|
||||
#endif
|
||||
normalize_cache_entry(conn->cached, conn->from);
|
||||
}
|
||||
|
||||
abort_connection(conn, state);
|
||||
}
|
||||
|
||||
|
||||
/* Add a link. The title of the destination is set, as there is no way of
|
||||
* knowing what the title is when we arrive.
|
||||
*
|
||||
@ -713,7 +689,7 @@ read_gopher_response_data(struct socket *socket, struct read_buffer *rb)
|
||||
assert(gopher && gopher->entity);
|
||||
|
||||
if (!conn->cached && !init_gopher_cache_entry(conn)) {
|
||||
end_gopher_connection(conn, S_OUT_OF_MEM);
|
||||
abort_connection(conn, S_OUT_OF_MEM);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -763,7 +739,7 @@ read_gopher_response_data(struct socket *socket, struct read_buffer *rb)
|
||||
}
|
||||
|
||||
if (state != S_TRANS) {
|
||||
end_gopher_connection(conn, state);
|
||||
abort_connection(conn, state);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -797,7 +773,7 @@ gopher_protocol_handler(struct connection *conn)
|
||||
* - FM */
|
||||
if (uri->datalen == 1 && *uri->data == GOPHER_CSO) {
|
||||
/* FIXME: redirect_cache() */
|
||||
end_gopher_connection(conn, S_GOPHER_CSO_ERROR);
|
||||
abort_connection(conn, S_GOPHER_CSO_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -810,7 +786,7 @@ gopher_protocol_handler(struct connection *conn)
|
||||
* - FM */
|
||||
if (uri->datalen >= 1 && *uri->data == GOPHER_FILE) {
|
||||
/* FIXME: redirect_cache() */
|
||||
end_gopher_connection(conn, S_OK);
|
||||
abort_connection(conn, S_OK);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
@ -819,7 +795,7 @@ gopher_protocol_handler(struct connection *conn)
|
||||
state = init_gopher_connection_info(conn);
|
||||
if (state != S_CONN) {
|
||||
/* FIXME: Handle bad selector ... */
|
||||
end_gopher_connection(conn, state);
|
||||
abort_connection(conn, state);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -470,14 +470,12 @@ http_end_request(struct connection *conn, enum connection_state state,
|
||||
{
|
||||
shutdown_connection_stream(conn);
|
||||
|
||||
if (state == S_OK && conn->cached) {
|
||||
normalize_cache_entry(conn->cached, !notrunc ? conn->from : -1);
|
||||
}
|
||||
|
||||
if (conn->info && !((struct http_connection_info *) conn->info)->close
|
||||
&& (!conn->socket->ssl) /* We won't keep alive ssl connections */
|
||||
&& (!get_opt_bool("protocol.http.bugs.post_no_keepalive")
|
||||
|| !conn->uri->post)) {
|
||||
if (state == S_OK && conn->cached)
|
||||
normalize_cache_entry(conn->cached, !notrunc ? conn->from : -1);
|
||||
set_connection_state(conn, state);
|
||||
add_keepalive_connection(conn, HTTP_KEEPALIVE_TIMEOUT, NULL);
|
||||
} else {
|
||||
|
@ -217,17 +217,16 @@ nntp_end_request(struct connection *conn, enum connection_state state)
|
||||
return;
|
||||
}
|
||||
|
||||
set_connection_state(conn, state);
|
||||
|
||||
if (conn->state == S_OK) {
|
||||
if (state == S_OK) {
|
||||
if (conn->cached) {
|
||||
normalize_cache_entry(conn->cached, conn->from);
|
||||
}
|
||||
} else if (conn->state == S_OUT_OF_MEM) {
|
||||
} else if (state == S_OUT_OF_MEM) {
|
||||
/* FIXME: Clear the socket buffers before ending so the one
|
||||
* grabing the keepalive connection will be able to go on. */
|
||||
}
|
||||
|
||||
set_connection_state(conn, state);
|
||||
add_keepalive_connection(conn, NNTP_KEEPALIVE_TIMEOUT, nntp_quit);
|
||||
}
|
||||
|
||||
|
@ -475,10 +475,8 @@ end_smb_connection(struct connection *conn)
|
||||
|
||||
if (smb_get_cache(conn)) return;
|
||||
|
||||
if (conn->from) {
|
||||
normalize_cache_entry(conn->cached, conn->from);
|
||||
if (conn->from)
|
||||
goto bye;
|
||||
}
|
||||
|
||||
/* Ensure termination by LF + NUL chars, memory for this
|
||||
* was reserved by smb_read_text(). */
|
||||
@ -507,7 +505,6 @@ end_smb_connection(struct connection *conn)
|
||||
|
||||
add_fragment(conn->cached, 0, page.source, page.length);
|
||||
conn->from += page.length;
|
||||
normalize_cache_entry(conn->cached, page.length);
|
||||
done_string(&page);
|
||||
|
||||
mem_free_set(&conn->cached->content_type, stracpy("text/html"));
|
||||
|
@ -460,6 +460,8 @@ struct string *
|
||||
add_uri_to_string(struct string *string, struct uri *uri,
|
||||
enum uri_component components)
|
||||
{
|
||||
int add_host = 0;
|
||||
|
||||
/* Custom or unknown keep the URI untouched. */
|
||||
if (uri->protocol == PROTOCOL_UNKNOWN)
|
||||
return add_to_string(string, struri(uri));
|
||||
@ -486,7 +488,7 @@ add_uri_to_string(struct string *string, struct uri *uri,
|
||||
}
|
||||
|
||||
if (wants(URI_HOST) && uri->hostlen) {
|
||||
int add_host = 1;
|
||||
add_host = 1;
|
||||
|
||||
#ifdef CONFIG_IPV6
|
||||
/* Rationale for wants(URI_PORT): The [notation] was invented
|
||||
@ -550,7 +552,7 @@ add_uri_to_string(struct string *string, struct uri *uri,
|
||||
}
|
||||
|
||||
/* Only add slash if we need to separate */
|
||||
if ((wants(URI_DATA) || wants(URI_POST))
|
||||
if ((wants(URI_DATA) || wants(URI_POST) || add_host)
|
||||
&& wants(~(URI_DATA | URI_PORT))
|
||||
&& get_protocol_need_slash_after_host(uri->protocol))
|
||||
add_char_to_string(string, '/');
|
||||
|
@ -968,10 +968,7 @@ tp_display(struct type_query *type_query)
|
||||
new->callback = (download_callback_T *) doc_loading_callback;
|
||||
new->data = ses;
|
||||
|
||||
if (is_in_progress_state(old->state))
|
||||
move_download(old, new, PRI_MAIN);
|
||||
else
|
||||
new->state = old->state;
|
||||
}
|
||||
|
||||
display_timer(ses);
|
||||
|
@ -604,10 +604,18 @@ doc_loading_callback(struct download *download, struct session *ses)
|
||||
print_screen_status(ses);
|
||||
|
||||
#ifdef CONFIG_GLOBHIST
|
||||
if (download->conn && download->pri != PRI_CSS) {
|
||||
if (download->pri != PRI_CSS) {
|
||||
unsigned char *title = ses->doc_view->document->title;
|
||||
struct uri *uri = download->conn->proxied_uri;
|
||||
struct uri *uri;
|
||||
|
||||
if (download->conn)
|
||||
uri = download->conn->proxied_uri;
|
||||
else if (download->cached)
|
||||
uri = download->cached->uri;
|
||||
else
|
||||
uri = NULL;
|
||||
|
||||
if (uri)
|
||||
add_global_history_item(struri(uri), title, time(NULL));
|
||||
}
|
||||
#endif
|
||||
|
@ -373,5 +373,4 @@ refresh_view(struct session *ses, struct document_view *doc_view, int frames)
|
||||
draw_doc(ses, doc_view, 1);
|
||||
if (frames) draw_frames(ses);
|
||||
print_screen_status(ses);
|
||||
redraw_from_window(ses->tab);
|
||||
}
|
||||
|
@ -982,8 +982,6 @@ get_form_uri(struct session *ses, struct document_view *doc_view,
|
||||
if (fc->type == FC_RESET) {
|
||||
do_reset_form(doc_view, form);
|
||||
return NULL;
|
||||
} else if (fc->type == FC_BUTTON) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!form->action
|
||||
|
@ -860,18 +860,28 @@ get_link_uri(struct session *ses, struct document_view *doc_view,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
try_submit_given_form(struct session *ses, struct document_view *doc_view,
|
||||
struct form *form, int do_reload)
|
||||
static int
|
||||
call_onsubmit_and_submit(struct session *ses, struct document_view *doc_view,
|
||||
struct form_control *fc, int do_reload)
|
||||
{
|
||||
struct uri *uri = NULL;
|
||||
enum cache_mode mode = do_reload ? CACHE_MODE_FORCE_RELOAD : CACHE_MODE_NORMAL;
|
||||
|
||||
assert(fc->form); /* regardless of whether there is a FORM element */
|
||||
if_assert_failed return 0;
|
||||
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
if (form->onsubmit) {
|
||||
/* If the form has multiple submit buttons, this does not
|
||||
* explicitly tell the ECMAScript code which of them was
|
||||
* pressed. W3C DOM Level 3 doesn't seem to include such a
|
||||
* feature. */
|
||||
if (fc->form->onsubmit) {
|
||||
struct string code;
|
||||
|
||||
if (init_string(&code)) {
|
||||
struct view_state *vs = doc_view->vs;
|
||||
struct ecmascript_interpreter *interpreter;
|
||||
unsigned char *ret = form->onsubmit;
|
||||
unsigned char *ret = fc->form->onsubmit;
|
||||
int res;
|
||||
|
||||
if (vs->ecmascript_fragile)
|
||||
@ -883,14 +893,24 @@ try_submit_given_form(struct session *ses, struct document_view *doc_view,
|
||||
while ((ret = strstr(ret, "return ")))
|
||||
while (*ret != ' ') *ret++ = ' ';
|
||||
|
||||
add_to_string(&code, form->onsubmit);
|
||||
add_to_string(&code, fc->form->onsubmit);
|
||||
res = ecmascript_eval_boolback(interpreter, &code);
|
||||
done_string(&code);
|
||||
if (!res) return;
|
||||
/* If the user presses Enter in a text field,
|
||||
* and document.browse.forms.auto_submit is
|
||||
* true, and the form has an onsubmit script
|
||||
* that returns false, then insert mode should
|
||||
* end, so return 1 here rather than 0. */
|
||||
if (!res) return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
submit_given_form(ses, doc_view, form, do_reload);
|
||||
#endif /* CONFIG_ECMASCRIPT */
|
||||
|
||||
uri = get_form_uri(ses, doc_view, fc);
|
||||
if (!uri) return 0;
|
||||
goto_uri_frame(ses, uri, fc->form->target, mode);
|
||||
done_uri(uri);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct link *
|
||||
@ -907,9 +927,10 @@ goto_current_link(struct session *ses, struct document_view *doc_view, int do_re
|
||||
|
||||
if (link_is_form(link)) {
|
||||
struct form_control *fc = link->data.form_control;
|
||||
struct form *form = fc->form;
|
||||
|
||||
try_submit_given_form(ses, doc_view, form, do_reload);
|
||||
if (!call_onsubmit_and_submit(ses, doc_view, fc, do_reload))
|
||||
return NULL;
|
||||
else
|
||||
return link;
|
||||
} else
|
||||
uri = get_link_uri(ses, doc_view, link);
|
||||
|
Loading…
Reference in New Issue
Block a user