clean up import
This commit is contained in:
parent
2dea3cacb5
commit
a6ef9be155
@ -1,10 +1,10 @@
|
||||
# from: @(#)Makefile 5.4 (Berkeley) 10/26/90
|
||||
# $Id: Makefile,v 1.3 1993/08/01 05:38:29 mycroft Exp $
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
# $Id: Makefile,v 1.4 1994/06/18 20:55:54 cgd Exp $
|
||||
|
||||
PROG= chown
|
||||
CFLAGS+=-DSUPPORT_DOT
|
||||
MAN1= chgrp.0
|
||||
MAN8= chown.0
|
||||
LINKS= ${BINDIR}/chown ${BINDIR}/../bin/chgrp
|
||||
LINKS= ${BINDIR}/chown /usr/bin/chgrp
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Copyright (c) 1983, 1990 The Regents of the University of California.
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 1983, 1990, 1993, 1994
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" the Institute of Electrical and Electronics Engineers, Inc.
|
||||
@ -32,10 +32,10 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)chgrp.1 6.7 (Berkeley) 6/27/91
|
||||
.\" $Id: chgrp.1,v 1.3 1993/11/30 00:38:53 jtc Exp $
|
||||
.\" from: @(#)chgrp.1 8.3 (Berkeley) 3/31/94
|
||||
.\" $Id: chgrp.1,v 1.4 1994/06/18 20:55:56 cgd Exp $
|
||||
.\"
|
||||
.Dd June 27, 1991
|
||||
.Dd March 31, 1994
|
||||
.Dt CHGRP 1
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
@ -43,7 +43,11 @@
|
||||
.Nd change group
|
||||
.Sh SYNOPSIS
|
||||
.Nm chgrp
|
||||
.Op Fl Rf
|
||||
.Oo
|
||||
.Fl R
|
||||
.Op Fl H | Fl L | Fl P
|
||||
.Oc
|
||||
.Op Fl f
|
||||
.Ar group
|
||||
.Ar files ...
|
||||
.Sh DESCRIPTION
|
||||
@ -55,38 +59,66 @@ ID specified by the group operand.
|
||||
.Pp
|
||||
Options:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl H
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, symbolic links on the command line are followed.
|
||||
(Symbolic links encountered in the tree traversal are not followed.)
|
||||
.It Fl L
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, all symbolic links are followed.
|
||||
.It Fl P
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, no symbolic links are followed.
|
||||
.It Fl R
|
||||
Recursively change file group IDs.
|
||||
For each
|
||||
.Ar file
|
||||
operand that names a directory, chgrp changes the
|
||||
group of the directory and all files in the file
|
||||
hierarchy below it.
|
||||
When symbolic links are encountered, their group is changed,
|
||||
but they are not traversed.
|
||||
Change the group ID for the file hierarchies rooted
|
||||
in the files instead of just the files themselves.
|
||||
.It Fl f
|
||||
The force option ignores errors, except for usage errors and doesn't
|
||||
query about strange modes (unless user does not have proper permissions).
|
||||
query about strange modes (unless the user does not have proper permissions).
|
||||
.El
|
||||
.Pp
|
||||
Operands:
|
||||
.Bl -tag -width group
|
||||
.It Ar group
|
||||
Symbolic links don't have groups, so unless the
|
||||
.Fl H
|
||||
or
|
||||
.Fl L
|
||||
option is set,
|
||||
.Nm chgrp
|
||||
on a symbolic link always succeeds and has no effect.
|
||||
The
|
||||
.Fl H ,
|
||||
.Fl L
|
||||
and
|
||||
.Fl P
|
||||
options are ignored unless the
|
||||
.Fl R
|
||||
option is specified.
|
||||
In addition, these options override each other and the
|
||||
command's actions are determined by the last one specified.
|
||||
.Pp
|
||||
The
|
||||
.Ar group
|
||||
can be either a group name from the group database, or a numeric
|
||||
group ID.
|
||||
.It Ar file
|
||||
A pathname of a file whose group ID is to be modified.
|
||||
.El
|
||||
operand can be either a group name from the group database,
|
||||
or a numeric group ID.
|
||||
If a group name is also a numeric group ID, the operand is used as a
|
||||
group name.
|
||||
.Pp
|
||||
The user invoking
|
||||
must belong
|
||||
to the specified group and be the owner of the file, or be the super-user.
|
||||
.Nm chgrp
|
||||
must belong to the specified group and be the owner of the file,
|
||||
or be the super-user.
|
||||
.Pp
|
||||
The
|
||||
.Nm chgrp
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Sh COMPATIBILITY
|
||||
Previous versions of the
|
||||
.Nm chgrp
|
||||
utility changed the group of symbolic links specified on the command
|
||||
line.
|
||||
In this system, symbolic links do not have groups.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/group -compact
|
||||
.It Pa /etc/group
|
||||
@ -94,11 +126,12 @@ Group ID file
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr chown 2 ,
|
||||
.Xr chown 8 ,
|
||||
.Xr group 5 ,
|
||||
.Xr passwd 5
|
||||
.Xr passwd 5 ,
|
||||
.Xr fts 3 ,
|
||||
.Xr symlink 7 ,
|
||||
.Xr chown 8
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm chgrp
|
||||
function is expected to conform to
|
||||
.St -p1003.2-92 .
|
||||
utility is expected to be POSIX 1003.2 compatible.
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Copyright (c) 1990, 1991 The Regents of the University of California.
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 1990, 1991, 1993, 1994
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -29,10 +29,10 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)chown.8 6.6 (Berkeley) 6/17/91
|
||||
.\" $Id: chown.8,v 1.3 1993/11/30 00:38:54 jtc Exp $
|
||||
.\" from: @(#)chown.8 8.3 (Berkeley) 3/31/94
|
||||
.\" $Id: chown.8,v 1.4 1994/06/18 20:55:57 cgd Exp $
|
||||
.\"
|
||||
.Dd June 17, 1991
|
||||
.Dd March 31, 1994
|
||||
.Dt CHOWN 8
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
@ -40,11 +40,19 @@
|
||||
.Nd change file owner and group
|
||||
.Sh SYNOPSIS
|
||||
.Nm chown
|
||||
.Op Fl Rf
|
||||
.Oo
|
||||
.Fl R
|
||||
.Op Fl H | Fl L | Fl P
|
||||
.Oc
|
||||
.Op Fl f
|
||||
.Ar owner Op Ar :group
|
||||
.Ar file ...
|
||||
.Nm chown
|
||||
.Op Fl Rf
|
||||
.Oo
|
||||
.Fl R
|
||||
.Op Fl H | Fl L | Fl P
|
||||
.Oc
|
||||
.Op Fl f
|
||||
.Ar :group
|
||||
.Ar file ...
|
||||
.Sh DESCRIPTION
|
||||
@ -53,6 +61,19 @@ sets the user ID and/or the group ID of the specified files.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl H
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, symbolic links on the command line are followed.
|
||||
(Symbolic links encountered in the tree traversal are not followed.)
|
||||
.It Fl L
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, all symbolic links are followed.
|
||||
.It Fl P
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, no symbolic links are followed.
|
||||
.It Fl R
|
||||
Change the user ID and/or the group ID for the file hierarchies rooted
|
||||
in the files instead of just the files themselves.
|
||||
@ -61,6 +82,24 @@ Don't report any failure to change file owner or group, nor modify
|
||||
the exit status to reflect such failures.
|
||||
.El
|
||||
.Pp
|
||||
Symbolic links don't have owners, so unless the
|
||||
.Fl H
|
||||
or
|
||||
.Fl L
|
||||
option is set,
|
||||
.Nm chown
|
||||
on a symbolic link always succeeds and has no effect.
|
||||
The
|
||||
.Fl H ,
|
||||
.Fl L
|
||||
and
|
||||
.Fl P
|
||||
options are ignored unless the
|
||||
.Fl R
|
||||
option is specified.
|
||||
In addition, these options override each other and the
|
||||
command's actions are determined by the last one specified.
|
||||
.Pp
|
||||
The
|
||||
.Ar owner
|
||||
and
|
||||
@ -84,9 +123,6 @@ group name.
|
||||
The ownership of a file may only be altered by a super-user for
|
||||
obvious security reasons.
|
||||
.Pp
|
||||
The owner and group of symbolic links are themselves changed instead
|
||||
of the file to which the link points.
|
||||
.Pp
|
||||
The
|
||||
.Nm chown
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
@ -96,12 +132,19 @@ Previous versions of the
|
||||
utility used the dot (``.'') character to distinguish the group name.
|
||||
This has been changed to be a colon (``:'') character so that user and
|
||||
group names may contain the dot character.
|
||||
.Pp
|
||||
Previous versions of the
|
||||
.Nm chown
|
||||
utility changed the owner of symbolic links specified on the command
|
||||
line.
|
||||
In this system, symbolic links do not have owners.
|
||||
.Sh SEE ALSO
|
||||
.Xr chgrp 1 ,
|
||||
.Xr find 1 ,
|
||||
.Xr chown 2
|
||||
.Xr chown 2 ,
|
||||
.Xr fts 3 ,
|
||||
.Xr symlink 7
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm chown
|
||||
command is expected to conform to
|
||||
.St -p1003.2-92 .
|
||||
command is expected to be POSIX 1003.2 compliant.
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1988, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,53 +32,86 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1988 Regents of the University of California.\n\
|
||||
All rights reserved.\n";
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1988, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)chown.c 5.18 (Berkeley) 3/9/91";*/
|
||||
static char rcsid[] = "$Id: chown.c,v 1.4 1994/04/01 01:19:08 jtc Exp $";
|
||||
/* from: static char sccsid[] = "@(#)chown.c 8.8 (Berkeley) 4/4/94"; */
|
||||
static char *rcsid = "$Id: chown.c,v 1.5 1994/06/18 20:55:58 cgd Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/errno.h>
|
||||
#include <dirent.h>
|
||||
#include <fts.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fts.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int ischown, uid, gid, fflag, rflag, retval;
|
||||
void a_gid __P((char *));
|
||||
void a_uid __P((char *));
|
||||
void chownerr __P((char *));
|
||||
u_long id __P((char *, char *));
|
||||
void usage __P((void));
|
||||
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int Rflag, ischown, fflag;
|
||||
char *gname, *myname;
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
char *argv[];
|
||||
{
|
||||
extern int optind;
|
||||
register FTS *fts;
|
||||
register FTSENT *p;
|
||||
register char *cp;
|
||||
int ch;
|
||||
|
||||
FTS *ftsp;
|
||||
FTSENT *p;
|
||||
int Hflag, Lflag, Pflag, ch, fts_options, hflag, rval;
|
||||
char *cp;
|
||||
|
||||
myname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
|
||||
ischown = myname[2] == 'o';
|
||||
|
||||
while ((ch = getopt(argc, argv, "Rf")) != -1)
|
||||
switch((char)ch) {
|
||||
|
||||
Hflag = Lflag = Pflag = hflag = 0;
|
||||
while ((ch = getopt(argc, argv, "HLPRfh")) != EOF)
|
||||
switch (ch) {
|
||||
case 'H':
|
||||
Hflag = 1;
|
||||
Lflag = Pflag = 0;
|
||||
break;
|
||||
case 'L':
|
||||
Lflag = 1;
|
||||
Hflag = Pflag = 0;
|
||||
break;
|
||||
case 'P':
|
||||
Pflag = 1;
|
||||
Hflag = Lflag = 0;
|
||||
break;
|
||||
case 'R':
|
||||
rflag = 1;
|
||||
Rflag = 1;
|
||||
break;
|
||||
case 'f':
|
||||
fflag = 1;
|
||||
break;
|
||||
case 'h':
|
||||
/*
|
||||
* In System V (and probably POSIX.2) the -h option
|
||||
* causes chown/chgrp to change the owner/group of
|
||||
* the symbolic link. 4.4BSD's symbolic links don't
|
||||
* have owners/groups, so it's an undocumented noop.
|
||||
* Do syntax checking, though.
|
||||
*/
|
||||
hflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
@ -89,136 +122,153 @@ main(argc, argv)
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
fts_options = FTS_PHYSICAL;
|
||||
if (Rflag) {
|
||||
if (hflag)
|
||||
errx(1,
|
||||
"the -R and -h options may not be specified together.");
|
||||
if (Hflag)
|
||||
fts_options |= FTS_COMFOLLOW;
|
||||
if (Lflag) {
|
||||
fts_options &= ~FTS_PHYSICAL;
|
||||
fts_options |= FTS_LOGICAL;
|
||||
}
|
||||
}
|
||||
|
||||
uid = gid = -1;
|
||||
if (ischown) {
|
||||
#ifdef SUPPORT_DOT
|
||||
if (cp = index(*argv, '.')) {
|
||||
if ((cp = strchr(*argv, '.')) != NULL) {
|
||||
*cp++ = '\0';
|
||||
a_gid(cp);
|
||||
} else
|
||||
#endif
|
||||
if (cp = index(*argv, ':')) {
|
||||
if ((cp = strchr(*argv, ':')) != NULL) {
|
||||
*cp++ = '\0';
|
||||
a_gid(cp);
|
||||
}
|
||||
a_uid(*argv);
|
||||
}
|
||||
else
|
||||
} else
|
||||
a_gid(*argv);
|
||||
|
||||
if (rflag) {
|
||||
if (!(fts = fts_open(++argv, FTS_NOSTAT|FTS_PHYSICAL, 0))) {
|
||||
(void)fprintf(stderr,
|
||||
"%s: %s.\n", myname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
while (p = fts_read(fts)) {
|
||||
if (p->fts_info == FTS_D)
|
||||
if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
|
||||
switch (p->fts_info) {
|
||||
case FTS_D:
|
||||
if (Rflag) /* Change it at FTS_DP. */
|
||||
continue;
|
||||
if (p->fts_info == FTS_ERR) {
|
||||
error(p->fts_path);
|
||||
continue;
|
||||
}
|
||||
if (chown(p->fts_accpath, uid, gid) && !fflag)
|
||||
chownerr(p->fts_path);
|
||||
fts_set(ftsp, p, FTS_SKIP);
|
||||
break;
|
||||
case FTS_DNR: /* Warn, chown, continue. */
|
||||
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||
rval = 1;
|
||||
break;
|
||||
case FTS_ERR: /* Warn, continue. */
|
||||
case FTS_NS:
|
||||
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||
rval = 1;
|
||||
continue;
|
||||
case FTS_SL: /* Ignore. */
|
||||
case FTS_SLNONE:
|
||||
/*
|
||||
* The only symlinks that end up here are ones that
|
||||
* don't point to anything and ones that we found
|
||||
* doing a physical walk.
|
||||
*/
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (chown(p->fts_accpath, uid, gid) && !fflag) {
|
||||
chownerr(p->fts_path);
|
||||
rval = 1;
|
||||
}
|
||||
exit(retval);
|
||||
}
|
||||
while (*++argv)
|
||||
if (chown(*argv, uid, gid) && !fflag)
|
||||
chownerr(*argv);
|
||||
exit(retval);
|
||||
if (errno)
|
||||
err(1, "fts_read");
|
||||
exit(rval);
|
||||
}
|
||||
|
||||
void
|
||||
a_gid(s)
|
||||
register char *s;
|
||||
char *s;
|
||||
{
|
||||
struct group *gr;
|
||||
|
||||
if (!*s) {
|
||||
gid = -1; /* argument was "uid." */
|
||||
if (*s == '\0') /* Argument was "uid[:.]". */
|
||||
return;
|
||||
}
|
||||
gname = s;
|
||||
if (gr = getgrnam(s))
|
||||
gid = gr->gr_gid;
|
||||
else {
|
||||
for (; *s && isdigit(*s); ++s);
|
||||
if (!*s)
|
||||
gid = atoi(gname);
|
||||
else {
|
||||
(void)fprintf(stderr, "%s: unknown group id: %s\n",
|
||||
myname, gname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
gid = ((gr = getgrnam(s)) == NULL) ? id(s, "group") : gr->gr_gid;
|
||||
}
|
||||
|
||||
void
|
||||
a_uid(s)
|
||||
register char *s;
|
||||
char *s;
|
||||
{
|
||||
struct passwd *pw;
|
||||
char *uname;
|
||||
|
||||
if (!*s) {
|
||||
uid = -1; /* argument was ".gid" */
|
||||
if (*s == '\0') /* Argument was "[:.]gid". */
|
||||
return;
|
||||
}
|
||||
if (pw = getpwnam(s))
|
||||
uid = pw->pw_uid;
|
||||
else {
|
||||
for (uname = s; *s && isdigit(*s); ++s);
|
||||
if (!*s)
|
||||
uid = atoi(uname);
|
||||
else {
|
||||
(void)fprintf(stderr,
|
||||
"chown: unknown user id: %s\n", uname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
uid = ((pw = getpwnam(s)) == NULL) ? id(s, "user") : pw->pw_uid;
|
||||
}
|
||||
|
||||
u_long
|
||||
id(name, type)
|
||||
char *name, *type;
|
||||
{
|
||||
u_long val;
|
||||
char *ep;
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* We know that uid_t's and gid_t's are unsigned longs.
|
||||
*/
|
||||
errno = 0;
|
||||
val = strtoul(name, &ep, 10);
|
||||
if (errno)
|
||||
err(1, "%s", name);
|
||||
if (*ep != '\0')
|
||||
errx(1, "%s: illegal %s name", name, type);
|
||||
return (val);
|
||||
}
|
||||
|
||||
void
|
||||
chownerr(file)
|
||||
char *file;
|
||||
{
|
||||
static int euid = -1, ngroups = -1;
|
||||
gid_t groups[NGROUPS];
|
||||
|
||||
/* check for chown without being root */
|
||||
if (errno != EPERM || uid != -1 && euid == -1 && (euid = geteuid())) {
|
||||
/* Check for chown without being root. */
|
||||
if (errno != EPERM ||
|
||||
uid != -1 && euid == -1 && (euid = geteuid()) != 0) {
|
||||
if (fflag)
|
||||
exit(0);
|
||||
error(file);
|
||||
exit(1);
|
||||
err(1, "%s", file);
|
||||
}
|
||||
/* check group membership; kernel just returns EPERM */
|
||||
if (gid != -1 && ngroups == -1) {
|
||||
gid_t groups[NGROUPS];
|
||||
|
||||
/* Check group membership; kernel just returns EPERM. */
|
||||
if (gid != -1 && ngroups == -1) {
|
||||
ngroups = getgroups(NGROUPS, groups);
|
||||
while (--ngroups >= 0 && gid != groups[ngroups]);
|
||||
if (ngroups < 0) {
|
||||
if (fflag)
|
||||
exit(0);
|
||||
(void)fprintf(stderr,
|
||||
"%s: you are not a member of group %s.\n",
|
||||
myname, gname);
|
||||
exit(1);
|
||||
errx(1, "you are not a member of group %s", gname);
|
||||
}
|
||||
}
|
||||
if (!fflag)
|
||||
error(file);
|
||||
}
|
||||
|
||||
error(name)
|
||||
char *name;
|
||||
{
|
||||
(void)fprintf(stderr, "%s: %s: %s\n", myname, name, strerror(errno));
|
||||
retval = 1;
|
||||
|
||||
if (!fflag)
|
||||
warn("%s", file);
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: %s [-Rf] %s file ...\n", myname,
|
||||
ischown ? "[owner][:group]" : "group");
|
||||
(void)fprintf(stderr,
|
||||
"usage: %s [-R [-H | -L | -P]] [-f] %s file ...\n",
|
||||
myname, ischown ? "[owner][:group]" : "group");
|
||||
exit(1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user