xref: /illumos-gate/usr/src/cmd/fs.d/fsck.c (revision 355d6bb5)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23*355d6bb5Sswilcox  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include	<stdio.h>
347c478bd9Sstevel@tonic-gate #include	<errno.h>
357c478bd9Sstevel@tonic-gate #include	<limits.h>
367c478bd9Sstevel@tonic-gate #include	<fcntl.h>
377c478bd9Sstevel@tonic-gate #include	<string.h>
387c478bd9Sstevel@tonic-gate #include	<sys/types.h>
397c478bd9Sstevel@tonic-gate #include	<sys/stat.h>
407c478bd9Sstevel@tonic-gate #include	<sys/wait.h>
417c478bd9Sstevel@tonic-gate #include	<sys/vfstab.h>
427c478bd9Sstevel@tonic-gate #include	<sys/mntent.h>
437c478bd9Sstevel@tonic-gate #include	<locale.h>
447c478bd9Sstevel@tonic-gate #include	<libintl.h>
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #define	ARGV_MAX	16
477c478bd9Sstevel@tonic-gate #define	FSTYPE_MAX	8
487c478bd9Sstevel@tonic-gate #define	VFS_PATH	"/usr/lib/fs"
497c478bd9Sstevel@tonic-gate #define	VFS_PATH2	"/etc/fs"
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #define	CHECK(xx, yy)\
527c478bd9Sstevel@tonic-gate 	if (xx == (yy)-1) {\
537c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("%s: too many arguments\n"), myname); \
547c478bd9Sstevel@tonic-gate 		usage(); \
557c478bd9Sstevel@tonic-gate 	}
567c478bd9Sstevel@tonic-gate #define	OPTION(flag)\
577c478bd9Sstevel@tonic-gate 		options++; \
587c478bd9Sstevel@tonic-gate 		nargv[nargc++] = flag; \
597c478bd9Sstevel@tonic-gate 		CHECK(nargc, ARGV_MAX); \
607c478bd9Sstevel@tonic-gate 		break
617c478bd9Sstevel@tonic-gate #define	OPTARG(flag)\
627c478bd9Sstevel@tonic-gate 		nargv[nargc++] = flag; \
637c478bd9Sstevel@tonic-gate 		CHECK(nargc, ARGV_MAX); \
647c478bd9Sstevel@tonic-gate 		if (optarg) {\
657c478bd9Sstevel@tonic-gate 			nargv[nargc++] = optarg; \
667c478bd9Sstevel@tonic-gate 			CHECK(nargc, ARGV_MAX); \
677c478bd9Sstevel@tonic-gate 		}\
687c478bd9Sstevel@tonic-gate 		break
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate int	nrun, ndisks;
727c478bd9Sstevel@tonic-gate int	maxrun = 8;	/* should be based on the machine resources */
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate extern char	*optarg;
757c478bd9Sstevel@tonic-gate extern int	optind;
767c478bd9Sstevel@tonic-gate extern char	*default_fstype();
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate int	nargc = 2;
797c478bd9Sstevel@tonic-gate int	options = 0;
807c478bd9Sstevel@tonic-gate int	mnt_passno = 0;
817c478bd9Sstevel@tonic-gate int	exitstat = 0;
82*355d6bb5Sswilcox int	verbose = 0;
837c478bd9Sstevel@tonic-gate char	*nargv[ARGV_MAX];
847c478bd9Sstevel@tonic-gate char	*myname, *fstype;
857c478bd9Sstevel@tonic-gate char	*malloc();
867c478bd9Sstevel@tonic-gate char	vfstab[] = VFSTAB;
877c478bd9Sstevel@tonic-gate char	pflg = 0, Vflg = 0;
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate /*
907c478bd9Sstevel@tonic-gate  * Keep an idea of the last device arg type as a hint to the
917c478bd9Sstevel@tonic-gate  * type of the next arg. In the case of mountall, it's very likely
927c478bd9Sstevel@tonic-gate  * to be the same type and the next entry in the file. This should
937c478bd9Sstevel@tonic-gate  * help speed vfstab lookups.
947c478bd9Sstevel@tonic-gate  */
957c478bd9Sstevel@tonic-gate enum dev_arg_t { UNKNOWN, SPECIAL, FSCKDEV, MOUNTPT };
967c478bd9Sstevel@tonic-gate enum dev_arg_t arg_hint = UNKNOWN;
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate static struct devlist {
997c478bd9Sstevel@tonic-gate 	char *name;
1007c478bd9Sstevel@tonic-gate 	char *fsname;
1017c478bd9Sstevel@tonic-gate 	pid_t pid;
1027c478bd9Sstevel@tonic-gate 	struct devlist *nxt;
1037c478bd9Sstevel@tonic-gate } *newdev(), *getdev();
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate /*
1067c478bd9Sstevel@tonic-gate  * private copy vfstab functions
1077c478bd9Sstevel@tonic-gate  */
1087c478bd9Sstevel@tonic-gate static struct vfstab	vfsave = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate static int
1117c478bd9Sstevel@tonic-gate vfdup(struct vfstab *vp)
1127c478bd9Sstevel@tonic-gate {
1137c478bd9Sstevel@tonic-gate 	if (vfsave.vfs_special != NULL) {
1147c478bd9Sstevel@tonic-gate 		free(vfsave.vfs_special);
1157c478bd9Sstevel@tonic-gate 		vfsave.vfs_special = NULL;
1167c478bd9Sstevel@tonic-gate 	}
1177c478bd9Sstevel@tonic-gate 	if ((vp->vfs_special != NULL) &&
1187c478bd9Sstevel@tonic-gate 	    ((vfsave.vfs_special = strdup(vp->vfs_special)) == NULL)) {
1197c478bd9Sstevel@tonic-gate 		perror(myname);
1207c478bd9Sstevel@tonic-gate 		return (4);	/* XXX */
1217c478bd9Sstevel@tonic-gate 	}
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 	if (vfsave.vfs_fsckdev != NULL) {
1247c478bd9Sstevel@tonic-gate 		free(vfsave.vfs_fsckdev);
1257c478bd9Sstevel@tonic-gate 		vfsave.vfs_fsckdev = NULL;
1267c478bd9Sstevel@tonic-gate 	}
1277c478bd9Sstevel@tonic-gate 	if ((vp->vfs_fsckdev != NULL) &&
1287c478bd9Sstevel@tonic-gate 	    ((vfsave.vfs_fsckdev = strdup(vp->vfs_fsckdev)) == NULL)) {
1297c478bd9Sstevel@tonic-gate 		perror(myname);
1307c478bd9Sstevel@tonic-gate 		return (4);	/* XXX */
1317c478bd9Sstevel@tonic-gate 	}
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	if (vfsave.vfs_mountp != NULL) {
1347c478bd9Sstevel@tonic-gate 		free(vfsave.vfs_mountp);
1357c478bd9Sstevel@tonic-gate 		vfsave.vfs_mountp = NULL;
1367c478bd9Sstevel@tonic-gate 	}
1377c478bd9Sstevel@tonic-gate 	if ((vp->vfs_mountp != NULL) &&
1387c478bd9Sstevel@tonic-gate 	    ((vfsave.vfs_mountp = strdup(vp->vfs_mountp)) == NULL)) {
1397c478bd9Sstevel@tonic-gate 		perror(myname);
1407c478bd9Sstevel@tonic-gate 		return (4);	/* XXX */
1417c478bd9Sstevel@tonic-gate 	}
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	if (vfsave.vfs_fstype != NULL) {
1447c478bd9Sstevel@tonic-gate 		free(vfsave.vfs_fstype);
1457c478bd9Sstevel@tonic-gate 		vfsave.vfs_fstype = NULL;
1467c478bd9Sstevel@tonic-gate 	}
1477c478bd9Sstevel@tonic-gate 	if ((vp->vfs_fstype != NULL) &&
1487c478bd9Sstevel@tonic-gate 	    ((vfsave.vfs_fstype = strdup(vp->vfs_fstype)) == NULL)) {
1497c478bd9Sstevel@tonic-gate 		perror(myname);
1507c478bd9Sstevel@tonic-gate 		return (4);	/* XXX */
1517c478bd9Sstevel@tonic-gate 	}
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	if (vfsave.vfs_fsckpass != NULL) {
1547c478bd9Sstevel@tonic-gate 		free(vfsave.vfs_fsckpass);
1557c478bd9Sstevel@tonic-gate 		vfsave.vfs_fsckpass = NULL;
1567c478bd9Sstevel@tonic-gate 	}
1577c478bd9Sstevel@tonic-gate 	if ((vp->vfs_fsckpass != NULL) &&
1587c478bd9Sstevel@tonic-gate 	    ((vfsave.vfs_fsckpass = strdup(vp->vfs_fsckpass)) == NULL)) {
1597c478bd9Sstevel@tonic-gate 		perror(myname);
1607c478bd9Sstevel@tonic-gate 		return (4);	/* XXX */
1617c478bd9Sstevel@tonic-gate 	}
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 	if (vfsave.vfs_automnt != NULL) {
1647c478bd9Sstevel@tonic-gate 		free(vfsave.vfs_automnt);
1657c478bd9Sstevel@tonic-gate 		vfsave.vfs_automnt = NULL;
1667c478bd9Sstevel@tonic-gate 	}
1677c478bd9Sstevel@tonic-gate 	if ((vp->vfs_automnt != NULL) &&
1687c478bd9Sstevel@tonic-gate 	    ((vfsave.vfs_automnt = strdup(vp->vfs_automnt)) == NULL)) {
1697c478bd9Sstevel@tonic-gate 		perror(myname);
1707c478bd9Sstevel@tonic-gate 		return (4);	/* XXX */
1717c478bd9Sstevel@tonic-gate 	}
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate 	if (vfsave.vfs_mntopts != NULL) {
1747c478bd9Sstevel@tonic-gate 		free(vfsave.vfs_mntopts);
1757c478bd9Sstevel@tonic-gate 		vfsave.vfs_mntopts = NULL;
1767c478bd9Sstevel@tonic-gate 	}
1777c478bd9Sstevel@tonic-gate 	if ((vp->vfs_mntopts != NULL) &&
1787c478bd9Sstevel@tonic-gate 	    ((vfsave.vfs_mntopts = strdup(vp->vfs_mntopts)) == NULL)) {
1797c478bd9Sstevel@tonic-gate 		perror(myname);
1807c478bd9Sstevel@tonic-gate 		return (4);	/* XXX */
1817c478bd9Sstevel@tonic-gate 	}
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	*vp = vfsave;
1847c478bd9Sstevel@tonic-gate 	return (0);
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate static int
1887c478bd9Sstevel@tonic-gate mygetvfsent(FILE *fp, struct vfstab *vp)
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate 	int	error;
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	if ((error = getvfsent(fp, vp)) != 0)
1937c478bd9Sstevel@tonic-gate 		return (error);
1947c478bd9Sstevel@tonic-gate 	return (vfdup(vp));
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate static int
1987c478bd9Sstevel@tonic-gate mygetvfsany(FILE *fp, struct vfstab *vp, struct vfstab *vrefp)
1997c478bd9Sstevel@tonic-gate {
2007c478bd9Sstevel@tonic-gate 	int	error;
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 	if ((error = getvfsany(fp, vp, vrefp)) != 0)
2037c478bd9Sstevel@tonic-gate 		return (error);
2047c478bd9Sstevel@tonic-gate 	return (vfdup(vp));
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate main(argc, argv)
2087c478bd9Sstevel@tonic-gate 	int	argc;
2097c478bd9Sstevel@tonic-gate 	char	*argv[];
2107c478bd9Sstevel@tonic-gate {
2117c478bd9Sstevel@tonic-gate 	int	cc, ret, other_than_ufs = 0;
2127c478bd9Sstevel@tonic-gate 	int	questflg = 0, Fflg = 0, Vflg = 0, sanity = 0;
2137c478bd9Sstevel@tonic-gate 	char	*subopt;
2147c478bd9Sstevel@tonic-gate 	FILE	*fd = NULL;
2157c478bd9Sstevel@tonic-gate 	struct vfstab	vget, vref;
2167c478bd9Sstevel@tonic-gate 	int preencnt = 0;
2177c478bd9Sstevel@tonic-gate 	struct devlist *dp, *devs = NULL;
2187c478bd9Sstevel@tonic-gate 	int status;
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
2217c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
2227c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
2237c478bd9Sstevel@tonic-gate #endif
2247c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 	myname = strrchr(argv[0], '/');
2277c478bd9Sstevel@tonic-gate 	if (myname)
2287c478bd9Sstevel@tonic-gate 		myname++;
2297c478bd9Sstevel@tonic-gate 	else
2307c478bd9Sstevel@tonic-gate 		myname = argv[0];
2317c478bd9Sstevel@tonic-gate 
232*355d6bb5Sswilcox 	while ((cc = getopt(argc, argv, "?F:mnNo:vVyY")) != -1) {
2337c478bd9Sstevel@tonic-gate 		switch (cc) {
2347c478bd9Sstevel@tonic-gate 		case '?':
2357c478bd9Sstevel@tonic-gate 			questflg++;
2367c478bd9Sstevel@tonic-gate 			if (questflg > 1)
2377c478bd9Sstevel@tonic-gate 				usage();
2387c478bd9Sstevel@tonic-gate 			nargv[nargc++] = "-?";
2397c478bd9Sstevel@tonic-gate 			CHECK(nargc, ARGV_MAX);
2407c478bd9Sstevel@tonic-gate 			break;
2417c478bd9Sstevel@tonic-gate 		case 'F':
2427c478bd9Sstevel@tonic-gate 			Fflg++;
2437c478bd9Sstevel@tonic-gate 			/* check for more that one -F */
2447c478bd9Sstevel@tonic-gate 			if (Fflg > 1) {
2457c478bd9Sstevel@tonic-gate 				fprintf(stderr,
2467c478bd9Sstevel@tonic-gate 				gettext("%s: more than one fstype specified\n"),
2477c478bd9Sstevel@tonic-gate 					myname);
2487c478bd9Sstevel@tonic-gate 				usage();
2497c478bd9Sstevel@tonic-gate 			}
2507c478bd9Sstevel@tonic-gate 			fstype = optarg;
251*355d6bb5Sswilcox 			if (strlen(fstype) > (size_t)FSTYPE_MAX) {
2527c478bd9Sstevel@tonic-gate 				fprintf(stderr,
2537c478bd9Sstevel@tonic-gate 			gettext("%s: Fstype %s exceeds %d characters\n"),
2547c478bd9Sstevel@tonic-gate 					myname, fstype, FSTYPE_MAX);
2557c478bd9Sstevel@tonic-gate 						exit(1);
2567c478bd9Sstevel@tonic-gate 			}
2577c478bd9Sstevel@tonic-gate 			break;
2587c478bd9Sstevel@tonic-gate 		case 'm':
2597c478bd9Sstevel@tonic-gate 			sanity++;
2607c478bd9Sstevel@tonic-gate 			OPTION("-m");
2617c478bd9Sstevel@tonic-gate 		case 'n':
2627c478bd9Sstevel@tonic-gate 			OPTION("-n");
2637c478bd9Sstevel@tonic-gate 		case 'N':
2647c478bd9Sstevel@tonic-gate 			OPTION("-N");
2657c478bd9Sstevel@tonic-gate 		case 'o':
2667c478bd9Sstevel@tonic-gate 			subopt = optarg;
2677c478bd9Sstevel@tonic-gate 			while (*subopt != '\0') {
2687c478bd9Sstevel@tonic-gate 				if (*subopt == 'p') {
2697c478bd9Sstevel@tonic-gate 					pflg++;
2707c478bd9Sstevel@tonic-gate 					break;
2717c478bd9Sstevel@tonic-gate 				}
2727c478bd9Sstevel@tonic-gate 				subopt++;
2737c478bd9Sstevel@tonic-gate 			}
2747c478bd9Sstevel@tonic-gate 			OPTARG("-o");
275*355d6bb5Sswilcox 		case 'v':
276*355d6bb5Sswilcox 			OPTION("-v");
2777c478bd9Sstevel@tonic-gate 		case 'V':
2787c478bd9Sstevel@tonic-gate 			Vflg++;
2797c478bd9Sstevel@tonic-gate 			if (Vflg > 1)
2807c478bd9Sstevel@tonic-gate 				usage();
2817c478bd9Sstevel@tonic-gate 			break;
2827c478bd9Sstevel@tonic-gate 		case 'y':
2837c478bd9Sstevel@tonic-gate 			OPTION("-y");
2847c478bd9Sstevel@tonic-gate 		case 'Y':
2857c478bd9Sstevel@tonic-gate 			OPTION("-Y");
2867c478bd9Sstevel@tonic-gate 		}
2877c478bd9Sstevel@tonic-gate 		optarg = NULL;
2887c478bd9Sstevel@tonic-gate 	}
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	/* copy '--' to specific */
2917c478bd9Sstevel@tonic-gate 	if (strcmp(argv[optind-1], "--") == 0) {
2927c478bd9Sstevel@tonic-gate 		nargv[nargc++] = argv[optind-1];
2937c478bd9Sstevel@tonic-gate 		CHECK(nargc, ARGV_MAX);
2947c478bd9Sstevel@tonic-gate 	}
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	if (questflg) {
2977c478bd9Sstevel@tonic-gate 		if (Fflg) {
2987c478bd9Sstevel@tonic-gate 			nargc = 2;
2997c478bd9Sstevel@tonic-gate 			nargv[nargc++] = "-?";
3007c478bd9Sstevel@tonic-gate 			nargv[nargc] = NULL;
3017c478bd9Sstevel@tonic-gate 			do_exec(fstype, nargv);
3027c478bd9Sstevel@tonic-gate 		}
3037c478bd9Sstevel@tonic-gate 		usage();
3047c478bd9Sstevel@tonic-gate 	}
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 	if ((sanity) && (options > 1)) {
3077c478bd9Sstevel@tonic-gate 		usage();
3087c478bd9Sstevel@tonic-gate 	}
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate 	if (optind == argc) {	/* no device name is specified */
3117c478bd9Sstevel@tonic-gate 		if (fstype == NULL) {
3127c478bd9Sstevel@tonic-gate 			if ((argc > 2) && (sanity)) {
3137c478bd9Sstevel@tonic-gate 				usage();
3147c478bd9Sstevel@tonic-gate 			}
3157c478bd9Sstevel@tonic-gate 		}
3167c478bd9Sstevel@tonic-gate 		/*
3177c478bd9Sstevel@tonic-gate 		 * Try to check UFS filesystems first, then check other
3187c478bd9Sstevel@tonic-gate 		 * filesystems if they exist.
3197c478bd9Sstevel@tonic-gate 		 * Note: Parallel checking is only available in UFS for now.
3207c478bd9Sstevel@tonic-gate 		 */
3217c478bd9Sstevel@tonic-gate 		if (fstype == NULL || strcmp(fstype, MNTTYPE_UFS) == 0) {
3227c478bd9Sstevel@tonic-gate 			if ((fd = fopen(vfstab, "r")) == NULL) {
3237c478bd9Sstevel@tonic-gate 				fprintf(stderr,
3247c478bd9Sstevel@tonic-gate 					gettext("%s: cannot open vfstab\n"),
3257c478bd9Sstevel@tonic-gate 					myname);
3267c478bd9Sstevel@tonic-gate 				exit(1);
3277c478bd9Sstevel@tonic-gate 			}
3287c478bd9Sstevel@tonic-gate 			while ((ret = mygetvfsent(fd, &vget)) == 0) {
3297c478bd9Sstevel@tonic-gate 				if (strcmp(vget.vfs_fstype, MNTTYPE_UFS) &&
3307c478bd9Sstevel@tonic-gate 				    numbers(vget.vfs_fsckpass)) {
3317c478bd9Sstevel@tonic-gate 					other_than_ufs ++;
3327c478bd9Sstevel@tonic-gate 					continue;
3337c478bd9Sstevel@tonic-gate 				}
3347c478bd9Sstevel@tonic-gate 				if (numbers(vget.vfs_fsckpass))
3357c478bd9Sstevel@tonic-gate 					mnt_passno = atoi(vget.vfs_fsckpass);
3367c478bd9Sstevel@tonic-gate 				else
3377c478bd9Sstevel@tonic-gate 					continue;
3387c478bd9Sstevel@tonic-gate 				if (mnt_passno < 1)
3397c478bd9Sstevel@tonic-gate 					continue;
3407c478bd9Sstevel@tonic-gate 				if (pflg == 0 || mnt_passno == 1) {
3417c478bd9Sstevel@tonic-gate 					status = execute(vget.vfs_fsckdev,
3427c478bd9Sstevel@tonic-gate 					    MNTTYPE_UFS, Vflg, fd);
3437c478bd9Sstevel@tonic-gate 					/* return the highest exit code */
3447c478bd9Sstevel@tonic-gate 					if (status > exitstat)
3457c478bd9Sstevel@tonic-gate 						exitstat = status;
3467c478bd9Sstevel@tonic-gate 				} else if (preen_addev(vget.vfs_fsckdev) == 0) {
3477c478bd9Sstevel@tonic-gate 					preencnt++;
3487c478bd9Sstevel@tonic-gate 					dp = newdev(&vget);
3497c478bd9Sstevel@tonic-gate 					dp->nxt = devs;
3507c478bd9Sstevel@tonic-gate 					devs = dp;
3517c478bd9Sstevel@tonic-gate 				} else {
3527c478bd9Sstevel@tonic-gate 					/*
3537c478bd9Sstevel@tonic-gate 					 * preening setup failed, so
3547c478bd9Sstevel@tonic-gate 					 * execute serially here...
3557c478bd9Sstevel@tonic-gate 					 */
3567c478bd9Sstevel@tonic-gate 					fprintf(stderr,
3577c478bd9Sstevel@tonic-gate 					gettext("%s: preen_addev error\n"),
3587c478bd9Sstevel@tonic-gate 						myname);
3597c478bd9Sstevel@tonic-gate 					status = execute(vget.vfs_fsckdev,
3607c478bd9Sstevel@tonic-gate 					    MNTTYPE_UFS, Vflg, fd);
3617c478bd9Sstevel@tonic-gate 					/* return the highest exit code */
3627c478bd9Sstevel@tonic-gate 					if (status > exitstat)
3637c478bd9Sstevel@tonic-gate 						exitstat = status;
3647c478bd9Sstevel@tonic-gate 				}
3657c478bd9Sstevel@tonic-gate 			}
3667c478bd9Sstevel@tonic-gate 			fclose(fd);
3677c478bd9Sstevel@tonic-gate 			if (ret > 0)
3687c478bd9Sstevel@tonic-gate 				vfserror(ret);
3697c478bd9Sstevel@tonic-gate 			if (pflg && exitstat == 0) {
3707c478bd9Sstevel@tonic-gate 				fsck_dopreen(&devs, preencnt);
3717c478bd9Sstevel@tonic-gate 			}
3727c478bd9Sstevel@tonic-gate 		}
3737c478bd9Sstevel@tonic-gate 		else
3747c478bd9Sstevel@tonic-gate 			other_than_ufs = 1;
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 		if (other_than_ufs) {
3777c478bd9Sstevel@tonic-gate 			if ((fd = fopen(vfstab, "r")) == NULL) {
3787c478bd9Sstevel@tonic-gate 				fprintf(stderr,
3797c478bd9Sstevel@tonic-gate 					gettext("%s: cannot open vfstab\n"),
3807c478bd9Sstevel@tonic-gate 					myname);
3817c478bd9Sstevel@tonic-gate 				exit(1);
3827c478bd9Sstevel@tonic-gate 			}
3837c478bd9Sstevel@tonic-gate 			while ((ret = mygetvfsent(fd, &vget)) == 0)
3847c478bd9Sstevel@tonic-gate 				if (strcmp(vget.vfs_fstype, MNTTYPE_UFS) &&
3857c478bd9Sstevel@tonic-gate 				    numbers(vget.vfs_fsckpass) &&
3867c478bd9Sstevel@tonic-gate 				    vget.vfs_fsckdev != NULL &&
3877c478bd9Sstevel@tonic-gate 				    (fstype == NULL ||
3887c478bd9Sstevel@tonic-gate 				    strcmp(fstype, vget.vfs_fstype) == 0)) {
3897c478bd9Sstevel@tonic-gate 					status = execute(vget.vfs_fsckdev,
3907c478bd9Sstevel@tonic-gate 					    vget.vfs_fstype, Vflg, fd);
3917c478bd9Sstevel@tonic-gate 					/* return the highest exit code */
3927c478bd9Sstevel@tonic-gate 					if (status > exitstat)
3937c478bd9Sstevel@tonic-gate 						exitstat = status;
3947c478bd9Sstevel@tonic-gate 				}
3957c478bd9Sstevel@tonic-gate 			fclose(fd);
3967c478bd9Sstevel@tonic-gate 			if (ret > 0)
3977c478bd9Sstevel@tonic-gate 				vfserror(ret);
3987c478bd9Sstevel@tonic-gate 		}
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	} else {	/* device name is specified */
4017c478bd9Sstevel@tonic-gate 		if (fstype == NULL && (fd = fopen(vfstab, "r")) == NULL) {
4027c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("%s: cannot open vfstab\n"),
4037c478bd9Sstevel@tonic-gate 				myname);
4047c478bd9Sstevel@tonic-gate 			exit(1);
4057c478bd9Sstevel@tonic-gate 		}
4067c478bd9Sstevel@tonic-gate 		while (optind < argc) {
4077c478bd9Sstevel@tonic-gate 			/*
4087c478bd9Sstevel@tonic-gate 			 * If "-F FStype" is specified, use that fs type.
4097c478bd9Sstevel@tonic-gate 			 * Otherwise, determine the fs type from /etc/vfstab
4107c478bd9Sstevel@tonic-gate 			 * if the entry exists.  Otherwise, determine the
4117c478bd9Sstevel@tonic-gate 			 * local or remote fs type from /etc/default/df
4127c478bd9Sstevel@tonic-gate 			 * or /etc/dfs/fstypes respectively.
4137c478bd9Sstevel@tonic-gate 			 */
4147c478bd9Sstevel@tonic-gate 			if (fstype == NULL) {
4157c478bd9Sstevel@tonic-gate 				if ((argc > 3) && (sanity)) {
4167c478bd9Sstevel@tonic-gate 					usage();
4177c478bd9Sstevel@tonic-gate 				}
4187c478bd9Sstevel@tonic-gate 				/* must check for both special && raw devices */
4197c478bd9Sstevel@tonic-gate 				vfsnull(&vref);
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate 				/*
4227c478bd9Sstevel@tonic-gate 				 * Find the vfstab entry for this device.
4237c478bd9Sstevel@tonic-gate 				 * arg_hint tells us what to try to match,
4247c478bd9Sstevel@tonic-gate 				 * based on the type of the last arg. If
4257c478bd9Sstevel@tonic-gate 				 * arg_hint equals UNKNOWN, then we're not
4267c478bd9Sstevel@tonic-gate 				 * sure of the type and need to fallthrough
4277c478bd9Sstevel@tonic-gate 				 * all 3 possibilities for vfstab lookup.
4287c478bd9Sstevel@tonic-gate 				 * Try it as a mountpt first, since that's
4297c478bd9Sstevel@tonic-gate 				 * what mountall gives us.
4307c478bd9Sstevel@tonic-gate 				 */
4317c478bd9Sstevel@tonic-gate try_again:
4327c478bd9Sstevel@tonic-gate 				switch (arg_hint) {
4337c478bd9Sstevel@tonic-gate 				case UNKNOWN:
4347c478bd9Sstevel@tonic-gate 					/* FALLTHROUGH */
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate 				case MOUNTPT:
4377c478bd9Sstevel@tonic-gate 					vref.vfs_mountp = argv[optind];
4387c478bd9Sstevel@tonic-gate 					if ((ret = mygetvfsany(fd, &vget,
4397c478bd9Sstevel@tonic-gate 						&vref)) == -1 ||
4407c478bd9Sstevel@tonic-gate 						vget.vfs_fstype == NULL) {
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate 						vref.vfs_mountp = NULL;
4437c478bd9Sstevel@tonic-gate 						rewind(fd);
4447c478bd9Sstevel@tonic-gate 
4457c478bd9Sstevel@tonic-gate 						if (arg_hint == MOUNTPT) {
4467c478bd9Sstevel@tonic-gate 							arg_hint = UNKNOWN;
4477c478bd9Sstevel@tonic-gate 							goto try_again;
4487c478bd9Sstevel@tonic-gate 						}
4497c478bd9Sstevel@tonic-gate 						/* FALLTHROUGH */
4507c478bd9Sstevel@tonic-gate 					} else {
4517c478bd9Sstevel@tonic-gate 						/* Found it */
4527c478bd9Sstevel@tonic-gate 						if (vget.vfs_fsckdev != NULL) {
4537c478bd9Sstevel@tonic-gate 							argv[optind] =
4547c478bd9Sstevel@tonic-gate 							vget.vfs_fsckdev;
4557c478bd9Sstevel@tonic-gate 						}
4567c478bd9Sstevel@tonic-gate 						arg_hint = MOUNTPT;
4577c478bd9Sstevel@tonic-gate 						break;
4587c478bd9Sstevel@tonic-gate 					}
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 				case FSCKDEV:
4617c478bd9Sstevel@tonic-gate 					vref.vfs_fsckdev = argv[optind];
4627c478bd9Sstevel@tonic-gate 					if ((ret = mygetvfsany(fd, &vget,
4637c478bd9Sstevel@tonic-gate 						&vref)) == -1 ||
4647c478bd9Sstevel@tonic-gate 						vget.vfs_fstype == NULL) {
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 						vref.vfs_fsckdev = NULL;
4677c478bd9Sstevel@tonic-gate 						rewind(fd);
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 						if (arg_hint == FSCKDEV) {
4707c478bd9Sstevel@tonic-gate 							arg_hint = UNKNOWN;
4717c478bd9Sstevel@tonic-gate 							goto try_again;
4727c478bd9Sstevel@tonic-gate 						}
4737c478bd9Sstevel@tonic-gate 						/* FALLTHROUGH */
4747c478bd9Sstevel@tonic-gate 					} else {
4757c478bd9Sstevel@tonic-gate 						/* Found it */
4767c478bd9Sstevel@tonic-gate 						arg_hint = FSCKDEV;
4777c478bd9Sstevel@tonic-gate 						break;
4787c478bd9Sstevel@tonic-gate 					}
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 				case SPECIAL:
4817c478bd9Sstevel@tonic-gate 					vref.vfs_special = argv[optind];
4827c478bd9Sstevel@tonic-gate 					if ((ret = mygetvfsany(fd, &vget,
4837c478bd9Sstevel@tonic-gate 						&vref)) == -1 ||
4847c478bd9Sstevel@tonic-gate 						vget.vfs_fstype == NULL) {
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate 						vref.vfs_special = NULL;
4877c478bd9Sstevel@tonic-gate 						rewind(fd);
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate 						if (arg_hint == SPECIAL) {
4907c478bd9Sstevel@tonic-gate 							arg_hint = UNKNOWN;
4917c478bd9Sstevel@tonic-gate 							goto try_again;
4927c478bd9Sstevel@tonic-gate 						}
4937c478bd9Sstevel@tonic-gate 						/* FALLTHROUGH */
4947c478bd9Sstevel@tonic-gate 					} else {
4957c478bd9Sstevel@tonic-gate 						/* Found it */
4967c478bd9Sstevel@tonic-gate 						arg_hint = SPECIAL;
4977c478bd9Sstevel@tonic-gate 						break;
4987c478bd9Sstevel@tonic-gate 					}
4997c478bd9Sstevel@tonic-gate 				}
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate 				if (ret == 0 && vget.vfs_fstype) {
5027c478bd9Sstevel@tonic-gate 					if ((pflg) && (strcmp(vget.vfs_fstype,
5037c478bd9Sstevel@tonic-gate 					    MNTTYPE_UFS) == 0) && (preen_addev(
5047c478bd9Sstevel@tonic-gate 					    vget.vfs_fsckdev) == 0)) {
5057c478bd9Sstevel@tonic-gate 						preencnt++;
5067c478bd9Sstevel@tonic-gate 						dp = newdev(&vget);
5077c478bd9Sstevel@tonic-gate 						dp->nxt = devs;
5087c478bd9Sstevel@tonic-gate 						devs = dp;
5097c478bd9Sstevel@tonic-gate 					} else {
5107c478bd9Sstevel@tonic-gate 						status = execute(argv[optind],
5117c478bd9Sstevel@tonic-gate 						    vget.vfs_fstype, Vflg, fd);
5127c478bd9Sstevel@tonic-gate 						if (status > exitstat)
5137c478bd9Sstevel@tonic-gate 							exitstat = status;
5147c478bd9Sstevel@tonic-gate 					}
5157c478bd9Sstevel@tonic-gate 				} else if (ret == -1 ||
5167c478bd9Sstevel@tonic-gate 				    vget.vfs_fstype == NULL) {
5177c478bd9Sstevel@tonic-gate 					fstype =
5187c478bd9Sstevel@tonic-gate 					    default_fstype(argv[optind]);
5197c478bd9Sstevel@tonic-gate 					status = execute(argv[optind], fstype,
5207c478bd9Sstevel@tonic-gate 					    Vflg, fd);
5217c478bd9Sstevel@tonic-gate 					/* return the highest exit code */
5227c478bd9Sstevel@tonic-gate 					if (status > exitstat)
5237c478bd9Sstevel@tonic-gate 						exitstat = status;
5247c478bd9Sstevel@tonic-gate 				} else
5257c478bd9Sstevel@tonic-gate 					vfserror(ret);
5267c478bd9Sstevel@tonic-gate 			} else {
5277c478bd9Sstevel@tonic-gate 				status = execute(argv[optind], fstype,
5287c478bd9Sstevel@tonic-gate 				    Vflg, NULL);
5297c478bd9Sstevel@tonic-gate 				/* return the highest exit code */
5307c478bd9Sstevel@tonic-gate 				if (status > exitstat)
5317c478bd9Sstevel@tonic-gate 					exitstat = status;
5327c478bd9Sstevel@tonic-gate 			}
5337c478bd9Sstevel@tonic-gate 			optind++;
5347c478bd9Sstevel@tonic-gate 		}
5357c478bd9Sstevel@tonic-gate 		if (fd != NULL)
5367c478bd9Sstevel@tonic-gate 			fclose(fd);
5377c478bd9Sstevel@tonic-gate 		if ((pflg) && (exitstat == 0)) {
5387c478bd9Sstevel@tonic-gate 			fsck_dopreen(&devs, preencnt);
5397c478bd9Sstevel@tonic-gate 		}
5407c478bd9Sstevel@tonic-gate 	}
5417c478bd9Sstevel@tonic-gate 	exit(exitstat);
5427c478bd9Sstevel@tonic-gate }
5437c478bd9Sstevel@tonic-gate 
5447c478bd9Sstevel@tonic-gate static
5457c478bd9Sstevel@tonic-gate fsck_dopreen(devp, ndevs)
5467c478bd9Sstevel@tonic-gate 	struct devlist **devp;
5477c478bd9Sstevel@tonic-gate 	int ndevs;
5487c478bd9Sstevel@tonic-gate {
5497c478bd9Sstevel@tonic-gate 	char name[1024];
5507c478bd9Sstevel@tonic-gate 	int rc;
5517c478bd9Sstevel@tonic-gate 	register int i;
5527c478bd9Sstevel@tonic-gate 	struct devlist *bl, *bdp;
5537c478bd9Sstevel@tonic-gate 	struct devlist *badlist;
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 	bl = badlist = NULL;
5567c478bd9Sstevel@tonic-gate 	while (ndevs > 0) {
5577c478bd9Sstevel@tonic-gate 		if (nrun > maxrun)
5587c478bd9Sstevel@tonic-gate 			waiter(&bl, &badlist);
5597c478bd9Sstevel@tonic-gate 		rc = preen_getdev(name);
5607c478bd9Sstevel@tonic-gate 		switch (rc) {
5617c478bd9Sstevel@tonic-gate 		case 0:
5627c478bd9Sstevel@tonic-gate 			break;
5637c478bd9Sstevel@tonic-gate 		case 1:
5647c478bd9Sstevel@tonic-gate 			bdp = getdev(name, devp);
5657c478bd9Sstevel@tonic-gate 			if (bdp == NULL) {
5667c478bd9Sstevel@tonic-gate 				fprintf(stderr,
5677c478bd9Sstevel@tonic-gate 					gettext("%s: unknown dev: `%s'\n"),
5687c478bd9Sstevel@tonic-gate 					myname, name);
5697c478bd9Sstevel@tonic-gate 				exit(1);
5707c478bd9Sstevel@tonic-gate 			}
5717c478bd9Sstevel@tonic-gate 			bdp->nxt = bl;
5727c478bd9Sstevel@tonic-gate 			bl = bdp;
5737c478bd9Sstevel@tonic-gate 			startdisk(bdp);
5747c478bd9Sstevel@tonic-gate 			ndevs--;
5757c478bd9Sstevel@tonic-gate 			break;
5767c478bd9Sstevel@tonic-gate 		case 2:
5777c478bd9Sstevel@tonic-gate 			waiter(&bl, &badlist);
5787c478bd9Sstevel@tonic-gate 			break;
5797c478bd9Sstevel@tonic-gate 		default:
5807c478bd9Sstevel@tonic-gate 			fprintf(stderr,
5817c478bd9Sstevel@tonic-gate 			gettext("%s: bad return `%d' from preen_getdev\n"),
5827c478bd9Sstevel@tonic-gate 				myname, rc);
5837c478bd9Sstevel@tonic-gate 			break;
5847c478bd9Sstevel@tonic-gate 		}
5857c478bd9Sstevel@tonic-gate 	}
5867c478bd9Sstevel@tonic-gate 	while (bl != NULL) {
5877c478bd9Sstevel@tonic-gate 		waiter(&bl, &badlist);
5887c478bd9Sstevel@tonic-gate 	}
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate 	if (badlist != NULL)
5917c478bd9Sstevel@tonic-gate 		print_badlist(badlist);
5927c478bd9Sstevel@tonic-gate }
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate static
5957c478bd9Sstevel@tonic-gate startdisk(dp)
5967c478bd9Sstevel@tonic-gate 	struct devlist *dp;
5977c478bd9Sstevel@tonic-gate {
5987c478bd9Sstevel@tonic-gate 	pid_t pid;
5997c478bd9Sstevel@tonic-gate 
6007c478bd9Sstevel@tonic-gate 	nrun++;
6017c478bd9Sstevel@tonic-gate 	if ((pid = fork()) == -1) {
6027c478bd9Sstevel@tonic-gate 		perror("fork");
6037c478bd9Sstevel@tonic-gate 		exit(1);
6047c478bd9Sstevel@tonic-gate 	} else if (pid == 0) {
6057c478bd9Sstevel@tonic-gate 		exitstat = execute(dp->name, MNTTYPE_UFS, Vflg, NULL);
6067c478bd9Sstevel@tonic-gate 		exit(exitstat);
6077c478bd9Sstevel@tonic-gate 	} else {
6087c478bd9Sstevel@tonic-gate 		dp->pid = pid;
6097c478bd9Sstevel@tonic-gate 	}
6107c478bd9Sstevel@tonic-gate }
6117c478bd9Sstevel@tonic-gate 
6127c478bd9Sstevel@tonic-gate static
6137c478bd9Sstevel@tonic-gate waiter(blp, badlist)
6147c478bd9Sstevel@tonic-gate 	struct devlist **blp;
6157c478bd9Sstevel@tonic-gate 	struct devlist **badlist;
6167c478bd9Sstevel@tonic-gate {
6177c478bd9Sstevel@tonic-gate 	pid_t curpid;
6187c478bd9Sstevel@tonic-gate 	int status;
6197c478bd9Sstevel@tonic-gate 	register struct devlist *bdp, *pbdp;
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate 	curpid = wait(&status);
6227c478bd9Sstevel@tonic-gate 	if (curpid == -1) {
6237c478bd9Sstevel@tonic-gate 		perror("wait");
6247c478bd9Sstevel@tonic-gate 		exit(1);
6257c478bd9Sstevel@tonic-gate 	}
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate 	for (pbdp = NULL, bdp = *blp; bdp != NULL; pbdp = bdp, bdp = bdp->nxt) {
6287c478bd9Sstevel@tonic-gate 		if (bdp->pid == curpid) {
6297c478bd9Sstevel@tonic-gate 			break;
6307c478bd9Sstevel@tonic-gate 		}
6317c478bd9Sstevel@tonic-gate 	}
6327c478bd9Sstevel@tonic-gate 	if (bdp == NULL)
6337c478bd9Sstevel@tonic-gate 		return;
6347c478bd9Sstevel@tonic-gate 	nrun--;
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 	if (pbdp)
6377c478bd9Sstevel@tonic-gate 		pbdp->nxt = bdp->nxt;
6387c478bd9Sstevel@tonic-gate 	else
6397c478bd9Sstevel@tonic-gate 		*blp = bdp->nxt;
6407c478bd9Sstevel@tonic-gate 	preen_releasedev(bdp->name);
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate 	if (WTERMSIG(status)) {
6437c478bd9Sstevel@tonic-gate 		printf(gettext("%s (%s): EXITED WITH SIGNAL %d\n"),
6447c478bd9Sstevel@tonic-gate 			bdp->name, bdp->fsname, WTERMSIG(status));
6457c478bd9Sstevel@tonic-gate 		status = status&0377 | 8<<8;
6467c478bd9Sstevel@tonic-gate 	}
6477c478bd9Sstevel@tonic-gate 	if (WHIBYTE(status) != 0) {
6487c478bd9Sstevel@tonic-gate 		if (WHIBYTE(status) > exitstat)
6497c478bd9Sstevel@tonic-gate 			exitstat = WHIBYTE(status);
6507c478bd9Sstevel@tonic-gate 		while (*badlist != NULL)
6517c478bd9Sstevel@tonic-gate 			badlist = &(*badlist)->nxt;
6527c478bd9Sstevel@tonic-gate 		*badlist = bdp;
6537c478bd9Sstevel@tonic-gate 		bdp->nxt = NULL;
6547c478bd9Sstevel@tonic-gate 	}
6557c478bd9Sstevel@tonic-gate }
6567c478bd9Sstevel@tonic-gate 
6577c478bd9Sstevel@tonic-gate static
6587c478bd9Sstevel@tonic-gate print_badlist(lp)
6597c478bd9Sstevel@tonic-gate 	struct devlist *lp;
6607c478bd9Sstevel@tonic-gate {
6617c478bd9Sstevel@tonic-gate 	int x, len;
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 	printf(
6647c478bd9Sstevel@tonic-gate gettext("\nTHE FOLLOWING FILE SYSTEM(S) HAD AN UNEXPECTED INCONSISTENCY:"));
6657c478bd9Sstevel@tonic-gate 	for (x = 3; lp != NULL; lp = lp->nxt) {
6667c478bd9Sstevel@tonic-gate 		len = strlen(lp->name) + strlen(lp->fsname) + 5;
6677c478bd9Sstevel@tonic-gate 		x += len;
6687c478bd9Sstevel@tonic-gate 		if (x >= 80) {
6697c478bd9Sstevel@tonic-gate 			printf("\n   ");
6707c478bd9Sstevel@tonic-gate 			x = len + 3;
6717c478bd9Sstevel@tonic-gate 		} else {
6727c478bd9Sstevel@tonic-gate 			printf(" ");
6737c478bd9Sstevel@tonic-gate 		}
6747c478bd9Sstevel@tonic-gate 		printf("%s (%s)%s", lp->name, lp->fsname,
6757c478bd9Sstevel@tonic-gate 		    lp->nxt ? "," : "\n");
6767c478bd9Sstevel@tonic-gate 	}
6777c478bd9Sstevel@tonic-gate }
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate /*
6807c478bd9Sstevel@tonic-gate  * allocate and initialize a `devlist' structure
6817c478bd9Sstevel@tonic-gate  */
6827c478bd9Sstevel@tonic-gate static
6837c478bd9Sstevel@tonic-gate struct devlist *
6847c478bd9Sstevel@tonic-gate newdev(vfsp)
6857c478bd9Sstevel@tonic-gate 	struct vfstab *vfsp;
6867c478bd9Sstevel@tonic-gate {
6877c478bd9Sstevel@tonic-gate 	struct devlist *dp;
6887c478bd9Sstevel@tonic-gate 	extern char *strdup();
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate 	dp = (struct devlist *)malloc(sizeof (struct devlist));
6917c478bd9Sstevel@tonic-gate 	if (dp == NULL) {
6927c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("%s: out of memory\n"), myname);
6937c478bd9Sstevel@tonic-gate 		exit(1);
6947c478bd9Sstevel@tonic-gate 	}
6957c478bd9Sstevel@tonic-gate 	dp->name = strdup(vfsp->vfs_fsckdev);
6967c478bd9Sstevel@tonic-gate 	dp->fsname = strdup(vfsp->vfs_mountp);
6977c478bd9Sstevel@tonic-gate 	if (dp->name == NULL || dp->fsname == NULL) {
6987c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("%s: out of memory\n"), myname);
6997c478bd9Sstevel@tonic-gate 		exit(1);
7007c478bd9Sstevel@tonic-gate 	}
7017c478bd9Sstevel@tonic-gate 	return (dp);
7027c478bd9Sstevel@tonic-gate }
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate /*
7057c478bd9Sstevel@tonic-gate  * locate the devlist structure in the given list that matches `name'.
7067c478bd9Sstevel@tonic-gate  * If found, the structure is removed from the list, and a pointer to
7077c478bd9Sstevel@tonic-gate  * it is returned.  If not, NULL is returned.
7087c478bd9Sstevel@tonic-gate  */
7097c478bd9Sstevel@tonic-gate static
7107c478bd9Sstevel@tonic-gate struct devlist *
7117c478bd9Sstevel@tonic-gate getdev(name, list)
7127c478bd9Sstevel@tonic-gate 	char *name;
7137c478bd9Sstevel@tonic-gate 	struct devlist **list;
7147c478bd9Sstevel@tonic-gate {
7157c478bd9Sstevel@tonic-gate 	register struct devlist *p, *lp;
7167c478bd9Sstevel@tonic-gate 
7177c478bd9Sstevel@tonic-gate 	for (lp = NULL, p = *list; p != NULL; lp = p, p = p->nxt) {
7187c478bd9Sstevel@tonic-gate 		if (strcmp(p->name, name) == 0)
7197c478bd9Sstevel@tonic-gate 			break;
7207c478bd9Sstevel@tonic-gate 	}
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate 	if (p != NULL) {
7237c478bd9Sstevel@tonic-gate 		if (lp != NULL)
7247c478bd9Sstevel@tonic-gate 			lp->nxt = p->nxt;
7257c478bd9Sstevel@tonic-gate 		else
7267c478bd9Sstevel@tonic-gate 			*list = p->nxt;
7277c478bd9Sstevel@tonic-gate 	}
7287c478bd9Sstevel@tonic-gate 	return (p);
7297c478bd9Sstevel@tonic-gate }
7307c478bd9Sstevel@tonic-gate 
7317c478bd9Sstevel@tonic-gate /* see if all numbers */
7327c478bd9Sstevel@tonic-gate numbers(yp)
7337c478bd9Sstevel@tonic-gate 	char	*yp;
7347c478bd9Sstevel@tonic-gate {
7357c478bd9Sstevel@tonic-gate 	if (yp == NULL)
7367c478bd9Sstevel@tonic-gate 		return (0);
7377c478bd9Sstevel@tonic-gate 	while ('0' <= *yp && *yp <= '9')
7387c478bd9Sstevel@tonic-gate 		yp++;
7397c478bd9Sstevel@tonic-gate 	if (*yp)
7407c478bd9Sstevel@tonic-gate 		return (0);
7417c478bd9Sstevel@tonic-gate 	return (1);
7427c478bd9Sstevel@tonic-gate }
7437c478bd9Sstevel@tonic-gate 
7447c478bd9Sstevel@tonic-gate execute(fsckdev, fstype, Vflg, fd)
7457c478bd9Sstevel@tonic-gate 	char	*fsckdev, *fstype;
7467c478bd9Sstevel@tonic-gate 	int	Vflg;
7477c478bd9Sstevel@tonic-gate 	FILE	*fd;
7487c478bd9Sstevel@tonic-gate {
7497c478bd9Sstevel@tonic-gate 	int	st;
7507c478bd9Sstevel@tonic-gate 	pid_t	fk;
7517c478bd9Sstevel@tonic-gate 	char	full_path[PATH_MAX];
7527c478bd9Sstevel@tonic-gate 	char	*vfs_path = VFS_PATH;
7537c478bd9Sstevel@tonic-gate 	int	status = 0;
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate 	nargv[nargc] = fsckdev;
7567c478bd9Sstevel@tonic-gate 
7577c478bd9Sstevel@tonic-gate 	if (Vflg) {
7587c478bd9Sstevel@tonic-gate 		prnt_cmd(stdout, fstype);
7597c478bd9Sstevel@tonic-gate 		return (0);
7607c478bd9Sstevel@tonic-gate 	}
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate 	if (fd)
7637c478bd9Sstevel@tonic-gate 		fcntl(fileno(fd), F_SETFD, 1);	/* close on exec */
7647c478bd9Sstevel@tonic-gate 
7657c478bd9Sstevel@tonic-gate 	if ((fk = fork()) == (pid_t)-1) {
7667c478bd9Sstevel@tonic-gate 		fprintf(stderr,
7677c478bd9Sstevel@tonic-gate 			gettext("%s: cannot fork.  Try again later\n"),
7687c478bd9Sstevel@tonic-gate 			myname);
7697c478bd9Sstevel@tonic-gate 		perror(myname);
7707c478bd9Sstevel@tonic-gate 		exit(1);
7717c478bd9Sstevel@tonic-gate 	}
7727c478bd9Sstevel@tonic-gate 
7737c478bd9Sstevel@tonic-gate 	if (fk == 0) {
7747c478bd9Sstevel@tonic-gate 		/* Try to exec the fstype dependent portion of the fsck. */
7757c478bd9Sstevel@tonic-gate 		do_exec(fstype, nargv);
7767c478bd9Sstevel@tonic-gate 	} else {
7777c478bd9Sstevel@tonic-gate 		/* parent waits for child */
7787c478bd9Sstevel@tonic-gate 		if (wait(&st) == (pid_t)-1) {
7797c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("%s: bad wait\n"), myname);
7807c478bd9Sstevel@tonic-gate 			perror(myname);
7817c478bd9Sstevel@tonic-gate 			exit(1);
7827c478bd9Sstevel@tonic-gate 		}
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate 		if ((st & 0xff) == 0x7f) {
7857c478bd9Sstevel@tonic-gate 			fprintf(stderr,
7867c478bd9Sstevel@tonic-gate 				gettext("%s: warning: the following command"
7877c478bd9Sstevel@tonic-gate 				" (process %d) was stopped by signal %d\n"),
7887c478bd9Sstevel@tonic-gate 				myname, fk, (st >> 8) & 0xff);
7897c478bd9Sstevel@tonic-gate 			prnt_cmd(stderr, fstype);
7907c478bd9Sstevel@tonic-gate 			status = ((st >> 8) & 0xff) | 0x80;
7917c478bd9Sstevel@tonic-gate 		} else if (st & 0xff) {
7927c478bd9Sstevel@tonic-gate 			if (st & 0x80)
7937c478bd9Sstevel@tonic-gate 				fprintf(stderr,
7947c478bd9Sstevel@tonic-gate 				gettext("%s: warning: the following command"
7957c478bd9Sstevel@tonic-gate 				" (process %d) was terminated by signal %d"
7967c478bd9Sstevel@tonic-gate 				" and dumped core\n"),
7977c478bd9Sstevel@tonic-gate 				myname, fk, st & 0x7f);
7987c478bd9Sstevel@tonic-gate 			else
7997c478bd9Sstevel@tonic-gate 				fprintf(stderr,
8007c478bd9Sstevel@tonic-gate 				gettext("%s: warning: the following command"
8017c478bd9Sstevel@tonic-gate 				" (process %d) was terminated by signal %d\n"),
8027c478bd9Sstevel@tonic-gate 				myname, fk, st & 0x7f);
8037c478bd9Sstevel@tonic-gate 
8047c478bd9Sstevel@tonic-gate 			prnt_cmd(stderr, fstype);
8057c478bd9Sstevel@tonic-gate 			status = ((st & 0xff) | 0x80);
8067c478bd9Sstevel@tonic-gate 		} else if (st & 0xff00)
8077c478bd9Sstevel@tonic-gate 			status = (st >> 8) & 0xff;
8087c478bd9Sstevel@tonic-gate 	}
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate 	return (status);
8117c478bd9Sstevel@tonic-gate }
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate do_exec(fstype, nargv)
8147c478bd9Sstevel@tonic-gate 	char	*fstype, *nargv[];
8157c478bd9Sstevel@tonic-gate {
8167c478bd9Sstevel@tonic-gate 	char	full_path[PATH_MAX];
8177c478bd9Sstevel@tonic-gate 	char	*vfs_path = VFS_PATH;
8187c478bd9Sstevel@tonic-gate 
819*355d6bb5Sswilcox 	if (strlen(fstype) > (size_t)FSTYPE_MAX) {
8207c478bd9Sstevel@tonic-gate 		fprintf(stderr,
8217c478bd9Sstevel@tonic-gate 			gettext("%s: Fstype %s exceeds %d characters\n"),
8227c478bd9Sstevel@tonic-gate 			myname, fstype, FSTYPE_MAX);
8237c478bd9Sstevel@tonic-gate 		exit(1);
8247c478bd9Sstevel@tonic-gate 	}
8257c478bd9Sstevel@tonic-gate 	/* build the full pathname of the fstype dependent command. */
8267c478bd9Sstevel@tonic-gate 	sprintf(full_path, "%s/%s/%s", vfs_path, fstype, myname);
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate 	/* set the new argv[0] to the filename */
8297c478bd9Sstevel@tonic-gate 	nargv[1] = myname;
8307c478bd9Sstevel@tonic-gate 	/* Try to exec the fstype dependent portion of the fsck. */
8317c478bd9Sstevel@tonic-gate 	execv(full_path, &nargv[1]);
8327c478bd9Sstevel@tonic-gate 	if (errno == EACCES) {
8337c478bd9Sstevel@tonic-gate 		fprintf(stderr,
8347c478bd9Sstevel@tonic-gate 			gettext("%s: cannot execute %s - permission denied\n"),
8357c478bd9Sstevel@tonic-gate 			myname, full_path);
8367c478bd9Sstevel@tonic-gate 	}
8377c478bd9Sstevel@tonic-gate 	if (errno == ENOEXEC) {
8387c478bd9Sstevel@tonic-gate 		nargv[0] = "sh";
8397c478bd9Sstevel@tonic-gate 		nargv[1] = full_path;
8407c478bd9Sstevel@tonic-gate 		execv("/sbin/sh", &nargv[0]);
8417c478bd9Sstevel@tonic-gate 	}
8427c478bd9Sstevel@tonic-gate 	/* second path to try */
8437c478bd9Sstevel@tonic-gate 	vfs_path = VFS_PATH2;
8447c478bd9Sstevel@tonic-gate 	/* build the full pathname of the fstype dependent command. */
8457c478bd9Sstevel@tonic-gate 	sprintf(full_path, "%s/%s/%s", vfs_path, fstype, myname);
8467c478bd9Sstevel@tonic-gate 
8477c478bd9Sstevel@tonic-gate 	/* set the new argv[0] to the filename */
8487c478bd9Sstevel@tonic-gate 	nargv[1] = myname;
8497c478bd9Sstevel@tonic-gate 	/* Try to exec the second fstype dependent portion of the fsck. */
8507c478bd9Sstevel@tonic-gate 	execv(full_path, &nargv[1]);
8517c478bd9Sstevel@tonic-gate 	if (errno == EACCES) {
8527c478bd9Sstevel@tonic-gate 		fprintf(stderr,
8537c478bd9Sstevel@tonic-gate 			gettext("%s: cannot execute %s - permission denied\n"),
8547c478bd9Sstevel@tonic-gate 			myname, full_path);
8557c478bd9Sstevel@tonic-gate 		exit(1);
8567c478bd9Sstevel@tonic-gate 	}
8577c478bd9Sstevel@tonic-gate 	if (errno == ENOEXEC) {
8587c478bd9Sstevel@tonic-gate 		nargv[0] = "sh";
8597c478bd9Sstevel@tonic-gate 		nargv[1] = full_path;
8607c478bd9Sstevel@tonic-gate 		execv("/sbin/sh", &nargv[0]);
8617c478bd9Sstevel@tonic-gate 	}
8627c478bd9Sstevel@tonic-gate 	fprintf(stderr,
8637c478bd9Sstevel@tonic-gate 		gettext("%s: operation not applicable to FSType %s\n"),
8647c478bd9Sstevel@tonic-gate 		myname, fstype);
8657c478bd9Sstevel@tonic-gate 	exit(1);
8667c478bd9Sstevel@tonic-gate }
8677c478bd9Sstevel@tonic-gate 
8687c478bd9Sstevel@tonic-gate prnt_cmd(fd, fstype)
8697c478bd9Sstevel@tonic-gate 	FILE	*fd;
8707c478bd9Sstevel@tonic-gate 	char	*fstype;
8717c478bd9Sstevel@tonic-gate {
8727c478bd9Sstevel@tonic-gate 	char	**argp;
8737c478bd9Sstevel@tonic-gate 
8747c478bd9Sstevel@tonic-gate 	fprintf(fd, "%s -F %s", myname, fstype);
8757c478bd9Sstevel@tonic-gate 	for (argp = &nargv[2]; *argp; argp++)
8767c478bd9Sstevel@tonic-gate 		fprintf(fd, " %s", *argp);
8777c478bd9Sstevel@tonic-gate 	fprintf(fd, "\n");
8787c478bd9Sstevel@tonic-gate }
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate vfserror(flag)
8817c478bd9Sstevel@tonic-gate 	int	flag;
8827c478bd9Sstevel@tonic-gate {
8837c478bd9Sstevel@tonic-gate 	switch (flag) {
8847c478bd9Sstevel@tonic-gate 	case VFS_TOOLONG:
8857c478bd9Sstevel@tonic-gate 		fprintf(stderr,
8867c478bd9Sstevel@tonic-gate 			gettext("%s: line in vfstab exceeds %d characters\n"),
8877c478bd9Sstevel@tonic-gate 			myname, VFS_LINE_MAX-2);
8887c478bd9Sstevel@tonic-gate 		break;
8897c478bd9Sstevel@tonic-gate 	case VFS_TOOFEW:
8907c478bd9Sstevel@tonic-gate 		fprintf(stderr,
8917c478bd9Sstevel@tonic-gate 			gettext("%s: line in vfstab has too few entries\n"),
8927c478bd9Sstevel@tonic-gate 			myname);
8937c478bd9Sstevel@tonic-gate 		break;
8947c478bd9Sstevel@tonic-gate 	case VFS_TOOMANY:
8957c478bd9Sstevel@tonic-gate 		fprintf(stderr,
8967c478bd9Sstevel@tonic-gate 			gettext("%s: line in vfstab has too many entries\n"),
8977c478bd9Sstevel@tonic-gate 			myname);
8987c478bd9Sstevel@tonic-gate 		break;
8997c478bd9Sstevel@tonic-gate 	}
9007c478bd9Sstevel@tonic-gate 	exit(1);
9017c478bd9Sstevel@tonic-gate }
9027c478bd9Sstevel@tonic-gate 
9037c478bd9Sstevel@tonic-gate int opterr = 1, optind = 1, optopt = 0;
9047c478bd9Sstevel@tonic-gate char *optarg = 0;
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate int
9077c478bd9Sstevel@tonic-gate getopt(int argc, char * const *argv, const char *opts)
9087c478bd9Sstevel@tonic-gate {
9097c478bd9Sstevel@tonic-gate 	static int sp = 1;
9107c478bd9Sstevel@tonic-gate 	register int c;
9117c478bd9Sstevel@tonic-gate 	register char *cp;
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate 	if (sp == 1)
9147c478bd9Sstevel@tonic-gate 		if (optind >= argc ||
9157c478bd9Sstevel@tonic-gate 		    argv[optind][0] != '-' || argv[optind][1] == '\0')
9167c478bd9Sstevel@tonic-gate 			return (-1);
9177c478bd9Sstevel@tonic-gate 		else if (strcmp(argv[optind], "--") == 0) {
9187c478bd9Sstevel@tonic-gate 			optind++;
9197c478bd9Sstevel@tonic-gate 			return (-1);
9207c478bd9Sstevel@tonic-gate 		}
9217c478bd9Sstevel@tonic-gate 	optopt = c = argv[optind][sp];
9227c478bd9Sstevel@tonic-gate 	if (c == ':' || (cp = strchr(opts, c)) == 0) {
9237c478bd9Sstevel@tonic-gate 		if (opterr)
9247c478bd9Sstevel@tonic-gate 			fprintf(stderr,
9257c478bd9Sstevel@tonic-gate 				gettext("%s: illegal option -- %c\n"),
9267c478bd9Sstevel@tonic-gate 				*argv, c);
9277c478bd9Sstevel@tonic-gate 		if (argv[optind][++sp] == '\0') {
9287c478bd9Sstevel@tonic-gate 			optind++;
9297c478bd9Sstevel@tonic-gate 			sp = 1;
9307c478bd9Sstevel@tonic-gate 		}
9317c478bd9Sstevel@tonic-gate 		return ('?');
9327c478bd9Sstevel@tonic-gate 	}
9337c478bd9Sstevel@tonic-gate 	if (*++cp == ':') {
9347c478bd9Sstevel@tonic-gate 		if (argv[optind][sp+1] != '\0')
9357c478bd9Sstevel@tonic-gate 			optarg = &argv[optind++][sp+1];
9367c478bd9Sstevel@tonic-gate 		else if (++optind >= argc) {
9377c478bd9Sstevel@tonic-gate 			if (opterr)
9387c478bd9Sstevel@tonic-gate 				fprintf(stderr,
9397c478bd9Sstevel@tonic-gate 		gettext("%s: option requires an argument -- %c\n"), *argv, c);
9407c478bd9Sstevel@tonic-gate 			sp = 1;
9417c478bd9Sstevel@tonic-gate 			return ('?');
9427c478bd9Sstevel@tonic-gate 		} else
9437c478bd9Sstevel@tonic-gate 			optarg = argv[optind++];
9447c478bd9Sstevel@tonic-gate 		sp = 1;
9457c478bd9Sstevel@tonic-gate 	} else if (*cp == ';') {
9467c478bd9Sstevel@tonic-gate 		if (argv[optind][++sp] != '\0')
9477c478bd9Sstevel@tonic-gate 			if (isoptarg(c, &argv[optind][sp])) {
9487c478bd9Sstevel@tonic-gate 				optarg = &argv[optind++][sp];
9497c478bd9Sstevel@tonic-gate 				sp = 1;
9507c478bd9Sstevel@tonic-gate 			} else
9517c478bd9Sstevel@tonic-gate 				optarg = NULL;
9527c478bd9Sstevel@tonic-gate 		else {
9537c478bd9Sstevel@tonic-gate 			sp = 1;
9547c478bd9Sstevel@tonic-gate 			if (++optind >= argc || !isoptarg(c, &argv[optind][0]))
9557c478bd9Sstevel@tonic-gate 				optarg = NULL;
9567c478bd9Sstevel@tonic-gate 			else
9577c478bd9Sstevel@tonic-gate 				optarg = argv[optind++];
9587c478bd9Sstevel@tonic-gate 		}
9597c478bd9Sstevel@tonic-gate 	} else {
9607c478bd9Sstevel@tonic-gate 		if (argv[optind][++sp] == '\0') {
9617c478bd9Sstevel@tonic-gate 			sp = 1;
9627c478bd9Sstevel@tonic-gate 			optind++;
9637c478bd9Sstevel@tonic-gate 		}
9647c478bd9Sstevel@tonic-gate 		optarg = NULL;
9657c478bd9Sstevel@tonic-gate 	}
9667c478bd9Sstevel@tonic-gate 	return (c);
9677c478bd9Sstevel@tonic-gate }
9687c478bd9Sstevel@tonic-gate 
9697c478bd9Sstevel@tonic-gate isoptarg(cc, arg)
9707c478bd9Sstevel@tonic-gate 	int	cc;
9717c478bd9Sstevel@tonic-gate 	char	*arg;
9727c478bd9Sstevel@tonic-gate {
9737c478bd9Sstevel@tonic-gate 	if (cc == 's' || cc == 'S') {
9747c478bd9Sstevel@tonic-gate 		while (*arg >= '0' && *arg <= '9')
9757c478bd9Sstevel@tonic-gate 			arg++;
9767c478bd9Sstevel@tonic-gate 		if (*arg++ != ':')
9777c478bd9Sstevel@tonic-gate 			return (0);
9787c478bd9Sstevel@tonic-gate 		while (*arg >= '0' && *arg <= '9')
9797c478bd9Sstevel@tonic-gate 			arg++;
9807c478bd9Sstevel@tonic-gate 		if (*arg)
9817c478bd9Sstevel@tonic-gate 			return (0);
9827c478bd9Sstevel@tonic-gate 		return (1);
9837c478bd9Sstevel@tonic-gate 	}
9847c478bd9Sstevel@tonic-gate 	return (0);
9857c478bd9Sstevel@tonic-gate }
9867c478bd9Sstevel@tonic-gate 
9877c478bd9Sstevel@tonic-gate usage()
9887c478bd9Sstevel@tonic-gate {
9897c478bd9Sstevel@tonic-gate 	fprintf(stderr,
9907c478bd9Sstevel@tonic-gate 		gettext("Usage:\n%s [-F FSType] [-V] [-m] [special ...]\n"
9917c478bd9Sstevel@tonic-gate 			"%s [-F FSType] [-V] [-y|Y|n|N]"
9927c478bd9Sstevel@tonic-gate 			" [-o specific_options] [special ...]\n"),
9937c478bd9Sstevel@tonic-gate 			myname, myname);
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate 	exit(1);
9967c478bd9Sstevel@tonic-gate }
997