diff --git a/sbin/fsck/Makefile b/sbin/fsck/Makefile deleted file mode 100644 index 87d57f7a9..000000000 --- a/sbin/fsck/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# $NetBSD: Makefile,v 1.18 2009/06/05 21:52:31 haad Exp $ - -PROG= fsck -SRCS= fsck.c fsutil.c preen.c -MAN= fsck.8 - -LDADD+=-lutil -DPADD+=${LIBUTIL} - -LDADD+=-lprop -DPADD+=${LIBPROP} - -.include diff --git a/sbin/fsck/exitvalues.h b/sbin/fsck/exitvalues.h deleted file mode 100644 index 98ab81705..000000000 --- a/sbin/fsck/exitvalues.h +++ /dev/null @@ -1,36 +0,0 @@ -/* $NetBSD: exitvalues.h,v 1.3 2015/06/21 03:33:22 dholland Exp $ */ -/*- - * Copyright (c) 2008 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#define FSCK_EXIT_OK 0 -#define FSCK_EXIT_USAGE 1 -#define FSCK_EXIT_UNRESOLVED 2 -#define FSCK_EXIT_ROOT_CHANGED 4 -#define FSCK_EXIT_CHECK_FAILED 8 -#define FSCK_EXIT_SIGNALLED 12 diff --git a/sbin/fsck/fsck.8 b/sbin/fsck/fsck.8 deleted file mode 100644 index f4a7a2f1d..000000000 --- a/sbin/fsck/fsck.8 +++ /dev/null @@ -1,176 +0,0 @@ -.\" $NetBSD: fsck.8,v 1.38 2011/04/28 12:16:10 wiz Exp $ -.\" -.\" Copyright (c) 1996 Christos Zoulas. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.Dd February 17, 2010 -.Dt FSCK 8 -.Os -.Sh NAME -.Nm fsck -.Nd file system consistency check and interactive repair -.Sh SYNOPSIS -.Nm -.Op Fl dfnPpqvy -.Op Fl l Ar maxparallel -.Op Fl T Ar fstype:fsoptions -.Op Fl t Ar fstype -.Op Fl x Ar mountpoint -.Op special | node ... -.Sh DESCRIPTION -The -.Nm -command invokes file system-specific programs to check -the special devices listed in the -.Xr fstab 5 -file or in the command line for consistency. -.Pp -It is normally used in the script -.Pa /etc/rc -during automatic reboot. -If no file systems are specified, and -.Dq preen -mode is enabled ( -.Fl p -option) -.Nm -reads the table -.Pa /etc/fstab -to determine which file systems to check, in what order. -Only partitions in fstab that are mounted ``rw,'' ``rq'' or ``ro'' -and that have non-zero pass number are checked. -File systems with pass number 1 (normally just the root file system) -are checked one at a time. -When pass 1 completes, all remaining file systems are checked, -running one process per disk drive. -By default, file systems which are already mounted read-write are not checked. -The disk drive containing each file system is inferred from the longest prefix -of the device name that ends in a digit; the remaining characters are assumed -to be the partition designator. -.Pp -The options are as follows: -.Bl -tag -width indent -.It Fl d -Debugging mode. -Just print the commands without executing them. -.It Fl f -Force checking of file systems, even when they are marked clean (for file -systems that support this), or when they are mounted read-write. -.It Fl l Ar maxparallel -Limit the number of parallel checks to the number specified in -the following argument. -By default, the limit is the number of disks, running one process per disk. -If a smaller limit is given, the disks are checked round-robin, -one file system at a time. -.It Fl n -Causes -.Nm -to assume no as the answer to all operator questions, except "CONTINUE?". -.It Fl P -Display a progress meter for each file system check. -This option also disables parallel checking. -Note that progress meters are not supported by all file system types. -.It Fl p -Enter preen mode. -In preen mode, -.Nm -will check all file systems listed in -.Pa /etc/fstab -according to their pass number, and will make minor repairs without -human intervention. -.It Fl q -Quiet mode, do not output any messages for clean filesystems. -.It Fl T Ar fstype:fsoptions -List of comma separated file system specific options for the specified -file system type, in the same format as -.Xr mount 8 . -.It Fl t Ar fstype -Invoke -.Nm -only for the comma separated list of file system types. -If the list starts with -.Dq no -then invoke -.Nm -for the file system types that are not specified in the list. -.It Fl v -Print the commands before executing them. -.It Fl x Ar mountpoint -Exclude the filesystem which has a -.Ar mountpoint -the same as in -.Pa /etc/fstab . -Used only in -.Dq preen -mode. -.It Fl y -Causes -.Nm -to assume yes -as the answer to all operator questions. -.El -.Sh FILES -.Bl -tag -width /etc/fstab -compact -.It Pa /etc/fstab -file system table -.El -.Sh EXIT STATUS -.Nm -exits with -.Dv 0 -on success. -Any major problems will cause -.Nm -to exit with the following non-zero -.Xr exit 3 -codes, so as to alert any invoking program or script that human -intervention is required. -.Bl -tag -width XXXX -.It Dv 1 -Usage problem. -.It Dv 2 -Unresolved errors while checking the filesystem. -Re-running -.Nm -on the filesystem(s) is required. -.It Dv 4 -The root filesystem was changed in the process of checking, and updating the -mount was unsuccessful. -A reboot (without sync) is required. -.It Dv 8 -The filesystem check has failed, and a subsequent check is required -that will require human intervention. -.It Dv 12 -.Nm -exited because of the result of a signal (usually -.Dv SIGINT -or -.Dv SIGQUIT -from the terminal). -.El -.Sh SEE ALSO -.Xr fstab 5 , -.Xr fsck_ext2fs 8 , -.Xr fsck_ffs 8 , -.Xr fsck_lfs 8 , -.Xr fsck_msdos 8 , -.Xr mount 8 diff --git a/sbin/fsck/fsck.c b/sbin/fsck/fsck.c deleted file mode 100644 index 3c40371ad..000000000 --- a/sbin/fsck/fsck.c +++ /dev/null @@ -1,614 +0,0 @@ -/* $NetBSD: fsck.c,v 1.52 2014/10/25 22:00:19 mlelstv Exp $ */ - -/* - * Copyright (c) 1996 Christos Zoulas. All rights reserved. - * Copyright (c) 1980, 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * From: @(#)mount.c 8.19 (Berkeley) 4/19/94 - * From: NetBSD: mount.c,v 1.24 1995/11/18 03:34:29 cgd Exp - * - */ - -#include -#ifndef lint -__RCSID("$NetBSD: fsck.c,v 1.52 2014/10/25 22:00:19 mlelstv Exp $"); -#endif /* not lint */ - -#include -#include -#include -#include -#define FSTYPENAMES -#define FSCKNAMES -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pathnames.h" -#include "fsutil.h" -#include "exitvalues.h" - -static enum { IN_LIST, NOT_IN_LIST } which = NOT_IN_LIST; - -TAILQ_HEAD(fstypelist, entry) opthead, selhead, omhead; - -struct entry { - char *type; - char *options; - TAILQ_ENTRY(entry) entries; -}; - -static int maxrun = 0; -static char *options = NULL; -static int flags = 0; - -static int checkfs(const char *, const char *, const char *, void *, pid_t *); -static int selected(const char *); -static int omitted(const char *); -static void addoption(char *); -static const char *getoptions(const char *); -static void addentry(struct fstypelist *, const char *, const char *); -static void maketypelist(char *); -static void catopt(char **, const char *); -static void mangle(char *, int *, const char ** volatile *, int *); -static const char *getfslab(const char *); -__dead static void usage(void); -static void *isok(struct fstab *); - -int -main(int argc, char *argv[]) -{ - struct fstab *fs; - int i, rval; - const char *vfstype = NULL; - char globopt[3]; - int ret = FSCK_EXIT_OK; - char buf[MAXPATHLEN]; - - globopt[0] = '-'; - globopt[2] = '\0'; - - TAILQ_INIT(&selhead); - TAILQ_INIT(&opthead); - TAILQ_INIT(&omhead); - - while ((i = getopt(argc, argv, "dfl:nPpqT:t:vx:y")) != -1) { - switch (i) { - case 'd': - flags |= CHECK_DEBUG; - continue; - - case 'f': - flags |= CHECK_FORCE; - break; - - case 'n': - flags |= CHECK_NOFIX; - break; - - case 'p': - flags |= CHECK_PREEN; - break; - - case 'P': - flags |= CHECK_PROGRESS; - break; - - case 'q': - break; - - case 'l': - maxrun = atoi(optarg); - continue; - - case 'T': - if (*optarg) - addoption(optarg); - continue; - - case 't': - if (TAILQ_FIRST(&selhead) != NULL) - errx(1, "only one -t option may be specified."); - - maketypelist(optarg); - vfstype = optarg; - continue; - - case 'v': - flags |= CHECK_VERBOSE; - continue; - - case 'x': - addentry(&omhead, optarg, ""); - continue; - - case 'y': - break; - - case '?': - default: - usage(); - /* NOTREACHED */ - } - - /* Pass option to fsck_xxxfs */ - globopt[1] = i; - catopt(&options, globopt); - } - - /* Don't do progress meters if we're debugging. */ - if (flags & CHECK_DEBUG) - flags &= ~CHECK_PROGRESS; - - /* - * If progress meters are being used, force max parallel to 1 - * so the progress meter outputs don't interfere with one another. - */ - if (flags & CHECK_PROGRESS) - maxrun = 1; - -#if defined(__minix) - /* parallel checking heuristic doesn't work for minix currently */ - maxrun = 1; -#endif /* !defined(__minix) */ - argc -= optind; - argv += optind; - - if (argc == 0) - return checkfstab(flags, maxrun, isok, checkfs); - -#define BADTYPE(type) \ - (strcmp(type, FSTAB_RO) && \ - strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ)) - - - for (; argc--; argv++) { - const char *spec, *spec2, *mntpt, *type, *cp; - char device[MAXPATHLEN]; - - spec = mntpt = *argv; - spec2 = getfsspecname(buf, sizeof(buf), spec); - if (spec2 == NULL) - spec2 = spec; - - cp = strrchr(spec2, '/'); - if (cp == 0) { - (void)snprintf(device, sizeof(device), "%s%s", - _PATH_DEV, spec2); - spec2 = device; - } - - fs = getfsfile(spec); - if (fs == NULL) - fs = getfsspec(spec); - if (fs == NULL && spec != spec2) { - fs = getfsspec(spec2); - spec = spec2; - } - - if (fs) { - spec = getfsspecname(buf, sizeof(buf), fs->fs_spec); - if (spec == NULL) - err(FSCK_EXIT_CHECK_FAILED, "%s", buf); - type = fs->fs_vfstype; - if (BADTYPE(fs->fs_type)) - errx(FSCK_EXIT_CHECK_FAILED, - "%s has unknown file system type.", - spec); - } else { - if (vfstype == NULL) - vfstype = getfslab(spec); - type = vfstype; - } - - rval = checkfs(type, blockcheck(spec), *argv, NULL, NULL); - if (rval > ret) - ret = rval; - } - - return ret; -} - - -static void * -isok(struct fstab *fs) -{ - - if (fs->fs_passno == 0) - return NULL; - - if (BADTYPE(fs->fs_type)) - return NULL; - - if (!selected(fs->fs_vfstype)) - return NULL; - - if (omitted(fs->fs_file)) - return NULL; - - return fs; -} - - -static int -checkfs(const char *vfst, const char *spec, const char *mntpt, void *auxarg, - pid_t *pidp) -{ - /* List of directories containing fsck_xxx subcommands. */ - static const char *edirs[] = { -#ifdef RESCUEDIR - RESCUEDIR, -#endif - _PATH_SBIN, - _PATH_USRSBIN, -#if defined(__minix) - "/usr/pkg/sbin/", -#endif /* defined(__minix) */ - NULL - }; - const char ** volatile argv, **edir; - const char * volatile vfstype = vfst; - pid_t pid; - int argc, i, status, maxargc; - char *optb; - char *volatile optbuf; - char execname[MAXPATHLEN + 1], execbase[MAXPATHLEN]; - const char *extra = getoptions(vfstype); - - if (!strcmp(vfstype, "ufs")) - vfstype = MOUNT_UFS; - - optb = NULL; - if (options) - catopt(&optb, options); - if (extra) - catopt(&optb, extra); - optbuf = optb; - - maxargc = 64; - argv = emalloc(sizeof(char *) * maxargc); - - (void) snprintf(execbase, sizeof(execbase), "fsck_%s", vfstype); - argc = 0; - argv[argc++] = execbase; - if (optbuf) - mangle(optbuf, &argc, &argv, &maxargc); - argv[argc++] = spec; - argv[argc] = NULL; - - if (flags & (CHECK_DEBUG|CHECK_VERBOSE)) { - (void)printf("start %s %swait", mntpt, - pidp ? "no" : ""); - for (i = 0; i < argc; i++) - (void)printf(" %s", argv[i]); - (void)printf("\n"); - } - - switch (pid = vfork()) { - case -1: /* Error. */ - warn("vfork"); - if (optbuf) - free(optbuf); - free(argv); - return FSCK_EXIT_CHECK_FAILED; - - case 0: /* Child. */ - if ((flags & CHECK_FORCE) == 0) { - struct statvfs sfs; - - /* - * if mntpt is a mountpoint of a mounted file - * system and it's mounted read-write, skip it - * unless -f is given. - */ - if ((statvfs(mntpt, &sfs) == 0) && - (strcmp(mntpt, sfs.f_mntonname) == 0) && - ((sfs.f_flag & MNT_RDONLY) == 0)) { - printf( - "%s: file system is mounted read-write on %s; not checking\n", - spec, mntpt); - if ((flags & CHECK_PREEN) && auxarg != NULL) - _exit(FSCK_EXIT_OK); /* fsck -p */ - else - _exit(FSCK_EXIT_CHECK_FAILED); /* fsck [[-p] ...] */ - } - } - - if (flags & CHECK_DEBUG) - _exit(FSCK_EXIT_OK); - - /* Go find an executable. */ - edir = edirs; - do { - (void)snprintf(execname, - sizeof(execname), "%s/%s", *edir, execbase); - execv(execname, (char * const *)__UNCONST(argv)); - if (errno != ENOENT) { - if (spec) - warn("exec %s for %s", execname, spec); - else - warn("exec %s", execname); - } - } while (*++edir != NULL); - - if (errno == ENOENT) { - if (spec) - warn("exec %s for %s", execname, spec); - else - warn("exec %s", execname); - } - _exit(FSCK_EXIT_CHECK_FAILED); - /* NOTREACHED */ - - default: /* Parent. */ - if (optbuf) - free(optbuf); - free(argv); - - if (pidp) { - *pidp = pid; - return FSCK_EXIT_OK; - } - - if (waitpid(pid, &status, 0) < 0) { - warn("waitpid"); - return FSCK_EXIT_CHECK_FAILED; - } - - if (WIFEXITED(status)) { - if (WEXITSTATUS(status) != 0) - return WEXITSTATUS(status); - } - else if (WIFSIGNALED(status)) { - warnx("%s: %s", spec, strsignal(WTERMSIG(status))); - return FSCK_EXIT_CHECK_FAILED; - } - break; - } - - return FSCK_EXIT_OK; -} - - -static int -selected(const char *type) -{ - struct entry *e; - - /* If no type specified, it's always selected. */ - TAILQ_FOREACH(e, &selhead, entries) - if (!strcmp(e->type, type)) - return which == IN_LIST ? 1 : 0; - - return which == IN_LIST ? 0 : 1; -} - - -static int -omitted(const char *mountedon) -{ - struct entry *e; - - /* If no type specified, it's always selected. */ - TAILQ_FOREACH(e, &omhead, entries) - if (!strcmp(e->type, mountedon)) - return 1; - - return 0; -} - - -static const char * -getoptions(const char *type) -{ - struct entry *e; - - TAILQ_FOREACH(e, &opthead, entries) - if (!strcmp(e->type, type)) - return e->options; - return ""; -} - - -static void -addoption(char *optstr) -{ - char *newoptions; - struct entry *e; - - if ((newoptions = strchr(optstr, ':')) == NULL) - errx(1, "Invalid option string"); - - *newoptions++ = '\0'; - - TAILQ_FOREACH(e, &opthead, entries) - if (!strcmp(e->type, optstr)) { - catopt(&e->options, newoptions); - return; - } - addentry(&opthead, optstr, newoptions); -} - - -static void -addentry(struct fstypelist *list, const char *type, const char *opts) -{ - struct entry *e; - - e = emalloc(sizeof(struct entry)); - e->type = estrdup(type); - e->options = estrdup(opts); - TAILQ_INSERT_TAIL(list, e, entries); -} - - -static void -maketypelist(char *fslist) -{ - char *ptr; - - if ((fslist == NULL) || (fslist[0] == '\0')) - errx(1, "empty type list"); - - if (fslist[0] == 'n' && fslist[1] == 'o') { - fslist += 2; - which = NOT_IN_LIST; - } - else - which = IN_LIST; - - while ((ptr = strsep(&fslist, ",")) != NULL) - addentry(&selhead, ptr, ""); - -} - - -static void -catopt(char **sp, const char *o) -{ - char *s; - size_t i, j; - - s = *sp; - if (s) { - i = strlen(s); - j = i + 1 + strlen(o) + 1; - s = erealloc(s, j); - (void)snprintf(s + i, j, ",%s", o); - } else - s = estrdup(o); - *sp = s; -} - - -static void -mangle(char *opts, int *argcp, const char ** volatile *argvp, int *maxargcp) -{ - char *p, *s; - int argc, maxargc; - const char **argv; - - argc = *argcp; - argv = *argvp; - maxargc = *maxargcp; - - for (s = opts; (p = strsep(&s, ",")) != NULL;) { - /* Always leave space for one more argument and the NULL. */ - if (argc >= maxargc - 3) { - maxargc <<= 1; - argv = erealloc(argv, maxargc * sizeof(char *)); - } - if (*p != '\0') { - if (*p == '-') { - argv[argc++] = p; - p = strchr(p, '='); - if (p) { - *p = '\0'; - argv[argc++] = p+1; - } - } else { - argv[argc++] = "-o"; - argv[argc++] = p; - } - } - } - - *argcp = argc; - *argvp = argv; - *maxargcp = maxargc; -} - -static const char * -getfslab(const char *str) -{ -#if defined(__minix) - errx(1, "cannot determine vfstype under minix"); -#else - static struct dkwedge_info dkw; - struct disklabel dl; - int fd; - char p; - const char *vfstype; - u_char t; - - /* deduce the file system type from the disk label */ - if ((fd = open(str, O_RDONLY)) == -1) - err(1, "cannot open `%s'", str); - - /* First check to see if it's a wedge. */ - if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == 0) { - /* Yup, this is easy. */ - (void) close(fd); - return (dkw.dkw_ptype); - } - - if (ioctl(fd, DIOCGDINFO, &dl) == -1) - err(1, "cannot get disklabel for `%s'", str); - - (void) close(fd); - - p = str[strlen(str) - 1]; - - if ((p - 'a') >= dl.d_npartitions) - errx(1, "partition `%s' is not defined on disk", str); - - if ((t = dl.d_partitions[p - 'a'].p_fstype) >= FSMAXTYPES) - errx(1, "partition `%s' is not of a legal vfstype", - str); - - if ((vfstype = fscknames[t]) == NULL) - errx(1, "vfstype `%s' on partition `%s' is not supported", - fstypenames[t], str); - - return vfstype; -#endif /* defined(__minix) */ -} - - -static void -usage(void) -{ - static const char common[] = - "[-dfnPpqvy] [-x excludemount] [-l maxparallel] [-T fstype:fsoptions]\n\t\t[-t fstype]"; - - (void)fprintf(stderr, "usage: %s %s [special|node]...\n", - getprogname(), common); - exit(FSCK_EXIT_USAGE); -} diff --git a/sbin/fsck/fsutil.c b/sbin/fsck/fsutil.c deleted file mode 100644 index 0752705e1..000000000 --- a/sbin/fsck/fsutil.c +++ /dev/null @@ -1,306 +0,0 @@ -/* $NetBSD: fsutil.c,v 1.26 2015/06/21 04:01:40 dholland Exp $ */ - -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: fsutil.c,v 1.26 2015/06/21 04:01:40 dholland Exp $"); -#endif /* not lint */ - -/* - * used by sbin/fsck - * used by sbin/fsck_ext2fs - * used by sbin/fsck_ffs - * used by sbin/fsck_lfs - * used by sbin/fsck_msdos - * used by sbin/fsck_v7fs - * used by sbin/fsdb - * used by usr.sbin/quotacheck - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "fsutil.h" -#include "exitvalues.h" - -volatile sig_atomic_t returntosingle; - -static const char *dev = NULL; -static int hot = 0; -static int preen = 0; -int quiet; -#define F_ERROR 0x80000000 - -void -setcdevname(const char *cd, int pr) -{ - - dev = cd; - preen = pr; -} - -const char * -cdevname(void) -{ - - return dev; -} - -int -hotroot(void) -{ - - return hot; -} - -/*VARARGS*/ -void -errexit(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - (void) vfprintf(stderr, fmt, ap); - va_end(ap); - (void)fprintf(stderr, "\n"); - exit(FSCK_EXIT_CHECK_FAILED); -} - -void -vmsg(int fatal, const char *fmt, va_list ap) -{ - int serr = fatal & F_ERROR; - int serrno = errno; - fatal &= ~F_ERROR; - - if (!fatal && preen) - (void)printf("%s: ", dev); - if (quiet && !preen) { - (void)printf("** %s (vmsg)\n", dev); - quiet = 0; - } - - (void) vprintf(fmt, ap); - if (serr) - printf(" (%s)", strerror(serrno)); - - if (fatal && preen) - (void) printf("\n"); - - if (fatal && preen) { - (void) printf( - "%s: UNEXPECTED INCONSISTENCY; RUN %s MANUALLY.\n", - dev, getprogname()); - exit(FSCK_EXIT_CHECK_FAILED); - } -} - -/*VARARGS*/ -void -pfatal(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vmsg(1, fmt, ap); - va_end(ap); -} - -/*VARARGS*/ -void -pwarn(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vmsg(0, fmt, ap); - va_end(ap); -} - -void -perr(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vmsg(1 | F_ERROR, fmt, ap); - va_end(ap); -} - -void -panic(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vmsg(1, fmt, ap); - va_end(ap); - exit(FSCK_EXIT_CHECK_FAILED); -} - -const char * -blockcheck(const char *origname) -{ -#if defined(__minix) - return origname; -#else - struct stat stslash, stblock, stchar; - const char *newname, *raw, *cooked; - struct fstab *fsp; - int retried = 0; - ssize_t len; - char cbuf[MAXPATHLEN]; - static char buf[MAXPATHLEN]; - - hot = 0; - if (stat("/", &stslash) < 0) { - perr("Can't stat `/'"); - return (origname); - } - len = readlink(origname, cbuf, sizeof(cbuf)-1); - if (len == -1) { - newname = origname; - } else { - cbuf[len] = '\0'; - newname = cbuf; - } -retry: - if (stat(newname, &stblock) < 0) { - perr("Can't stat `%s'", newname); - return origname; - } - if (S_ISBLK(stblock.st_mode)) { - if (stslash.st_dev == stblock.st_rdev) - hot++; - raw = getdiskrawname(buf, sizeof(buf), newname); - if (raw == NULL) { - perr("Can't convert to raw `%s'", newname); - return origname; - } - if (stat(raw, &stchar) < 0) { - perr("Can't stat `%s'", raw); - return origname; - } - if (S_ISCHR(stchar.st_mode)) { - return raw; - } else { - perr("%s is not a character device\n", raw); - return origname; - } - } else if (S_ISCHR(stblock.st_mode) && !retried) { - cooked = getdiskcookedname(cbuf, sizeof(cbuf), newname); - if (cooked == NULL) { - perr("Can't convert to cooked `%s'", newname); - return origname; - } else - newname = cooked; - retried++; - goto retry; - } else if ((fsp = getfsfile(newname)) != 0 && !retried) { - newname = getfsspecname(cbuf, sizeof(cbuf), fsp->fs_spec); - if (newname == NULL) - perr("%s", buf); - retried++; - goto retry; - } - /* - * Not a block or character device, just return name and - * let the user decide whether to use it. - */ - return origname; -#endif /* defined(__minix) */ -} - -const char * -print_mtime(time_t t) -{ - static char b[128]; - char *p = ctime(&t); - if (p != NULL) - (void)snprintf(b, sizeof(b), "%12.12s %4.4s ", &p[4], &p[20]); - else - (void)snprintf(b, sizeof(b), "%lld ", (long long)t); - return b; -} - - -void -catch(int n) -{ - if (ckfinish) (*ckfinish)(0); - _exit(FSCK_EXIT_SIGNALLED); -} - -/* - * When preening, allow a single quit to signal - * a special exit after filesystem checks complete - * so that reboot sequence may be interrupted. - */ -void -catchquit(int n) -{ - static const char msg[] = - "returning to single-user after filesystem check\n"; - int serrno = errno; - - (void)write(STDOUT_FILENO, msg, sizeof(msg) - 1); - returntosingle = 1; - (void)signal(SIGQUIT, SIG_DFL); - errno = serrno; -} - -/* - * Ignore a single quit signal; wait and flush just in case. - * Used by child processes in preen. - */ -void -voidquit(int n) -{ - int serrno = errno; - - sleep(1); - (void)signal(SIGQUIT, SIG_IGN); - (void)signal(SIGQUIT, SIG_DFL); - errno = serrno; -} diff --git a/sbin/fsck/fsutil.h b/sbin/fsck/fsutil.h deleted file mode 100644 index e9cd0bcd4..000000000 --- a/sbin/fsck/fsutil.h +++ /dev/null @@ -1,57 +0,0 @@ -/* $NetBSD: fsutil.h,v 1.20 2015/06/21 03:58:36 dholland Exp $ */ - -/* - * Copyright (c) 1996 Christos Zoulas. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -void errexit(const char *, ...) __printflike(1, 2) __dead; -void pfatal(const char *, ...) __printflike(1, 2); -void pwarn(const char *, ...) __printflike(1, 2); -void perr(const char *, ...) __printflike(1, 2); -void panic(const char *, ...) __printflike(1, 2) __dead; -void vmsg(int, const char *, va_list) __printflike(2, 0); -const char *blockcheck(const char *); -const char *cdevname(void); -void setcdevname(const char *, int); -int hotroot(void); -const char *print_mtime(time_t); - -#define CHECK_PREEN 1 -#define CHECK_VERBOSE 2 -#define CHECK_DEBUG 4 -#define CHECK_FORCE 8 -#define CHECK_PROGRESS 16 -#define CHECK_NOFIX 32 - -struct fstab; -int checkfstab(int, int, void *(*)(struct fstab *), - int (*) (const char *, const char *, const char *, void *, pid_t *)); - -void (*ckfinish)(int); -extern volatile sig_atomic_t returntosingle; -void catch(int) __dead; -void catchquit(int); -void voidquit(int); diff --git a/sbin/fsck/partutil.c b/sbin/fsck/partutil.c deleted file mode 100644 index 08c354eec..000000000 --- a/sbin/fsck/partutil.c +++ /dev/null @@ -1,205 +0,0 @@ -/* $NetBSD: partutil.c,v 1.15 2015/06/03 17:53:23 martin Exp $ */ - -/*- - * Copyright (c) 2006 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__RCSID("$NetBSD: partutil.c,v 1.15 2015/06/03 17:53:23 martin Exp $"); - -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "partutil.h" - -/* - * Convert disklabel geometry info to disk_geom. - */ -static void -label2geom(struct disk_geom *geo, const struct disklabel *lp) -{ - geo->dg_secperunit = lp->d_secperunit; - geo->dg_secsize = lp->d_secsize; - geo->dg_nsectors = lp->d_nsectors; - geo->dg_ntracks = lp->d_ntracks; - geo->dg_ncylinders = lp->d_ncylinders; - geo->dg_secpercyl = lp->d_secpercyl; - geo->dg_pcylinders = lp->d_ncylinders; - geo->dg_sparespertrack = lp->d_sparespertrack; - geo->dg_sparespercyl = lp->d_sparespercyl; - geo->dg_acylinders = lp->d_acylinders; -} - -/* - * Set what we need to know about disk geometry. - */ -static void -dict2geom(struct disk_geom *geo, prop_dictionary_t dict) -{ - (void)memset(geo, 0, sizeof(struct disk_geom)); - prop_dictionary_get_int64(dict, "sectors-per-unit", - &geo->dg_secperunit); - prop_dictionary_get_uint32(dict, "sector-size", &geo->dg_secsize); - prop_dictionary_get_uint32(dict, "sectors-per-track", - &geo->dg_nsectors); - prop_dictionary_get_uint32(dict, "tracks-per-cylinder", - &geo->dg_ntracks); - prop_dictionary_get_uint32(dict, "cylinders-per-unit", - &geo->dg_ncylinders); -} - - -int -getdiskinfo(const char *s, int fd, const char *dt, struct disk_geom *geo, - struct dkwedge_info *dkw) -{ - struct disklabel lab; - struct disklabel *lp = &lab; - prop_dictionary_t disk_dict, geom_dict; -#if !defined(__minix) - struct stat sb; - const struct partition *pp; - int ptn, error; -#endif /* defined(__minix) */ - - if (dt) { -#if defined(__minix) - errx(1, "minix doesn't know about disk types (%s)", dt); -#else - lp = getdiskbyname(dt); - if (lp == NULL) - errx(1, "unknown disk type `%s'", dt); -#endif /* defined(__minix) */ - } - - /* Get disk description dictionary */ -#if !defined(__minix) - error = prop_dictionary_recv_ioctl(fd, DIOCGDISKINFO, &disk_dict); - - /* fail quickly if the device does not exist at all */ - if (error == ENXIO) - return -1; - - if (error) { -#else - if (1) { -#endif /* !defined(__minix) */ - /* - * Ask for disklabel if DIOCGDISKINFO failed. This is - * compatibility call and can be removed when all devices - * will support DIOCGDISKINFO. - * cgd, ccd pseudo disk drives doesn't support DIOCGDDISKINFO - */ - if (ioctl(fd, DIOCGDINFO, lp) == -1) { - if (errno != ENXIO) - warn("DIOCGDINFO on %s failed", s); - return -1; - } - label2geom(geo, lp); - } else { - geom_dict = prop_dictionary_get(disk_dict, "geometry"); - dict2geom(geo, geom_dict); - } - - if (dkw == NULL) - return 0; - - /* Get info about partition/wedge */ - if (ioctl(fd, DIOCGWEDGEINFO, dkw) != -1) { - /* DIOCGWEDGEINFO didn't fail, we're done */ - return 0; - } - - if (ioctl(fd, DIOCGDINFO, lp) == -1) { - err(1, "Please implement DIOCGWEDGEINFO or " - "DIOCGDINFO for disk device %s", s); - } - -#if !defined(__minix) - /* DIOCGDINFO didn't fail */ - (void)memset(dkw, 0, sizeof(*dkw)); - - if (stat(s, &sb) == -1) - return 0; - - ptn = strchr(s, '\0')[-1] - 'a'; - if ((unsigned)ptn >= lp->d_npartitions || - (devminor_t)ptn != DISKPART(sb.st_rdev)) - return 0; - - pp = &lp->d_partitions[ptn]; - if (ptn != getrawpartition()) { - dkw->dkw_offset = pp->p_offset; - dkw->dkw_size = pp->p_size; - } else { - dkw->dkw_offset = 0; - dkw->dkw_size = geo->dg_secperunit; - } - dkw->dkw_parent[0] = '*'; - strlcpy(dkw->dkw_ptype, getfstypename(pp->p_fstype), - sizeof(dkw->dkw_ptype)); -#endif /* !defined(__minix) */ - - return 0; -} - -int -getdisksize(const char *name, u_int *secsize, off_t *mediasize) -{ - char buf[MAXPATHLEN]; - struct disk_geom geo; - int fd, error; - - if ((fd = opendisk(name, O_RDONLY, buf, sizeof(buf), 0)) == -1) - return -1; - - error = getdiskinfo(name, fd, NULL, &geo, NULL); - close(fd); - if (error) - return error; - - *secsize = geo.dg_secsize; - *mediasize = geo.dg_secsize * geo.dg_secperunit; - return 0; -} diff --git a/sbin/fsck/partutil.h b/sbin/fsck/partutil.h deleted file mode 100644 index c812a0167..000000000 --- a/sbin/fsck/partutil.h +++ /dev/null @@ -1,42 +0,0 @@ -/* $NetBSD: partutil.h,v 1.3 2014/12/29 16:27:43 christos Exp $ */ - -/*- - * Copyright (c) 2006 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef _PARTUTIL_H_ -#define _PARTUTIL_H_ - -__BEGIN_DECLS -struct dkwedge_info; -struct disk_geom; -int getdiskinfo(const char *, int, const char *, - struct disk_geom *, struct dkwedge_info *); -int getdisksize(const char *, u_int *, off_t *); -__END_DECLS - -#endif /* _PARTUTIL_H_ */ diff --git a/sbin/fsck/pathnames.h b/sbin/fsck/pathnames.h deleted file mode 100644 index a7847467e..000000000 --- a/sbin/fsck/pathnames.h +++ /dev/null @@ -1,28 +0,0 @@ -/* $NetBSD: pathnames.h,v 1.2 2009/10/21 01:07:46 snj Exp $ */ - -/* - * Copyright (c) 1996 Christos Zoulas. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _PATH_SBIN "/sbin" -#define _PATH_USRSBIN "/usr/sbin" diff --git a/sbin/fsck/preen.c b/sbin/fsck/preen.c deleted file mode 100644 index 104eca800..000000000 --- a/sbin/fsck/preen.c +++ /dev/null @@ -1,374 +0,0 @@ -/* $NetBSD: preen.c,v 1.32 2015/06/21 04:01:40 dholland Exp $ */ - -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95"; -#else -__RCSID("$NetBSD: preen.c,v 1.32 2015/06/21 04:01:40 dholland Exp $"); -#endif -#endif /* not lint */ - -/* - * used by sbin/fsck - * used by usr.sbin/quotacheck - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fsutil.h" -#include "exitvalues.h" - -struct partentry { - TAILQ_ENTRY(partentry) p_entries; - char *p_devname; /* device name */ - char *p_mntpt; /* mount point */ - char *p_type; /* file system type */ - void *p_auxarg; /* auxiliary argument */ -}; - -TAILQ_HEAD(part, partentry) badh; - -struct diskentry { - TAILQ_ENTRY(diskentry) d_entries; - char *d_name; /* disk base name */ - TAILQ_HEAD(prt, partentry) d_part; /* list of partitions on disk */ - int d_pid; /* 0 or pid of fsck proc */ -}; - -TAILQ_HEAD(diskinfo, diskentry) diskh; - -static int nrun = 0, ndisks = 0; - -static struct diskentry *finddisk(const char *); -static void addpart(const char *, const char *, const char *, void *); -static int startdisk(struct diskentry *, - int (*)(const char *, const char *, const char *, void *, pid_t *)); -static void printpart(void); - -int -checkfstab(int flags, int maxrun, void *(*docheck)(struct fstab *), - int (*checkit)(const char *, const char *, const char *, void *, pid_t *)) -{ - struct fstab *fs; - struct diskentry *d, *nextdisk; - struct partentry *p; - int ret, pid, retcode, passno, sumstatus, status; - void *auxarg; - const char *name; - int error = FSCK_EXIT_OK; - - TAILQ_INIT(&badh); - TAILQ_INIT(&diskh); - - sumstatus = FSCK_EXIT_OK; - - for (passno = 1; passno <= 2; passno++) { - if (setfsent() == 0) { - warnx("Can't open checklist file: %s", _PATH_FSTAB); - return FSCK_EXIT_CHECK_FAILED; - } - while ((fs = getfsent()) != 0) { - char buf[MAXPATHLEN]; - const char *fsspec; - if ((auxarg = (*docheck)(fs)) == NULL) - continue; - fsspec = getfsspecname(buf, sizeof(buf), fs->fs_spec); - if (fsspec == NULL) { - warn("%s", buf); - return FSCK_EXIT_CHECK_FAILED; - } - name = blockcheck(fsspec); - if (flags & CHECK_DEBUG) - printf("pass %d, name %s\n", passno, name); - - if ((flags & CHECK_PREEN) == 0 || - (passno == 1 && fs->fs_passno == 1)) { - if (name == NULL) { - if (flags & CHECK_PREEN) - return FSCK_EXIT_CHECK_FAILED; - else - continue; - } - sumstatus = (*checkit)(fs->fs_vfstype, - name, fs->fs_file, auxarg, NULL); - - if (sumstatus) { - if ((flags & CHECK_NOFIX) == 0) - return sumstatus; - else if (error < sumstatus) - error = sumstatus; - } - } else if (passno == 2 && fs->fs_passno > 1) { - if (name == NULL) { - (void) fprintf(stderr, - "BAD DISK NAME %s\n", fsspec); - sumstatus = FSCK_EXIT_CHECK_FAILED; - continue; - } - addpart(fs->fs_vfstype, name, fs->fs_file, - auxarg); - } - } - if ((flags & CHECK_PREEN) == 0) - return error; - } - - if (flags & CHECK_DEBUG) - printpart(); - - if (flags & CHECK_PREEN) { - if (maxrun == 0) - maxrun = ndisks; - if (maxrun > ndisks) - maxrun = ndisks; - nextdisk = TAILQ_FIRST(&diskh); - for (passno = 0; passno < maxrun; ++passno) { - if ((ret = startdisk(nextdisk, checkit)) != 0) { - if ((flags & CHECK_NOFIX) == 0) - return ret; - else if (error < ret) - error = ret; - } - nextdisk = TAILQ_NEXT(nextdisk, d_entries); - } - - while ((pid = wait(&status)) != -1) { - TAILQ_FOREACH(d, &diskh, d_entries) - if (d->d_pid == pid) - break; - - if (d == NULL) { - warnx("Unknown pid %d", pid); - continue; - } - - - if (WIFEXITED(status)) - retcode = WEXITSTATUS(status); - else - retcode = 0; - - p = TAILQ_FIRST(&d->d_part); - - if (flags & (CHECK_DEBUG|CHECK_VERBOSE)) - (void) printf("done %s: %s (%s) = 0x%x\n", - p->p_type, p->p_devname, p->p_mntpt, - status); - - if (WIFSIGNALED(status)) { - (void) fprintf(stderr, - "%s: %s (%s): EXITED WITH SIGNAL %d\n", - p->p_type, p->p_devname, p->p_mntpt, - WTERMSIG(status)); - retcode = FSCK_EXIT_SIGNALLED; - } - - TAILQ_REMOVE(&d->d_part, p, p_entries); - - if (retcode != 0) { - TAILQ_INSERT_TAIL(&badh, p, p_entries); - sumstatus |= retcode; - } else { - free(p->p_type); - free(p->p_devname); - free(p); - } - d->d_pid = 0; - nrun--; - - if (TAILQ_FIRST(&d->d_part) == NULL) - ndisks--; - - if (nextdisk == NULL) { - if (TAILQ_FIRST(&d->d_part) != NULL) { - if ((ret = startdisk(d, checkit)) != 0) - { - if ((flags & CHECK_NOFIX) == 0) - return ret; - else if (error < ret) - error = ret; - } - } - } else if (nrun < maxrun && nrun < ndisks) { - for ( ;; ) { - nextdisk = TAILQ_NEXT(nextdisk, - d_entries); - if (nextdisk == NULL) - nextdisk = TAILQ_FIRST(&diskh); - if (TAILQ_FIRST(&nextdisk->d_part) - != NULL && nextdisk->d_pid == 0) - break; - } - if ((ret = startdisk(nextdisk, checkit)) != 0) - { - if ((flags & CHECK_NOFIX) == 0) - return ret; - else if (error < ret) - error = ret; - } - } - } - } - if (sumstatus) { - p = TAILQ_FIRST(&badh); - if (p == NULL) - return sumstatus; - - (void) fprintf(stderr, - "THE FOLLOWING FILE SYSTEM%s HAD AN %s\n\t", - TAILQ_NEXT(p, p_entries) ? "S" : "", - "UNEXPECTED INCONSISTENCY:"); - - TAILQ_FOREACH(p, &badh, p_entries) - (void) fprintf(stderr, - "%s: %s (%s)%s", p->p_type, p->p_devname, - p->p_mntpt, TAILQ_NEXT(p, p_entries) ? ", " : "\n"); - - return sumstatus; - } - (void) endfsent(); - return error; -} - - -static struct diskentry * -finddisk(const char *name) -{ - const char *p; - size_t len, dlen; - struct diskentry *d; -#if !defined(__minix) - char buf[MAXPATHLEN]; - struct dkwedge_info dkw; - int fd; - - if ((fd = opendisk(name, O_RDONLY, buf, sizeof(buf), 0)) != -1) { - if (ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1) - name = dkw.dkw_parent; - (void)close(fd); - } -#endif /* !defined(__minix) */ - - for (dlen = len = strlen(name), p = name + len - 1; p >= name; --p) - if (isdigit((unsigned char)*p)) { - len = p - name + 1; - break; - } - if (p < name) - len = dlen; - - TAILQ_FOREACH(d, &diskh, d_entries) - if (strncmp(d->d_name, name, len) == 0 && d->d_name[len] == 0) - return d; - - d = emalloc(sizeof(*d)); - d->d_name = estrdup(name); - d->d_name[len] = '\0'; - TAILQ_INIT(&d->d_part); - d->d_pid = 0; - - TAILQ_INSERT_TAIL(&diskh, d, d_entries); - ndisks++; - - return d; -} - - -static void -printpart(void) -{ - struct diskentry *d; - struct partentry *p; - - TAILQ_FOREACH(d, &diskh, d_entries) { - (void) printf("disk %s:", d->d_name); - TAILQ_FOREACH(p, &d->d_part, p_entries) - (void) printf(" %s", p->p_devname); - (void) printf("\n"); - } -} - - -static void -addpart(const char *type, const char *dev, const char *mntpt, void *auxarg) -{ - struct diskentry *d = finddisk(dev); - struct partentry *p; - - TAILQ_FOREACH(p, &d->d_part, p_entries) - if (strcmp(p->p_devname, dev) == 0) { - warnx("%s in fstab more than once!", dev); - return; - } - - p = emalloc(sizeof(*p)); - p->p_devname = estrdup(dev); - p->p_mntpt = estrdup(mntpt); - p->p_type = estrdup(type); - p->p_auxarg = auxarg; - - TAILQ_INSERT_TAIL(&d->d_part, p, p_entries); -} - - -static int -startdisk(struct diskentry *d, - int (*checkit)(const char *, const char *, const char *, void *, pid_t *)) -{ - struct partentry *p = TAILQ_FIRST(&d->d_part); - int rv; - - while ((rv = (*checkit)(p->p_type, p->p_devname, p->p_mntpt, - p->p_auxarg, &d->d_pid)) != 0 && nrun > 0) - sleep(10); - - if (rv == 0) - nrun++; - - return rv; -} diff --git a/sbin/fsck/progress.c b/sbin/fsck/progress.c deleted file mode 100644 index 9c137a06d..000000000 --- a/sbin/fsck/progress.c +++ /dev/null @@ -1,168 +0,0 @@ -/* $NetBSD: progress.c,v 1.5 2009/04/11 06:48:36 lukem Exp $ */ - -/*- - * Copyright (c) 1997-2004 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Luke Mewburn; by Chris Gilbert; and by Jason R. Thorpe. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SMALL -#include -__RCSID("$NetBSD: progress.c,v 1.5 2009/04/11 06:48:36 lukem Exp $"); - -/* - * File system independent fsck progress bar routines. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "progress.h" - -static size_t ttywidth = 80; - -static int progress_onoff; -static int progress_lowlim; -static int progress_highlim; - -#define BUFLEFT (sizeof(buf) - len) - -void -progress_switch(int onoff) -{ - progress_onoff = onoff; -} - -void -progress_init(void) -{ - progress_setrange(0, 100); -} - -/* Set both low and high limit. */ -void -progress_setrange(int lowlim, int highlim) -{ - progress_lowlim = lowlim; - progress_highlim = highlim; -} - -/* Previous high limit becomes new low limit; set new high limit. */ -void -progress_sethighlim(int highlim) -{ - progress_setrange(progress_highlim, highlim); -} - -/* - * Display a progress bar, assuming that current/total represents a - * percentage in the range [progress_lowlim .. progress_highlim]. - */ -void -progress_bar(const char *dev, const char *label, off_t current, off_t total) -{ - static int lastpercentage = -1; - char buf[256]; - int len, percentage; - int barlength; - int i; - int lengthextras; - -#define BAROVERHEAD 10 /* non-* portion of progress bar */ - - /* - * stars should contain at least sizeof(buf) - BAROVERHEAD - * entries. - */ - static const char stars[] = -"*****************************************************************************" -"*****************************************************************************" -"*****************************************************************************"; - - if (progress_onoff == 0) - return; - - len = 0; - lengthextras = strlen(dev) + (label != NULL ? strlen(label) : 0); - percentage = progress_lowlim + - (current * (progress_highlim - progress_lowlim)) / total; - percentage = MAX(percentage, 0); - percentage = MIN(percentage, 100); - - if (percentage == lastpercentage) - return; - lastpercentage = percentage; - - len += snprintf(buf + len, BUFLEFT, "%s: ", dev); - if (label != NULL) - len += snprintf(buf + len, BUFLEFT, "%s ", label); - - barlength = MIN(sizeof(buf) - 1, ttywidth) - BAROVERHEAD - lengthextras; - if (barlength > 0) { - i = barlength * percentage / 100; - len += snprintf(buf + len, BUFLEFT, - "|%.*s%*s| ", i, stars, barlength - i, ""); - } - len += snprintf(buf + len, BUFLEFT, "%3d%%\r", percentage); - write(fileno(stdout), buf, len); -} - -void -progress_done(void) -{ - char buf[256]; - int len; - - if (progress_onoff == 0) - return; - - len = MIN(sizeof(buf) - 2, ttywidth); - memset(buf, ' ', len); - buf[len] = '\r'; - buf[len + 1] = '\0'; - write(fileno(stdout), buf, len + 1); -} - -void -progress_ttywidth(int a) -{ - struct winsize winsize; - int oerrno = errno; - - if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1 && - winsize.ws_col != 0) - ttywidth = winsize.ws_col; - else - ttywidth = 80; - errno = oerrno; -} - -#endif /* ! SMALL */ diff --git a/sbin/fsck/progress.h b/sbin/fsck/progress.h deleted file mode 100644 index d17c5e557..000000000 --- a/sbin/fsck/progress.h +++ /dev/null @@ -1,42 +0,0 @@ -/* $NetBSD: progress.h,v 1.3 2008/04/28 20:23:08 martin Exp $ */ - -/*- - * Copyright (c) 1997-2004 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Luke Mewburn; by Chris Gilbert; and by Jason R. Thorpe. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * File system independent fsck progress bar routines. - */ - -void progress_init(void); -void progress_setrange(int, int); -void progress_sethighlim(int); -void progress_switch(int); -void progress_ttywidth(int); -void progress_bar(const char *, const char *, off_t, off_t); -void progress_done(void); diff --git a/sbin/fsck_ext2fs/Makefile b/sbin/fsck_ext2fs/Makefile deleted file mode 100644 index 06f469c5f..000000000 --- a/sbin/fsck_ext2fs/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# $NetBSD: Makefile,v 1.17 2014/03/04 21:07:22 joerg Exp $ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 - -.include - -PROG= fsck_ext2fs -MAN= fsck_ext2fs.8 -SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \ - pass5.c fsutil.c setup.c utilities.c ext2fs_bswap.c -FSCK= ${NETBSDSRCDIR}/sbin/fsck -CPPFLAGS+= -I${FSCK} -.PATH: ${NETBSDSRCDIR}/sys/ufs/ext2fs ${FSCK} - -CWARNFLAGS.clang+= -Wno-error=tautological-pointer-compare - -.if defined(__MINIX) -# To compile with clang 3.4 -NOCLANGERROR= yes -.endif # defined(__MINIX) - -.include - -LDADD+=-lutil -DPADD+=${LIBUTIL} diff --git a/sbin/fsck_ext2fs/dir.c b/sbin/fsck_ext2fs/dir.c deleted file mode 100644 index 10ad9a88a..000000000 --- a/sbin/fsck_ext2fs/dir.c +++ /dev/null @@ -1,723 +0,0 @@ -/* $NetBSD: dir.c,v 1.28 2013/06/23 07:28:36 dholland Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)dir.c 8.5 (Berkeley) 12/8/94"; -#else -__RCSID("$NetBSD: dir.c,v 1.28 2013/06/23 07:28:36 dholland Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include - -#include /* for IFMT & friends */ - -#include -#include -#include -#include - -#include "fsck.h" -#include "fsutil.h" -#include "extern.h" - -const char *lfname = "lost+found"; -int lfmode = 01700; -struct ext2fs_dirtemplate emptydir = { - .dot_ino = 0, - .dot_reclen = UFS_DIRBLKSIZ, -}; -struct ext2fs_dirtemplate dirhead = { - .dot_ino = 0, - .dot_reclen = 12, - .dot_namlen = 1, - .dot_type = EXT2_FT_DIR, - .dot_name = ".", - .dotdot_ino = 0, - .dotdot_reclen = UFS_DIRBLKSIZ - 12, - .dotdot_namlen = 2, - .dotdot_type = EXT2_FT_DIR, - .dotdot_name = "..", -}; -#undef UFS_DIRBLKSIZ - -static int expanddir(struct ext2fs_dinode *, char *); -static void freedir(ino_t, ino_t); -static struct ext2fs_direct *fsck_readdir(struct inodesc *); -static struct bufarea *getdirblk(daddr_t, long); -static int lftempname(char *, ino_t); -static int mkentry(struct inodesc *); -static int chgino(struct inodesc *); - -/* - * Propagate connected state through the tree. - */ -void -propagate(void) -{ - struct inoinfo **inpp, *inp, *pinp; - struct inoinfo **inpend; - - /* - * Create a list of children for each directory. - */ - inpend = &inpsort[inplast]; - for (inpp = inpsort; inpp < inpend; inpp++) { - inp = *inpp; - if (inp->i_parent == 0 || - inp->i_number == EXT2_ROOTINO) - continue; - pinp = getinoinfo(inp->i_parent); - inp->i_parentp = pinp; - inp->i_sibling = pinp->i_child; - pinp->i_child = inp; - } - inp = getinoinfo(EXT2_ROOTINO); - while (inp) { - statemap[inp->i_number] = DFOUND; - if (inp->i_child && - statemap[inp->i_child->i_number] == DSTATE) - inp = inp->i_child; - else if (inp->i_sibling) - inp = inp->i_sibling; - else - inp = inp->i_parentp; - } -} - -/* - * Scan each entry in a directory block. - */ -int -dirscan(struct inodesc *idesc) -{ - struct ext2fs_direct *dp; - struct bufarea *bp; - int dsize, n; - long blksiz; - char *dbuf = NULL; - - if ((dbuf = malloc(sblock.e2fs_bsize)) == NULL) - err(8, "Can't allocate directory block"); - - if (idesc->id_type != DATA) - errexit("wrong type to dirscan %d", idesc->id_type); - if (idesc->id_entryno == 0 && - (idesc->id_filesize & (sblock.e2fs_bsize - 1)) != 0) - idesc->id_filesize = roundup(idesc->id_filesize, sblock.e2fs_bsize); - blksiz = idesc->id_numfrags * sblock.e2fs_bsize; - if (chkrange(idesc->id_blkno, idesc->id_numfrags)) { - idesc->id_filesize -= blksiz; - free(dbuf); - return (SKIP); - } - idesc->id_loc = 0; - for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) { - dsize = fs2h16(dp->e2d_reclen); - memcpy(dbuf, dp, (size_t)dsize); - idesc->id_dirp = (struct ext2fs_direct *)dbuf; - if ((n = (*idesc->id_func)(idesc)) & ALTERED) { - bp = getdirblk(idesc->id_blkno, blksiz); - memcpy(bp->b_un.b_buf + idesc->id_loc - dsize, dbuf, - (size_t)dsize); - dirty(bp); - sbdirty(); - } - if (n & STOP) { - free(dbuf); - return (n); - } - } - free(dbuf); - return (idesc->id_filesize > 0 ? KEEPON : STOP); -} - -/* - * get next entry in a directory. - */ -static struct ext2fs_direct * -fsck_readdir(struct inodesc *idesc) -{ - struct ext2fs_direct *dp, *ndp; - struct bufarea *bp; - long size, blksiz, fix, dploc; - - blksiz = idesc->id_numfrags * sblock.e2fs_bsize; - bp = getdirblk(idesc->id_blkno, blksiz); - if (idesc->id_loc % sblock.e2fs_bsize == 0 && idesc->id_filesize > 0 && - idesc->id_loc < blksiz) { - dp = (struct ext2fs_direct *)(bp->b_un.b_buf + idesc->id_loc); - if (dircheck(idesc, dp)) - goto dpok; - if (idesc->id_fix == IGNORE) - return (0); - fix = dofix(idesc, "DIRECTORY CORRUPTED"); - bp = getdirblk(idesc->id_blkno, blksiz); - dp = (struct ext2fs_direct *)(bp->b_un.b_buf + idesc->id_loc); - dp->e2d_reclen = h2fs16(sblock.e2fs_bsize); - dp->e2d_ino = 0; - dp->e2d_namlen = 0; - dp->e2d_type = 0; - dp->e2d_name[0] = '\0'; - if (fix) - dirty(bp); - idesc->id_loc += sblock.e2fs_bsize; - idesc->id_filesize -= sblock.e2fs_bsize; - return (dp); - } -dpok: - if (idesc->id_filesize <= 0 || idesc->id_loc >= blksiz) - return NULL; - dploc = idesc->id_loc; - dp = (struct ext2fs_direct *)(bp->b_un.b_buf + dploc); - idesc->id_loc += fs2h16(dp->e2d_reclen); - idesc->id_filesize -= fs2h16(dp->e2d_reclen); - if ((idesc->id_loc % sblock.e2fs_bsize) == 0) - return (dp); - ndp = (struct ext2fs_direct *)(bp->b_un.b_buf + idesc->id_loc); - if (idesc->id_loc < blksiz && idesc->id_filesize > 0 && - dircheck(idesc, ndp) == 0) { - size = sblock.e2fs_bsize - (idesc->id_loc % sblock.e2fs_bsize); - idesc->id_loc += size; - idesc->id_filesize -= size; - if (idesc->id_fix == IGNORE) - return (0); - fix = dofix(idesc, "DIRECTORY CORRUPTED"); - bp = getdirblk(idesc->id_blkno, blksiz); - dp = (struct ext2fs_direct *)(bp->b_un.b_buf + dploc); - dp->e2d_reclen = h2fs16(fs2h16(dp->e2d_reclen) + size); - if (fix) - dirty(bp); - } - return (dp); -} - -/* - * Verify that a directory entry is valid. - * This is a superset of the checks made in the kernel. - */ -int -dircheck(struct inodesc *idesc, struct ext2fs_direct *dp) -{ - int size; - char *cp; - int spaceleft; - u_int16_t reclen = fs2h16(dp->e2d_reclen); - - spaceleft = sblock.e2fs_bsize - (idesc->id_loc % sblock.e2fs_bsize); - if (fs2h32(dp->e2d_ino) > maxino || - reclen == 0 || - reclen > spaceleft || - (reclen & 0x3) != 0) - return (0); - if (dp->e2d_ino == 0) - return (1); - if (sblock.e2fs.e2fs_rev < E2FS_REV1 || - (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE) == 0) - if (dp->e2d_type != 0) - return (1); - size = EXT2FS_DIRSIZ(dp->e2d_namlen); - if (reclen < size || - idesc->id_filesize < size /* || - dp->e2d_namlen > EXT2FS_MAXNAMLEN */) - return (0); - for (cp = dp->e2d_name, size = 0; size < dp->e2d_namlen; size++) - if (*cp == '\0' || (*cp++ == '/')) - return (0); - return (1); -} - -void -direrror(ino_t ino, const char *errmesg) -{ - - fileerror(ino, ino, errmesg); -} - -void -fileerror(ino_t cwd, ino_t ino, const char *errmesg) -{ - struct ext2fs_dinode *dp; - char pathbuf[MAXPATHLEN + 1]; - - pwarn("%s ", errmesg); - pinode(ino); - printf("\n"); - getpathname(pathbuf, sizeof(pathbuf), cwd, ino); - if ((ino < EXT2_FIRSTINO && ino != EXT2_ROOTINO) || ino > maxino) { - pfatal("NAME=%s\n", pathbuf); - return; - } - dp = ginode(ino); - if (ftypeok(dp)) - pfatal("%s=%s\n", - (fs2h16(dp->e2di_mode) & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf); - else - pfatal("NAME=%s\n", pathbuf); -} - -void -adjust(struct inodesc *idesc, short lcnt) -{ - struct ext2fs_dinode *dp; - - dp = ginode(idesc->id_number); - if (fs2h16(dp->e2di_nlink) == lcnt) { - if (linkup(idesc->id_number, (ino_t)0) == 0) - clri(idesc, "UNREF", 0); - } else { - pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname : - ((fs2h16(dp->e2di_mode) & IFMT) == IFDIR ? "DIR" : "FILE")); - pinode(idesc->id_number); - printf(" COUNT %d SHOULD BE %d", - fs2h16(dp->e2di_nlink), fs2h16(dp->e2di_nlink) - lcnt); - if (preen) { - if (lcnt < 0) { - printf("\n"); - pfatal("LINK COUNT INCREASING"); - } - printf(" (ADJUSTED)\n"); - } - if (preen || reply("ADJUST") == 1) { - dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) - lcnt); - inodirty(); - } - } -} - -static int -mkentry(struct inodesc *idesc) -{ - struct ext2fs_direct *dirp = idesc->id_dirp; - struct ext2fs_direct newent; - int newlen, oldlen; - - newent.e2d_type = 0; /* XXX gcc */ - newent.e2d_namlen = strlen(idesc->id_name); - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) - newent.e2d_type = inot2ext2dt(typemap[idesc->id_parent]); - newlen = EXT2FS_DIRSIZ(newent.e2d_namlen); - if (dirp->e2d_ino != 0) - oldlen = EXT2FS_DIRSIZ(dirp->e2d_namlen); - else - oldlen = 0; - if (fs2h16(dirp->e2d_reclen) - oldlen < newlen) - return (KEEPON); - newent.e2d_reclen = h2fs16(fs2h16(dirp->e2d_reclen) - oldlen); - dirp->e2d_reclen = h2fs16(oldlen); - dirp = (struct ext2fs_direct *)(((char *)dirp) + oldlen); - dirp->e2d_ino = h2fs32(idesc->id_parent); /* ino to be entered is in id_parent */ - dirp->e2d_reclen = newent.e2d_reclen; - dirp->e2d_namlen = newent.e2d_namlen; - dirp->e2d_type = newent.e2d_type; - memcpy(dirp->e2d_name, idesc->id_name, (size_t)(dirp->e2d_namlen)); - return (ALTERED|STOP); -} - -static int -chgino(struct inodesc *idesc) -{ - struct ext2fs_direct *dirp = idesc->id_dirp; - u_int16_t namlen = dirp->e2d_namlen; - - if (strlen(idesc->id_name) != namlen || - strncmp(dirp->e2d_name, idesc->id_name, (int)namlen)) - return (KEEPON); - dirp->e2d_ino = h2fs32(idesc->id_parent); - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) - dirp->e2d_type = inot2ext2dt(typemap[idesc->id_parent]); - else - dirp->e2d_type = 0; - return (ALTERED|STOP); -} - -int -linkup(ino_t orphan, ino_t parentdir) -{ - struct ext2fs_dinode *dp; - int lostdir; - ino_t oldlfdir; - struct inodesc idesc; - char tempname[BUFSIZ]; - - memset(&idesc, 0, sizeof(struct inodesc)); - dp = ginode(orphan); - lostdir = (fs2h16(dp->e2di_mode) & IFMT) == IFDIR; - pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); - pinode(orphan); - if (preen && inosize(dp) == 0) - return (0); - if (preen) - printf(" (RECONNECTED)\n"); - else - if (reply("RECONNECT") == 0) - return (0); - if (lfdir == 0) { - dp = ginode(EXT2_ROOTINO); - idesc.id_name = lfname; - idesc.id_type = DATA; - idesc.id_func = findino; - idesc.id_number = EXT2_ROOTINO; - if ((ckinode(dp, &idesc) & FOUND) != 0) { - lfdir = idesc.id_parent; - } else { - pwarn("NO lost+found DIRECTORY"); - if (preen || reply("CREATE")) { - lfdir = allocdir(EXT2_ROOTINO, (ino_t)0, lfmode); - if (lfdir != 0) { - if (makeentry(EXT2_ROOTINO, lfdir, lfname) != 0) { - if (preen) - printf(" (CREATED)\n"); - } else { - freedir(lfdir, EXT2_ROOTINO); - lfdir = 0; - if (preen) - printf("\n"); - } - } - } - } - if (lfdir == 0) { - pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY"); - printf("\n\n"); - return (0); - } - } - dp = ginode(lfdir); - if ((fs2h16(dp->e2di_mode) & IFMT) != IFDIR) { - pfatal("lost+found IS NOT A DIRECTORY"); - if (reply("REALLOCATE") == 0) - return (0); - oldlfdir = lfdir; - if ((lfdir = allocdir(EXT2_ROOTINO, (ino_t)0, lfmode)) == 0) { - pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY\n\n"); - return (0); - } - if ((changeino(EXT2_ROOTINO, lfname, lfdir) & ALTERED) == 0) { - pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY\n\n"); - return (0); - } - inodirty(); - idesc.id_type = ADDR; - idesc.id_func = pass4check; - idesc.id_number = oldlfdir; - adjust(&idesc, lncntp[oldlfdir] + 1); - lncntp[oldlfdir] = 0; - dp = ginode(lfdir); - } - if (statemap[lfdir] != DFOUND) { - pfatal("SORRY. NO lost+found DIRECTORY\n\n"); - return (0); - } - (void)lftempname(tempname, orphan); - if (makeentry(lfdir, orphan, tempname) == 0) { - pfatal("SORRY. NO SPACE IN lost+found DIRECTORY"); - printf("\n\n"); - return (0); - } - lncntp[orphan]--; - if (lostdir) { - if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 && - parentdir != (ino_t)-1) - (void)makeentry(orphan, lfdir, ".."); - dp = ginode(lfdir); - dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) +1); - inodirty(); - lncntp[lfdir]++; - pwarn("DIR I=%llu CONNECTED. ", (unsigned long long)orphan); - if (parentdir != (ino_t)-1) - printf("PARENT WAS I=%llu\n", - (unsigned long long)parentdir); - if (preen == 0) - printf("\n"); - } - return (1); -} - -/* - * fix an entry in a directory. - */ -int -changeino(ino_t dir, const char *name, ino_t newnum) -{ - struct inodesc idesc; - - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = DATA; - idesc.id_func = chgino; - idesc.id_number = dir; - idesc.id_fix = DONTKNOW; - idesc.id_name = name; - idesc.id_parent = newnum; /* new value for name */ - return (ckinode(ginode(dir), &idesc)); -} - -/* - * make an entry in a directory - */ -int -makeentry(ino_t parent, ino_t ino, const char *name) -{ - struct ext2fs_dinode *dp; - struct inodesc idesc; - char pathbuf[MAXPATHLEN + 1]; - - if ((parent < EXT2_FIRSTINO && parent != EXT2_ROOTINO) - || parent >= maxino || - (ino < EXT2_FIRSTINO && ino < EXT2_ROOTINO) || ino >= maxino) - return (0); - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = DATA; - idesc.id_func = mkentry; - idesc.id_number = parent; - idesc.id_parent = ino; /* this is the inode to enter */ - idesc.id_fix = DONTKNOW; - idesc.id_name = name; - dp = ginode(parent); - if (inosize(dp) % sblock.e2fs_bsize) { - inossize(dp, roundup(inosize(dp), sblock.e2fs_bsize)); - inodirty(); - } - if ((ckinode(dp, &idesc) & ALTERED) != 0) - return (1); - getpathname(pathbuf, sizeof(pathbuf), parent, parent); - dp = ginode(parent); - if (expanddir(dp, pathbuf) == 0) - return (0); - return (ckinode(dp, &idesc) & ALTERED); -} - -/* - * Attempt to expand the size of a directory - */ -static int -expanddir(struct ext2fs_dinode *dp, char *name) -{ - daddr_t lastbn, newblk; - struct bufarea *bp; - char *firstblk; - - lastbn = ext2_lblkno(&sblock, inosize(dp)); - if (lastbn >= EXT2FS_NDADDR - 1 || fs2h32(dp->e2di_blocks[lastbn]) == 0 || - inosize(dp) == 0) { - return (0); - } - if ((newblk = allocblk()) == 0) { - return (0); - } - dp->e2di_blocks[lastbn + 1] = dp->e2di_blocks[lastbn]; - dp->e2di_blocks[lastbn] = h2fs32(newblk); - inossize(dp, inosize(dp) + sblock.e2fs_bsize); - inosnblock(dp, inonblock(dp) + btodb(sblock.e2fs_bsize)); - bp = getdirblk(fs2h32(dp->e2di_blocks[lastbn + 1]), - sblock.e2fs_bsize); - if (bp->b_errs) - goto bad; - if ((firstblk = malloc(sblock.e2fs_bsize)) == NULL) - err(8, "cannot allocate first block"); - memcpy(firstblk, bp->b_un.b_buf, sblock.e2fs_bsize); - bp = getdirblk(newblk, sblock.e2fs_bsize); - if (bp->b_errs) { - free(firstblk); - goto bad; - } - memcpy(bp->b_un.b_buf, firstblk, sblock.e2fs_bsize); - free(firstblk); - dirty(bp); - bp = getdirblk(fs2h32(dp->e2di_blocks[lastbn + 1]), - sblock.e2fs_bsize); - if (bp->b_errs) - goto bad; - emptydir.dot_reclen = h2fs16(sblock.e2fs_bsize); - memcpy(bp->b_un.b_buf, &emptydir, sizeof emptydir); - pwarn("NO SPACE LEFT IN %s", name); - if (preen) - printf(" (EXPANDED)\n"); - else if (reply("EXPAND") == 0) - goto bad; - dirty(bp); - inodirty(); - return (1); -bad: - dp->e2di_blocks[lastbn] = dp->e2di_blocks[lastbn + 1]; - dp->e2di_blocks[lastbn + 1] = 0; - inossize(dp, inosize(dp) - sblock.e2fs_bsize); - inosnblock(dp, inonblock(dp) - btodb(sblock.e2fs_bsize)); - freeblk(newblk); - return (0); -} - -/* - * allocate a new directory - */ -int -allocdir(ino_t parent, ino_t request, int mode) -{ - ino_t ino; - struct ext2fs_dinode *dp; - struct bufarea *bp; - struct ext2fs_dirtemplate *dirp; - - ino = allocino(request, IFDIR|mode); - dirhead.dot_reclen = h2fs16(12); /* XXX */ - dirhead.dotdot_reclen = h2fs16(sblock.e2fs_bsize - 12); /* XXX */ - dirhead.dot_namlen = 1; - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) - dirhead.dot_type = EXT2_FT_DIR; - else - dirhead.dot_type = 0; - dirhead.dotdot_namlen = 2; - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) - dirhead.dotdot_type = EXT2_FT_DIR; - else - dirhead.dotdot_type = 0; - dirp = &dirhead; - dirp->dot_ino = h2fs32(ino); - dirp->dotdot_ino = h2fs32(parent); - dp = ginode(ino); - bp = getdirblk(fs2h32(dp->e2di_blocks[0]), sblock.e2fs_bsize); - if (bp->b_errs) { - freeino(ino); - return (0); - } - memcpy(bp->b_un.b_buf, dirp, sizeof(struct ext2fs_dirtemplate)); - dirty(bp); - dp->e2di_nlink = h2fs16(2); - inodirty(); - if (ino == EXT2_ROOTINO) { - lncntp[ino] = fs2h16(dp->e2di_nlink); - cacheino(dp, ino); - return(ino); - } - if (statemap[parent] != DSTATE && statemap[parent] != DFOUND) { - freeino(ino); - return (0); - } - cacheino(dp, ino); - statemap[ino] = statemap[parent]; - if (statemap[ino] == DSTATE) { - lncntp[ino] = fs2h16(dp->e2di_nlink); - lncntp[parent]++; - } - dp = ginode(parent); - dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) + 1); - inodirty(); - return (ino); -} - -/* - * free a directory inode - */ -static void -freedir(ino_t ino, ino_t parent) -{ - struct ext2fs_dinode *dp; - - if (ino != parent) { - dp = ginode(parent); - dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) - 1); - inodirty(); - } - freeino(ino); -} - -/* - * generate a temporary name for the lost+found directory. - */ -static int -lftempname(char *bufp, ino_t ino) -{ - ino_t in; - char *cp; - int namlen; - - cp = bufp + 2; - for (in = maxino; in > 0; in /= 10) - cp++; - *--cp = 0; - namlen = cp - bufp; - in = ino; - while (cp > bufp) { - *--cp = (in % 10) + '0'; - in /= 10; - } - *cp = '#'; - return (namlen); -} - -/* - * Get a directory block. - * Insure that it is held until another is requested. - */ -static struct bufarea * -getdirblk(daddr_t blkno, long size) -{ - - if (pdirbp != 0) - pdirbp->b_flags &= ~B_INUSE; - pdirbp = getdatablk(blkno, size); - return (pdirbp); -} diff --git a/sbin/fsck_ext2fs/extern.h b/sbin/fsck_ext2fs/extern.h deleted file mode 100644 index ae76f96ae..000000000 --- a/sbin/fsck_ext2fs/extern.h +++ /dev/null @@ -1,75 +0,0 @@ -/* $NetBSD: extern.h,v 1.8 2012/11/25 19:42:14 jakllsch Exp $ */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * Copyright (c) 1994 James A. Jegers - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -void adjust(struct inodesc *, short); -int allocblk(void); -int allocdir(ino_t, ino_t, int); -void blkerror(ino_t, const char *, daddr_t); -int bread(int, char *, daddr_t, long); -void bufinit(void); -void bwrite(int, char *, daddr_t, long); -void cacheino(struct ext2fs_dinode *, ino_t); -int changeino(ino_t, const char *, ino_t); -int chkrange(daddr_t, int); -void ckfini(int); -int ckinode(struct ext2fs_dinode *, struct inodesc *); -void clri(struct inodesc *, const char *, int); -int dircheck(struct inodesc *, struct ext2fs_direct *); -void direrror(ino_t, const char *); -int dirscan(struct inodesc *); -int dofix(struct inodesc *, const char *); -void fileerror(ino_t, ino_t, const char *); -int findino(struct inodesc *); -int findname(struct inodesc *); -void flush(int, struct bufarea *); -void freeblk(daddr_t); -void freeino(ino_t); -void freeinodebuf(void); -int ftypeok(struct ext2fs_dinode *); -void getpathname(char *, size_t, ino_t, ino_t); -void inocleanup(void); -void inodirty(void); -u_int64_t inosize(struct ext2fs_dinode *); -void inossize(struct ext2fs_dinode *, u_int64_t); -int linkup(ino_t, ino_t); -int makeentry(ino_t, ino_t, const char *); -void pass1(void); -void pass1b(void); -void pass2(void); -void pass3(void); -void pass4(void); -int pass1check(struct inodesc *); -int pass4check(struct inodesc *); -void pass5(void); -void pinode(ino_t); -void propagate(void); -int reply(const char *); -void resetinodebuf(void); -int setup(const char *); -struct ext2fs_dinode * getnextinode(ino_t); -uint64_t inonblock(struct ext2fs_dinode *); -void inosnblock(struct ext2fs_dinode *, uint64_t); diff --git a/sbin/fsck_ext2fs/fsck.h b/sbin/fsck_ext2fs/fsck.h deleted file mode 100644 index cd02016c3..000000000 --- a/sbin/fsck_ext2fs/fsck.h +++ /dev/null @@ -1,238 +0,0 @@ -/* $NetBSD: fsck.h,v 1.15 2009/10/19 18:41:08 bouyer Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)fsck.h 8.1 (Berkeley) 6/5/93 - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @(#)fsck.h 8.1 (Berkeley) 6/5/93 - */ - -#define MAXDUP 10 /* limit on dup blks (per inode) */ -#define MAXBAD 10 /* limit on bad blks (per inode) */ -#define MAXBUFSPACE 80*1024 /* maximum space to allocate to buffers */ -#define INOBUFSIZE 128*1024 /* size of buffer to read inodes in pass1 */ - -#ifndef BUFSIZ -#define BUFSIZ 1024 -#endif - -#define USTATE 01 /* inode not allocated */ -#define FSTATE 02 /* inode is file */ -#define DSTATE 03 /* inode is directory */ -#define DFOUND 04 /* directory found during descent */ -#define DCLEAR 05 /* directory is to be cleared */ -#define FCLEAR 06 /* file is to be cleared */ - -/* - * buffer cache structure. - */ -struct bufarea { - struct bufarea *b_next; /* free list queue */ - struct bufarea *b_prev; /* free list queue */ - daddr_t b_bno; - int b_size; - int b_errs; - int b_flags; - union { - char *b_buf; /* buffer space */ - /* XXX ondisk32 */ - int32_t *b_indir; /* indirect block */ - struct ext2fs *b_fs; /* super block */ - struct ext2_gd *b_cgd; /* cylinder group descriptor */ - struct ext2fs_dinode *b_dinode; /* inode block */ - } b_un; - char b_dirty; -}; - -#define B_INUSE 1 - -#define MINBUFS 5 /* minimum number of buffers required */ -struct bufarea bufhead; /* head of list of other blks in filesys */ -struct bufarea sblk; /* file system superblock */ -struct bufarea asblk; /* first alternate superblock */ -struct bufarea *pdirbp; /* current directory contents */ -struct bufarea *pbp; /* current inode block */ -struct bufarea *getdatablk(daddr_t, long); -struct m_ext2fs sblock; - -#define dirty(bp) (bp)->b_dirty = 1 -#define initbarea(bp) \ - (bp)->b_dirty = 0; \ - (bp)->b_bno = (daddr_t)-1; \ - (bp)->b_flags = 0; - -#define sbdirty() copyback_sb(&sblk); sblk.b_dirty = 1 - -enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE}; - -struct inodesc { - enum fixstate id_fix; /* policy on fixing errors */ - int (*id_func) /* function to be applied to blocks of inode */ - (struct inodesc *); - ino_t id_number; /* inode number described */ - ino_t id_parent; /* for DATA nodes, their parent */ - daddr_t id_blkno; /* current block number being examined */ - int id_numfrags; /* number of frags contained in block */ - quad_t id_filesize; /* for DATA nodes, the size of the directory */ - int id_loc; /* for DATA nodes, current location in dir */ - int id_entryno; /* for DATA nodes, current entry number */ - struct ext2fs_direct *id_dirp; /* for DATA nodes, ptr to current entry */ - const char *id_name; /* for DATA nodes, name to find or enter */ - char id_type; /* type of descriptor, DATA or ADDR */ -}; -/* file types */ -#define DATA 1 -#define ADDR 2 - -/* - * Linked list of duplicate blocks. - * - * The list is composed of two parts. The first part of the - * list (from duplist through the node pointed to by muldup) - * contains a single copy of each duplicate block that has been - * found. The second part of the list (from muldup to the end) - * contains duplicate blocks that have been found more than once. - * To check if a block has been found as a duplicate it is only - * necessary to search from duplist through muldup. To find the - * total number of times that a block has been found as a duplicate - * the entire list must be searched for occurrences of the block - * in question. The following diagram shows a sample list where - * w (found twice), x (found once), y (found three times), and z - * (found once) are duplicate block numbers: - * - * w -> y -> x -> z -> y -> w -> y - * ^ ^ - * | | - * duplist muldup - */ -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 */ - -/* - * Linked list of inodes with zero link counts. - */ -struct zlncnt { - struct zlncnt *next; - ino_t zlncnt; -}; -struct zlncnt *zlnhead; /* head of zero link count list */ - -/* - * Inode cache data structures. - */ -struct inoinfo { - struct inoinfo *i_nexthash; /* next entry in hash chain */ - struct inoinfo *i_child, *i_sibling, *i_parentp; - ino_t i_number; /* inode number of this entry */ - ino_t i_parent; /* inode number of parent */ - ino_t i_dotdot; /* inode number of `..' */ - u_int64_t i_isize; /* size of inode */ - u_int i_numblks; /* size of block array in bytes */ - /* XXX ondisk32 */ - int32_t i_blks[1]; /* actually longer */ -} **inphead, **inpsort; -long numdirs, listmax, inplast; - -long dev_bsize; /* computed value of DEV_BSIZE */ -long secsize; /* actual disk sector size */ -char nflag; /* assume a no response */ -char yflag; /* assume a yes response */ -int bflag; /* location of alternate super block */ -int Uflag; /* resolve user names */ -int debug; /* output debugging info */ -int preen; /* just fix normal inconsistencies */ -char havesb; /* superblock has been read */ -char skipclean; /* skip clean file systems if preening */ -int fsmodified; /* 1 => write done to file system */ -int fsreadfd; /* file descriptor for reading file system */ -int fswritefd; /* file descriptor for writing file system */ -int rerun; /* rerun fsck. Only used in non-preen mode */ - -daddr_t maxfsblock; /* number of blocks in the file system */ -char *blockmap; /* ptr to primary blk allocation map */ -ino_t maxino; /* number of inodes in file system */ -ino_t lastino; /* last inode in use */ -char *statemap; /* ptr to inode state table */ -u_char *typemap; /* ptr to inode type table */ -int16_t *lncntp; /* ptr to link count table */ - -ino_t lfdir; /* lost & found directory inode number */ -extern const char *lfname; /* lost & found directory name */ -extern int lfmode; /* lost & found directory creation mode */ - -daddr_t n_blks; /* number of blocks in use */ -daddr_t n_files; /* number of files in use */ - -#define clearinode(dp) (*(dp) = zino) -struct ext2fs_dinode zino; - -#define setbmap(blkno) setbit(blockmap, blkno) -#define testbmap(blkno) isset(blockmap, blkno) -#define clrbmap(blkno) clrbit(blockmap, blkno) - -#define STOP 0x01 -#define SKIP 0x02 -#define KEEPON 0x04 -#define ALTERED 0x08 -#define FOUND 0x10 - -struct ext2fs_dinode *ginode(ino_t); -struct inoinfo *getinoinfo(ino_t); -void getblk(struct bufarea *, daddr_t, long); -ino_t allocino(ino_t, int); -void copyback_sb(struct bufarea*); -daddr_t cgoverhead(int); /* overhead per cg */ diff --git a/sbin/fsck_ext2fs/fsck_ext2fs.8 b/sbin/fsck_ext2fs/fsck_ext2fs.8 deleted file mode 100644 index 4dcefa89c..000000000 --- a/sbin/fsck_ext2fs/fsck_ext2fs.8 +++ /dev/null @@ -1,253 +0,0 @@ -.\" $NetBSD: fsck_ext2fs.8,v 1.19 2010/02/21 13:26:45 wiz Exp $ -.\" -.\" Copyright (c) 1980, 1989, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" Copyright (c) 1997 Manuel Bouyer. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" @(#)fsck.8 8.3 (Berkeley) 11/29/94 -.\" -.Dd October 9, 2008 -.Dt FSCK_EXT2FS 8 -.Os -.Sh NAME -.Nm fsck_ext2fs -.Nd ext2 File System consistency check and interactive repair -.Sh SYNOPSIS -.Nm -.Op Fl dfnpUy -.Op Fl b Ar block# -.Op Fl c Ar level -.Op Fl m Ar mode -.Ar filesystem ... -.Sh DESCRIPTION -.Nm -performs interactive filesystem consistency checks and repair for each of -the filesystems specified on the command line. -It is normally invoked from -.Xr fsck 8 . -.Pp -The kernel takes care that only a restricted class of innocuous filesystem -inconsistencies can happen unless hardware or software failures intervene. -These are limited to the following: -.Pp -.Bl -item -compact -.It -Unreferenced inodes -.It -Link counts in inodes too large -.It -Missing blocks in the free map -.It -Blocks in the free map also in files -.It -Counts in the super-block wrong -.El -.Pp -These are the only inconsistencies that -.Nm -in -.Dq preen -mode (with the -.Fl p -option) will correct; if it encounters other inconsistencies, it exits -with an abnormal return status. -For each corrected inconsistency one or more lines will be printed -identifying the filesystem on which the correction will take place, -and the nature of the correction. -After successfully correcting a filesystem, -.Nm -will print the number of files on that filesystem -and the number of used and free blocks. -.Pp -If sent a -.Dv QUIT -signal, -.Nm -will finish the filesystem checks, then exit with an abnormal return status. -.Pp -Without the -.Fl p -option, -.Nm -audits and interactively repairs inconsistent conditions for filesystems. -If the filesystem is inconsistent the operator is prompted for concurrence -before each correction is attempted. -It should be noted that some of the corrective actions which are not -correctable under the -.Fl p -option will result in some loss of data. -The amount and severity of data lost may be determined from the diagnostic -output. -The default action for each consistency correction -is to wait for the operator to respond -.Li yes -or -.Li no . -If the operator does not have write permission on the filesystem -.Nm -will default to a -.Fl n -action. -.Pp -The following flags are interpreted by -.Nm . -.Bl -tag -width indent -.It Fl b -Use the block specified immediately after the flag as -the super block for the filesystem. -Block 8193 is usually an alternate super block. -.It Fl d -Print debugging output. -.It Fl f -Force checking of file systems. -Normally, if a file system is cleanly unmounted, the kernel will set a -.Dq clean flag -in the file system superblock, and -.Nm -will not check the file system. -This option forces -.Nm -to check the file system, regardless of the state of the clean flag. -.It Fl m -Use the mode specified in octal immediately after the flag as the -permission bits to use when creating the -.Pa lost+found -directory rather than the default 1777. -In particular, systems that do not wish to have lost files accessible -by all users on the system should use a more restrictive -set of permissions such as 700. -.It Fl n -Assume a no response to all questions asked by -.Nm -except for -.Ql CONTINUE? , -which is assumed to be affirmative; -do not open the filesystem for writing. -.It Fl p -Specify -.Dq preen -mode, described above. -.It Fl U -Resolve numeric userids to usernames. -.It Fl y -Assume a yes response to all questions asked by -.Nm ; -this should be used with great caution as this is a free license -to continue after essentially unlimited trouble has been encountered. -.El -.Pp -Inconsistencies checked are as follows: -.Bl -enum -offset indent -compact -.It -Blocks claimed by more than one inode or the free map. -.It -Blocks claimed by an inode outside the range of the filesystem. -.It -Incorrect link counts. -.It -Size checks: -.Bl -item -offset indent -compact -.It -Directory size not a multiple of filesystem block size. -.It -Partially truncated file. -.El -.It -Bad inode format. -.It -Blocks not accounted for anywhere. -.It -Directory checks: -.Bl -item -offset indent -compact -.It -File pointing to unallocated inode. -.It -Inode number out of range. -.It -Dot or dot-dot not the first two entries of a directory -or having the wrong inode number. -.El -.It -Super Block checks: -.Bl -item -offset indent -compact -.It -More blocks for inodes than there are in the filesystem. -.It -Bad free block map format. -.It -Total free block and/or free inode count incorrect. -.El -.El -.Pp -Orphaned files and directories (allocated but unreferenced) are, -with the operator's concurrence, reconnected by -placing them in the -.Pa lost+found -directory. -The name assigned is the inode number. -If the -.Pa lost+found -directory does not exist, it is created. -If there is insufficient space its size is increased. -.Pp -Because of inconsistencies between the block device and the buffer cache, -the raw device should always be used. -.Sh DIAGNOSTICS -The diagnostics produced by -.Nm -are fully enumerated and explained in Appendix A of -.Rs -.%T "Fsck \- The UNIX File System Check Program" -.Re -.Sh SEE ALSO -.Xr fs 5 , -.Xr fstab 5 , -.Xr fsck 8 , -.Xr fsdb 8 , -.Xr newfs 8 , -.Xr reboot 8 diff --git a/sbin/fsck_ext2fs/inode.c b/sbin/fsck_ext2fs/inode.c deleted file mode 100644 index 693b9208b..000000000 --- a/sbin/fsck_ext2fs/inode.c +++ /dev/null @@ -1,812 +0,0 @@ -/* $NetBSD: inode.c,v 1.36 2013/06/23 07:28:36 dholland Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95"; -#else -__RCSID("$NetBSD: inode.c,v 1.36 2013/06/23 07:28:36 dholland Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include - -#include /* for IFMT & friends */ -#ifndef SMALL -#include -#endif -#include -#include -#include -#include - -#include "fsck.h" -#include "fsutil.h" -#include "extern.h" - -/* - * CG is stored in fs byte order in memory, so we can't use ino_to_fsba - * here. - */ - -#define fsck_ino_to_fsba(fs, x) \ - (fs2h32((fs)->e2fs_gd[ino_to_cg(fs, x)].ext2bgd_i_tables) + \ - (((x)-1) % (fs)->e2fs.e2fs_ipg)/(fs)->e2fs_ipb) - - -static ino_t startinum; - -static int iblock(struct inodesc *, long, u_int64_t); - -static int setlarge(void); - -static int sethuge(void); - -static int -setlarge(void) -{ - if (sblock.e2fs.e2fs_rev < E2FS_REV1) { - pfatal("LARGE FILES UNSUPPORTED ON REVISION 0 FILESYSTEMS"); - return 0; - } - if (!(sblock.e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_LARGEFILE)) { - if (preen) - pwarn("SETTING LARGE FILE INDICATOR\n"); - else if (!reply("SET LARGE FILE INDICATOR")) - return 0; - sblock.e2fs.e2fs_features_rocompat |= EXT2F_ROCOMPAT_LARGEFILE; - sbdirty(); - } - return 1; -} - -static int -sethuge(void) -{ - if (sblock.e2fs.e2fs_rev < E2FS_REV1) { - pfatal("HUGE FILES UNSUPPORTED ON REVISION 0 FILESYSTEMS"); - return 0; - } - if (!(sblock.e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_HUGE_FILE)) { - if (preen) - pwarn("SETTING HUGE FILE FEATURE\n"); - else if (!reply("SET HUGE FILE FEATURE")) - return 0; - sblock.e2fs.e2fs_features_rocompat |= EXT2F_ROCOMPAT_HUGE_FILE; - sbdirty(); - } - return 1; -} - -u_int64_t -inosize(struct ext2fs_dinode *dp) -{ - u_int64_t size = fs2h32(dp->e2di_size); - - if ((fs2h16(dp->e2di_mode) & IFMT) == IFREG) - size |= (u_int64_t)fs2h32(dp->e2di_dacl) << 32; - if (size > INT32_MAX) - (void)setlarge(); - return size; -} - -void -inossize(struct ext2fs_dinode *dp, u_int64_t size) -{ - if ((fs2h16(dp->e2di_mode) & IFMT) == IFREG) { - dp->e2di_dacl = h2fs32(size >> 32); - if (size > INT32_MAX) - if (!setlarge()) - return; - } else if (size > INT32_MAX) { - pfatal("TRYING TO SET FILESIZE TO %llu ON MODE %x FILE\n", - (unsigned long long)size, fs2h16(dp->e2di_mode) & IFMT); - return; - } - dp->e2di_size = h2fs32(size); -} - -int -ckinode(struct ext2fs_dinode *dp, struct inodesc *idesc) -{ - u_int32_t *ap; - long ret, n, ndb; - struct ext2fs_dinode dino; - u_int64_t remsize, sizepb; - mode_t mode; - char pathbuf[MAXPATHLEN + 1]; - - if (idesc->id_fix != IGNORE) - idesc->id_fix = DONTKNOW; - idesc->id_entryno = 0; - idesc->id_filesize = inosize(dp); - mode = fs2h16(dp->e2di_mode) & IFMT; - if (mode == IFBLK || mode == IFCHR || mode == IFIFO || - (mode == IFLNK && (inosize(dp) < EXT2_MAXSYMLINKLEN))) - return (KEEPON); - dino = *dp; - ndb = howmany(inosize(&dino), sblock.e2fs_bsize); - for (ap = &dino.e2di_blocks[0]; ap < &dino.e2di_blocks[EXT2FS_NDADDR]; - ap++,ndb--) { - idesc->id_numfrags = 1; - if (*ap == 0) { - if (idesc->id_type == DATA && ndb > 0) { - /* An empty block in a directory XXX */ - getpathname(pathbuf, sizeof(pathbuf), - idesc->id_number, idesc->id_number); - pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", - pathbuf); - if (reply("ADJUST LENGTH") == 1) { - dp = ginode(idesc->id_number); - inossize(dp, - (ap - &dino.e2di_blocks[0]) * - sblock.e2fs_bsize); - printf( - "YOU MUST RERUN FSCK AFTERWARDS\n"); - rerun = 1; - inodirty(); - } - } - continue; - } - idesc->id_blkno = fs2h32(*ap); - if (idesc->id_type == ADDR) - ret = (*idesc->id_func)(idesc); - else - ret = dirscan(idesc); - if (ret & STOP) - return (ret); - } - idesc->id_numfrags = 1; - remsize = inosize(&dino) - sblock.e2fs_bsize * EXT2FS_NDADDR; - sizepb = sblock.e2fs_bsize; - for (ap = &dino.e2di_blocks[EXT2FS_NDADDR], n = 1; n <= EXT2FS_NIADDR; ap++, n++) { - if (*ap) { - idesc->id_blkno = fs2h32(*ap); - ret = iblock(idesc, n, remsize); - if (ret & STOP) - return (ret); - } else { - if (idesc->id_type == DATA && remsize > 0) { - /* An empty block in a directory XXX */ - getpathname(pathbuf, sizeof(pathbuf), - idesc->id_number, idesc->id_number); - pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", - pathbuf); - if (reply("ADJUST LENGTH") == 1) { - dp = ginode(idesc->id_number); - inossize(dp, inosize(dp) - remsize); - remsize = 0; - printf( - "YOU MUST RERUN FSCK AFTERWARDS\n"); - rerun = 1; - inodirty(); - break; - } - } - } - sizepb *= EXT2_NINDIR(&sblock); - remsize -= sizepb; - } - return (KEEPON); -} - -static int -iblock(struct inodesc *idesc, long ilevel, u_int64_t isize) -{ - /* XXX ondisk32 */ - int32_t *ap; - int32_t *aplim; - struct bufarea *bp; - int i, n, (*func)(struct inodesc *); - size_t nif; - u_int64_t sizepb; - char buf[BUFSIZ]; - char pathbuf[MAXPATHLEN + 1]; - struct ext2fs_dinode *dp; - - if (idesc->id_type == ADDR) { - func = idesc->id_func; - if (((n = (*func)(idesc)) & KEEPON) == 0) - return (n); - } else - func = dirscan; - if (chkrange(idesc->id_blkno, idesc->id_numfrags)) - return (SKIP); - bp = getdatablk(idesc->id_blkno, sblock.e2fs_bsize); - ilevel--; - for (sizepb = sblock.e2fs_bsize, i = 0; i < ilevel; i++) - sizepb *= EXT2_NINDIR(&sblock); - if (isize > sizepb * EXT2_NINDIR(&sblock)) - nif = EXT2_NINDIR(&sblock); - else - nif = howmany(isize, sizepb); - if (idesc->id_func == pass1check && - nif < EXT2_NINDIR(&sblock)) { - aplim = &bp->b_un.b_indir[EXT2_NINDIR(&sblock)]; - for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) { - if (*ap == 0) - continue; - (void)snprintf(buf, sizeof(buf), - "PARTIALLY TRUNCATED INODE I=%llu", - (unsigned long long)idesc->id_number); - if (dofix(idesc, buf)) { - *ap = 0; - dirty(bp); - } - } - flush(fswritefd, bp); - } - aplim = &bp->b_un.b_indir[nif]; - for (ap = bp->b_un.b_indir; ap < aplim; ap++) { - if (*ap) { - idesc->id_blkno = fs2h32(*ap); - if (ilevel == 0) - n = (*func)(idesc); - else - n = iblock(idesc, ilevel, isize); - if (n & STOP) { - bp->b_flags &= ~B_INUSE; - return (n); - } - } else { - if (idesc->id_type == DATA && isize > 0) { - /* An empty block in a directory XXX */ - getpathname(pathbuf, sizeof(pathbuf), - idesc->id_number, idesc->id_number); - pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", - pathbuf); - if (reply("ADJUST LENGTH") == 1) { - dp = ginode(idesc->id_number); - inossize(dp, inosize(dp) - isize); - isize = 0; - printf( - "YOU MUST RERUN FSCK AFTERWARDS\n"); - rerun = 1; - inodirty(); - bp->b_flags &= ~B_INUSE; - return(STOP); - } - } - } - isize -= sizepb; - } - bp->b_flags &= ~B_INUSE; - return (KEEPON); -} - -/* - * Check that a block in a legal block number. - * Return 0 if in range, 1 if out of range. - */ -int -chkrange(daddr_t blk, int cnt) -{ - int c, overh; - - if ((unsigned int)(blk + cnt) > maxfsblock) - return (1); - c = dtog(&sblock, blk); - overh = cgoverhead(c); - if (blk < sblock.e2fs.e2fs_bpg * c + overh + - sblock.e2fs.e2fs_first_dblock) { - if ((blk + cnt) > sblock.e2fs.e2fs_bpg * c + overh + - sblock.e2fs.e2fs_first_dblock) { - if (debug) { - printf("blk %lld < cgdmin %d;", - (long long)blk, - sblock.e2fs.e2fs_bpg * c + overh + - sblock.e2fs.e2fs_first_dblock); - printf(" blk + cnt %lld > cgsbase %d\n", - (long long)(blk + cnt), - sblock.e2fs.e2fs_bpg * c + - overh + sblock.e2fs.e2fs_first_dblock); - } - return (1); - } - } else { - if ((blk + cnt) > sblock.e2fs.e2fs_bpg * (c + 1) + overh + - sblock.e2fs.e2fs_first_dblock) { - if (debug) { - printf("blk %lld >= cgdmin %d;", - (long long)blk, - sblock.e2fs.e2fs_bpg * c + overh + - sblock.e2fs.e2fs_first_dblock); - printf(" blk + cnt %lld > cgdmax %d\n", - (long long)(blk+cnt), - sblock.e2fs.e2fs_bpg * (c + 1) + - overh + sblock.e2fs.e2fs_first_dblock); - } - return (1); - } - } - return (0); -} - -/* - * General purpose interface for reading inodes. - */ -struct ext2fs_dinode * -ginode(ino_t inumber) -{ - daddr_t iblk; - struct ext2fs_dinode *dp; - - if ((inumber < EXT2_FIRSTINO && - inumber != EXT2_ROOTINO && - !(inumber == EXT2_RESIZEINO && - (sblock.e2fs.e2fs_features_compat & EXT2F_COMPAT_RESIZE) != 0)) - || inumber > maxino) - errexit("bad inode number %llu to ginode", - (unsigned long long)inumber); - if (startinum == 0 || - inumber < startinum || inumber >= startinum + sblock.e2fs_ipb) { - iblk = fsck_ino_to_fsba(&sblock, inumber); - if (pbp != 0) - pbp->b_flags &= ~B_INUSE; - pbp = getdatablk(iblk, sblock.e2fs_bsize); - startinum = - ((inumber - 1) / sblock.e2fs_ipb) * sblock.e2fs_ipb + 1; - } - dp = (struct ext2fs_dinode *)(pbp->b_un.b_buf + - EXT2_DINODE_SIZE(&sblock) * ino_to_fsbo(&sblock, inumber)); - - return dp; -} - -/* - * Special purpose version of ginode used to optimize first pass - * over all the inodes in numerical order. - */ -ino_t nextino, lastinum; -long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize; -char *inodebuf; - -struct ext2fs_dinode * -getnextinode(ino_t inumber) -{ - long size; - daddr_t dblk; - struct ext2fs_dinode *dp; - static char *bp; - - if (inumber != nextino++ || inumber > maxino) - errexit("bad inode number %llu to nextinode", - (unsigned long long)inumber); - if (inumber >= lastinum) { - readcnt++; - dblk = EXT2_FSBTODB(&sblock, fsck_ino_to_fsba(&sblock, lastinum)); - if (readcnt % readpercg == 0) { - size = partialsize; - lastinum += partialcnt; - } else { - size = inobufsize; - lastinum += fullcnt; - } - (void)bread(fsreadfd, inodebuf, dblk, size); - bp = inodebuf; - } - dp = (struct ext2fs_dinode *)bp; - bp += EXT2_DINODE_SIZE(&sblock); - - return dp; -} - -void -resetinodebuf(void) -{ - - startinum = 0; - nextino = 1; - lastinum = 1; - readcnt = 0; - inobufsize = ext2_blkroundup(&sblock, INOBUFSIZE); - fullcnt = inobufsize / EXT2_DINODE_SIZE(&sblock); - readpercg = sblock.e2fs.e2fs_ipg / fullcnt; - partialcnt = sblock.e2fs.e2fs_ipg % fullcnt; - partialsize = partialcnt * EXT2_DINODE_SIZE(&sblock); - if (partialcnt != 0) { - readpercg++; - } else { - partialcnt = fullcnt; - partialsize = inobufsize; - } - if (inodebuf == NULL && - (inodebuf = malloc((unsigned int)inobufsize)) == NULL) - errexit("Cannot allocate space for inode buffer"); - while (nextino < EXT2_ROOTINO) - (void)getnextinode(nextino); -} - -void -freeinodebuf(void) -{ - - if (inodebuf != NULL) - free(inodebuf); - inodebuf = NULL; -} - -/* - * Routines to maintain information about directory inodes. - * This is built during the first pass and used during the - * second and third passes. - * - * Enter inodes into the cache. - */ -void -cacheino(struct ext2fs_dinode *dp, ino_t inumber) -{ - struct inoinfo *inp; - struct inoinfo **inpp; - unsigned int blks; - - blks = howmany(inosize(dp), sblock.e2fs_bsize); - if (blks > EXT2FS_NDADDR) - blks = EXT2FS_NDADDR + EXT2FS_NIADDR; - /* XXX ondisk32 */ - inp = malloc(sizeof(*inp) + (blks - 1) * sizeof(int32_t)); - if (inp == NULL) - return; - inpp = &inphead[inumber % numdirs]; - inp->i_nexthash = *inpp; - *inpp = inp; - inp->i_child = inp->i_sibling = inp->i_parentp = 0; - if (inumber == EXT2_ROOTINO) - inp->i_parent = EXT2_ROOTINO; - else - inp->i_parent = (ino_t)0; - inp->i_dotdot = (ino_t)0; - inp->i_number = inumber; - inp->i_isize = inosize(dp); - /* XXX ondisk32 */ - inp->i_numblks = blks * sizeof(int32_t); - memcpy(&inp->i_blks[0], &dp->e2di_blocks[0], (size_t)inp->i_numblks); - if (inplast == listmax) { - listmax += 100; - inpsort = (struct inoinfo **)realloc((char *)inpsort, - (unsigned int)listmax * sizeof(struct inoinfo *)); - if (inpsort == NULL) - errexit("cannot increase directory list"); - } - inpsort[inplast++] = inp; -} - -/* - * Look up an inode cache structure. - */ -struct inoinfo * -getinoinfo(ino_t inumber) -{ - struct inoinfo *inp; - - for (inp = inphead[inumber % numdirs]; inp; inp = inp->i_nexthash) { - if (inp->i_number != inumber) - continue; - return (inp); - } - errexit("cannot find inode %llu", (unsigned long long)inumber); - return ((struct inoinfo *)0); -} - -/* - * Clean up all the inode cache structure. - */ -void -inocleanup(void) -{ - struct inoinfo **inpp; - - if (inphead == NULL) - return; - for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--) - free(*inpp); - free(inphead); - free(inpsort); - inphead = inpsort = NULL; -} - -void -inodirty(void) -{ - - dirty(pbp); -} - -void -clri(struct inodesc *idesc, const char *type, int flag) -{ - struct ext2fs_dinode *dp; - - dp = ginode(idesc->id_number); - if (flag == 1) { - pwarn("%s %s", type, - (fs2h16(dp->e2di_mode) & IFMT) == IFDIR ? "DIR" : "FILE"); - pinode(idesc->id_number); - } - if (preen || reply("CLEAR") == 1) { - if (preen) - printf(" (CLEARED)\n"); - n_files--; - (void)ckinode(dp, idesc); - clearinode(dp); - statemap[idesc->id_number] = USTATE; - inodirty(); - } -} - -int -findname(struct inodesc *idesc) -{ - struct ext2fs_direct *dirp = idesc->id_dirp; - u_int16_t namlen = dirp->e2d_namlen; - /* from utilities.c namebuf[] variable */ - char *buf = __UNCONST(idesc->id_name); - if (namlen > MAXPATHLEN) { - /* XXX: Prevent overflow but don't fix */ - namlen = MAXPATHLEN; - } - - if (fs2h32(dirp->e2d_ino) != idesc->id_parent) - return (KEEPON); - (void)memcpy(buf, dirp->e2d_name, (size_t)namlen); - buf[namlen] = '\0'; - return (STOP|FOUND); -} - -int -findino(struct inodesc *idesc) -{ - struct ext2fs_direct *dirp = idesc->id_dirp; - u_int32_t ino = fs2h32(dirp->e2d_ino); - - if (ino == 0) - return (KEEPON); - if (strcmp(dirp->e2d_name, idesc->id_name) == 0 && - (ino == EXT2_ROOTINO || ino >= EXT2_FIRSTINO) - && ino <= maxino) { - idesc->id_parent = ino; - return (STOP|FOUND); - } - return (KEEPON); -} - -void -pinode(ino_t ino) -{ - struct ext2fs_dinode *dp; - struct passwd *pw; - uid_t uid; - - printf(" I=%llu ", (unsigned long long)ino); - if ((ino < EXT2_FIRSTINO && ino != EXT2_ROOTINO) || ino > maxino) - return; - dp = ginode(ino); - uid = fs2h16(dp->e2di_uid); - if (sblock.e2fs.e2fs_rev > E2FS_REV0) - uid |= fs2h16(dp->e2di_uid_high) << 16; - printf(" OWNER="); -#ifndef SMALL - if (Uflag && (pw = getpwuid(uid)) != 0) - printf("%s ", pw->pw_name); - else -#endif - printf("%u ", (unsigned int)uid); - printf("MODE=%o\n", fs2h16(dp->e2di_mode)); - if (preen) - printf("%s: ", cdevname()); - printf("SIZE=%llu ", (long long)inosize(dp)); - printf("MTIME=%s ", print_mtime(fs2h32(dp->e2di_mtime))); -} - -void -blkerror(ino_t ino, const char *type, daddr_t blk) -{ - - pfatal("%lld %s I=%llu", (long long)blk, type, (unsigned long long)ino); - printf("\n"); - switch (statemap[ino]) { - - case FSTATE: - statemap[ino] = FCLEAR; - return; - - case DSTATE: - statemap[ino] = DCLEAR; - return; - - case FCLEAR: - case DCLEAR: - return; - - default: - errexit("BAD STATE %d TO BLKERR", statemap[ino]); - /* NOTREACHED */ - } -} - -/* - * allocate an unused inode - */ -ino_t -allocino(ino_t request, int type) -{ - ino_t ino; - struct ext2fs_dinode *dp; - time_t t; - - if (request == 0) - request = EXT2_ROOTINO; - else if (statemap[request] != USTATE) - return (0); - for (ino = request; ino < maxino; ino++) { - if ((ino > EXT2_ROOTINO) && (ino < EXT2_FIRSTINO)) - continue; - if (statemap[ino] == USTATE) - break; - } - if (ino == maxino) - return (0); - switch (type & IFMT) { - case IFDIR: - statemap[ino] = DSTATE; - break; - case IFREG: - case IFLNK: - statemap[ino] = FSTATE; - break; - default: - return (0); - } - dp = ginode(ino); - dp->e2di_blocks[0] = h2fs32(allocblk()); - if (dp->e2di_blocks[0] == 0) { - statemap[ino] = USTATE; - return (0); - } - dp->e2di_mode = h2fs16(type); - (void)time(&t); - dp->e2di_atime = h2fs32(t); - dp->e2di_mtime = dp->e2di_ctime = dp->e2di_atime; - dp->e2di_dtime = 0; - inossize(dp, sblock.e2fs_bsize); - inosnblock(dp, btodb(sblock.e2fs_bsize)); - n_files++; - inodirty(); - typemap[ino] = E2IFTODT(type); - return (ino); -} - -/* - * deallocate an inode - */ -void -freeino(ino_t ino) -{ - struct inodesc idesc; - struct ext2fs_dinode *dp; - - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = ADDR; - idesc.id_func = pass4check; - idesc.id_number = ino; - dp = ginode(ino); - (void)ckinode(dp, &idesc); - clearinode(dp); - inodirty(); - statemap[ino] = USTATE; - n_files--; -} - -uint64_t -inonblock(struct ext2fs_dinode *dp) -{ - uint64_t nblock; - - /* XXX check for EXT2_HUGE_FILE without EXT2F_ROCOMPAT_HUGE_FILE? */ - - nblock = fs2h32(dp->e2di_nblock); - - if ((sblock.e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_HUGE_FILE)) { - nblock |= (uint64_t)fs2h16(dp->e2di_nblock_high) << 32; - if (fs2h32(dp->e2di_flags) & EXT2_HUGE_FILE) { - nblock = EXT2_FSBTODB(&sblock, nblock); - } - } - - return nblock; -} - -void -inosnblock(struct ext2fs_dinode *dp, uint64_t nblock) -{ - uint32_t flags; - - flags = fs2h32(dp->e2di_flags); - - if (nblock <= 0xffffffffULL) { - flags &= ~EXT2_HUGE_FILE; - dp->e2di_flags = h2fs32(flags); - dp->e2di_nblock = h2fs32(nblock); - return; - } - - sethuge(); - - if (nblock <= 0xffffffffffffULL) { - flags &= ~EXT2_HUGE_FILE; - dp->e2di_flags = h2fs32(flags); - dp->e2di_nblock = h2fs32(nblock); - dp->e2di_nblock_high = h2fs16((nblock >> 32)); - return; - } - - if (EXT2_DBTOFSB(&sblock, nblock) <= 0xffffffffffffULL) { - flags |= EXT2_HUGE_FILE; - dp->e2di_flags = h2fs32(flags); - dp->e2di_nblock = h2fs32(EXT2_DBTOFSB(&sblock, nblock)); - dp->e2di_nblock_high = h2fs16((EXT2_DBTOFSB(&sblock, nblock) >> 32)); - return; - } - - pfatal("trying to set nblocks higher than representable"); - - return; -} diff --git a/sbin/fsck_ext2fs/main.c b/sbin/fsck_ext2fs/main.c deleted file mode 100644 index 62a0ae62a..000000000 --- a/sbin/fsck_ext2fs/main.c +++ /dev/null @@ -1,358 +0,0 @@ -/* $NetBSD: main.c,v 1.37 2011/06/09 19:57:51 christos Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1993\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94"; -#else -__RCSID("$NetBSD: main.c,v 1.37 2011/06/09 19:57:51 christos Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fsck.h" -#include "extern.h" -#include "fsutil.h" -#include "exitvalues.h" - -volatile sig_atomic_t returntosingle = 0; - - -static int argtoi(int, const char *, const char *, int); -static int checkfilesys(const char *, char *, long, int); -static void usage(void) __dead; - -int -main(int argc, char *argv[]) -{ - int ch; - int ret = FSCK_EXIT_OK; - - ckfinish = ckfini; - sync(); - skipclean = 1; - while ((ch = getopt(argc, argv, "b:dfm:npPqUy")) != -1) { - switch (ch) { - case 'b': - skipclean = 0; - bflag = argtoi('b', "number", optarg, 10); - printf("Alternate super block location: %d\n", bflag); - break; - - case 'd': - debug++; - break; - - case 'f': - skipclean = 0; - break; - - case 'm': - lfmode = argtoi('m', "mode", optarg, 8); - if (lfmode &~ 07777) - errexit("bad mode to -m: %o", lfmode); - printf("** lost+found creation mode %o\n", lfmode); - break; - - case 'n': - nflag++; - yflag = 0; - break; - - case 'p': - preen++; - break; - - case 'P': - /* Progress meter not implemented. */ - break; - - case 'q': /* Quiet not implemented */ - break; - -#ifndef SMALL - case 'U': - Uflag++; - break; -#endif - - case 'y': - yflag++; - nflag = 0; - break; - - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - if (!argc) - usage(); - - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - (void)signal(SIGINT, catch); - if (preen) - (void)signal(SIGQUIT, catchquit); - - while (argc-- > 0) { - int nret = checkfilesys(blockcheck(*argv++), 0, 0L, 0); - if (ret < nret) - ret = nret; - } - - return returntosingle ? FSCK_EXIT_UNRESOLVED : ret; -} - -static int -argtoi(int flag, const char *req, const char *str, int base) -{ - char *cp; - int ret; - - ret = (int)strtol(str, &cp, base); - if (cp == str || *cp) - errexit("-%c flag requires a %s", flag, req); - return (ret); -} - -/* - * Check the specified filesystem. - */ -/* ARGSUSED */ -static int -checkfilesys(const char *filesys, char *mntpt, long auxdata, int child) -{ - daddr_t n_bfree; - struct dups *dp; - struct zlncnt *zlnp; - int i; - - if (preen && child) - (void)signal(SIGQUIT, voidquit); - setcdevname(filesys, preen); - if (debug && preen) - pwarn("starting\n"); - switch (setup(filesys)) { - case 0: - if (preen) - pfatal("CAN'T CHECK FILE SYSTEM."); - case -1: - return FSCK_EXIT_OK; - } - /* - * 1: scan inodes tallying blocks used - */ - if (preen == 0) { - if (sblock.e2fs.e2fs_rev > E2FS_REV0) { - printf("** Last Mounted on %s\n", - sblock.e2fs.e2fs_fsmnt); - } - if (hotroot()) - printf("** Root file system\n"); - printf("** Phase 1 - Check Blocks and Sizes\n"); - } - pass1(); - - /* - * 1b: locate first references to duplicates, if any - */ - if (duplist) { - if (preen) - pfatal("INTERNAL ERROR: dups with -p"); - printf("** Phase 1b - Rescan For More DUPS\n"); - pass1b(); - } - - /* - * 2: traverse directories from root to mark all connected directories - */ - if (preen == 0) - printf("** Phase 2 - Check Pathnames\n"); - pass2(); - - /* - * 3: scan inodes looking for disconnected directories - */ - if (preen == 0) - printf("** Phase 3 - Check Connectivity\n"); - pass3(); - - /* - * 4: scan inodes looking for disconnected files; check reference counts - */ - if (preen == 0) - printf("** Phase 4 - Check Reference Counts\n"); - pass4(); - - /* - * 5: check and repair resource counts in cylinder groups - */ - if (preen == 0) - printf("** Phase 5 - Check Cyl groups\n"); - pass5(); - - /* - * print out summary statistics - */ - n_bfree = sblock.e2fs.e2fs_fbcount; - - pwarn("%lld files, %lld used, %lld free\n", - (long long)n_files, (long long)n_blks, (long long)n_bfree); - if (debug && - /* 9 reserved and unused inodes in FS */ - (n_files -= maxino - 9 - sblock.e2fs.e2fs_ficount)) - printf("%lld files missing\n", (long long)n_files); - if (debug) { - for (i = 0; i < sblock.e2fs_ncg; i++) - n_blks += cgoverhead(i); - n_blks += sblock.e2fs.e2fs_first_dblock; - if (n_blks -= maxfsblock - n_bfree) - printf("%lld blocks missing\n", (long long)n_blks); - if (duplist != NULL) { - printf("The following duplicate blocks remain:"); - for (dp = duplist; dp; dp = dp->next) - printf(" %lld,", (long long)dp->dup); - printf("\n"); - } - if (zlnhead != NULL) { - printf("The following zero link count inodes remain:"); - for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) - printf(" %llu,", - (unsigned long long)zlnp->zlncnt); - printf("\n"); - } - } - zlnhead = (struct zlncnt *)0; - duplist = (struct dups *)0; - muldup = (struct dups *)0; - inocleanup(); - if (fsmodified) { - time_t t; - (void)time(&t); - sblock.e2fs.e2fs_wtime = t; - sblock.e2fs.e2fs_lastfsck = t; - sbdirty(); - } - ckfini(1); - free(blockmap); - free(statemap); - free((char *)lncntp); - if (!fsmodified) - return FSCK_EXIT_OK; - if (!preen) - printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); - if (rerun) - printf("\n***** PLEASE RERUN FSCK *****\n"); -#if !defined(__minix) - if (hotroot()) { - struct statvfs stfs_buf; - /* - * We modified the root. Do a mount update on - * it, unless it is read-write, so we can continue. - */ - if (statvfs("/", &stfs_buf) == 0) { - long flags = stfs_buf.f_flag; - struct ufs_args args; - - if (flags & MNT_RDONLY) { - args.fspec = 0; - flags |= MNT_UPDATE | MNT_RELOAD; - if (mount(MOUNT_EXT2FS, "/", flags, - &args, sizeof args) == 0) - return FSCK_EXIT_OK; - } - } - if (!preen) - printf("\n***** REBOOT NOW *****\n"); - sync(); - return FSCK_EXIT_ROOT_CHANGED; - } -#endif /* !defined(__minix) */ - return FSCK_EXIT_OK; -} - -static void -usage(void) -{ - - (void) fprintf(stderr, - "usage: %s [-dfnpUy] [-b block] [-c level] [-m mode] filesystem ...\n", - getprogname()); - exit(FSCK_EXIT_USAGE); -} - diff --git a/sbin/fsck_ext2fs/pass1.c b/sbin/fsck_ext2fs/pass1.c deleted file mode 100644 index 31e949cb3..000000000 --- a/sbin/fsck_ext2fs/pass1.c +++ /dev/null @@ -1,395 +0,0 @@ -/* $NetBSD: pass1.c,v 1.24 2013/06/19 17:51:25 dholland Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93"; -#else -__RCSID("$NetBSD: pass1.c,v 1.24 2013/06/19 17:51:25 dholland Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include - -#include /* for IFMT & friends */ - -#include -#include -#include -#include - -#include "fsck.h" -#include "extern.h" -#include "fsutil.h" -#include "exitvalues.h" - -static daddr_t badblk; -static daddr_t dupblk; -static void checkinode(ino_t, struct inodesc *); - -void -pass1(void) -{ - ino_t inumber; - int c, i; - size_t j; - daddr_t dbase; - struct inodesc idesc; - - /* - * Set file system reserved blocks in used block map. - */ - for (c = 0; c < sblock.e2fs_ncg; c++) { - dbase = c * sblock.e2fs.e2fs_bpg + - sblock.e2fs.e2fs_first_dblock; - /* Mark the blocks used for the inode table */ - if (fs2h32(sblock.e2fs_gd[c].ext2bgd_i_tables) >= dbase) { - for (i = 0; i < sblock.e2fs_itpg; i++) - setbmap( - fs2h32(sblock.e2fs_gd[c].ext2bgd_i_tables) - + i); - } - /* Mark the blocks used for the block bitmap */ - if (fs2h32(sblock.e2fs_gd[c].ext2bgd_b_bitmap) >= dbase) - setbmap(fs2h32(sblock.e2fs_gd[c].ext2bgd_b_bitmap)); - /* Mark the blocks used for the inode bitmap */ - if (fs2h32(sblock.e2fs_gd[c].ext2bgd_i_bitmap) >= dbase) - setbmap(fs2h32(sblock.e2fs_gd[c].ext2bgd_i_bitmap)); - - if (sblock.e2fs.e2fs_rev == E2FS_REV0 || - (sblock.e2fs.e2fs_features_rocompat & - EXT2F_ROCOMPAT_SPARSESUPER) == 0 || - cg_has_sb(c)) { - /* Mark copuy of SB and descriptors */ - setbmap(dbase); - for (i = 1; i <= sblock.e2fs_ngdb; i++) - setbmap(dbase+i); - } - - - if (c == 0) { - for(i = 0; i < dbase; i++) - setbmap(i); - } - } - - /* - * Find all allocated blocks. - */ - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = ADDR; - idesc.id_func = pass1check; - inumber = 1; - n_files = n_blks = 0; - resetinodebuf(); - for (c = 0; c < sblock.e2fs_ncg; c++) { - for (j = 0; - j < sblock.e2fs.e2fs_ipg && inumber <= sblock.e2fs.e2fs_icount; - j++, inumber++) { - if (inumber < EXT2_ROOTINO) /* XXX */ - continue; - checkinode(inumber, &idesc); - } - } - freeinodebuf(); -} - -static void -checkinode(ino_t inumber, struct inodesc *idesc) -{ - struct ext2fs_dinode *dp; - struct zlncnt *zlnp; - int ndb, j; - mode_t mode; - - dp = getnextinode(inumber); - if (inumber < EXT2_FIRSTINO && - inumber != EXT2_ROOTINO && - !(inumber == EXT2_RESIZEINO && - (sblock.e2fs.e2fs_features_compat & EXT2F_COMPAT_RESIZE) != 0)) - return; - - mode = fs2h16(dp->e2di_mode) & IFMT; - if (mode == 0 || (dp->e2di_dtime != 0 && dp->e2di_nlink == 0)) { - if (mode == 0 && ( - memcmp(dp->e2di_blocks, zino.e2di_blocks, - (EXT2FS_NDADDR + EXT2FS_NIADDR) * sizeof(u_int32_t)) || - dp->e2di_mode || inosize(dp))) { - pfatal("PARTIALLY ALLOCATED INODE I=%llu", - (unsigned long long)inumber); - if (reply("CLEAR") == 1) { - dp = ginode(inumber); - clearinode(dp); - inodirty(); - } - } -#ifdef notyet /* it seems that dtime == 0 is valid for a unallocated inode */ - if (dp->e2di_dtime == 0) { - pwarn("DELETED INODE I=%llu HAS A NULL DTIME", - (unsigned long long)inumber); - if (preen) { - printf(" (CORRECTED)\n"); - } - if (preen || reply("CORRECT")) { - time_t t; - time(&t); - dp->e2di_dtime = h2fs32(t); - dp = ginode(inumber); - inodirty(); - } - } -#endif - statemap[inumber] = USTATE; - return; - } - lastino = inumber; - if (dp->e2di_dtime != 0) { - pwarn("INODE I=%llu HAS DTIME=%s", - (unsigned long long)inumber, - print_mtime(fs2h32(dp->e2di_dtime))); - if (preen) { - printf(" (CORRECTED)\n"); - } - if (preen || reply("CORRECT")) { - dp = ginode(inumber); - dp->e2di_dtime = 0; - inodirty(); - } - } - if (inosize(dp) + sblock.e2fs_bsize - 1 < inosize(dp)) { - if (debug) - printf("bad size %llu:", (unsigned long long)inosize(dp)); - goto unknown; - } - if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) { - dp = ginode(inumber); - dp->e2di_mode = h2fs16(IFREG|0600); - inossize(dp, sblock.e2fs_bsize); - inodirty(); - } - ndb = howmany(inosize(dp), sblock.e2fs_bsize); - if (ndb < 0) { - if (debug) - printf("bad size %llu ndb %d:", - (unsigned long long)inosize(dp), ndb); - goto unknown; - } - if (mode == IFBLK || mode == IFCHR) - ndb++; - if (mode == IFLNK) { - /* - * Fake ndb value so direct/indirect block checks below - * will detect any garbage after symlink string. - */ - if (inosize(dp) < EXT2_MAXSYMLINKLEN || - (EXT2_MAXSYMLINKLEN == 0 && dp->e2di_blocks == 0)) { - ndb = howmany(inosize(dp), sizeof(u_int32_t)); - if (ndb > EXT2FS_NDADDR) { - j = ndb - EXT2FS_NDADDR; - for (ndb = 1; j > 1; j--) - ndb *= EXT2_NINDIR(&sblock); - ndb += EXT2FS_NDADDR; - } - } - } - /* Linux puts things in blocks for FIFO, so skip this check */ - if (mode != IFIFO) { - for (j = ndb; j < EXT2FS_NDADDR; j++) - if (dp->e2di_blocks[j] != 0) { - if (debug) - printf("bad direct addr: %d\n", - fs2h32(dp->e2di_blocks[j])); - goto unknown; - } - for (j = 0, ndb -= EXT2FS_NDADDR; ndb > 0; j++) - ndb /= EXT2_NINDIR(&sblock); - for (; j < EXT2FS_NIADDR; j++) { - if (dp->e2di_blocks[j+EXT2FS_NDADDR] != 0) { - if (debug) - printf("bad indirect addr: %d\n", - fs2h32(dp->e2di_blocks[j+EXT2FS_NDADDR])); - goto unknown; - } - } - } - if (ftypeok(dp) == 0) - goto unknown; - if (inumber >= EXT2_FIRSTINO || inumber == EXT2_ROOTINO) { - /* Don't count reserved inodes except root */ - n_files++; - } - lncntp[inumber] = fs2h16(dp->e2di_nlink); - if (dp->e2di_nlink == 0) { - zlnp = malloc(sizeof *zlnp); - if (zlnp == NULL) { - pfatal("LINK COUNT TABLE OVERFLOW"); - if (reply("CONTINUE") == 0) - exit(FSCK_EXIT_CHECK_FAILED); - } else { - zlnp->zlncnt = inumber; - zlnp->next = zlnhead; - zlnhead = zlnp; - } - } - if (mode == IFDIR) { - if (inosize(dp) == 0) - statemap[inumber] = DCLEAR; - else - statemap[inumber] = DSTATE; - cacheino(dp, inumber); - } else { - statemap[inumber] = FSTATE; - } - typemap[inumber] = E2IFTODT(mode); - badblk = dupblk = 0; - idesc->id_number = inumber; - (void)ckinode(dp, idesc); - idesc->id_entryno *= btodb(sblock.e2fs_bsize); - if (inonblock(dp) != (uint32_t)idesc->id_entryno) { - pwarn("INCORRECT BLOCK COUNT I=%llu (%llu should be %d)", - (unsigned long long)inumber, - (unsigned long long)inonblock(dp), - idesc->id_entryno); - if (preen) - printf(" (CORRECTED)\n"); - else if (reply("CORRECT") == 0) - return; - dp = ginode(inumber); - inosnblock(dp, idesc->id_entryno); - inodirty(); - } - return; -unknown: - pfatal("UNKNOWN FILE TYPE I=%llu", (unsigned long long)inumber); - statemap[inumber] = FCLEAR; - if (reply("CLEAR") == 1) { - statemap[inumber] = USTATE; - dp = ginode(inumber); - clearinode(dp); - inodirty(); - } -} - -int -pass1check(struct inodesc *idesc) -{ - int res = KEEPON; - int anyout, nfrags; - daddr_t blkno = idesc->id_blkno; - struct dups *dlp; - struct dups *new; - - if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) { - blkerror(idesc->id_number, "BAD", blkno); - if (badblk++ >= MAXBAD) { - pwarn("EXCESSIVE BAD BLKS I=%llu", - (unsigned long long)idesc->id_number); - if (preen) - printf(" (SKIPPING)\n"); - else if (reply("CONTINUE") == 0) - exit(FSCK_EXIT_CHECK_FAILED); - return (STOP); - } - } - for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { - if (anyout && chkrange(blkno, 1)) { - res = SKIP; - } else if (!testbmap(blkno)) { - n_blks++; - setbmap(blkno); - } else { - blkerror(idesc->id_number, "DUP", blkno); - if (dupblk++ >= MAXDUP) { - pwarn("EXCESSIVE DUP BLKS I=%llu", - (unsigned long long)idesc->id_number); - if (preen) - printf(" (SKIPPING)\n"); - else if (reply("CONTINUE") == 0) - exit(FSCK_EXIT_CHECK_FAILED); - return (STOP); - } - new = malloc(sizeof(struct dups)); - if (new == NULL) { - pfatal("DUP TABLE OVERFLOW."); - if (reply("CONTINUE") == 0) - exit(FSCK_EXIT_CHECK_FAILED); - return (STOP); - } - new->dup = blkno; - 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 == blkno) - break; - if (dlp == muldup && dlp->dup != blkno) - muldup = new; - } - /* - * count the number of blocks found in id_entryno - */ - idesc->id_entryno++; - } - return (res); -} diff --git a/sbin/fsck_ext2fs/pass1b.c b/sbin/fsck_ext2fs/pass1b.c deleted file mode 100644 index 31b1d3e26..000000000 --- a/sbin/fsck_ext2fs/pass1b.c +++ /dev/null @@ -1,130 +0,0 @@ -/* $NetBSD: pass1b.c,v 1.8 2009/10/19 18:41:08 bouyer Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)pass1b.c 8.1 (Berkeley) 6/5/93"; -#else -__RCSID("$NetBSD: pass1b.c,v 1.8 2009/10/19 18:41:08 bouyer Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include - -#include -#include "fsck.h" -#include "extern.h" - -static int pass1bcheck(struct inodesc *); -static struct dups *duphead; - -void -pass1b(void) -{ - int c; - uint32_t i; - struct ext2fs_dinode *dp; - struct inodesc idesc; - ino_t inumber; - - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = ADDR; - idesc.id_func = pass1bcheck; - duphead = duplist; - inumber = 0; - for (c = 0; c < sblock.e2fs_ncg; c++) { - for (i = 0; i < sblock.e2fs.e2fs_ipg; i++, inumber++) { - if ((inumber < EXT2_FIRSTINO) && (inumber != EXT2_ROOTINO)) - continue; - dp = ginode(inumber); - if (dp == NULL) - continue; - idesc.id_number = inumber; - if (statemap[inumber] != USTATE && - (ckinode(dp, &idesc) & STOP)) - return; - } - } -} - -static int -pass1bcheck(struct inodesc *idesc) -{ - struct dups *dlp; - int nfrags, res = KEEPON; - daddr_t blkno = idesc->id_blkno; - - for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { - if (chkrange(blkno, 1)) - res = SKIP; - for (dlp = duphead; dlp; dlp = dlp->next) { - if (dlp->dup == blkno) { - blkerror(idesc->id_number, "DUP", blkno); - dlp->dup = duphead->dup; - duphead->dup = blkno; - duphead = duphead->next; - } - if (dlp == muldup) - break; - } - if (muldup == 0 || duphead == muldup->next) - return (STOP); - } - return (res); -} diff --git a/sbin/fsck_ext2fs/pass2.c b/sbin/fsck_ext2fs/pass2.c deleted file mode 100644 index 01f0aa589..000000000 --- a/sbin/fsck_ext2fs/pass2.c +++ /dev/null @@ -1,470 +0,0 @@ -/* $NetBSD: pass2.c,v 1.15 2009/10/19 18:41:08 bouyer Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)pass2.c 8.6 (Berkeley) 10/27/94"; -#else -__RCSID("$NetBSD: pass2.c,v 1.15 2009/10/19 18:41:08 bouyer Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include - -#include /* for IFMT & friends */ - -#include -#include -#include - -#include "fsck.h" -#include "fsutil.h" -#include "extern.h" -#include "exitvalues.h" - -#define MINDIRSIZE (sizeof (struct ext2fs_dirtemplate)) - -static int pass2check(struct inodesc *); -static int blksort(const void *, const void *); - -void -pass2(void) -{ - struct ext2fs_dinode *dp; - struct inoinfo **inpp, *inp; - struct inoinfo **inpend; - struct inodesc curino; - struct ext2fs_dinode dino; - char pathbuf[MAXPATHLEN + 1]; - - switch (statemap[EXT2_ROOTINO]) { - - case USTATE: - pfatal("ROOT INODE UNALLOCATED"); - if (reply("ALLOCATE") == 0) - exit(FSCK_EXIT_CHECK_FAILED); - if (allocdir(EXT2_ROOTINO, EXT2_ROOTINO, 0755) != EXT2_ROOTINO) - errexit("CANNOT ALLOCATE ROOT INODE"); - break; - - case DCLEAR: - pfatal("DUPS/BAD IN ROOT INODE"); - if (reply("REALLOCATE")) { - freeino(EXT2_ROOTINO); - if (allocdir(EXT2_ROOTINO, EXT2_ROOTINO, 0755) != EXT2_ROOTINO) - errexit("CANNOT ALLOCATE ROOT INODE"); - break; - } - if (reply("CONTINUE") == 0) - exit(FSCK_EXIT_CHECK_FAILED); - break; - - case FSTATE: - case FCLEAR: - pfatal("ROOT INODE NOT DIRECTORY"); - if (reply("REALLOCATE")) { - freeino(EXT2_ROOTINO); - if (allocdir(EXT2_ROOTINO, EXT2_ROOTINO, 0755) != EXT2_ROOTINO) - errexit("CANNOT ALLOCATE ROOT INODE"); - break; - } - if (reply("FIX") == 0) - exit(FSCK_EXIT_CHECK_FAILED); - dp = ginode(EXT2_ROOTINO); - dp->e2di_mode = h2fs16((fs2h16(dp->e2di_mode) & ~IFMT) | IFDIR); - inodirty(); - break; - - case DSTATE: - break; - - default: - errexit("BAD STATE %d FOR ROOT INODE", statemap[EXT2_ROOTINO]); - } - - /* - * Sort the directory list into disk block order. - */ - qsort((char *)inpsort, (size_t)inplast, sizeof *inpsort, blksort); - /* - * Check the integrity of each directory. - */ - memset(&curino, 0, sizeof(struct inodesc)); - curino.id_type = DATA; - curino.id_func = pass2check; - inpend = &inpsort[inplast]; - for (inpp = inpsort; inpp < inpend; inpp++) { - inp = *inpp; - if (inp->i_isize == 0) - continue; - if (inp->i_isize < MINDIRSIZE) { - direrror(inp->i_number, "DIRECTORY TOO SHORT"); - inp->i_isize = roundup(MINDIRSIZE, sblock.e2fs_bsize); - if (reply("FIX") == 1) { - dp = ginode(inp->i_number); - inossize(dp, inp->i_isize); - inodirty(); - } - } else if ((inp->i_isize & (sblock.e2fs_bsize - 1)) != 0) { - getpathname(pathbuf, sizeof(pathbuf), inp->i_number, - inp->i_number); - pwarn("DIRECTORY %s: LENGTH %lu NOT MULTIPLE OF %d", - pathbuf, (u_long)inp->i_isize, sblock.e2fs_bsize); - if (preen) - printf(" (ADJUSTED)\n"); - inp->i_isize = roundup(inp->i_isize, sblock.e2fs_bsize); - if (preen || reply("ADJUST") == 1) { - dp = ginode(inp->i_number); - inossize(dp, inp->i_isize); - inodirty(); - } - } - memset(&dino, 0, sizeof(struct ext2fs_dinode)); - dino.e2di_mode = h2fs16(IFDIR); - inossize(&dino, inp->i_isize); - memcpy(&dino.e2di_blocks[0], &inp->i_blks[0], (size_t)inp->i_numblks); - curino.id_number = inp->i_number; - curino.id_parent = inp->i_parent; - (void)ckinode(&dino, &curino); - } - /* - * Now that the parents of all directories have been found, - * make another pass to verify the value of `..' - */ - for (inpp = inpsort; inpp < inpend; inpp++) { - inp = *inpp; - if (inp->i_parent == 0 || inp->i_isize == 0) - continue; - if (inp->i_dotdot == inp->i_parent || - inp->i_dotdot == (ino_t)-1) - continue; - if (inp->i_dotdot == 0) { - inp->i_dotdot = inp->i_parent; - fileerror(inp->i_parent, inp->i_number, "MISSING '..'"); - if (reply("FIX") == 0) - continue; - (void)makeentry(inp->i_number, inp->i_parent, ".."); - lncntp[inp->i_parent]--; - continue; - } - fileerror(inp->i_parent, inp->i_number, - "BAD INODE NUMBER FOR '..'"); - if (reply("FIX") == 0) - continue; - lncntp[inp->i_dotdot]++; - lncntp[inp->i_parent]--; - inp->i_dotdot = inp->i_parent; - (void)changeino(inp->i_number, "..", inp->i_parent); - } - /* - * Mark all the directories that can be found from the root. - */ - propagate(); -} - -static int -pass2check(struct inodesc *idesc) -{ - struct ext2fs_direct *dirp = idesc->id_dirp; - struct inoinfo *inp; - int n, entrysize, ret = 0; - struct ext2fs_dinode *dp; - const char *errmsg; - struct ext2fs_direct proto; - char namebuf[MAXPATHLEN + 1]; - char pathbuf[MAXPATHLEN + 1]; - - /* - * check for "." - */ - if (idesc->id_entryno != 0) - goto chk1; - if (fs2h32(dirp->e2d_ino) != 0 && dirp->e2d_namlen == 1 && - dirp->e2d_name[0] == '.') { - if (fs2h32(dirp->e2d_ino) != idesc->id_number) { - direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'"); - dirp->e2d_ino = h2fs32(idesc->id_number); - if (reply("FIX") == 1) - ret |= ALTERED; - } - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE) - && (dirp->e2d_type != EXT2_FT_DIR)) { - direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'"); - dirp->e2d_type = EXT2_FT_DIR; - if (reply("FIX") == 1) - ret |= ALTERED; - } - goto chk1; - } - direrror(idesc->id_number, "MISSING '.'"); - proto.e2d_ino = h2fs32(idesc->id_number); - proto.e2d_namlen = 1; - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) - proto.e2d_type = EXT2_FT_DIR; - else - proto.e2d_type = 0; - (void)strlcpy(proto.e2d_name, ".", sizeof(proto.e2d_name)); - entrysize = EXT2FS_DIRSIZ(proto.e2d_namlen); - if (fs2h32(dirp->e2d_ino) != 0 && strcmp(dirp->e2d_name, "..") != 0) { - pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n", - dirp->e2d_name); - } else if (fs2h16(dirp->e2d_reclen) < entrysize) { - pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n"); - } else if (fs2h16(dirp->e2d_reclen) < 2 * entrysize) { - proto.e2d_reclen = dirp->e2d_reclen; - memcpy(dirp, &proto, (size_t)entrysize); - if (reply("FIX") == 1) - ret |= ALTERED; - } else { - n = fs2h16(dirp->e2d_reclen) - entrysize; - proto.e2d_reclen = h2fs16(entrysize); - memcpy(dirp, &proto, (size_t)entrysize); - idesc->id_entryno++; - lncntp[fs2h32(dirp->e2d_ino)]--; - dirp = (struct ext2fs_direct *)((char *)(dirp) + entrysize); - memset(dirp, 0, (size_t)n); - dirp->e2d_reclen = h2fs16(n); - if (reply("FIX") == 1) - ret |= ALTERED; - } -chk1: - if (idesc->id_entryno > 1) - goto chk2; - inp = getinoinfo(idesc->id_number); - proto.e2d_ino = h2fs32(inp->i_parent); - proto.e2d_namlen = 2; - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) - proto.e2d_type = EXT2_FT_DIR; - else - proto.e2d_type = 0; - (void)strlcpy(proto.e2d_name, "..", sizeof(proto.e2d_name)); - entrysize = EXT2FS_DIRSIZ(2); - if (idesc->id_entryno == 0) { - n = EXT2FS_DIRSIZ(dirp->e2d_namlen); - if (fs2h16(dirp->e2d_reclen) < n + entrysize) - goto chk2; - proto.e2d_reclen = h2fs16(fs2h16(dirp->e2d_reclen) - n); - dirp->e2d_reclen = h2fs16(n); - idesc->id_entryno++; - lncntp[fs2h32(dirp->e2d_ino)]--; - dirp = (struct ext2fs_direct *)((char *)(dirp) + n); - memset(dirp, 0, (size_t)fs2h16(proto.e2d_reclen)); - dirp->e2d_reclen = proto.e2d_reclen; - } - if (fs2h32(dirp->e2d_ino) != 0 && - dirp->e2d_namlen == 2 && - strncmp(dirp->e2d_name, "..", 2) == 0) { - inp->i_dotdot = fs2h32(dirp->e2d_ino); - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE) - && dirp->e2d_type != EXT2_FT_DIR) { - direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'"); - dirp->e2d_type = EXT2_FT_DIR; - if (reply("FIX") == 1) - ret |= ALTERED; - } - goto chk2; - } - if (fs2h32(dirp->e2d_ino) != 0 && - dirp->e2d_namlen == 1 && - strncmp(dirp->e2d_name, ".", 1) != 0) { - fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); - pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n", - dirp->e2d_name); - inp->i_dotdot = (ino_t)-1; - } else if (fs2h16(dirp->e2d_reclen) < entrysize) { - fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); - pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n"); - inp->i_dotdot = (ino_t)-1; - } else if (inp->i_parent != 0) { - /* - * We know the parent, so fix now. - */ - inp->i_dotdot = inp->i_parent; - fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); - proto.e2d_reclen = dirp->e2d_reclen; - memcpy(dirp, &proto, (size_t)entrysize); - if (reply("FIX") == 1) - ret |= ALTERED; - } - idesc->id_entryno++; - if (fs2h32(dirp->e2d_ino) != 0) - lncntp[fs2h32(dirp->e2d_ino)]--; - return (ret|KEEPON); -chk2: - if (fs2h32(dirp->e2d_ino) == 0) - return (ret|KEEPON); - if (dirp->e2d_namlen <= 2 && - dirp->e2d_name[0] == '.' && - idesc->id_entryno >= 2) { - if (dirp->e2d_namlen == 1) { - direrror(idesc->id_number, "EXTRA '.' ENTRY"); - dirp->e2d_ino = 0; - if (reply("FIX") == 1) - ret |= ALTERED; - return (KEEPON | ret); - } - if (dirp->e2d_name[1] == '.') { - direrror(idesc->id_number, "EXTRA '..' ENTRY"); - dirp->e2d_ino = 0; - if (reply("FIX") == 1) - ret |= ALTERED; - return (KEEPON | ret); - } - } - idesc->id_entryno++; - n = 0; - if (fs2h32(dirp->e2d_ino) > maxino || - (fs2h32(dirp->e2d_ino) < EXT2_FIRSTINO && - fs2h32(dirp->e2d_ino) != EXT2_ROOTINO)) { - fileerror(idesc->id_number, fs2h32(dirp->e2d_ino), "I OUT OF RANGE"); - n = reply("REMOVE"); - } else { -again: - switch (statemap[fs2h32(dirp->e2d_ino)]) { - case USTATE: - if (idesc->id_entryno <= 2) - break; - fileerror(idesc->id_number, fs2h32(dirp->e2d_ino), "UNALLOCATED"); - n = reply("REMOVE"); - break; - - case DCLEAR: - case FCLEAR: - if (idesc->id_entryno <= 2) - break; - if (statemap[fs2h32(dirp->e2d_ino)] == FCLEAR) - errmsg = "DUP/BAD"; - else if (!preen) - errmsg = "ZERO LENGTH DIRECTORY"; - else { - n = 1; - break; - } - fileerror(idesc->id_number, fs2h32(dirp->e2d_ino), errmsg); - if ((n = reply("REMOVE")) == 1) - break; - dp = ginode(fs2h32(dirp->e2d_ino)); - statemap[fs2h32(dirp->e2d_ino)] = - (fs2h16(dp->e2di_mode) & IFMT) == IFDIR ? DSTATE : FSTATE; - lncntp[fs2h32(dirp->e2d_ino)] = fs2h16(dp->e2di_nlink); - goto again; - - case DSTATE: - case DFOUND: - inp = getinoinfo(fs2h32(dirp->e2d_ino)); - if (inp->i_parent != 0 && idesc->id_entryno > 2) { - getpathname(pathbuf, sizeof(pathbuf), - idesc->id_number, idesc->id_number); - getpathname(namebuf, sizeof(namebuf), - fs2h32(dirp->e2d_ino), - fs2h32(dirp->e2d_ino)); - pwarn("%s %s %s\n", pathbuf, - "IS AN EXTRANEOUS HARD LINK TO DIRECTORY", - namebuf); - if (preen) - printf(" (IGNORED)\n"); - else if ((n = reply("REMOVE")) == 1) - break; - } - if (idesc->id_entryno > 2) - inp->i_parent = idesc->id_number; - /* fall through */ - - case FSTATE: - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_incompat & - EXT2F_INCOMPAT_FTYPE) && - dirp->e2d_type != - inot2ext2dt(typemap[fs2h32(dirp->e2d_ino)])) { - dirp->e2d_type = - inot2ext2dt(typemap[fs2h32(dirp->e2d_ino)]); - fileerror(idesc->id_number, - fs2h32(dirp->e2d_ino), - "BAD TYPE VALUE"); - if (reply("FIX") == 1) - ret |= ALTERED; - } - lncntp[fs2h32(dirp->e2d_ino)]--; - break; - - default: - errexit("BAD STATE %d FOR INODE I=%d", - statemap[fs2h32(dirp->e2d_ino)], fs2h32(dirp->e2d_ino)); - } - } - if (n == 0) - return (ret|KEEPON); - dirp->e2d_ino = 0; - return (ret|KEEPON|ALTERED); -} - -/* - * Routine to sort disk blocks. - */ -static int -blksort(const void *inpp1, const void *inpp2) -{ - return ((* (const struct inoinfo * const*) inpp1)->i_blks[0] - - (* (const struct inoinfo * const*) inpp2)->i_blks[0]); -} diff --git a/sbin/fsck_ext2fs/pass3.c b/sbin/fsck_ext2fs/pass3.c deleted file mode 100644 index bc19338c9..000000000 --- a/sbin/fsck_ext2fs/pass3.c +++ /dev/null @@ -1,100 +0,0 @@ -/* $NetBSD: pass3.c,v 1.7 2009/10/19 18:41:08 bouyer Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)pass3.c 8.1 (Berkeley) 6/5/93"; -#else -__RCSID("$NetBSD: pass3.c,v 1.7 2009/10/19 18:41:08 bouyer Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include "fsck.h" -#include "extern.h" - -void -pass3(void) -{ - struct inoinfo **inpp, *inp; - ino_t orphan; - int loopcnt; - - for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--) { - inp = *inpp; - if (inp->i_number == EXT2_ROOTINO || - !(inp->i_parent == 0 || statemap[inp->i_number] == DSTATE)) - continue; - if (statemap[inp->i_number] == DCLEAR) - continue; - for (loopcnt = 0; ; loopcnt++) { - orphan = inp->i_number; - if (inp->i_parent == 0 || - statemap[inp->i_parent] != DSTATE || - loopcnt > numdirs) - break; - inp = getinoinfo(inp->i_parent); - } - (void)linkup(orphan, inp->i_dotdot); - inp->i_parent = inp->i_dotdot = lfdir; - lncntp[lfdir]--; - statemap[orphan] = DFOUND; - propagate(); - } -} diff --git a/sbin/fsck_ext2fs/pass4.c b/sbin/fsck_ext2fs/pass4.c deleted file mode 100644 index f184e38ec..000000000 --- a/sbin/fsck_ext2fs/pass4.c +++ /dev/null @@ -1,164 +0,0 @@ -/* $NetBSD: pass4.c,v 1.10 2009/10/19 18:41:08 bouyer Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)pass4.c 8.1 (Berkeley) 6/5/93"; -#else -__RCSID("$NetBSD: pass4.c,v 1.10 2009/10/19 18:41:08 bouyer Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include - -#include "fsutil.h" -#include "fsck.h" -#include "extern.h" - -void -pass4(void) -{ - ino_t inumber; - struct zlncnt *zlnp; - struct ext2fs_dinode *dp; - struct inodesc idesc; - int n; - - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = ADDR; - idesc.id_func = pass4check; - for (inumber = EXT2_ROOTINO; inumber <= lastino; inumber++) { - if (inumber < EXT2_FIRSTINO && inumber > EXT2_ROOTINO) - continue; - idesc.id_number = inumber; - switch (statemap[inumber]) { - - case FSTATE: - case DFOUND: - n = lncntp[inumber]; - if (n) - adjust(&idesc, (short)n); - else { - for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) - if (zlnp->zlncnt == inumber) { - zlnp->zlncnt = zlnhead->zlncnt; - zlnp = zlnhead; - zlnhead = zlnhead->next; - free((char *)zlnp); - clri(&idesc, "UNREF", 1); - break; - } - } - break; - - case DSTATE: - clri(&idesc, "UNREF", 1); - break; - - case DCLEAR: - dp = ginode(inumber); - if (inosize(dp) == 0) { - clri(&idesc, "ZERO LENGTH", 1); - break; - } - /* fall through */ - case FCLEAR: - clri(&idesc, "BAD/DUP", 1); - break; - - case USTATE: - break; - - default: - errexit("BAD STATE %d FOR INODE I=%llu", - statemap[inumber], (unsigned long long)inumber); - } - } -} - -int -pass4check(struct inodesc *idesc) -{ - struct dups *dlp; - int nfrags, res = KEEPON; - daddr_t blkno = idesc->id_blkno; - - for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { - if (chkrange(blkno, 1)) { - res = SKIP; - } else if (testbmap(blkno)) { - for (dlp = duplist; dlp; dlp = dlp->next) { - if (dlp->dup != blkno) - continue; - dlp->dup = duplist->dup; - dlp = duplist; - duplist = duplist->next; - free((char *)dlp); - break; - } - if (dlp == 0) { - clrbmap(blkno); - n_blks--; - } - } - } - return (res); -} diff --git a/sbin/fsck_ext2fs/pass5.c b/sbin/fsck_ext2fs/pass5.c deleted file mode 100644 index 8ce1085c8..000000000 --- a/sbin/fsck_ext2fs/pass5.c +++ /dev/null @@ -1,277 +0,0 @@ -/* $NetBSD: pass5.c,v 1.20 2012/08/26 09:33:18 dholland Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)pass5.c 8.6 (Berkeley) 11/30/94"; -#else -__RCSID("$NetBSD: pass5.c,v 1.20 2012/08/26 09:33:18 dholland Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fsutil.h" -#include "fsck.h" -#include "extern.h" - - -static void print_bmap(char *, uint32_t); - -void -pass5(void) -{ - int c; - struct m_ext2fs *fs = &sblock; - daddr_t dbase, dmax; - daddr_t d; - uint32_t i, j; - struct inodesc idesc[3]; - struct bufarea *ino_bitmap = NULL, *blk_bitmap = NULL; - char *ibmap, *bbmap; - u_int32_t cs_ndir, cs_nbfree, cs_nifree; - char msg[255]; - - cs_ndir = 0; - cs_nbfree = 0; - cs_nifree = 0; - - ibmap = malloc(fs->e2fs_bsize); - bbmap = malloc(fs->e2fs_bsize); - if (ibmap == NULL || bbmap == NULL) { - errexit("out of memory"); - } - - for (c = 0; c < fs->e2fs_ncg; c++) { - u_int32_t nbfree = 0; - u_int32_t nifree = 0; - u_int32_t ndirs = 0; - - nbfree = 0; - nifree = fs->e2fs.e2fs_ipg; - ndirs = 0; - - if (blk_bitmap == NULL) { - blk_bitmap = getdatablk(fs2h32(fs->e2fs_gd[c].ext2bgd_b_bitmap), - fs->e2fs_bsize); - } else { - getblk(blk_bitmap, fs2h32(fs->e2fs_gd[c].ext2bgd_b_bitmap), - fs->e2fs_bsize); - } - if (ino_bitmap == NULL) { - ino_bitmap = getdatablk(fs2h32(fs->e2fs_gd[c].ext2bgd_i_bitmap), - fs->e2fs_bsize); - } else { - getblk(ino_bitmap, fs2h32(fs->e2fs_gd[c].ext2bgd_i_bitmap), - fs->e2fs_bsize); - } - memset(bbmap, 0, fs->e2fs_bsize); - memset(ibmap, 0, fs->e2fs_bsize); - memset(&idesc[0], 0, sizeof idesc); - for (i = 0; i < 3; i++) { - idesc[i].id_type = ADDR; - } - - j = fs->e2fs.e2fs_ipg * c + 1; - - for (i = 0; i < fs->e2fs.e2fs_ipg; j++, i++) { - if ((j < EXT2_FIRSTINO) && (j != EXT2_ROOTINO)) { - setbit(ibmap, i); - nifree--; - continue; - } - if (j > fs->e2fs.e2fs_icount) { - setbit(ibmap, i); - continue; - } - switch (statemap[j]) { - - case USTATE: - break; - - case DSTATE: - case DCLEAR: - case DFOUND: - ndirs++; - /* fall through */ - - case FSTATE: - case FCLEAR: - nifree--; - setbit(ibmap, i); - break; - - default: - errexit("BAD STATE %d FOR INODE I=%"PRIu32, - statemap[j], j); - } - } - - /* fill in unused par of the inode map */ - for (i = fs->e2fs.e2fs_ipg / NBBY; i < (uint32_t)fs->e2fs_bsize; i++) - ibmap[i] = 0xff; - - dbase = c * sblock.e2fs.e2fs_bpg + - sblock.e2fs.e2fs_first_dblock; - dmax = (c+1) * sblock.e2fs.e2fs_bpg + - sblock.e2fs.e2fs_first_dblock; - - for (i = 0, d = dbase; - d < dmax; - d ++, i ++) { - if (testbmap(d) || d >= sblock.e2fs.e2fs_bcount) { - setbit(bbmap, i); - continue; - } else { - nbfree++; - } - - } - cs_nbfree += nbfree; - cs_nifree += nifree; - cs_ndir += ndirs; - - if (debug && (fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree || - fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree || - fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs)) { - printf("summary info for cg %d is %d, %d, %d," - "should be %d, %d, %d\n", c, - fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree), - fs2h16(fs->e2fs_gd[c].ext2bgd_nifree), - fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs), - nbfree, - nifree, - ndirs); - } - (void)snprintf(msg, sizeof(msg), - "SUMMARY INFORMATIONS WRONG FOR CG #%d", c); - if ((fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree || - fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree || - fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs) && - dofix(&idesc[0], msg)) { - fs->e2fs_gd[c].ext2bgd_nbfree = h2fs16(nbfree); - fs->e2fs_gd[c].ext2bgd_nifree = h2fs16(nifree); - fs->e2fs_gd[c].ext2bgd_ndirs = h2fs16(ndirs); - sbdirty(); - } - - if (debug && memcmp(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize)) { - printf("blk_bitmap:\n"); - print_bmap(blk_bitmap->b_un.b_buf, fs->e2fs_bsize); - printf("bbmap:\n"); - print_bmap(bbmap, fs->e2fs_bsize); - } - - (void)snprintf(msg, sizeof(msg), - "BLK(S) MISSING IN BIT MAPS #%d", c); - if (memcmp(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize) && - dofix(&idesc[1], msg)) { - memcpy(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize); - dirty(blk_bitmap); - } - if (debug && memcmp(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize)) { - printf("ino_bitmap:\n"); - print_bmap(ino_bitmap->b_un.b_buf, fs->e2fs_bsize); - printf("ibmap:\n"); - print_bmap(ibmap, fs->e2fs_bsize); - } - (void)snprintf(msg, sizeof(msg), - "INODE(S) MISSING IN BIT MAPS #%d", c); - if (memcmp(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize) && - dofix(&idesc[1], msg)) { - memcpy(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize); - dirty(ino_bitmap); - } - - } - if (debug && (fs->e2fs.e2fs_fbcount != cs_nbfree || - fs->e2fs.e2fs_ficount != cs_nifree)) { - printf("summary info bad in superblock: %d, %d should be %d, %d\n", - fs->e2fs.e2fs_fbcount, fs->e2fs.e2fs_ficount, - cs_nbfree, cs_nifree); - } - if ((fs->e2fs.e2fs_fbcount != cs_nbfree || - fs->e2fs.e2fs_ficount != cs_nifree) - && dofix(&idesc[0], "SUPERBLK SUMMARY INFORMATION BAD")) { - fs->e2fs.e2fs_fbcount = cs_nbfree; - fs->e2fs.e2fs_ficount = cs_nifree; - sbdirty(); - } - free(ibmap); - free(bbmap); -} - -static void -print_bmap(char *map, uint32_t size) -{ - uint32_t i, j; - - i = 0; - while (i < size) { - printf("%04x: ",i); - for (j = 0; j < 16; j++, i++) - printf("%02x ", (unsigned char)map[i] & 0xff); - printf("\n"); - } -} diff --git a/sbin/fsck_ext2fs/setup.c b/sbin/fsck_ext2fs/setup.c deleted file mode 100644 index 47c8fa815..000000000 --- a/sbin/fsck_ext2fs/setup.c +++ /dev/null @@ -1,557 +0,0 @@ -/* $NetBSD: setup.c,v 1.32 2014/12/04 01:41:37 christos Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94"; -#else -__RCSID("$NetBSD: setup.c,v 1.32 2014/12/04 01:41:37 christos Exp $"); -#endif -#endif /* not lint */ - -#define FSTYPENAMES -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "fsck.h" -#include "extern.h" -#include "fsutil.h" -#include "exitvalues.h" - -void badsb(int, const char *); -int calcsb(const char *, int, struct m_ext2fs *); -static struct disklabel *getdisklabel(const char *, int); -static int readsb(int); - -int -setup(const char *dev) -{ - long cg, asked, i; - long bmapsize; - struct disklabel *lp; - off_t sizepb; - struct stat statb; - struct m_ext2fs proto; - int doskipclean; - u_int64_t maxfilesize; - - havesb = 0; - fswritefd = -1; - doskipclean = skipclean; - if (stat(dev, &statb) < 0) { - printf("Can't stat %s: %s\n", dev, strerror(errno)); - return 0; - } -#if !defined(__minix) - if (!S_ISCHR(statb.st_mode)) { - pfatal("%s is not a character device", dev); - if (reply("CONTINUE") == 0) - return 0; - } -#endif /* !defined(__minix) */ - if ((fsreadfd = open(dev, O_RDONLY)) < 0) { - printf("Can't open %s: %s\n", dev, strerror(errno)); - return 0; - } - if (preen == 0) - printf("** %s", dev); - if (nflag || (fswritefd = open(dev, O_WRONLY)) < 0) { - fswritefd = -1; - if (preen) - pfatal("NO WRITE ACCESS"); - printf(" (NO WRITE)"); - } - if (preen == 0) - printf("\n"); - fsmodified = 0; - lfdir = 0; - initbarea(&sblk); - initbarea(&asblk); - sblk.b_un.b_buf = malloc(SBSIZE); - asblk.b_un.b_buf = malloc(SBSIZE); - if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL) - errexit("cannot allocate space for superblock"); - if ((lp = getdisklabel(NULL, fsreadfd)) != NULL) - dev_bsize = secsize = lp->d_secsize; - else - dev_bsize = secsize = DEV_BSIZE; - /* - * Read in the superblock, looking for alternates if necessary - */ - if (readsb(1) == 0) { - if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0) - return 0; - if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0) - return 0; - for (cg = 1; cg < proto.e2fs_ncg; cg++) { - bflag = EXT2_FSBTODB(&proto, - cg * proto.e2fs.e2fs_bpg + - proto.e2fs.e2fs_first_dblock); - if (readsb(0) != 0) - break; - } - if (cg >= proto.e2fs_ncg) { - printf("%s %s\n%s %s\n%s %s\n", - "SEARCH FOR ALTERNATE SUPER-BLOCK", - "FAILED. YOU MUST USE THE", - "-b OPTION TO FSCK_FFS TO SPECIFY THE", - "LOCATION OF AN ALTERNATE", - "SUPER-BLOCK TO SUPPLY NEEDED", - "INFORMATION; SEE fsck_ext2fs(8)."); - return 0; - } - doskipclean = 0; - pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag); - } - if (debug) - printf("state = %d\n", sblock.e2fs.e2fs_state); - if (sblock.e2fs.e2fs_state == E2FS_ISCLEAN) { - if (doskipclean) { - pwarn("%sile system is clean; not checking\n", - preen ? "f" : "** F"); - return -1; - } - if (!preen) - pwarn("** File system is already clean\n"); - } - maxfsblock = sblock.e2fs.e2fs_bcount; - maxino = sblock.e2fs_ncg * sblock.e2fs.e2fs_ipg; - sizepb = sblock.e2fs_bsize; - maxfilesize = sblock.e2fs_bsize * EXT2FS_NDADDR - 1; - for (i = 0; i < EXT2FS_NIADDR; i++) { - sizepb *= EXT2_NINDIR(&sblock); - maxfilesize += sizepb; - } - /* - * Check and potentially fix certain fields in the super block. - */ - if (/* (sblock.e2fs.e2fs_rbcount < 0) || */ - (sblock.e2fs.e2fs_rbcount > sblock.e2fs.e2fs_bcount)) { - pfatal("IMPOSSIBLE RESERVED BLOCK COUNT=%d IN SUPERBLOCK", - sblock.e2fs.e2fs_rbcount); - if (reply("SET TO DEFAULT") == 1) { - sblock.e2fs.e2fs_rbcount = - sblock.e2fs.e2fs_bcount * MINFREE / 100; - sbdirty(); - dirty(&asblk); - } - } - if (sblock.e2fs.e2fs_bpg != sblock.e2fs.e2fs_fpg) { - pfatal("WRONG FPG=%d (BPG=%d) IN SUPERBLOCK", - sblock.e2fs.e2fs_fpg, sblock.e2fs.e2fs_bpg); - return 0; - } - if (asblk.b_dirty && !bflag) { - copyback_sb(&asblk); - flush(fswritefd, &asblk); - } - /* - * read in the summary info. - */ - - sblock.e2fs_gd = malloc(sblock.e2fs_ngdb * sblock.e2fs_bsize); - if (sblock.e2fs_gd == NULL) - errexit("out of memory"); - asked = 0; - for (i = 0; i < sblock.e2fs_ngdb; i++) { - if (bread(fsreadfd, - (char *)&sblock.e2fs_gd[i * sblock.e2fs_bsize / - sizeof(struct ext2_gd)], - EXT2_FSBTODB(&sblock, ((sblock.e2fs_bsize > 1024) ? 0 : 1) + - i + 1), - sblock.e2fs_bsize) != 0 && !asked) { - pfatal("BAD SUMMARY INFORMATION"); - if (reply("CONTINUE") == 0) - exit(FSCK_EXIT_CHECK_FAILED); - asked++; - } - } - /* - * allocate and initialize the necessary maps - */ - bmapsize = roundup(howmany(maxfsblock, NBBY), sizeof(int16_t)); - blockmap = calloc((unsigned int)bmapsize, sizeof(char)); - if (blockmap == NULL) { - printf("cannot alloc %u bytes for blockmap\n", - (unsigned int)bmapsize); - goto badsblabel; - } - statemap = calloc((unsigned int)(maxino + 2), sizeof(char)); - if (statemap == NULL) { - printf("cannot alloc %u bytes for statemap\n", - (unsigned int)(maxino + 1)); - goto badsblabel; - } - typemap = calloc((unsigned int)(maxino + 1), sizeof(char)); - if (typemap == NULL) { - printf("cannot alloc %u bytes for typemap\n", - (unsigned int)(maxino + 1)); - goto badsblabel; - } - lncntp = calloc((unsigned)(maxino + 1), sizeof(int16_t)); - if (lncntp == NULL) { - printf("cannot alloc %u bytes for lncntp\n", - (unsigned int)((maxino + 1) * sizeof(int16_t))); - goto badsblabel; - } - for (numdirs = 0, cg = 0; cg < sblock.e2fs_ncg; cg++) { - numdirs += fs2h16(sblock.e2fs_gd[cg].ext2bgd_ndirs); - } - inplast = 0; - listmax = numdirs + 10; - inpsort = calloc((unsigned int)listmax, sizeof(struct inoinfo *)); - inphead = calloc((unsigned int)numdirs, sizeof(struct inoinfo *)); - if (inpsort == NULL || inphead == NULL) { - printf("cannot alloc %u bytes for inphead\n", - (unsigned int)(numdirs * sizeof(struct inoinfo *))); - goto badsblabel; - } - bufinit(); - return 1; - -badsblabel: - ckfini(0); - return 0; -} - -/* - * Read in the super block and its summary info, convert to host byte order. - */ -static int -readsb(int listerr) -{ - daddr_t super = bflag ? bflag : SBOFF / dev_bsize; - - if (bread(fsreadfd, (char *)sblk.b_un.b_fs, super, (long)SBSIZE) != 0) - return 0; - sblk.b_bno = super; - sblk.b_size = SBSIZE; - - /* Copy the superblock in memory */ - e2fs_sbload(sblk.b_un.b_fs, &sblock.e2fs); - - /* - * run a few consistency checks of the super block - */ - if (sblock.e2fs.e2fs_magic != E2FS_MAGIC) { - badsb(listerr, "MAGIC NUMBER WRONG"); - return 0; - } - if (sblock.e2fs.e2fs_log_bsize > 2) { - badsb(listerr, "BAD LOG_BSIZE"); - return 0; - } - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (!powerof2(sblock.e2fs.e2fs_inode_size) || - sblock.e2fs.e2fs_inode_size < sizeof(struct ext2fs_dinode) || - sblock.e2fs.e2fs_inode_size > - (1024 << sblock.e2fs.e2fs_log_bsize))) { - badsb(listerr, "BAD INODE_SIZE"); - return 0; - } - - /* compute the dynamic fields of the in-memory sb */ - /* compute dynamic sb infos */ - sblock.e2fs_ncg = - howmany(sblock.e2fs.e2fs_bcount - sblock.e2fs.e2fs_first_dblock, - sblock.e2fs.e2fs_bpg); - /* XXX assume hw bsize = 512 */ - sblock.e2fs_fsbtodb = sblock.e2fs.e2fs_log_bsize + 1; - sblock.e2fs_bsize = 1024 << sblock.e2fs.e2fs_log_bsize; - sblock.e2fs_bshift = LOG_MINBSIZE + sblock.e2fs.e2fs_log_bsize; - sblock.e2fs_qbmask = sblock.e2fs_bsize - 1; - sblock.e2fs_bmask = ~sblock.e2fs_qbmask; - sblock.e2fs_ngdb = howmany(sblock.e2fs_ncg, - sblock.e2fs_bsize / sizeof(struct ext2_gd)); - sblock.e2fs_ipb = sblock.e2fs_bsize / EXT2_DINODE_SIZE(&sblock); - sblock.e2fs_itpg = howmany(sblock.e2fs.e2fs_ipg, sblock.e2fs_ipb); - - /* - * Compute block size that the filesystem is based on, - * according to fsbtodb, and adjust superblock block number - * so we can tell if this is an alternate later. - */ - super *= dev_bsize; - dev_bsize = sblock.e2fs_bsize / EXT2_FSBTODB(&sblock, 1); - sblk.b_bno = super / dev_bsize; - - if (sblock.e2fs_ncg == 1) { - /* no alternate superblock; assume it's okay */ - havesb = 1; - return 1; - } - getblk(&asblk, 1 * sblock.e2fs.e2fs_bpg + sblock.e2fs.e2fs_first_dblock, - (long)SBSIZE); - if (asblk.b_errs) - return 0; - if (bflag) { - havesb = 1; - return 1; - } - - /* - * Set all possible fields that could differ, then do check - * of whole super block against an alternate super block. - * When an alternate super-block is specified this check is skipped. - */ - asblk.b_un.b_fs->e2fs_rbcount = sblk.b_un.b_fs->e2fs_rbcount; - asblk.b_un.b_fs->e2fs_fbcount = sblk.b_un.b_fs->e2fs_fbcount; - asblk.b_un.b_fs->e2fs_ficount = sblk.b_un.b_fs->e2fs_ficount; - asblk.b_un.b_fs->e2fs_mtime = sblk.b_un.b_fs->e2fs_mtime; - asblk.b_un.b_fs->e2fs_wtime = sblk.b_un.b_fs->e2fs_wtime; - asblk.b_un.b_fs->e2fs_mnt_count = sblk.b_un.b_fs->e2fs_mnt_count; - asblk.b_un.b_fs->e2fs_max_mnt_count = - sblk.b_un.b_fs->e2fs_max_mnt_count; - asblk.b_un.b_fs->e2fs_state = sblk.b_un.b_fs->e2fs_state; - asblk.b_un.b_fs->e2fs_beh = sblk.b_un.b_fs->e2fs_beh; - asblk.b_un.b_fs->e2fs_lastfsck = sblk.b_un.b_fs->e2fs_lastfsck; - asblk.b_un.b_fs->e2fs_fsckintv = sblk.b_un.b_fs->e2fs_fsckintv; - asblk.b_un.b_fs->e2fs_ruid = sblk.b_un.b_fs->e2fs_ruid; - asblk.b_un.b_fs->e2fs_rgid = sblk.b_un.b_fs->e2fs_rgid; - asblk.b_un.b_fs->e2fs_block_group_nr = - sblk.b_un.b_fs->e2fs_block_group_nr; - asblk.b_un.b_fs->e2fs_features_rocompat &= ~EXT2F_ROCOMPAT_LARGEFILE; - asblk.b_un.b_fs->e2fs_features_rocompat |= - sblk.b_un.b_fs->e2fs_features_rocompat & EXT2F_ROCOMPAT_LARGEFILE; - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - ((sblock.e2fs.e2fs_features_incompat & ~EXT2F_INCOMPAT_SUPP) || - (sblock.e2fs.e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP))) { - if (debug) { - printf("compat 0x%08x, incompat 0x%08x, compat_ro " - "0x%08x\n", - sblock.e2fs.e2fs_features_compat, - sblock.e2fs.e2fs_features_incompat, - sblock.e2fs.e2fs_features_rocompat); - } - badsb(listerr, "INCOMPATIBLE FEATURE BITS IN SUPER BLOCK"); - return 0; - } - if (memcmp(sblk.b_un.b_fs, asblk.b_un.b_fs, SBSIZE)) { - if (debug) { - u_int32_t *nlp, *olp, *endlp; - - printf("superblock mismatches\n"); - nlp = (u_int32_t *)asblk.b_un.b_fs; - olp = (u_int32_t *)sblk.b_un.b_fs; - endlp = olp + (SBSIZE / sizeof(*olp)); - for ( ; olp < endlp; olp++, nlp++) { - if (*olp == *nlp) - continue; - printf("offset %ld, original %ld, " - "alternate %ld\n", - (long)(olp - (u_int32_t *)sblk.b_un.b_fs), - (long)fs2h32(*olp), - (long)fs2h32(*nlp)); - } - } - badsb(listerr, - "VALUES IN SUPER BLOCK DISAGREE WITH " - "THOSE IN FIRST ALTERNATE"); - return 0; - } - havesb = 1; - return 1; -} - -void -copyback_sb(struct bufarea *bp) -{ - /* Copy the in-memory superblock back to buffer */ - bp->b_un.b_fs->e2fs_icount = h2fs32(sblock.e2fs.e2fs_icount); - bp->b_un.b_fs->e2fs_bcount = h2fs32(sblock.e2fs.e2fs_bcount); - bp->b_un.b_fs->e2fs_rbcount = h2fs32(sblock.e2fs.e2fs_rbcount); - bp->b_un.b_fs->e2fs_fbcount = h2fs32(sblock.e2fs.e2fs_fbcount); - bp->b_un.b_fs->e2fs_ficount = h2fs32(sblock.e2fs.e2fs_ficount); - bp->b_un.b_fs->e2fs_first_dblock = - h2fs32(sblock.e2fs.e2fs_first_dblock); - bp->b_un.b_fs->e2fs_log_bsize = h2fs32(sblock.e2fs.e2fs_log_bsize); - bp->b_un.b_fs->e2fs_fsize = h2fs32(sblock.e2fs.e2fs_fsize); - bp->b_un.b_fs->e2fs_bpg = h2fs32(sblock.e2fs.e2fs_bpg); - bp->b_un.b_fs->e2fs_fpg = h2fs32(sblock.e2fs.e2fs_fpg); - bp->b_un.b_fs->e2fs_ipg = h2fs32(sblock.e2fs.e2fs_ipg); - bp->b_un.b_fs->e2fs_mtime = h2fs32(sblock.e2fs.e2fs_mtime); - bp->b_un.b_fs->e2fs_wtime = h2fs32(sblock.e2fs.e2fs_wtime); - bp->b_un.b_fs->e2fs_lastfsck = h2fs32(sblock.e2fs.e2fs_lastfsck); - bp->b_un.b_fs->e2fs_fsckintv = h2fs32(sblock.e2fs.e2fs_fsckintv); - bp->b_un.b_fs->e2fs_creator = h2fs32(sblock.e2fs.e2fs_creator); - bp->b_un.b_fs->e2fs_rev = h2fs32(sblock.e2fs.e2fs_rev); - bp->b_un.b_fs->e2fs_mnt_count = h2fs16(sblock.e2fs.e2fs_mnt_count); - bp->b_un.b_fs->e2fs_max_mnt_count = - h2fs16(sblock.e2fs.e2fs_max_mnt_count); - bp->b_un.b_fs->e2fs_magic = h2fs16(sblock.e2fs.e2fs_magic); - bp->b_un.b_fs->e2fs_state = h2fs16(sblock.e2fs.e2fs_state); - bp->b_un.b_fs->e2fs_beh = h2fs16(sblock.e2fs.e2fs_beh); - bp->b_un.b_fs->e2fs_ruid = h2fs16(sblock.e2fs.e2fs_ruid); - bp->b_un.b_fs->e2fs_rgid = h2fs16(sblock.e2fs.e2fs_rgid); -} - -void -badsb(int listerr, const char *s) -{ - - if (!listerr) - return; - if (preen) - printf("%s: ", cdevname()); - pfatal("BAD SUPER BLOCK: %s\n", s); -} - -/* - * Calculate a prototype superblock based on information in the disk label. - * When done the cgsblock macro can be calculated and the fs_ncg field - * can be used. Do NOT attempt to use other macros without verifying that - * their needed information is available! - */ - -int -calcsb(const char *dev, int devfd, struct m_ext2fs *fs) -{ -#if defined(__minix) - errexit("%s: calcsb: can't read disk label under minix", dev); -#else - struct disklabel *lp; - struct partition *pp; - char *cp; - - cp = strchr(dev, '\0'); - if (cp-- == dev || - ((*cp < 'a' || *cp > 'h') && !isdigit((unsigned char)*cp))) { - pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev); - return 0; - } - lp = getdisklabel(dev, devfd); - if (isdigit((unsigned char)*cp)) - pp = &lp->d_partitions[0]; - else - pp = &lp->d_partitions[*cp - 'a']; - if (pp->p_fstype != FS_EX2FS) { - pfatal("%s: NOT LABELED AS A EXT2 FILE SYSTEM (%s)\n", - dev, pp->p_fstype < FSMAXTYPES ? - fstypenames[pp->p_fstype] : "unknown"); - return 0; - } - if (pp->p_fsize == 0) { - pfatal("%s: PARTITION SIZE IS 0\n", dev); - return 0; - } - memset(fs, 0, sizeof(struct m_ext2fs)); - fs->e2fs_bsize = pp->p_fsize; - fs->e2fs.e2fs_log_bsize = pp->p_fsize / 1024; - fs->e2fs.e2fs_bcount = (pp->p_size * DEV_BSIZE) / fs->e2fs_bsize; - fs->e2fs.e2fs_first_dblock = (fs->e2fs.e2fs_log_bsize == 0) ? 1 : 0; - fs->e2fs.e2fs_bpg = fs->e2fs_bsize * NBBY; - fs->e2fs_bshift = LOG_MINBSIZE + fs->e2fs.e2fs_log_bsize; - fs->e2fs_qbmask = fs->e2fs_bsize - 1; - fs->e2fs_bmask = ~fs->e2fs_qbmask; - fs->e2fs_ncg = - howmany(fs->e2fs.e2fs_bcount - fs->e2fs.e2fs_first_dblock, - fs->e2fs.e2fs_bpg); - fs->e2fs_fsbtodb = fs->e2fs.e2fs_log_bsize + 1; - fs->e2fs_ngdb = howmany(fs->e2fs_ncg, - fs->e2fs_bsize / sizeof(struct ext2_gd)); - - return 1; -#endif /* defined(__minix) */ -} - -static struct disklabel * -getdisklabel(const char *s, int fd) -{ - static struct disklabel lab; - -#if defined(__minix) - if (s == NULL) - return NULL; - errexit("%s: can't read disk label under minix", s); -#else - if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { - if (s == NULL) - return NULL; - pwarn("ioctl (GCINFO): %s\n", strerror(errno)); - errexit("%s: can't read disk label", s); - } -#endif /* defined(__minix) */ - return &lab; -} - -daddr_t -cgoverhead(int c) -{ - int overh; - overh = - 1 /* block bitmap */ + - 1 /* inode bitmap */ + - sblock.e2fs_itpg; - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - sblock.e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_SPARSESUPER) { - if (cg_has_sb(c) == 0) - return overh; - } - overh += 1 /* superblock */ + sblock.e2fs_ngdb; - return overh; -} diff --git a/sbin/fsck_ext2fs/utilities.c b/sbin/fsck_ext2fs/utilities.c deleted file mode 100644 index 1ab57e4ba..000000000 --- a/sbin/fsck_ext2fs/utilities.c +++ /dev/null @@ -1,499 +0,0 @@ -/* $NetBSD: utilities.c,v 1.23 2013/06/23 02:06:04 dholland Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; -#else -__RCSID("$NetBSD: utilities.c,v 1.23 2013/06/23 02:06:04 dholland Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include /* for IFMT & friends */ -#include -#include -#include -#include -#include -#include -#include - -#include "fsutil.h" -#include "fsck.h" -#include "extern.h" -#include "exitvalues.h" - -long diskreads, totalreads; /* Disk cache statistics */ - -static void rwerror(const char *, daddr_t); - -int -ftypeok(struct ext2fs_dinode *dp) -{ - switch (fs2h16(dp->e2di_mode) & IFMT) { - - case IFDIR: - case IFREG: - case IFBLK: - case IFCHR: - case IFLNK: - case IFSOCK: - case IFIFO: - return (1); - - default: - if (debug) - printf("bad file type 0%o\n", fs2h16(dp->e2di_mode)); - return (0); - } -} - -int -reply(const char *question) -{ - int persevere; - char c; - - if (preen) - pfatal("INTERNAL ERROR: GOT TO reply()"); - persevere = !strcmp(question, "CONTINUE"); - printf("\n"); - if (!persevere && (nflag || fswritefd < 0)) { - printf("%s? no\n\n", question); - return (0); - } - if (yflag || (persevere && nflag)) { - printf("%s? yes\n\n", question); - return (1); - } - do { - printf("%s? [yn] ", question); - (void) fflush(stdout); - c = getc(stdin); - while (c != '\n' && getc(stdin) != '\n') - if (feof(stdin)) - return (0); - } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N'); - printf("\n"); - if (c == 'y' || c == 'Y') - return (1); - return (0); -} - -/* - * Malloc buffers and set up cache. - */ -void -bufinit(void) -{ - struct bufarea *bp; - long bufcnt, i; - char *bufp; - - diskreads = totalreads = 0; - pbp = pdirbp = (struct bufarea *)0; - bufhead.b_next = bufhead.b_prev = &bufhead; - bufcnt = MAXBUFSPACE / sblock.e2fs_bsize; - if (bufcnt < MINBUFS) - bufcnt = MINBUFS; - for (i = 0; i < bufcnt; i++) { - bp = malloc(sizeof(struct bufarea)); - bufp = malloc((size_t)sblock.e2fs_bsize); - if (bp == NULL || bufp == NULL) { - free(bp); - free(bufp); - if (i >= MINBUFS) - break; - errexit("cannot allocate buffer pool"); - } - bp->b_un.b_buf = bufp; - bp->b_prev = &bufhead; - bp->b_next = bufhead.b_next; - bufhead.b_next->b_prev = bp; - bufhead.b_next = bp; - initbarea(bp); - } - bufhead.b_size = i; /* save number of buffers */ -} - -/* - * Manage a cache of directory blocks. - */ -struct bufarea * -getdatablk(daddr_t blkno, long size) -{ - struct bufarea *bp; - - for (bp = bufhead.b_next; bp != &bufhead; bp = bp->b_next) - if (bp->b_bno == EXT2_FSBTODB(&sblock, blkno)) - goto foundit; - for (bp = bufhead.b_prev; bp != &bufhead; bp = bp->b_prev) - if ((bp->b_flags & B_INUSE) == 0) - break; - if (bp == &bufhead) - errexit("deadlocked buffer pool"); - getblk(bp, blkno, size); - diskreads++; - /* fall through */ -foundit: - totalreads++; - bp->b_prev->b_next = bp->b_next; - bp->b_next->b_prev = bp->b_prev; - bp->b_prev = &bufhead; - bp->b_next = bufhead.b_next; - bufhead.b_next->b_prev = bp; - bufhead.b_next = bp; - bp->b_flags |= B_INUSE; - return (bp); -} - -void -getblk(struct bufarea *bp, daddr_t blk, long size) -{ - daddr_t dblk; - - dblk = EXT2_FSBTODB(&sblock, blk); - if (bp->b_bno != dblk) { - flush(fswritefd, bp); - bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, dblk, size); - bp->b_bno = dblk; - bp->b_size = size; - } -} - -void -flush(int fd, struct bufarea *bp) -{ - int i; - - if (!bp->b_dirty) - return; - if (bp->b_errs != 0) - pfatal("WRITING %sZERO'ED BLOCK %lld TO DISK\n", - (bp->b_errs == bp->b_size / dev_bsize) ? "" : "PARTIALLY ", - (long long)bp->b_bno); - bp->b_dirty = 0; - bp->b_errs = 0; - bwrite(fd, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size); - if (bp != &sblk) - return; - for (i = 0; i < sblock.e2fs_ngdb; i++) { - bwrite(fswritefd, (char *) - &sblock.e2fs_gd[i* sblock.e2fs_bsize / sizeof(struct ext2_gd)], - EXT2_FSBTODB(&sblock, ((sblock.e2fs_bsize>1024)?0:1)+i+1), - sblock.e2fs_bsize); - } -} - -static void -rwerror(const char *mesg, daddr_t blk) -{ - - if (preen == 0) - printf("\n"); - pfatal("CANNOT %s: BLK %lld", mesg, (long long)blk); - if (reply("CONTINUE") == 0) - errexit("Program terminated"); -} - -void -ckfini(int markclean) -{ - struct bufarea *bp, *nbp; - int cnt = 0; - - if (fswritefd < 0) { - (void)close(fsreadfd); - return; - } - flush(fswritefd, &sblk); - if (havesb && sblk.b_bno != SBOFF / dev_bsize && - !preen && reply("UPDATE STANDARD SUPERBLOCKS")) { - sblk.b_bno = SBOFF / dev_bsize; - sbdirty(); - flush(fswritefd, &sblk); - copyback_sb(&asblk); - asblk.b_dirty = 1; - flush(fswritefd, &asblk); - } - for (bp = bufhead.b_prev; bp && bp != &bufhead; bp = nbp) { - cnt++; - flush(fswritefd, bp); - nbp = bp->b_prev; - free(bp->b_un.b_buf); - free(bp); - } - if (bufhead.b_size != cnt) - errexit("Panic: lost %d buffers", bufhead.b_size - cnt); - pbp = pdirbp = (struct bufarea *)0; - if (markclean && (sblock.e2fs.e2fs_state & E2FS_ISCLEAN) == 0) { - /* - * Mark the file system as clean, and sync the superblock. - */ - if (preen) - pwarn("MARKING FILE SYSTEM CLEAN\n"); - else if (!reply("MARK FILE SYSTEM CLEAN")) - markclean = 0; - if (markclean) { - sblock.e2fs.e2fs_state = E2FS_ISCLEAN; - sbdirty(); - flush(fswritefd, &sblk); - } - } - if (debug) - printf("cache missed %ld of %ld (%d%%)\n", diskreads, - totalreads, (int)(diskreads * 100 / totalreads)); - (void)close(fsreadfd); - (void)close(fswritefd); -} - -int -bread(int fd, char *buf, daddr_t blk, long size) -{ - char *cp; - int i, errs; - off_t offset; - - offset = blk; - offset *= dev_bsize; - if (lseek(fd, offset, 0) < 0) - rwerror("SEEK", blk); - else if (read(fd, buf, (int)size) == size) - return (0); - rwerror("READ", blk); - if (lseek(fd, offset, 0) < 0) - rwerror("SEEK", blk); - errs = 0; - memset(buf, 0, (size_t)size); - printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:"); - for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) { - if (read(fd, cp, (int)secsize) != secsize) { - (void)lseek(fd, offset + i + secsize, 0); - if (secsize != dev_bsize && dev_bsize != 1) - printf(" %lld (%lld),", - (long long)((blk*dev_bsize + i) / secsize), - (long long)(blk + i / dev_bsize)); - else - printf(" %lld,", (long long)(blk + - i / dev_bsize)); - errs++; - } - } - printf("\n"); - return (errs); -} - -void -bwrite(int fd, char *buf, daddr_t blk, long size) -{ - int i; - char *cp; - off_t offset; - - if (fd < 0) - return; - offset = blk; - offset *= dev_bsize; - if (lseek(fd, offset, 0) < 0) - rwerror("SEEK", blk); - else if (write(fd, buf, (int)size) == size) { - fsmodified = 1; - return; - } - rwerror("WRITE", blk); - if (lseek(fd, offset, 0) < 0) - rwerror("SEEK", blk); - printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:"); - for (cp = buf, i = 0; i < size; i += dev_bsize, cp += dev_bsize) - if (write(fd, cp, (int)dev_bsize) != dev_bsize) { - (void)lseek(fd, offset + i + dev_bsize, 0); - printf(" %lld,", (long long)(blk + i / dev_bsize)); - } - printf("\n"); - return; -} - -/* - * allocate a data block - */ -int -allocblk(void) -{ - int i; - - for (i = 0; i < maxfsblock - 1; i++) { - if (testbmap(i)) - continue; - setbmap(i); - n_blks++; - return (i); - } - return (0); -} - -/* - * Free a previously allocated block - */ -void -freeblk(daddr_t blkno) -{ - struct inodesc idesc; - - idesc.id_blkno = blkno; - idesc.id_numfrags = 1; - (void)pass4check(&idesc); -} - -/* - * Find a pathname - */ -void -getpathname(char *namebuf, size_t namebuflen, ino_t curdir, ino_t ino) -{ - int len; - char *cp; - struct inodesc idesc; - static int busy = 0; - - if (curdir == ino && ino == EXT2_ROOTINO) { - (void)strlcpy(namebuf, "/", namebuflen); - return; - } - if (busy || - (statemap[curdir] != DSTATE && statemap[curdir] != DFOUND)) { - (void)strlcpy(namebuf, "?", namebuflen); - return; - } - busy = 1; - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = DATA; - idesc.id_fix = IGNORE; - cp = &namebuf[MAXPATHLEN - 1]; - *cp = '\0'; - if (curdir != ino) { - idesc.id_parent = curdir; - goto namelookup; - } - while (ino != EXT2_ROOTINO) { - idesc.id_number = ino; - idesc.id_func = findino; - idesc.id_name = ".."; - if ((ckinode(ginode(ino), &idesc) & FOUND) == 0) - break; - namelookup: - idesc.id_number = idesc.id_parent; - idesc.id_parent = ino; - idesc.id_func = findname; - idesc.id_name = namebuf; - if ((ckinode(ginode(idesc.id_number), &idesc)&FOUND) == 0) - break; - len = strlen(namebuf); - cp -= len; - memcpy(cp, namebuf, (size_t)len); - *--cp = '/'; - if (cp < &namebuf[EXT2FS_MAXNAMLEN]) - break; - ino = idesc.id_number; - } - busy = 0; - if (ino != EXT2_ROOTINO) - *--cp = '?'; - memcpy(namebuf, cp, (size_t)(&namebuf[MAXPATHLEN] - cp)); -} - -/* - * determine whether an inode should be fixed. - */ -int -dofix(struct inodesc *idesc, const char *msg) -{ - - switch (idesc->id_fix) { - - case DONTKNOW: - if (idesc->id_type == DATA) - direrror(idesc->id_number, msg); - else - pwarn("%s", msg); - if (preen) { - printf(" (SALVAGED)\n"); - idesc->id_fix = FIX; - return (ALTERED); - } - if (reply("SALVAGE") == 0) { - idesc->id_fix = NOFIX; - return (0); - } - idesc->id_fix = FIX; - return (ALTERED); - - case FIX: - return (ALTERED); - - case NOFIX: - case IGNORE: - return (0); - - default: - errexit("UNKNOWN INODESC FIX MODE %d", idesc->id_fix); - } - /* NOTREACHED */ -} diff --git a/sbin/ifconfig/env.h b/sbin/ifconfig/env.h deleted file mode 100644 index a5749e05f..000000000 --- a/sbin/ifconfig/env.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _IFCONFIG_ENV_H -#define _IFCONFIG_ENV_H - -#include - -const char *getifname(prop_dictionary_t); -ssize_t getargstr(prop_dictionary_t, const char *, char *, size_t); -ssize_t getargdata(prop_dictionary_t, const char *, uint8_t *, size_t); -int getaf(prop_dictionary_t); -int getifflags(prop_dictionary_t, prop_dictionary_t, unsigned short *); -const char *getifinfo(prop_dictionary_t, prop_dictionary_t, unsigned short *); -prop_dictionary_t prop_dictionary_augment(prop_dictionary_t, prop_dictionary_t); - -/* - * XXX: this really doesn't belong in here, but env.h is conveniently - * included from all source modules *after* system headers, so it - * allows us to be lazy. See Makefile for more details. - */ -#ifdef RUMP_ACTION -#include -#include -#include -#endif /* RUMP_ACTION */ - -#endif /* _IFCONFIG_ENV_H */ diff --git a/sbin/ifconfig/parse.h b/sbin/ifconfig/parse.h deleted file mode 100644 index 231dfd971..000000000 --- a/sbin/ifconfig/parse.h +++ /dev/null @@ -1,284 +0,0 @@ -#ifndef _IFCONFIG_PARSE_H -#define _IFCONFIG_PARSE_H - -#include -#include -#include -#include -#include -#include - -struct match; -struct parser; - -extern struct pbranch command_root; - -typedef int (*parser_exec_t)(prop_dictionary_t, prop_dictionary_t); -typedef int (*parser_match_t)(const struct parser *, const struct match *, - struct match *, int, const char *); -typedef int (*parser_init_t)(struct parser *); - -struct match { - prop_dictionary_t m_env; - const struct parser *m_nextparser; - const struct parser *m_parser; - int m_argidx; - parser_exec_t m_exec; -}; - -/* method table */ -struct parser_methods { - parser_match_t pm_match; - parser_init_t pm_init; -}; - -struct parser { - const struct parser_methods *p_methods; - parser_exec_t p_exec; - const char *p_name; - struct parser *p_nextparser; - bool p_initialized; -}; - -struct branch { - SIMPLEQ_ENTRY(branch) b_next; - struct parser *b_nextparser; -}; - -struct pbranch { - struct parser pb_parser; - SIMPLEQ_HEAD(, branch) pb_branches; - bool pb_match_first; - const struct branch *pb_brinit; - size_t pb_nbrinit; -}; - -struct pterm { - struct parser pt_parser; - const char *pt_key; -}; - -extern const struct parser_methods paddr_methods; -extern const struct parser_methods pbranch_methods; -extern const struct parser_methods piface_methods; -extern const struct parser_methods pinteger_methods; -extern const struct parser_methods pstr_methods; -extern const struct parser_methods pkw_methods; -extern const struct parser_methods pterm_methods; - -#define PTERM_INITIALIZER(__pt, __name, __exec, __key) \ -{ \ - .pt_parser = {.p_name = (__name), .p_methods = &pterm_methods, \ - .p_exec = (__exec)}, \ - .pt_key = (__key) \ -} - -#define PBRANCH_INITIALIZER(__pb, __name, __brs, __nbr, __match_first) \ -{ \ - .pb_parser = {.p_name = (__name), .p_methods = &pbranch_methods},\ - .pb_branches = SIMPLEQ_HEAD_INITIALIZER((__pb)->pb_branches), \ - .pb_brinit = (__brs), \ - .pb_nbrinit = (__nbr), \ - .pb_match_first = (__match_first) \ -} - -#define PSTR_INITIALIZER(__ps, __name, __defexec, __defkey, __defnext) \ - PSTR_INITIALIZER1((__ps), (__name), (__defexec), (__defkey), \ - true, (__defnext)) - -#define PSTR_INITIALIZER1(__ps, __name, __defexec, __defkey, __defhexok,\ - __defnext) \ -{ \ - .ps_parser = {.p_name = (__name), .p_methods = &pstr_methods, \ - .p_exec = (__defexec), \ - .p_nextparser = (__defnext)}, \ - .ps_key = (__defkey), \ - .ps_hexok = (__defhexok) \ -} - -#define PADDR_INITIALIZER(__pa, __name, __defexec, __addrkey, \ - __maskkey, __activator, __deactivator, __defnext) \ -{ \ - .pa_parser = {.p_name = (__name), .p_methods = &paddr_methods, \ - .p_exec = (__defexec), \ - .p_nextparser = (__defnext)}, \ - .pa_addrkey = (__addrkey), \ - .pa_maskkey = (__maskkey), \ - .pa_activator = (__activator), \ - .pa_deactivator = (__deactivator), \ -} - -#define PIFACE_INITIALIZER(__pif, __name, __defexec, __defkey, __defnext)\ -{ \ - .pif_parser = {.p_name = (__name), .p_methods = &piface_methods,\ - .p_exec = (__defexec), \ - .p_nextparser = (__defnext)}, \ - .pif_key = (__defkey) \ -} - -#define PINTEGER_INITIALIZER1(__pi, __name, __min, __max, __base, \ - __defexec, __defkey, __defnext) \ -{ \ - .pi_parser = {.p_name = (__name), .p_methods = &pinteger_methods,\ - .p_exec = (__defexec), \ - .p_nextparser = (__defnext), \ - .p_initialized = false}, \ - .pi_min = (__min), \ - .pi_max = (__max), \ - .pi_base = (__base), \ - .pi_key = (__defkey) \ -} - -#define PINTEGER_INITIALIZER(__pi, __name, __base, __defexec, __defkey, \ - __defnext) \ - PINTEGER_INITIALIZER1(__pi, __name, INTMAX_MIN, INTMAX_MAX, \ - __base, __defexec, __defkey, __defnext) - -#define PKW_INITIALIZER(__pk, __name, __defexec, __defkey, __kws, __nkw,\ - __defnext) \ -{ \ - .pk_parser = {.p_name = (__name), \ - .p_exec = (__defexec), \ - .p_methods = &pkw_methods, \ - .p_initialized = false}, \ - .pk_keywords = SIMPLEQ_HEAD_INITIALIZER((__pk)->pk_keywords), \ - .pk_kwinit = (__kws), \ - .pk_nkwinit = (__nkw), \ - .pk_keyinit = (__defkey), \ - .pk_nextinit = (__defnext) \ -} - -#define IFKW(__word, __flag) \ -{ \ - .k_word = (__word), .k_neg = true, .k_type = KW_T_INT, \ - .k_int = (__flag), \ - .k_negint = -(__flag) \ -} - -#define KW_T_NONE 0 -#define KW_T_OBJ 1 -#define KW_T_INT 2 -#define KW_T_STR 3 -#define KW_T_BOOL 4 -#define KW_T_UINT 5 - -struct kwinst { - SIMPLEQ_ENTRY(kwinst) k_next; - int k_type; - const char *k_word; - const char *k_key; - const char *k_act; - const char *k_deact; - const char *k_altdeact; - parser_exec_t k_exec; - union kwval { - int64_t u_sint; - uint64_t u_uint; - const char *u_str; - prop_object_t u_obj; - bool u_bool; - } k_u, k_negu; -#define k_int k_u.u_sint -#define k_uint k_u.u_uint -#define k_str k_u.u_str -#define k_obj k_u.u_obj -#define k_bool k_u.u_bool - -#define k_negint k_negu.u_sint -#define k_neguint k_negu.u_uint -#define k_negstr k_negu.u_str -#define k_negobj k_negu.u_obj -#define k_negbool k_negu.u_bool - - bool k_neg; /* allow negative form, -keyword */ - struct parser *k_nextparser; -}; - -struct pkw { - struct parser pk_parser; - const char *pk_key; - const char *pk_keyinit; - const struct kwinst *pk_kwinit; - size_t pk_nkwinit; - SIMPLEQ_HEAD(, kwinst) pk_keywords; -}; - -#define pk_nextinit pk_parser.p_nextparser -#define pk_execinit pk_parser.p_exec - -struct pstr { - struct parser ps_parser; - const char *ps_key; - bool ps_hexok; -}; - -struct pinteger { - struct parser pi_parser; - int64_t pi_min; - int64_t pi_max; - int pi_base; - const char *pi_key; -}; - -struct intrange { - SIMPLEQ_ENTRY(intrange) r_next; - int64_t r_bottom; - int64_t r_top; - struct parser *r_nextparser; -}; - -struct pranges { - struct parser pr_parser; - SIMPLEQ_HEAD(, intrange) pr_ranges; -}; - -struct paddr_prefix { - int16_t pfx_len; - struct sockaddr pfx_addr; -}; - -static inline size_t -paddr_prefix_size(const struct paddr_prefix *pfx) -{ - return offsetof(struct paddr_prefix, pfx_addr) + pfx->pfx_addr.sa_len; -} - -struct paddr { - struct parser pa_parser; - const char *pa_addrkey; - const char *pa_maskkey; - const char *pa_activator; - const char *pa_deactivator; -}; - -struct piface { - struct parser pif_parser; - const char *pif_key; -}; - -struct prest { - struct parser pr_parser; -}; - -struct prest *prest_create(const char *); -struct paddr *paddr_create(const char *, parser_exec_t, const char *, - const char *, struct parser *); -struct pstr *pstr_create(const char *, parser_exec_t, const char *, - bool, struct parser *); -struct piface *piface_create(const char *, parser_exec_t, const char *, - struct parser *); -struct pkw *pkw_create(const char *, parser_exec_t, - const char *, const struct kwinst *, size_t, struct parser *); -struct pranges *pranges_create(const char *, parser_exec_t, const char *, - const struct intrange *, size_t, struct parser *); -struct pbranch *pbranch_create(const char *, const struct branch *, size_t, - bool); -int pbranch_addbranch(struct pbranch *, struct parser *); -int pbranch_setbranches(struct pbranch *, const struct branch *, size_t); - -int parse(int, char **, const struct parser *, struct match *, size_t *, int *); - -int matches_exec(const struct match *, prop_dictionary_t, size_t); -int parser_init(struct parser *); - -#endif /* _IFCONFIG_PARSE_H */ diff --git a/sbin/ifconfig/util.h b/sbin/ifconfig/util.h deleted file mode 100644 index ed8e55683..000000000 --- a/sbin/ifconfig/util.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _IFCONFIG_UTIL_H -#define _IFCONFIG_UTIL_H - -#include -#include -#include -#include - -#include "parse.h" - -struct afswtch { - const char *af_name; - short af_af; - void (*af_status)(prop_dictionary_t, prop_dictionary_t, bool); - void (*af_addr_commit)(prop_dictionary_t, prop_dictionary_t); - bool (*af_addr_tentative)(struct ifaddrs *); - SIMPLEQ_ENTRY(afswtch) af_next; -}; - -void print_link_addresses(prop_dictionary_t, bool); -const char *get_string(const char *, const char *, u_int8_t *, int *, bool); -const struct afswtch *lookup_af_byname(const char *); -const struct afswtch *lookup_af_bynum(int); -void print_string(const u_int8_t *, int); -int getsock(int); -struct paddr_prefix *prefixlen_to_mask(int, int); -int direct_ioctl(prop_dictionary_t, unsigned long, void *); -int indirect_ioctl(prop_dictionary_t, unsigned long, void *); -bool ifa_any_preferences(const char *, struct ifaddrs *, int); -void ifa_print_preference(const char *, const struct sockaddr *); -int16_t ifa_get_preference(const char *, const struct sockaddr *); - -#endif /* _IFCONFIG_UTIL_H */ diff --git a/sbin/mknod/Makefile b/sbin/mknod/Makefile deleted file mode 100644 index a7d150555..000000000 --- a/sbin/mknod/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $NetBSD: Makefile,v 1.13 2009/04/11 07:58:12 lukem Exp $ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 - -PROG= mknod -SRCS= mknod.c pack_dev.c -MAN= mknod.8 - -.include diff --git a/sbin/mknod/mknod.c b/sbin/mknod/mknod.c deleted file mode 100644 index 824152923..000000000 --- a/sbin/mknod/mknod.c +++ /dev/null @@ -1,393 +0,0 @@ -/* $NetBSD: mknod.c,v 1.42 2014/08/22 22:28:50 mlelstv Exp $ */ - -/*- - * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Charles M. Hannum. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#if HAVE_NBTOOL_CONFIG_H -#include "nbtool_config.h" -#endif - -#include -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1998\ - The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD: mknod.c,v 1.42 2014/08/22 22:28:50 mlelstv Exp $"); -#endif /* not lint */ - -#include -#include -#include -#if !HAVE_NBTOOL_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pack_dev.h" - -static int gid_name(const char *, gid_t *); -static dev_t callPack(pack_t *, int, u_long *); - -__dead static void usage(void); - -#ifdef KERN_DRIVERS -static struct kinfo_drivers *kern_drivers; -static int num_drivers; - -static void get_device_info(void); -static void print_device_info(char **); -static int major_from_name(const char *, mode_t); -#endif - -#define MAXARGS 3 /* 3 for bsdos, 2 for rest */ - -int -main(int argc, char **argv) -{ - char *name, *p; - mode_t mode; - dev_t dev; - pack_t *pack; - u_long numbers[MAXARGS]; - int n, ch, fifo, hasformat; - int r_flag = 0; /* force: delete existing entry */ -#ifdef KERN_DRIVERS - int l_flag = 0; /* list device names and numbers */ - int major; -#endif - void *modes = 0; - uid_t uid = -1; - gid_t gid = -1; - int rval; - - dev = 0; - fifo = hasformat = 0; - pack = pack_native; - -#ifdef KERN_DRIVERS - while ((ch = getopt(argc, argv, "lrRF:g:m:u:")) != -1) { -#else - while ((ch = getopt(argc, argv, "rRF:g:m:u:")) != -1) { -#endif - switch (ch) { - -#ifdef KERN_DRIVERS - case 'l': - l_flag = 1; - break; -#endif - - case 'r': - r_flag = 1; - break; - - case 'R': - r_flag = 2; - break; - - case 'F': - pack = pack_find(optarg); - if (pack == NULL) - errx(1, "invalid format: %s", optarg); - hasformat++; - break; - - case 'g': - if (optarg[0] == '#') { - gid = strtol(optarg + 1, &p, 10); - if (*p == 0) - break; - } - if (gid_name(optarg, &gid) == 0) - break; - gid = strtol(optarg, &p, 10); - if (*p == 0) - break; - errx(1, "%s: invalid group name", optarg); - - case 'm': - modes = setmode(optarg); - if (modes == NULL) - err(1, "Cannot set file mode `%s'", optarg); - break; - - case 'u': - if (optarg[0] == '#') { - uid = strtol(optarg + 1, &p, 10); - if (*p == 0) - break; - } - if (uid_from_user(optarg, &uid) == 0) - break; - uid = strtol(optarg, &p, 10); - if (*p == 0) - break; - errx(1, "%s: invalid user name", optarg); - - default: - case '?': - usage(); - } - } - argc -= optind; - argv += optind; - -#ifdef KERN_DRIVERS - if (l_flag) { - print_device_info(argv); - return 0; - } -#endif - - if (argc < 2 || argc > 10) - usage(); - - name = *argv; - argc--; - argv++; - - umask(mode = umask(0)); - mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) & ~mode; - - if (argv[0][1] != '\0') - goto badtype; - switch (*argv[0]) { - case 'c': - mode |= S_IFCHR; - break; - - case 'b': - mode |= S_IFBLK; - break; - - case 'p': - if (hasformat) - errx(1, "format is meaningless for fifos"); - mode |= S_IFIFO; - fifo = 1; - break; - - default: - badtype: - errx(1, "node type must be 'b', 'c' or 'p'."); - } - argc--; - argv++; - - if (fifo) { - if (argc != 0) - usage(); - } else { - if (argc < 1 || argc > MAXARGS) - usage(); - } - - for (n = 0; n < argc; n++) { - errno = 0; - numbers[n] = strtoul(argv[n], &p, 0); - if (*p == 0 && errno == 0) - continue; -#ifdef KERN_DRIVERS - if (argc == 2 && n == 0) { - major = major_from_name(argv[0], mode); - if (major != -1) { - numbers[0] = major; - continue; - } - if (!isdigit(*(unsigned char *)argv[0])) - errx(1, "unknown driver: %s", argv[0]); - } -#endif - errx(1, "invalid number: %s", argv[n]); - } - - switch (argc) { - case 0: - dev = 0; - break; - - case 1: - dev = numbers[0]; - break; - - default: - dev = callPack(pack, argc, numbers); - break; - } - - if (modes != NULL) - mode = getmode(modes, mode); - umask(0); - rval = fifo ? mkfifo(name, mode) : mknod(name, mode, dev); - if (rval < 0 && errno == EEXIST && r_flag) { - struct stat sb; - if (lstat(name, &sb) != 0 || (!fifo && sb.st_rdev != dev)) - sb.st_mode = 0; - - if ((sb.st_mode & S_IFMT) == (mode & S_IFMT)) { - if (r_flag == 1) - /* Ignore permissions and user/group */ - return 0; - if (sb.st_mode != mode) - rval = chmod(name, mode); - else - rval = 0; - } else { - unlink(name); - rval = fifo ? mkfifo(name, mode) - : mknod(name, mode, dev); - } - } - if (rval < 0) - err(1, "%s", name); - if ((uid != (uid_t)-1 || gid != (uid_t)-1) && chown(name, uid, gid) == -1) - /* XXX Should we unlink the files here? */ - warn("%s: uid/gid not changed", name); - - return 0; -} - -static void -usage(void) -{ - const char *progname = getprogname(); - - (void)fprintf(stderr, - "usage: %s [-rR] [-F format] [-m mode] [-u user] [-g group]\n", - progname); - (void)fprintf(stderr, -#ifdef KERN_DRIVERS - " [ name [b | c] [major | driver] minor\n" -#else - " [ name [b | c] major minor\n" -#endif - " | name [b | c] major unit subunit\n" - " | name [b | c] number\n" - " | name p ]\n"); -#ifdef KERN_DRIVERS - (void)fprintf(stderr, " %s -l [driver] ...\n", progname); -#endif - exit(1); -} - -static int -gid_name(const char *name, gid_t *gid) -{ - struct group *g; - - g = getgrnam(name); - if (!g) - return -1; - *gid = g->gr_gid; - return 0; -} - -static dev_t -callPack(pack_t *f, int n, u_long *numbers) -{ - dev_t d; - const char *error = NULL; - - d = (*f)(n, numbers, &error); - if (error != NULL) - errx(1, "%s", error); - return d; -} - -#ifdef KERN_DRIVERS -static void -get_device_info(void) -{ - static int mib[2] = {CTL_KERN, KERN_DRIVERS}; - size_t len; - - if (sysctl(mib, 2, NULL, &len, NULL, 0) != 0) - err(1, "kern.drivers" ); - kern_drivers = malloc(len); - if (kern_drivers == NULL) - err(1, "malloc"); - if (sysctl(mib, 2, kern_drivers, &len, NULL, 0) != 0) - err(1, "kern.drivers" ); - - num_drivers = len / sizeof *kern_drivers; -} - -static void -print_device_info(char **names) -{ - int i; - struct kinfo_drivers *kd; - - if (kern_drivers == NULL) - get_device_info(); - - do { - kd = kern_drivers; - for (i = 0; i < num_drivers; kd++, i++) { - if (*names && strcmp(*names, kd->d_name)) - continue; - printf("%s", kd->d_name); - if (kd->d_cmajor != -1) - printf(" character major %d", kd->d_cmajor); - if (kd->d_bmajor != -1) - printf(" block major %d", kd->d_bmajor); - printf("\n"); - } - } while (*names && *++names); -} - -static int -major_from_name(const char *name, mode_t mode) -{ - int i; - struct kinfo_drivers *kd; - - if (kern_drivers == NULL) - get_device_info(); - - kd = kern_drivers; - for (i = 0; i < num_drivers; kd++, i++) { - if (strcmp(name, kd->d_name)) - continue; - if (S_ISCHR(mode)) - return kd->d_cmajor; - return kd->d_bmajor; - } - return -1; -} -#endif diff --git a/sbin/nologin/nologin.sh b/sbin/nologin/nologin.sh deleted file mode 100644 index ec791a339..000000000 --- a/sbin/nologin/nologin.sh +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -echo "This account is currently not available." -exit 1 diff --git a/sbin/ping/Makefile b/sbin/ping/Makefile deleted file mode 100644 index 12e2c5da7..000000000 --- a/sbin/ping/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# $NetBSD: Makefile,v 1.17 2013/11/09 21:39:27 christos Exp $ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 - -USE_FORT?= yes # setuid -RUMPPRG=ping -MAN= ping.8 -BINOWN= root -BINMODE=4555 -LDADD= -lm -DPADD= ${LIBM} -.include -.if !defined(__MINIX) -CPPFLAGS+= -DIPSEC -LDADD+= -lipsec -DPADD+= ${LIBIPSEC} -.endif # !defined(__MINIX) - -.if ${MACHINE_ARCH} == "vax" -COPTS.ping.c=-O0 -.endif - -.include diff --git a/sbin/ping/ping.8 b/sbin/ping/ping.8 deleted file mode 100644 index b74b740d9..000000000 --- a/sbin/ping/ping.8 +++ /dev/null @@ -1,478 +0,0 @@ -.\" $NetBSD: ping.8,v 1.50 2011/09/10 20:47:33 wiz Exp $ -.\" -.\" Copyright (c) 1985, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)ping.8 8.2 (Berkeley) 12/11/93 -.\" -.Dd September 10, 2011 -.Dt PING 8 -.Os -.Sh NAME -.Nm ping -.Nd send -.Tn ICMP ECHO_REQUEST -packets to network hosts -.Sh SYNOPSIS -.Nm -.Op Fl aCDdfLnoPQqRrv -.Op Fl c Ar count -.Op Fl E Ar policy -.Op Fl g Ar gateway -.Op Fl h Ar host -.Op Fl I Ar srcaddr -.Op Fl i Ar interval -.Op Fl l Ar preload -.Op Fl p Ar pattern -.Op Fl s Ar packetsize -.Op Fl T Ar ttl -.Op Fl t Ar tos -.Op Fl w Ar deadline -.Ar host -.Sh DESCRIPTION -.Nm -uses the -.Tn ICMP -protocol's mandatory -.Tn ECHO_REQUEST -datagram to elicit an -.Tn ICMP ECHO_RESPONSE -from a host or gateway. -.Tn ECHO_REQUEST -datagrams (``pings'') have an IP and -.Tn ICMP -header, -followed by a -.Dq struct timespec -and then an arbitrary number of ``pad'' bytes used to fill out the -packet. -The options are as follows: -.Bl -tag -width Ds -.It Fl a -Emit an audible beep (by sending an ascii BEL character to the -standard error output) after each non-duplicate response is received. -This is disabled for flood pings as it would probably cause temporary -insanity. -.It Fl C -Send timestamps in compat format; two 32 bit words in little endian format, -the first one representing seconds, and the second one representing -microseconds. -.It Fl c Ar count -Stop after sending (and waiting the specified delay to receive) -.Ar count -.Tn ECHO_RESPONSE -packets. -.It Fl D -Set the -.Dv Don't Fragment -bit in the IP header. -This can be used to determine the path MTU. -.It Fl d -Set the -.Dv SO_DEBUG -option on the socket being used. -.It Fl E Ar policy -Use IPsec policy specification string -.Ar policy -for packets. -For the format of specification string, please refer -.Xr ipsec_set_policy 3 . -Please note that this option is same as -.Fl P -in KAME/FreeBSD and KAME/BSDI -(as -.Fl P -was already occupied in -.Nx ) . -.It Fl f -Flood ping. -Outputs packets as fast as they come back or one hundred times per second, -whichever is more. -For every -.Tn ECHO_REQUEST -sent a period ``.'' is printed, while for every -.Tn ECHO_REPLY -received a backspace is printed. -This provides a rapid display of how many packets are being dropped. -Only the super-user may use this option. -.Bf -emphasis -This can be very hard on a network and should be used with caution. -.Ef -.It Fl g Ar gateway -Use Loose Source Routing to send the ECHO_REQUEST packets via -.Ar gateway . -.It Fl h Ar host -is an alternate way of specifying the target host instead of as the -last argument. -.It Fl I Ar srcaddr -Set the source IP address to -.Ar srcaddr -which can be a hostname or an IP number. -For multicast datagrams, it also specifies the outgoing interface. -.It Fl i Ar interval -Wait -.Ar interval -seconds -.Em between sending each packet . -The default is to wait for one second between each packet, -except when the -f option is used the wait interval is 0.01 seconds. -.It Fl L -Disable loopback when sending to multicast destinations, -so the transmitting host doesn't see the ICMP requests. -.It Fl l Ar preload -If -.Ar preload -is specified, -.Nm -sends that many packets as fast as possible before falling into its normal -mode of behavior. -Only the super-user may use this option. -.It Fl n -Numeric output only. -No attempt will be made to look up symbolic names for host addresses. -.It Fl o -Exit successfully after receiving one reply packet. -.It Fl P -Use a pseudo-random sequence for the data instead of the default, -fixed sequence of incrementing 8-bit integers. -This is useful to foil compression on PPP and other links. -.It Fl p Ar pattern -You may specify up to 16 ``pad'' bytes to fill out the packet you send. -This is useful for diagnosing data-dependent problems in a network. -For example, -.Dq Li \-p ff -will cause the sent packet to be filled with all -ones. -.It Fl Q -Do not display responses such as Network Unreachable ICMP messages -concerning the ECHO_REQUESTs sent. -.It Fl q -Quiet output. -Nothing is displayed except the summary lines at startup time and -when finished. -.It Fl R -Record Route. -Includes the -.Tn RECORD_ROUTE -option in the -.Tn ECHO_REQUEST -packet and displays the route buffer on returned packets. -This should show the path to the target host and back, which is -especially useful in the case of asymmetric routing. -Note that the IP header is only large enough for nine such addresses, -and only seven when using the -.Fl g -option. -This is why it was necessary to invent -.Xr traceroute 8 . -Many hosts ignore or discard this option. -.It Fl r -Bypass the normal routing tables and send directly to a host on an attached -network. -If the host is not on a directly-attached network, an error is returned. -This option can be used to ping a local host through an interface -that has no route through it (e.g., after the interface was dropped by -.Xr routed 8 ) . -.It Fl s Ar packetsize -Specifies the number of data bytes to be sent. -The default is 56, which translates into 64 -.Tn ICMP -data bytes when combined -with the 8 bytes of -.Tn ICMP -header data. -The maximum allowed value is 65467 bytes. -.It Fl T Ar ttl -Use the specified time-to-live. -.It Fl t Ar tos -Use the specified hexadecimal type of service. -.It Fl v -Verbose output. -.Tn ICMP -packets other than -.Tn ECHO_RESPONSE -that are received are listed. -.It Fl w Ar deadline -Specifies a timeout, in seconds, before ping exits regardless of -how many packets have been sent or received. -.El -.Pp -When using -.Nm -for fault isolation, it should first be run on the local host, to verify -that the local network interface is up and running. -Then, hosts and gateways further and further away should be ``pinged''. -.Pp -Round-trip times and packet loss statistics are computed. -If duplicate packets are received, they are not included in the packet -loss calculation, although the round trip time of these packets is used -in calculating the minimum/average/maximum round-trip time numbers. -.Pp -When the specified number of packets have been sent (and received) or -if the program is terminated with a -.Dv SIGINT , -a brief summary is displayed. -The summary information can be displayed while -.Nm -is running by sending it a -.Dv SIGINFO -signal (see the -.Dq status -argument for -.Xr stty 1 -for more information). -.Pp -.Nm -continually sends one datagram per second, and prints one line of -output for every ECHO_RESPONSE returned. -On a trusted system with IP -Security Options enabled, if the network idiom is not MONO, -.Nm -also prints a second line containing the hexadecimal representation -of the IP security option in the ECHO_RESPONSE. -If the -.Fl c -count option is given, only that number of requests is sent. -No output is produced if there is no response. -Round-trip times and packet loss statistics are computed. -If duplicate packets are received, -they are not included in the packet loss calculation, -although the round trip time of these packets is used in calculating -the minimum/average/maximum round-trip time numbers. -When the specified number of packets have been sent (and received) or if -the program is terminated with an interrupt (SIGINT), a brief -summary is displayed. -When not using the -.Fl f -(flood) option, the first interrupt, usually generated by control-C or DEL, -causes -.Nm -to wait for its outstanding requests to return. -It will wait no longer than the longest round trip time -encountered by previous, successful pings. -The second interrupt stops ping immediately. -.Pp -This program is intended for use in network testing, measurement and -management. -Because of the load it can impose on the network, it is unwise to use -.Nm -during normal operations or from automated scripts. -.Sh ICMP PACKET DETAILS -An IP header without options is 20 bytes. -An -.Tn ICMP -.Tn ECHO_REQUEST -packet contains an additional 8 bytes worth of -.Tn ICMP -header followed by an arbitrary amount of data. -When a -.Ar packetsize -is given, this indicated the size of this extra piece of data (the -default is 56). -Thus the amount of data received inside of an IP packet of type -.Tn ICMP -.Tn ECHO_REPLY -will always be 8 bytes more than the requested data space (the -.Tn ICMP -header). -.Pp -If the data space is at least -.Dv sizeof(struct timespec) -(16) large, -.Nm -uses the first -.Dv sizeof(struct timespec) -bytes to include a timestamp to compute round trip times. -Otherwise if the data space is at least eight bytes large (or the -.Fl C -flag is specified), -.Nm -uses the first eight bytes of this space to include a timestamp to compute -round trip times. -If there are not enough bytes of pad no round trip times are given. -.Sh DUPLICATE AND DAMAGED PACKETS -.Nm -will report duplicate and damaged packets. -Duplicate packets should never occur, and seem to be caused by -inappropriate link-level retransmissions. -Duplicates may occur in many situations and are rarely (if ever) a -good sign, although the presence of low levels of duplicates may not -always be cause for alarm. -.Pp -Damaged packets are obviously serious cause for alarm and often -indicate broken hardware somewhere in the -.Nm -packet's path (in the network or in the hosts). -.Sh TRYING DIFFERENT DATA PATTERNS -The (inter)network layer should never treat packets differently depending -on the data contained in the data portion. -Unfortunately, data-dependent problems have been known to sneak into -networks and remain undetected for long periods of time. -In many cases the particular pattern that will have problems is something -that doesn't have sufficient ``transitions'', such as all ones or all -zeros, or a pattern right at the edge, such as almost all zeros. -It isn't necessarily enough to specify a data pattern of all zeros (for -example) on the command line because the pattern that is of interest is -at the data link level, and the relationship between what you type and -what the controllers transmit can be complicated. -.Pp -This means that if you have a data-dependent problem you will probably -have to do a lot of testing to find it. -If you are lucky, you may manage to find a file that either can't be sent -across your network or that takes much longer to transfer than other -similar length files. -You can then examine this file for repeated patterns that you can test -using the -.Fl p -option of -.Nm . -.Sh TTL DETAILS -The -.Tn TTL -value of an IP packet represents the maximum number of IP routers -that the packet can go through before being thrown away. -In current practice you can expect each router in the Internet to decrement -the -.Tn TTL -field by exactly one. -.Pp -The -.Tn TCP/IP -specification states that the -.Tn TTL -field for -.Tn TCP -packets should -be set to 60, but many systems use smaller values -.Po -.Bx 4.3 -uses 30, -.Bx 4.2 -used 15 -.Pc . -.Pp -The maximum possible value of this field is 255, and most -.Ux -systems set the -.Tn TTL -field of -.Tn ICMP ECHO_REQUEST -packets to 255. -This is why you will find you can ``ping'' some hosts, but not reach them -with -.Xr telnet 1 -or -.Xr ftp 1 . -.Pp -In normal operation ping prints the ttl value from the packet it receives. -When a remote system receives a ping packet, it can do one of three things -with the -.Tn TTL -field in its response: -.Bl -bullet -.It -Not change it; this is what Berkeley -.Ux -systems did before the -.Bx 4.3 tahoe -release. -In this case the -.Tn TTL -value in the received packet will be 255 minus the -number of routers in the round-trip path. -.It -Set it to 255; this is what current Berkeley -.Ux -systems do. -In this case the -.Tn TTL -value in the received packet will be 255 minus the -number of routers in the path -.Em from -the remote system -.Em to -the -.Nm Ns Em ing -host. -.It -Set it to some other value. -Some machines use the same value for -.Tn ICMP -packets that they use for -.Tn TCP -packets, for example either 30 or 60. -Others may use completely wild values. -.El -.Sh EXIT STATUS -.Nm -returns 0 on success (the host is alive), -and non-zero if the arguments are incorrect or the host is not responding. -.Sh SEE ALSO -.Xr netstat 1 , -.Xr icmp 4 , -.Xr inet 4 , -.Xr ip 4 , -.Xr ifconfig 8 , -.Xr routed 8 , -.Xr spray 8 , -.Xr traceroute 8 -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.3 . -IPsec support was added by WIDE/KAME project. -.Sh BUGS -Flood pinging is not recommended in general, and flood pinging a broadcast -or multicast address should only be done under very controlled conditions. -.Pp -The -.Nm -program has evolved differently under different operating systems, -and in some cases the same flag performs a different function -under different operating systems. -The -.Fl t -flag conflicts with -.Fx . -The -.Fl a , c , I , i , -.Fl l , P , p , s , -and -.Fl t -flags conflict with -.Sy Solaris . -.Pp -Some hosts and gateways ignore the -.Tn RECORD_ROUTE -option. -.Pp -The maximum IP header length is too small for options like -.Tn RECORD_ROUTE -to -be completely useful. -There's not much that that can be done about this, however. diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c deleted file mode 100644 index 5cdae652c..000000000 --- a/sbin/ping/ping.c +++ /dev/null @@ -1,1924 +0,0 @@ -/* $NetBSD: ping.c,v 1.109 2014/11/29 14:48:42 christos Exp $ */ - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Muuss. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * P I N G . C - * - * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, - * measure round-trip-delays and packet loss across network paths. - * - * Author - - * Mike Muuss - * U. S. Army Ballistic Research Laboratory - * December, 1983 - * Modified at Uc Berkeley - * Record Route and verbose headers - Phil Dykstra, BRL, March 1988. - * Multicast options (ttl, if, loop) - Steve Deering, Stanford, August 1988. - * ttl, duplicate detection - Cliff Frost, UCB, April 1989 - * Pad pattern - Cliff Frost (from Tom Ferrin, UCSF), April 1989 - * - * Status - - * Public Domain. Distribution Unlimited. - * - * Bugs - - * More statistics could always be gathered. - * This program has to run SUID to ROOT to access the ICMP socket. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: ping.c,v 1.109 2014/11/29 14:48:42 christos Exp $"); -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef IPSEC -#include -#endif /*IPSEC*/ - -#include "prog_ops.h" - -#define FLOOD_INTVL 0.01 /* default flood output interval */ -#define MAXPACKET (IP_MAXPACKET-60-8) /* max packet size */ - -#define F_VERBOSE 0x0001 -#define F_QUIET 0x0002 /* minimize all output */ -#define F_SEMI_QUIET 0x0004 /* ignore our ICMP errors */ -#define F_FLOOD 0x0008 /* flood-ping */ -#define F_RECORD_ROUTE 0x0010 /* record route */ -#define F_SOURCE_ROUTE 0x0020 /* loose source route */ -#define F_PING_FILLED 0x0040 /* is buffer filled with user data? */ -#define F_PING_RANDOM 0x0080 /* use random data */ -#define F_NUMERIC 0x0100 /* do not do gethostbyaddr() calls */ -#define F_TIMING 0x0200 /* room for a timestamp */ -#define F_DF 0x0400 /* set IP DF bit */ -#define F_SOURCE_ADDR 0x0800 /* set source IP address/interface */ -#define F_ONCE 0x1000 /* exit(0) after receiving 1 reply */ -#define F_MCAST 0x2000 /* multicast target */ -#define F_MCAST_NOLOOP 0x4000 /* no multicast loopback */ -#define F_AUDIBLE 0x8000 /* audible output */ -#define F_TIMING64 0x10000 /* 64 bit time, nanoseconds */ -#ifdef IPSEC -#ifdef IPSEC_POLICY_IPSEC -#define F_POLICY 0x20000 -#else -#define F_AUTHHDR 0x20000 -#define F_ENCRYPT 0x40000 -#endif /*IPSEC_POLICY_IPSEC*/ -#endif /*IPSEC*/ - - -/* MAX_DUP_CHK is the number of bits in received table, the - * maximum number of received sequence numbers we can track to check - * for duplicates. - */ -#define MAX_DUP_CHK (8 * 2048) -static u_char rcvd_tbl[MAX_DUP_CHK/8]; -static int nrepeats = 0; -#define A(seq) rcvd_tbl[(seq/8)%sizeof(rcvd_tbl)] /* byte in array */ -#define B(seq) (1 << (seq & 0x07)) /* bit in byte */ -#define SET(seq) (A(seq) |= B(seq)) -#define CLR(seq) (A(seq) &= (~B(seq))) -#define TST(seq) (A(seq) & B(seq)) - -struct tv32 { - int32_t tv32_sec; - int32_t tv32_usec; -}; - - -static u_char *packet; -static int packlen; -static int pingflags = 0, options; -static int pongflags = 0; -static char *fill_pat; - -static int s; /* Socket file descriptor */ -static int sloop; /* Socket file descriptor/loopback */ - -#define PHDR_LEN sizeof(struct tv32) /* size of timestamp header */ -#define PHDR64_LEN sizeof(struct timespec) /* size of timestamp header */ -static struct sockaddr_in whereto, send_addr; /* Who to ping */ -static struct sockaddr_in src_addr; /* from where */ -static struct sockaddr_in loc_addr; /* 127.1 */ -static int datalen; /* How much data */ -static int phdrlen; - -#ifndef __NetBSD__ -static char *progname; -#define getprogname() (progname) -#define setprogname(name) ((void)(progname = (name))) -#endif - -static char hostname[MAXHOSTNAMELEN]; - -static struct { - struct ip o_ip; - char o_opt[MAX_IPOPTLEN]; - union { - u_char u_buf[MAXPACKET+offsetof(struct icmp, icmp_data)]; - struct icmp u_icmp; - } o_u; -} out_pack; -#define opack_icmp out_pack.o_u.u_icmp -static struct ip *opack_ip; - -static char optspace[MAX_IPOPTLEN]; /* record route space */ -static int optlen; - -static int npackets; /* total packets to send */ -static int preload; /* number of packets to "preload" */ -static int ntransmitted; /* output sequence # = #sent */ -static int ident; /* our ID, in network byte order */ - -static int nreceived; /* # of packets we got back */ - -static double interval; /* interval between packets */ -static struct timespec interval_tv; -static double tmin = 999999999.0; -static double tmax = 0.0; -static double tsum = 0.0; /* sum of all times */ -static double tsumsq = 0.0; -static double maxwait = 0.0; - -static int bufspace = IP_MAXPACKET; - -static struct timespec now, clear_cache, last_tx, next_tx, first_tx; -static struct timespec last_rx, first_rx; -static int lastrcvd = 1; /* last ping sent has been received */ - -static struct timespec jiggle_time; -static int jiggle_cnt, total_jiggled, jiggle_direction = -1; - -__dead static void doit(void); -static void prefinish(int); -static void prtsig(int); -__dead static void finish(int); -static void summary(int); -static void pinger(void); -static void fill(void); -static void rnd_fill(void); -static double diffsec(struct timespec *, struct timespec *); -#if 0 -static void timespecadd(struct timespec *, struct timespec *); -#endif -static void sec_to_timespec(const double, struct timespec *); -static double timespec_to_sec(const struct timespec *); -static void pr_pack(u_char *, int, struct sockaddr_in *); -static u_int16_t in_cksum(u_int16_t *, u_int); -static void pr_saddr(u_char *); -static char *pr_addr(struct in_addr *); -static void pr_iph(struct icmp *, int); -static void pr_retip(struct icmp *, int); -static int pr_icmph(struct icmp *, struct sockaddr_in *, int); -static void jiggle(int), jiggle_flush(int); -static void gethost(const char *, const char *, - struct sockaddr_in *, char *, int); -__dead static void usage(void); - -int -main(int argc, char *argv[]) -{ - int c, i, on = 1, hostind = 0; - long l; - int len = -1, compat = 0; - u_char ttl = 0; - u_long tos = 0; - char *p; -#ifdef IPSEC -#ifdef IPSEC_POLICY_IPSEC - char *policy_in = NULL; - char *policy_out = NULL; -#endif -#endif -#ifdef SIGINFO - struct sigaction sa; -#endif - - if (prog_init && prog_init() == -1) - err(EXIT_FAILURE, "init failed"); - - if ((s = prog_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) - err(EXIT_FAILURE, "Cannot create socket"); - if ((sloop = prog_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) - err(EXIT_FAILURE, "Cannot create socket"); - - /* - * sloop is never read on. This prevents packets from - * queueing in its recv buffer. - */ - if (prog_shutdown(sloop, SHUT_RD) == -1) - warn("Cannot shutdown for read"); - - if (prog_setuid(prog_getuid()) == -1) - err(EXIT_FAILURE, "setuid"); - - setprogname(argv[0]); - -#ifndef IPSEC -#define IPSECOPT -#else -#ifdef IPSEC_POLICY_IPSEC -#define IPSECOPT "E:" -#else -#define IPSECOPT "AE" -#endif /*IPSEC_POLICY_IPSEC*/ -#endif - while ((c = getopt(argc, argv, - "ac:CdDfg:h:i:I:l:Lnop:PqQrRs:t:T:vw:" IPSECOPT)) != -1) { -#undef IPSECOPT - switch (c) { - case 'a': - pingflags |= F_AUDIBLE; - break; - case 'C': - compat = 1; - break; - case 'c': - npackets = strtol(optarg, &p, 0); - if (*p != '\0' || npackets <= 0) - errx(EXIT_FAILURE, - "Bad/invalid number of packets: %s", - optarg); - break; - case 'D': - pingflags |= F_DF; - break; - case 'd': - options |= SO_DEBUG; - break; - case 'f': - pingflags |= F_FLOOD; - break; - case 'h': - hostind = optind-1; - break; - case 'i': /* wait between sending packets */ - interval = strtod(optarg, &p); - if (*p != '\0' || interval <= 0) - errx(EXIT_FAILURE, "Bad/invalid interval: %s", - optarg); - break; - case 'l': - preload = strtol(optarg, &p, 0); - if (*p != '\0' || preload < 0) - errx(EXIT_FAILURE, "Bad/invalid preload value: " - "%s", optarg); - break; - case 'n': - pingflags |= F_NUMERIC; - break; - case 'o': - pingflags |= F_ONCE; - break; - case 'p': /* fill buffer with user pattern */ - if (pingflags & F_PING_RANDOM) - errx(EXIT_FAILURE, - "Only one of -P and -p allowed"); - pingflags |= F_PING_FILLED; - fill_pat = optarg; - break; - case 'P': - if (pingflags & F_PING_FILLED) - errx(EXIT_FAILURE, - "Only one of -P and -p allowed"); - pingflags |= F_PING_RANDOM; - break; - case 'q': - pingflags |= F_QUIET; - break; - case 'Q': - pingflags |= F_SEMI_QUIET; - break; - case 'r': - options |= SO_DONTROUTE; - break; - case 's': /* size of packet to send */ - l = strtol(optarg, &p, 0); - if (*p != '\0' || l < 0) - errx(EXIT_FAILURE, - "Bad/invalid packet size: %s", optarg); - if (l > MAXPACKET) - errx(EXIT_FAILURE, "packet size is too large"); - len = (int)l; - break; - case 'v': - pingflags |= F_VERBOSE; - break; - case 'R': - pingflags |= F_RECORD_ROUTE; - break; - case 'L': - pingflags |= F_MCAST_NOLOOP; - break; - case 't': - tos = strtoul(optarg, &p, 0); - if (*p != '\0' || tos > 0xFF) - errx(EXIT_FAILURE, "bad tos value: %s", optarg); - break; - case 'T': - l = strtol(optarg, &p, 0); - if (*p != '\0' || l > 255 || l <= 0) - errx(EXIT_FAILURE, "ttl out of range: %s", - optarg); - ttl = (u_char)l; /* cannot check >255 otherwise */ - break; - case 'I': - pingflags |= F_SOURCE_ADDR; - gethost("-I", optarg, &src_addr, 0, 0); - break; - case 'g': - pingflags |= F_SOURCE_ROUTE; - gethost("-g", optarg, &send_addr, 0, 0); - break; - case 'w': - maxwait = strtod(optarg, &p); - if (*p != '\0' || maxwait <= 0) - errx(EXIT_FAILURE, "Bad/invalid maxwait time: " - "%s", optarg); - break; -#ifdef IPSEC -#ifdef IPSEC_POLICY_IPSEC - case 'E': - pingflags |= F_POLICY; - if (!strncmp("in", optarg, 2)) { - policy_in = strdup(optarg); - if (!policy_in) - err(EXIT_FAILURE, "strdup"); - } else if (!strncmp("out", optarg, 3)) { - policy_out = strdup(optarg); - if (!policy_out) - err(EXIT_FAILURE, "strdup"); - } else - errx(EXIT_FAILURE, "invalid security policy: " - "%s", optarg); - break; -#else - case 'A': - pingflags |= F_AUTHHDR; - break; - case 'E': - pingflags |= F_ENCRYPT; - break; -#endif /*IPSEC_POLICY_IPSEC*/ -#endif /*IPSEC*/ - default: - usage(); - break; - } - } - - if (interval == 0) - interval = (pingflags & F_FLOOD) ? FLOOD_INTVL : 1.0; -#ifndef sgi - if (pingflags & F_FLOOD && prog_getuid()) - errx(EXIT_FAILURE, "Must be superuser to use -f"); - if (interval < 1.0 && prog_getuid()) - errx(EXIT_FAILURE, "Must be superuser to use < 1 sec " - "ping interval"); - if (preload > 0 && prog_getuid()) - errx(EXIT_FAILURE, "Must be superuser to use -l"); -#endif - sec_to_timespec(interval, &interval_tv); - - if ((pingflags & (F_AUDIBLE|F_FLOOD)) == (F_AUDIBLE|F_FLOOD)) - warnx("Sorry, no audible output for flood pings"); - - if (npackets != 0) { - npackets += preload; - } else { - npackets = INT_MAX; - } - - if (hostind == 0) { - if (optind != argc-1) - usage(); - else - hostind = optind; - } - else if (hostind >= argc - 1) - usage(); - - gethost("", argv[hostind], &whereto, hostname, sizeof(hostname)); - if (IN_MULTICAST(ntohl(whereto.sin_addr.s_addr))) - pingflags |= F_MCAST; - if (!(pingflags & F_SOURCE_ROUTE)) - (void) memcpy(&send_addr, &whereto, sizeof(send_addr)); - - loc_addr.sin_family = AF_INET; - loc_addr.sin_len = sizeof(struct sockaddr_in); - loc_addr.sin_addr.s_addr = htonl((127 << 24) + 1); - - if (len != -1) - datalen = len; - else - datalen = 64 - PHDR_LEN; - if (!compat && datalen >= (int)PHDR64_LEN) { /* can we time them? */ - pingflags |= F_TIMING64; - phdrlen = PHDR64_LEN; - } else if (datalen >= (int)PHDR_LEN) { /* can we time them? */ - pingflags |= F_TIMING; - phdrlen = PHDR_LEN; - } else - phdrlen = 0; - - packlen = datalen + 60 + 76; /* MAXIP + MAXICMP */ - if ((packet = malloc(packlen)) == NULL) - err(EXIT_FAILURE, "Can't allocate %d bytes", packlen); - - if (pingflags & F_PING_FILLED) { - fill(); - } else if (pingflags & F_PING_RANDOM) { - rnd_fill(); - } else { - for (i = phdrlen; i < datalen; i++) - opack_icmp.icmp_data[i] = i; - } - - ident = arc4random() & 0xFFFF; - - if (options & SO_DEBUG) { - if (prog_setsockopt(s, SOL_SOCKET, SO_DEBUG, - (char *)&on, sizeof(on)) == -1) - warn("Can't turn on socket debugging"); - } - if (options & SO_DONTROUTE) { - if (prog_setsockopt(s, SOL_SOCKET, SO_DONTROUTE, - (char *)&on, sizeof(on)) == -1) - warn("SO_DONTROUTE"); - } - - if (options & SO_DEBUG) { - if (prog_setsockopt(sloop, SOL_SOCKET, SO_DEBUG, - (char *)&on, sizeof(on)) == -1) - warn("Can't turn on socket debugging"); - } - if (options & SO_DONTROUTE) { - if (prog_setsockopt(sloop, SOL_SOCKET, SO_DONTROUTE, - (char *)&on, sizeof(on)) == -1) - warn("SO_DONTROUTE"); - } - - if (pingflags & F_SOURCE_ROUTE) { - optspace[IPOPT_OPTVAL] = IPOPT_LSRR; - optspace[IPOPT_OLEN] = optlen = 7; - optspace[IPOPT_OFFSET] = IPOPT_MINOFF; - (void)memcpy(&optspace[IPOPT_MINOFF-1], &whereto.sin_addr, - sizeof(whereto.sin_addr)); - optspace[optlen++] = IPOPT_NOP; - } - if (pingflags & F_RECORD_ROUTE) { - optspace[optlen+IPOPT_OPTVAL] = IPOPT_RR; - optspace[optlen+IPOPT_OLEN] = (MAX_IPOPTLEN -1-optlen); - optspace[optlen+IPOPT_OFFSET] = IPOPT_MINOFF; - optlen = MAX_IPOPTLEN; - } - /* this leaves opack_ip 0(mod 4) aligned */ - opack_ip = (struct ip *)((char *)&out_pack.o_ip - + sizeof(out_pack.o_opt) - - optlen); - (void) memcpy(opack_ip + 1, optspace, optlen); - - if (prog_setsockopt(s, IPPROTO_IP, IP_HDRINCL, - (char *) &on, sizeof(on)) < 0) - err(EXIT_FAILURE, "Can't set special IP header"); - - opack_ip->ip_v = IPVERSION; - opack_ip->ip_hl = (sizeof(struct ip)+optlen) >> 2; - opack_ip->ip_tos = tos; - opack_ip->ip_off = (pingflags & F_DF) ? IP_DF : 0; - opack_ip->ip_ttl = ttl ? ttl : MAXTTL; - opack_ip->ip_p = IPPROTO_ICMP; - opack_ip->ip_src = src_addr.sin_addr; - opack_ip->ip_dst = send_addr.sin_addr; - - if (pingflags & F_MCAST) { - if (pingflags & F_MCAST_NOLOOP) { - u_char loop = 0; - if (prog_setsockopt(s, IPPROTO_IP, - IP_MULTICAST_LOOP, - (char *) &loop, 1) < 0) - err(EXIT_FAILURE, "Can't disable multicast loopback"); - } - - if (ttl != 0 - && prog_setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, - (char *) &ttl, 1) < 0) - err(EXIT_FAILURE, "Can't set multicast time-to-live"); - - if ((pingflags & F_SOURCE_ADDR) - && prog_setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, - (char *) &src_addr.sin_addr, - sizeof(src_addr.sin_addr)) < 0) - err(EXIT_FAILURE, "Can't set multicast source interface"); - - } else if (pingflags & F_SOURCE_ADDR) { - if (prog_setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, - (char *) &src_addr.sin_addr, - sizeof(src_addr.sin_addr)) < 0) - err(EXIT_FAILURE, "Can't set source interface/address"); - } -#ifdef IPSEC -#ifdef IPSEC_POLICY_IPSEC - { - char *buf; - if (pingflags & F_POLICY) { - if (policy_in != NULL) { - buf = ipsec_set_policy(policy_in, strlen(policy_in)); - if (buf == NULL) - errx(EXIT_FAILURE, "%s", ipsec_strerror()); - if (prog_setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY, - buf, ipsec_get_policylen(buf)) < 0) { - err(EXIT_FAILURE, "ipsec policy cannot be " - "configured"); - } - free(buf); - } - if (policy_out != NULL) { - buf = ipsec_set_policy(policy_out, strlen(policy_out)); - if (buf == NULL) - errx(EXIT_FAILURE, "%s", ipsec_strerror()); - if (prog_setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY, - buf, ipsec_get_policylen(buf)) < 0) { - err(EXIT_FAILURE, "ipsec policy cannot be " - "configured"); - } - free(buf); - } - } - buf = ipsec_set_policy("out bypass", strlen("out bypass")); - if (buf == NULL) - errx(EXIT_FAILURE, "%s", ipsec_strerror()); - if (prog_setsockopt(sloop, IPPROTO_IP, IP_IPSEC_POLICY, - buf, ipsec_get_policylen(buf)) < 0) { -#if 0 - warnx("ipsec is not configured"); -#else - /* ignore it, should be okay */ -#endif - } - free(buf); - } -#else - { - int optval; - if (pingflags & F_AUTHHDR) { - optval = IPSEC_LEVEL_REQUIRE; -#ifdef IP_AUTH_TRANS_LEVEL - (void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, - (char *)&optval, sizeof(optval)); -#else - (void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_LEVEL, - (char *)&optval, sizeof(optval)); -#endif - } - if (pingflags & F_ENCRYPT) { - optval = IPSEC_LEVEL_REQUIRE; - (void)prog_setsockopt(s, IPPROTO_IP, IP_ESP_TRANS_LEVEL, - (char *)&optval, sizeof(optval)); - } - optval = IPSEC_LEVEL_BYPASS; -#ifdef IP_AUTH_TRANS_LEVEL - (void)prog_setsockopt(sloop, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, - (char *)&optval, sizeof(optval)); -#else - (void)prog_setsockopt(sloop, IPPROTO_IP, IP_AUTH_LEVEL, - (char *)&optval, sizeof(optval)); -#endif - (void)prog_setsockopt(sloop, IPPROTO_IP, IP_ESP_TRANS_LEVEL, - (char *)&optval, sizeof(optval)); - } -#endif /*IPSEC_POLICY_IPSEC*/ -#endif /*IPSEC*/ - - (void)printf("PING %s (%s): %d data bytes\n", hostname, - inet_ntoa(whereto.sin_addr), datalen); - - /* When pinging the broadcast address, you can get a lot - * of answers. Doing something so evil is useful if you - * are trying to stress the ethernet, or just want to - * fill the arp cache to get some stuff for /etc/ethers. - */ - while (0 > prog_setsockopt(s, SOL_SOCKET, SO_RCVBUF, - (char*)&bufspace, sizeof(bufspace))) { - if ((bufspace -= 4096) <= 0) - err(EXIT_FAILURE, "Cannot set the receive buffer size"); - } - - /* make it possible to send giant probes, but do not worry now - * if it fails, since we probably won't send giant probes. - */ - (void)prog_setsockopt(s, SOL_SOCKET, SO_SNDBUF, - (char*)&bufspace, sizeof(bufspace)); - - (void)signal(SIGINT, prefinish); - -#ifdef SIGINFO - sa.sa_handler = prtsig; - sa.sa_flags = SA_NOKERNINFO; - sigemptyset(&sa.sa_mask); - (void)sigaction(SIGINFO, &sa, NULL); -#else - (void)signal(SIGQUIT, prtsig); -#endif - (void)signal(SIGCONT, prtsig); - - /* fire off them quickies */ - for (i = 0; i < preload; i++) { - clock_gettime(CLOCK_MONOTONIC, &now); - pinger(); - } - - doit(); - return 0; -} - - -static void -doit(void) -{ - int cc; - struct sockaddr_in from; - socklen_t fromlen; - double sec, last, d_last; - struct pollfd fdmaskp[1]; - - (void)clock_gettime(CLOCK_MONOTONIC, &clear_cache); - if (maxwait != 0) { - last = timespec_to_sec(&clear_cache) + maxwait; - d_last = 0; - } else { - last = 0; - d_last = 365*24*60*60; - } - - do { - clock_gettime(CLOCK_MONOTONIC, &now); - - if (last != 0) - d_last = last - timespec_to_sec(&now); - - if (ntransmitted < npackets && d_last > 0) { - /* send if within 100 usec or late for next packet */ - sec = diffsec(&next_tx, &now); - if (sec <= 0.0001 || - (lastrcvd && (pingflags & F_FLOOD))) { - pinger(); - sec = diffsec(&next_tx, &now); - } - if (sec < 0.0) - sec = 0.0; - if (d_last < sec) - sec = d_last; - - } else { - /* For the last response, wait twice as long as the - * worst case seen, or 10 times as long as the - * maximum interpacket interval, whichever is longer. - */ - sec = MAX(2 * tmax, 10 * interval) - - diffsec(&now, &last_tx); - if (d_last < sec) - sec = d_last; - if (sec <= 0) - break; - } - - fdmaskp[0].fd = s; - fdmaskp[0].events = POLLIN; - cc = prog_poll(fdmaskp, 1, (int)(sec * 1000)); - if (cc <= 0) { - if (cc < 0) { - if (errno == EINTR) - continue; - jiggle_flush(1); - err(EXIT_FAILURE, "poll"); - } - continue; - } - - fromlen = sizeof(from); - cc = prog_recvfrom(s, (char *) packet, packlen, - 0, (struct sockaddr *)&from, - &fromlen); - if (cc < 0) { - if (errno != EINTR) { - jiggle_flush(1); - warn("recvfrom"); - (void)fflush(stderr); - } - continue; - } - clock_gettime(CLOCK_MONOTONIC, &now); - pr_pack(packet, cc, &from); - - } while (nreceived < npackets - && (nreceived == 0 || !(pingflags & F_ONCE))); - - finish(0); -} - - -static void -jiggle_flush(int nl) /* new line if there are dots */ -{ - int serrno = errno; - - if (jiggle_cnt > 0) { - total_jiggled += jiggle_cnt; - jiggle_direction = 1; - do { - (void)putchar('.'); - } while (--jiggle_cnt > 0); - - } else if (jiggle_cnt < 0) { - total_jiggled -= jiggle_cnt; - jiggle_direction = -1; - do { - (void)putchar('\b'); - } while (++jiggle_cnt < 0); - } - - if (nl) { - if (total_jiggled != 0) - (void)putchar('\n'); - total_jiggled = 0; - jiggle_direction = -1; - } - - (void)fflush(stdout); - (void)fflush(stderr); - jiggle_time = now; - errno = serrno; -} - - -/* jiggle the cursor for flood-ping - */ -static void -jiggle(int delta) -{ - double dt; - - if (pingflags & F_QUIET) - return; - - /* do not back up into messages */ - if (total_jiggled+jiggle_cnt+delta < 0) - return; - - jiggle_cnt += delta; - - /* flush the FLOOD dots when things are quiet - * or occassionally to make the cursor jiggle. - */ - dt = diffsec(&last_tx, &jiggle_time); - if (dt > 0.2 || (dt >= 0.15 && delta*jiggle_direction < 0)) - jiggle_flush(0); -} - - -/* - * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet - * will be added on by the kernel. The ID field is our UNIX process ID, - * and the sequence number is an ascending integer. The first phdrlen bytes - * of the data portion are used to hold a UNIX "timeval" struct in VAX - * byte-order, to compute the round-trip time, or a UNIX "timespec" in native - * format. - */ -static void -pinger(void) -{ - struct tv32 tv32; -#if !defined(__minix) - int i, cc, sw; -#else - int i, cc; -#endif /* !defined(__minix) */ - - opack_icmp.icmp_code = 0; - opack_icmp.icmp_seq = htons((u_int16_t)(ntransmitted)); - -#if !defined(__minix) - /* clear the cached route in the kernel after an ICMP - * response such as a Redirect is seen to stop causing - * more such packets. Also clear the cached route - * periodically in case of routing changes that make - * black holes come and go. - */ - if (clear_cache.tv_sec != now.tv_sec) { - opack_icmp.icmp_type = ICMP_ECHOREPLY; - opack_icmp.icmp_id = ~ident; - opack_icmp.icmp_cksum = 0; - opack_icmp.icmp_cksum = in_cksum((u_int16_t *)&opack_icmp, - phdrlen); - sw = 0; - if (prog_setsockopt(sloop, IPPROTO_IP, IP_HDRINCL, - (char *)&sw, sizeof(sw)) < 0) - err(EXIT_FAILURE, "Can't turn off special IP header"); - if (prog_sendto(sloop, (char *) &opack_icmp, - ICMP_MINLEN, MSG_DONTROUTE, - (struct sockaddr *)&loc_addr, - sizeof(struct sockaddr_in)) < 0) { - /* - * XXX: we only report this as a warning in verbose - * mode because people get confused when they see - * this error when they are running in single user - * mode and they have not configured lo0 - */ - if (pingflags & F_VERBOSE) - warn("failed to clear cached route"); - } - sw = 1; - if (prog_setsockopt(sloop, IPPROTO_IP, IP_HDRINCL, - (char *)&sw, sizeof(sw)) < 0) - err(EXIT_FAILURE, "Can't set special IP header"); - - (void)clock_gettime(CLOCK_MONOTONIC, &clear_cache); - } -#endif /* !defined(__minix) */ - - opack_icmp.icmp_type = ICMP_ECHO; - opack_icmp.icmp_id = ident; - - if (pingflags & F_TIMING) { - tv32.tv32_sec = (uint32_t)htonl(now.tv_sec); - tv32.tv32_usec = htonl(now.tv_nsec / 1000); - (void) memcpy(&opack_icmp.icmp_data[0], &tv32, sizeof(tv32)); - } else if (pingflags & F_TIMING64) - (void) memcpy(&opack_icmp.icmp_data[0], &now, sizeof(now)); - - cc = MAX(datalen, ICMP_MINLEN) + PHDR_LEN; - opack_icmp.icmp_cksum = 0; - opack_icmp.icmp_cksum = in_cksum((u_int16_t *)&opack_icmp, cc); - - cc += opack_ip->ip_hl<<2; - opack_ip->ip_len = cc; - i = prog_sendto(s, (char *) opack_ip, cc, 0, - (struct sockaddr *)&send_addr, sizeof(struct sockaddr_in)); - if (i != cc) { - jiggle_flush(1); - if (i < 0) - warn("sendto"); - else - warnx("wrote %s %d chars, ret=%d", hostname, cc, i); - (void)fflush(stderr); - } - lastrcvd = 0; - - CLR(ntransmitted); - ntransmitted++; - - last_tx = now; - if (next_tx.tv_sec == 0) { - first_tx = now; - next_tx = now; - } - - /* Transmit regularly, at always the same microsecond in the - * second when going at one packet per second. - * If we are at most 100 ms behind, send extras to get caught up. - * Otherwise, skip packets we were too slow to send. - */ - if (diffsec(&next_tx, &now) <= interval) { - do { - timespecadd(&next_tx, &interval_tv, &next_tx); - } while (diffsec(&next_tx, &now) < -0.1); - } - - if (pingflags & F_FLOOD) - jiggle(1); - - /* While the packet is going out, ready buffer for the next - * packet. Use a fast but not very good random number generator. - */ - if (pingflags & F_PING_RANDOM) - rnd_fill(); -} - - -static void -pr_pack_sub(int cc, - char *addr, - int seqno, - int dupflag, - int ttl, - double triptime) -{ - jiggle_flush(1); - - if (pingflags & F_FLOOD) - return; - - (void)printf("%d bytes from %s: icmp_seq=%u", cc, addr, seqno); - if (dupflag) - (void)printf(" DUP!"); - (void)printf(" ttl=%d", ttl); - if (pingflags & (F_TIMING|F_TIMING64)) { - const unsigned int prec = (pingflags & F_TIMING64) != 0 ? 6 : 3; - - (void)printf(" time=%.*f ms", prec, triptime*1000.0); - } - - /* - * Send beep to stderr, since that's more likely than stdout - * to go to a terminal.. - */ - if (pingflags & F_AUDIBLE && !dupflag) - (void)fprintf(stderr,"\a"); -} - - -/* - * Print out the packet, if it came from us. This logic is necessary - * because ALL readers of the ICMP socket get a copy of ALL ICMP packets - * which arrive ('tis only fair). This permits multiple copies of this - * program to be run without having intermingled output (or statistics!). - */ -static void -pr_pack(u_char *buf, - int tot_len, - struct sockaddr_in *from) -{ - struct ip *ip; - struct icmp *icp; - int i, j, net_len; - u_char *cp; - static int old_rrlen; - static char old_rr[MAX_IPOPTLEN]; - int hlen, dupflag = 0, dumped; - double triptime = 0.0; -#define PR_PACK_SUB() {if (!dumped) { \ - dumped = 1; \ - pr_pack_sub(net_len, inet_ntoa(from->sin_addr), \ - ntohs((u_int16_t)icp->icmp_seq), \ - dupflag, ip->ip_ttl, triptime);}} - - /* Check the IP header */ - ip = (struct ip *) buf; - hlen = ip->ip_hl << 2; - if (tot_len < hlen + ICMP_MINLEN) { - if (pingflags & F_VERBOSE) { - jiggle_flush(1); - (void)printf("packet too short (%d bytes) from %s\n", - tot_len, inet_ntoa(from->sin_addr)); - } - return; - } - - /* Now the ICMP part */ - dumped = 0; - net_len = tot_len - hlen; - icp = (struct icmp *)(buf + hlen); - if (icp->icmp_type == ICMP_ECHOREPLY - && icp->icmp_id == ident) { - - if (icp->icmp_seq == htons((u_int16_t)(ntransmitted-1))) - lastrcvd = 1; - last_rx = now; - if (first_rx.tv_sec == 0) - first_rx = last_rx; - nreceived++; - if (pingflags & (F_TIMING|F_TIMING64)) { - struct timespec tv; - - if (pingflags & F_TIMING) { - struct tv32 tv32; - - (void)memcpy(&tv32, icp->icmp_data, sizeof(tv32)); - tv.tv_sec = (uint32_t)ntohl(tv32.tv32_sec); - tv.tv_nsec = ntohl(tv32.tv32_usec) * 1000; - } else if (pingflags & F_TIMING64) - (void)memcpy(&tv, icp->icmp_data, sizeof(tv)); - else - memset(&tv, 0, sizeof(tv)); /* XXX: gcc */ - - triptime = diffsec(&last_rx, &tv); - tsum += triptime; - tsumsq += triptime * triptime; - if (triptime < tmin) - tmin = triptime; - if (triptime > tmax) - tmax = triptime; - } - - if (TST(ntohs((u_int16_t)icp->icmp_seq))) { - nrepeats++, nreceived--; - dupflag=1; - } else { - SET(ntohs((u_int16_t)icp->icmp_seq)); - } - - if (tot_len != opack_ip->ip_len) { - PR_PACK_SUB(); - switch (opack_ip->ip_len - tot_len) { - case MAX_IPOPTLEN: - if ((pongflags & F_RECORD_ROUTE) != 0) - break; - if ((pingflags & F_RECORD_ROUTE) == 0) - goto out; - pongflags |= F_RECORD_ROUTE; - (void)printf("\nremote host does not " - "support record route"); - break; - case 8: - if ((pongflags & F_SOURCE_ROUTE) != 0) - break; - if ((pingflags & F_SOURCE_ROUTE) == 0) - goto out; - pongflags |= F_SOURCE_ROUTE; - (void)printf("\nremote host does not " - "support source route"); - break; - default: - out: - (void)printf("\nwrong total length %d " - "instead of %d", tot_len, opack_ip->ip_len); - break; - } - } - - if (!dupflag) { - static u_int16_t last_seqno = 0xffff; - u_int16_t seqno = ntohs((u_int16_t)icp->icmp_seq); - u_int16_t gap = seqno - (last_seqno + 1); - if (gap > 0 && gap < 0x8000 && - (pingflags & F_VERBOSE)) { - (void)printf("[*** sequence gap of %u " - "packets from %u ... %u ***]\n", gap, - (u_int16_t) (last_seqno + 1), - (u_int16_t) (seqno - 1)); - if (pingflags & F_QUIET) - summary(0); - } - - if (gap < 0x8000) - last_seqno = seqno; - } - - if (pingflags & F_QUIET) - return; - - if (!(pingflags & F_FLOOD)) - PR_PACK_SUB(); - - /* check the data */ - if ((size_t)(tot_len - hlen) > - offsetof(struct icmp, icmp_data) + datalen - && !(pingflags & F_PING_RANDOM) - && memcmp(icp->icmp_data + phdrlen, - opack_icmp.icmp_data + phdrlen, - datalen - phdrlen)) { - for (i = phdrlen; i < datalen; i++) { - if (icp->icmp_data[i] != - opack_icmp.icmp_data[i]) - break; - } - PR_PACK_SUB(); - (void)printf("\nwrong data byte #%d should have been" - " %#x but was %#x", i - phdrlen, - (u_char)opack_icmp.icmp_data[i], - (u_char)icp->icmp_data[i]); - for (i = phdrlen; i < datalen; i++) { - if ((i % 16) == 0) - (void)printf("\n\t"); - (void)printf("%2x ",(u_char)icp->icmp_data[i]); - } - } - - } else { - if (!pr_icmph(icp, from, net_len)) - return; - dumped = 2; - } - - /* Display any IP options */ - cp = buf + sizeof(struct ip); - while (hlen > (int)sizeof(struct ip)) { - switch (*cp) { - case IPOPT_EOL: - hlen = 0; - break; - case IPOPT_LSRR: - hlen -= 2; - j = *++cp; - ++cp; - j -= IPOPT_MINOFF; - if (j <= 0) - continue; - if (dumped <= 1) { - j = ((j+3)/4)*4; - hlen -= j; - cp += j; - break; - } - PR_PACK_SUB(); - (void)printf("\nLSRR: "); - for (;;) { - pr_saddr(cp); - cp += 4; - hlen -= 4; - j -= 4; - if (j <= 0) - break; - (void)putchar('\n'); - } - break; - case IPOPT_RR: - j = *++cp; /* get length */ - i = *++cp; /* and pointer */ - hlen -= 2; - if (i > j) - i = j; - i -= IPOPT_MINOFF; - if (i <= 0) - continue; - if (dumped <= 1) { - if (i == old_rrlen - && !memcmp(cp, old_rr, i)) { - if (dumped) - (void)printf("\t(same route)"); - j = ((i+3)/4)*4; - hlen -= j; - cp += j; - break; - } - old_rrlen = i; - (void) memcpy(old_rr, cp, i); - } - if (!dumped) { - jiggle_flush(1); - (void)printf("RR: "); - dumped = 1; - } else { - (void)printf("\nRR: "); - } - for (;;) { - pr_saddr(cp); - cp += 4; - hlen -= 4; - i -= 4; - if (i <= 0) - break; - (void)putchar('\n'); - } - break; - case IPOPT_NOP: - if (dumped <= 1) - break; - PR_PACK_SUB(); - (void)printf("\nNOP"); - break; -#ifdef sgi - case IPOPT_SECURITY: /* RFC 1108 RIPSO BSO */ - case IPOPT_ESO: /* RFC 1108 RIPSO ESO */ - case IPOPT_CIPSO: /* Commercial IPSO */ - if ((sysconf(_SC_IP_SECOPTS)) > 0) { - i = (unsigned)cp[1]; - hlen -= i - 1; - PR_PACK_SUB(); - (void)printf("\nSEC:"); - while (i--) { - (void)printf(" %02x", *cp++); - } - cp--; - break; - } -#endif - default: - PR_PACK_SUB(); - (void)printf("\nunknown option 0x%x", *cp); - break; - } - hlen--; - cp++; - } - - if (dumped) { - (void)putchar('\n'); - (void)fflush(stdout); - } else { - jiggle(-1); - } -} - - -/* Compute the IP checksum - * This assumes the packet is less than 32K long. - */ -static u_int16_t -in_cksum(u_int16_t *p, u_int len) -{ - u_int32_t sum = 0; - int nwords = len >> 1; - - while (nwords-- != 0) - sum += *p++; - - if (len & 1) { - union { - u_int16_t w; - u_int8_t c[2]; - } u; - u.c[0] = *(u_char *)p; - u.c[1] = 0; - sum += u.w; - } - - /* end-around-carry */ - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - return (~sum); -} - - -/* - * compute the difference of two timespecs in seconds - */ -static double -diffsec(struct timespec *timenow, - struct timespec *then) -{ - if (timenow->tv_sec == 0) - return -1; - return (timenow->tv_sec - then->tv_sec) - * 1.0 + (timenow->tv_nsec - then->tv_nsec) / 1000000000.0; -} - - -#if 0 -static void -timespecadd(struct timespec *t1, - struct timespec *t2) -{ - - t1->tv_sec += t2->tv_sec; - if ((t1->tv_nsec += t2->tv_nsec) >= 1000000000) { - t1->tv_sec++; - t1->tv_nsec -= 1000000000; - } -} -#endif - - -static void -sec_to_timespec(const double sec, struct timespec *tp) -{ - tp->tv_sec = sec; - tp->tv_nsec = (sec - tp->tv_sec) * 1000000000.0; -} - - -static double -timespec_to_sec(const struct timespec *tp) -{ - return tp->tv_sec + tp->tv_nsec / 1000000000.0; -} - - -/* - * Print statistics. - * Heavily buffered STDIO is used here, so that all the statistics - * will be written with 1 sys-write call. This is nice when more - * than one copy of the program is running on a terminal; it prevents - * the statistics output from becomming intermingled. - */ -static void -summary(int header) -{ - jiggle_flush(1); - - if (header) - (void)printf("\n----%s PING Statistics----\n", hostname); - (void)printf("%d packets transmitted, ", ntransmitted); - (void)printf("%d packets received, ", nreceived); - if (nrepeats) - (void)printf("+%d duplicates, ", nrepeats); - if (ntransmitted) { - if (nreceived > ntransmitted) - (void)printf("-- somebody's duplicating packets!"); - else - (void)printf("%.1f%% packet loss", - (((ntransmitted-nreceived)*100.0) / - ntransmitted)); - } - (void)printf("\n"); - if (nreceived && (pingflags & (F_TIMING|F_TIMING64))) { - double n = nreceived + nrepeats; - double avg = (tsum / n); - double variance = 0.0; - const unsigned int prec = (pingflags & F_TIMING64) != 0 ? 6 : 3; - if (n>1) - variance = (tsumsq - n*avg*avg) /(n-1); - - (void)printf("round-trip min/avg/max/stddev = " - "%.*f/%.*f/%.*f/%.*f ms\n", - prec, tmin * 1000.0, - prec, avg * 1000.0, - prec, tmax * 1000.0, - prec, sqrt(variance) * 1000.0); - if (pingflags & F_FLOOD) { - double r = diffsec(&last_rx, &first_rx); - double t = diffsec(&last_tx, &first_tx); - if (r == 0) - r = 0.0001; - if (t == 0) - t = 0.0001; - (void)printf(" %.1f packets/sec sent, " - " %.1f packets/sec received\n", - ntransmitted/t, nreceived/r); - } - } -} - - -/* - * Print statistics when SIGINFO is received. - */ -/* ARGSUSED */ -static void -prtsig(int dummy) -{ - - summary(0); -#ifndef SIGINFO - (void)signal(SIGQUIT, prtsig); -#endif -} - - -/* - * On the first SIGINT, allow any outstanding packets to dribble in - */ -static void -prefinish(int dummy) -{ - if (lastrcvd /* quit now if caught up */ - || nreceived == 0) /* or if remote is dead */ - finish(0); - - (void)signal(dummy, finish); /* do this only the 1st time */ - - if (npackets > ntransmitted) /* let the normal limit work */ - npackets = ntransmitted; -} - -/* - * Print statistics and give up. - */ -/* ARGSUSED */ -static void -finish(int dummy) -{ -#ifdef SIGINFO - (void)signal(SIGINFO, SIG_DFL); -#else - (void)signal(SIGQUIT, SIG_DFL); -#endif - - summary(1); - exit(nreceived > 0 ? 0 : 2); -} - - -static int /* 0=do not print it */ -ck_pr_icmph(struct icmp *icp, - struct sockaddr_in *from, - int cc, - int override) /* 1=override VERBOSE if interesting */ -{ - int hlen; - struct ip ipb, *ip = &ipb; - struct icmp icp2b, *icp2 = &icp2b; - int res; - - if (pingflags & F_VERBOSE) { - res = 1; - jiggle_flush(1); - } else { - res = 0; - } - - (void) memcpy(ip, icp->icmp_data, sizeof(*ip)); - hlen = ip->ip_hl << 2; - if (ip->ip_p == IPPROTO_ICMP - && hlen + 6 <= cc) { - (void) memcpy(icp2, &icp->icmp_data[hlen], sizeof(*icp2)); - if (icp2->icmp_id == ident) { - /* remember to clear route cached in kernel - * if this non-Echo-Reply ICMP message was for one - * of our packets. - */ - clear_cache.tv_sec = 0; - - if (!res && override - && (pingflags & (F_QUIET|F_SEMI_QUIET)) == 0) { - jiggle_flush(1); - (void)printf("%d bytes from %s: ", - cc, pr_addr(&from->sin_addr)); - res = 1; - } - } - } - - return res; -} - - -/* - * Print a descriptive string about an ICMP header other than an echo reply. - */ -static int /* 0=printed nothing */ -pr_icmph(struct icmp *icp, - struct sockaddr_in *from, - int cc) -{ - switch (icp->icmp_type ) { - case ICMP_UNREACH: - if (!ck_pr_icmph(icp, from, cc, 1)) - return 0; - switch (icp->icmp_code) { - case ICMP_UNREACH_NET: - (void)printf("Destination Net Unreachable"); - break; - case ICMP_UNREACH_HOST: - (void)printf("Destination Host Unreachable"); - break; - case ICMP_UNREACH_PROTOCOL: - (void)printf("Destination Protocol Unreachable"); - break; - case ICMP_UNREACH_PORT: - (void)printf("Destination Port Unreachable"); - break; - case ICMP_UNREACH_NEEDFRAG: - (void)printf("frag needed and DF set. Next MTU=%d", - ntohs(icp->icmp_nextmtu)); - break; - case ICMP_UNREACH_SRCFAIL: - (void)printf("Source Route Failed"); - break; - case ICMP_UNREACH_NET_UNKNOWN: - (void)printf("Unreachable unknown net"); - break; - case ICMP_UNREACH_HOST_UNKNOWN: - (void)printf("Unreachable unknown host"); - break; - case ICMP_UNREACH_ISOLATED: - (void)printf("Unreachable host isolated"); - break; - case ICMP_UNREACH_NET_PROHIB: - (void)printf("Net prohibited access"); - break; - case ICMP_UNREACH_HOST_PROHIB: - (void)printf("Host prohibited access"); - break; - case ICMP_UNREACH_TOSNET: - (void)printf("Bad TOS for net"); - break; - case ICMP_UNREACH_TOSHOST: - (void)printf("Bad TOS for host"); - break; - case 13: - (void)printf("Communication prohibited"); - break; - case 14: - (void)printf("Host precedence violation"); - break; - case 15: - (void)printf("Precedence cutoff"); - break; - default: - (void)printf("Bad Destination Unreachable Code: %d", - icp->icmp_code); - break; - } - /* Print returned IP header information */ - pr_retip(icp, cc); - break; - - case ICMP_SOURCEQUENCH: - if (!ck_pr_icmph(icp, from, cc, 1)) - return 0; - (void)printf("Source Quench"); - pr_retip(icp, cc); - break; - - case ICMP_REDIRECT: - if (!ck_pr_icmph(icp, from, cc, 1)) - return 0; - switch (icp->icmp_code) { - case ICMP_REDIRECT_NET: - (void)printf("Redirect Network"); - break; - case ICMP_REDIRECT_HOST: - (void)printf("Redirect Host"); - break; - case ICMP_REDIRECT_TOSNET: - (void)printf("Redirect Type of Service and Network"); - break; - case ICMP_REDIRECT_TOSHOST: - (void)printf("Redirect Type of Service and Host"); - break; - default: - (void)printf("Redirect--Bad Code: %d", icp->icmp_code); - break; - } - (void)printf(" New router addr: %s", - pr_addr(&icp->icmp_hun.ih_gwaddr)); - pr_retip(icp, cc); - break; - - case ICMP_ECHO: - if (!ck_pr_icmph(icp, from, cc, 0)) - return 0; - (void)printf("Echo Request: ID=%d seq=%d", - ntohs(icp->icmp_id), ntohs(icp->icmp_seq)); - break; - - case ICMP_ECHOREPLY: - /* displaying other's pings is too noisey */ -#if 0 - if (!ck_pr_icmph(icp, from, cc, 0)) - return 0; - (void)printf("Echo Reply: ID=%d seq=%d", - ntohs(icp->icmp_id), ntohs(icp->icmp_seq)); - break; -#else - return 0; -#endif - - case ICMP_ROUTERADVERT: - if (!ck_pr_icmph(icp, from, cc, 0)) - return 0; - (void)printf("Router Discovery Advert"); - break; - - case ICMP_ROUTERSOLICIT: - if (!ck_pr_icmph(icp, from, cc, 0)) - return 0; - (void)printf("Router Discovery Solicit"); - break; - - case ICMP_TIMXCEED: - if (!ck_pr_icmph(icp, from, cc, 1)) - return 0; - switch (icp->icmp_code ) { - case ICMP_TIMXCEED_INTRANS: - (void)printf("Time To Live exceeded"); - break; - case ICMP_TIMXCEED_REASS: - (void)printf("Frag reassembly time exceeded"); - break; - default: - (void)printf("Time exceeded, Bad Code: %d", - icp->icmp_code); - break; - } - pr_retip(icp, cc); - break; - - case ICMP_PARAMPROB: - if (!ck_pr_icmph(icp, from, cc, 1)) - return 0; - (void)printf("Parameter problem: pointer = 0x%02x", - icp->icmp_hun.ih_pptr); - pr_retip(icp, cc); - break; - - case ICMP_TSTAMP: - if (!ck_pr_icmph(icp, from, cc, 0)) - return 0; - (void)printf("Timestamp"); - break; - - case ICMP_TSTAMPREPLY: - if (!ck_pr_icmph(icp, from, cc, 0)) - return 0; - (void)printf("Timestamp Reply"); - break; - - case ICMP_IREQ: - if (!ck_pr_icmph(icp, from, cc, 0)) - return 0; - (void)printf("Information Request"); - break; - - case ICMP_IREQREPLY: - if (!ck_pr_icmph(icp, from, cc, 0)) - return 0; - (void)printf("Information Reply"); - break; - - case ICMP_MASKREQ: - if (!ck_pr_icmph(icp, from, cc, 0)) - return 0; - (void)printf("Address Mask Request"); - break; - - case ICMP_MASKREPLY: - if (!ck_pr_icmph(icp, from, cc, 0)) - return 0; - (void)printf("Address Mask Reply"); - break; - - default: - if (!ck_pr_icmph(icp, from, cc, 0)) - return 0; - (void)printf("Bad ICMP type: %d", icp->icmp_type); - if (pingflags & F_VERBOSE) - pr_iph(icp, cc); - } - - return 1; -} - - -/* - * Print an IP header with options. - */ -static void -pr_iph(struct icmp *icp, - int cc) -{ - int hlen; - u_char *cp; - struct ip ipb, *ip = &ipb; - - (void) memcpy(ip, icp->icmp_data, sizeof(*ip)); - - hlen = ip->ip_hl << 2; - cp = (u_char *) &icp->icmp_data[20]; /* point to options */ - - (void)printf("\n Vr HL TOS Len ID Flg off TTL Pro cks Src Dst\n"); - (void)printf(" %1x %1x %02x %04x %04x", - ip->ip_v, ip->ip_hl, ip->ip_tos, ip->ip_len, ip->ip_id); - (void)printf(" %1x %04x", - ((ip->ip_off)&0xe000)>>13, (ip->ip_off)&0x1fff); - (void)printf(" %02x %02x %04x", - ip->ip_ttl, ip->ip_p, ip->ip_sum); - (void)printf(" %15s ", - inet_ntoa(*(struct in_addr *)&ip->ip_src.s_addr)); - (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr)); - /* dump any option bytes */ - while (hlen-- > 20 && cp < (u_char*)icp+cc) { - (void)printf("%02x", *cp++); - } -} - -/* - * Print an ASCII host address starting from a string of bytes. - */ -static void -pr_saddr(u_char *cp) -{ - n_long l; - struct in_addr addr; - - l = (u_char)*++cp; - l = (l<<8) + (u_char)*++cp; - l = (l<<8) + (u_char)*++cp; - l = (l<<8) + (u_char)*++cp; - addr.s_addr = htonl(l); - (void)printf("\t%s", (l == 0) ? "0.0.0.0" : pr_addr(&addr)); -} - - -/* - * Return an ASCII host address - * as a dotted quad and optionally with a hostname - */ -static char * -pr_addr(struct in_addr *addr) /* in network order */ -{ - struct hostent *hp; - static char buf[MAXHOSTNAMELEN+4+16+1]; - - if ((pingflags & F_NUMERIC) - || !(hp = gethostbyaddr((char *)addr, sizeof(*addr), AF_INET))) { - (void)snprintf(buf, sizeof(buf), "%s", inet_ntoa(*addr)); - } else { - (void)snprintf(buf, sizeof(buf), "%s (%s)", hp->h_name, - inet_ntoa(*addr)); - } - - return buf; -} - -/* - * Dump some info on a returned (via ICMP) IP packet. - */ -static void -pr_retip(struct icmp *icp, - int cc) -{ - int hlen; - u_char *cp; - struct ip ipb, *ip = &ipb; - - (void) memcpy(ip, icp->icmp_data, sizeof(*ip)); - - if (pingflags & F_VERBOSE) - pr_iph(icp, cc); - - hlen = ip->ip_hl << 2; - cp = (u_char *) &icp->icmp_data[hlen]; - - if (ip->ip_p == IPPROTO_TCP) { - if (pingflags & F_VERBOSE) - (void)printf("\n TCP: from port %u, to port %u", - (*cp*256+*(cp+1)), (*(cp+2)*256+*(cp+3))); - } else if (ip->ip_p == IPPROTO_UDP) { - if (pingflags & F_VERBOSE) - (void)printf("\n UDP: from port %u, to port %u", - (*cp*256+*(cp+1)), (*(cp+2)*256+*(cp+3))); - } else if (ip->ip_p == IPPROTO_ICMP) { - struct icmp icp2; - (void) memcpy(&icp2, cp, sizeof(icp2)); - if (icp2.icmp_type == ICMP_ECHO) { - if (pingflags & F_VERBOSE) - (void)printf("\n ID=%u icmp_seq=%u", - ntohs((u_int16_t)icp2.icmp_id), - ntohs((u_int16_t)icp2.icmp_seq)); - else - (void)printf(" for icmp_seq=%u", - ntohs((u_int16_t)icp2.icmp_seq)); - } - } -} - -static void -fill(void) -{ - int i, j, k; - char *cp; - int pat[16]; - - for (cp = fill_pat; *cp != '\0'; cp++) { - if (!isxdigit((unsigned char)*cp)) - break; - } - if (cp == fill_pat || *cp != '\0' || (cp-fill_pat) > 16*2) { - (void)fflush(stdout); - errx(EXIT_FAILURE, "\"-p %s\": patterns must be specified with" - " 1-32 hex digits\n", - fill_pat); - } - - i = sscanf(fill_pat, - "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", - &pat[0], &pat[1], &pat[2], &pat[3], - &pat[4], &pat[5], &pat[6], &pat[7], - &pat[8], &pat[9], &pat[10], &pat[11], - &pat[12], &pat[13], &pat[14], &pat[15]); - - for (k = phdrlen, j = 0; k < datalen; k++) { - opack_icmp.icmp_data[k] = pat[j]; - if (++j >= i) - j = 0; - } - - if (!(pingflags & F_QUIET)) { - (void)printf("PATTERN: 0x"); - for (j=0; j>24; - } -} - - -static void -gethost(const char *arg, - const char *name, - struct sockaddr_in *sa, - char *realname, - int realname_len) -{ - struct hostent *hp; - - (void)memset(sa, 0, sizeof(*sa)); - sa->sin_family = AF_INET; - sa->sin_len = sizeof(struct sockaddr_in); - - /* If it is an IP address, try to convert it to a name to - * have something nice to display. - */ - if (inet_aton(name, &sa->sin_addr) != 0) { - if (realname) { - if (pingflags & F_NUMERIC) - hp = 0; - else - hp = gethostbyaddr((char *)&sa->sin_addr, - sizeof(sa->sin_addr), AF_INET); - (void)strlcpy(realname, hp ? hp->h_name : name, - realname_len); - } - return; - } - - hp = gethostbyname(name); - if (!hp) - errx(EXIT_FAILURE, "Cannot resolve \"%s\" (%s)", - name, hstrerror(h_errno)); - - if (hp->h_addrtype != AF_INET) - errx(EXIT_FAILURE, "%s only supported with IP", arg); - - (void)memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr)); - - if (realname) - (void)strlcpy(realname, hp->h_name, realname_len); -} - - -static void -usage(void) -{ -#ifdef IPSEC -#ifdef IPSEC_POLICY_IPSEC -#define IPSECOPT "\n [-E policy] " -#else -#define IPSECOPT "\n [-AE] " -#endif /*IPSEC_POLICY_IPSEC*/ -#else -#define IPSECOPT "" -#endif /*IPSEC*/ - - (void)fprintf(stderr, "usage: \n" - "%s [-aCDdfLnoPQqRrv] [-c count] [-g gateway] [-h host]" - " [-I addr] [-i interval]\n" - " [-l preload] [-p pattern] [-s size] [-T ttl] [-t tos]" - " [-w maxwait] " IPSECOPT "host\n", - getprogname()); - exit(1); -} diff --git a/sbin/ping/ping_rumpops.c b/sbin/ping/ping_rumpops.c deleted file mode 100644 index 7e2f21144..000000000 --- a/sbin/ping/ping_rumpops.c +++ /dev/null @@ -1,58 +0,0 @@ -/* $NetBSD: ping_rumpops.c,v 1.2 2011/03/11 09:59:56 pooka Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: ping_rumpops.c,v 1.2 2011/03/11 09:59:56 pooka Exp $"); -#endif /* !lint */ - -#include -#include - -#include -#include - -#include -#include -#include - -#include "prog_ops.h" - -const struct prog_ops prog_ops = { - .op_init = rumpclient_init, - - .op_socket = rump_sys_socket, - .op_setsockopt= rump_sys_setsockopt, - .op_shutdown = rump_sys_shutdown, - .op_poll = rump_sys_poll, - .op_sendto = rump_sys_sendto, - .op_recvfrom = rump_sys_recvfrom, - .op_close = rump_sys_close, - .op_getuid = rump_sys_getuid, - .op_setuid = rump_sys_setuid, -};