/* * We suck in lots of fsck code, and just pick & choose the stuff we want. * * fsreadfd is set up to read from the file system, fswritefd to write to * the file system. */ int main(int argc, char *argv[]) { int ch, rval; char *fsys = NULL; while (-1 != (ch = getopt(argc, argv, "fdr"))) { switch (ch) { case 'f': /* The -f option is left for historical * reasons and has no meaning. */ break; case 'd': debug++; break; case 'r': nflag++; /* "no" in fsck, readonly for us */ break; default: usage(); } } argc -= optind; argv += optind; if (argc != 1) usage(); else fsys = argv[0]; sblock_init(); if (!setup(fsys)) errx(1, "cannot set up file system `%s'", fsys); printf("%s file system `%s'\nLast Mounted on %s\n", nflag? "Examining": "Editing", fsys, sblock.fs_fsmnt); rval = cmdloop(); if (!nflag) { sblock.fs_clean = 0; /* mark it dirty */ sbdirty(); ckfini(0); printf("*** FILE SYSTEM MARKED DIRTY\n"); printf("*** BE SURE TO RUN FSCK TO CLEAN UP ANY DAMAGE\n"); printf("*** IF IT WAS MOUNTED, RE-MOUNT WITH -u -o reload\n"); } exit(rval); }
caddr_t setup(caddr_t dev) { int corefs; static char devstr[MAXPATHLEN + 1]; havesb = 0; devname = devstr; derive_devstr(dev, devstr, sizeof (devstr)); errorlocked = is_errorlocked(devstr); corefs = check_mount_state(devstr, sizeof (devstr)); sblock_init(); if (open_and_intro(devstr, corefs) == -1) goto cleanup; /* * Check log state */ if (!logsetup(devstr)) goto cleanup; /* * Flush fs if we're going to do anything other than a sanity check. * Note, if logging then the fs was already flushed in logsetup(). */ if (!islog && !mflag) flush_fs(); if (find_superblock(devstr) == -1) goto cleanup; fixup_superblock(); if (errorlocked && (initial_error_state_adjust() == -1)) goto cleanup; /* * asblk could be dirty because we found a mismatch between * the primary superblock and one of its backups in checksb(). */ if (asblk.b_dirty && !bflag) { (void) memmove(&altsblock, &sblock, (size_t)sblock.fs_sbsize); flush(fswritefd, &asblk); } getsummaryinfo(); /* * if not error-locked, using the standard superblock, * not bad log, not forced, preening, and is clean; * stop checking */ if (!errorlocked && (bflag == 0) && ((!islog || islogok) && (fflag == 0) && preen && (FSOKAY == (sblock.fs_state + sblock.fs_time)) && ((sblock.fs_clean == FSLOG && islog) || ((sblock.fs_clean == FSCLEAN) || (sblock.fs_clean == FSSTABLE))))) { iscorrupt = 0; printclean(); goto cleanup; } if (create_and_init_maps() == -1) goto nomaps; bufinit(); return (devstr); nomaps: ckfini(); exitstat = EXERRFATAL; /* FALLTHROUGH */ cleanup: unbufinit(); uncreate_maps(); ungetsummaryinfo(); /* * Can't get rid of the superblock buffer, because our * caller references it to generate the summary statistics. */ return (NULL); }