Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 May 2000 11:26:33 -0500 (EST)
From:      ajk@iu.edu
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/18776: [PATCH] Add rm -P functionality to mv
Message-ID:  <200005231626.LAA17175@verbal.uits.iupui.edu>

next in thread | raw e-mail | index | archive | help

>Number:         18776
>Category:       bin
>Synopsis:       [PATCH] Add rm -P functionality to mv
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 23 09:30:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Andrew J. Korty
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
Office of the VP of Information Technology, Indiana University
>Environment:

FreeBSD verbal.uits.iupui.edu 5.0-CURRENT FreeBSD 5.0-CURRENT #1:
Mon Apr 24 20:16:01 EST 2000
ajk@verbal.uits.iupui.edu:/usr/src/sys/compile/KUJAN  i386

>Description:

Add a -P option to the mv command to overwrite the source files
before deleting them when moving across a filesystem boundary.  As
with the rm command, files are overwritten three times, first with
the byte pattern 0xff, then 0x00, and then 0xff again, before they
are deleted.

Note that only source files are overwritten.  We could overwrite
to-be-clobbered destination files as well, but we would have to
change the cp command, which already has a -P option.  Discussion?

>How-To-Repeat:

Apply the patch below.

>Fix:

This patch breaks out the rm_overwrite() function from rm.c, renaming
it obliterate(), and makes the necessary changes for both commands
to call obliterate().

diff -Nu mv/Makefile.orig mv/Makefile
--- mv/Makefile.orig	Sat Jan  1 10:40:40 2000
+++ mv/Makefile	Tue May 23 09:52:54 2000
@@ -2,5 +2,8 @@
 # $FreeBSD: src/bin/mv/Makefile,v 1.6 2000/01/01 15:40:40 joe Exp $
 
 PROG=	mv
+SRCS=	mv.c obliterate.c
+
+.PATH:	${.CURDIR}/../rm
 
 .include <bsd.prog.mk>
diff -Nu mv/mv.1.orig mv/mv.1
--- mv/mv.1.orig	Fri Sep  3 22:33:18 1999
+++ mv/mv.1	Tue May 23 10:41:21 2000
@@ -44,11 +44,11 @@
 .Sh SYNOPSIS
 .Nm mv
 .Op Fl f | Fl i
-.Op Fl v
+.Op Fl Pv
 .Ar source target
 .Nm mv
 .Op  Fl f | Fl i
-.Op Fl v
+.Op Fl Pv
 .Ar source ... directory
 .Sh DESCRIPTION
 In its first form, the
@@ -97,6 +97,11 @@
 option overrides any previous
 .Fl f
 options.)
+.It Fl P
+When moving regular files across a filesystem boundary, overwrite
+the source files before deleting them.
+Files are overwritten three times, first with the byte pattern
+0xff, then 0x00, and then 0xff again, before they are deleted.
 .It Fl v
 Cause
 .Nm
diff -Nu mv/mv.c.orig mv/mv.c
--- mv/mv.c.orig	Sun Aug 29 03:21:16 1999
+++ mv/mv.c	Tue May 23 10:39:55 2000
@@ -65,11 +65,12 @@
 
 #include "pathnames.h"
 
-int fflg, iflg, vflg;
+int Pflg, fflg, iflg, vflg;
 
 int	copy __P((char *, char *));
 int	do_move __P((char *, char *));
 int	fastcopy __P((char *, char *, struct stat *));
+int	obliterate __P((char *, struct stat *));
 void	usage __P((void));
 
 int
@@ -83,8 +84,11 @@
 	int ch;
 	char path[MAXPATHLEN];
 
-	while ((ch = getopt(argc, argv, "fiv")) != -1)
+	while ((ch = getopt(argc, argv, "Pfiv")) != -1)
 		switch (ch) {
+		case 'P':
+			Pflg = 1;
+			break;
 		case 'i':
 			iflg = 1;
 			fflg = 0;
@@ -192,6 +196,7 @@
 			}
 		}
 	}
+
 	if (!rename(from, to)) {
 		if (vflg)
 			printf("%s -> %s\n", from, to);
@@ -302,6 +307,9 @@
 		return (1);
 	}
 
+	if (Pflg && obliterate(from, sbp) == -1)
+		return 1;
+
 	if (unlink(from)) {
 		warn("%s: remove", from);
 		return (1);
@@ -336,7 +344,7 @@
 		return (1);
 	}
 	if (!(pid = vfork())) {
-		execl(_PATH_RM, "mv", "-rf", from, NULL);
+		execl(_PATH_RM, "mv", Pflg ? "-Prf" : "-rf", from, NULL);
 		warn("%s", _PATH_RM);
 		_exit(1);
 	}
@@ -361,7 +369,7 @@
 {
 
 	(void)fprintf(stderr, "%s\n%s\n",
-		      "usage: mv [-f | -i] [-v] source target",
-		      "       mv [-f | -i] [-v] source ... directory");
+		      "usage: mv [-f | -i] [-Pv] source target",
+		      "       mv [-f | -i] [-Pv] source ... directory");
 	exit(EX_USAGE);
 }
diff -Nu rm/Makefile.orig rm/Makefile
--- rm/Makefile.orig	Sat Feb  5 13:42:29 2000
+++ rm/Makefile	Tue May 23 09:45:16 2000
@@ -2,7 +2,7 @@
 # $FreeBSD: src/bin/rm/Makefile,v 1.12 2000/02/05 18:42:29 joe Exp $
 
 PROG=	rm
-SRCS=	rm.c setflags.c
+SRCS=	rm.c setflags.c obliterate.c
 
 LINKS=	${BINDIR}/rm ${BINDIR}/unlink
 MLINKS=	rm.1 unlink.1
diff -Nu rm/obliterate.c.orig rm/obliterate.c
--- rm/obliterate.c.orig	Wed Dec 31 19:00:00 1969
+++ rm/obliterate.c	Tue May 23 09:51:52 2000
@@ -0,0 +1,121 @@
+/*-
+ * Copyright (c) 1990, 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1990, 1993, 1994\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rm.c	8.5 (Berkeley) 4/18/94";
+#else
+static const char rcsid[] =
+  "$FreeBSD: src/bin/rm/rm.c,v 1.30 2000/05/01 18:34:36 asmodai Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * obliterate --
+ *	Overwrite the file 3 times with varying bit patterns.
+ *
+ * XXX
+ * This is a cheap way to *really* delete files.  Note that only regular
+ * files are deleted, directories (and therefore names) will remain.
+ * Also, this assumes a fixed-block file system (like FFS, or a V7 or a
+ * System V file system).  In a logging file system, you'll have to have
+ * kernel support.
+ */
+int
+obliterate(file, sbp)
+	char *file;
+	struct stat *sbp;
+{
+	struct stat sb;
+	struct statfs fsb;
+	off_t len;
+	int bsize, fd, wlen;
+	char *buf = NULL;
+
+	fd = -1;
+	if (sbp == NULL) {
+		if (lstat(file, &sb))
+			goto err;
+		sbp = &sb;
+	}
+	if (!S_ISREG(sbp->st_mode))
+		return 0;
+	if ((fd = open(file, O_WRONLY, 0)) == -1)
+		goto err;
+	if (fstatfs(fd, &fsb) == -1)
+		goto err;
+	bsize = MAX(fsb.f_iosize, 1024);
+	if ((buf = malloc(bsize)) == NULL)
+		err(1, "malloc");
+
+#define	PASS(byte) {							\
+	memset(buf, byte, bsize);					\
+	for (len = sbp->st_size; len > 0; len -= wlen) {		\
+		wlen = len < bsize ? len : bsize;			\
+		if (write(fd, buf, wlen) != wlen)			\
+			goto err;					\
+	}								\
+}
+	PASS(0xff);
+	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
+		goto err;
+	PASS(0x00);
+	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
+		goto err;
+	PASS(0xff);
+	if (!fsync(fd) && !close(fd)) {
+		free(buf);
+		return 0;
+	}
+
+err:	if (buf)
+		free(buf);
+	warn("%s", file);
+	return -1;
+}
+
diff -Nu rm/rm.c.orig rm/rm.c
--- rm/rm.c.orig	Mon May  1 13:34:36 2000
+++ rm/rm.c	Tue May 23 09:53:35 2000
@@ -67,8 +67,8 @@
 
 int	check __P((char *, char *, struct stat *));
 void	checkdot __P((char **));
+int	obliterate __P((char *, struct stat *));
 void	rm_file __P((char **));
-void	rm_overwrite __P((char *, struct stat *));
 void	rm_tree __P((char **));
 void	usage __P((void));
 
@@ -272,7 +272,9 @@
 
 			default:
 				if (Pflag)
-					rm_overwrite(p->fts_accpath, NULL);
+					if (obliterate(p->fts_accpath,
+					    NULL) == -1)
+						eval = 1;
 				rval = unlink(p->fts_accpath);
 				if (rval == 0 || (fflag && errno == ENOENT)) {
 					if (rval == 0 && vflag)
@@ -339,7 +341,8 @@
 				rval = rmdir(f);
 			else {
 				if (Pflag)
-					rm_overwrite(f, &sb);
+					if (obliterate(f, &sb) == -1)
+						eval = 1;
 				rval = unlink(f);
 			}
 		}
@@ -350,70 +353,6 @@
 		if (vflag && rval == 0)
 			(void)printf("%s\n", f);
 	}
-}
-
-/*
- * rm_overwrite --
- *	Overwrite the file 3 times with varying bit patterns.
- *
- * XXX
- * This is a cheap way to *really* delete files.  Note that only regular
- * files are deleted, directories (and therefore names) will remain.
- * Also, this assumes a fixed-block file system (like FFS, or a V7 or a
- * System V file system).  In a logging file system, you'll have to have
- * kernel support.
- */
-void
-rm_overwrite(file, sbp)
-	char *file;
-	struct stat *sbp;
-{
-	struct stat sb;
-	struct statfs fsb;
-	off_t len;
-	int bsize, fd, wlen;
-	char *buf = NULL;
-
-	fd = -1;
-	if (sbp == NULL) {
-		if (lstat(file, &sb))
-			goto err;
-		sbp = &sb;
-	}
-	if (!S_ISREG(sbp->st_mode))
-		return;
-	if ((fd = open(file, O_WRONLY, 0)) == -1)
-		goto err;
-	if (fstatfs(fd, &fsb) == -1)
-		goto err;
-	bsize = MAX(fsb.f_iosize, 1024);
-	if ((buf = malloc(bsize)) == NULL)
-		err(1, "malloc");
-
-#define	PASS(byte) {							\
-	memset(buf, byte, bsize);					\
-	for (len = sbp->st_size; len > 0; len -= wlen) {		\
-		wlen = len < bsize ? len : bsize;			\
-		if (write(fd, buf, wlen) != wlen)			\
-			goto err;					\
-	}								\
-}
-	PASS(0xff);
-	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
-		goto err;
-	PASS(0x00);
-	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
-		goto err;
-	PASS(0xff);
-	if (!fsync(fd) && !close(fd)) {
-		free(buf);
-		return;
-	}
-
-err:	eval = 1;
-	if (buf)
-		free(buf);
-	warn("%s", file);
 }
 
 

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200005231626.LAA17175>