summaryrefslogtreecommitdiff
path: root/ufs-fsck
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2013-09-17 19:20:42 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2013-09-17 19:20:42 +0200
commit84cf9c0f312637b670cc87224ff7e7c4da659e36 (patch)
tree5e7f0f1f6c7579d1275bb5cf1856ce52767ac8b3 /ufs-fsck
parent3e6aab0243da094f1ca05b80eb3e5a9adb8ea519 (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/Makefile33
-rw-r--r--ufs-fsck/dir.c567
-rw-r--r--ufs-fsck/fsck.h183
-rw-r--r--ufs-fsck/inode.c203
-rw-r--r--ufs-fsck/main.c170
-rw-r--r--ufs-fsck/pass1.c437
-rw-r--r--ufs-fsck/pass1b.c90
-rw-r--r--ufs-fsck/pass2.c400
-rw-r--r--ufs-fsck/pass3.c71
-rw-r--r--ufs-fsck/pass4.c94
-rw-r--r--ufs-fsck/pass5.c450
-rw-r--r--ufs-fsck/setup.c191
-rw-r--r--ufs-fsck/utilities.c455
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;
- }
- }
-}