diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-09-17 19:20:42 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-09-17 19:20:42 +0200 |
commit | 84cf9c0f312637b670cc87224ff7e7c4da659e36 (patch) | |
tree | 5e7f0f1f6c7579d1275bb5cf1856ce52767ac8b3 /ufs-fsck | |
parent | 3e6aab0243da094f1ca05b80eb3e5a9adb8ea519 (diff) |
Remove UFS support
It has been unused/untested/unmaintained for a decade now, and its
4-clause BSD licence poses problem.
* configure.ac (default_static): Remove ufs.
* Makefile (prog-subdirs): Remove ufs, ufs-fsck and ufs-utils.
* NEWS, TODO: doc/hurd.texi, doc/navigating: Remove UFS notes.
* ufs: Remove directory
* ufs-fsck: Remove directory
* ufs-utils: Remove directory
* bsdfsck: Remove directory
Diffstat (limited to 'ufs-fsck')
-rw-r--r-- | ufs-fsck/Makefile | 33 | ||||
-rw-r--r-- | ufs-fsck/dir.c | 567 | ||||
-rw-r--r-- | ufs-fsck/fsck.h | 183 | ||||
-rw-r--r-- | ufs-fsck/inode.c | 203 | ||||
-rw-r--r-- | ufs-fsck/main.c | 170 | ||||
-rw-r--r-- | ufs-fsck/pass1.c | 437 | ||||
-rw-r--r-- | ufs-fsck/pass1b.c | 90 | ||||
-rw-r--r-- | ufs-fsck/pass2.c | 400 | ||||
-rw-r--r-- | ufs-fsck/pass3.c | 71 | ||||
-rw-r--r-- | ufs-fsck/pass4.c | 94 | ||||
-rw-r--r-- | ufs-fsck/pass5.c | 450 | ||||
-rw-r--r-- | ufs-fsck/setup.c | 191 | ||||
-rw-r--r-- | ufs-fsck/utilities.c | 455 |
13 files changed, 0 insertions, 3344 deletions
diff --git a/ufs-fsck/Makefile b/ufs-fsck/Makefile deleted file mode 100644 index 03ce9cc7..00000000 --- a/ufs-fsck/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (C) 1994, 1995, 1996, 2012 Free Software Foundation -# Written by Michael I. Bushnell. -# -# This file is part of the GNU Hurd. -# -# The GNU Hurd is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2, or (at -# your option) any later version. -# -# The GNU Hurd is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -dir := ufs-fsck -makemode := utility - -SRCS = dir.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \ - pass5.c setup.c utilities.c inode.c -OBJS = $(subst .c,.o,$(SRCS)) tables.o -target = fsck.ufs -installationdir = $(sbindir) -HURDLIBS=shouldbeinlibc - -include ../Makeconf - -vpath tables.c $(top_srcdir)/ufs - diff --git a/ufs-fsck/dir.c b/ufs-fsck/dir.c deleted file mode 100644 index 85757b16..00000000 --- a/ufs-fsck/dir.c +++ /dev/null @@ -1,567 +0,0 @@ -/* Directory management subroutines - Copyright (C) 1994,96,99,2002 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "fsck.h" - -/* This routine is used in pass 1 to initialize DIRARRAY and DIRSORTED. - Copy information from DP (for number NUMBER) into a newly allocated - dirinfo structure and add it to the arrays. */ -void -record_directory (struct dinode *dp, ino_t number) -{ - u_int blks; - struct dirinfo *dnp; - - blks = howmany (dp->di_size, sblock->fs_bsize); - if (blks > NDADDR) - blks = NDADDR + NIADDR; - blks *= sizeof (daddr_t); - dnp = malloc (sizeof (struct dirinfo) + blks); - - dnp->i_number = number; - dnp->i_parent = dnp->i_dotdot = 0; - dnp->i_isize = dp->di_size; - dnp->i_numblks = blks; - bcopy (dp->di_db, dnp->i_blks, blks); - - if (dirarrayused == dirarraysize) - { - if (dirarraysize == 0) - { - dirarraysize = 100; - dirarray = malloc (dirarraysize * sizeof (struct dirinfo *)); - dirsorted = malloc (dirarraysize * sizeof (struct dirinfo *)); - } - else - { - dirarraysize *= 2; - dirarray = realloc (dirarray, - dirarraysize * sizeof (struct dirinfo *)); - dirsorted = realloc (dirsorted, - dirarraysize * sizeof (struct dirinfo *)); - } - } - dirarray[dirarrayused] = dnp; - dirsorted[dirarrayused] = dnp; - dirarrayused++; -} - -/* Return the cached dirinfo structure for directory INO. */ -struct dirinfo * -lookup_directory (ino_t ino) -{ - int i; - - for (i = 0; i < dirarrayused; i++) - if (dirarray[i]->i_number == ino) - return dirarray[i]; - - errexit ("Cannot find cached directory I=%Ld\n", ino); -} - -/* Check to see if DIR is really a readable directory; if it - isn't, then bail with an appropriate message and return 0; - else return 1. MSG identifies the action contemplated */ -static int -validdir (ino_t dir, char *action) -{ - switch (inodestate[dir]) - { - case DIRECTORY: - case DIRECTORY|DIR_REF: - return 1; - - case UNALLOC: - warning (1, "CANNOT %s I=%Ld; NOT ALLOCATED", action, dir); - return 0; - - case BADDIR: - warning (1, "CANNOT %s I=%Ld; BAD BLOCKS", action, dir); - return 0; - - case REG: - warning (1, "CANNOT %s I=%Ld; NOT DIRECTORY", action, dir); - return 0; - - default: - errexit ("ILLEGAL STATE"); - } -} - -/* Search directory DIR for name NAME. If NAME is found, then - set *INO to the inode of the entry; otherwise clear INO. Returns 1 if all - was normal, or 0 if there was some error doing the search. */ -int -searchdir (ino_t dir, char *name, ino_t *ino) -{ - struct dinode dino; - int len; - - /* Scan through one directory block and see if it - contains NAME. */ - void - check1block (void *buf) - { - struct directory_entry *dp; - - for (dp = buf; (void *)dp - buf < DIRBLKSIZ; - dp = (struct directory_entry *) ((void *)dp + dp->d_reclen)) - { - if (dp->d_reclen == 0 - || dp->d_reclen + (void *)dp - buf > DIRBLKSIZ) - return; - - if (dp->d_ino == 0 || dp->d_ino > maxino) - continue; - - if (DIRECT_NAMLEN (dp) == len && strcmp (dp->d_name, name) == 0) - { - *ino = dp->d_ino; - return; - } - } - } - - /* Read part of a directory and look to see if it contains - NAME. Return 1 if we should keep looking at more - blocks. */ - int - checkdirblock (daddr_t bno, int nfrags, off_t offset) - { - void *buf = alloca (nfrags * sblock->fs_fsize); - void *bufp; - - readblock (fsbtodb (sblock, bno), buf, nfrags * sblock->fs_fsize); - for (bufp = buf; - bufp - buf < nfrags * sblock->fs_fsize - && offset + (bufp - buf) + DIRBLKSIZ <= dino.di_size; - bufp += DIRBLKSIZ) - { - check1block (bufp); - if (*ino) - return 0; - } - return 1; - } - - *ino = 0; - - if (!validdir (dir, "READ")) - return 0; - - getinode (dir, &dino); - - len = strlen (name); - datablocks_iterate (&dino, checkdirblock); - - return 1; -} - -/* Change the existing entry in DIR for name NAME to be - inode INO. Return 1 if the entry was found and - replaced, else return 0. */ -int -changeino (ino_t dir, char *name, ino_t ino) -{ - struct dinode dino; - int len; - int madechange; - - /* Scan through a directory block looking for NAME; - if we find it then change the inode pointer to point - at INO and return 1; if we don't find it then return 0. */ - int - check1block (void *buf) - { - struct directory_entry *dp; - - for (dp = buf; (void *)dp - buf < DIRBLKSIZ; - dp = (struct directory_entry *) ((void *)dp + dp->d_reclen)) - { - if (dp->d_reclen == 0 - || dp->d_reclen + (void *)dp - buf > DIRBLKSIZ) - return 0; - - if (dp->d_ino == 0 || dp->d_ino > maxino) - continue; - - if (DIRECT_NAMLEN (dp) == len && strcmp (dp->d_name, name) == 0) - { - dp->d_ino = ino; - madechange = 1; - return 1; - } - } - return 0; - } - - /* Read part of a directory and look to see if it - contains NAME. Return 1 if we should keep looking - at more blocks. */ - int - checkdirblock (daddr_t bno, int nfrags, off_t offset) - { - void *buf = alloca (nfrags * sblock->fs_fsize); - void *bufp; - - readblock (fsbtodb (sblock, bno), buf, nfrags * sblock->fs_fsize); - for (bufp = buf; - bufp - buf < nfrags * sblock->fs_fsize - && offset + (bufp - buf) + DIRBLKSIZ <= dino.di_size; - bufp += DIRBLKSIZ) - { - if (check1block (bufp)) - { - writeblock (fsbtodb (sblock, bno), buf, - nfrags * sblock->fs_fsize); - return 0; - } - } - return 1; - } - - if (!validdir (dir, "REWRITE")) - return 0; - - getinode (dir, &dino); - len = strlen (name); - madechange = 0; - datablocks_iterate (&dino, checkdirblock); - return madechange; -} - -/* Attempt to expand the size of a directory. Return - 1 if we succeeded. */ -static int -expanddir (struct dinode *dp) -{ - daddr_t lastbn, newblk; - char *cp, buf[sblock->fs_bsize]; - - lastbn = lblkno (sblock, dp->di_size); - if (blkoff (sblock, dp->di_size) && lastbn >= NDADDR - 1) - return 0; - else if (!blkoff (sblock, dp->di_size) && lastbn >= NDADDR) - return 0; - else if (blkoff (sblock, dp->di_size) && !dp->di_db[lastbn]) - return 0; - else if (!blkoff (sblock, dp->di_size) && dp->di_db[lastbn]) - return 0; - - newblk = allocblk (sblock->fs_frag); - if (!newblk) - return 0; - - if (blkoff (sblock, dp->di_size)) - dp->di_db[lastbn + 1] = dp->di_db[lastbn]; - dp->di_db[lastbn] = newblk; - dp->di_size += sblock->fs_bsize; - dp->di_blocks += sblock->fs_bsize / DEV_BSIZE; - - for (cp = buf; cp < buf + sblock->fs_bsize; cp += DIRBLKSIZ) - { - struct directory_entry *dir = (struct directory_entry *) cp; - dir->d_ino = 0; - dir->d_reclen = DIRBLKSIZ; - } - - writeblock (fsbtodb (sblock, newblk), buf, sblock->fs_bsize); - return 1; -} - -/* Add a new link into directory DIR with name NAME and target - INO. Return 1 if we succeeded and 0 if we failed. It is - an error to call this routine if NAME is already present - in DIR. */ -int -makeentry (ino_t dir, ino_t ino, char *name) -{ - int len; - struct dinode dino; - int needed; - int madeentry; - - /* Read a directory block and see if it contains room for the - new entry. If so, add it and return 1; otherwise return 0. */ - int - check1block (void *buf) - { - struct directory_entry *dp; - - for (dp = buf; (void *)dp - buf < DIRBLKSIZ; - dp = (struct directory_entry *) ((void *)dp + dp->d_reclen)) - { - if (dp->d_reclen == 0 - || dp->d_reclen + (void *)dp - buf > DIRBLKSIZ) - return 0; - if (dp->d_ino - && dp->d_reclen - DIRSIZ (DIRECT_NAMLEN (dp)) >= needed) - { - struct directory_entry *newdp; - newdp = (struct directory_entry *) - ((void *)dp + DIRSIZ (DIRECT_NAMLEN (dp))); - - newdp->d_reclen = dp->d_reclen - DIRSIZ (DIRECT_NAMLEN (dp)); - DIRECT_NAMLEN (newdp) = len; - newdp->d_ino = ino; - if (direct_symlink_extension) - newdp->d_type = typemap[ino]; - bcopy (name, newdp->d_name, len + 1); - - dp->d_reclen -= newdp->d_reclen; - madeentry = 1; - return 1; - } - else if (!dp->d_ino && dp->d_reclen >= needed) - { - DIRECT_NAMLEN (dp) = len; - dp->d_ino = ino; - if (direct_symlink_extension) - dp->d_type = typemap[ino]; - bcopy (name, dp->d_name, len + 1); - madeentry = 1; - return 1; - } - } - return 0; - } - - /* Read part of a directory and look to see if it - contains NAME. Return 1 if we should keep looking - at more blocks. */ - int - checkdirblock (daddr_t bno, int nfrags, off_t offset) - { - void *buf = alloca (nfrags * sblock->fs_fsize); - void *bufp; - - readblock (fsbtodb (sblock, bno), buf, nfrags * sblock->fs_fsize); - for (bufp = buf; - bufp - buf < nfrags * sblock->fs_fsize - && offset + (bufp - buf) + DIRBLKSIZ <= dino.di_size; - bufp += DIRBLKSIZ) - { - if (check1block (bufp)) - { - writeblock (fsbtodb (sblock, bno), buf, - nfrags * sblock->fs_fsize); - return 0; - } - } - return 1; - } - - if (!validdir (dir, "MODIFY")) - return 0; - - getinode (dir, &dino); - len = strlen (name); - needed = DIRSIZ (len); - madeentry = 0; - datablocks_iterate (&dino, checkdirblock); - if (!madeentry) - { - /* Attempt to expand the directory. */ - problem (0, "NO SPACE LEFT IN DIR INO=%Ld", dir); - if (preen || reply ("EXPAND")) - { - if (expanddir (&dino)) - { - write_inode (ino, &dino); - datablocks_iterate (&dino, checkdirblock); - pfix ("EXPANDED"); - } - else - { - pfail (0); - warning (1, "CANNOT EXPAND DIRECTORY"); - } - } - } - return madeentry; -} - -/* Create a directory node whose parent is to be PARENT, whose inode - is REQUEST, and whose mode is to be MODE. If REQUEST is zero, then - allocate any inode. Initialze the contents of the - directory. Return the inode of the new directory. */ -ino_t -allocdir (ino_t parent, ino_t request, mode_t mode) -{ - ino_t ino; - - mode |= IFDIR; - - ino = allocino (request, mode); - if (!ino) - return 0; - if (!makeentry (ino, ino, ".")) - goto bad; - if (!makeentry (ino, parent, "..")) - goto bad; - - linkfound[ino]++; - linkfound[parent]++; - return ino; - - bad: - freeino (ino); - return 0; -} - -/* Link node INO into lost+found. If PARENT is positive then INO is - a directory, and PARENT is the number of `..' as found in INO. - If PARENT is zero then INO is a directory without any .. entry. - If the node could be linked, return 1; else return 0. */ -int -linkup (ino_t ino, ino_t parent) -{ - int search_failed; - struct dinode lfdino; - char *tempname; - ino_t foo; - - if (lfdir == 0) - { - if (!searchdir (ROOTINO, lfname, &lfdir)) - { - warning (1, "FAILURE SEARCHING FOR `%s'", lfname); - return 0; - } - if (lfdir == 0) - { - problem (0, "NO `%s' DIRECTORY", lfname); - if (preen || reply ("CREATE")) - { - lfdir = allocdir (ROOTINO, 0, lfmode); - if (lfdir != 0) - { - if (! makeentry (ROOTINO, lfdir, lfname)) - { - freeino (lfdir); - linkfound[ROOTINO]--; - lfdir = 0; - } - } - } - if (lfdir) - pfix ("CREATED"); - else - { - pfail (0); - warning (1, "SORRY, CANNOT CREATE `%s' DIRECTORY", lfname); - return 0; - } - } - } - - getinode (lfdir, &lfdino); - if ((lfdino.di_model & IFMT) != IFDIR) - { - ino_t oldlfdir; - - problem (1, "`%s' IS NOT A DIRECTORY", lfname); - if (! reply ("REALLOCATE")) - return 0; - - oldlfdir = lfdir; - - lfdir = allocdir (ROOTINO, 0, lfmode); - if (!lfdir) - { - warning (1, "SORRY, CANNOT CREATE `%s' DIRECTORY", lfname); - return 0; - } - if (!changeino (ROOTINO, lfname, lfdir)) - { - warning (1, "SORRY, CANNOT CREATE `%s' DIRECTORY", lfname); - return 0; - } - - /* One less link to the old one */ - linkfound[oldlfdir]--; - - getinode (lfdir, &lfdino); - } - - if (inodestate[lfdir] != DIRECTORY && inodestate[lfdir] != (DIRECTORY|DIR_REF)) - { - warning (1, "SORRY. `%s' DIRECTORY NOT ALLOCATED", lfname); - return 0; - } - - asprintf (&tempname, "#%Ld", ino); - search_failed = !searchdir (lfdir, tempname, &foo); - while (foo) - { - char *newname; - asprintf (&newname, "%sa", tempname); - free (tempname); - tempname = newname; - search_failed = !searchdir (lfdir, tempname, &foo); - } - if (search_failed) - { - warning (1, "FAILURE SEARCHING FOR `%s' IN `%s'", tempname, lfname); - free (tempname); - return 0; - } - if (!makeentry (lfdir, ino, tempname)) - { - free (tempname); - warning (1, "SORRY, NO SPACE IN `%s' DIRECTORY", lfname); - return 0; - } - free (tempname); - linkfound[ino]++; - - if (parent != -1) - { - /* Reset `..' in ino */ - if (parent) - { - if (!changeino (ino, "..", lfdir)) - { - warning (1, "CANNOT ADJUST `..' LINK I=%Ld", ino); - return 0; - } - /* Forget about link to old parent */ - linkfound[parent]--; - } - else if (!makeentry (ino, lfdir, "..")) - { - warning (1, "CANNOT CREAT `..' LINK I=%Ld", ino); - return 0; - } - - /* Account for link to lost+found; update inode directly - here to avoid confusing warning later. */ - linkfound[lfdir]++; - linkcount[lfdir]++; - lfdino.di_nlink++; - write_inode (lfdir, &lfdino); - - if (parent) - warning (0, "DIR I=%Ld CONNECTED; PARENT WAS I=%Ld", ino, parent); - else - warning (0, "DIR I=%Ld CONNECTED", ino); - } - return 1; -} diff --git a/ufs-fsck/fsck.h b/ufs-fsck/fsck.h deleted file mode 100644 index 4a5dabf5..00000000 --- a/ufs-fsck/fsck.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - Copyright (C) 1994,95,96,2002 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include <sys/types.h> -#include <sys/time.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <dirent.h> - -#define swab_disk 0 - -#include "../ufs/fs.h" -#include "../ufs/dinode.h" -#include "../ufs/dir.h" - -/* Type of an inode */ -#define UNALLOC 0 -#define REG 1 -#define DIRECTORY 2 -#define BADDIR 3 - -/* Added to directories in pass 2 */ -#define DIR_REF 4 /* dir has been found in connectivity search */ - -/* State of each inode (set by pass 1) */ -char *inodestate; - -/* Number of links claimed by each inode (set by pass 1) */ -nlink_t *linkcount; - -/* Number of links found to each inode (set by pass 2) */ -nlink_t *linkfound; - -/* DT_foo type of each inode (set by pass 1) */ -char *typemap; - -/* Map of blocks allocated */ -char *blockmap; - -/* A string identifying what we're trying to check. */ -extern char *device_name; - - -/* Command line flags */ -int nowrite; /* all questions fail */ -int noquery; /* all questions succeed */ - - -enum contret -{ - RET_STOP, - RET_GOOD, - RET_BAD, -}; - - -/* One of these structures is set up for each directory by - pass 1 and used by passes 2 and 3. */ -struct dirinfo -{ - struct inoinfo *i_nexthash; /* next entry in hash chain */ - ino_t i_number; /* inode entry of this dir */ - ino_t i_parent; /* inode entry of parent */ - ino_t i_dotdot; /* inode number of `..' */ - ino_t i_dot; /* inode number of `.' */ - u_int i_isize; /* size of inode */ - u_int i_numblks; /* size of block array in bytes */ - daddr_t i_blks[0]; /* array of inode block addresses */ -}; - -/* Array of all the dirinfo structures in inode number order */ -struct dirinfo **dirarray; - -/* Array of all thi dirinfo structures sorted by their first - block address */ -struct dirinfo **dirsorted; - -int dirarrayused; /* number of directories */ -int dirarraysize; /* alloced size of dirarray/dirsorted */ - -struct dups { - struct dups *next; - daddr_t dup; -}; -struct dups *duplist; /* head of dup list */ -struct dups *muldup; /* end of unique duplicate dup block numbers */ - - -extern struct fs *sblock; - -extern daddr_t maxfsblock; -extern int maxino; -extern int direct_symlink_extension; - -extern int newinofmt; - -/* Terse automatic mode for noninteractive use; punts on severe problems. */ -extern int preen; - -extern int readfd, writefd; - -extern int fix_denied; - -extern int fsmodified; - -extern ino_t lfdir; - -/* Total number of files found on the partition. */ -extern long num_files; - -extern mode_t lfmode; -extern char *lfname; - -#define NBBY 8 -#define howmany(x,y) (((x)+((y)-1))/(y)) -#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) -#define isclr(a, i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) -#define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) -#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) -#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<(i)%NBBY)) -#define DEV_BSIZE 512 - -#define setbmap(blkno) setbit (blockmap, blkno) -#define testbmap(blkno) isset (blockmap, blkno) -#define clrbmap(blkno) clrbit (blockmap, blkno) - -#define DI_MODE(dp) (((dp)->di_modeh << 16) | (dp)->di_model) - - - -int setup (char *); -void pass1 (), pass1b (), pass2 (), pass3 (), pass4 (), pass5 (); - -void readblock (daddr_t, void *, size_t); -void writeblock (daddr_t, void *, size_t); - -void getinode (ino_t, struct dinode *); -void write_inode (ino_t, struct dinode *); -void clear_inode (ino_t, struct dinode *); - -daddr_t allocblk (int); -int check_range (daddr_t, int); - -ino_t allocino (ino_t, mode_t); -void freeino (ino_t); -ino_t allocdir (ino_t, ino_t, mode_t); - -int makeentry (ino_t, ino_t, char *); -int changeino (ino_t, char *, ino_t); - -int linkup (ino_t, ino_t); - -void datablocks_iterate (struct dinode *, int (*)(daddr_t, int, off_t)); -void allblock_iterate (struct dinode *, int (*)(daddr_t, int, off_t)); - -void record_directory (struct dinode *, ino_t); -struct dirinfo *lookup_directory (ino_t); - -void errexit (char *, ...) __attribute__ ((format (printf, 1, 2), noreturn)); -void warning (int, char *, ...) __attribute__ ((format (printf, 2, 3))); -void problem (int, char *, ...) __attribute__ ((format (printf, 2, 3))); -void pinode (int, ino_t, char *fmt, ...) __attribute__ ((format (printf, 3, 4))); -void pextend (char *, ...) __attribute__ ((format (printf, 1, 2))); -void pfix (char *fix), pfail (char *reason); -int reply (char *); diff --git a/ufs-fsck/inode.c b/ufs-fsck/inode.c deleted file mode 100644 index df4b880e..00000000 --- a/ufs-fsck/inode.c +++ /dev/null @@ -1,203 +0,0 @@ -/* Inode allocation, deallocation, etc. - Copyright (C) 1994, 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "fsck.h" - -static void -inode_iterate (struct dinode *dp, - int (*fn) (daddr_t, int, off_t), - int doaddrblocks) -{ - mode_t mode = dp->di_model & IFMT; - int nb, maxb; - off_t totaloffset = 0; - - /* Call FN for iblock IBLOCK of level LEVEL and recurse down - the indirect block pointers. */ - int - scaniblock (daddr_t iblock, int level) - { - int cont; - daddr_t ptrs[NINDIR(sblock)]; - int i; - - if (doaddrblocks) - { - cont = (*fn)(iblock, sblock->fs_frag, totaloffset); - if (cont == RET_STOP) - return RET_STOP; - else if (cont == RET_BAD) - return RET_GOOD; - } - - readblock (fsbtodb (sblock, iblock), ptrs, sblock->fs_bsize); - for (i = 0; i < NINDIR (sblock); i++) - { - if (!ptrs[i]) - continue; - - if (level == 0) - { - cont = (*fn)(ptrs[i], sblock->fs_frag, totaloffset); - totaloffset += sblock->fs_bsize; - } - else - cont = scaniblock (ptrs[i], level - 1); - if (cont == RET_STOP) - return RET_STOP; - } - return RET_GOOD; - } - - if (mode == IFBLK || mode == IFCHR - || (mode == IFLNK && sblock->fs_maxsymlinklen != -1 - && (dp->di_size < sblock->fs_maxsymlinklen - || (sblock->fs_maxsymlinklen == 0 && dp->di_blocks == 0)))) - return; - - maxb = lblkno (sblock, dp->di_size - 1); - totaloffset = 0; - for (nb = 0; nb < NDADDR; nb++) - { - int offset; - int nfrags; - - if (nb == maxb && (offset = blkoff (sblock, dp->di_size))) - nfrags = numfrags (sblock, fragroundup (sblock, offset)); - else - nfrags = sblock->fs_frag; - - if (dp->di_db[nb] - && (*fn)(dp->di_db[nb], nfrags, totaloffset) != RET_GOOD) - return; - totaloffset += nfrags * sizeof (sblock->fs_fsize); - } - - for (nb = 0; nb < NIADDR; nb++) - if (dp->di_ib[nb] && scaniblock (dp->di_ib[nb], nb) != RET_GOOD) - return; - - if (doaddrblocks && dp->di_trans) - (*fn)(dp->di_trans, sblock->fs_frag, totaloffset); -} - -void -datablocks_iterate (struct dinode *dp, - int (*fn) (daddr_t, int, off_t)) -{ - inode_iterate (dp, fn, 0); -} - -void -allblock_iterate (struct dinode *dp, - int (*fn) (daddr_t, int, off_t)) -{ - inode_iterate (dp, fn, 1); -} - -/* Allocate an inode. If INUM is nonzero, then allocate that - node specifically, otherwise allocate any available inode. - MODE is the mode of the new file. Return the allocated - inode number (or 0 if the allocation failed). */ -ino_t -allocino (ino_t request, mode_t mode) -{ - ino_t ino; - struct dinode dino; - struct timeval tv; - - if (request) - { - if (inodestate[request] != UNALLOC) - return 0; - ino = request; - } - else - { - for (ino = ROOTINO; ino < maxino; ino++) - if (inodestate[ino] == UNALLOC) - break; - if (ino == maxino) - return 0; - } - - if ((mode & IFMT) == IFDIR) - inodestate[ino] = DIRECTORY | DIR_REF; - else - inodestate[ino] = REG; - - getinode (ino, &dino); - dino.di_modeh = (mode & 0xffff0000) >> 16; - dino.di_model = (mode & 0x0000ffff); - gettimeofday (&tv, 0); - dino.di_atime.tv_sec = tv.tv_sec; - dino.di_atime.tv_nsec = tv.tv_usec * 1000; - dino.di_mtime = dino.di_ctime = dino.di_atime; - dino.di_size = 0; - dino.di_blocks = 0; - num_files++; - write_inode (ino, &dino); - typemap[ino] = IFTODT (mode); - return ino; -} - -/* Deallocate inode INUM. */ -void -freeino (ino_t inum) -{ - struct dinode dino; - - int - clearblock (daddr_t bno, int nfrags, off_t offset) - { - int i; - - for (i = 0; i < nfrags; i++) - { - if (check_range (bno + i, 1)) - return RET_BAD; - if (testbmap (bno + i)) - { - struct dups *dlp; - for (dlp = duplist; dlp; dlp = dlp->next) - { - if (dlp->dup != bno + i) - continue; - dlp->dup = duplist->dup; - dlp = duplist; - duplist = duplist->next; - free (dlp); - break; - } - if (dlp == 0) - clrbmap (bno + i); - } - } - return RET_GOOD; - } - - getinode (inum, &dino); - allblock_iterate (&dino, clearblock); - - clear_inode (inum, &dino); - inodestate[inum] = UNALLOC; - - num_files--; -} diff --git a/ufs-fsck/main.c b/ufs-fsck/main.c deleted file mode 100644 index 34c32a67..00000000 --- a/ufs-fsck/main.c +++ /dev/null @@ -1,170 +0,0 @@ -/* Main program for GNU fsck - Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include <errno.h> -#include <argp.h> -#include <hurd.h> -#include <version.h> - -#include "fsck.h" - -const char *argp_program_version = STANDARD_HURD_VERSION (fsck.ufs); - -char *lfname = "lost+found"; -mode_t lfmode = 0755; - -/* Terse automatic mode for noninteractive use; punts on severe problems. */ -int preen = 0; - -/* Total number of files found on the partition. */ -long num_files = 0; - -static struct argp_option options[] = -{ - {"preen", 'p', 0, 0, "Terse automatic mode", 1}, - {"yes", 'y', 0, 0, "Automatically answer yes to all questions"}, - {"no", 'n', 0, 0, "Automatically answer no to all questions"}, - {"lost+found", 'l', "NAME", 0, "The name of the lost+found directory in /"}, - {"lf-mode", 'm', "MODE", 0, "The mode of the lost+found directory in /"}, - {0, 0, 0, 0, "In --preen mode, the following also apply:", 2}, - {"force", 'f', 0, 0, "Check even if clean"}, - {"silent", 's', 0, 0, "Only print diagostic messages"}, - {0, 0} -}; -char *args_doc = "DEVICE"; - -/* Returns a malloced buffer containing a nice printable size for FRAGS. */ -static char * -nice_size (long frags) -{ - char *rep; - char *units = "KMGT", *u = units; - float num = ((float)frags * sblock->fs_fsize) / 1024; - - while (num > 1024) - { - num /= 1024; - u++; - } - - asprintf (&rep, num >= 1000 ? "%.0f%c" : "%.3g%c", num, *u); - - return rep; -} - -/* Print summary statistics. */ -static void -show_stats () -{ - long num_ffree = sblock->fs_cstotal.cs_nffree; - long num_bfree = sblock->fs_cstotal.cs_nbfree; - long tot_ffree = num_ffree + sblock->fs_frag * num_bfree; - char *urep = nice_size (sblock->fs_dsize - tot_ffree); - char *frep = nice_size (tot_ffree); - warning (0, "%ld files, %s used, %s free (%ld.%ld%% fragmentation)", - num_files, urep, frep, - (num_ffree * 100) / sblock->fs_dsize, - (((num_ffree * 1000 + sblock->fs_dsize / 2) / sblock->fs_dsize) - % 10)); - free (urep); - free (frep); -} - -int -main (int argc, char **argv) -{ - int silent = 0, force = 0; - char *device = 0; - error_t parse_opt (int key, char *arg, struct argp_state *state) - { - switch (key) - { - case 'p': preen = 1; break; - case 'y': noquery = 1; break; - case 'n': nowrite = 1; break; - case 'l': lfname = arg; break; - case 'm': lfmode = strtol (arg, 0, 8); break; - case 'f': force = 1; break; - case 's': silent = 1; break; - case ARGP_KEY_ARG: - if (!device) - { - device = arg; - break; - } - /* Fall through */ - case ARGP_KEY_NO_ARGS: - argp_usage (state); - default: - return ARGP_ERR_UNKNOWN; - } - return 0; - } - struct argp argp = {options, parse_opt, args_doc}; - - preen = nowrite = noquery = 0; - argp_parse (&argp, argc, argv, 0, 0, 0); - - if (!setup (device)) - exit (1); - - if (preen && sblock->fs_clean && !force) - { - if (! silent) - warning (0, "FILESYSTEM CLEAN"); - } - else - { - if (!preen) - printf ("** Phase 1 -- Check Blocks and Sizes\n"); - pass1 (); - - if (duplist) - { - if (!preen) - printf ("** Phase 1b -- Rescan for More Duplicates\n"); - pass1b (); - } - - if (!preen) - printf ("** Phase 2 -- Check Pathnames\n"); - pass2 (); - - if (!preen) - printf ("** Phase 3 -- Check Connectivity\n"); - pass3 (); - - if (!preen) - printf ("** Phase 4 -- Check Reference Counts\n"); - pass4 (); - - if (!preen) - printf ("** Phase 5 -- Check Cyl Groups\n"); - pass5 (); - - if (! silent) - show_stats (sblock); - } - - if (fsmodified && !preen) - printf ("\n***** FILE SYSTEM WAS MODIFIED *****\n"); - - exit (fsmodified ? 2 : 0); -} diff --git a/ufs-fsck/pass1.c b/ufs-fsck/pass1.c deleted file mode 100644 index bd41cc62..00000000 --- a/ufs-fsck/pass1.c +++ /dev/null @@ -1,437 +0,0 @@ -/* Pass one of GNU fsck -- count blocks and verify inodes - Copyright (C) 1994,95,96,2002 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - - -#include "fsck.h" - -static struct dinode zino; - -/* Find all the blocks in use by files and filesystem reserved blocks. - Set them in the global block map. For each file, if a block is found - allocated twice, then record the block and inode in DUPLIST. - Initialize INODESTATE, LINKCOUNT, and TYPEMAP. */ -void -pass1 () -{ - ino_t number; - ino_t i; - int cg; - struct dinode dino; - struct dinode *dp = &dino; - mode_t mode, type; - int ndb; - int holdallblocks; - int lbn; - int nblocks; - int blkerror; - int nblkrngerrors; - int nblkduperrors; - - /* This function is called for each block of DP. Check to see - if the block number is valid. If so, set the entry in the - block map. If the block map entry is already set, then keep - track of this block and see if the user wants to clear the - node. Increment NBLOCKS by the number of data blocks held. - Set BLKERROR if this block is invalid. - Return RET_GOOD, RET_BAD, RET_STOP if the block is good, - bad, or if we should entirely stop checking blocks in this - inode. */ - int - checkblock (daddr_t bno, int nfrags, off_t offset) - { -#define MAXBAD 10 - int outofrange; - struct dups *dlp, *new; - int wasbad = 0; - - /* Check to see if this block is in range */ - outofrange = check_range (bno, nfrags); - if (outofrange) - { - blkerror = 1; - wasbad = 1; - if (nblkrngerrors == 0) - warning (0, "I=%Ld HAS BAD BLOCKS", number); - if (nblkrngerrors++ > MAXBAD) - { - problem (0, "EXCESSIVE BAD BLKS I=%Ld", number); - if (preen || reply ("SKIP")) - { - pfail ("SKIPPING"); - return RET_STOP; - } - } - } - - for (; nfrags > 0; bno++, nfrags--) - { - if (outofrange && check_range (bno, 1)) - warning (0, "BAD BLOCK %lu", bno); - else - { - if (!testbmap (bno)) - setbmap (bno); - else - { - blkerror = 1; - if (nblkduperrors == 0) - warning (0, "I=%Ld HAS DUPLICATE BLOCKS", number); - warning (0, "DUPLICATE BLOCK %ld", bno); - wasbad = 1; - if (nblkduperrors++ > MAXBAD) - { - problem (0, "EXCESSIVE DUP BLKS I=%Ld", number); - if (preen || reply ("SKIP")) - { - pfail ("SKIPPING"); - return RET_STOP; - } - } - new = malloc (sizeof (struct dups)); - new->dup = bno; - if (muldup == 0) - { - duplist = muldup = new; - new->next = 0; - } - else - { - new->next = muldup->next; - muldup->next = new; - } - for (dlp = duplist; dlp != muldup; dlp = dlp->next) - if (dlp->dup == bno) - break; - if (dlp == muldup && dlp->dup != bno) - muldup = new; - } - } - nblocks += sblock->fs_fsize / DEV_BSIZE; - } - return wasbad ? RET_BAD : RET_GOOD; - } - - - /* Account for blocks used by meta data */ - for (cg = 0; cg < sblock->fs_ncg; cg++) - { - daddr_t firstdata, firstcgblock, bno; - - /* Each cylinder group past the first reserves data - from its cylinder group copy to (but not including) - the first datablock. - - The first, however, reserves from the very front of the - cylinder group (thus including the boot block), and it also - reserves the data blocks holding the csum information. */ - firstdata = cgdmin (sblock, cg); - if (cg == 0) - { - firstcgblock = cgbase (sblock, cg); - firstdata += howmany (sblock->fs_cssize, sblock->fs_fsize); - } - else - firstcgblock = cgsblock (sblock, cg); - - /* Mark the blocks set */ - for (bno = firstcgblock; bno < firstdata; bno++) - setbmap (bno); - } - - /* Loop through each inode, doing initial checks */ - for (number = 0, cg = 0; cg < sblock->fs_ncg; cg++) - for (i = 0; i < sblock->fs_ipg; i++, number++) - { - /* These record whether we've already complained about extra - direct/indirect blocks. */ - int dbwarn = 0, ibwarn = 0; - -/* if (!preen && !(number % 10000)) - printf ("I=%Ld\n", number); */ - - if (number < ROOTINO) - continue; - - getinode (number, dp); - mode = DI_MODE (dp); - type = mode & IFMT; - - /* If the node is not allocated, then make sure it's - properly clear */ - if (type == 0) - { - if (bcmp (dp->di_db, zino.di_db, NDADDR * sizeof (daddr_t)) - || bcmp (dp->di_ib, zino.di_ib, NIADDR * sizeof (daddr_t)) - || dp->di_trans - || DI_MODE (dp) - || dp->di_size) - { - problem (0, "PARTIALLY ALLOCATED INODE I=%Ld", number); - if (preen || reply ("CLEAR")) - { - clear_inode (number, dp); - pfix ("CLEARED"); - } - } - inodestate[number] = UNALLOC; - } - else - { - /* Node is allocated. */ - - /* Check to see if we think the node should be cleared */ - - /* Verify size for basic validity */ - holdallblocks = 0; - - if (dp->di_size + sblock->fs_bsize - 1 < dp->di_size) - { - problem (1, "OVERFLOW IN FILE SIZE I=%Ld (SIZE == %lld)", number, - dp->di_size); - if (reply ("CLEAR")) - { - clear_inode (number, dp); - inodestate[number] = UNALLOC; - continue; - } - inodestate[number] = UNALLOC; - warning (0, "WILL TREAT ANY BLOCKS HELD BY I=%Ld AS ALLOCATED", - number); - holdallblocks = 1; - } - - /* Decode type and set NDB - also set inodestate correctly. */ - inodestate[number] = REG; - switch (type) - { - case IFBLK: - case IFCHR: - ndb = 1; - break; - - case IFIFO: - case IFSOCK: - ndb = 0; - break; - - case IFLNK: - if (sblock->fs_maxsymlinklen != -1) - { - /* Check to see if this is a fastlink. The - old fast link format has fs_maxsymlinklen - of zero and di_blocks zero; the new format has - fs_maxsymlinklen set and we ignore di_blocks. - So check for either. */ - if ((sblock->fs_maxsymlinklen - && dp->di_size < sblock->fs_maxsymlinklen) - || (!sblock->fs_maxsymlinklen && !dp->di_blocks)) - { - /* Fake NDB value so that we will check - all the block pointers past the symlink */ - ndb = howmany (dp->di_size, sizeof (daddr_t)); - if (ndb > NDADDR) - { - int j = ndb - NDADDR; - for (ndb = 1; j > 1; i--) - ndb *= NINDIR (sblock); - ndb += NDADDR; - } - } - else - ndb = howmany (dp->di_size, sblock->fs_bsize); - } - else - ndb = howmany (dp->di_size, sblock->fs_bsize); - break; - - case IFDIR: - inodestate[number] = DIRECTORY; - /* Fall through */ - case IFREG: - ndb = howmany (dp->di_size, sblock->fs_bsize); - break; - - default: - problem (1, "UNKNOWN FILE TYPE I=%Ld (MODE=%ol)", number, mode); - if (reply ("CLEAR")) - { - clear_inode (number, dp); - inodestate[number] = UNALLOC; - continue; - } - inodestate[number] = UNALLOC; - holdallblocks = 1; - warning (0, "WILL TREAT ANY BLOCKS HELD BY I=%Ld " - "AS ALLOCATED", number); - ndb = 0; - } - - if (ndb < 0) - { - problem (1, "BAD FILE SIZE I= %Ld (SIZE == %lld)", number, - dp->di_size); - if (reply ("CLEAR")) - { - clear_inode (number, dp); - inodestate[number] = UNALLOC; - continue; - } - inodestate[number] = UNALLOC; - warning (0, "WILL TREAT ANY BLOCKS HELD BY I=%Ld AS ALLOCATED", - number); - holdallblocks = 1; - } - - /* Make sure that direct and indirect block pointers - past the file size are zero. If the size is bogus, then - don't bother (they should all be zero, but the user has - requested that they be treated as allocated). */ - if (!holdallblocks) - { - if (dp->di_size - && (type == IFBLK || type == IFCHR - || type == IFSOCK || type == IFIFO)) - { - problem (1, "SPECIAL NODE I=%Ld (MODE=%ol) HAS SIZE %lld", - number, mode, dp->di_size); - if (reply ("TRUNCATE")) - { - dp->di_size = 0; - write_inode (number, dp); - } - } - - /* If we haven't set NDB speciall above, then it is set from - the file size correctly by the size check. */ - - /* Check all the direct and indirect blocks that are past the - amount necessary to be zero. */ - for (lbn = ndb; lbn < NDADDR; lbn++) - { - if (dp->di_db[lbn]) - { - if (!dbwarn) - { - dbwarn = 1; - problem (0, "INODE I=%Ld HAS EXTRA DIRECT BLOCKS", - number); - if (preen || reply ("DEALLOCATE")) - { - dp->di_db[lbn] = 0; - dbwarn = 2; - pfix ("DEALLOCATED"); - } - } - else if (dbwarn == 2) - dp->di_db[lbn] = 0; - } - if (dbwarn == 2) - write_inode (number, dp); - } - - for (lbn = 0, ndb -= NDADDR; ndb > 0; lbn++) - ndb /= NINDIR (sblock); - for (; lbn < NIADDR; lbn++) - { - if (dp->di_ib[lbn]) - { - if (ibwarn) - { - ibwarn = 1; - problem (0, "INODE I=%Ld HAS EXTRA INDIRECT BLOCKS", - number); - if (preen || reply ("DEALLOCATE")) - { - dp->di_ib[lbn] = 0; - ibwarn = 2; - pfix ("DEALLOCATED"); - } - } - else if (ibwarn == 2) - dp->di_ib[lbn] = 0; - } - if (ibwarn == 2) - write_inode (number, dp); - } - } - - /* If this node is really allocated (as opposed to something - that we should clear but the user won't) then set LINKCOUNT - and TYPEMAP entries. */ - if (inodestate[number] != UNALLOC) - { - linkcount[number] = dp->di_nlink; - typemap[number] = IFTODT (mode); - } - - /* Iterate over the blocks of the file, - calling CHECKBLOCK for each file. */ - nblocks = 0; - blkerror = 0; - nblkduperrors = 0; - nblkrngerrors = 0; - allblock_iterate (dp, checkblock); - - if (blkerror) - { - if (preen) - warning (1, "DUPLICATE or BAD BLOCKS"); - else - { - problem (0, "I=%Ld has ", number); - if (nblkduperrors) - { - pextend ("%d DUPLICATE BLOCKS", nblkduperrors); - if (nblkrngerrors) - pextend (" and "); - } - if (nblkrngerrors) - pextend ("%d BAD BLOCKS", nblkrngerrors); - if (reply ("CLEAR")) - { - clear_inode (number, dp); - inodestate[number] = UNALLOC; - continue; - } - else if (inodestate[number] == DIRECTORY) - inodestate[number] = BADDIR; - } - } - else if (dp->di_blocks != nblocks) - { - problem (0, "INCORRECT BLOCK COUNT I=%Ld (%ld should be %d)", - number, dp->di_blocks, nblocks); - if (preen || reply ("CORRECT")) - { - dp->di_blocks = nblocks; - write_inode (number, dp); - pfix ("CORRECTED"); - } - } - - num_files++; - - if (type == IFDIR) - record_directory (dp, number); - } - } -} diff --git a/ufs-fsck/pass1b.c b/ufs-fsck/pass1b.c deleted file mode 100644 index 4da86974..00000000 --- a/ufs-fsck/pass1b.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Pass 1b of fsck -- scan inodes for references to duplicate blocks - Copyright (C) 1994,96,2002 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "fsck.h" - -void -pass1b () -{ - struct dinode dino; - struct dinode *dp = &dino; - int cg, i; - ino_t number = 0; - int dupblk; - struct dups *duphead = duplist; - - /* Check each block of file DP; if the block is in the dup block - list then add it to the dup block list under this file. - Return RET_GOOD or RET_BAD if the block is - good or bad, respectively. */ - int - checkblock (daddr_t bno, int nfrags, off_t offset) - { - struct dups *dlp; - int hadbad = 0; - - for (; nfrags > 0; bno++, nfrags--) - { - if (check_range (bno, 1)) - return RET_BAD; - for (dlp = duphead; dlp; dlp = dlp->next) - { - if (dlp->dup == bno) - { - dupblk++; - warning (0, "DUPLICATE BLOCK %ld\n", bno); - dlp->dup = duphead->dup; - duphead->dup = bno; - duphead = duphead->next; - hadbad = 1; - } - if (dlp == muldup) - break; - } - } - return hadbad ? RET_BAD : RET_GOOD; - } - - /* Call CHECKBLOCK for each block of each node, to see if it holds - a block already found to be a duplicate. */ - for (cg = 0; cg < sblock->fs_ncg; cg++) - for (i = 0; i < sblock->fs_ipg; i++, number++) - { - if (number < ROOTINO) - continue; - if (inodestate[number] != UNALLOC) - { - getinode (number, dp); - dupblk = 0; - allblock_iterate (dp, checkblock); - if (dupblk) - { - problem (1, "I=%Ld HAS %d DUPLICATE BLOCKS", number, dupblk); - if (reply ("CLEAR")) - { - clear_inode (number, dp); - inodestate[number] = UNALLOC; - } - else if (inodestate[number] == DIRECTORY) - inodestate[number] = BADDIR; - } - } - } -} diff --git a/ufs-fsck/pass2.c b/ufs-fsck/pass2.c deleted file mode 100644 index d95929ef..00000000 --- a/ufs-fsck/pass2.c +++ /dev/null @@ -1,400 +0,0 @@ -/* Pass 2 of GNU fsck -- examine all directories for validity - Copyright (C) 1994,96,2002 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "fsck.h" -#include <assert.h> - -/* Verify root inode's allocation and check all directories for - viability. Set DIRSORTED array fully and check to make sure - each directory has a correct . and .. in it. */ -void -pass2 () -{ - int nd; - struct dirinfo *dnp; - struct dinode dino; - - /* Return negative, zero, or positive according to the - ordering of the first data block of **DNP1 and **DNP2. */ - int - sortfunc (const void *ptr1, const void *ptr2) - { - struct dirinfo * const *dnp1 = ptr1; - struct dirinfo * const *dnp2 = ptr2; - return ((*dnp1)->i_blks[0] - (*dnp2)->i_blks[0]); - } - - /* Called for each DIRBLKSIZ chunk of the directory. - BUF is the data of the directory block. Return - 1 if this block has been modified and should be written - to disk; otherwise return 0. */ - int - check1block (void *buf) - { - struct directory_entry *dp; - int mod = 0; - u_char namlen; - char type; - int i; - - for (dp = buf; (void *)dp - buf < DIRBLKSIZ; - dp = (struct directory_entry *) ((void *)dp + dp->d_reclen)) - { - /* Check RECLEN for basic validity */ - if (dp->d_reclen == 0 - || dp->d_reclen + (void *)dp - buf > DIRBLKSIZ) - { - /* Perhaps the entire dir block is zero. UFS does that - when extending directories. So allow preening - to safely patch up all-null dir blocks. */ - if (dp == buf) - { - char *bp; - for (bp = (char *)buf; bp < (char *)buf + DIRBLKSIZ; bp++) - if (*bp) - goto reclen_problem; - - problem (0, "NULL BLOCK IN DIRECTORY"); - if (preen || reply ("PATCH")) - { - /* Mark this entry free, and return. */ - dp->d_ino = 0; - dp->d_reclen = DIRBLKSIZ; - pfix ("PATCHED"); - return 1; - } - else - return mod; - } - - reclen_problem: - problem (1, "BAD RECLEN IN DIRECTORY"); - if (reply ("SALVAGE")) - { - /* Skip over everything else in this dirblock; - mark this entry free. */ - dp->d_ino = 0; - dp->d_reclen = DIRBLKSIZ - ((void *)dp - buf); - return 1; - } - else - /* But give up regardless */ - return mod; - } - - /* Check INO */ - if (dp->d_ino > maxino) - { - problem (1, "BAD INODE NUMBER IN DIRECTORY"); - if (reply ("SALVAGE")) - { - /* Mark this entry clear */ - dp->d_ino = 0; - mod = 1; - } - } - - if (!dp->d_ino) - continue; - - /* Check INO */ - if (inodestate[dp->d_ino] == UNALLOC) - { - pinode (0, dnp->i_number, "REF TO UNALLOCATED NODE IN"); - if (preen || reply ("REMOVE")) - { - dp->d_ino = 0; - mod = 1; - pfix ("REMOVED"); - continue; - } - } - - /* Check NAMLEN */ - namlen = DIRECT_NAMLEN (dp); - if (namlen > MAXNAMLEN) - { - problem (1, "BAD NAMLEN IN DIRECTORY"); - if (reply ("SALVAGE")) - { - /* Mark this entry clear */ - dp->d_ino = 0; - mod = 1; - } - } - else - { - /* Check for illegal characters */ - for (i = 0; i < DIRECT_NAMLEN (dp); i++) - if (dp->d_name[i] == '\0' || dp->d_name[i] == '/') - { - problem (1, "ILLEGAL CHARACTER IN FILE NAME"); - if (reply ("SALVAGE")) - { - /* Mark this entry clear */ - dp->d_ino = 0; - mod = 1; - break; - } - } - if (dp->d_name[DIRECT_NAMLEN (dp)]) - { - problem (1, "DIRECTORY NAME NOT TERMINATED"); - if (reply ("SALVAGE")) - { - /* Mark this entry clear */ - dp->d_ino = 0; - mod = 1; - } - } - } - - if (!dp->d_ino) - continue; - - /* Check TYPE */ - type = DIRECT_TYPE (dp); - if (type != DT_UNKNOWN && type != typemap[dp->d_ino]) - { - problem (0, "INCORRECT NODE TYPE IN DIRECTORY"); - if (preen || reply ("CLEAR")) - { - pfix ("CLEARED"); - dp->d_type = 0; - mod = 1; - } - } - - /* Here we should check for duplicate directory entries; - that's too much trouble right now. */ - - /* Account for the inode in the linkfound map */ - if (inodestate[dp->d_ino] != UNALLOC) - linkfound[dp->d_ino]++; - - if (inodestate[dp->d_ino] == DIRECTORY - || inodestate[dp->d_ino] == BADDIR) - { - if (DIRECT_NAMLEN (dp) == 1 && dp->d_name[0] == '.') - dnp->i_dot = dp->d_ino; - else if (DIRECT_NAMLEN (dp) == 2 - && dp->d_name[0] == '.' && dp->d_name[1] == '.') - dnp->i_dotdot = dp->d_ino; - else - { - struct dirinfo *targetdir; - targetdir = lookup_directory (dp->d_ino); - if (targetdir->i_parent) - { - problem (0, "EXTRANEOUS LINK `%s' TO DIR I=%ld", - dp->d_name, dp->d_ino); - pextend (" FOUND IN DIR I=%Ld", dnp->i_number); - if (preen || reply ("REMOVE")) - { - dp->d_ino = 0; - mod = 1; - pfix ("REMOVED"); - } - } - else - targetdir->i_parent = dnp->i_number; - } - } - } - return mod; - } - - /* Called for each filesystem block of the directory. Load BNO - into core and then call CHECK1BLOCK for each DIRBLKSIZ chunk. - OFFSET is the offset this block occupies ithe file. - Always return 1. */ - int - checkdirblock (daddr_t bno, int nfrags, off_t offset) - { - void *buf = alloca (nfrags * sblock->fs_fsize); - void *bufp; - int rewrite; - - readblock (fsbtodb (sblock, bno), buf, nfrags * sblock->fs_fsize); - rewrite = 0; - for (bufp = buf; - bufp - buf < nfrags * sblock->fs_fsize - && offset + (bufp - buf) + DIRBLKSIZ <= dnp->i_isize; - bufp += DIRBLKSIZ) - { - if (check1block (bufp)) - rewrite = 1; - } - if (rewrite) - writeblock (fsbtodb (sblock, bno), buf, nfrags * sblock->fs_fsize); - return 1; - } - - switch (inodestate [ROOTINO]) - { - default: - errexit ("BAD STATE %d FOR ROOT INODE", (int) (inodestate[ROOTINO])); - - case DIRECTORY: - break; - - case UNALLOC: - problem (1, "ROOT INODE UNALLOCATED"); - if (!reply ("ALLOCATE")) - errexit ("ABORTING"); - if (allocdir (ROOTINO, ROOTINO, 0755) != ROOTINO) - errexit ("CANNOT ALLOCATE ROOT INODE"); - break; - - case REG: - problem (1, "ROOT INODE NOT DIRECTORY"); - if (reply ("REALLOCATE")) - freeino (ROOTINO); - if (allocdir (ROOTINO, ROOTINO, 0755) != ROOTINO) - errexit ("CANNOT ALLOCATE ROOT INODE"); - break; - - case BADDIR: - problem (1, "DUPLICATE or BAD BLOCKS IN ROOT INODE"); - if (reply ("REALLOCATE")) - { - freeino (ROOTINO); - if (allocdir (ROOTINO, ROOTINO, 0755) != ROOTINO) - errexit ("CANNOT ALLOCATE ROOT INODE"); - } - if (reply ("CONTINUE") == 0) - errexit ("ABORTING"); - break; - } - - /* Sort inpsort */ - qsort (dirsorted, dirarrayused, sizeof (struct dirinfo *), sortfunc); - - /* Check basic integrity of each directory */ - for (nd = 0; nd < dirarrayused; nd++) - { - dnp = dirsorted[nd]; - - if (dnp->i_isize == 0) - continue; - if (dnp->i_isize % DIRBLKSIZ) - { - problem (0, "DIRECTORY INO=%Ld: LENGTH %d NOT MULTIPLE OF %d", - dnp->i_number, dnp->i_isize, DIRBLKSIZ); - if (preen || reply ("ADJUST")) - { - getinode (dnp->i_number, &dino); - dino.di_size = roundup (dnp->i_isize, DIRBLKSIZ); - write_inode (dnp->i_number, &dino); - pfix ("ADJUSTED"); - } - } - bzero (&dino, sizeof (struct dinode)); - dino.di_size = dnp->i_isize; - assert (dnp->i_numblks <= (NDADDR + NIADDR) * sizeof (daddr_t)); - bcopy (dnp->i_blks, dino.di_db, dnp->i_numblks); - - datablocks_iterate (&dino, checkdirblock); - } - - - /* At this point for each directory: - If this directory is an entry in another directory, then i_parent is - set to that node's number. - If this directory has a `..' entry, then i_dotdot is set to that link. - Check to see that `..' is set correctly. */ - for (nd = 0; nd < dirarrayused; nd++) - { - dnp = dirsorted[nd]; - - /* Root is considered to be its own parent even though it isn't - listed. */ - if (dnp->i_number == ROOTINO && !dnp->i_parent) - dnp->i_parent = ROOTINO; - - /* Check `.' to make sure it exists and is correct */ - if (dnp->i_dot == 0) - { - dnp->i_dot = dnp->i_number; - pinode (0, dnp->i_number, "MISSING `.' IN"); - if ((preen || reply ("FIX")) - && makeentry (dnp->i_number, dnp->i_number, ".")) - { - linkfound[dnp->i_number]++; - pfix ("FIXED"); - } - else - pfail (0); - } - else if (dnp->i_dot != dnp->i_number) - { - pinode (0, dnp->i_number, "BAD INODE NUMBER FOR `.' IN"); - if (preen || reply ("FIX")) - { - ino_t old_dot = dnp->i_dot; - dnp->i_dot = dnp->i_number; - if (changeino (dnp->i_number, ".", dnp->i_number)) - { - linkfound[dnp->i_number]++; - if (inodestate[old_dot] != UNALLOC) - linkfound[old_dot]--; - pfix ("FIXED"); - } - else - pfail (0); - } - } - - /* Check `..' to make sure it exists and is correct */ - if (dnp->i_parent && dnp->i_dotdot == 0) - { - dnp->i_dotdot = dnp->i_parent; - pinode (0, dnp->i_number, "MISSING `..' IN"); - if ((preen || reply ("FIX")) - && makeentry (dnp->i_number, dnp->i_parent, "..")) - { - linkfound[dnp->i_parent]++; - pfix ("FIXED"); - } - else - pfail (0); - } - else if (dnp->i_parent && dnp->i_dotdot != dnp->i_parent) - { - pinode (0, dnp->i_number, "BAD INODE NUMBER FOR `..' IN"); - if (preen || reply ("FIX")) - { - ino_t parent = dnp->i_parent, old_dotdot = dnp->i_dotdot; - dnp->i_dotdot = parent; - if (changeino (dnp->i_number, "..", parent)) - /* Adjust what the parent's link count should be; the actual - count will be corrected in an later pass. */ - { - linkfound[parent]++; - if (inodestate[old_dotdot] != UNALLOC) - linkfound[old_dotdot]--; - pfix ("FIXED"); - } - else - pfail (0); - } - } - } -} diff --git a/ufs-fsck/pass3.c b/ufs-fsck/pass3.c deleted file mode 100644 index fd5ad1b0..00000000 --- a/ufs-fsck/pass3.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Pass 3 of GNU fsck -- Look for disconnected directories - Copyright (C) 1994, 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "fsck.h" - -void -pass3 () -{ - struct dirinfo *dnp; - int nd; - int change; - - /* Mark all the directories that can be found from the root. */ - - inodestate[ROOTINO] |= DIR_REF; - - do - { - change = 0; - for (nd = 0; nd < dirarrayused; nd++) - { - dnp = dirsorted[nd]; - if (dnp->i_parent - && inodestate[dnp->i_parent] == (DIRECTORY | DIR_REF) - && inodestate[dnp->i_number] == DIRECTORY) - { - inodestate[dnp->i_number] |= DIR_REF; - change = 1; - } - } - } - while (change); - - /* Check for orphaned directories */ - for (nd = 0; nd < dirarrayused; nd++) - { - dnp = dirsorted[nd]; - - if (dnp->i_parent == 0) - { - if (inodestate[dnp->i_number] & DIR_REF) - errexit ("ORPHANED DIR MARKED WITH CONNECT"); - pinode (0, dnp->i_number, "UNREF"); - if ((preen || reply ("RECONNECT")) - && linkup (dnp->i_number, dnp->i_dotdot)) - { - dnp->i_parent = dnp->i_dotdot = lfdir; - pfix ("RECONNECTED"); - } - else - pfail (0); - } - } -} diff --git a/ufs-fsck/pass4.c b/ufs-fsck/pass4.c deleted file mode 100644 index f8fe9814..00000000 --- a/ufs-fsck/pass4.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Pass 4 of GNU fsck -- Check reference counts - Copyright (C) 1994, 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "fsck.h" - -void -pass4() -{ - ino_t number; - /* True if any reconnect attempt failed, in which case we don't try again. */ - int reconn_failed = 0; - - for (number = ROOTINO; number < maxino; number++) - { - if (linkfound[number] && inodestate[number] != UNALLOC) - { - if (linkcount[number] != linkfound[number]) - { - pinode (0, number, - "LINK COUNT %d SHOULD BE %d IN", - linkcount[number], linkfound[number]); - if (preen || reply ("ADJUST")) - { - struct dinode dino; - getinode (number, &dino); - dino.di_nlink = linkfound[number]; - write_inode (number, &dino); - pfix ("ADJUSTED"); - } - } - } - else if (linkfound[number] && inodestate[number] == UNALLOC) - { - /* This can't happen because we never count links to unallocated - nodes. */ - errexit ("LINK RECORDED FOR UNALLOCATED NODE"); - } - else if (!linkfound[number] && inodestate[number] != UNALLOC) - { - /* No links to allocated node. If the size is zero, then - we want to clear it; if the size is positive, then we - want to reattach in. */ - struct dinode dino; - - pinode (0, number, "UNREF"); - - getinode (number, &dino); - if (dino.di_size && !reconn_failed) - { - /* This can't happen for dirctories because pass 3 should - already have reset them up. */ - if ((DI_MODE (&dino) & IFMT) == IFDIR) - errexit ("NO LINKS TO NONZERO DIRECTORY"); - - if (preen || reply ("RECONNECT")) - reconn_failed = !linkup (number, -1); - if (! reconn_failed) - pfix ("RECONNECTED"); - if (preen && reconn_failed) - pfail ("RECONNECT FAILED"); - } - if (dino.di_size == 0 || reconn_failed) - { - if (reconn_failed && !preen) - /* If preening, the previous call to problem is still active - (more likely the failure was too severe, and exited). */ - problem (0, "RECONNECT FAILED"); - if (preen || reply ("CLEAR")) - { - inodestate[number] = UNALLOC; - clear_inode (number, &dino); - pfix ("CLEARED"); - } - } - } - } -} diff --git a/ufs-fsck/pass5.c b/ufs-fsck/pass5.c deleted file mode 100644 index cb426a7d..00000000 --- a/ufs-fsck/pass5.c +++ /dev/null @@ -1,450 +0,0 @@ -/* Pass 5 of GNU fsck -- check allocation maps and summaries - Copyright (C) 1994,96,2001 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "fsck.h" - -/* From ../ufs/subr.c: */ - -/* - * Update the frsum fields to reflect addition or deletion - * of some frags. - */ -static void -ffs_fragacct(fs, fragmap, fraglist, cnt) - struct fs *fs; - int fragmap; - long fraglist[]; - int cnt; -{ - int inblk; - register int field, subfield; - register int siz, pos; - - inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1; - fragmap <<= 1; - for (siz = 1; siz < fs->fs_frag; siz++) { - if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) - continue; - field = around[siz]; - subfield = inside[siz]; - for (pos = siz; pos <= fs->fs_frag; pos++) { - if ((fragmap & field) == subfield) { - fraglist[siz] += cnt; - pos += siz; - field <<= siz; - subfield <<= siz; - } - field <<= 1; - subfield <<= 1; - } - } -} - -void -pass5 () -{ - struct cg *newcg, *cg; - struct ocg *newocg; - int savednrpos = 0; - struct csum cstotal; - int i, j; - int c; - daddr_t d; - struct csum *sbcsums; - - int basesize; /* size of cg not counting flexibly sized */ - int sumsize; /* size of block totals and pos tbl */ - int mapsize; /* size of inode map + block map */ - - int writesb; - int writecg; - int writecsum; - - writesb = 0; - writecsum = 0; - - cg = alloca (sblock->fs_cgsize); - - newcg = alloca (sblock->fs_cgsize); - newocg = (struct ocg *)newcg; - - sbcsums = alloca (fragroundup (sblock, sblock->fs_cssize)); - - readblock (fsbtodb (sblock, sblock->fs_csaddr), sbcsums, - fragroundup (sblock, sblock->fs_cssize)); - - /* Construct a CG structure; initialize everything that's the same - in each cylinder group. */ - bzero (newcg, sblock->fs_cgsize); - newcg->cg_niblk = sblock->fs_ipg; - switch (sblock->fs_postblformat) - { - case FS_42POSTBLFMT: - /* Initialize size information */ - basesize = (char *)(&newocg->cg_btot[0]) - (char *)(&newocg->cg_link); - sumsize = &newocg->cg_iused[0] - (char *)(&newocg->cg_btot[0]); - mapsize = (&newocg->cg_free[howmany(sblock->fs_fpg, NBBY)] - - (u_char *)&newocg->cg_iused[0]); - savednrpos = sblock->fs_nrpos; - sblock->fs_nrpos = 8; - break; - - case FS_DYNAMICPOSTBLFMT: - /* Set fields unique to new cg structure */ - newcg->cg_btotoff = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); - newcg->cg_boff = newcg->cg_btotoff + sblock->fs_cpg * sizeof (long); - newcg->cg_iusedoff = newcg->cg_boff + (sblock->fs_cpg - * sblock->fs_nrpos - * sizeof (short)); - newcg->cg_freeoff = newcg->cg_iusedoff + howmany (sblock->fs_ipg, NBBY); - - if (sblock->fs_contigsumsize <= 0) - { - newcg->cg_nextfreeoff = - (newcg->cg_freeoff - + howmany (sblock->fs_cpg * sblock->fs_spc / NSPF (sblock), - NBBY)); - } - else - { - newcg->cg_clustersumoff = - (newcg->cg_freeoff - + howmany (sblock->fs_cpg * sblock->fs_spc / NSPF (sblock), NBBY) - - sizeof (long)); - newcg->cg_clustersumoff = - roundup (newcg->cg_clustersumoff, sizeof (long)); - newcg->cg_clusteroff = - (newcg->cg_clustersumoff - + (sblock->fs_contigsumsize + 1) * sizeof (long)); - newcg->cg_nextfreeoff = - (newcg->cg_clusteroff - + howmany (sblock->fs_cpg * sblock->fs_spc / NSPB (sblock), - NBBY)); - } - - newcg->cg_magic = CG_MAGIC; - - /* Set map sizes */ - basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); - sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; - mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; - break; - - default: - errexit ("UNKNOWN POSTBL FORMAT"); - } - - bzero (&cstotal, sizeof (struct csum)); - - /* Mark fragments past the end of the filesystem as used. */ - j = blknum (sblock, sblock->fs_size + sblock->fs_frag - 1); - for (i = sblock->fs_size; i < j; i++) - setbmap (i); - - /* Now walk through the cylinder groups, checking each one. */ - for (c = 0; c < sblock->fs_ncg; c++) - { - int dbase, dmax; - - /* Read the cylinder group structure */ - readblock (fsbtodb (sblock, cgtod (sblock, c)), cg, sblock->fs_cgsize); - writecg = 0; - - if (!cg_chkmagic (cg)) - warning (1, "CG %d: BAD MAGIC NUMBER", c); - - /* Compute first and last data block addresses in this group */ - dbase = cgbase (sblock, c); - dmax = dbase + sblock->fs_fpg; - if (dmax > sblock->fs_size) - dmax = sblock->fs_size; - - /* Initialize newcg fully; values from cg for those - we can't check. */ - newcg->cg_time = cg->cg_time; - newcg->cg_cgx = c; - if (c == sblock->fs_ncg - 1) - newcg->cg_ncyl = sblock->fs_ncyl % sblock->fs_cpg; - else - newcg->cg_ncyl = sblock->fs_cpg; - newcg->cg_ndblk = dmax - dbase; - if (sblock->fs_contigsumsize > 0) - newcg->cg_nclusterblks = newcg->cg_ndblk / sblock->fs_frag; - newcg->cg_cs.cs_ndir = 0; - newcg->cg_cs.cs_nffree = 0; - newcg->cg_cs.cs_nbfree = 0; - newcg->cg_cs.cs_nifree = sblock->fs_ipg; - - /* Check these for basic viability; if they are wrong - then clear them. */ - newcg->cg_rotor = cg->cg_rotor; - newcg->cg_frotor = cg->cg_frotor; - newcg->cg_irotor = cg->cg_irotor; - if (newcg->cg_rotor > newcg->cg_ndblk) - { - problem (0, "ILLEGAL ROTOR VALUE IN CG %d", c); - if (preen || reply ("FIX")) - { - newcg->cg_rotor = 0; - cg->cg_rotor = 0; - writecg = 1; - pfix ("FIXED"); - } - } - if (newcg->cg_frotor > newcg->cg_ndblk) - { - problem (0, "ILLEGAL FROTOR VALUE IN CG %d", c); - if (preen || reply ("FIX")) - { - newcg->cg_frotor = 0; - cg->cg_frotor = 0; - writecg = 1; - pfix ("FIXED"); - } - } - if (newcg->cg_irotor > newcg->cg_niblk) - { - problem (0, "ILLEGAL IROTOR VALUE IN CG %d", c); - if (preen || reply ("FIX")) - { - newcg->cg_irotor = 0; - cg->cg_irotor = 0; - writecg = 1; - pfix ("FIXED"); - } - } - - /* Zero the block maps and summary areas */ - bzero (&newcg->cg_frsum[0], sizeof newcg->cg_frsum); - bzero (&cg_blktot (newcg)[0], sumsize + mapsize); - if (sblock->fs_postblformat == FS_42POSTBLFMT) - newocg->cg_magic = CG_MAGIC; - - /* Walk through each inode, accounting for it in - the inode map and in newcg->cg_cs. */ - /* In this loop, J is the inode number, and I is the - inode number relative to this CG. */ - j = sblock->fs_ipg * c; - for (i = 0; i < sblock->fs_ipg; j++, i++) - switch (inodestate[j]) - { - case DIRECTORY: - case DIRECTORY | DIR_REF: - case BADDIR: - newcg->cg_cs.cs_ndir++; - /* Fall through... */ - case REG: - newcg->cg_cs.cs_nifree--; - setbit (cg_inosused (newcg), i); - /* Fall through... */ - case UNALLOC: - break; - - default: - errexit ("UNKNOWN STATE I=%d", j); - } - /* Account for inodes 0 and 1 */ - if (c == 0) - for (i = 0; i < ROOTINO; i++) - { - setbit (cg_inosused (newcg), i); - newcg->cg_cs.cs_nifree--; - } - - /* Walk through each data block, accounting for it in - the block map and in newcg->cg_cs. */ - /* In this look, D is the block number and I is the - block number relative to this CG. */ - for (i = 0, d = dbase; - d < dmax; - d += sblock->fs_frag, i += sblock->fs_frag) - { - int frags = 0; - - /* Set each free frag of this block in the block map; - count how many frags were free. */ - for (j = 0; j < sblock->fs_frag; j++) - { - if (testbmap (d + j)) - continue; - setbit (cg_blksfree (newcg), i + j); - frags++; - } - - /* If all the frags were free, then count this as - a free block too. */ - if (frags == sblock->fs_frag) - { - newcg->cg_cs.cs_nbfree++; - j = cbtocylno (sblock, i); - cg_blktot(newcg)[j]++; - cg_blks(sblock, newcg, j)[cbtorpos(sblock, i)]++; - if (sblock->fs_contigsumsize > 0) - setbit (cg_clustersfree (newcg), i / sblock->fs_frag); - } - else if (frags) - { - /* Partial; account for the frags. */ - int blk; - newcg->cg_cs.cs_nffree += frags; - blk = blkmap (sblock, cg_blksfree (newcg), i); - ffs_fragacct (sblock, blk, newcg->cg_frsum, 1); - } - } - - if (sblock->fs_contigsumsize > 0) - { - long *sump = cg_clustersum (newcg); - u_char *mapp = cg_clustersfree (newcg); - int map = *mapp++; - int bit = 1; - int run = 0; - - for (i = 0; i < newcg->cg_nclusterblks; i++) - { - if ((map & bit) != 0) - run++; - else if (run) - { - if (run > sblock->fs_contigsumsize) - run = sblock->fs_contigsumsize; - sump[run]++; - run = 0; - } - - if ((i & (NBBY - 1)) != (NBBY - 1)) - bit <<= 1; - else - { - map = *mapp++; - bit = 1; - } - } - if (run != 0) - { - if (run > sblock->fs_contigsumsize) - run = sblock->fs_contigsumsize; - sump[run]++; - } - } - - /* Add this cylinder group's totals into the superblock's - totals. */ - cstotal.cs_nffree += newcg->cg_cs.cs_nffree; - cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; - cstotal.cs_nifree += newcg->cg_cs.cs_nifree; - cstotal.cs_ndir += newcg->cg_cs.cs_ndir; - - /* Check counts in superblock */ - if (bcmp (&newcg->cg_cs, &sbcsums[c], sizeof (struct csum))) - { - problem (0, "FREE BLK COUNTS FOR CG %d WRONG IN SUPERBLOCK", c); - if (preen || reply ("FIX")) - { - bcopy (&newcg->cg_cs, &sbcsums[c], sizeof (struct csum)); - writecsum = 1; - pfix ("FIXED"); - } - } - - /* Check inode and block maps */ - if (bcmp (cg_inosused (newcg), cg_inosused (cg), mapsize)) - { - problem (0, "BLKS OR INOS MISSING IN CG %d BIT MAPS", c); - if (preen || reply ("FIX")) - { - bcopy (cg_inosused (newcg), cg_inosused (cg), mapsize); - writecg = 1; - pfix ("FIXED"); - } - } - - if (bcmp (&cg_blktot(newcg)[0], &cg_blktot(cg)[0], sumsize)) - { - problem (0, "SUMMARY INFORMATION FOR CG %d BAD", c); - if (preen || reply ("FIX")) - { - bcopy (&cg_blktot(newcg)[0], &cg_blktot(cg)[0], sumsize); - writecg = 1; - pfix ("FIXED"); - } - } - - if (bcmp (newcg, cg, basesize)) - { - problem (0, "CYLINDER GROUP %d BAD", c); - if (preen || reply ("FIX")) - { - bcopy (newcg, cg, basesize); - writecg = 1; - pfix ("FIXED"); - } - } - - if (writecg) - writeblock (fsbtodb (sblock, cgtod (sblock, c)), - cg, sblock->fs_cgsize); - } - - /* Restore nrpos */ - if (sblock->fs_postblformat == FS_42POSTBLFMT) - sblock->fs_nrpos = savednrpos; - - if (bcmp (&cstotal, &sblock->fs_cstotal, sizeof (struct csum))) - { - problem (0, "TOTAL FREE BLK COUNTS WRONG IN SUPERBLOCK"); - if (preen || reply ("FIX")) - { - bcopy (&cstotal, &sblock->fs_cstotal, sizeof (struct csum)); - sblock->fs_ronly = 0; - sblock->fs_fmod = 0; - writesb = 1; - pfix ("FIXED"); - } - } - - if (sblock->fs_clean == 0 && !fix_denied) - { - problem (0, fsmodified ? "FILESYSTEM MODIFIED" : "FILESYSTEM UNCLEAN"); - if (preen || reply ("MARK CLEAN")) - { - sblock->fs_clean = 1; - writesb = 1; - pfix ("MARKED CLEAN"); - } - } - - if (writesb) - writeblock (SBLOCK, sblock, SBSIZE); - - if (writecsum) - { - const int cssize = fragroundup (sblock, sblock->fs_cssize); - struct csum *test; - - writeblock (fsbtodb (sblock, sblock->fs_csaddr), sbcsums, - fragroundup (sblock, sblock->fs_cssize)); - - test = alloca (cssize); - readblock (fsbtodb (sblock, sblock->fs_csaddr), test, cssize); - if (bcmp (test, sbcsums, cssize)) - warning (0, "CSUM WRITE INCONSISTENT"); - } -} diff --git a/ufs-fsck/setup.c b/ufs-fsck/setup.c deleted file mode 100644 index 9433bd68..00000000 --- a/ufs-fsck/setup.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - Copyright (C) 1994,96,99,2002 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "fsck.h" -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <error.h> - -static char sblockbuf[SBSIZE]; -struct fs *sblock = (struct fs *)sblockbuf; - -/* A string identifying what we're trying to check. */ -char *device_name = 0; - -daddr_t maxfsblock; -int maxino; -int direct_symlink_extension; - -int newinofmt; - -int readfd, writefd; - -int fix_denied = 0; - -int fsmodified = 0; - -ino_t lfdir; - -/* Get ready to run on device with pathname DEV. */ -int -setup (char *dev) -{ - struct stat st; - int changedsb; - size_t bmapsize; - - device_name = dev; - - if (stat (dev, &st) == -1) - { - error (0, errno, "%s", dev); - return 0; - } - if (!S_ISCHR (st.st_mode) && !S_ISBLK (st.st_mode)) - { - problem (1, "%s is not a character or block device", dev); - if (! reply ("CONTINUE")) - return 0; - } - if (preen == 0) - printf ("** %s", dev); - if (!nowrite) - readfd = open (dev, O_RDWR); - if (nowrite || readfd == -1) - { - readfd = open (dev, O_RDONLY); - if (readfd == -1) - { - error (0, errno, "%s", dev); - return 0; - } - writefd = -1; - nowrite = 1; - if (preen) - warning (1, "NO WRITE ACCESS"); - printf (" (NO WRITE)"); - } - else - writefd = readfd; - - if (preen == 0) - printf ("\n"); - - lfdir = 0; - - /* We don't do the alternate superblock stuff here (yet). */ - readblock (SBLOCK, sblock, SBSIZE); - changedsb = 0; - - if (sblock->fs_magic != FS_MAGIC) - { - warning (1, "BAD MAGIC NUMBER"); - return 0; - } - if (sblock->fs_ncg < 1) - { - warning (1, "NCG OUT OF RANGE"); - return 0; - } - if (sblock->fs_cpg < 1) - { - warning (1, "CPG OUT OF RANGE"); - return 0; - } - if (sblock->fs_ncg * sblock->fs_cpg < sblock->fs_ncyl - || (sblock->fs_ncg - 1) * sblock->fs_cpg >= sblock->fs_ncyl) - { - warning (1, "NCYL INCONSISTENT WITH NCG AND CPG"); - return 0; - } - if (sblock->fs_sbsize > SBSIZE) - { - warning (1, "SBLOCK SIZE PREPONTEROUSLY LARGE"); - return 0; - } - if (sblock->fs_optim != FS_OPTTIME && sblock->fs_optim != FS_OPTSPACE) - { - problem (1, "UNDEFINED OPTIMIZATION IN SUPERBLOCK"); - if (reply ("SET TO DEFAULT")) - { - sblock->fs_optim = FS_OPTTIME; - changedsb = 1; - } - } - if (sblock->fs_minfree < 0 || sblock->fs_minfree > 99) - { - problem (0, "IMPOSSIBLE MINFREE=%ld IN SUPERBLOCK", sblock->fs_minfree); - if (preen || reply ("SET TO DEFAULT")) - { - sblock->fs_minfree = 10; - changedsb = 1; - pfix ("SET TO DEFAULT"); - } - } - if (sblock->fs_interleave < 1 - || sblock->fs_interleave > sblock->fs_nsect) - { - problem (0, "IMPOSSIBLE INTERLEAVE=%ld IN SUPERBLOCK", - sblock->fs_interleave); - if (preen || reply ("SET TO DEFAULT")) - { - sblock->fs_interleave = 1; - changedsb = 1; - pfix ("SET TO DEFAULT"); - } - } - if (sblock->fs_npsect < sblock->fs_nsect - || sblock->fs_npsect > sblock->fs_nsect * 2) - { - problem (0, "IMPOSSIBLE NPSECT=%ld IN SUPERBLOCK", sblock->fs_npsect); - if (preen || reply ("SET TO DEFAULT")) - { - sblock->fs_npsect = sblock->fs_nsect; - changedsb = 1; - pfix ("SET TO DEFAULT"); - } - } - if (sblock->fs_inodefmt >= FS_44INODEFMT) - newinofmt = 1; - else - { - sblock->fs_qbmask = ~sblock->fs_bmask; - sblock->fs_qfmask = ~sblock->fs_fmask; - newinofmt = 0; - } - - if (changedsb) - writeblock (SBLOCK, sblock, SBSIZE); - - /* Constants */ - maxfsblock = sblock->fs_size; - maxino = sblock->fs_ncg * sblock->fs_ipg; - direct_symlink_extension = sblock->fs_maxsymlinklen > 0; - - /* Allocate and initialize maps */ - bmapsize = roundup (howmany (maxfsblock, NBBY), sizeof (short)); - blockmap = calloc (bmapsize, sizeof (char)); - inodestate = calloc (maxino + 1, sizeof (char)); - typemap = calloc (maxino + 1, sizeof (char)); - linkcount = calloc (maxino + 1, sizeof (nlink_t)); - linkfound = calloc (maxino + 1, sizeof (nlink_t)); - return 1; -} diff --git a/ufs-fsck/utilities.c b/ufs-fsck/utilities.c deleted file mode 100644 index 14705f84..00000000 --- a/ufs-fsck/utilities.c +++ /dev/null @@ -1,455 +0,0 @@ -/* Miscellaneous functions for fsck - Copyright (C) 1994,95,96,99,2001,02 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "fsck.h" -#include <fcntl.h> -#include <sys/file.h> -#include <unistd.h> -#include <stdarg.h> -#include <pwd.h> -#include <error.h> -#include <time.h> - -static void retch (char *reason); - -/* Read disk block ADDR into BUF of SIZE bytes. */ -void -readblock (daddr_t addr, void *buf, size_t size) -{ - if (lseek (readfd, addr * DEV_BSIZE, L_SET) == -1) - errexit ("CANNOT SEEK TO BLOCK %ld", addr); - if (read (readfd, buf, size) != size) - errexit ("CANNOT READ BLOCK %ld", addr); -} - -/* Write disk block BLKNO from BUF of SIZE bytes. */ -void -writeblock (daddr_t addr, void *buf, size_t size) -{ - if (lseek (writefd, addr * DEV_BSIZE, L_SET) == -1) - errexit ("CANNOT SEEK TO BLOCK %ld", addr); - if (write (writefd, buf, size) != size) - errexit ("CANNOT WRITE BLOCK %ld", addr); - fsmodified = 1; -} - -/* Last filesystem fragment that we read an inode from */ -static char *lastifrag; -static daddr_t lastifragaddr; - -/* Read inode number INO into DINODE. */ -void -getinode (ino_t ino, struct dinode *di) -{ - daddr_t iblk; - - if (!lastifrag) - lastifrag = malloc (sblock->fs_bsize); - - iblk = ino_to_fsba (sblock, ino); - if (iblk != lastifragaddr) - readblock (fsbtodb (sblock, iblk), lastifrag, sblock->fs_bsize); - lastifragaddr = iblk; - bcopy (lastifrag + ino_to_fsbo (sblock, ino) * sizeof (struct dinode), - di, sizeof (struct dinode)); -} - -/* Write inode number INO from DINODE. */ -void -write_inode (ino_t ino, struct dinode *di) -{ - daddr_t iblk; - - iblk = ino_to_fsba (sblock, ino); - if (iblk != lastifragaddr) - readblock (fsbtodb (sblock, iblk), lastifrag, sblock->fs_bsize); - lastifragaddr = iblk; - bcopy (di, lastifrag + ino_to_fsbo (sblock, ino) * sizeof (struct dinode), - sizeof (struct dinode)); - writeblock (fsbtodb (sblock, iblk), lastifrag, sblock->fs_bsize); -} - -/* Clear inode number INO and zero DI. */ -void -clear_inode (ino_t ino, struct dinode *di) -{ - bzero (di, sizeof (struct dinode)); - write_inode (ino, di); -} - -/* Allocate and return a block and account for it in all the block - maps locally. Don't trust or change the disk block maps. - The block should be NFRAGS fragments long. */ -daddr_t -allocblk (int nfrags) -{ - daddr_t i; - int j, k; - - if (nfrags <= 0 || nfrags > sblock->fs_frag) - return 0; - - /* Examine each block of the filesystem. */ - for (i = 0; i < maxfsblock - sblock->fs_frag; i += sblock->fs_frag) - { - /* For each piece of the block big enough to hold this frag... */ - for (j = 0; j <= sblock->fs_frag - nfrags; j++) - { - /* For each frag of this piece... */ - for (k = 0; k < nfrags; k++) - if (testbmap (i + j + k)) - break; - - /* If one of the frags was allocated... */ - if (k < nfrags) - { - /* Skip at least that far (short cut) */ - j += k; - continue; - } - - /* It's free (at address i + j) */ - - /* Mark the frags allocated in our map */ - for (k = 0; k < nfrags; k++) - setbmap (i + j + k); - - return (i + j); - } - } - return 0; -} - -/* Check if a block starting at BLK and extending for CNT - fragments is out of range; if it is, then return 1; otherwise return 0. */ -int -check_range (daddr_t blk, int cnt) -{ - int c; - - if ((unsigned)(blk + cnt) > maxfsblock) - return 1; - - c = dtog (sblock, blk); - if (blk < cgdmin (sblock, c)) - { - if (blk + cnt > cgsblock (sblock, c)) - return 1; - } - else - { - if (blk + cnt > cgbase (sblock, c + 1)) - return 1; - } - - return 0; -} - -struct problem { - char *desc; - struct problem *prev; -}; - -/* A queue of problems found by fsck that are waiting resolution. The front - of the list is the most recent problem found (and presumably since - previous problems haven't been resolved yet, they depend on this one being - solved for their resolution). */ -static struct problem *problems = 0; - -static struct problem *free_problems = 0; - -static void -push_problem (char *fmt, va_list args) -{ - struct problem *prob = free_problems; - - if (! prob) - prob = malloc (sizeof (struct problem)); - else - problems = prob->prev; - if (! prob) - retch ("malloc failed"); - - if (vasprintf (&prob->desc, fmt, args) < 0) - retch ("vasprintf failed"); - - prob->prev = problems; - problems = prob; -} - -/* Print the most recent problem, and perhaps how it was resolved. */ -static void -resolve_problem (char *fix) -{ - struct problem *prob = problems; - - if (! prob) - retch ("no more problems"); - - problems = prob->prev; - prob->prev = free_problems; - - if (preen && device_name) - printf ("%s: %s", device_name, prob->desc); - else - printf ("%s", prob->desc); - if (fix) - printf (" (%s)\n", fix); - else - putchar ('\n'); - free (prob->desc); -} - -/* Retire all problems as if they failed. We print them in chronological - order rather than lifo order, as this is a bit clearer, and we can do it - when we know they're all going to fail. */ -static void -flush_problems () -{ - struct problem *fail (struct problem *prob) - { - struct problem *last = prob->prev ? fail (prob->prev) : prob; - if (preen && device_name) - printf ("%s: %s\n", device_name, prob->desc); - else - puts (prob->desc); - free (prob->desc); - return last; - } - if (problems) - { - fail (problems)->prev = free_problems; - free_problems = problems; - } -} - -/* Like printf, but exit after printing. */ -void -errexit (char *fmt, ...) -{ - va_list args; - - flush_problems (); - - if (preen && device_name) - printf ("%s: ", device_name); - - va_start (args, fmt); - vprintf (fmt, args); - va_end (args); - putchar ('\n'); - - exit (8); -} - -static void -retch (char *reason) -{ - flush_problems (); - error (99, 0, "(internal error) %s!", reason); -} - -/* Prints all unresolved problems and exits, printing MSG as well. */ -static void -punt (char *msg) -{ - problem (0, "%s", msg); - flush_problems (); - exit (8); -} - -/* If SEVERE is true, and we're in preen mode, then things are too hair to - fix automatically, so tell the user to do it himself and punt. */ -static void -no_preen (int severe) -{ - if (severe && preen) - punt ("PLEASE RUN fsck MANUALLY"); -} - -/* Store away the given message about a problem found. A call to problem must - be matched later with a call to pfix, pfail, or reply; to print more - in the same message, intervening calls to pextend can be used. If SEVERE is - true, and we're in preen mode, then the program is terminated. */ -void -problem (int severe, char *fmt, ...) -{ - va_list args; - - va_start (args, fmt); - push_problem (fmt, args); - va_end (args); - - no_preen (severe); -} - -/* Following a call to problem (with perhaps intervening calls to - pmore), appends the given message to that message. */ -void -pextend (char *fmt, ...) -{ - va_list args; - char *more, *concat; - struct problem *prob = problems; - - if (! prob) - retch ("No pending problem to add to"); - - va_start (args, fmt); - if (vasprintf (&more, fmt, args) < 0) - retch ("vasprintf failed"); - va_end (args); - - concat = realloc (prob->desc, strlen (prob->desc) + 1 + strlen (more) + 1); - if (! concat) - retch ("realloc failed"); - - strcpy (concat + strlen (concat), more); - prob->desc = concat; - free (more); -} - -/* Like problem, but as if immediately followed by pfail. */ -void -warning (int severe, char *fmt, ...) -{ - va_list args; - - va_start (args, fmt); - push_problem (fmt, args); - va_end (args); - - no_preen (severe); - - resolve_problem (0); -} - -/* Like problem, but appends a helpful description of the given inode number to - the message. */ -void -pinode (int severe, ino_t ino, char *fmt, ...) -{ - if (fmt) - { - va_list args; - va_start (args, fmt); - push_problem (fmt, args); - va_end (args); - } - - if (ino < ROOTINO || ino > maxino) - pextend (" (BOGUS INODE) I=%Ld", ino); - else - { - char *p; - struct dinode dino; - struct passwd *pw; - - getinode (ino, &dino); - - pextend (" %s I=%Ld", (DI_MODE (&dino) & IFMT) == IFDIR ? "DIR" : "FILE", - ino); - - pw = getpwuid (dino.di_uid); - if (pw) - pextend (" O=%s", pw->pw_name); - else - pextend (" O=%lu", dino.di_uid); - - pextend (" M=0%o", DI_MODE (&dino)); - pextend (" SZ=%llu", dino.di_size); - p = ctime (&dino.di_mtime.tv_sec); - pextend (" MT=%12.12s %4.4s", &p[4], &p[20]); - } - - no_preen (severe); -} - -/* Print a successful resolution to a pending problem. Must follow a call to - problem or pextend. */ -void -pfix (char *fix) -{ - if (preen) - resolve_problem (fix ?: "FIXED"); -} - -/* Print an unsuccessful resolution to a pending problem. Must follow a call - to problem or pextend. */ -void -pfail (char *failure) -{ - if (preen) - resolve_problem (failure); -} - -/* Ask the user a question; return 1 if the user says yes, and 0 - if the user says no. This call must follow a call to problem or pextend, - which it completes. */ -int -reply (char *question) -{ - int persevere; - char c; - - if (preen) - retch ("Got to reply() in preen mode"); - - /* Emit the problem to which the question pertains. */ - resolve_problem (0); - - persevere = !strcmp (question, "CONTINUE"); - - if (!persevere && (nowrite || writefd < 0)) - { - fix_denied = 1; - printf ("%s? no\n\n", question); - return 0; - } - else if (noquery || (persevere && nowrite)) - { - printf ("%s? yes\n\n", question); - return 1; - } - else - { - do - { - printf ("%s? [yn] ", question); - fflush (stdout); - c = getchar (); - while (c != '\n' && getchar () != '\n') - if (feof (stdin)) - { - fix_denied = 1; - return 0; - } - } - while (c != 'y' && c != 'Y' && c != 'n' && c != 'N'); - putchar ('\n'); - if (c == 'y' || c == 'Y') - return 1; - else - { - fix_denied = 1; - return 0; - } - } -} |