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