mirror of
https://github.com/ipmitool/ipmitool.git
synced 2026-01-22 22:52:20 +08:00
add support for readline,
move raw command to its own file, remove md5 header that doesn't belong
This commit is contained in:
parent
e092eedd5b
commit
f6495ddf0e
@ -3,7 +3,7 @@ dnl autoconf for ipmitool
|
|||||||
dnl
|
dnl
|
||||||
AC_INIT([src/ipmitool.c])
|
AC_INIT([src/ipmitool.c])
|
||||||
AC_CANONICAL_SYSTEM
|
AC_CANONICAL_SYSTEM
|
||||||
AM_INIT_AUTOMAKE([ipmitool], [1.6.0pre3])
|
AM_INIT_AUTOMAKE([ipmitool], [1.6.0pre4])
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
AC_CONFIG_SRCDIR([src/ipmitool.c])
|
AC_CONFIG_SRCDIR([src/ipmitool.c])
|
||||||
AC_PREREQ(2.50)
|
AC_PREREQ(2.50)
|
||||||
@ -20,6 +20,7 @@ AC_CHECK_PROG([SED], [sed], [sed])
|
|||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
AC_CHECK_HEADERS([stdlib.h string.h sys/ioctl.h sys/stat.h unistd.h])
|
AC_CHECK_HEADERS([stdlib.h string.h sys/ioctl.h sys/stat.h unistd.h])
|
||||||
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h sys/socket.h])
|
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h sys/socket.h])
|
||||||
|
AC_CHECK_HEADERS([sys/byteorder.h byteswap.h])
|
||||||
|
|
||||||
AC_C_CONST
|
AC_C_CONST
|
||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
@ -32,6 +33,9 @@ AC_CHECK_FUNCS([alarm gethostbyname socket select])
|
|||||||
AC_CHECK_FUNCS([memmove memset strchr strdup strerror])
|
AC_CHECK_FUNCS([memmove memset strchr strdup strerror])
|
||||||
AC_CHECK_FUNCS([getpassphrase])
|
AC_CHECK_FUNCS([getpassphrase])
|
||||||
|
|
||||||
|
dnl CFLAGS="$CFLAGS -Wall -Werror"
|
||||||
|
dnl AC_SUBST(CFLAGS)
|
||||||
|
|
||||||
AM_PROG_LIBTOOL
|
AM_PROG_LIBTOOL
|
||||||
LIBTOOL="$LIBTOOL --silent"
|
LIBTOOL="$LIBTOOL --silent"
|
||||||
|
|
||||||
@ -40,7 +44,14 @@ AC_SEARCH_LIBS([socket], [socket], [],
|
|||||||
[AC_CHECK_LIB([nsl], [socket],
|
[AC_CHECK_LIB([nsl], [socket],
|
||||||
[LIBS="$LIBS -lsocket -lnsl"], [], [-lsocket])])
|
[LIBS="$LIBS -lsocket -lnsl"], [], [-lsocket])])
|
||||||
|
|
||||||
AC_CHECK_HEADERS([sys/byteorder.h byteswap.h])
|
have_readline=no
|
||||||
|
AC_SEARCH_LIBS([readline], [readline], [have_readline=yes],
|
||||||
|
[AC_CHECK_LIB([readline], [readline],
|
||||||
|
[have_readline=yes; LIBS="$LIBS -lcurses -lreadline"],
|
||||||
|
[], [-lcurses])])
|
||||||
|
if test "x$have_readline" = "xyes"; then
|
||||||
|
AC_DEFINE(HAVE_READLINE, [1], [Define to 1 if readline present.])
|
||||||
|
fi
|
||||||
|
|
||||||
if test "x$prefix" = "xNONE"; then
|
if test "x$prefix" = "xNONE"; then
|
||||||
prefix="$ac_default_prefix"
|
prefix="$ac_default_prefix"
|
||||||
@ -71,12 +82,18 @@ AC_CHECK_LIB([crypto], [EVP_aes_128_cbc],
|
|||||||
[have_crypto=no], [-lcrypto])
|
[have_crypto=no], [-lcrypto])
|
||||||
|
|
||||||
AC_CHECK_LIB([crypto], [MD5_Init],
|
AC_CHECK_LIB([crypto], [MD5_Init],
|
||||||
[LIBS="$LIBS -lcrypto"
|
[if test "x$have_crypto" != "xyes"; then
|
||||||
|
LIBS="$LIBS -lcrypto"
|
||||||
|
have_crypto=yes
|
||||||
|
fi
|
||||||
AC_DEFINE(HAVE_CRYPTO_MD5, [1], [Define to 1 if libcrypto supports MD5.])],
|
AC_DEFINE(HAVE_CRYPTO_MD5, [1], [Define to 1 if libcrypto supports MD5.])],
|
||||||
[], [-lcrypto])
|
[], [-lcrypto])
|
||||||
|
|
||||||
AC_CHECK_LIB([crypto], [MD2_Init],
|
AC_CHECK_LIB([crypto], [MD2_Init],
|
||||||
[LIBS="$LIBS -lcrypto"
|
[if test "x$have_crypto" != "xyes"; then
|
||||||
|
LIBS="$LIBS -lcrypto"
|
||||||
|
have_crypto=yes
|
||||||
|
fi
|
||||||
AC_DEFINE(HAVE_CRYPTO_MD2, [1], [Define to 1 if libcrypto supports MD2.])],
|
AC_DEFINE(HAVE_CRYPTO_MD2, [1], [Define to 1 if libcrypto supports MD2.])],
|
||||||
[], [-lcrypto])
|
[], [-lcrypto])
|
||||||
|
|
||||||
@ -178,11 +195,12 @@ AC_ARG_ENABLE([ipmievd],
|
|||||||
[AC_HELP_STRING([--enable-ipmievd],
|
[AC_HELP_STRING([--enable-ipmievd],
|
||||||
[enable IPMI Event daemon [default=yes]])],
|
[enable IPMI Event daemon [default=yes]])],
|
||||||
[], [enable_ipmievd=yes])
|
[], [enable_ipmievd=yes])
|
||||||
AM_CONDITIONAL(IPMIEVD, test "x$enable_ipmievd" = "xyes")
|
AM_CONDITIONAL(IPMIEVD, [test "x$enable_ipmievd" = "xyes"])
|
||||||
if test "x$enable_ipmievd" = "xyes"; then
|
if test "x$enable_ipmievd" = "xyes"; then
|
||||||
AC_SUBST(IPMIEVD_BIN, [ipmievd])
|
AC_SUBST(IPMIEVD_BIN, [ipmievd])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl Generate files for build
|
||||||
AC_CONFIG_FILES([Makefile
|
AC_CONFIG_FILES([Makefile
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
contrib/Makefile
|
contrib/Makefile
|
||||||
|
|||||||
@ -36,7 +36,7 @@ MAINTAINERCLEANFILES = Makefile.in
|
|||||||
|
|
||||||
noinst_HEADERS = log.h bswap.h helper.h ipmi.h ipmi_intf.h \
|
noinst_HEADERS = log.h bswap.h helper.h ipmi.h ipmi_intf.h \
|
||||||
ipmi_chassis.h ipmi_entity.h ipmi_fru.h ipmi_lanp.h \
|
ipmi_chassis.h ipmi_entity.h ipmi_fru.h ipmi_lanp.h \
|
||||||
ipmi_sdr.h ipmi_sel.h ipmi_sol.h ipmi_bmc.h \
|
ipmi_sdr.h ipmi_sel.h ipmi_sol.h ipmi_bmc.h ipmi_raw.h \
|
||||||
ipmi_channel.h ipmi_sensor.h ipmi_event.h ipmi_session.h \
|
ipmi_channel.h ipmi_sensor.h ipmi_event.h ipmi_session.h \
|
||||||
ipmi_strings.h ipmi_constants.h ipmi_isol.h ipmi_user.h
|
ipmi_strings.h ipmi_constants.h ipmi_isol.h ipmi_user.h
|
||||||
|
|
||||||
|
|||||||
44
ipmitool/include/ipmitool/ipmi_raw.h
Normal file
44
ipmitool/include/ipmitool/ipmi_raw.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistribution of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistribution in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of Sun Microsystems, Inc. or the names of
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* This software is provided "AS IS," without a warranty of any kind.
|
||||||
|
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
|
||||||
|
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
|
||||||
|
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
|
||||||
|
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||||||
|
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
|
||||||
|
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
|
||||||
|
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
|
||||||
|
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
|
||||||
|
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
|
||||||
|
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
*
|
||||||
|
* You acknowledge that this software is not designed or intended for use
|
||||||
|
* in the design, construction, operation or maintenance of any nuclear
|
||||||
|
* facility.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IPMI_RAW_H
|
||||||
|
#define IPMI_RAW_H
|
||||||
|
|
||||||
|
#include <ipmitool/ipmi.h>
|
||||||
|
|
||||||
|
int ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||||
|
|
||||||
|
#endif /* IPMI_RAW_H */
|
||||||
@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any damages
|
|
||||||
arising from the use of this software.
|
|
||||||
|
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
|
||||||
including commercial applications, and to alter it and redistribute it
|
|
||||||
freely, subject to the following restrictions:
|
|
||||||
|
|
||||||
1. The origin of this software must not be misrepresented; you must not
|
|
||||||
claim that you wrote the original software. If you use this software
|
|
||||||
in a product, an acknowledgment in the product documentation would be
|
|
||||||
appreciated but is not required.
|
|
||||||
2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
misrepresented as being the original software.
|
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
|
||||||
|
|
||||||
L. Peter Deutsch
|
|
||||||
ghost@aladdin.com
|
|
||||||
|
|
||||||
*/
|
|
||||||
/* $Id: md5.h,v 1.1 2004/05/25 20:53:49 iceblink Exp $ */
|
|
||||||
/*
|
|
||||||
Independent implementation of MD5 (RFC 1321).
|
|
||||||
|
|
||||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
|
||||||
text is available at
|
|
||||||
http://www.ietf.org/rfc/rfc1321.txt
|
|
||||||
The code is derived from the text of the RFC, including the test suite
|
|
||||||
(section A.5) but excluding the rest of Appendix A. It does not include
|
|
||||||
any code or documentation that is identified in the RFC as being
|
|
||||||
copyrighted.
|
|
||||||
|
|
||||||
The original and principal author of md5.h is L. Peter Deutsch
|
|
||||||
<ghost@aladdin.com>. Other authors are noted in the change history
|
|
||||||
that follows (in reverse chronological order):
|
|
||||||
|
|
||||||
2002-04-13 lpd Removed support for non-ANSI compilers; removed
|
|
||||||
references to Ghostscript; clarified derivation from RFC 1321;
|
|
||||||
now handles byte order either statically or dynamically.
|
|
||||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
|
||||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
|
|
||||||
added conditionalization for C++ compilation from Martin
|
|
||||||
Purschke <purschke@bnl.gov>.
|
|
||||||
1999-05-03 lpd Original version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef md5_INCLUDED
|
|
||||||
# define md5_INCLUDED
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This package supports both compile-time and run-time determination of CPU
|
|
||||||
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
|
|
||||||
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
|
|
||||||
* defined as non-zero, the code will be compiled to run only on big-endian
|
|
||||||
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
|
|
||||||
* run on either big- or little-endian CPUs, but will run slightly less
|
|
||||||
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef unsigned char md5_byte_t; /* 8-bit byte */
|
|
||||||
typedef unsigned int md5_word_t; /* 32-bit word */
|
|
||||||
|
|
||||||
/* Define the state of the MD5 Algorithm. */
|
|
||||||
typedef struct md5_state_s {
|
|
||||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
|
||||||
md5_word_t abcd[4]; /* digest buffer */
|
|
||||||
md5_byte_t buf[64]; /* accumulate block */
|
|
||||||
} md5_state_t;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize the algorithm. */
|
|
||||||
void md5_init(md5_state_t *pms);
|
|
||||||
|
|
||||||
/* Append a string to the message. */
|
|
||||||
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
|
|
||||||
|
|
||||||
/* Finish the message and return the digest. */
|
|
||||||
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* multi-session authcode generation for md5
|
|
||||||
* H(password + session_id + msg + session_seq + password)
|
|
||||||
*/
|
|
||||||
unsigned char * ipmi_auth_md5(unsigned char * data, int data_len);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* end extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* md5_INCLUDED */
|
|
||||||
@ -36,9 +36,10 @@ INCLUDES = -I$(top_srcdir)/include
|
|||||||
MAINTAINERCLEANFILES = Makefile.in
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libipmitool.la
|
noinst_LTLIBRARIES = libipmitool.la
|
||||||
libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_isol.c ipmi_lanp.c \
|
libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_isol.c \
|
||||||
ipmi_fru.c ipmi_chassis.c ipmi_bmc.c dimm_spd.c ipmi_sensor.c \
|
ipmi_lanp.c ipmi_fru.c ipmi_chassis.c ipmi_bmc.c log.c \
|
||||||
ipmi_channel.c ipmi_event.c ipmi_session.c ipmi_strings.c ipmi_user.c log.c
|
dimm_spd.c ipmi_sensor.c ipmi_channel.c ipmi_event.c \
|
||||||
|
ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c
|
||||||
libipmitool_la_LDFLAGS = -export-dynamic
|
libipmitool_la_LDFLAGS = -export-dynamic
|
||||||
libipmitool_la_LIBADD = -lm
|
libipmitool_la_LIBADD = -lm
|
||||||
libipmitool_la_DEPENDENCIES =
|
libipmitool_la_DEPENDENCIES =
|
||||||
|
|||||||
101
ipmitool/lib/ipmi_raw.c
Normal file
101
ipmitool/lib/ipmi_raw.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistribution of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistribution in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of Sun Microsystems, Inc. or the names of
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* This software is provided "AS IS," without a warranty of any kind.
|
||||||
|
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
|
||||||
|
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
|
||||||
|
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
|
||||||
|
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||||||
|
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
|
||||||
|
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
|
||||||
|
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
|
||||||
|
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
|
||||||
|
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
|
||||||
|
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
*
|
||||||
|
* You acknowledge that this software is not designed or intended for use
|
||||||
|
* in the design, construction, operation or maintenance of any nuclear
|
||||||
|
* facility.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ipmitool/ipmi.h>
|
||||||
|
#include <ipmitool/ipmi_intf.h>
|
||||||
|
#include <ipmitool/ipmi_raw.h>
|
||||||
|
|
||||||
|
int ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||||
|
{
|
||||||
|
struct ipmi_rs * rsp;
|
||||||
|
struct ipmi_rq req;
|
||||||
|
unsigned char netfn, cmd;
|
||||||
|
int i;
|
||||||
|
unsigned char data[32];
|
||||||
|
|
||||||
|
if (argc < 2 || !strncmp(argv[0], "help", 4)) {
|
||||||
|
printf("RAW Commands: raw <netfn> <cmd> [data]\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
netfn = (unsigned char)strtol(argv[0], NULL, 0);
|
||||||
|
cmd = (unsigned char)strtol(argv[1], NULL, 0);
|
||||||
|
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
req.msg.netfn = netfn;
|
||||||
|
req.msg.cmd = cmd;
|
||||||
|
req.msg.data = data;
|
||||||
|
|
||||||
|
for (i=2; i<argc; i++) {
|
||||||
|
unsigned char val = (unsigned char)strtol(argv[i], NULL, 0);
|
||||||
|
req.msg.data[i-2] = val;
|
||||||
|
req.msg.data_len++;
|
||||||
|
}
|
||||||
|
if (verbose && req.msg.data_len) {
|
||||||
|
for (i=0; i<req.msg.data_len; i++) {
|
||||||
|
if (((i%16) == 0) && (i != 0))
|
||||||
|
printf("\n");
|
||||||
|
printf(" %2.2x", req.msg.data[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
printf("RAW REQ (netfn=0x%x cmd=0x%x data_len=%d)\n",
|
||||||
|
req.msg.netfn, req.msg.cmd, req.msg.data_len);
|
||||||
|
|
||||||
|
rsp = intf->sendrecv(intf, &req);
|
||||||
|
|
||||||
|
if (!rsp || rsp->ccode) {
|
||||||
|
printf("Error:%x sending RAW command\n",
|
||||||
|
rsp ? rsp->ccode : 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
printf("RAW RSP (%d bytes)\n", rsp->data_len);
|
||||||
|
|
||||||
|
for (i=0; i<rsp->data_len; i++) {
|
||||||
|
if (((i%16) == 0) && (i != 0))
|
||||||
|
printf("\n");
|
||||||
|
printf(" %2.2x", rsp->data[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user