summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2007-05-21 18:13:12 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2007-05-21 18:13:12 +0000
commita4aafbbab023fe1852b260663cef709a5c6627c8 (patch)
tree97a050b84dd7fd3179c72ed896ab26b21eb6ab1c /sbin
parentcc4b0c9b2b77a29e638c8e8ec7082a854fa4edba (diff)
Add ffs2 support. Adapted from the ufs2 changes in FreeBSD and NetBSD.
Diffstat (limited to 'sbin')
-rw-r--r--sbin/clri/clri.c129
1 files changed, 77 insertions, 52 deletions
diff --git a/sbin/clri/clri.c b/sbin/clri/clri.c
index ecf51b86a8a..f0a6dbe6f66 100644
--- a/sbin/clri/clri.c
+++ b/sbin/clri/clri.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: clri.c,v 1.10 2004/01/25 19:18:54 deraadt Exp $ */
-/* $NetBSD: clri.c,v 1.9 1995/03/18 14:54:33 cgd Exp $ */
+/* $OpenBSD: clri.c,v 1.11 2007/05/21 18:13:11 millert Exp $ */
+/* $NetBSD: clri.c,v 1.19 2005/01/20 15:50:47 xtraeme Exp $ */
/*
* Copyright (c) 1990, 1993
@@ -33,71 +33,98 @@
* SUCH DAMAGE.
*/
+#if 0
#ifndef lint
-static char copyright[] =
+static const char copyright[] =
"@(#) Copyright (c) 1990, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
-#if 0
static char sccsid[] = "@(#)clri.c 8.2 (Berkeley) 9/23/93";
-#else
-static char rcsid[] = "$OpenBSD: clri.c,v 1.10 2004/01/25 19:18:54 deraadt Exp $";
-#endif
#endif /* not lint */
+#endif
#include <sys/param.h>
-#include <sys/time.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <err.h>
-#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
+/*
+ * Possible superblock locations ordered from most to least likely.
+ */
+static int sblock_try[] = SBLOCKSEARCH;
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr, "usage: clri special_device inode_number ...\n");
+ exit(1);
+}
+
int
main(int argc, char *argv[])
{
- struct ufs1_dinode ibuf[MAXBSIZE / sizeof (struct ufs1_dinode)];
- char *fs, sblock[SBSIZE];
- struct ufs1_dinode *ip;
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
struct fs *sbp;
- int fd, inonum;
- off_t offset;
+ char *ibuf[MAXBSIZE];
+ char *fs, sblock[SBLOCKSIZE];
size_t bsize;
+ off_t offset;
+ int i, fd, imax, inonum;
- if (argc < 3) {
- fprintf(stderr, "usage: clri filesystem inode ...\n");
- return (1);
- }
+ if (argc < 3)
+ usage();
fs = *++argv;
+ sbp = NULL;
/* get the superblock. */
if ((fd = open(fs, O_RDWR, 0)) < 0)
err(1, "%s", fs);
- if (lseek(fd, (off_t)(SBLOCK * DEV_BSIZE), SEEK_SET) < 0)
- err(1, "%s", fs);
- if (read(fd, sblock, sizeof(sblock)) != sizeof(sblock))
- errx(1, "%s: can't read superblock", fs);
-
- sbp = (struct fs *)sblock;
- if (sbp->fs_magic != FS_MAGIC)
- errx(1, "%s: superblock magic number 0x%x, not 0x%x",
- fs, sbp->fs_magic, FS_MAGIC);
+ for (i = 0; sblock_try[i] != -1; i++) {
+ offset = (off_t)(sblock_try[i]);
+ if (pread(fd, sblock, sizeof(sblock), offset) != sizeof(sblock))
+ err(1, "%s: can't read superblock", fs);
+ sbp = (struct fs *)sblock;
+ if ((sbp->fs_magic == FS_UFS1_MAGIC ||
+ (sbp->fs_magic == FS_UFS2_MAGIC &&
+ sbp->fs_sblockloc == sblock_try[i])) &&
+ sbp->fs_bsize <= MAXBSIZE &&
+ sbp->fs_bsize >= (int)sizeof(struct fs))
+ break;
+ }
+ if (sblock_try[i] == -1)
+ errx(2, "cannot find file system superblock");
bsize = sbp->fs_bsize;
+ /* check that inode numbers are valid */
+ imax = sbp->fs_ncg * sbp->fs_ipg;
+ for (i = 1; i < (argc - 1); i++) {
+ if (atoi(argv[i]) <= 0 || atoi(argv[i]) >= imax)
+ errx(1, "%s is not a valid inode number", argv[i]);
+ }
+
+ /* clear the clean flag in the superblock */
+ if (sbp->fs_inodefmt >= FS_44INODEFMT) {
+ sbp->fs_clean = 0;
+ if (pwrite(fd, sblock, sizeof(sblock), offset) != sizeof(sblock))
+ err(1, "%s: can't update superblock", fs);
+ (void)fsync(fd);
+ }
+
/* remaining arguments are inode numbers. */
while (*++argv) {
/* get the inode number. */
- if ((inonum = atoi(*argv)) <= 0)
- errx(1, "%s is not a valid inode number", *argv);
+ inonum = atoi(*argv);
(void)printf("clearing %d\n", inonum);
/* read in the appropriate block. */
@@ -106,34 +133,32 @@ main(int argc, char *argv[])
offset *= DEV_BSIZE; /* disk blk to bytes */
/* seek and read the block */
- if (lseek(fd, offset, SEEK_SET) < 0)
+ if (pread(fd, ibuf, bsize, offset) != bsize)
err(1, "%s", fs);
- if (read(fd, ibuf, bsize) != bsize)
- err(1, "%s", fs);
-
- /* get the inode within the block. */
- ip = &ibuf[ino_to_fsbo(sbp, inonum)];
- /* clear the inode, and bump the generation count. */
- memset(ip, 0, sizeof(*ip));
- ip->di_gen = arc4random();
+ if (sbp->fs_magic == FS_UFS2_MAGIC) {
+ /* get the inode within the block. */
+ dp2 = &(((struct ufs2_dinode *)ibuf)
+ [ino_to_fsbo(sbp, inonum)]);
+
+ /* clear the inode, and bump the generation count. */
+ memset(dp2, 0, sizeof(*dp2));
+ dp2->di_gen = arc4random();
+ } else {
+ /* get the inode within the block. */
+ dp1 = &(((struct ufs1_dinode *)ibuf)
+ [ino_to_fsbo(sbp, inonum)]);
+
+ /* clear the inode, and bump the generation count. */
+ memset(dp1, 0, sizeof(*dp1));
+ dp1->di_gen = arc4random();
+ }
/* backup and write the block */
- if (lseek(fd, offset, SEEK_SET) < 0)
- err(1, "%s", fs);
- if (write(fd, ibuf, bsize) != bsize)
+ if (pwrite(fd, ibuf, bsize, offset) != bsize)
err(1, "%s", fs);
(void)fsync(fd);
-
- if (sbp->fs_inodefmt >= FS_44INODEFMT) {
- /* update after each inode cleared */
- sbp->fs_clean = 0;
- if (lseek(fd, (off_t)(SBLOCK * DEV_BSIZE), SEEK_SET) < 0)
- err(1, "%s", fs);
- if (write(fd, sblock, sizeof(sblock)) != sizeof(sblock))
- errx(1, "%s: can't update superblock", fs);
- }
}
-
- return close(fd);
+ (void)close(fd);
+ exit(0);
}