View | Details | Raw Unified | Return to bug 18776
Collapse All | Expand All

(-)mv/Makefile (+3 lines)
Lines 2-6 Link Here
2
# $FreeBSD: src/bin/mv/Makefile,v 1.6 2000/01/01 15:40:40 joe Exp $
2
# $FreeBSD: src/bin/mv/Makefile,v 1.6 2000/01/01 15:40:40 joe Exp $
3
3
4
PROG=	mv
4
PROG=	mv
5
SRCS=	mv.c obliterate.c
6
7
.PATH:	${.CURDIR}/../rm
5
8
6
.include <bsd.prog.mk>
9
.include <bsd.prog.mk>
(-)mv/mv.1 (-2 / +7 lines)
Lines 44-54 Link Here
44
.Sh SYNOPSIS
44
.Sh SYNOPSIS
45
.Nm mv
45
.Nm mv
46
.Op Fl f | Fl i
46
.Op Fl f | Fl i
47
.Op Fl v
47
.Op Fl Pv
48
.Ar source target
48
.Ar source target
49
.Nm mv
49
.Nm mv
50
.Op  Fl f | Fl i
50
.Op  Fl f | Fl i
51
.Op Fl v
51
.Op Fl Pv
52
.Ar source ... directory
52
.Ar source ... directory
53
.Sh DESCRIPTION
53
.Sh DESCRIPTION
54
In its first form, the
54
In its first form, the
Lines 97-102 Link Here
97
option overrides any previous
97
option overrides any previous
98
.Fl f
98
.Fl f
99
options.)
99
options.)
100
.It Fl P
101
When moving regular files across a filesystem boundary, overwrite
102
the source files before deleting them.
103
Files are overwritten three times, first with the byte pattern
104
0xff, then 0x00, and then 0xff again, before they are deleted.
100
.It Fl v
105
.It Fl v
101
Cause
106
Cause
102
.Nm
107
.Nm
(-)mv/mv.c (-5 / +13 lines)
Lines 65-75 Link Here
65
65
66
#include "pathnames.h"
66
#include "pathnames.h"
67
67
68
int fflg, iflg, vflg;
68
int Pflg, fflg, iflg, vflg;
69
69
70
int	copy __P((char *, char *));
70
int	copy __P((char *, char *));
71
int	do_move __P((char *, char *));
71
int	do_move __P((char *, char *));
72
int	fastcopy __P((char *, char *, struct stat *));
72
int	fastcopy __P((char *, char *, struct stat *));
73
int	obliterate __P((char *, struct stat *));
73
void	usage __P((void));
74
void	usage __P((void));
74
75
75
int
76
int
Lines 83-90 Link Here
83
	int ch;
84
	int ch;
84
	char path[MAXPATHLEN];
85
	char path[MAXPATHLEN];
85
86
86
	while ((ch = getopt(argc, argv, "fiv")) != -1)
87
	while ((ch = getopt(argc, argv, "Pfiv")) != -1)
87
		switch (ch) {
88
		switch (ch) {
89
		case 'P':
90
			Pflg = 1;
91
			break;
88
		case 'i':
92
		case 'i':
89
			iflg = 1;
93
			iflg = 1;
90
			fflg = 0;
94
			fflg = 0;
Lines 192-197 Link Here
192
			}
196
			}
193
		}
197
		}
194
	}
198
	}
199
195
	if (!rename(from, to)) {
200
	if (!rename(from, to)) {
196
		if (vflg)
201
		if (vflg)
197
			printf("%s -> %s\n", from, to);
202
			printf("%s -> %s\n", from, to);
Lines 302-307 Link Here
302
		return (1);
307
		return (1);
303
	}
308
	}
304
309
310
	if (Pflg && obliterate(from, sbp) == -1)
311
		return 1;
312
305
	if (unlink(from)) {
313
	if (unlink(from)) {
306
		warn("%s: remove", from);
314
		warn("%s: remove", from);
307
		return (1);
315
		return (1);
Lines 336-342 Link Here
336
		return (1);
344
		return (1);
337
	}
345
	}
338
	if (!(pid = vfork())) {
346
	if (!(pid = vfork())) {
339
		execl(_PATH_RM, "mv", "-rf", from, NULL);
347
		execl(_PATH_RM, "mv", Pflg ? "-Prf" : "-rf", from, NULL);
340
		warn("%s", _PATH_RM);
348
		warn("%s", _PATH_RM);
341
		_exit(1);
349
		_exit(1);
342
	}
350
	}
Lines 361-367 Link Here
361
{
369
{
362
370
363
	(void)fprintf(stderr, "%s\n%s\n",
371
	(void)fprintf(stderr, "%s\n%s\n",
364
		      "usage: mv [-f | -i] [-v] source target",
372
		      "usage: mv [-f | -i] [-Pv] source target",
365
		      "       mv [-f | -i] [-v] source ... directory");
373
		      "       mv [-f | -i] [-Pv] source ... directory");
366
	exit(EX_USAGE);
374
	exit(EX_USAGE);
367
}
375
}
(-)rm/Makefile (-1 / +1 lines)
Lines 2-8 Link Here
2
# $FreeBSD: src/bin/rm/Makefile,v 1.12 2000/02/05 18:42:29 joe Exp $
2
# $FreeBSD: src/bin/rm/Makefile,v 1.12 2000/02/05 18:42:29 joe Exp $
3
3
4
PROG=	rm
4
PROG=	rm
5
SRCS=	rm.c setflags.c
5
SRCS=	rm.c setflags.c obliterate.c
6
6
7
LINKS=	${BINDIR}/rm ${BINDIR}/unlink
7
LINKS=	${BINDIR}/rm ${BINDIR}/unlink
8
MLINKS=	rm.1 unlink.1
8
MLINKS=	rm.1 unlink.1
(-)rm/obliterate.c (+121 lines)
Line 0 Link Here
1
/*-
2
 * Copyright (c) 1990, 1993, 1994
3
 *	The Regents of the University of California.  All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. All advertising materials mentioning features or use of this software
14
 *    must display the following acknowledgement:
15
 *	This product includes software developed by the University of
16
 *	California, Berkeley and its contributors.
17
 * 4. Neither the name of the University nor the names of its contributors
18
 *    may be used to endorse or promote products derived from this software
19
 *    without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
 * SUCH DAMAGE.
32
 */
33
34
#ifndef lint
35
static const char copyright[] =
36
"@(#) Copyright (c) 1990, 1993, 1994\n\
37
	The Regents of the University of California.  All rights reserved.\n";
38
#endif /* not lint */
39
40
#ifndef lint
41
#if 0
42
static char sccsid[] = "@(#)rm.c	8.5 (Berkeley) 4/18/94";
43
#else
44
static const char rcsid[] =
45
  "$FreeBSD: src/bin/rm/rm.c,v 1.30 2000/05/01 18:34:36 asmodai Exp $";
46
#endif
47
#endif /* not lint */
48
49
#include <sys/param.h>
50
#include <sys/mount.h>
51
#include <sys/stat.h>
52
53
#include <err.h>
54
#include <fcntl.h>
55
#include <stdlib.h>
56
#include <unistd.h>
57
58
/*
59
 * obliterate --
60
 *	Overwrite the file 3 times with varying bit patterns.
61
 *
62
 * XXX
63
 * This is a cheap way to *really* delete files.  Note that only regular
64
 * files are deleted, directories (and therefore names) will remain.
65
 * Also, this assumes a fixed-block file system (like FFS, or a V7 or a
66
 * System V file system).  In a logging file system, you'll have to have
67
 * kernel support.
68
 */
69
int
70
obliterate(file, sbp)
71
	char *file;
72
	struct stat *sbp;
73
{
74
	struct stat sb;
75
	struct statfs fsb;
76
	off_t len;
77
	int bsize, fd, wlen;
78
	char *buf = NULL;
79
80
	fd = -1;
81
	if (sbp == NULL) {
82
		if (lstat(file, &sb))
83
			goto err;
84
		sbp = &sb;
85
	}
86
	if (!S_ISREG(sbp->st_mode))
87
		return 0;
88
	if ((fd = open(file, O_WRONLY, 0)) == -1)
89
		goto err;
90
	if (fstatfs(fd, &fsb) == -1)
91
		goto err;
92
	bsize = MAX(fsb.f_iosize, 1024);
93
	if ((buf = malloc(bsize)) == NULL)
94
		err(1, "malloc");
95
96
#define	PASS(byte) {							\
97
	memset(buf, byte, bsize);					\
98
	for (len = sbp->st_size; len > 0; len -= wlen) {		\
99
		wlen = len < bsize ? len : bsize;			\
100
		if (write(fd, buf, wlen) != wlen)			\
101
			goto err;					\
102
	}								\
103
}
104
	PASS(0xff);
105
	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
106
		goto err;
107
	PASS(0x00);
108
	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
109
		goto err;
110
	PASS(0xff);
111
	if (!fsync(fd) && !close(fd)) {
112
		free(buf);
113
		return 0;
114
	}
115
116
err:	if (buf)
117
		free(buf);
118
	warn("%s", file);
119
	return -1;
120
}
121
(-)rm/rm.c (-67 / +6 lines)
Lines 67-74 Link Here
67
67
68
int	check __P((char *, char *, struct stat *));
68
int	check __P((char *, char *, struct stat *));
69
void	checkdot __P((char **));
69
void	checkdot __P((char **));
70
int	obliterate __P((char *, struct stat *));
70
void	rm_file __P((char **));
71
void	rm_file __P((char **));
71
void	rm_overwrite __P((char *, struct stat *));
72
void	rm_tree __P((char **));
72
void	rm_tree __P((char **));
73
void	usage __P((void));
73
void	usage __P((void));
74
74
Lines 272-278 Link Here
272
272
273
			default:
273
			default:
274
				if (Pflag)
274
				if (Pflag)
275
					rm_overwrite(p->fts_accpath, NULL);
275
					if (obliterate(p->fts_accpath,
276
					    NULL) == -1)
277
						eval = 1;
276
				rval = unlink(p->fts_accpath);
278
				rval = unlink(p->fts_accpath);
277
				if (rval == 0 || (fflag && errno == ENOENT)) {
279
				if (rval == 0 || (fflag && errno == ENOENT)) {
278
					if (rval == 0 && vflag)
280
					if (rval == 0 && vflag)
Lines 339-345 Link Here
339
				rval = rmdir(f);
341
				rval = rmdir(f);
340
			else {
342
			else {
341
				if (Pflag)
343
				if (Pflag)
342
					rm_overwrite(f, &sb);
344
					if (obliterate(f, &sb) == -1)
345
						eval = 1;
343
				rval = unlink(f);
346
				rval = unlink(f);
344
			}
347
			}
345
		}
348
		}
Lines 350-419 Link Here
350
		if (vflag && rval == 0)
353
		if (vflag && rval == 0)
351
			(void)printf("%s\n", f);
354
			(void)printf("%s\n", f);
352
	}
355
	}
353
}
354
355
/*
356
 * rm_overwrite --
357
 *	Overwrite the file 3 times with varying bit patterns.
358
 *
359
 * XXX
360
 * This is a cheap way to *really* delete files.  Note that only regular
361
 * files are deleted, directories (and therefore names) will remain.
362
 * Also, this assumes a fixed-block file system (like FFS, or a V7 or a
363
 * System V file system).  In a logging file system, you'll have to have
364
 * kernel support.
365
 */
366
void
367
rm_overwrite(file, sbp)
368
	char *file;
369
	struct stat *sbp;
370
{
371
	struct stat sb;
372
	struct statfs fsb;
373
	off_t len;
374
	int bsize, fd, wlen;
375
	char *buf = NULL;
376
377
	fd = -1;
378
	if (sbp == NULL) {
379
		if (lstat(file, &sb))
380
			goto err;
381
		sbp = &sb;
382
	}
383
	if (!S_ISREG(sbp->st_mode))
384
		return;
385
	if ((fd = open(file, O_WRONLY, 0)) == -1)
386
		goto err;
387
	if (fstatfs(fd, &fsb) == -1)
388
		goto err;
389
	bsize = MAX(fsb.f_iosize, 1024);
390
	if ((buf = malloc(bsize)) == NULL)
391
		err(1, "malloc");
392
393
#define	PASS(byte) {							\
394
	memset(buf, byte, bsize);					\
395
	for (len = sbp->st_size; len > 0; len -= wlen) {		\
396
		wlen = len < bsize ? len : bsize;			\
397
		if (write(fd, buf, wlen) != wlen)			\
398
			goto err;					\
399
	}								\
400
}
401
	PASS(0xff);
402
	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
403
		goto err;
404
	PASS(0x00);
405
	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
406
		goto err;
407
	PASS(0xff);
408
	if (!fsync(fd) && !close(fd)) {
409
		free(buf);
410
		return;
411
	}
412
413
err:	eval = 1;
414
	if (buf)
415
		free(buf);
416
	warn("%s", file);
417
}
356
}

Return to bug 18776