GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/clri/clri.c Lines: 0 50 0.0 %
Date: 2016-12-06 Branches: 0 38 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: clri.c,v 1.19 2016/03/07 21:47:04 natano Exp $	*/
2
/*	$NetBSD: clri.c,v 1.19 2005/01/20 15:50:47 xtraeme Exp $	*/
3
4
/*
5
 * Copyright (c) 1990, 1993
6
 *	The Regents of the University of California.  All rights reserved.
7
 *
8
 * This code is derived from software contributed to Berkeley by
9
 * Rich $alz of BBN Inc.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions and the following disclaimer.
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in the
18
 *    documentation and/or other materials provided with the distribution.
19
 * 3. Neither the name of the University nor the names of its contributors
20
 *    may be used to endorse or promote products derived from this software
21
 *    without specific prior written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
 * SUCH DAMAGE.
34
 */
35
36
#include <sys/param.h>	/* MAXBSIZE DEV_BSIZE */
37
38
#include <ufs/ufs/dinode.h>
39
#include <ufs/ffs/fs.h>
40
41
#include <err.h>
42
#include <fcntl.h>
43
#include <stdlib.h>
44
#include <string.h>
45
#include <stdio.h>
46
#include <unistd.h>
47
#include <util.h>
48
49
/*
50
 * Possible superblock locations ordered from most to least likely.
51
 */
52
static int sblock_try[] = SBLOCKSEARCH;
53
54
static void
55
usage(void)
56
{
57
	(void)fprintf(stderr, "usage: clri special_device inode_number ...\n");
58
	exit(1);
59
}
60
61
int
62
main(int argc, char *argv[])
63
{
64
	struct ufs1_dinode *dp1;
65
	struct ufs2_dinode *dp2;
66
	struct fs *sbp;
67
	char *ibuf[MAXBSIZE];
68
	char *fs, sblock[SBLOCKSIZE];
69
	size_t bsize;
70
	off_t offset;
71
	int i, fd, imax, inonum;
72
73
	if (argc < 3)
74
		usage();
75
76
	fs = *++argv;
77
	sbp = NULL;
78
79
	/* get the superblock. */
80
	if ((fd = opendev(fs, O_RDWR, 0, NULL)) < 0)
81
		err(1, "%s", fs);
82
83
	if (pledge("stdio rpath cpath wpath", NULL) == -1)
84
		err(1, "pledge");
85
86
	for (i = 0; sblock_try[i] != -1; i++) {
87
		offset = (off_t)(sblock_try[i]);
88
		if (pread(fd, sblock, sizeof(sblock), offset) != sizeof(sblock))
89
			err(1, "%s: can't read superblock", fs);
90
		sbp = (struct fs *)sblock;
91
		if ((sbp->fs_magic == FS_UFS1_MAGIC ||
92
		     (sbp->fs_magic == FS_UFS2_MAGIC &&
93
		      sbp->fs_sblockloc == sblock_try[i])) &&
94
		    sbp->fs_bsize <= MAXBSIZE &&
95
		    sbp->fs_bsize >= (int)sizeof(struct fs))
96
			break;
97
	}
98
	if (sblock_try[i] == -1)
99
		errx(2, "cannot find file system superblock");
100
	bsize = sbp->fs_bsize;
101
102
	/* check that inode numbers are valid */
103
	imax = sbp->fs_ncg * sbp->fs_ipg;
104
	for (i = 1; i < (argc - 1); i++) {
105
		const char *errstr;
106
		strtonum(argv[i], 1, imax, &errstr);
107
		if (errstr)
108
			errx(1, "%s is not a valid inode number: %s", argv[i], errstr);
109
	}
110
111
	/* clear the clean flag in the superblock */
112
	if (sbp->fs_inodefmt >= FS_44INODEFMT) {
113
		sbp->fs_clean = 0;
114
		if (pwrite(fd, sblock, sizeof(sblock), offset) != sizeof(sblock))
115
			err(1, "%s: can't update superblock", fs);
116
		(void)fsync(fd);
117
	}
118
119
	/* remaining arguments are inode numbers. */
120
	while (*++argv) {
121
		/* get the inode number. */
122
		inonum = strtonum(*argv, 1, imax, NULL);
123
		(void)printf("clearing %u\n", inonum);
124
125
		/* read in the appropriate block. */
126
		offset = ino_to_fsba(sbp, inonum);	/* inode to fs blk */
127
		offset = fsbtodb(sbp, offset);		/* fs blk disk blk */
128
		offset *= DEV_BSIZE;			/* disk blk to bytes */
129
130
		/* seek and read the block */
131
		if (pread(fd, ibuf, bsize, offset) != bsize)
132
			err(1, "%s", fs);
133
134
		if (sbp->fs_magic == FS_UFS2_MAGIC) {
135
			/* get the inode within the block. */
136
			dp2 = &(((struct ufs2_dinode *)ibuf)
137
			    [ino_to_fsbo(sbp, inonum)]);
138
139
			/* clear the inode, and bump the generation count. */
140
			memset(dp2, 0, sizeof(*dp2));
141
			dp2->di_gen = arc4random();
142
		} else {
143
			/* get the inode within the block. */
144
			dp1 = &(((struct ufs1_dinode *)ibuf)
145
			    [ino_to_fsbo(sbp, inonum)]);
146
147
			/* clear the inode, and bump the generation count. */
148
			memset(dp1, 0, sizeof(*dp1));
149
			dp1->di_gen = arc4random();
150
		}
151
152
		/* backup and write the block */
153
		if (pwrite(fd, ibuf, bsize, offset) != bsize)
154
			err(1, "%s", fs);
155
		(void)fsync(fd);
156
	}
157
	(void)close(fd);
158
	exit(0);
159
}