fixed another psql \e bug (handle newlines as whitespace)
repaired psql option scanning bug (special treatment to \g |pipe) fixed ipcclean makefile made configure look for Perl to handle psql help build gracefully
This commit is contained in:
parent
ade95052f8
commit
ffc9812451
@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/Makefile.global.in,v 1.69 2000/03/31 14:14:31 momjian Exp $
|
# $Header: /cvsroot/pgsql/src/Makefile.global.in,v 1.70 2000/04/14 23:43:41 petere Exp $
|
||||||
#
|
#
|
||||||
# NOTES
|
# NOTES
|
||||||
# Essentially all Postgres make files include this file and use the
|
# Essentially all Postgres make files include this file and use the
|
||||||
@ -156,7 +156,7 @@ USE_TK= @USE_TK@
|
|||||||
WISH= @WISH@
|
WISH= @WISH@
|
||||||
|
|
||||||
USE_PERL= @USE_PERL@
|
USE_PERL= @USE_PERL@
|
||||||
PERL= perl
|
PERL= @PERL@
|
||||||
|
|
||||||
#
|
#
|
||||||
# enable native odbc driver support
|
# enable native odbc driver support
|
||||||
|
@ -1,29 +1,25 @@
|
|||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Makefile.inc--
|
# Makefile for bin/ipcclean
|
||||||
# Makefile for bin/initdb
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 1994, Regents of the University of California
|
# Copyright (c) 1994, Regents of the University of California
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/bin/ipcclean/Attic/Makefile,v 1.9 1999/12/08 10:29:46 momjian Exp $
|
# $Header: /cvsroot/pgsql/src/bin/ipcclean/Attic/Makefile,v 1.10 2000/04/14 23:43:43 petere Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
SRCDIR= ../..
|
SRCDIR= ../..
|
||||||
include ../../Makefile.global
|
include ../../Makefile.global
|
||||||
|
|
||||||
SEDSCRIPT= \
|
|
||||||
-e "s^PG_OPT_IPCCLEANPATH_PARAM^$(IPCSDIR)^g"
|
|
||||||
|
|
||||||
all: ipcclean
|
all: ipcclean
|
||||||
|
|
||||||
ipcclean:
|
ipcclean: ipcclean.sh
|
||||||
sed $(SEDSCRIPT) <ipcclean.sh >ipcclean
|
cp $< $@
|
||||||
|
|
||||||
install: ipcclean
|
install: ipcclean
|
||||||
$(INSTALL) $(INSTL_EXE_OPTS) $+ $(BINDIR)
|
$(INSTALL) $(INSTL_EXE_OPTS) $^ $(BINDIR)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f ipcclean
|
rm -f ipcclean
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/bin/psql/Attic/Makefile.in,v 1.21 2000/03/08 01:58:22 momjian Exp $
|
# $Header: /cvsroot/pgsql/src/bin/psql/Attic/Makefile.in,v 1.22 2000/04/14 23:43:44 petere Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -65,6 +65,7 @@ sql_help.h: $(wildcard $(SRCDIR)/../doc/src/sgml/ref/*.sgml) create_help.pl
|
|||||||
$(PERL) create_help.pl sql_help.h
|
$(PERL) create_help.pl sql_help.h
|
||||||
else
|
else
|
||||||
sql_help.h:
|
sql_help.h:
|
||||||
|
@echo "*** Perl is needed to build psql help."
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: submake
|
.PHONY: submake
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2000 by PostgreSQL Global Development Group
|
* Copyright 2000 by PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.28 2000/04/12 17:16:22 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.29 2000/04/14 23:43:44 petere Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
@ -51,7 +51,7 @@ static backslashResult exec_command(const char *cmd,
|
|||||||
|
|
||||||
enum option_type
|
enum option_type
|
||||||
{
|
{
|
||||||
OT_NORMAL, OT_SQLID
|
OT_NORMAL, OT_SQLID, OT_FILEPIPE
|
||||||
};
|
};
|
||||||
static char *scan_option(char **string, enum option_type type, char *quote);
|
static char *scan_option(char **string, enum option_type type, char *quote);
|
||||||
static char *unescape(const unsigned char *source, size_t len);
|
static char *unescape(const unsigned char *source, size_t len);
|
||||||
@ -105,7 +105,7 @@ HandleSlashCmds(const char *line,
|
|||||||
*
|
*
|
||||||
* Also look for a backslash, so stuff like \p\g works.
|
* Also look for a backslash, so stuff like \p\g works.
|
||||||
*/
|
*/
|
||||||
blank_loc = strcspn(my_line, " \t\\");
|
blank_loc = strcspn(my_line, " \t\n\r\\");
|
||||||
|
|
||||||
if (my_line[blank_loc] == '\\')
|
if (my_line[blank_loc] == '\\')
|
||||||
{
|
{
|
||||||
@ -408,7 +408,7 @@ exec_command(const char *cmd,
|
|||||||
/* \g means send query */
|
/* \g means send query */
|
||||||
else if (strcmp(cmd, "g") == 0)
|
else if (strcmp(cmd, "g") == 0)
|
||||||
{
|
{
|
||||||
char *fname = scan_option(&string, OT_NORMAL, NULL);
|
char *fname = scan_option(&string, OT_FILEPIPE, NULL);
|
||||||
|
|
||||||
if (!fname)
|
if (!fname)
|
||||||
pset.gfname = NULL;
|
pset.gfname = NULL;
|
||||||
@ -421,7 +421,7 @@ exec_command(const char *cmd,
|
|||||||
/* help */
|
/* help */
|
||||||
else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
|
else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
|
||||||
{
|
{
|
||||||
helpSQL(options_string ? &options_string[strspn(options_string, " \t")] : NULL);
|
helpSQL(options_string ? &options_string[strspn(options_string, " \t\n\r")] : NULL);
|
||||||
/* set pointer to end of line */
|
/* set pointer to end of line */
|
||||||
if (string)
|
if (string)
|
||||||
string += strlen(string);
|
string += strlen(string);
|
||||||
@ -518,7 +518,7 @@ exec_command(const char *cmd,
|
|||||||
/* \o -- set query output */
|
/* \o -- set query output */
|
||||||
else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
|
else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
|
||||||
{
|
{
|
||||||
char *fname = scan_option(&string, OT_NORMAL, NULL);
|
char *fname = scan_option(&string, OT_FILEPIPE, NULL);
|
||||||
|
|
||||||
success = setQFout(fname);
|
success = setQFout(fname);
|
||||||
free(fname);
|
free(fname);
|
||||||
@ -676,7 +676,7 @@ exec_command(const char *cmd,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fname = scan_option(&string, OT_NORMAL, NULL);
|
fname = scan_option(&string, OT_FILEPIPE, NULL);
|
||||||
|
|
||||||
if (!fname)
|
if (!fname)
|
||||||
{
|
{
|
||||||
@ -806,7 +806,7 @@ scan_option(char **string, enum option_type type, char *quote)
|
|||||||
|
|
||||||
options_string = *string;
|
options_string = *string;
|
||||||
/* skip leading whitespace */
|
/* skip leading whitespace */
|
||||||
pos += strspn(options_string + pos, " \t");
|
pos += strspn(options_string + pos, " \t\n\r");
|
||||||
|
|
||||||
switch (options_string[pos])
|
switch (options_string[pos])
|
||||||
{
|
{
|
||||||
@ -845,17 +845,11 @@ scan_option(char **string, enum option_type type, char *quote)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == OT_NORMAL)
|
|
||||||
{
|
|
||||||
strncpy(return_val, &options_string[pos], jj - pos + 1);
|
|
||||||
return_val[jj - pos + 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is expected to be an SQL identifier like option
|
* If this is expected to be an SQL identifier like option
|
||||||
* then we strip out the double quotes
|
* then we strip out the double quotes
|
||||||
*/
|
*/
|
||||||
else if (type == OT_SQLID)
|
if (type == OT_SQLID)
|
||||||
{
|
{
|
||||||
unsigned int k,
|
unsigned int k,
|
||||||
cc;
|
cc;
|
||||||
@ -877,6 +871,12 @@ scan_option(char **string, enum option_type type, char *quote)
|
|||||||
return_val[cc] = '\0';
|
return_val[cc] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(return_val, &options_string[pos], jj - pos + 1);
|
||||||
|
return_val[jj - pos + 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
*string = options_string + jj + 1;
|
*string = options_string + jj + 1;
|
||||||
if (quote)
|
if (quote)
|
||||||
*quote = '"';
|
*quote = '"';
|
||||||
@ -1010,7 +1010,7 @@ scan_option(char **string, enum option_type type, char *quote)
|
|||||||
const char *value;
|
const char *value;
|
||||||
char save_char;
|
char save_char;
|
||||||
|
|
||||||
token_end = strcspn(&options_string[pos + 1], " \t");
|
token_end = strcspn(&options_string[pos + 1], " \t\n\r");
|
||||||
save_char = options_string[pos + token_end + 1];
|
save_char = options_string[pos + token_end + 1];
|
||||||
options_string[pos + token_end + 1] = '\0';
|
options_string[pos + token_end + 1] = '\0';
|
||||||
value = GetVariable(pset.vars, options_string + pos + 1);
|
value = GetVariable(pset.vars, options_string + pos + 1);
|
||||||
@ -1030,6 +1030,19 @@ scan_option(char **string, enum option_type type, char *quote)
|
|||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* | could be the beginning of a pipe
|
||||||
|
* if so, take rest of line as command
|
||||||
|
*/
|
||||||
|
case '|':
|
||||||
|
if (type == OT_FILEPIPE)
|
||||||
|
{
|
||||||
|
*string += strlen(options_string + pos);
|
||||||
|
return xstrdup(options_string + pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fallthrough for other option types */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A normal word
|
* A normal word
|
||||||
*/
|
*/
|
||||||
@ -1038,7 +1051,7 @@ scan_option(char **string, enum option_type type, char *quote)
|
|||||||
size_t token_end;
|
size_t token_end;
|
||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
token_end = strcspn(&options_string[pos], " \t");
|
token_end = strcspn(&options_string[pos], " \t\n\r");
|
||||||
return_val = malloc(token_end + 1);
|
return_val = malloc(token_end + 1);
|
||||||
if (!return_val)
|
if (!return_val)
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2000 by PostgreSQL Global Development Group
|
* Copyright 2000 by PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.13 2000/04/12 17:16:22 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.14 2000/04/14 23:43:44 petere Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "copy.h"
|
#include "copy.h"
|
||||||
@ -82,7 +82,7 @@ parse_slash_copy(const char *args)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
token = strtokx(line, " \t", "\"", '\\', "e, NULL, pset.encoding);
|
token = strtokx(line, " \t\n\r", "\"", '\\', "e, NULL, pset.encoding);
|
||||||
if (!token)
|
if (!token)
|
||||||
error = true;
|
error = true;
|
||||||
else
|
else
|
||||||
@ -92,7 +92,7 @@ parse_slash_copy(const char *args)
|
|||||||
if (!quote && strcasecmp(token, "binary") == 0)
|
if (!quote && strcasecmp(token, "binary") == 0)
|
||||||
{
|
{
|
||||||
result->binary = true;
|
result->binary = true;
|
||||||
token = strtokx(NULL, " \t", "\"", '\\', "e, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", "\"", '\\', "e, NULL, pset.encoding);
|
||||||
if (!token)
|
if (!token)
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@ -107,14 +107,14 @@ parse_slash_copy(const char *args)
|
|||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||||
if (!token)
|
if (!token)
|
||||||
error = true;
|
error = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (strcasecmp(token, "with") == 0)
|
if (strcasecmp(token, "with") == 0)
|
||||||
{
|
{
|
||||||
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||||
if (!token || strcasecmp(token, "oids") != 0)
|
if (!token || strcasecmp(token, "oids") != 0)
|
||||||
error = true;
|
error = true;
|
||||||
else
|
else
|
||||||
@ -122,7 +122,7 @@ parse_slash_copy(const char *args)
|
|||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||||
if (!token)
|
if (!token)
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ parse_slash_copy(const char *args)
|
|||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
token = strtokx(NULL, " \t", "'", '\\', "e, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", "'", '\\', "e, NULL, pset.encoding);
|
||||||
if (!token)
|
if (!token)
|
||||||
error = true;
|
error = true;
|
||||||
else if (!quote && (strcasecmp(token, "stdin") == 0 || strcasecmp(token, "stdout") == 0))
|
else if (!quote && (strcasecmp(token, "stdin") == 0 || strcasecmp(token, "stdout") == 0))
|
||||||
@ -150,21 +150,21 @@ parse_slash_copy(const char *args)
|
|||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||||
if (token)
|
if (token)
|
||||||
{
|
{
|
||||||
if (strcasecmp(token, "using") == 0)
|
if (strcasecmp(token, "using") == 0)
|
||||||
{
|
{
|
||||||
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||||
if (!token || strcasecmp(token, "delimiters") != 0)
|
if (!token || strcasecmp(token, "delimiters") != 0)
|
||||||
error = true;
|
error = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
token = strtokx(NULL, " \t", "'", '\\', NULL, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding);
|
||||||
if (token)
|
if (token)
|
||||||
{
|
{
|
||||||
result->delim = xstrdup(token);
|
result->delim = xstrdup(token);
|
||||||
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error = true;
|
error = true;
|
||||||
@ -175,17 +175,17 @@ parse_slash_copy(const char *args)
|
|||||||
{
|
{
|
||||||
if (strcasecmp(token, "with") == 0)
|
if (strcasecmp(token, "with") == 0)
|
||||||
{
|
{
|
||||||
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||||
if (!token || strcasecmp(token, "null") != 0)
|
if (!token || strcasecmp(token, "null") != 0)
|
||||||
error = true;
|
error = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||||
if (!token || strcasecmp(token, "as") != 0)
|
if (!token || strcasecmp(token, "as") != 0)
|
||||||
error = true;
|
error = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
token = strtokx(NULL, " \t", "'", '\\', NULL, NULL, pset.encoding);
|
token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding);
|
||||||
if (token)
|
if (token)
|
||||||
result->null = xstrdup(token);
|
result->null = xstrdup(token);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2000 by PostgreSQL Global Development Group
|
* Copyright 2000 by PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.28 2000/04/12 17:16:22 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.29 2000/04/14 23:43:44 petere Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "mainloop.h"
|
#include "mainloop.h"
|
||||||
@ -397,7 +397,7 @@ MainLoop(FILE *source)
|
|||||||
{
|
{
|
||||||
line[i] = '\0';
|
line[i] = '\0';
|
||||||
/* is there anything else on the line? */
|
/* is there anything else on the line? */
|
||||||
if (line[query_start + strspn(line + query_start, " \t")] != '\0')
|
if (line[query_start + strspn(line + query_start, " \t\n\r")] != '\0')
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -441,7 +441,7 @@ MainLoop(FILE *source)
|
|||||||
line[i - prevlen] = '\0'; /* overwrites backslash */
|
line[i - prevlen] = '\0'; /* overwrites backslash */
|
||||||
|
|
||||||
/* is there anything else on the line for the command? */
|
/* is there anything else on the line for the command? */
|
||||||
if (line[query_start + strspn(line + query_start, " \t")] != '\0')
|
if (line[query_start + strspn(line + query_start, " \t\n\r")] != '\0')
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -499,7 +499,7 @@ MainLoop(FILE *source)
|
|||||||
|
|
||||||
|
|
||||||
/* Put the rest of the line in the query buffer. */
|
/* Put the rest of the line in the query buffer. */
|
||||||
if (line[query_start + strspn(line + query_start, " \t\n")] != '\0')
|
if (line[query_start + strspn(line + query_start, " \t\n\r")] != '\0')
|
||||||
{
|
{
|
||||||
if (query_buf->len > 0)
|
if (query_buf->len > 0)
|
||||||
appendPQExpBufferChar(query_buf, '\n');
|
appendPQExpBufferChar(query_buf, '\n');
|
||||||
|
833
src/configure
vendored
833
src/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -594,10 +594,9 @@ AC_PATH_PROG(tar, tar)
|
|||||||
AC_PATH_PROG(split, split)
|
AC_PATH_PROG(split, split)
|
||||||
AC_PATH_PROG(etags, etags)
|
AC_PATH_PROG(etags, etags)
|
||||||
AC_PATH_PROG(xargs, xargs)
|
AC_PATH_PROG(xargs, xargs)
|
||||||
AC_PATH_PROG(ipcs, ipcs)
|
|
||||||
AC_PATH_PROG(ipcrm, ipcrm)
|
|
||||||
AC_PATH_PROGS(TR, trbsd tr, NOT_FOUND)
|
AC_PATH_PROGS(TR, trbsd tr, NOT_FOUND)
|
||||||
AC_PATH_PROGS(GZCAT, gzcat zcat, gzcat)
|
AC_PATH_PROGS(GZCAT, gzcat zcat, gzcat)
|
||||||
|
AC_CHECK_PROGS(PERL, perl,)
|
||||||
|
|
||||||
dnl Check tr flags to convert from lower to upper case
|
dnl Check tr flags to convert from lower to upper case
|
||||||
TRSTRINGS="`echo ABCdef | $TR '[[a-z]]' '[[A-Z]]' 2>/dev/null | grep ABCDEF`"
|
TRSTRINGS="`echo ABCdef | $TR '[[a-z]]' '[[A-Z]]' 2>/dev/null | grep ABCDEF`"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user