mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-24 14:27:57 +02:00
commit bash-20150717 snapshot
This commit is contained in:
@@ -9006,3 +9006,77 @@ subst.c
|
||||
introducing a `@' operator, but instead retains its meaning as all
|
||||
variables whose name begins with vvv. Fixes bug reported by
|
||||
konsolebox <konsolebox@gmail.com>
|
||||
|
||||
7/14
|
||||
----
|
||||
execute_cmd.c
|
||||
- execute_connection: remove the fork optimization from and AND_AND
|
||||
and OR_OR cases; it has trouble with `a && b && c', since the `&&'
|
||||
is left-associative. Putting that code here can result in unwanted
|
||||
fork optimizations since the `b' will end up as `second' on a
|
||||
recursive call to execute_command. Bug reported by Mike Frysinger
|
||||
<vapier@gentoo.org>
|
||||
|
||||
builtins/evalstring.c
|
||||
- optimize_fork: moved code from execute_connection to here; checks
|
||||
whether the RHS of a && or || passes the suppress_fork() tests and
|
||||
turns on the NO_FORK bit if so
|
||||
- parse_and_execute: if suppress_fork() tests fail, check whether the
|
||||
command to be executed is a connection and attempt to optimize the
|
||||
fork for the right side using optimize_fork(). The key is dealing
|
||||
with the entire command passed to `bash -c' or `eval'
|
||||
|
||||
builtins/common.h
|
||||
- optimize_fork: new extern declaration
|
||||
|
||||
execute_cmd.c
|
||||
- execute_command_internal: enable code put in to undo redirections
|
||||
before exiting the shell due to `set -e' in the case of a shell
|
||||
function that gets command-not-found or a syntax error. Reported
|
||||
back in May, 2014 by Mark Ferrell <major@homeonderanged.org>
|
||||
|
||||
bashhist.c
|
||||
- bash_history_inhibit_expansion: enable change from 1/10 that skips
|
||||
over history expansion character in command and process
|
||||
substitution
|
||||
|
||||
7/15
|
||||
----
|
||||
lib/readline/{history,undo}.c
|
||||
- replace_history_data now _hs_replace_history_data
|
||||
|
||||
7/16
|
||||
----
|
||||
lib/readline/readline.c
|
||||
- make sure _rl_to_lower doesn't ever get characters that are outside
|
||||
of its valid range by casting arg to unsigned char
|
||||
|
||||
lib/readline/colors.h
|
||||
- change completion prefix color (C_PREFIX) to be the same as C_SOCK,
|
||||
which is less likely to collide with file type colorings (magenta)
|
||||
|
||||
lib/readline/complete.c
|
||||
- fnprint: now takes an additional argument: the full, expanded pathname
|
||||
corresponding to the `toprint' argument
|
||||
- fnprint: don't zero out prefix_bytes if we're not printing the
|
||||
ellipisis but we still want to use prefix_bytes for displaying
|
||||
the common prefix in a color
|
||||
- print_filename: move colored-stats display responsibility into fnprint
|
||||
- fnprint: change so colored-prefix and colored-stats can cooperate
|
||||
and display filenames with multiple colors: one for the prefix and
|
||||
one for the file type. The prefix is displayed in the prefix color
|
||||
and the remainder of the pathname, if any, is displayed in the color
|
||||
corresponding to the file type. Report and suggestion from Mike
|
||||
Frysinger <vapier@gentoo.org>
|
||||
|
||||
7/17
|
||||
----
|
||||
lib/readline/readline.[ch]
|
||||
- rl_readline_state: now unsigned long
|
||||
|
||||
7/18
|
||||
----
|
||||
lib/readline/history.h
|
||||
- history_offset: now declared here, was always a global variable
|
||||
- copy_history_entry: now declared here, part of the public interface
|
||||
- alloc_history_entry: now declared here, part of the public interface
|
||||
|
||||
@@ -529,6 +529,8 @@ po/ja.po f
|
||||
po/lt.gmo f
|
||||
po/lt.po f
|
||||
po/nl.gmo f
|
||||
po/nb.po f
|
||||
po/nb.gmo f
|
||||
po/nl.po f
|
||||
po/pl.gmo f
|
||||
po/pl.po f
|
||||
@@ -947,6 +949,7 @@ tests/exec8.sub f
|
||||
tests/exec9.sub f
|
||||
tests/exec10.sub f
|
||||
tests/exec11.sub f
|
||||
tests/exec12.sub f
|
||||
tests/exp.tests f
|
||||
tests/exp.right f
|
||||
tests/exp1.sub f
|
||||
@@ -1002,6 +1005,7 @@ tests/heredoc3.sub f
|
||||
tests/herestr.tests f
|
||||
tests/herestr.right f
|
||||
tests/histexp.tests f
|
||||
tests/histexp1.sub f
|
||||
tests/histexp.right f
|
||||
tests/history.tests f
|
||||
tests/history.right f
|
||||
|
||||
+2
-3
@@ -226,12 +226,11 @@ bash_history_inhibit_expansion (string, i)
|
||||
else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
|
||||
return (1);
|
||||
#endif
|
||||
#if 0 /* bash-4.4 */
|
||||
|
||||
/* Make sure the history expansion should not be skipped by quoting or
|
||||
command/process substitution. */
|
||||
else if (t = skip_to_delim (string, 0, hx, SD_NOJMP) > 0 && t > i)
|
||||
else if ((t = skip_to_delim (string, 0, hx, SD_NOJMP)) > 0 && t > i)
|
||||
return (1);
|
||||
#endif
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -202,6 +202,7 @@ extern int evalstring __P((char *, const char *, int));
|
||||
extern void parse_and_execute_cleanup __P((void));
|
||||
extern int parse_string __P((char *, const char *, int, char **));
|
||||
extern int should_suppress_fork __P((COMMAND *));
|
||||
extern int optimize_fork __P((COMMAND *));
|
||||
|
||||
/* Functions from evalfile.c */
|
||||
extern int maybe_execute_file __P((const char *, int));
|
||||
|
||||
@@ -109,6 +109,20 @@ should_suppress_fork (command)
|
||||
((command->flags & CMD_TIME_PIPELINE) == 0) &&
|
||||
((command->flags & CMD_INVERT_RETURN) == 0));
|
||||
}
|
||||
|
||||
int
|
||||
optimize_fork (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
if (command->type == cm_connection &&
|
||||
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR) &&
|
||||
should_suppress_fork (command->value.Connection->second))
|
||||
{
|
||||
command->value.Connection->second->flags |= CMD_NO_FORK;
|
||||
command->value.Connection->second->value.Simple->flags |= CMD_NO_FORK;
|
||||
}
|
||||
}
|
||||
|
||||
/* How to force parse_and_execute () to clean up after itself. */
|
||||
void
|
||||
parse_and_execute_cleanup ()
|
||||
@@ -375,6 +389,8 @@ parse_and_execute (string, from_file, flags)
|
||||
command->flags |= CMD_NO_FORK;
|
||||
command->value.Simple->flags |= CMD_NO_FORK;
|
||||
}
|
||||
else if (command->type == cm_connection)
|
||||
optimize_fork (command);
|
||||
#endif /* ONESHOT */
|
||||
|
||||
/* See if this is a candidate for $( <file ). */
|
||||
|
||||
@@ -875,13 +875,11 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
last_command_exit_value = exec_result;
|
||||
run_pending_traps ();
|
||||
|
||||
#if 0 /* XXX - bash-4.4 or bash-5.0 */
|
||||
/* Undo redirections before running exit trap on the way out of
|
||||
set -e. Report by Mark Farrell 5/19/2014 */
|
||||
if (exit_immediately_on_error && signal_is_trapped (0) &&
|
||||
unwind_protect_tag_on_stack ("saved-redirects"))
|
||||
run_unwind_frame ("saved-redirects");
|
||||
#endif
|
||||
|
||||
jump_to_top_level (ERREXIT);
|
||||
}
|
||||
@@ -2629,11 +2627,6 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
||||
second = command->value.Connection->second;
|
||||
if (ignore_return && second)
|
||||
second->flags |= CMD_IGNORE_RETURN;
|
||||
if (should_suppress_fork (second))
|
||||
{
|
||||
second->flags |= CMD_NO_FORK;
|
||||
second->value.Simple->flags |= CMD_NO_FORK;
|
||||
}
|
||||
|
||||
exec_result = execute_command (second);
|
||||
}
|
||||
|
||||
@@ -114,8 +114,8 @@ enum filetype
|
||||
arg_directory
|
||||
};
|
||||
|
||||
/* Prefix color, currently same as directory */
|
||||
#define C_PREFIX C_DIR
|
||||
/* Prefix color, currently same as socket */
|
||||
#define C_PREFIX C_SOCK
|
||||
|
||||
extern void _rl_put_indicator (const struct bin_str *ind);
|
||||
extern void _rl_set_normal_color (void);
|
||||
|
||||
+29
-16
@@ -128,7 +128,7 @@ static int get_y_or_n PARAMS((int));
|
||||
static int _rl_internal_pager PARAMS((int));
|
||||
static char *printable_part PARAMS((char *));
|
||||
static int fnwidth PARAMS((const char *));
|
||||
static int fnprint PARAMS((const char *, int));
|
||||
static int fnprint PARAMS((const char *, int, const char *));
|
||||
static int print_filename PARAMS((char *, char *, int));
|
||||
|
||||
static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
|
||||
@@ -212,6 +212,8 @@ int rl_visible_stats = 0;
|
||||
completions. The colors used are taken from $LS_COLORS, if set. */
|
||||
int _rl_colored_stats = 0;
|
||||
|
||||
/* Non-zero means to use a color (currently magenta) to indicate the common
|
||||
prefix of a set of possible word completions. */
|
||||
int _rl_colored_completion_prefix = 1;
|
||||
#endif
|
||||
|
||||
@@ -798,9 +800,10 @@ fnwidth (string)
|
||||
#define ELLIPSIS_LEN 3
|
||||
|
||||
static int
|
||||
fnprint (to_print, prefix_bytes)
|
||||
fnprint (to_print, prefix_bytes, real_pathname)
|
||||
const char *to_print;
|
||||
int prefix_bytes;
|
||||
const char *real_pathname;
|
||||
{
|
||||
int printed_len, w;
|
||||
const char *s;
|
||||
@@ -819,10 +822,17 @@ fnprint (to_print, prefix_bytes)
|
||||
printed_len = common_prefix_len = 0;
|
||||
|
||||
/* Don't print only the ellipsis if the common prefix is one of the
|
||||
possible completions */
|
||||
if (to_print[prefix_bytes] == '\0')
|
||||
possible completions. Only cut off prefix_bytes if we're going to be
|
||||
printing the ellipsis, which takes precedence over coloring the
|
||||
completion prefix (see print_filename() below). */
|
||||
if (_rl_completion_prefix_display_length > 0 && to_print[prefix_bytes] == '\0')
|
||||
prefix_bytes = 0;
|
||||
|
||||
#if defined (COLOR_SUPPORT)
|
||||
if (_rl_colored_stats && (prefix_bytes == 0 || _rl_colored_completion_prefix <= 0))
|
||||
colored_stat_start (real_pathname);
|
||||
#endif
|
||||
|
||||
if (prefix_bytes && _rl_completion_prefix_display_length > 0)
|
||||
{
|
||||
char ellipsis;
|
||||
@@ -893,13 +903,23 @@ fnprint (to_print, prefix_bytes)
|
||||
}
|
||||
if (common_prefix_len > 0 && (s - to_print) >= common_prefix_len)
|
||||
{
|
||||
#if defined (COLOR_SUPPORT)
|
||||
/* printed bytes = s - to_print */
|
||||
/* printed bytes should never be > but check for paranoia's sake */
|
||||
colored_prefix_end ();
|
||||
if (_rl_colored_stats)
|
||||
colored_stat_start (real_pathname); /* XXX - experiment */
|
||||
#endif
|
||||
common_prefix_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (COLOR_SUPPORT)
|
||||
/* XXX - unconditional for now */
|
||||
if (_rl_colored_stats)
|
||||
colored_stat_end ();
|
||||
#endif
|
||||
|
||||
return printed_len;
|
||||
}
|
||||
|
||||
@@ -920,7 +940,7 @@ print_filename (to_print, full_pathname, prefix_bytes)
|
||||
/* Defer printing if we want to prefix with a color indicator */
|
||||
if (_rl_colored_stats == 0 || rl_filename_completion_desired == 0)
|
||||
#endif
|
||||
printed_len = fnprint (to_print, prefix_bytes);
|
||||
printed_len = fnprint (to_print, prefix_bytes, to_print);
|
||||
|
||||
if (rl_filename_completion_desired && (
|
||||
#if defined (VISIBLE_STATS)
|
||||
@@ -989,13 +1009,10 @@ print_filename (to_print, full_pathname, prefix_bytes)
|
||||
extension_char = '/';
|
||||
}
|
||||
|
||||
/* Move colored-stats code inside fnprint() */
|
||||
#if defined (COLOR_SUPPORT)
|
||||
if (_rl_colored_stats)
|
||||
{
|
||||
colored_stat_start (new_full_pathname);
|
||||
printed_len = fnprint (to_print, prefix_bytes);
|
||||
colored_stat_end ();
|
||||
}
|
||||
printed_len = fnprint (to_print, prefix_bytes, new_full_pathname);
|
||||
#endif
|
||||
|
||||
xfree (new_full_pathname);
|
||||
@@ -1012,15 +1029,11 @@ print_filename (to_print, full_pathname, prefix_bytes)
|
||||
if (_rl_complete_mark_directories && path_isdir (s))
|
||||
extension_char = '/';
|
||||
|
||||
/* Move colored-stats code inside fnprint() */
|
||||
#if defined (COLOR_SUPPORT)
|
||||
if (_rl_colored_stats)
|
||||
{
|
||||
colored_stat_start (s);
|
||||
printed_len = fnprint (to_print, prefix_bytes);
|
||||
colored_stat_end ();
|
||||
}
|
||||
printed_len = fnprint (to_print, prefix_bytes, s);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
xfree (s);
|
||||
|
||||
@@ -405,7 +405,7 @@ replace_history_entry (which, line, data)
|
||||
WHICH >= 0 means to replace that particular history entry's data, as
|
||||
long as it matches OLD. */
|
||||
void
|
||||
replace_history_data (which, old, new)
|
||||
_hs_replace_history_data (which, old, new)
|
||||
int which;
|
||||
histdata_t *old, *new;
|
||||
{
|
||||
|
||||
@@ -91,6 +91,13 @@ extern void add_history_time PARAMS((const char *));
|
||||
elements are numbered from 0. */
|
||||
extern HIST_ENTRY *remove_history PARAMS((int));
|
||||
|
||||
/* Allocate a history entry consisting of STRING and TIMESTAMP and return
|
||||
a pointer to it. */
|
||||
extern HIST_ENTRY *alloc_history_entry PARAMS((char *, char *));
|
||||
|
||||
/* Copy the history entry H, but not the (opaque) data pointer */
|
||||
extern HIST_ENTRY *copy_history_entry PARAMS((HIST_ENTRY *));
|
||||
|
||||
/* Free the history entry H and return any application-specific data
|
||||
associated with it. */
|
||||
extern histdata_t free_history_entry PARAMS((HIST_ENTRY *));
|
||||
@@ -241,6 +248,7 @@ extern char **history_tokenize PARAMS((const char *));
|
||||
extern int history_base;
|
||||
extern int history_length;
|
||||
extern int history_max_entries;
|
||||
extern int history_offset;
|
||||
|
||||
extern int history_lines_read_from_file;
|
||||
extern int history_lines_written_to_file;
|
||||
|
||||
@@ -151,7 +151,7 @@ static int running_in_emacs;
|
||||
#endif
|
||||
|
||||
/* Flags word encapsulating the current readline state. */
|
||||
int rl_readline_state = RL_STATE_NONE;
|
||||
unsigned long rl_readline_state = RL_STATE_NONE;
|
||||
|
||||
/* The current offset in the current input line. */
|
||||
int rl_point;
|
||||
@@ -846,7 +846,7 @@ _rl_dispatch_subseq (key, map, got_subseq)
|
||||
/* Special case rl_do_lowercase_version (). */
|
||||
if (func == rl_do_lowercase_version)
|
||||
/* Should we do anything special if key == ANYOTHERKEY? */
|
||||
return (_rl_dispatch (_rl_to_lower (key), map));
|
||||
return (_rl_dispatch (_rl_to_lower ((unsigned char)key), map));
|
||||
|
||||
rl_executing_keymap = map;
|
||||
rl_executing_key = key;
|
||||
@@ -1022,7 +1022,7 @@ _rl_subseq_result (r, map, key, got_subseq)
|
||||
type = m[ANYOTHERKEY].type;
|
||||
func = m[ANYOTHERKEY].function;
|
||||
if (type == ISFUNC && func == rl_do_lowercase_version)
|
||||
r = _rl_dispatch (_rl_to_lower (key), map);
|
||||
r = _rl_dispatch (_rl_to_lower ((unsigned char)key), map);
|
||||
else if (type == ISFUNC)
|
||||
{
|
||||
/* If we shadowed a function, whatever it is, we somehow need a
|
||||
|
||||
@@ -493,7 +493,7 @@ extern int rl_readline_version; /* e.g., 0x0402 */
|
||||
extern int rl_gnu_readline_p;
|
||||
|
||||
/* Flags word encapsulating the current readline state. */
|
||||
extern int rl_readline_state;
|
||||
extern unsigned long rl_readline_state;
|
||||
|
||||
/* Says which editing mode readline is currently using. 1 means emacs mode;
|
||||
0 means vi mode. */
|
||||
|
||||
+3
-3
@@ -50,7 +50,7 @@
|
||||
#include "rlprivate.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
extern void replace_history_data PARAMS((int, histdata_t *, histdata_t *));
|
||||
extern void _hs_replace_history_data PARAMS((int, histdata_t *, histdata_t *));
|
||||
|
||||
/* Non-zero tells rl_delete_text and rl_insert_text to not add to
|
||||
the undo list. */
|
||||
@@ -129,7 +129,7 @@ rl_free_undo_list ()
|
||||
orig_list = rl_undo_list;
|
||||
_rl_free_undo_list (rl_undo_list);
|
||||
rl_undo_list = (UNDO_LIST *)NULL;
|
||||
replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL);
|
||||
_hs_replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL);
|
||||
}
|
||||
|
||||
UNDO_LIST *
|
||||
@@ -245,7 +245,7 @@ rl_do_undo ()
|
||||
xfree (temp);
|
||||
}
|
||||
|
||||
replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list);
|
||||
_hs_replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list);
|
||||
|
||||
xfree (release);
|
||||
}
|
||||
|
||||
@@ -121,10 +121,7 @@ redirection_error (temp, error)
|
||||
else if ((temp->rflags & REDIR_VARASSIGN) == 0 && temp->redirector.dest < 0)
|
||||
/* This can happen when read_token_word encounters overflow, like in
|
||||
exec 4294967297>x */
|
||||
{
|
||||
itrace("redirection_error: temp->redirector.dest = %d", temp->redirector.dest);
|
||||
filename = _("file descriptor out of range");
|
||||
}
|
||||
#ifdef EBADF
|
||||
/* This error can never involve NOCLOBBER */
|
||||
else if (error != NOCLOBBER_REDIRECT && temp->redirector.dest >= 0 && error == EBADF)
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
@@ -81,3 +81,19 @@ group pipeline: 1
|
||||
EXIT-group.1
|
||||
foo 0
|
||||
after
|
||||
exit code: 1
|
||||
exit code: 1
|
||||
exit code: 1
|
||||
exit code: 127
|
||||
exit code: 127
|
||||
exit code: 127
|
||||
a
|
||||
b
|
||||
c
|
||||
A
|
||||
B
|
||||
c
|
||||
d
|
||||
c
|
||||
d
|
||||
e
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
: ${TMPDIR:=/var/tmp}
|
||||
TMPFILE=$TMPDIR/exitcode
|
||||
|
||||
rm -f $TMPFILE
|
||||
set -e
|
||||
exit_handler() { echo "exit code: $?" ; touch $TMPFILE; }
|
||||
false() { ! :; }
|
||||
notfound() { nosuchcommand ; }
|
||||
syntaxerror() { !:; }
|
||||
|
||||
main()
|
||||
{(
|
||||
trap exit_handler 0
|
||||
"$@" >> /dev/null 2>&1
|
||||
)}
|
||||
main "$@"
|
||||
echo "after main: should not get here"
|
||||
@@ -128,3 +128,30 @@ ${THIS_SH} -c 'VAR=0; VAR=1 command exec; exit ${VAR}'
|
||||
echo bad
|
||||
) 2>/dev/null
|
||||
[ $? = 127 ] || echo FAIL: bad exit status $? at $LINENO
|
||||
|
||||
unset FALSE
|
||||
if [ -x /bin/false ]; then
|
||||
FALSE=/bin/false
|
||||
elif [ -x /usr/bin/false ]; then
|
||||
FALSE=/usr/bin/false
|
||||
else
|
||||
FALSE='command false'
|
||||
fi
|
||||
|
||||
# problem with undoing redirections before running exit trap through bash-4.3
|
||||
|
||||
${THIS_SH} ./exec12.sub false # function
|
||||
${THIS_SH} ./exec12.sub command false
|
||||
${THIS_SH} ./exec12.sub $FALSE
|
||||
|
||||
${THIS_SH} ./exec12.sub notfound
|
||||
${THIS_SH} ./exec12.sub syntaxerror
|
||||
${THIS_SH} ./exec12.sub nosuchcommand
|
||||
|
||||
# problem with fork optimization in bash-4.4-alpha
|
||||
|
||||
$THIS_SH -c 'echo a && /bin/echo b && echo c'
|
||||
$THIS_SH -c 'echo A && /bin/echo B'
|
||||
|
||||
$THIS_SH -c '/bin/echo c && echo d'
|
||||
$THIS_SH -c '/bin/echo c && /bin/echo d && echo e'
|
||||
|
||||
@@ -130,3 +130,16 @@ ok 3
|
||||
echo shopt a
|
||||
shopt a
|
||||
echo a b c d 2 > /dev/null
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
\!
|
||||
\!
|
||||
\!
|
||||
\!
|
||||
|
||||
@@ -127,3 +127,5 @@ shopt a b c d 2>/dev/null
|
||||
echo !shopt-1
|
||||
|
||||
echo !shopt*
|
||||
|
||||
${THIS_SH} ./histexp1.sub
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
LC_ALL=C
|
||||
LANG=C
|
||||
|
||||
set -o history
|
||||
set -H
|
||||
|
||||
echo '!'
|
||||
echo "!"
|
||||
echo !
|
||||
|
||||
echo "$( echo '!' )"
|
||||
echo "$( echo "!" )"
|
||||
echo "$( echo ! )"
|
||||
|
||||
echo $( echo '!' )
|
||||
echo $( echo "!" )
|
||||
echo $( echo ! )
|
||||
|
||||
echo "$( echo "\!" )"
|
||||
echo "\!"
|
||||
|
||||
echo "$( echo '\!' )"
|
||||
echo '\!'
|
||||
Reference in New Issue
Block a user