xref: /netbsd/usr.sbin/vnconfig/vnconfig.c (revision bf9ec67e)
1 /*	$NetBSD: vnconfig.c,v 1.24 2001/12/12 16:55:10 fredette Exp $	*/
2 
3 /*-
4  * Copyright (c) 1997 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe.
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  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the NetBSD
21  *	Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Copyright (c) 1993 University of Utah.
41  * Copyright (c) 1990, 1993
42  *	The Regents of the University of California.  All rights reserved.
43  *
44  * This code is derived from software contributed to Berkeley by
45  * the Systems Programming Group of the University of Utah Computer
46  * Science Department.
47  *
48  * Redistribution and use in source and binary forms, with or without
49  * modification, are permitted provided that the following conditions
50  * are met:
51  * 1. Redistributions of source code must retain the above copyright
52  *    notice, this list of conditions and the following disclaimer.
53  * 2. Redistributions in binary form must reproduce the above copyright
54  *    notice, this list of conditions and the following disclaimer in the
55  *    documentation and/or other materials provided with the distribution.
56  * 3. All advertising materials mentioning features or use of this software
57  *    must display the following acknowledgement:
58  *	This product includes software developed by the University of
59  *	California, Berkeley and its contributors.
60  * 4. Neither the name of the University nor the names of its contributors
61  *    may be used to endorse or promote products derived from this software
62  *    without specific prior written permission.
63  *
64  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74  * SUCH DAMAGE.
75  *
76  * from: Utah $Hdr: vnconfig.c 1.1 93/12/15$
77  *
78  *	@(#)vnconfig.c	8.1 (Berkeley) 12/15/93
79  */
80 
81 #include <sys/param.h>
82 #include <sys/ioctl.h>
83 #include <sys/mount.h>
84 #include <sys/buf.h>
85 #include <sys/disklabel.h>
86 #include <sys/disk.h>
87 
88 #include <dev/vndvar.h>
89 
90 #include <disktab.h>
91 #include <err.h>
92 #include <errno.h>
93 #include <fcntl.h>
94 #include <stdio.h>
95 #include <stdlib.h>
96 #include <string.h>
97 #include <unistd.h>
98 #include <util.h>
99 
100 #define VND_CONFIG	1
101 #define VND_UNCONFIG	2
102 
103 int	verbose = 0;
104 char	*tabname;
105 
106 int	config __P((char *, char *, char *, int));
107 int	getgeom __P((struct vndgeom *, char *));
108 int	main __P((int, char **));
109 char   *rawdevice __P((char *));
110 void	usage __P((void));
111 
112 int
113 main(argc, argv)
114 	int argc;
115 	char *argv[];
116 {
117 	int ch, rv, action = VND_CONFIG;
118 
119 	while ((ch = getopt(argc, argv, "cf:t:uv")) != -1) {
120 		switch (ch) {
121 		case 'c':
122 			action = VND_CONFIG;
123 			break;
124 		case 'f':
125 			if (setdisktab(optarg) == -1)
126 				usage();
127 			break;
128 		case 't':
129 			tabname = optarg;
130 			break;
131 		case 'u':
132 			action = VND_UNCONFIG;
133 			break;
134 		case 'v':
135 			verbose = 1;
136 			break;
137 		default:
138 		case '?':
139 			usage();
140 			/* NOTREACHED */
141 		}
142 	}
143 	argc -= optind;
144 	argv += optind;
145 
146 	if (action == VND_CONFIG) {
147 		if ((argc < 2 || argc > 3) ||
148 		    (argc == 3 && tabname != NULL))
149 			usage();
150 		rv = config(argv[0], argv[1], (argc == 3) ? argv[2] : NULL,
151 		    action);
152 	} else {
153 		if (argc != 1 || tabname != NULL)
154 			usage();
155 		rv = config(argv[0], NULL, NULL, action);
156 	}
157 	exit(rv);
158 }
159 
160 int
161 config(dev, file, geom, action)
162 	char *dev, *file, *geom;
163 	int action;
164 {
165 	struct vnd_ioctl vndio;
166 	struct disklabel *lp;
167 	char rdev[MAXPATHLEN + 1];
168 	int fd, rv;
169 
170 	fd = opendisk(dev, O_RDWR, rdev, sizeof(rdev), 0);
171 	if (fd < 0) {
172 		warn("%s: opendisk", rdev);
173 		return (1);
174 	}
175 
176 	memset(&vndio, 0, sizeof(vndio));
177 #ifdef __GNUC__
178 	rv = 0;			/* XXX */
179 #endif
180 
181 	vndio.vnd_file = file;
182 	if (geom != NULL) {
183 		rv = getgeom(&vndio.vnd_geom, geom);
184 		if (rv != 0)
185 			errx(1, "invalid geometry: %s", geom);
186 		vndio.vnd_flags = VNDIOF_HASGEOM;
187 	} else if (tabname != NULL) {
188 		lp = getdiskbyname(tabname);
189 		if (lp == NULL)
190 			errx(1, "unknown disk type: %s", tabname);
191 		vndio.vnd_geom.vng_secsize = lp->d_secsize;
192 		vndio.vnd_geom.vng_nsectors = lp->d_nsectors;
193 		vndio.vnd_geom.vng_ntracks = lp->d_ntracks;
194 		vndio.vnd_geom.vng_ncylinders = lp->d_ncylinders;
195 		vndio.vnd_flags = VNDIOF_HASGEOM;
196 	}
197 
198 	/*
199 	 * Clear (un-configure) the device
200 	 */
201 	if (action == VND_UNCONFIG) {
202 		rv = ioctl(fd, VNDIOCCLR, &vndio);
203 		if (rv)
204 			warn("%s: VNDIOCCLR", rdev);
205 		else if (verbose)
206 			printf("%s: cleared\n", rdev);
207 	}
208 	/*
209 	 * Configure the device
210 	 */
211 	if (action == VND_CONFIG) {
212 		int	ffd;
213 
214 		ffd = open(file, O_RDWR);
215 		if (ffd < 0)
216 			warn("%s", file);
217 		else {
218 			(void) close(ffd);
219 
220 			rv = ioctl(fd, VNDIOCSET, &vndio);
221 			if (rv)
222 				warn("%s: VNDIOCSET", rdev);
223 			else if (verbose) {
224 				printf("%s: %d bytes on %s", rdev,
225 				    vndio.vnd_size, file);
226 				if (vndio.vnd_flags & VNDIOF_HASGEOM)
227 					printf(" using geometry %d/%d/%d/%d",
228 					    vndio.vnd_geom.vng_secsize,
229 					    vndio.vnd_geom.vng_nsectors,
230 					    vndio.vnd_geom.vng_ntracks,
231 				    vndio.vnd_geom.vng_ncylinders);
232 				printf("\n");
233 			}
234 		}
235 	}
236 
237 	(void) close(fd);
238 	fflush(stdout);
239 	return (rv < 0);
240 }
241 
242 int
243 getgeom(vng, cp)
244 	struct vndgeom *vng;
245 	char *cp;
246 {
247 	char *secsize, *nsectors, *ntracks, *ncylinders;
248 
249 #define	GETARG(arg) \
250 	do { \
251 		if (cp == NULL || *cp == '\0') \
252 			return (1); \
253 		arg = strsep(&cp, "/"); \
254 		if (arg == NULL) \
255 			return (1); \
256 	} while (0)
257 
258 	GETARG(secsize);
259 	GETARG(nsectors);
260 	GETARG(ntracks);
261 	GETARG(ncylinders);
262 
263 #undef GETARG
264 
265 	/* Too many? */
266 	if (cp != NULL)
267 		return (1);
268 
269 #define	CVTARG(str, num) \
270 	do { \
271 		num = strtol(str, &cp, 10); \
272 		if (*cp != '\0') \
273 			return (1); \
274 	} while (0)
275 
276 	CVTARG(secsize, vng->vng_secsize);
277 	CVTARG(nsectors, vng->vng_nsectors);
278 	CVTARG(ntracks, vng->vng_ntracks);
279 	CVTARG(ncylinders, vng->vng_ncylinders);
280 
281 #undef CVTARG
282 
283 	return (0);
284 }
285 
286 void
287 usage()
288 {
289 
290 	(void)fprintf(stderr, "%s%s",
291 	    "usage: vnconfig [-c] [-f disktab] [-t typename] [-v] special-file"
292 		" regular-file [geomspec]\n",
293 	    "       vnconfig -u [-v] special-file\n");
294 	exit(1);
295 }
296