From ajk@verbal.uits.iupui.edu  Tue May 23 09:26:37 2000
Return-Path: <ajk@verbal.uits.iupui.edu>
Received: from verbal.uits.iupui.edu (verbal.uits.iupui.edu [149.166.240.10])
	by hub.freebsd.org (Postfix) with ESMTP id 7EF5B37BB50
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 23 May 2000 09:26:35 -0700 (PDT)
	(envelope-from ajk@verbal.uits.iupui.edu)
Received: (from ajk@localhost)
	by verbal.uits.iupui.edu (8.9.3/8.9.3) id LAA17175;
	Tue, 23 May 2000 11:26:33 -0500 (EST)
	(envelope-from ajk)
Message-Id: <200005231626.LAA17175@verbal.uits.iupui.edu>
Date: Tue, 23 May 2000 11:26:33 -0500 (EST)
From: ajk@iu.edu
Sender: ajk@verbal.uits.iupui.edu
Reply-To: ajk@iu.edu
To: FreeBSD-gnats-submit@freebsd.org
Subject: [PATCH] Add rm -P functionality to mv
X-Send-Pr-Version: 3.2

>Number:         18776
>Category:       bin
>Synopsis:       [PATCH] Add rm -P functionality to mv
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 23 09:30:01 PDT 2000
>Closed-Date:    Sat Nov 30 17:21:27 PST 2002
>Last-Modified:  Sat Nov 30 17:21:27 PST 2002
>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:
State-Changed-From-To: open->closed 
State-Changed-By: iedowse 
State-Changed-When: Sat Nov 30 17:07:27 PST 2002 
State-Changed-Why:  

Sorry, there hasn't been any interest in adding this feature, and 
it is of very marginal use anyway. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=18776 
>Unformatted:
