Merge Lite2 mods, and -Wall cleaning. Unimplemented undelete(2)
cruft is protected by a #ifdef (BSD4_4_LITE) that should be removed when this is supported by the kernel.
This commit is contained in:
parent
78b09ffeaf
commit
1f64b5c98e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=20421
19
bin/rm/rm.1
19
bin/rm/rm.1
@ -32,10 +32,10 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)rm.1 8.2 (Berkeley) 4/18/94
|
||||
.\" $Id: rm.1,v 1.3 1996/03/07 23:26:58 wosch Exp $
|
||||
.\" @(#)rm.1 8.5 (Berkeley) 12/5/94
|
||||
.\" $Id: rm.1,v 1.4 1996/08/29 18:06:07 wosch Exp $
|
||||
.\"
|
||||
.Dd April 18, 1994
|
||||
.Dd December 5, 1994
|
||||
.Dt RM 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -44,7 +44,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm rm
|
||||
.Op Fl f | Fl i
|
||||
.Op Fl dPRr
|
||||
.Op Fl dPRrW
|
||||
.Ar file ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
@ -100,6 +100,10 @@ that directory is skipped.
|
||||
.It Fl r
|
||||
Equivalent to
|
||||
.Fl R .
|
||||
.It Fl W
|
||||
Attempts to undelete the named files.
|
||||
Currently, this option can only be used to recover
|
||||
files covered by whiteouts. (UNIMPLEMENTED)
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
@ -135,6 +139,7 @@ Example:
|
||||
``$ rm -- -filename''.
|
||||
.Sh SEE ALSO
|
||||
.Xr rmdir 1 ,
|
||||
.Xr undelete 2 ,
|
||||
.Xr unlink 2 ,
|
||||
.Xr fts 3 ,
|
||||
.Xr getopt 3 ,
|
||||
@ -147,6 +152,12 @@ system.
|
||||
UFS is a fixed-block file system, LFS is not.
|
||||
In addition, only regular files are overwritten, other types of files
|
||||
are not.
|
||||
.Pp
|
||||
No support exists for the
|
||||
.Xr undelete 2
|
||||
call in the kernel, so the
|
||||
.Fl W
|
||||
option is not yet implemented.
|
||||
.Sh COMPATIBILITY
|
||||
The
|
||||
.Nm rm
|
||||
|
132
bin/rm/rm.c
132
bin/rm/rm.c
@ -30,17 +30,17 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: rm.c,v 1.10 1996/02/19 05:57:22 pst Exp $
|
||||
* $Id: rm.c,v 1.11 1996/03/07 23:26:59 wosch Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
static char const copyright[] =
|
||||
"@(#) Copyright (c) 1990, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)rm.c 8.5 (Berkeley) 4/18/94";
|
||||
static char const sccsid[] = "@(#)rm.c 8.5 (Berkeley) 4/18/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -55,9 +55,19 @@ static char sccsid[] = "@(#)rm.c 8.5 (Berkeley) 4/18/94";
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* XXX Until we get kernel support for the undelete(2) system call,
|
||||
* this define *must* remain in place.
|
||||
*/
|
||||
#define BSD4_4_LITE
|
||||
|
||||
extern char *flags_to_string __P((u_long, char *));
|
||||
|
||||
#ifdef BSD4_4_LITE
|
||||
int dflag, eval, fflag, iflag, Pflag, stdin_ok;
|
||||
#else
|
||||
int dflag, eval, fflag, iflag, Pflag, Wflag, stdin_ok;
|
||||
#endif
|
||||
uid_t uid;
|
||||
|
||||
int check __P((char *, char *, struct stat *));
|
||||
@ -81,8 +91,12 @@ main(argc, argv)
|
||||
{
|
||||
int ch, rflag;
|
||||
|
||||
rflag = 0;
|
||||
Pflag = rflag = 0;
|
||||
#ifdef BSD4_4_LITE
|
||||
while ((ch = getopt(argc, argv, "dfiPRr")) != EOF)
|
||||
#else
|
||||
while ((ch = getopt(argc, argv, "dfiPRrW")) != EOF)
|
||||
#endif
|
||||
switch(ch) {
|
||||
case 'd':
|
||||
dflag = 1;
|
||||
@ -102,6 +116,11 @@ main(argc, argv)
|
||||
case 'r': /* Compatibility. */
|
||||
rflag = 1;
|
||||
break;
|
||||
#ifndef BSD4_4_LITE
|
||||
case 'W':
|
||||
Wflag = 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
@ -112,16 +131,17 @@ main(argc, argv)
|
||||
usage();
|
||||
|
||||
checkdot(argv);
|
||||
if (!*argv)
|
||||
exit (eval);
|
||||
|
||||
stdin_ok = isatty(STDIN_FILENO);
|
||||
uid = geteuid();
|
||||
|
||||
if (rflag)
|
||||
rm_tree(argv);
|
||||
else
|
||||
rm_file(argv);
|
||||
if (*argv) {
|
||||
stdin_ok = isatty(STDIN_FILENO);
|
||||
|
||||
if (rflag)
|
||||
rm_tree(argv);
|
||||
else
|
||||
rm_file(argv);
|
||||
}
|
||||
|
||||
exit (eval);
|
||||
}
|
||||
|
||||
@ -132,13 +152,14 @@ rm_tree(argv)
|
||||
FTS *fts;
|
||||
FTSENT *p;
|
||||
int needstat;
|
||||
int flags;
|
||||
int rval;
|
||||
|
||||
/*
|
||||
* Remove a file hierarchy. If forcing removal (-f), or interactive
|
||||
* (-i) or can't ask anyway (stdin_ok), don't stat the file.
|
||||
*/
|
||||
needstat = !uid || !fflag && !iflag && stdin_ok;
|
||||
needstat = !uid || (!fflag && !iflag && stdin_ok);
|
||||
|
||||
/*
|
||||
* If the -i option is specified, the user can skip on the pre-order
|
||||
@ -146,9 +167,14 @@ rm_tree(argv)
|
||||
*/
|
||||
#define SKIPPED 1
|
||||
|
||||
if (!(fts = fts_open(argv,
|
||||
needstat ? FTS_PHYSICAL|FTS_NOCHDIR :
|
||||
FTS_PHYSICAL|FTS_NOSTAT|FTS_NOCHDIR, (int (*)())NULL)))
|
||||
flags = FTS_PHYSICAL | FTS_NOCHDIR;
|
||||
if (!needstat)
|
||||
flags |= FTS_NOSTAT;
|
||||
#ifndef BSD4_4_LITE
|
||||
if (Wflag)
|
||||
flags |= FTS_WHITEOUT;
|
||||
#endif
|
||||
if (!(fts = fts_open(argv, flags, (int (*)())NULL)))
|
||||
err(1, NULL);
|
||||
while ((p = fts_read(fts)) != NULL) {
|
||||
switch (p->fts_info) {
|
||||
@ -176,7 +202,7 @@ rm_tree(argv)
|
||||
continue;
|
||||
case FTS_D:
|
||||
/* Pre-order: give user chance to skip. */
|
||||
if (iflag && !check(p->fts_path, p->fts_accpath,
|
||||
if (!fflag && !check(p->fts_path, p->fts_accpath,
|
||||
p->fts_statp)) {
|
||||
(void)fts_set(fts, p, FTS_SKIP);
|
||||
p->fts_number = SKIPPED;
|
||||
@ -193,10 +219,11 @@ rm_tree(argv)
|
||||
if (p->fts_number == SKIPPED)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
if (!fflag &&
|
||||
!check(p->fts_path, p->fts_accpath, p->fts_statp))
|
||||
continue;
|
||||
}
|
||||
if (!fflag &&
|
||||
!check(p->fts_path, p->fts_accpath, p->fts_statp))
|
||||
continue;
|
||||
|
||||
rval = 0;
|
||||
if (!uid &&
|
||||
@ -210,15 +237,22 @@ rm_tree(argv)
|
||||
* able to remove it. Don't print out the un{read,search}able
|
||||
* message unless the remove fails.
|
||||
*/
|
||||
if (p->fts_info == FTS_DP || p->fts_info == FTS_DNR) {
|
||||
if (!rmdir(p->fts_accpath))
|
||||
switch (p->fts_info) {
|
||||
case FTS_DP:
|
||||
case FTS_DNR:
|
||||
if (!rmdir(p->fts_accpath) || (fflag && errno == ENOENT))
|
||||
continue;
|
||||
if (errno == ENOENT) {
|
||||
if (fflag)
|
||||
continue;
|
||||
} else if (p->fts_info != FTS_DP)
|
||||
warnx("%s: unable to read", p->fts_path);
|
||||
} else {
|
||||
break;
|
||||
|
||||
#ifndef BSD4_4_LITE
|
||||
case FTS_W:
|
||||
if (!undelete(p->fts_accpath) ||
|
||||
fflag && errno == ENOENT)
|
||||
continue;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
if (Pflag)
|
||||
rm_overwrite(p->fts_accpath, NULL);
|
||||
if (!unlink(p->fts_accpath) || (fflag && errno == ENOENT))
|
||||
@ -238,10 +272,9 @@ rm_file(argv)
|
||||
char **argv;
|
||||
{
|
||||
struct stat sb;
|
||||
int df, rval;
|
||||
int rval;
|
||||
char *f;
|
||||
|
||||
df = dflag;
|
||||
/*
|
||||
* Remove a file. POSIX 1003.2 states that, by default, attempting
|
||||
* to remove a directory is an error, so must always stat the file.
|
||||
@ -249,18 +282,38 @@ rm_file(argv)
|
||||
while ((f = *argv++) != NULL) {
|
||||
/* Assume if can't stat the file, can't unlink it. */
|
||||
if (lstat(f, &sb)) {
|
||||
#ifdef BSD4_4_LITE
|
||||
if (!fflag || errno != ENOENT) {
|
||||
warn("%s", f);
|
||||
eval = 1;
|
||||
}
|
||||
#else
|
||||
if (Wflag) {
|
||||
sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR;
|
||||
} else {
|
||||
if (!fflag || errno != ENOENT) {
|
||||
warn("%s", f);
|
||||
eval = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else if (Wflag) {
|
||||
warnx("%s: %s", f, strerror(EEXIST));
|
||||
eval = 1;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
if (S_ISDIR(sb.st_mode) && !df) {
|
||||
|
||||
if (S_ISDIR(sb.st_mode) && !dflag) {
|
||||
warnx("%s: is a directory", f);
|
||||
eval = 1;
|
||||
continue;
|
||||
}
|
||||
#ifdef BSD4_4_LITE
|
||||
if (!fflag && !check(f, f, &sb))
|
||||
#else
|
||||
if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb))
|
||||
#endif
|
||||
continue;
|
||||
rval = 0;
|
||||
if (!uid &&
|
||||
@ -268,7 +321,13 @@ rm_file(argv)
|
||||
!(sb.st_flags & (SF_APPEND|SF_IMMUTABLE)))
|
||||
rval = chflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE));
|
||||
if (!rval) {
|
||||
#ifdef BSD4_4_LITE
|
||||
if (S_ISDIR(sb.st_mode))
|
||||
#else
|
||||
if (S_ISWHT(sb.st_mode))
|
||||
rval = undelete(f);
|
||||
else if (S_ISDIR(sb.st_mode))
|
||||
#endif
|
||||
rval = rmdir(f);
|
||||
else {
|
||||
if (Pflag)
|
||||
@ -357,9 +416,9 @@ check(path, name, sp)
|
||||
* first because we may not have stat'ed the file.
|
||||
*/
|
||||
if (!stdin_ok || S_ISLNK(sp->st_mode) ||
|
||||
!access(name, W_OK) &&
|
||||
(!access(name, W_OK) &&
|
||||
!(sp->st_flags & (SF_APPEND|SF_IMMUTABLE)) &&
|
||||
(!(sp->st_flags & (UF_APPEND|UF_IMMUTABLE)) || !uid))
|
||||
(!(sp->st_flags & (UF_APPEND|UF_IMMUTABLE)) || !uid)))
|
||||
return (1);
|
||||
strmode(sp->st_mode, modep);
|
||||
strcpy(flagsp, flags_to_string(sp->st_flags, NULL));
|
||||
@ -398,7 +457,8 @@ checkdot(argv)
|
||||
if (!complained++)
|
||||
warnx("\".\" and \"..\" may not be removed");
|
||||
eval = 1;
|
||||
for (save = t; (t[0] = t[1]) != NULL; ++t);
|
||||
for (save = t; (t[0] = t[1]) != NULL; ++t)
|
||||
continue;
|
||||
t = save;
|
||||
} else
|
||||
++t;
|
||||
@ -409,6 +469,10 @@ void
|
||||
usage()
|
||||
{
|
||||
|
||||
#ifdef BSD4_4_LITE
|
||||
(void)fprintf(stderr, "usage: rm [-f | -i] [-dPRr] file ...\n");
|
||||
#else
|
||||
(void)fprintf(stderr, "usage: rm [-f | -i] [-dPRrW] file ...\n");
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user