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>