1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1993 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <stdio.h> 34*7c478bd9Sstevel@tonic-gate #include <errno.h> 35*7c478bd9Sstevel@tonic-gate #include <limits.h> 36*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 37*7c478bd9Sstevel@tonic-gate #include <string.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/wait.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/vfstab.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/mntent.h> 43*7c478bd9Sstevel@tonic-gate #include <locale.h> 44*7c478bd9Sstevel@tonic-gate #include <libintl.h> 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate #define ARGV_MAX 16 47*7c478bd9Sstevel@tonic-gate #define FSTYPE_MAX 8 48*7c478bd9Sstevel@tonic-gate #define VFS_PATH "/usr/lib/fs" 49*7c478bd9Sstevel@tonic-gate #define VFS_PATH2 "/etc/fs" 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate #define CHECK(xx, yy)\ 52*7c478bd9Sstevel@tonic-gate if (xx == (yy)-1) {\ 53*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: too many arguments\n"), myname); \ 54*7c478bd9Sstevel@tonic-gate usage(); \ 55*7c478bd9Sstevel@tonic-gate } 56*7c478bd9Sstevel@tonic-gate #define OPTION(flag)\ 57*7c478bd9Sstevel@tonic-gate options++; \ 58*7c478bd9Sstevel@tonic-gate nargv[nargc++] = flag; \ 59*7c478bd9Sstevel@tonic-gate CHECK(nargc, ARGV_MAX); \ 60*7c478bd9Sstevel@tonic-gate break 61*7c478bd9Sstevel@tonic-gate #define OPTARG(flag)\ 62*7c478bd9Sstevel@tonic-gate nargv[nargc++] = flag; \ 63*7c478bd9Sstevel@tonic-gate CHECK(nargc, ARGV_MAX); \ 64*7c478bd9Sstevel@tonic-gate if (optarg) {\ 65*7c478bd9Sstevel@tonic-gate nargv[nargc++] = optarg; \ 66*7c478bd9Sstevel@tonic-gate CHECK(nargc, ARGV_MAX); \ 67*7c478bd9Sstevel@tonic-gate }\ 68*7c478bd9Sstevel@tonic-gate break 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate int nrun, ndisks; 72*7c478bd9Sstevel@tonic-gate int maxrun = 8; /* should be based on the machine resources */ 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate extern char *optarg; 75*7c478bd9Sstevel@tonic-gate extern int optind; 76*7c478bd9Sstevel@tonic-gate extern char *default_fstype(); 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate int nargc = 2; 79*7c478bd9Sstevel@tonic-gate int options = 0; 80*7c478bd9Sstevel@tonic-gate int mnt_passno = 0; 81*7c478bd9Sstevel@tonic-gate int exitstat = 0; 82*7c478bd9Sstevel@tonic-gate char *nargv[ARGV_MAX]; 83*7c478bd9Sstevel@tonic-gate char *myname, *fstype; 84*7c478bd9Sstevel@tonic-gate char *malloc(); 85*7c478bd9Sstevel@tonic-gate char vfstab[] = VFSTAB; 86*7c478bd9Sstevel@tonic-gate char pflg = 0, Vflg = 0; 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate /* 89*7c478bd9Sstevel@tonic-gate * Keep an idea of the last device arg type as a hint to the 90*7c478bd9Sstevel@tonic-gate * type of the next arg. In the case of mountall, it's very likely 91*7c478bd9Sstevel@tonic-gate * to be the same type and the next entry in the file. This should 92*7c478bd9Sstevel@tonic-gate * help speed vfstab lookups. 93*7c478bd9Sstevel@tonic-gate */ 94*7c478bd9Sstevel@tonic-gate enum dev_arg_t { UNKNOWN, SPECIAL, FSCKDEV, MOUNTPT }; 95*7c478bd9Sstevel@tonic-gate enum dev_arg_t arg_hint = UNKNOWN; 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate static struct devlist { 98*7c478bd9Sstevel@tonic-gate char *name; 99*7c478bd9Sstevel@tonic-gate char *fsname; 100*7c478bd9Sstevel@tonic-gate pid_t pid; 101*7c478bd9Sstevel@tonic-gate struct devlist *nxt; 102*7c478bd9Sstevel@tonic-gate } *newdev(), *getdev(); 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate /* 105*7c478bd9Sstevel@tonic-gate * private copy vfstab functions 106*7c478bd9Sstevel@tonic-gate */ 107*7c478bd9Sstevel@tonic-gate static struct vfstab vfsave = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate static int 110*7c478bd9Sstevel@tonic-gate vfdup(struct vfstab *vp) 111*7c478bd9Sstevel@tonic-gate { 112*7c478bd9Sstevel@tonic-gate if (vfsave.vfs_special != NULL) { 113*7c478bd9Sstevel@tonic-gate free(vfsave.vfs_special); 114*7c478bd9Sstevel@tonic-gate vfsave.vfs_special = NULL; 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate if ((vp->vfs_special != NULL) && 117*7c478bd9Sstevel@tonic-gate ((vfsave.vfs_special = strdup(vp->vfs_special)) == NULL)) { 118*7c478bd9Sstevel@tonic-gate perror(myname); 119*7c478bd9Sstevel@tonic-gate return (4); /* XXX */ 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate if (vfsave.vfs_fsckdev != NULL) { 123*7c478bd9Sstevel@tonic-gate free(vfsave.vfs_fsckdev); 124*7c478bd9Sstevel@tonic-gate vfsave.vfs_fsckdev = NULL; 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate if ((vp->vfs_fsckdev != NULL) && 127*7c478bd9Sstevel@tonic-gate ((vfsave.vfs_fsckdev = strdup(vp->vfs_fsckdev)) == NULL)) { 128*7c478bd9Sstevel@tonic-gate perror(myname); 129*7c478bd9Sstevel@tonic-gate return (4); /* XXX */ 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate if (vfsave.vfs_mountp != NULL) { 133*7c478bd9Sstevel@tonic-gate free(vfsave.vfs_mountp); 134*7c478bd9Sstevel@tonic-gate vfsave.vfs_mountp = NULL; 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate if ((vp->vfs_mountp != NULL) && 137*7c478bd9Sstevel@tonic-gate ((vfsave.vfs_mountp = strdup(vp->vfs_mountp)) == NULL)) { 138*7c478bd9Sstevel@tonic-gate perror(myname); 139*7c478bd9Sstevel@tonic-gate return (4); /* XXX */ 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate if (vfsave.vfs_fstype != NULL) { 143*7c478bd9Sstevel@tonic-gate free(vfsave.vfs_fstype); 144*7c478bd9Sstevel@tonic-gate vfsave.vfs_fstype = NULL; 145*7c478bd9Sstevel@tonic-gate } 146*7c478bd9Sstevel@tonic-gate if ((vp->vfs_fstype != NULL) && 147*7c478bd9Sstevel@tonic-gate ((vfsave.vfs_fstype = strdup(vp->vfs_fstype)) == NULL)) { 148*7c478bd9Sstevel@tonic-gate perror(myname); 149*7c478bd9Sstevel@tonic-gate return (4); /* XXX */ 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate if (vfsave.vfs_fsckpass != NULL) { 153*7c478bd9Sstevel@tonic-gate free(vfsave.vfs_fsckpass); 154*7c478bd9Sstevel@tonic-gate vfsave.vfs_fsckpass = NULL; 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate if ((vp->vfs_fsckpass != NULL) && 157*7c478bd9Sstevel@tonic-gate ((vfsave.vfs_fsckpass = strdup(vp->vfs_fsckpass)) == NULL)) { 158*7c478bd9Sstevel@tonic-gate perror(myname); 159*7c478bd9Sstevel@tonic-gate return (4); /* XXX */ 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate if (vfsave.vfs_automnt != NULL) { 163*7c478bd9Sstevel@tonic-gate free(vfsave.vfs_automnt); 164*7c478bd9Sstevel@tonic-gate vfsave.vfs_automnt = NULL; 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate if ((vp->vfs_automnt != NULL) && 167*7c478bd9Sstevel@tonic-gate ((vfsave.vfs_automnt = strdup(vp->vfs_automnt)) == NULL)) { 168*7c478bd9Sstevel@tonic-gate perror(myname); 169*7c478bd9Sstevel@tonic-gate return (4); /* XXX */ 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate if (vfsave.vfs_mntopts != NULL) { 173*7c478bd9Sstevel@tonic-gate free(vfsave.vfs_mntopts); 174*7c478bd9Sstevel@tonic-gate vfsave.vfs_mntopts = NULL; 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate if ((vp->vfs_mntopts != NULL) && 177*7c478bd9Sstevel@tonic-gate ((vfsave.vfs_mntopts = strdup(vp->vfs_mntopts)) == NULL)) { 178*7c478bd9Sstevel@tonic-gate perror(myname); 179*7c478bd9Sstevel@tonic-gate return (4); /* XXX */ 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate *vp = vfsave; 183*7c478bd9Sstevel@tonic-gate return (0); 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate static int 187*7c478bd9Sstevel@tonic-gate mygetvfsent(FILE *fp, struct vfstab *vp) 188*7c478bd9Sstevel@tonic-gate { 189*7c478bd9Sstevel@tonic-gate int error; 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate if ((error = getvfsent(fp, vp)) != 0) 192*7c478bd9Sstevel@tonic-gate return (error); 193*7c478bd9Sstevel@tonic-gate return (vfdup(vp)); 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate static int 197*7c478bd9Sstevel@tonic-gate mygetvfsany(FILE *fp, struct vfstab *vp, struct vfstab *vrefp) 198*7c478bd9Sstevel@tonic-gate { 199*7c478bd9Sstevel@tonic-gate int error; 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate if ((error = getvfsany(fp, vp, vrefp)) != 0) 202*7c478bd9Sstevel@tonic-gate return (error); 203*7c478bd9Sstevel@tonic-gate return (vfdup(vp)); 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate main(argc, argv) 207*7c478bd9Sstevel@tonic-gate int argc; 208*7c478bd9Sstevel@tonic-gate char *argv[]; 209*7c478bd9Sstevel@tonic-gate { 210*7c478bd9Sstevel@tonic-gate int cc, ret, other_than_ufs = 0; 211*7c478bd9Sstevel@tonic-gate int questflg = 0, Fflg = 0, Vflg = 0, sanity = 0; 212*7c478bd9Sstevel@tonic-gate char *subopt; 213*7c478bd9Sstevel@tonic-gate FILE *fd = NULL; 214*7c478bd9Sstevel@tonic-gate struct vfstab vget, vref; 215*7c478bd9Sstevel@tonic-gate int preencnt = 0; 216*7c478bd9Sstevel@tonic-gate struct devlist *dp, *devs = NULL; 217*7c478bd9Sstevel@tonic-gate int status; 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 220*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 221*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 222*7c478bd9Sstevel@tonic-gate #endif 223*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate myname = strrchr(argv[0], '/'); 226*7c478bd9Sstevel@tonic-gate if (myname) 227*7c478bd9Sstevel@tonic-gate myname++; 228*7c478bd9Sstevel@tonic-gate else 229*7c478bd9Sstevel@tonic-gate myname = argv[0]; 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate while ((cc = getopt(argc, argv, "?F:mnNo:VyY")) != -1) { 232*7c478bd9Sstevel@tonic-gate switch (cc) { 233*7c478bd9Sstevel@tonic-gate case '?': 234*7c478bd9Sstevel@tonic-gate questflg++; 235*7c478bd9Sstevel@tonic-gate if (questflg > 1) 236*7c478bd9Sstevel@tonic-gate usage(); 237*7c478bd9Sstevel@tonic-gate nargv[nargc++] = "-?"; 238*7c478bd9Sstevel@tonic-gate CHECK(nargc, ARGV_MAX); 239*7c478bd9Sstevel@tonic-gate break; 240*7c478bd9Sstevel@tonic-gate case 'F': 241*7c478bd9Sstevel@tonic-gate Fflg++; 242*7c478bd9Sstevel@tonic-gate /* check for more that one -F */ 243*7c478bd9Sstevel@tonic-gate if (Fflg > 1) { 244*7c478bd9Sstevel@tonic-gate fprintf(stderr, 245*7c478bd9Sstevel@tonic-gate gettext("%s: more than one fstype specified\n"), 246*7c478bd9Sstevel@tonic-gate myname); 247*7c478bd9Sstevel@tonic-gate usage(); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate fstype = optarg; 250*7c478bd9Sstevel@tonic-gate if (strlen(fstype) > (size_t) FSTYPE_MAX) { 251*7c478bd9Sstevel@tonic-gate fprintf(stderr, 252*7c478bd9Sstevel@tonic-gate gettext("%s: Fstype %s exceeds %d characters\n"), 253*7c478bd9Sstevel@tonic-gate myname, fstype, FSTYPE_MAX); 254*7c478bd9Sstevel@tonic-gate exit(1); 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate break; 257*7c478bd9Sstevel@tonic-gate case 'm': 258*7c478bd9Sstevel@tonic-gate sanity++; 259*7c478bd9Sstevel@tonic-gate OPTION("-m"); 260*7c478bd9Sstevel@tonic-gate case 'n': 261*7c478bd9Sstevel@tonic-gate OPTION("-n"); 262*7c478bd9Sstevel@tonic-gate case 'N': 263*7c478bd9Sstevel@tonic-gate OPTION("-N"); 264*7c478bd9Sstevel@tonic-gate case 'o': 265*7c478bd9Sstevel@tonic-gate subopt = optarg; 266*7c478bd9Sstevel@tonic-gate while (*subopt != '\0') { 267*7c478bd9Sstevel@tonic-gate if (*subopt == 'p') { 268*7c478bd9Sstevel@tonic-gate pflg++; 269*7c478bd9Sstevel@tonic-gate break; 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate subopt++; 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate OPTARG("-o"); 274*7c478bd9Sstevel@tonic-gate case 'V': 275*7c478bd9Sstevel@tonic-gate Vflg++; 276*7c478bd9Sstevel@tonic-gate if (Vflg > 1) 277*7c478bd9Sstevel@tonic-gate usage(); 278*7c478bd9Sstevel@tonic-gate break; 279*7c478bd9Sstevel@tonic-gate case 'y': 280*7c478bd9Sstevel@tonic-gate OPTION("-y"); 281*7c478bd9Sstevel@tonic-gate case 'Y': 282*7c478bd9Sstevel@tonic-gate OPTION("-Y"); 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate optarg = NULL; 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate /* copy '--' to specific */ 288*7c478bd9Sstevel@tonic-gate if (strcmp(argv[optind-1], "--") == 0) { 289*7c478bd9Sstevel@tonic-gate nargv[nargc++] = argv[optind-1]; 290*7c478bd9Sstevel@tonic-gate CHECK(nargc, ARGV_MAX); 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate if (questflg) { 294*7c478bd9Sstevel@tonic-gate if (Fflg) { 295*7c478bd9Sstevel@tonic-gate nargc = 2; 296*7c478bd9Sstevel@tonic-gate nargv[nargc++] = "-?"; 297*7c478bd9Sstevel@tonic-gate nargv[nargc] = NULL; 298*7c478bd9Sstevel@tonic-gate do_exec(fstype, nargv); 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate usage(); 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate if ((sanity) && (options > 1)) { 304*7c478bd9Sstevel@tonic-gate usage(); 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate if (optind == argc) { /* no device name is specified */ 308*7c478bd9Sstevel@tonic-gate if (fstype == NULL) { 309*7c478bd9Sstevel@tonic-gate if ((argc > 2) && (sanity)) { 310*7c478bd9Sstevel@tonic-gate usage(); 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate } 313*7c478bd9Sstevel@tonic-gate /* 314*7c478bd9Sstevel@tonic-gate * Try to check UFS filesystems first, then check other 315*7c478bd9Sstevel@tonic-gate * filesystems if they exist. 316*7c478bd9Sstevel@tonic-gate * Note: Parallel checking is only available in UFS for now. 317*7c478bd9Sstevel@tonic-gate */ 318*7c478bd9Sstevel@tonic-gate if (fstype == NULL || strcmp(fstype, MNTTYPE_UFS) == 0) { 319*7c478bd9Sstevel@tonic-gate if ((fd = fopen(vfstab, "r")) == NULL) { 320*7c478bd9Sstevel@tonic-gate fprintf(stderr, 321*7c478bd9Sstevel@tonic-gate gettext("%s: cannot open vfstab\n"), 322*7c478bd9Sstevel@tonic-gate myname); 323*7c478bd9Sstevel@tonic-gate exit(1); 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate while ((ret = mygetvfsent(fd, &vget)) == 0) { 326*7c478bd9Sstevel@tonic-gate if (strcmp(vget.vfs_fstype, MNTTYPE_UFS) && 327*7c478bd9Sstevel@tonic-gate numbers(vget.vfs_fsckpass)) { 328*7c478bd9Sstevel@tonic-gate other_than_ufs ++; 329*7c478bd9Sstevel@tonic-gate continue; 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate if (numbers(vget.vfs_fsckpass)) 332*7c478bd9Sstevel@tonic-gate mnt_passno = atoi(vget.vfs_fsckpass); 333*7c478bd9Sstevel@tonic-gate else 334*7c478bd9Sstevel@tonic-gate continue; 335*7c478bd9Sstevel@tonic-gate if (mnt_passno < 1) 336*7c478bd9Sstevel@tonic-gate continue; 337*7c478bd9Sstevel@tonic-gate if (pflg == 0 || mnt_passno == 1) { 338*7c478bd9Sstevel@tonic-gate status = execute(vget.vfs_fsckdev, 339*7c478bd9Sstevel@tonic-gate MNTTYPE_UFS, Vflg, fd); 340*7c478bd9Sstevel@tonic-gate /* return the highest exit code */ 341*7c478bd9Sstevel@tonic-gate if (status > exitstat) 342*7c478bd9Sstevel@tonic-gate exitstat = status; 343*7c478bd9Sstevel@tonic-gate } else if (preen_addev(vget.vfs_fsckdev) == 0) { 344*7c478bd9Sstevel@tonic-gate preencnt++; 345*7c478bd9Sstevel@tonic-gate dp = newdev(&vget); 346*7c478bd9Sstevel@tonic-gate dp->nxt = devs; 347*7c478bd9Sstevel@tonic-gate devs = dp; 348*7c478bd9Sstevel@tonic-gate } else { 349*7c478bd9Sstevel@tonic-gate /* 350*7c478bd9Sstevel@tonic-gate * preening setup failed, so 351*7c478bd9Sstevel@tonic-gate * execute serially here... 352*7c478bd9Sstevel@tonic-gate */ 353*7c478bd9Sstevel@tonic-gate fprintf(stderr, 354*7c478bd9Sstevel@tonic-gate gettext("%s: preen_addev error\n"), 355*7c478bd9Sstevel@tonic-gate myname); 356*7c478bd9Sstevel@tonic-gate status = execute(vget.vfs_fsckdev, 357*7c478bd9Sstevel@tonic-gate MNTTYPE_UFS, Vflg, fd); 358*7c478bd9Sstevel@tonic-gate /* return the highest exit code */ 359*7c478bd9Sstevel@tonic-gate if (status > exitstat) 360*7c478bd9Sstevel@tonic-gate exitstat = status; 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate fclose(fd); 364*7c478bd9Sstevel@tonic-gate if (ret > 0) 365*7c478bd9Sstevel@tonic-gate vfserror(ret); 366*7c478bd9Sstevel@tonic-gate if (pflg && exitstat == 0) { 367*7c478bd9Sstevel@tonic-gate fsck_dopreen(&devs, preencnt); 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate else 371*7c478bd9Sstevel@tonic-gate other_than_ufs = 1; 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate if (other_than_ufs) { 374*7c478bd9Sstevel@tonic-gate if ((fd = fopen(vfstab, "r")) == NULL) { 375*7c478bd9Sstevel@tonic-gate fprintf(stderr, 376*7c478bd9Sstevel@tonic-gate gettext("%s: cannot open vfstab\n"), 377*7c478bd9Sstevel@tonic-gate myname); 378*7c478bd9Sstevel@tonic-gate exit(1); 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate while ((ret = mygetvfsent(fd, &vget)) == 0) 381*7c478bd9Sstevel@tonic-gate if (strcmp(vget.vfs_fstype, MNTTYPE_UFS) && 382*7c478bd9Sstevel@tonic-gate numbers(vget.vfs_fsckpass) && 383*7c478bd9Sstevel@tonic-gate vget.vfs_fsckdev != NULL && 384*7c478bd9Sstevel@tonic-gate (fstype == NULL || 385*7c478bd9Sstevel@tonic-gate strcmp(fstype, vget.vfs_fstype) == 0)) { 386*7c478bd9Sstevel@tonic-gate status = execute(vget.vfs_fsckdev, 387*7c478bd9Sstevel@tonic-gate vget.vfs_fstype, Vflg, fd); 388*7c478bd9Sstevel@tonic-gate /* return the highest exit code */ 389*7c478bd9Sstevel@tonic-gate if (status > exitstat) 390*7c478bd9Sstevel@tonic-gate exitstat = status; 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate fclose(fd); 393*7c478bd9Sstevel@tonic-gate if (ret > 0) 394*7c478bd9Sstevel@tonic-gate vfserror(ret); 395*7c478bd9Sstevel@tonic-gate } 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate } else { /* device name is specified */ 398*7c478bd9Sstevel@tonic-gate if (fstype == NULL && (fd = fopen(vfstab, "r")) == NULL) { 399*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: cannot open vfstab\n"), 400*7c478bd9Sstevel@tonic-gate myname); 401*7c478bd9Sstevel@tonic-gate exit(1); 402*7c478bd9Sstevel@tonic-gate } 403*7c478bd9Sstevel@tonic-gate while (optind < argc) { 404*7c478bd9Sstevel@tonic-gate /* 405*7c478bd9Sstevel@tonic-gate * If "-F FStype" is specified, use that fs type. 406*7c478bd9Sstevel@tonic-gate * Otherwise, determine the fs type from /etc/vfstab 407*7c478bd9Sstevel@tonic-gate * if the entry exists. Otherwise, determine the 408*7c478bd9Sstevel@tonic-gate * local or remote fs type from /etc/default/df 409*7c478bd9Sstevel@tonic-gate * or /etc/dfs/fstypes respectively. 410*7c478bd9Sstevel@tonic-gate */ 411*7c478bd9Sstevel@tonic-gate if (fstype == NULL) { 412*7c478bd9Sstevel@tonic-gate if ((argc > 3) && (sanity)) { 413*7c478bd9Sstevel@tonic-gate usage(); 414*7c478bd9Sstevel@tonic-gate } 415*7c478bd9Sstevel@tonic-gate /* must check for both special && raw devices */ 416*7c478bd9Sstevel@tonic-gate vfsnull(&vref); 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate /* 419*7c478bd9Sstevel@tonic-gate * Find the vfstab entry for this device. 420*7c478bd9Sstevel@tonic-gate * arg_hint tells us what to try to match, 421*7c478bd9Sstevel@tonic-gate * based on the type of the last arg. If 422*7c478bd9Sstevel@tonic-gate * arg_hint equals UNKNOWN, then we're not 423*7c478bd9Sstevel@tonic-gate * sure of the type and need to fallthrough 424*7c478bd9Sstevel@tonic-gate * all 3 possibilities for vfstab lookup. 425*7c478bd9Sstevel@tonic-gate * Try it as a mountpt first, since that's 426*7c478bd9Sstevel@tonic-gate * what mountall gives us. 427*7c478bd9Sstevel@tonic-gate */ 428*7c478bd9Sstevel@tonic-gate try_again: 429*7c478bd9Sstevel@tonic-gate switch (arg_hint) { 430*7c478bd9Sstevel@tonic-gate case UNKNOWN: 431*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate case MOUNTPT: 434*7c478bd9Sstevel@tonic-gate vref.vfs_mountp = argv[optind]; 435*7c478bd9Sstevel@tonic-gate if ((ret = mygetvfsany(fd, &vget, 436*7c478bd9Sstevel@tonic-gate &vref)) == -1 || 437*7c478bd9Sstevel@tonic-gate vget.vfs_fstype == NULL) { 438*7c478bd9Sstevel@tonic-gate 439*7c478bd9Sstevel@tonic-gate vref.vfs_mountp = NULL; 440*7c478bd9Sstevel@tonic-gate rewind(fd); 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate if (arg_hint == MOUNTPT) { 443*7c478bd9Sstevel@tonic-gate arg_hint = UNKNOWN; 444*7c478bd9Sstevel@tonic-gate goto try_again; 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 447*7c478bd9Sstevel@tonic-gate } else { 448*7c478bd9Sstevel@tonic-gate /* Found it */ 449*7c478bd9Sstevel@tonic-gate if (vget.vfs_fsckdev != NULL) { 450*7c478bd9Sstevel@tonic-gate argv[optind] = 451*7c478bd9Sstevel@tonic-gate vget.vfs_fsckdev; 452*7c478bd9Sstevel@tonic-gate } 453*7c478bd9Sstevel@tonic-gate arg_hint = MOUNTPT; 454*7c478bd9Sstevel@tonic-gate break; 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate case FSCKDEV: 458*7c478bd9Sstevel@tonic-gate vref.vfs_fsckdev = argv[optind]; 459*7c478bd9Sstevel@tonic-gate if ((ret = mygetvfsany(fd, &vget, 460*7c478bd9Sstevel@tonic-gate &vref)) == -1 || 461*7c478bd9Sstevel@tonic-gate vget.vfs_fstype == NULL) { 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate vref.vfs_fsckdev = NULL; 464*7c478bd9Sstevel@tonic-gate rewind(fd); 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate if (arg_hint == FSCKDEV) { 467*7c478bd9Sstevel@tonic-gate arg_hint = UNKNOWN; 468*7c478bd9Sstevel@tonic-gate goto try_again; 469*7c478bd9Sstevel@tonic-gate } 470*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 471*7c478bd9Sstevel@tonic-gate } else { 472*7c478bd9Sstevel@tonic-gate /* Found it */ 473*7c478bd9Sstevel@tonic-gate arg_hint = FSCKDEV; 474*7c478bd9Sstevel@tonic-gate break; 475*7c478bd9Sstevel@tonic-gate } 476*7c478bd9Sstevel@tonic-gate 477*7c478bd9Sstevel@tonic-gate case SPECIAL: 478*7c478bd9Sstevel@tonic-gate vref.vfs_special = argv[optind]; 479*7c478bd9Sstevel@tonic-gate if ((ret = mygetvfsany(fd, &vget, 480*7c478bd9Sstevel@tonic-gate &vref)) == -1 || 481*7c478bd9Sstevel@tonic-gate vget.vfs_fstype == NULL) { 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate vref.vfs_special = NULL; 484*7c478bd9Sstevel@tonic-gate rewind(fd); 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate if (arg_hint == SPECIAL) { 487*7c478bd9Sstevel@tonic-gate arg_hint = UNKNOWN; 488*7c478bd9Sstevel@tonic-gate goto try_again; 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 491*7c478bd9Sstevel@tonic-gate } else { 492*7c478bd9Sstevel@tonic-gate /* Found it */ 493*7c478bd9Sstevel@tonic-gate arg_hint = SPECIAL; 494*7c478bd9Sstevel@tonic-gate break; 495*7c478bd9Sstevel@tonic-gate } 496*7c478bd9Sstevel@tonic-gate } 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate if (ret == 0 && vget.vfs_fstype) { 499*7c478bd9Sstevel@tonic-gate if ((pflg) && (strcmp(vget.vfs_fstype, 500*7c478bd9Sstevel@tonic-gate MNTTYPE_UFS) == 0) && (preen_addev( 501*7c478bd9Sstevel@tonic-gate vget.vfs_fsckdev) == 0)) { 502*7c478bd9Sstevel@tonic-gate preencnt++; 503*7c478bd9Sstevel@tonic-gate dp = newdev(&vget); 504*7c478bd9Sstevel@tonic-gate dp->nxt = devs; 505*7c478bd9Sstevel@tonic-gate devs = dp; 506*7c478bd9Sstevel@tonic-gate } else { 507*7c478bd9Sstevel@tonic-gate status = execute(argv[optind], 508*7c478bd9Sstevel@tonic-gate vget.vfs_fstype, Vflg, fd); 509*7c478bd9Sstevel@tonic-gate if (status > exitstat) 510*7c478bd9Sstevel@tonic-gate exitstat = status; 511*7c478bd9Sstevel@tonic-gate } 512*7c478bd9Sstevel@tonic-gate } else if (ret == -1 || 513*7c478bd9Sstevel@tonic-gate vget.vfs_fstype == NULL) { 514*7c478bd9Sstevel@tonic-gate fstype = 515*7c478bd9Sstevel@tonic-gate default_fstype(argv[optind]); 516*7c478bd9Sstevel@tonic-gate status = execute(argv[optind], fstype, 517*7c478bd9Sstevel@tonic-gate Vflg, fd); 518*7c478bd9Sstevel@tonic-gate /* return the highest exit code */ 519*7c478bd9Sstevel@tonic-gate if (status > exitstat) 520*7c478bd9Sstevel@tonic-gate exitstat = status; 521*7c478bd9Sstevel@tonic-gate } else 522*7c478bd9Sstevel@tonic-gate vfserror(ret); 523*7c478bd9Sstevel@tonic-gate } else { 524*7c478bd9Sstevel@tonic-gate status = execute(argv[optind], fstype, 525*7c478bd9Sstevel@tonic-gate Vflg, NULL); 526*7c478bd9Sstevel@tonic-gate /* return the highest exit code */ 527*7c478bd9Sstevel@tonic-gate if (status > exitstat) 528*7c478bd9Sstevel@tonic-gate exitstat = status; 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate optind++; 531*7c478bd9Sstevel@tonic-gate } 532*7c478bd9Sstevel@tonic-gate if (fd != NULL) 533*7c478bd9Sstevel@tonic-gate fclose(fd); 534*7c478bd9Sstevel@tonic-gate if ((pflg) && (exitstat == 0)) { 535*7c478bd9Sstevel@tonic-gate fsck_dopreen(&devs, preencnt); 536*7c478bd9Sstevel@tonic-gate } 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate exit(exitstat); 539*7c478bd9Sstevel@tonic-gate } 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate static 542*7c478bd9Sstevel@tonic-gate fsck_dopreen(devp, ndevs) 543*7c478bd9Sstevel@tonic-gate struct devlist **devp; 544*7c478bd9Sstevel@tonic-gate int ndevs; 545*7c478bd9Sstevel@tonic-gate { 546*7c478bd9Sstevel@tonic-gate char name[1024]; 547*7c478bd9Sstevel@tonic-gate int rc; 548*7c478bd9Sstevel@tonic-gate register int i; 549*7c478bd9Sstevel@tonic-gate struct devlist *bl, *bdp; 550*7c478bd9Sstevel@tonic-gate struct devlist *badlist; 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate bl = badlist = NULL; 553*7c478bd9Sstevel@tonic-gate while (ndevs > 0) { 554*7c478bd9Sstevel@tonic-gate if (nrun > maxrun) 555*7c478bd9Sstevel@tonic-gate waiter(&bl, &badlist); 556*7c478bd9Sstevel@tonic-gate rc = preen_getdev(name); 557*7c478bd9Sstevel@tonic-gate switch (rc) { 558*7c478bd9Sstevel@tonic-gate case 0: 559*7c478bd9Sstevel@tonic-gate break; 560*7c478bd9Sstevel@tonic-gate case 1: 561*7c478bd9Sstevel@tonic-gate bdp = getdev(name, devp); 562*7c478bd9Sstevel@tonic-gate if (bdp == NULL) { 563*7c478bd9Sstevel@tonic-gate fprintf(stderr, 564*7c478bd9Sstevel@tonic-gate gettext("%s: unknown dev: `%s'\n"), 565*7c478bd9Sstevel@tonic-gate myname, name); 566*7c478bd9Sstevel@tonic-gate exit(1); 567*7c478bd9Sstevel@tonic-gate } 568*7c478bd9Sstevel@tonic-gate bdp->nxt = bl; 569*7c478bd9Sstevel@tonic-gate bl = bdp; 570*7c478bd9Sstevel@tonic-gate startdisk(bdp); 571*7c478bd9Sstevel@tonic-gate ndevs--; 572*7c478bd9Sstevel@tonic-gate break; 573*7c478bd9Sstevel@tonic-gate case 2: 574*7c478bd9Sstevel@tonic-gate waiter(&bl, &badlist); 575*7c478bd9Sstevel@tonic-gate break; 576*7c478bd9Sstevel@tonic-gate default: 577*7c478bd9Sstevel@tonic-gate fprintf(stderr, 578*7c478bd9Sstevel@tonic-gate gettext("%s: bad return `%d' from preen_getdev\n"), 579*7c478bd9Sstevel@tonic-gate myname, rc); 580*7c478bd9Sstevel@tonic-gate break; 581*7c478bd9Sstevel@tonic-gate } 582*7c478bd9Sstevel@tonic-gate } 583*7c478bd9Sstevel@tonic-gate while (bl != NULL) { 584*7c478bd9Sstevel@tonic-gate waiter(&bl, &badlist); 585*7c478bd9Sstevel@tonic-gate } 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate if (badlist != NULL) 588*7c478bd9Sstevel@tonic-gate print_badlist(badlist); 589*7c478bd9Sstevel@tonic-gate } 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate static 592*7c478bd9Sstevel@tonic-gate startdisk(dp) 593*7c478bd9Sstevel@tonic-gate struct devlist *dp; 594*7c478bd9Sstevel@tonic-gate { 595*7c478bd9Sstevel@tonic-gate pid_t pid; 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate nrun++; 598*7c478bd9Sstevel@tonic-gate if ((pid = fork()) == -1) { 599*7c478bd9Sstevel@tonic-gate perror("fork"); 600*7c478bd9Sstevel@tonic-gate exit(1); 601*7c478bd9Sstevel@tonic-gate } else if (pid == 0) { 602*7c478bd9Sstevel@tonic-gate exitstat = execute(dp->name, MNTTYPE_UFS, Vflg, NULL); 603*7c478bd9Sstevel@tonic-gate exit(exitstat); 604*7c478bd9Sstevel@tonic-gate } else { 605*7c478bd9Sstevel@tonic-gate dp->pid = pid; 606*7c478bd9Sstevel@tonic-gate } 607*7c478bd9Sstevel@tonic-gate } 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate static 610*7c478bd9Sstevel@tonic-gate waiter(blp, badlist) 611*7c478bd9Sstevel@tonic-gate struct devlist **blp; 612*7c478bd9Sstevel@tonic-gate struct devlist **badlist; 613*7c478bd9Sstevel@tonic-gate { 614*7c478bd9Sstevel@tonic-gate pid_t curpid; 615*7c478bd9Sstevel@tonic-gate int status; 616*7c478bd9Sstevel@tonic-gate register struct devlist *bdp, *pbdp; 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate curpid = wait(&status); 619*7c478bd9Sstevel@tonic-gate if (curpid == -1) { 620*7c478bd9Sstevel@tonic-gate perror("wait"); 621*7c478bd9Sstevel@tonic-gate exit(1); 622*7c478bd9Sstevel@tonic-gate } 623*7c478bd9Sstevel@tonic-gate 624*7c478bd9Sstevel@tonic-gate for (pbdp = NULL, bdp = *blp; bdp != NULL; pbdp = bdp, bdp = bdp->nxt) { 625*7c478bd9Sstevel@tonic-gate if (bdp->pid == curpid) { 626*7c478bd9Sstevel@tonic-gate break; 627*7c478bd9Sstevel@tonic-gate } 628*7c478bd9Sstevel@tonic-gate } 629*7c478bd9Sstevel@tonic-gate if (bdp == NULL) 630*7c478bd9Sstevel@tonic-gate return; 631*7c478bd9Sstevel@tonic-gate nrun--; 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate if (pbdp) 634*7c478bd9Sstevel@tonic-gate pbdp->nxt = bdp->nxt; 635*7c478bd9Sstevel@tonic-gate else 636*7c478bd9Sstevel@tonic-gate *blp = bdp->nxt; 637*7c478bd9Sstevel@tonic-gate preen_releasedev(bdp->name); 638*7c478bd9Sstevel@tonic-gate 639*7c478bd9Sstevel@tonic-gate if (WTERMSIG(status)) { 640*7c478bd9Sstevel@tonic-gate printf(gettext("%s (%s): EXITED WITH SIGNAL %d\n"), 641*7c478bd9Sstevel@tonic-gate bdp->name, bdp->fsname, WTERMSIG(status)); 642*7c478bd9Sstevel@tonic-gate status = status&0377 | 8<<8; 643*7c478bd9Sstevel@tonic-gate } 644*7c478bd9Sstevel@tonic-gate if (WHIBYTE(status) != 0) { 645*7c478bd9Sstevel@tonic-gate if (WHIBYTE(status) > exitstat) 646*7c478bd9Sstevel@tonic-gate exitstat = WHIBYTE(status); 647*7c478bd9Sstevel@tonic-gate while (*badlist != NULL) 648*7c478bd9Sstevel@tonic-gate badlist = &(*badlist)->nxt; 649*7c478bd9Sstevel@tonic-gate *badlist = bdp; 650*7c478bd9Sstevel@tonic-gate bdp->nxt = NULL; 651*7c478bd9Sstevel@tonic-gate } 652*7c478bd9Sstevel@tonic-gate } 653*7c478bd9Sstevel@tonic-gate 654*7c478bd9Sstevel@tonic-gate static 655*7c478bd9Sstevel@tonic-gate print_badlist(lp) 656*7c478bd9Sstevel@tonic-gate struct devlist *lp; 657*7c478bd9Sstevel@tonic-gate { 658*7c478bd9Sstevel@tonic-gate int x, len; 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate printf( 661*7c478bd9Sstevel@tonic-gate gettext("\nTHE FOLLOWING FILE SYSTEM(S) HAD AN UNEXPECTED INCONSISTENCY:")); 662*7c478bd9Sstevel@tonic-gate for (x = 3; lp != NULL; lp = lp->nxt) { 663*7c478bd9Sstevel@tonic-gate len = strlen(lp->name) + strlen(lp->fsname) + 5; 664*7c478bd9Sstevel@tonic-gate x += len; 665*7c478bd9Sstevel@tonic-gate if (x >= 80) { 666*7c478bd9Sstevel@tonic-gate printf("\n "); 667*7c478bd9Sstevel@tonic-gate x = len + 3; 668*7c478bd9Sstevel@tonic-gate } else { 669*7c478bd9Sstevel@tonic-gate printf(" "); 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate printf("%s (%s)%s", lp->name, lp->fsname, 672*7c478bd9Sstevel@tonic-gate lp->nxt ? "," : "\n"); 673*7c478bd9Sstevel@tonic-gate } 674*7c478bd9Sstevel@tonic-gate } 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate /* 677*7c478bd9Sstevel@tonic-gate * allocate and initialize a `devlist' structure 678*7c478bd9Sstevel@tonic-gate */ 679*7c478bd9Sstevel@tonic-gate static 680*7c478bd9Sstevel@tonic-gate struct devlist * 681*7c478bd9Sstevel@tonic-gate newdev(vfsp) 682*7c478bd9Sstevel@tonic-gate struct vfstab *vfsp; 683*7c478bd9Sstevel@tonic-gate { 684*7c478bd9Sstevel@tonic-gate struct devlist *dp; 685*7c478bd9Sstevel@tonic-gate extern char *strdup(); 686*7c478bd9Sstevel@tonic-gate 687*7c478bd9Sstevel@tonic-gate dp = (struct devlist *)malloc(sizeof (struct devlist)); 688*7c478bd9Sstevel@tonic-gate if (dp == NULL) { 689*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: out of memory\n"), myname); 690*7c478bd9Sstevel@tonic-gate exit(1); 691*7c478bd9Sstevel@tonic-gate } 692*7c478bd9Sstevel@tonic-gate dp->name = strdup(vfsp->vfs_fsckdev); 693*7c478bd9Sstevel@tonic-gate dp->fsname = strdup(vfsp->vfs_mountp); 694*7c478bd9Sstevel@tonic-gate if (dp->name == NULL || dp->fsname == NULL) { 695*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: out of memory\n"), myname); 696*7c478bd9Sstevel@tonic-gate exit(1); 697*7c478bd9Sstevel@tonic-gate } 698*7c478bd9Sstevel@tonic-gate return (dp); 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate /* 702*7c478bd9Sstevel@tonic-gate * locate the devlist structure in the given list that matches `name'. 703*7c478bd9Sstevel@tonic-gate * If found, the structure is removed from the list, and a pointer to 704*7c478bd9Sstevel@tonic-gate * it is returned. If not, NULL is returned. 705*7c478bd9Sstevel@tonic-gate */ 706*7c478bd9Sstevel@tonic-gate static 707*7c478bd9Sstevel@tonic-gate struct devlist * 708*7c478bd9Sstevel@tonic-gate getdev(name, list) 709*7c478bd9Sstevel@tonic-gate char *name; 710*7c478bd9Sstevel@tonic-gate struct devlist **list; 711*7c478bd9Sstevel@tonic-gate { 712*7c478bd9Sstevel@tonic-gate register struct devlist *p, *lp; 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate for (lp = NULL, p = *list; p != NULL; lp = p, p = p->nxt) { 715*7c478bd9Sstevel@tonic-gate if (strcmp(p->name, name) == 0) 716*7c478bd9Sstevel@tonic-gate break; 717*7c478bd9Sstevel@tonic-gate } 718*7c478bd9Sstevel@tonic-gate 719*7c478bd9Sstevel@tonic-gate if (p != NULL) { 720*7c478bd9Sstevel@tonic-gate if (lp != NULL) 721*7c478bd9Sstevel@tonic-gate lp->nxt = p->nxt; 722*7c478bd9Sstevel@tonic-gate else 723*7c478bd9Sstevel@tonic-gate *list = p->nxt; 724*7c478bd9Sstevel@tonic-gate } 725*7c478bd9Sstevel@tonic-gate return (p); 726*7c478bd9Sstevel@tonic-gate } 727*7c478bd9Sstevel@tonic-gate 728*7c478bd9Sstevel@tonic-gate /* see if all numbers */ 729*7c478bd9Sstevel@tonic-gate numbers(yp) 730*7c478bd9Sstevel@tonic-gate char *yp; 731*7c478bd9Sstevel@tonic-gate { 732*7c478bd9Sstevel@tonic-gate if (yp == NULL) 733*7c478bd9Sstevel@tonic-gate return (0); 734*7c478bd9Sstevel@tonic-gate while ('0' <= *yp && *yp <= '9') 735*7c478bd9Sstevel@tonic-gate yp++; 736*7c478bd9Sstevel@tonic-gate if (*yp) 737*7c478bd9Sstevel@tonic-gate return (0); 738*7c478bd9Sstevel@tonic-gate return (1); 739*7c478bd9Sstevel@tonic-gate } 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate execute(fsckdev, fstype, Vflg, fd) 742*7c478bd9Sstevel@tonic-gate char *fsckdev, *fstype; 743*7c478bd9Sstevel@tonic-gate int Vflg; 744*7c478bd9Sstevel@tonic-gate FILE *fd; 745*7c478bd9Sstevel@tonic-gate { 746*7c478bd9Sstevel@tonic-gate int st; 747*7c478bd9Sstevel@tonic-gate pid_t fk; 748*7c478bd9Sstevel@tonic-gate char full_path[PATH_MAX]; 749*7c478bd9Sstevel@tonic-gate char *vfs_path = VFS_PATH; 750*7c478bd9Sstevel@tonic-gate int status = 0; 751*7c478bd9Sstevel@tonic-gate 752*7c478bd9Sstevel@tonic-gate nargv[nargc] = fsckdev; 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate if (Vflg) { 755*7c478bd9Sstevel@tonic-gate prnt_cmd(stdout, fstype); 756*7c478bd9Sstevel@tonic-gate return (0); 757*7c478bd9Sstevel@tonic-gate } 758*7c478bd9Sstevel@tonic-gate 759*7c478bd9Sstevel@tonic-gate if (fd) 760*7c478bd9Sstevel@tonic-gate fcntl(fileno(fd), F_SETFD, 1); /* close on exec */ 761*7c478bd9Sstevel@tonic-gate 762*7c478bd9Sstevel@tonic-gate if ((fk = fork()) == (pid_t)-1) { 763*7c478bd9Sstevel@tonic-gate fprintf(stderr, 764*7c478bd9Sstevel@tonic-gate gettext("%s: cannot fork. Try again later\n"), 765*7c478bd9Sstevel@tonic-gate myname); 766*7c478bd9Sstevel@tonic-gate perror(myname); 767*7c478bd9Sstevel@tonic-gate exit(1); 768*7c478bd9Sstevel@tonic-gate } 769*7c478bd9Sstevel@tonic-gate 770*7c478bd9Sstevel@tonic-gate if (fk == 0) { 771*7c478bd9Sstevel@tonic-gate /* Try to exec the fstype dependent portion of the fsck. */ 772*7c478bd9Sstevel@tonic-gate do_exec(fstype, nargv); 773*7c478bd9Sstevel@tonic-gate } else { 774*7c478bd9Sstevel@tonic-gate /* parent waits for child */ 775*7c478bd9Sstevel@tonic-gate if (wait(&st) == (pid_t)-1) { 776*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: bad wait\n"), myname); 777*7c478bd9Sstevel@tonic-gate perror(myname); 778*7c478bd9Sstevel@tonic-gate exit(1); 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate 781*7c478bd9Sstevel@tonic-gate if ((st & 0xff) == 0x7f) { 782*7c478bd9Sstevel@tonic-gate fprintf(stderr, 783*7c478bd9Sstevel@tonic-gate gettext("%s: warning: the following command" 784*7c478bd9Sstevel@tonic-gate " (process %d) was stopped by signal %d\n"), 785*7c478bd9Sstevel@tonic-gate myname, fk, (st >> 8) & 0xff); 786*7c478bd9Sstevel@tonic-gate prnt_cmd(stderr, fstype); 787*7c478bd9Sstevel@tonic-gate status = ((st >> 8) & 0xff) | 0x80; 788*7c478bd9Sstevel@tonic-gate } else if (st & 0xff) { 789*7c478bd9Sstevel@tonic-gate if (st & 0x80) 790*7c478bd9Sstevel@tonic-gate fprintf(stderr, 791*7c478bd9Sstevel@tonic-gate gettext("%s: warning: the following command" 792*7c478bd9Sstevel@tonic-gate " (process %d) was terminated by signal %d" 793*7c478bd9Sstevel@tonic-gate " and dumped core\n"), 794*7c478bd9Sstevel@tonic-gate myname, fk, st & 0x7f); 795*7c478bd9Sstevel@tonic-gate else 796*7c478bd9Sstevel@tonic-gate fprintf(stderr, 797*7c478bd9Sstevel@tonic-gate gettext("%s: warning: the following command" 798*7c478bd9Sstevel@tonic-gate " (process %d) was terminated by signal %d\n"), 799*7c478bd9Sstevel@tonic-gate myname, fk, st & 0x7f); 800*7c478bd9Sstevel@tonic-gate 801*7c478bd9Sstevel@tonic-gate prnt_cmd(stderr, fstype); 802*7c478bd9Sstevel@tonic-gate status = ((st & 0xff) | 0x80); 803*7c478bd9Sstevel@tonic-gate } else if (st & 0xff00) 804*7c478bd9Sstevel@tonic-gate status = (st >> 8) & 0xff; 805*7c478bd9Sstevel@tonic-gate } 806*7c478bd9Sstevel@tonic-gate 807*7c478bd9Sstevel@tonic-gate return (status); 808*7c478bd9Sstevel@tonic-gate } 809*7c478bd9Sstevel@tonic-gate 810*7c478bd9Sstevel@tonic-gate do_exec(fstype, nargv) 811*7c478bd9Sstevel@tonic-gate char *fstype, *nargv[]; 812*7c478bd9Sstevel@tonic-gate { 813*7c478bd9Sstevel@tonic-gate char full_path[PATH_MAX]; 814*7c478bd9Sstevel@tonic-gate char *vfs_path = VFS_PATH; 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate if (strlen(fstype) > (size_t) FSTYPE_MAX) { 817*7c478bd9Sstevel@tonic-gate fprintf(stderr, 818*7c478bd9Sstevel@tonic-gate gettext("%s: Fstype %s exceeds %d characters\n"), 819*7c478bd9Sstevel@tonic-gate myname, fstype, FSTYPE_MAX); 820*7c478bd9Sstevel@tonic-gate exit(1); 821*7c478bd9Sstevel@tonic-gate } 822*7c478bd9Sstevel@tonic-gate /* build the full pathname of the fstype dependent command. */ 823*7c478bd9Sstevel@tonic-gate sprintf(full_path, "%s/%s/%s", vfs_path, fstype, myname); 824*7c478bd9Sstevel@tonic-gate 825*7c478bd9Sstevel@tonic-gate /* set the new argv[0] to the filename */ 826*7c478bd9Sstevel@tonic-gate nargv[1] = myname; 827*7c478bd9Sstevel@tonic-gate /* Try to exec the fstype dependent portion of the fsck. */ 828*7c478bd9Sstevel@tonic-gate execv(full_path, &nargv[1]); 829*7c478bd9Sstevel@tonic-gate if (errno == EACCES) { 830*7c478bd9Sstevel@tonic-gate fprintf(stderr, 831*7c478bd9Sstevel@tonic-gate gettext("%s: cannot execute %s - permission denied\n"), 832*7c478bd9Sstevel@tonic-gate myname, full_path); 833*7c478bd9Sstevel@tonic-gate } 834*7c478bd9Sstevel@tonic-gate if (errno == ENOEXEC) { 835*7c478bd9Sstevel@tonic-gate nargv[0] = "sh"; 836*7c478bd9Sstevel@tonic-gate nargv[1] = full_path; 837*7c478bd9Sstevel@tonic-gate execv("/sbin/sh", &nargv[0]); 838*7c478bd9Sstevel@tonic-gate } 839*7c478bd9Sstevel@tonic-gate /* second path to try */ 840*7c478bd9Sstevel@tonic-gate vfs_path = VFS_PATH2; 841*7c478bd9Sstevel@tonic-gate /* build the full pathname of the fstype dependent command. */ 842*7c478bd9Sstevel@tonic-gate sprintf(full_path, "%s/%s/%s", vfs_path, fstype, myname); 843*7c478bd9Sstevel@tonic-gate 844*7c478bd9Sstevel@tonic-gate /* set the new argv[0] to the filename */ 845*7c478bd9Sstevel@tonic-gate nargv[1] = myname; 846*7c478bd9Sstevel@tonic-gate /* Try to exec the second fstype dependent portion of the fsck. */ 847*7c478bd9Sstevel@tonic-gate execv(full_path, &nargv[1]); 848*7c478bd9Sstevel@tonic-gate if (errno == EACCES) { 849*7c478bd9Sstevel@tonic-gate fprintf(stderr, 850*7c478bd9Sstevel@tonic-gate gettext("%s: cannot execute %s - permission denied\n"), 851*7c478bd9Sstevel@tonic-gate myname, full_path); 852*7c478bd9Sstevel@tonic-gate exit(1); 853*7c478bd9Sstevel@tonic-gate } 854*7c478bd9Sstevel@tonic-gate if (errno == ENOEXEC) { 855*7c478bd9Sstevel@tonic-gate nargv[0] = "sh"; 856*7c478bd9Sstevel@tonic-gate nargv[1] = full_path; 857*7c478bd9Sstevel@tonic-gate execv("/sbin/sh", &nargv[0]); 858*7c478bd9Sstevel@tonic-gate } 859*7c478bd9Sstevel@tonic-gate fprintf(stderr, 860*7c478bd9Sstevel@tonic-gate gettext("%s: operation not applicable to FSType %s\n"), 861*7c478bd9Sstevel@tonic-gate myname, fstype); 862*7c478bd9Sstevel@tonic-gate exit(1); 863*7c478bd9Sstevel@tonic-gate } 864*7c478bd9Sstevel@tonic-gate 865*7c478bd9Sstevel@tonic-gate prnt_cmd(fd, fstype) 866*7c478bd9Sstevel@tonic-gate FILE *fd; 867*7c478bd9Sstevel@tonic-gate char *fstype; 868*7c478bd9Sstevel@tonic-gate { 869*7c478bd9Sstevel@tonic-gate char **argp; 870*7c478bd9Sstevel@tonic-gate 871*7c478bd9Sstevel@tonic-gate fprintf(fd, "%s -F %s", myname, fstype); 872*7c478bd9Sstevel@tonic-gate for (argp = &nargv[2]; *argp; argp++) 873*7c478bd9Sstevel@tonic-gate fprintf(fd, " %s", *argp); 874*7c478bd9Sstevel@tonic-gate fprintf(fd, "\n"); 875*7c478bd9Sstevel@tonic-gate } 876*7c478bd9Sstevel@tonic-gate 877*7c478bd9Sstevel@tonic-gate vfserror(flag) 878*7c478bd9Sstevel@tonic-gate int flag; 879*7c478bd9Sstevel@tonic-gate { 880*7c478bd9Sstevel@tonic-gate switch (flag) { 881*7c478bd9Sstevel@tonic-gate case VFS_TOOLONG: 882*7c478bd9Sstevel@tonic-gate fprintf(stderr, 883*7c478bd9Sstevel@tonic-gate gettext("%s: line in vfstab exceeds %d characters\n"), 884*7c478bd9Sstevel@tonic-gate myname, VFS_LINE_MAX-2); 885*7c478bd9Sstevel@tonic-gate break; 886*7c478bd9Sstevel@tonic-gate case VFS_TOOFEW: 887*7c478bd9Sstevel@tonic-gate fprintf(stderr, 888*7c478bd9Sstevel@tonic-gate gettext("%s: line in vfstab has too few entries\n"), 889*7c478bd9Sstevel@tonic-gate myname); 890*7c478bd9Sstevel@tonic-gate break; 891*7c478bd9Sstevel@tonic-gate case VFS_TOOMANY: 892*7c478bd9Sstevel@tonic-gate fprintf(stderr, 893*7c478bd9Sstevel@tonic-gate gettext("%s: line in vfstab has too many entries\n"), 894*7c478bd9Sstevel@tonic-gate myname); 895*7c478bd9Sstevel@tonic-gate break; 896*7c478bd9Sstevel@tonic-gate } 897*7c478bd9Sstevel@tonic-gate exit(1); 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate 900*7c478bd9Sstevel@tonic-gate int opterr = 1, optind = 1, optopt = 0; 901*7c478bd9Sstevel@tonic-gate char *optarg = 0; 902*7c478bd9Sstevel@tonic-gate 903*7c478bd9Sstevel@tonic-gate int 904*7c478bd9Sstevel@tonic-gate getopt(int argc, char * const *argv, const char *opts) 905*7c478bd9Sstevel@tonic-gate { 906*7c478bd9Sstevel@tonic-gate static int sp = 1; 907*7c478bd9Sstevel@tonic-gate register int c; 908*7c478bd9Sstevel@tonic-gate register char *cp; 909*7c478bd9Sstevel@tonic-gate 910*7c478bd9Sstevel@tonic-gate if (sp == 1) 911*7c478bd9Sstevel@tonic-gate if (optind >= argc || 912*7c478bd9Sstevel@tonic-gate argv[optind][0] != '-' || argv[optind][1] == '\0') 913*7c478bd9Sstevel@tonic-gate return (-1); 914*7c478bd9Sstevel@tonic-gate else if (strcmp(argv[optind], "--") == 0) { 915*7c478bd9Sstevel@tonic-gate optind++; 916*7c478bd9Sstevel@tonic-gate return (-1); 917*7c478bd9Sstevel@tonic-gate } 918*7c478bd9Sstevel@tonic-gate optopt = c = argv[optind][sp]; 919*7c478bd9Sstevel@tonic-gate if (c == ':' || (cp = strchr(opts, c)) == 0) { 920*7c478bd9Sstevel@tonic-gate if (opterr) 921*7c478bd9Sstevel@tonic-gate fprintf(stderr, 922*7c478bd9Sstevel@tonic-gate gettext("%s: illegal option -- %c\n"), 923*7c478bd9Sstevel@tonic-gate *argv, c); 924*7c478bd9Sstevel@tonic-gate if (argv[optind][++sp] == '\0') { 925*7c478bd9Sstevel@tonic-gate optind++; 926*7c478bd9Sstevel@tonic-gate sp = 1; 927*7c478bd9Sstevel@tonic-gate } 928*7c478bd9Sstevel@tonic-gate return ('?'); 929*7c478bd9Sstevel@tonic-gate } 930*7c478bd9Sstevel@tonic-gate if (*++cp == ':') { 931*7c478bd9Sstevel@tonic-gate if (argv[optind][sp+1] != '\0') 932*7c478bd9Sstevel@tonic-gate optarg = &argv[optind++][sp+1]; 933*7c478bd9Sstevel@tonic-gate else if (++optind >= argc) { 934*7c478bd9Sstevel@tonic-gate if (opterr) 935*7c478bd9Sstevel@tonic-gate fprintf(stderr, 936*7c478bd9Sstevel@tonic-gate gettext("%s: option requires an argument -- %c\n"), *argv, c); 937*7c478bd9Sstevel@tonic-gate sp = 1; 938*7c478bd9Sstevel@tonic-gate return ('?'); 939*7c478bd9Sstevel@tonic-gate } else 940*7c478bd9Sstevel@tonic-gate optarg = argv[optind++]; 941*7c478bd9Sstevel@tonic-gate sp = 1; 942*7c478bd9Sstevel@tonic-gate } else if (*cp == ';') { 943*7c478bd9Sstevel@tonic-gate if (argv[optind][++sp] != '\0') 944*7c478bd9Sstevel@tonic-gate if (isoptarg(c, &argv[optind][sp])) { 945*7c478bd9Sstevel@tonic-gate optarg = &argv[optind++][sp]; 946*7c478bd9Sstevel@tonic-gate sp = 1; 947*7c478bd9Sstevel@tonic-gate } else 948*7c478bd9Sstevel@tonic-gate optarg = NULL; 949*7c478bd9Sstevel@tonic-gate else { 950*7c478bd9Sstevel@tonic-gate sp = 1; 951*7c478bd9Sstevel@tonic-gate if (++optind >= argc || !isoptarg(c, &argv[optind][0])) 952*7c478bd9Sstevel@tonic-gate optarg = NULL; 953*7c478bd9Sstevel@tonic-gate else 954*7c478bd9Sstevel@tonic-gate optarg = argv[optind++]; 955*7c478bd9Sstevel@tonic-gate } 956*7c478bd9Sstevel@tonic-gate } else { 957*7c478bd9Sstevel@tonic-gate if (argv[optind][++sp] == '\0') { 958*7c478bd9Sstevel@tonic-gate sp = 1; 959*7c478bd9Sstevel@tonic-gate optind++; 960*7c478bd9Sstevel@tonic-gate } 961*7c478bd9Sstevel@tonic-gate optarg = NULL; 962*7c478bd9Sstevel@tonic-gate } 963*7c478bd9Sstevel@tonic-gate return (c); 964*7c478bd9Sstevel@tonic-gate } 965*7c478bd9Sstevel@tonic-gate 966*7c478bd9Sstevel@tonic-gate isoptarg(cc, arg) 967*7c478bd9Sstevel@tonic-gate int cc; 968*7c478bd9Sstevel@tonic-gate char *arg; 969*7c478bd9Sstevel@tonic-gate { 970*7c478bd9Sstevel@tonic-gate if (cc == 's' || cc == 'S') { 971*7c478bd9Sstevel@tonic-gate while (*arg >= '0' && *arg <= '9') 972*7c478bd9Sstevel@tonic-gate arg++; 973*7c478bd9Sstevel@tonic-gate if (*arg++ != ':') 974*7c478bd9Sstevel@tonic-gate return (0); 975*7c478bd9Sstevel@tonic-gate while (*arg >= '0' && *arg <= '9') 976*7c478bd9Sstevel@tonic-gate arg++; 977*7c478bd9Sstevel@tonic-gate if (*arg) 978*7c478bd9Sstevel@tonic-gate return (0); 979*7c478bd9Sstevel@tonic-gate return (1); 980*7c478bd9Sstevel@tonic-gate } 981*7c478bd9Sstevel@tonic-gate return (0); 982*7c478bd9Sstevel@tonic-gate } 983*7c478bd9Sstevel@tonic-gate 984*7c478bd9Sstevel@tonic-gate usage() 985*7c478bd9Sstevel@tonic-gate { 986*7c478bd9Sstevel@tonic-gate fprintf(stderr, 987*7c478bd9Sstevel@tonic-gate gettext("Usage:\n%s [-F FSType] [-V] [-m] [special ...]\n" 988*7c478bd9Sstevel@tonic-gate "%s [-F FSType] [-V] [-y|Y|n|N]" 989*7c478bd9Sstevel@tonic-gate " [-o specific_options] [special ...]\n"), 990*7c478bd9Sstevel@tonic-gate myname, myname); 991*7c478bd9Sstevel@tonic-gate 992*7c478bd9Sstevel@tonic-gate exit(1); 993*7c478bd9Sstevel@tonic-gate } 994