xref: /netbsd-src/sbin/fsck_v7fs/fsck_v7fs.c (revision 413d532bcc3f62d122e56d92e13ac64825a40baf)
1 /*	$NetBSD: fsck_v7fs.c,v 1.1 2011/06/27 11:52:58 uch Exp $ */
2 
3 /*-
4  * Copyright (c) 2004, 2011 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by UCHIYAMA Yasushi.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __RCSID("$NetBSD: fsck_v7fs.c,v 1.1 2011/06/27 11:52:58 uch Exp $");
35 #endif /* not lint */
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <fcntl.h>
42 #include <err.h>
43 #include <sys/ioctl.h>
44 #include <sys/disklabel.h>
45 
46 #include <fs/v7fs/v7fs.h>
47 #include "v7fs_impl.h"
48 #include "fsck_v7fs.h"
49 #include "progress.h"
50 
51 static void usage(void) __dead;
52 static void catopt(char **, const char *);
53 
54 enum fsck_operate fsck_operate;
55 bool verbose = true;
56 #define	VPRINTF(fmt, args...)	{ if (verbose) printf(fmt, ##args); }
57 
58 int
59 main(int argc, char **argv)
60 {
61 	const char *device;
62 	struct disklabel d;
63 	struct partition *p;
64 	struct stat st;
65 	int Fflag = 0;
66 	int part;
67 	int fd, ch;
68 	int endian = _BYTE_ORDER;
69 	int openflags = O_RDWR;
70 	size_t part_sectors;
71 	int fsck_flags = 0;
72 	char *options = 0;
73 	bool progress_bar_enable = false;
74 
75 	fsck_operate = ASK;
76 
77 	if (argc < 2)
78 		usage();
79 
80 	while ((ch = getopt(argc, argv, "pPqynfx:dFB:o:")) != -1) {
81 		switch (ch) {
82 			/*
83 			 * generic fsck options
84 			 */
85 		case 'd':	/* Not supported */
86 			break;
87 		case 'f':	/* Always forced */
88 			break;
89 		case 'p':
90 			fsck_operate = PREEN;
91 			break;
92 		case 'y':
93 			fsck_operate = ALWAYS_YES;
94 			break;
95 		case 'n':
96 			fsck_operate = ALWAYS_NO;
97 			openflags = O_RDONLY;
98 			break;
99 		case 'P':
100 			progress_bar_enable = true;
101 			break;
102 		case 'q':	/* Not supported */
103 			break;
104 		case 'x':	/* Not supported */
105 			break;
106 			/*
107 			 * v7fs fsck options
108 			 */
109 		case 'F':
110 			Fflag = 1;
111 			break;
112 		case 'B':
113 			switch (optarg[0]) {
114 			case 'l':
115 				endian = _LITTLE_ENDIAN;
116 				break;
117 			case 'b':
118 				endian = _BIG_ENDIAN;
119 				break;
120 			case 'p':
121 				endian = _PDP_ENDIAN;
122 				break;
123 			}
124 			break;
125 		case 'o': /* datablock, freeblock duplication check */
126 			if (*optarg)
127 				catopt(&options, optarg);
128 			break;
129 		default:
130 			usage();
131 			/*NOTREACHED*/
132 		}
133 	}
134 
135 	argc -= optind;
136 	argv += optind;
137 
138 	if (argc != 1)
139 		usage();
140 	device = argv[0];
141 
142 	if (options) {
143 		if (strstr(options, "data"))
144 			fsck_flags |= V7FS_FSCK_DATABLOCK_DUP;
145 		if (strstr(options, "free"))
146 			fsck_flags |= V7FS_FSCK_FREEBLOCK_DUP;
147 	}
148 
149 	if (Fflag) {
150 		if ((fd = open(device, openflags)) == -1) {
151 			pfatal("%s", device);
152 		}
153 		if (fstat(fd, &st)) {
154 			pfatal("stat");
155 		}
156 		part_sectors = st.st_size >> V7FS_BSHIFT;
157 		setcdevname(device, fsck_operate == PREEN);
158 	} else {
159 		/* blockcheck sets 'hot' */
160 		device = blockcheck(device);
161 		setcdevname(device, fsck_operate == PREEN);
162 
163 		if ((fd = open(device, openflags)) == -1) {
164 			pfatal("%s", device);
165 		}
166 		part = DISKPART(st.st_rdev);
167 
168 		if (ioctl(fd, DIOCGDINFO, &d) == -1) {
169 			pfatal("DIOCGDINFO");
170 		}
171 		p = &d.d_partitions[part];
172 		part_sectors = p->p_size;
173 		VPRINTF("partition=%d size=%d offset=%d fstype=%d secsize=%d\n",
174 		    part, p->p_size, p->p_offset, p->p_fstype, d.d_secsize);
175 		if (p->p_fstype != FS_V7) {
176 			pfatal("not a Version 7 partition.");
177 		}
178 	}
179 
180 	progress_switch(progress_bar_enable);
181 	progress_init();
182 	progress(&(struct progress_arg){ .cdev = device });
183 
184 	struct v7fs_mount_device mount;
185 	mount.device.fd = fd;
186 	mount.endian = endian;
187 	mount.sectors = part_sectors;
188 	int error = v7fs_fsck(&mount, fsck_flags);
189 
190 	close(fd);
191 
192 	return error;
193 }
194 
195 static void
196 catopt(char **sp, const char *o)
197 {
198 	char *s, *n;
199 
200 	s = *sp;
201 	if (s) {
202 		if (asprintf(&n, "%s,%s", s, o) < 0)
203 			err(1, "asprintf");
204 		free(s);
205 		s = n;
206 	} else
207 		s = strdup(o);
208 	*sp = s;
209 }
210 
211 static void
212 usage(void)
213 {
214 
215 	(void)fprintf(stderr, "usage: %s [-ynpP] [-o options] [-B endian] "
216 	    "special-device\n",
217 	    getprogname());
218 	(void)fprintf(stderr, "usage: %s -F [-ynpP] [-o options] [-B endian] "
219 	    "file\n",
220 	    getprogname());
221 
222 	exit(FSCK_EXIT_USAGE);
223 }
224