mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-25 22:29:48 +00:00
* Fix r2 -n, remove r2 -t
- Some more fixes related to r_io. still more stuff to do
This commit is contained in:
parent
39f77a430f
commit
ed8d076cbe
@ -1,6 +1,6 @@
|
|||||||
BIN=radare2
|
BIN=radare2
|
||||||
BINDEPS=r_core r_parse r_search r_cons r_lib r_config r_diff
|
BINDEPS=r_core r_parse r_search r_cons r_lib r_config r_diff
|
||||||
BINDEPS+=r_bin r_debug r_anal r_reg r_bp r_io r_cmd r_th r_vm
|
BINDEPS+=r_bin r_debug r_anal r_reg r_bp r_io r_cmd r_th r_vm r_fs
|
||||||
BINDEPS+=r_sign r_print r_lang r_asm r_syscall r_hash r_line r_socket r_flags r_util
|
BINDEPS+=r_sign r_print r_lang r_asm r_syscall r_hash r_line r_socket r_flags r_util
|
||||||
|
|
||||||
include ../binr.mk
|
include ../binr.mk
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
static struct r_core_t r;
|
static struct r_core_t r;
|
||||||
|
|
||||||
static int main_help(int line) {
|
static int main_help(int line) {
|
||||||
printf ("Usage: radare2 [-dwntLV] [-p prj] [-s addr] [-b bsz] [-e k=v] [file]\n");
|
printf ("Usage: radare2 [-dwnLV] [-p prj] [-s addr] [-b bsz] [-e k=v] [file]\n");
|
||||||
if (!line) printf (
|
if (!line) printf (
|
||||||
" -d use 'file' as a program to debug\n"
|
" -d use 'file' as a program to debug\n"
|
||||||
" -w open file in write mode\n"
|
" -w open file in write mode\n"
|
||||||
@ -22,7 +22,7 @@ static int main_help(int line) {
|
|||||||
" -i [file] run script file\n"
|
" -i [file] run script file\n"
|
||||||
" -V show radare2 version\n"
|
" -V show radare2 version\n"
|
||||||
" -l [lib] load plugin file\n"
|
" -l [lib] load plugin file\n"
|
||||||
" -t load rabin2 info in thread\n"
|
//" -t load rabin2 info in thread\n"
|
||||||
" -L list supported IO plugins\n"
|
" -L list supported IO plugins\n"
|
||||||
" -u unknown file size\n"
|
" -u unknown file size\n"
|
||||||
" -e k=v evaluate config var\n");
|
" -e k=v evaluate config var\n");
|
||||||
@ -73,7 +73,7 @@ int main(int argc, char **argv) {
|
|||||||
RThreadLock *lock = NULL;
|
RThreadLock *lock = NULL;
|
||||||
RThread *rabin_th = NULL;
|
RThread *rabin_th = NULL;
|
||||||
RCoreFile *fh = NULL;
|
RCoreFile *fh = NULL;
|
||||||
int threaded = R_FALSE;
|
//int threaded = R_FALSE;
|
||||||
int has_project = R_FALSE;
|
int has_project = R_FALSE;
|
||||||
int ret, c, perms = R_IO_READ;
|
int ret, c, perms = R_IO_READ;
|
||||||
int run_rc = 1;
|
int run_rc = 1;
|
||||||
@ -81,17 +81,20 @@ int main(int argc, char **argv) {
|
|||||||
int fullfile = 0;
|
int fullfile = 0;
|
||||||
ut32 bsize = 0;
|
ut32 bsize = 0;
|
||||||
ut64 seek = 0;
|
ut64 seek = 0;
|
||||||
|
char file[1024];
|
||||||
char *cmdfile = NULL;
|
char *cmdfile = NULL;
|
||||||
|
|
||||||
if (argc<2)
|
if (argc<2)
|
||||||
return main_help (1);
|
return main_help (1);
|
||||||
r_core_init (&r);
|
r_core_init (&r);
|
||||||
|
|
||||||
while ((c = getopt (argc, argv, "wtfhe:ndvVs:p:b:Lui:l:"))!=-1) {
|
while ((c = getopt (argc, argv, "wfhe:ndvVs:p:b:Lui:l:"))!=-1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
#if 0
|
||||||
case 't':
|
case 't':
|
||||||
threaded = R_TRUE;
|
threaded = R_TRUE;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case 'v':
|
case 'v':
|
||||||
r_config_set (r.config, "scr.prompt", "false");
|
r_config_set (r.config, "scr.prompt", "false");
|
||||||
break;
|
break;
|
||||||
@ -140,7 +143,6 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (debug) {
|
if (debug) {
|
||||||
char file[1024];
|
|
||||||
r_config_set (r.config, "io.va", "false"); // implicit?
|
r_config_set (r.config, "io.va", "false"); // implicit?
|
||||||
r_config_set (r.config, "cfg.debug", "true");
|
r_config_set (r.config, "cfg.debug", "true");
|
||||||
strcpy (file, "dbg://");
|
strcpy (file, "dbg://");
|
||||||
@ -181,9 +183,22 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
if (r.file == NULL) // no given file
|
if (r.file == NULL) // no given file
|
||||||
return 1;
|
return 1;
|
||||||
|
//if (!has_project && run_rc) {
|
||||||
|
#if 0
|
||||||
|
if (run_rc) {
|
||||||
|
rabin_cmd = r_str_dup_printf ("rabin2 -rSIeMzisR%s %s",
|
||||||
|
(debug||r.io->va)?"v":"", r.file->filename);
|
||||||
|
if (threaded) {
|
||||||
|
/* TODO: only load data if no project is used */
|
||||||
|
lock = r_th_lock_new ();
|
||||||
|
rabin_th = r_th_new (&rabin_delegate, lock, 0);
|
||||||
|
} else rabin_delegate (NULL);
|
||||||
|
} else eprintf ("Metadata loaded from 'file.project'\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (run_rc) {
|
if (run_rc) {
|
||||||
char *homerc = r_str_home (".radare2rc");
|
char *homerc = r_str_home (".radare2rc");
|
||||||
|
r_core_bin_load (&r, NULL);
|
||||||
if (homerc) {
|
if (homerc) {
|
||||||
r_core_cmd_file (&r, homerc);
|
r_core_cmd_file (&r, homerc);
|
||||||
free (homerc);
|
free (homerc);
|
||||||
@ -251,23 +266,11 @@ int main(int argc, char **argv) {
|
|||||||
free (path);
|
free (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_project && run_rc) {
|
|
||||||
#if 0
|
|
||||||
rabin_cmd = r_str_dup_printf ("rabin2 -rSIeMzisR%s %s",
|
|
||||||
(debug||r.io->va)?"v":"", r.file->filename);
|
|
||||||
if (threaded) {
|
|
||||||
/* TODO: only load data if no project is used */
|
|
||||||
lock = r_th_lock_new ();
|
|
||||||
rabin_th = r_th_new (&rabin_delegate, lock, 0);
|
|
||||||
} else rabin_delegate (NULL);
|
|
||||||
#endif
|
|
||||||
} else eprintf ("Metadata loaded from 'file.project'\n");
|
|
||||||
|
|
||||||
if (cmdfile)
|
if (cmdfile)
|
||||||
r_core_cmd_file (&r, cmdfile);
|
r_core_cmd_file (&r, cmdfile);
|
||||||
|
|
||||||
if (r_io_is_listener (r.io))
|
if (r_io_is_listener (r.io))
|
||||||
r_core_serve (&r, r.io->fd);
|
r_core_serve (&r, r.io->fd->fd);
|
||||||
else
|
else
|
||||||
for (;;) {
|
for (;;) {
|
||||||
do {
|
do {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
BIN=radiff2
|
BIN=radiff2
|
||||||
BINDEPS=r_core r_diff r_config r_parse r_lib r_cons r_search r_anal r_reg
|
BINDEPS=r_core r_diff r_config r_parse r_lib r_cons r_search r_anal r_reg
|
||||||
BINDEPS+=r_bin r_flags r_debug r_vm r_bp r_io r_cmd
|
BINDEPS+=r_bin r_flags r_debug r_vm r_bp r_io r_cmd r_fs
|
||||||
BINDEPS+=r_sign r_print r_lang r_asm r_syscall r_hash r_line r_socket r_util
|
BINDEPS+=r_sign r_print r_lang r_asm r_syscall r_hash r_line r_socket r_util
|
||||||
|
|
||||||
include ../binr.mk
|
include ../binr.mk
|
||||||
|
@ -3125,8 +3125,8 @@ static int cmd_open(void *data, const char *input) {
|
|||||||
if (file) {
|
if (file) {
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
addr = r_num_math (core->num, ptr+1);
|
addr = r_num_math (core->num, ptr+1);
|
||||||
size = r_io_size (core->io, file->fd);
|
size = r_io_size (core->io, file->fd->fd);
|
||||||
r_io_map_add (core->io, file->fd, R_IO_READ, 0, addr, size);
|
r_io_map_add (core->io, file->fd->fd, R_IO_READ, 0, addr, size);
|
||||||
eprintf ("Map '%s' in 0x%08"PFMT64x" with size 0x%"PFMT64x"\n",
|
eprintf ("Map '%s' in 0x%08"PFMT64x" with size 0x%"PFMT64x"\n",
|
||||||
input+1, addr, size);
|
input+1, addr, size);
|
||||||
}
|
}
|
||||||
@ -3935,7 +3935,7 @@ static void cmd_debug_pid(RCore *core, const char *input) {
|
|||||||
r_debug_select (core->dbg, core->dbg->pid, core->dbg->tid);
|
r_debug_select (core->dbg, core->dbg->pid, core->dbg->tid);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
r_debug_select (core->dbg, core->file->fd, core->dbg->tid);
|
r_debug_select (core->dbg, core->file->fd->fd, core->dbg->tid);
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
r_debug_select (core->dbg,
|
r_debug_select (core->dbg,
|
||||||
|
@ -59,7 +59,7 @@ static int config_cfgdebug_callback(void *user, void *data) {
|
|||||||
if (core->dbg && node->i_value) {
|
if (core->dbg && node->i_value) {
|
||||||
r_debug_use (core->dbg, r_config_get (core->config, "dbg.backend"));
|
r_debug_use (core->dbg, r_config_get (core->config, "dbg.backend"));
|
||||||
if (core->file)
|
if (core->file)
|
||||||
r_debug_select (core->dbg, core->file->fd, core->file->fd);
|
r_debug_select (core->dbg, core->file->fd->fd, core->file->fd->fd);
|
||||||
}
|
}
|
||||||
return R_TRUE;
|
return R_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -38,22 +38,30 @@ R_API void r_core_sysenv_update(RCore *core) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_core_bin_load(RCore *r, const char *file) {
|
R_API int r_core_bin_load(RCore *r, const char *file) {
|
||||||
|
RBinInfo *info;
|
||||||
|
RBinAddr *binmain;
|
||||||
RBinObj *obj;
|
RBinObj *obj;
|
||||||
RList *list;
|
RList *list;
|
||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
|
RBinAddr *entry;
|
||||||
|
RBinSymbol *symbol;
|
||||||
|
RBinReloc *reloc;
|
||||||
|
RBinString *string;
|
||||||
|
RBinImport *import;
|
||||||
|
RBinSection *section;
|
||||||
ut64 baddr;
|
ut64 baddr;
|
||||||
int va = r->io->va || r->io->debug;
|
int va = r->io->va || r->io->debug;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
char str[R_FLAG_NAME_SIZE];
|
char str[R_FLAG_NAME_SIZE];
|
||||||
|
|
||||||
|
if (file == NULL)
|
||||||
|
file = r->file->filename;
|
||||||
if (!r_bin_load (r->bin, file, 0))
|
if (!r_bin_load (r->bin, file, 0))
|
||||||
return R_FALSE;
|
return R_FALSE;
|
||||||
r->file->obj = obj = r_bin_get_object (r->bin, 0);
|
r->file->obj = obj = r_bin_get_object (r->bin, 0);
|
||||||
baddr = r_bin_get_baddr (r->bin);
|
baddr = r_bin_get_baddr (r->bin);
|
||||||
|
|
||||||
// I -> Binary info
|
// I -> Binary info
|
||||||
RBinInfo *info;
|
|
||||||
|
|
||||||
if ((info = r_bin_get_info (r->bin)) != NULL) {
|
if ((info = r_bin_get_info (r->bin)) != NULL) {
|
||||||
r_config_set (r->config, "file.type", info->rclass);
|
r_config_set (r->config, "file.type", info->rclass);
|
||||||
r_config_set (r->config, "cfg.bigendian", info->big_endian?"true":"false");
|
r_config_set (r->config, "cfg.bigendian", info->big_endian?"true":"false");
|
||||||
@ -66,15 +74,12 @@ R_API int r_core_bin_load(RCore *r, const char *file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// M -> Main
|
// M -> Main
|
||||||
RBinAddr *binmain;
|
|
||||||
|
|
||||||
r_flag_space_set (r->flags, "symbols");
|
r_flag_space_set (r->flags, "symbols");
|
||||||
if ((binmain = r_bin_get_sym (r->bin, R_BIN_SYM_MAIN)) != NULL)
|
if ((binmain = r_bin_get_sym (r->bin, R_BIN_SYM_MAIN)) != NULL)
|
||||||
r_flag_set (r->flags, "main", va?baddr+binmain->rva:binmain->offset,
|
r_flag_set (r->flags, "main", va?baddr+binmain->rva:binmain->offset,
|
||||||
r->blocksize, 0);
|
r->blocksize, 0);
|
||||||
|
|
||||||
// e -> Entrypoints
|
// e -> Entrypoints
|
||||||
RBinAddr *entry;
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if ((list = r_bin_get_entries (r->bin)) != NULL) {
|
if ((list = r_bin_get_entries (r->bin)) != NULL) {
|
||||||
@ -88,8 +93,6 @@ R_API int r_core_bin_load(RCore *r, const char *file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// s -> Symbols
|
// s -> Symbols
|
||||||
RBinSymbol *symbol;
|
|
||||||
|
|
||||||
if ((list = r_bin_get_symbols (r->bin)) != NULL) {
|
if ((list = r_bin_get_symbols (r->bin)) != NULL) {
|
||||||
r_list_foreach (list, iter, symbol) {
|
r_list_foreach (list, iter, symbol) {
|
||||||
r_flag_name_filter (symbol->name);
|
r_flag_name_filter (symbol->name);
|
||||||
@ -108,8 +111,6 @@ R_API int r_core_bin_load(RCore *r, const char *file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// R -> Relocations
|
// R -> Relocations
|
||||||
RBinReloc *reloc;
|
|
||||||
|
|
||||||
r_flag_space_set (r->flags, "relocs");
|
r_flag_space_set (r->flags, "relocs");
|
||||||
if ((list = r_bin_get_relocs (r->bin)) != NULL) {
|
if ((list = r_bin_get_relocs (r->bin)) != NULL) {
|
||||||
r_list_foreach (list, iter, reloc) {
|
r_list_foreach (list, iter, reloc) {
|
||||||
@ -120,8 +121,6 @@ R_API int r_core_bin_load(RCore *r, const char *file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// z -> Strings
|
// z -> Strings
|
||||||
RBinString *string;
|
|
||||||
|
|
||||||
r_flag_space_set (r->flags, "strings");
|
r_flag_space_set (r->flags, "strings");
|
||||||
if ((list = r_bin_get_strings (r->bin)) != NULL) {
|
if ((list = r_bin_get_strings (r->bin)) != NULL) {
|
||||||
r_list_foreach (list, iter, string) {
|
r_list_foreach (list, iter, string) {
|
||||||
@ -137,8 +136,6 @@ R_API int r_core_bin_load(RCore *r, const char *file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// i -> Imports
|
// i -> Imports
|
||||||
RBinImport *import;
|
|
||||||
|
|
||||||
if ((list = r_bin_get_imports (r->bin)) != NULL) {
|
if ((list = r_bin_get_imports (r->bin)) != NULL) {
|
||||||
r_list_foreach (list, iter, import) {
|
r_list_foreach (list, iter, import) {
|
||||||
r_flag_name_filter (import->name);
|
r_flag_name_filter (import->name);
|
||||||
@ -157,7 +154,6 @@ R_API int r_core_bin_load(RCore *r, const char *file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// S -> Sections
|
// S -> Sections
|
||||||
RBinSection *section;
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if ((list = r_bin_get_sections (r->bin)) != NULL) {
|
if ((list = r_bin_get_sections (r->bin)) != NULL) {
|
||||||
@ -202,10 +198,10 @@ R_API RCoreFile *r_core_file_open(RCore *r, const char *file, int mode) {
|
|||||||
fh->filename = p+3;
|
fh->filename = p+3;
|
||||||
fh->rwx = mode;
|
fh->rwx = mode;
|
||||||
r->file = fh;
|
r->file = fh;
|
||||||
fh->size = r_io_size (r->io, fd);
|
fh->size = r_io_size (r->io, fd->fd);
|
||||||
list_add (&(fh->list), &r->files);
|
list_add (&(fh->list), &r->files);
|
||||||
|
|
||||||
r_core_bin_load (r, fh->filename);
|
// r_core_bin_load (r, fh->filename);
|
||||||
r_core_block_read (r, 0);
|
r_core_block_read (r, 0);
|
||||||
|
|
||||||
cp = r_config_get (r->config, "cmd.open");
|
cp = r_config_get (r->config, "cmd.open");
|
||||||
@ -245,8 +241,10 @@ R_API int r_core_file_list(struct r_core_t *core) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_core_file_close_fd(struct r_core_t *core, int fd) {
|
R_API int r_core_file_close_fd(struct r_core_t *core, int fd) {
|
||||||
int ret = r_io_close (core->io, fd);
|
int ret;
|
||||||
struct r_core_file_t *fh = r_core_file_get_fd (core, fd);
|
struct r_core_file_t *fh;
|
||||||
|
fh = r_core_file_get_fd (core, fd);
|
||||||
|
ret = r_io_close (core->io, fh->fd);
|
||||||
if (fh != NULL)
|
if (fh != NULL)
|
||||||
list_del (&(fh->list));
|
list_del (&(fh->list));
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -62,12 +62,12 @@ R_API int r_core_write_op(RCore *core, const char *arg, char op) {
|
|||||||
|
|
||||||
R_API boolt r_core_seek(RCore *core, ut64 addr, boolt rb) {
|
R_API boolt r_core_seek(RCore *core, ut64 addr, boolt rb) {
|
||||||
ut64 old = core->offset;
|
ut64 old = core->offset;
|
||||||
int ret;
|
ut64 ret;
|
||||||
|
|
||||||
/* XXX unnecesary call */
|
/* XXX unnecesary call */
|
||||||
r_io_set_fd (core->io, core->file->fd);
|
r_io_set_fd (core->io, core->file->fd);
|
||||||
ret = r_io_seek (core->io, addr, R_IO_SEEK_SET);
|
ret = r_io_seek (core->io, addr, R_IO_SEEK_SET);
|
||||||
if (ret == -1) {
|
if (ret == UT64_MAX) {
|
||||||
//eprintf ("RET =%d %llx\n", ret, addr);
|
//eprintf ("RET =%d %llx\n", ret, addr);
|
||||||
/*
|
/*
|
||||||
XXX handle read errors correctly
|
XXX handle read errors correctly
|
||||||
@ -75,7 +75,7 @@ R_API boolt r_core_seek(RCore *core, ut64 addr, boolt rb) {
|
|||||||
core->offset = addr;
|
core->offset = addr;
|
||||||
} else return R_FALSE;
|
} else return R_FALSE;
|
||||||
*/
|
*/
|
||||||
core->offset = addr;
|
//core->offset = addr;
|
||||||
} else core->offset = addr;
|
} else core->offset = addr;
|
||||||
if (rb) {
|
if (rb) {
|
||||||
ret = r_core_block_read (core, 0);
|
ret = r_core_block_read (core, 0);
|
||||||
|
@ -182,6 +182,8 @@ R_API char* r_core_asm_search(RCore *core, const char *input, ut64 from, ut64 to
|
|||||||
R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut64 to);
|
R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut64 to);
|
||||||
R_API RList *r_core_asm_bwdisassemble (RCore *core, ut64 addr, int n, int len);
|
R_API RList *r_core_asm_bwdisassemble (RCore *core, ut64 addr, int n, int len);
|
||||||
|
|
||||||
|
R_API int r_core_bin_load(RCore *r, const char *file);
|
||||||
|
|
||||||
/* gdiff.c */
|
/* gdiff.c */
|
||||||
R_API int r_core_gdiff(RCore *c, RCore *c2);
|
R_API int r_core_gdiff(RCore *c, RCore *c2);
|
||||||
|
|
||||||
|
@ -280,21 +280,24 @@ R_API int r_io_write_at(struct r_io_t *io, ut64 addr, const ut8 *buf, int len) {
|
|||||||
R_API ut64 r_io_seek(struct r_io_t *io, ut64 offset, int whence) {
|
R_API ut64 r_io_seek(struct r_io_t *io, ut64 offset, int whence) {
|
||||||
int posix_whence = SEEK_SET;
|
int posix_whence = SEEK_SET;
|
||||||
ut64 ret = -1;
|
ut64 ret = -1;
|
||||||
if (io == NULL)
|
|
||||||
return offset; // XXX
|
|
||||||
switch(whence) {
|
switch(whence) {
|
||||||
case R_IO_SEEK_SET:
|
case R_IO_SEEK_SET:
|
||||||
posix_whence = SEEK_SET;
|
posix_whence = SEEK_SET;
|
||||||
|
ret=offset;
|
||||||
break;
|
break;
|
||||||
case R_IO_SEEK_CUR:
|
case R_IO_SEEK_CUR:
|
||||||
// offset += io->off;
|
// offset += io->off;
|
||||||
posix_whence = SEEK_CUR;
|
posix_whence = SEEK_CUR;
|
||||||
|
ret=offset+io->off;
|
||||||
break;
|
break;
|
||||||
case R_IO_SEEK_END:
|
case R_IO_SEEK_END:
|
||||||
//offset = UT64_MAX; // XXX: depending on io bits?
|
//offset = UT64_MAX; // XXX: depending on io bits?
|
||||||
|
ret = UT64_MAX;
|
||||||
posix_whence = SEEK_END;
|
posix_whence = SEEK_END;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (io == NULL)
|
||||||
|
return ret;
|
||||||
// XXX: list_empty trick must be done in r_io_set_va();
|
// XXX: list_empty trick must be done in r_io_set_va();
|
||||||
offset = (!io->debug && io->va && !list_empty (&io->sections))?
|
offset = (!io->debug && io->va && !list_empty (&io->sections))?
|
||||||
r_io_section_vaddr_to_offset (io, offset) : offset;
|
r_io_section_vaddr_to_offset (io, offset) : offset;
|
||||||
|
Loading…
Reference in New Issue
Block a user