home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!usc!cs.utexas.edu!uwm.edu!zaphod.mps.ohio-state.edu!saimiri.primate.wisc.edu!ames!agate!doc.ic.ac.uk!uknet!mcsun!fuug!kiae!rdrel!guam.relcom.msk.su!vak
- From: vak@guam.relcom.msk.su (Serge V.Vakulenko)
- Newsgroups: comp.unix.bsd
- Subject: [386BSD] fs - print info about opened files
- Message-ID: <1992Nov16.210249.1609@rdrel.relcom.msk.su>
- Date: 16 Nov 92 21:02:49 GMT
- Sender: usenet@rdrel.relcom.msk.su (Usenet News Administrator)
- Organization: Relcom R&D
- Lines: 859
- X-Newsreader: TIN [version 1.1 PL6]
-
- Here is simple utility, called `fs', which reads from the kernel
- and prints the information about files, opened by running
- processes. It also tries to convert dev/inode pairs to
- absolute file names.
-
- Share and enjoy!
-
- # This is a shell archive. Save it in a file, remove anything before
- # this line, and then unpack it by entering "sh file". Note, it may
- # create directories; files and directories will be owned by you and
- # have default permissions.
- #
- # This archive contains:
- #
- # Makefile
- # fs.1
- # fs.c
- # fs.h
- # fsdumpdb.c
- # fsmakedb.1
- # fsmakedb.c
- #
- echo x - Makefile
- sed 's/^X//' >Makefile << 'END-of-Makefile'
- X# Copyright (C) 1992 Sergey Vakulenko, <vak@kiae.su>.
- X# Permission to use and distribute this software is permitted
- X# without fee, provided that this copyright notice is not changed.
- X
- XSHELL = /bin/sh
- XCFLAGS = -pipe -O
- XLDFLAGS = -pipe -O
- X
- XSRCS = fs.c fsdumpdb.c fsmakedb.c
- X
- Xall: fs fsmakedb fs.0 fsmakedb.0
- X
- Xfs: fs.o
- X $(CC) $(LDFLAGS) fs.o -o fs -lutil
- X
- Xfsmakedb: fsmakedb.o
- X $(CC) $(LDFLAGS) fsmakedb.o -o fsmakedb
- X
- Xfsdumpdb: fsdumpdb.o
- X $(CC) $(LDFLAGS) fsdumpdb.o -o fsdumpdb
- X
- Xinstall: fs fsmakedb fs.0 fsmakedb.0
- X install -c -s -o root -m 4755 fs /usr/bin/fs
- X install -c -s -o root -m 4755 fsmakedb /usr/sbin/fsmakedb
- X install -c fs.0 /usr/share/man/cat1/fs.0
- X install -c fsmakedb.0 /usr/share/man/cat8/fsmakedb.0
- X
- Xdepend:
- X mkdep $(SRCS) &&\
- X sed '/^###$$/,$$d' Makefile > Makefile~ &&\
- X echo '###' >> Makefile~ &&\
- X cat .depend >> Makefile~ &&\
- X rm .depend &&\
- X mv Makefile~ Makefile
- X
- Xclean:
- X rm -f core.* .,* *.b *.o fs fsmakedb fsdumpdb .depend *.0
- X
- X.SUFFIXES: .1 .0
- X
- X.1.0:
- X nroff -man $< > $@
- X
- X###
- Xfs.o : fs.c /usr/include/stdio.h /usr/include/sys/cdefs.h \
- X /usr/include/machine/ansi.h /usr/include/nlist.h /usr/include/sys/types.h \
- X /usr/include/machine/types.h /usr/include/db.h /usr/include/dirent.h \
- X /usr/include/fcntl.h /usr/include/sys/param.h /usr/include/sys/syslimits.h \
- X /usr/include/sys/errno.h /usr/include/sys/time.h \
- X /usr/include/sys/resource.h /usr/include/sys/ucred.h /usr/include/sys/uio.h \
- X /usr/include/sys/signal.h /usr/include/machine/trap.h \
- X /usr/include/machine/param.h /usr/include/machine/endian.h \
- X /usr/include/machine/limits.h /usr/include/sys/stat.h \
- X /usr/include/ufs/quota.h /usr/include/sys/namei.h /usr/include/sys/file.h \
- X /usr/include/sys/fcntl.h /usr/include/sys/unistd.h /usr/include/sys/vnode.h \
- X /usr/include/ufs/inode.h /usr/include/ufs/../ufs/dinode.h \
- X /usr/include/sys/proc.h /usr/include/machine/proc.h fs.h
- Xfsdumpdb.o : fsdumpdb.c /usr/include/stdio.h /usr/include/sys/cdefs.h \
- X /usr/include/machine/ansi.h /usr/include/sys/types.h \
- X /usr/include/machine/types.h /usr/include/db.h /usr/include/fcntl.h fs.h
- Xfsmakedb.o : fsmakedb.c /usr/include/stdio.h /usr/include/sys/cdefs.h \
- X /usr/include/machine/ansi.h /usr/include/sys/types.h \
- X /usr/include/machine/types.h /usr/include/db.h /usr/include/dirent.h \
- X /usr/include/sys/stat.h /usr/include/fcntl.h fs.h
- END-of-Makefile
- echo x - fs.1
- sed 's/^X//' >fs.1 << 'END-of-fs.1'
- X.\" Copyright (C) 1992 Sergey Vakulenko, <vak@kiae.su>.
- X.\" Permission to use and distribute this software is permitted
- X.\" without fee, provided that this copyright notice is not changed.
- X.Dd November 16, 1992
- X.Dt FS 1
- X.Os BSD 3
- X.Sh NAME
- X.Nm fs
- X.Nd print opened files
- X.Sh SYNOPSIS
- X.Nm fs
- X.Op Fl s
- X.Op Fl f Ar dbfile
- X.Sh DESCRIPTION
- XThe
- X.Nm fs
- Xutility prints information about files, which are currently opened by
- Xrunning processes.
- X.Pp
- XGiven the device and inode numbers of file,
- X.Nm fs
- Xtries to compute the full file name, using the database of
- Xall files in the filesystem. This database should be create by
- X.Xr fsmakedb 1 ,
- Xand placed in
- X.Ql /var/db/fs.db .
- X.Pp
- XThe options are as follows:
- X.Bl -tag -width Ds
- X.It Fl s
- XShow opened sockets in addition to files.
- X.It Fl f
- XRead the file name info from the specified file.
- X.El
- X.Pp
- XIn order to have read access to /dev/kmem and other system files, the
- X.Nm fs
- Xutility should run setuid root.
- X.Sh SEE ALSO
- X.Xr fsmakedb 1 .
- END-of-fs.1
- echo x - fs.c
- sed 's/^X//' >fs.c << 'END-of-fs.c'
- X/*
- X * fs.c - print files, opened by running processes.
- X *
- X * Version 1.0, Tue Nov 17 00:03:11 MSK 1992
- X *
- X * Copyright (C) 1992 Sergey Vakulenko, <vak@kiae.su>.
- X * Permission to use and distribute this software is permitted
- X * without fee, provided that this copyright notice is not changed.
- X */
- X#include <stdio.h>
- X#include <nlist.h>
- X#include <sys/types.h>
- X#include <db.h>
- X#include <dirent.h>
- X#define KERNEL
- X#include <fcntl.h>
- X#include <sys/param.h>
- X#include <sys/time.h>
- X#include <sys/stat.h>
- X#include <ufs/quota.h>
- X#include <sys/namei.h>
- X#include <sys/uio.h>
- X#include <sys/file.h>
- X#include <sys/vnode.h>
- X#include <ufs/inode.h>
- X#include <sys/ucred.h>
- X#include <sys/proc.h>
- X#include "fs.h"
- X
- Xstruct devtab {
- X char *name;
- X int dev;
- X};
- X
- Xstruct nlist symtab [] = {
- X { "_filehead", }, /* struct file * */
- X#define FILEHEAD symtab[0]
- X { "_nfiles", }, /* int */
- X#define NFILES symtab[1]
- X { 0, },
- X};
- X
- Xint nfiles;
- Xstruct file *filetab;
- Xstruct vnode *vnodetab;
- Xstruct devtab *cdev, *bdev;
- Xint cdevlen, bdevlen;
- Xint cdevcnt, bdevcnt;
- Xint initdevtab = 0;
- XDB *db;
- Xint sflag = 0;
- X
- Xchar *progname;
- X
- Xextern char *strrchr (), *strdup (), *malloc (), *calloc ();
- X
- X/* VARARGS1 */
- Xvoid fatal (msg, a, b, c, d)
- Xchar *msg;
- Xlong a, b, c, d;
- X{
- X fprintf (stderr, "%s: ", progname);
- X fprintf (stderr, msg, a, b, c, d);
- X fprintf (stderr, "\n");
- X exit (-1);
- X}
- X
- Xvoid kread (off, addr, sz)
- Xlong off;
- Xvoid *addr;
- X{
- X if (kvm_read (off, addr, sz) != sz)
- X fatal ("cannot read kernel memory");
- X}
- X
- Xvoid readproc ()
- X{
- X struct file *f, *ptr;
- X struct vnode v;
- X
- X if (kvm_openfiles (0, 0, 0) < 0)
- X fatal ("cannot open kernel files");
- X if (kvm_nlist (symtab) != 0)
- X fatal ("cannot read kernel symbols");
- X kread (NFILES.n_value, &nfiles, sizeof (nfiles));
- X
- X filetab = (struct file *) calloc (nfiles, sizeof (struct file));
- X vnodetab = (struct vnode *) calloc (nfiles, sizeof (struct vnode));
- X if (!filetab || !vnodetab)
- X fatal ("out of memory");
- X
- X kread (FILEHEAD.n_value, &ptr, sizeof (ptr));
- X for (f=filetab; ptr && f<filetab+nfiles; ++f) {
- X int i = f - filetab;
- X kread (ptr, f, sizeof (struct file));
- X
- X if (f->f_type == DTYPE_VNODE)
- X kvm_read (f->f_data, vnodetab+i, sizeof (struct vnode));
- X
- X ptr = f->f_filef;
- X }
- X}
- X
- Xchar *fileflag (int fl)
- X{
- X static char buf [8];
- X char *p;
- X
- X if (fl & ~(FREAD | FWRITE | O_APPEND | O_NONBLOCK | FHASLOCK)) {
- X sprintf (buf, "%o", fl);
- X return (buf);
- X }
- X p = buf + sizeof(buf);
- X *--p = 0;
- X *--p = (fl & FREAD) ? 'r' : '-';
- X *--p = (fl & FWRITE) ? 'w' : '-';
- X *--p = (fl & O_APPEND) ? 'a' : '-';
- X *--p = (fl & O_NONBLOCK) ? 'n' : '-';
- X *--p = (fl & FHASLOCK) ? 'l' : '-';
- X return (p);
- X}
- X
- Xchar *filecount (cnt)
- X{
- X static char buf [16];
- X
- X if (cnt == 1)
- X return ("");
- X sprintf (buf, "(%d)", cnt);
- X return (buf);
- X}
- X
- Xchar *fileoffset (off)
- Xlong off;
- X{
- X static char buf [24];
- X
- X if (off == 0)
- X return ("");
- X sprintf (buf, "%x", off);
- X return (buf);
- X}
- X
- Xchar *vnodetype (typ)
- X{
- X switch (typ) {
- X case VNON: return ("non");
- X case VBAD: return ("bad");
- X case VSOCK: return ("sock");
- X case VFIFO: return ("fifo");
- X case VLNK: return ("lnk");
- X case VBLK: return ("blk");
- X case VCHR: return ("chr");
- X case VDIR: return ("dir");
- X case VREG: return ("file");
- X }
- X return ("?");
- X}
- X
- Xvoid makedevtab ()
- X{
- X DIR *dird;
- X struct dirent *d;
- X struct stat st;
- X char afname [128];
- X
- X cdevcnt = bdevcnt = 0;
- X cdevlen = bdevlen = 64;
- X bdev = (struct devtab *) malloc (bdevlen * sizeof (struct devtab));
- X cdev = (struct devtab *) malloc (cdevlen * sizeof (struct devtab));
- X if (! bdev || ! cdev)
- X fatal ("out of memory");
- X strcpy (afname, "/dev/");
- X dird = opendir (afname);
- X if (! dird)
- X fatal ("cannot read /dev directory");
- X for (d=readdir(dird); d; d=readdir(dird)) {
- X strcpy (afname+5, d->d_name);
- X if (stat (afname, &st) < 0)
- X continue;
- X if ((st.st_mode & S_IFMT) == S_IFBLK) {
- X if (bdevcnt >= bdevlen) {
- X bdevlen += 64;
- X bdev = (struct devtab *) realloc ((char *) bdev,
- X bdevlen * sizeof (struct devtab));
- X if (! bdev)
- X fatal ("out of memory");
- X }
- X bdev[bdevcnt].dev = st.st_rdev;
- X bdev[bdevcnt].name = strdup (afname);
- X ++bdevcnt;
- X } else if ((st.st_mode & S_IFMT) == S_IFCHR) {
- X if (cdevcnt >= cdevlen) {
- X cdevlen += 64;
- X cdev = (struct devtab *) realloc ((char *) cdev,
- X cdevlen * sizeof (struct devtab));
- X if (! cdev)
- X fatal ("out of memory");
- X }
- X cdev[cdevcnt].dev = st.st_rdev;
- X cdev[cdevcnt].name = strdup (afname);
- X ++cdevcnt;
- X }
- X }
- X closedir (dird);
- X}
- X
- Xchar *devname (typ, dev)
- X{
- X struct devtab *p;
- X int cnt, i;
- X static char buf [16];
- X
- X if (! initdevtab) {
- X makedevtab ();
- X initdevtab = 1;
- X }
- X p = typ=='b' ? bdev : cdev;
- X cnt = typ=='b' ? bdevcnt : cdevcnt;
- X for (; --cnt>=0; ++p)
- X if (p->dev == dev)
- X return (p->name);
- X sprintf (buf, "%c %d/%d", typ, major (dev), minor (dev));
- X return (buf);
- X}
- X
- Xchar *fetch (dev, inode, pdev, pinode)
- Xlong dev, inode, *pdev, *pinode;
- X{
- X DBT key, val;
- X struct fskey keyrec;
- X struct fsrec *v;
- X
- X keyrec.dev = dev;
- X keyrec.inode = inode;
- X key.data = (char *) &keyrec;
- X key.size = sizeof (keyrec);
- X if ((*db->get) (db, &key, &val, 0) != 0)
- X return (0);
- X v = (struct fsrec *) val.data;
- X *pdev = v->pdev;
- X *pinode = v->pinode;
- X return (v->filename);
- X}
- X
- Xchar *strrcpy (to, from)
- Xchar *to, *from;
- X{
- X int len = strlen (from);
- X
- X strncpy (to -= len, from, len);
- X return (to);
- X}
- X
- Xchar *filename (dev, inode)
- Xlong dev, inode;
- X{
- X long pdev, pinode;
- X static char fullname [512];
- X char *p, *name;
- X
- X if (! db)
- X return (0);
- X name = fetch (dev, inode, &pdev, &pinode);
- X if (! name)
- X return (0);
- X p = fullname + sizeof (fullname);
- X *--p = 0;
- X for (;;) {
- X p = strrcpy (p, name);
- X if (dev==pdev && inode==pinode)
- X break;
- X *--p = '/';
- X name = fetch (dev = pdev, inode = pinode, &pdev, &pinode);
- X if (! name)
- X return (0);
- X }
- X return (p);
- X}
- X
- Xvoid printvnode (v)
- Xstruct vnode *v;
- X{
- X struct inode *i;
- X char *name;
- X
- X switch (v->v_type) {
- X case VNON: case VBAD: case VSOCK: case VFIFO: case VLNK:
- X default:
- X printf (vnodetype (v->v_type));
- X return;
- X case VBLK: case VCHR: case VDIR: case VREG:
- X break;
- X }
- X switch (v->v_tag) {
- X default:
- X printf ("%s on %d fs", vnodetype (v->v_type), v->v_tag);
- X return;
- X case VT_NON:
- X printf ("%s nowhere", vnodetype (v->v_type));
- X return;
- X case VT_NFS:
- X printf ("%s on nfs", vnodetype (v->v_type));
- X return;
- X case VT_MFS:
- X printf ("%s on mfs", vnodetype (v->v_type));
- X return;
- X case VT_UFS:
- X break;
- X }
- X i = VTOI (v);
- X switch (v->v_type) {
- X case VBLK:
- X printf ("%s", devname ('b', i->i_rdev));
- X return;
- X case VCHR:
- X printf ("%s", devname ('c', i->i_rdev));
- X return;
- X }
- X name = filename (i->i_dev, i->i_number);
- X switch (v->v_type) {
- X case VDIR:
- X if (name)
- X printf ("%s/", name);
- X else
- X printf ("%s dir %d", devname ('b', i->i_dev), i->i_number);
- X break;
- X case VREG:
- X if (name)
- X printf ("%s", name);
- X else
- X printf ("%s file %d", devname ('b', i->i_dev), i->i_number);
- X break;
- X }
- X}
- X
- Xvoid printproc (f)
- Xstruct file *f;
- X{
- X printf ("%6s %5s %8s ",
- X fileflag (f->f_flag), /* read/write etc. */
- X filecount (f->f_count), /* reference count */
- X fileoffset (f->f_offset) /* seek offset in file */
- X );
- X if (f->f_type == DTYPE_VNODE)
- X printvnode (vnodetab + (f - filetab));
- X else if (f->f_type == DTYPE_SOCKET)
- X printf ("<socket>");
- X printf ("\n");
- X}
- X
- Xusage ()
- X{
- X fprintf (stderr, "Usage: %s [-s] [-f dbfile]\n", progname);
- X exit (-1);
- X}
- X
- Xint fsrechash (a, sz)
- Xstruct fskey *a;
- X{
- X return (a->inode);
- X}
- X
- Xint main (argc, argv)
- Xchar **argv;
- X{
- X struct file *f;
- X char *dbfile = FSDBFILE;
- X HASHINFO hi;
- X
- X /* Store the program name for message printing. */
- X progname = strrchr (*argv, '/');
- X if (! progname)
- X progname = *argv;
- X
- X /* Parse options. */
- X for (++argv, --argc; *argv && **argv=='-'; ++argv, --argc) {
- X char *p;
- X
- X for (p=1+*argv; *p; ++p) {
- X switch (*p) {
- X case 's':
- X ++sflag;
- X continue;
- X case 'f':
- X dbfile = *++argv;
- X --argc;
- X if (! dbfile)
- X usage ();
- X break;
- X default:
- X fprintf (stderr, "%s: no such option: %c\n",
- X progname, *p);
- X usage ();
- X }
- X break;
- X }
- X }
- X if (*argv)
- X usage ();
- X
- X /* Read kernel info. */
- X readproc ();
- X kvm_close ();
- X
- X /* Open dev/inode to file name conversion database */
- X hi.bsize = 512; /* page size */
- X hi.cachesize = 200*512; /* cache size */
- X hi.hash = fsrechash; /* hash function */
- X hi.lorder = 0; /* byte order */
- X hi.ffactor = 64; /* fill factor */
- X db = hash_open (dbfile, O_RDONLY, 0, &hi);
- X
- X /* Print processes information. */
- X printf (" FLAGS REFCNT OFFSET FILENAME\n");
- X
- X for (f=filetab; f->f_filef && f<filetab+nfiles; ++f)
- X if (sflag || f->f_type==DTYPE_VNODE)
- X printproc (f);
- X
- X return (0);
- X}
- END-of-fs.c
- echo x - fs.h
- sed 's/^X//' >fs.h << 'END-of-fs.h'
- X/*
- X * Copyright (C) 1992 Sergey Vakulenko, <vak@kiae.su>.
- X * Permission to use and distribute this software is permitted
- X * without fee, provided that this copyright notice is not changed.
- X */
- X#define FSDBFILE "/var/db/fs.db"
- X
- Xstruct fskey {
- X long dev;
- X long inode;
- X};
- X
- Xstruct fsrec {
- X long pdev;
- X long pinode;
- X char filename [256];
- X};
- END-of-fs.h
- echo x - fsdumpdb.c
- sed 's/^X//' >fsdumpdb.c << 'END-of-fsdumpdb.c'
- X/*
- X * Dump the file info database. Used for debugging.
- X *
- X * Copyright (C) 1992 Sergey Vakulenko, <vak@kiae.su>.
- X * Permission to use and distribute this software is permitted
- X * without fee, provided that this copyright notice is not changed.
- X */
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <db.h>
- X#include <fcntl.h>
- X#include "fs.h"
- X
- XDB *db;
- Xchar *progname;
- Xint vflag = 0;
- X
- Xextern char *strrchr ();
- X
- Xvoid dump ()
- X{
- X DBT key, val;
- X struct fskey *k;
- X struct fsrec *v;
- X
- X for (;;) {
- X if ((*db->seq) (db, &key, &val, 0) != 0) {
- X perror ("seq");
- X return;
- X }
- X k = (struct fskey *) key.data;
- X v = (struct fsrec *) val.data;
- X printf ("%d/%d -> %s\n", k->dev, k->inode, v->filename);
- X }
- X}
- X
- Xint fsrechash (a, sz)
- Xstruct fskey *a;
- X{
- X return (a->inode);
- X}
- X
- Xusage ()
- X{
- X fprintf (stderr, "Usage: %s [dbfile]\n", progname);
- X exit (-1);
- X}
- X
- Xint main (argc, argv)
- Xchar **argv;
- X{
- X char *dbname = FSDBFILE;
- X HASHINFO hi;
- X
- X /* Store the program name for message printing. */
- X progname = strrchr (*argv, '/');
- X if (! progname)
- X progname = *argv;
- X
- X /* Parse options. */
- X for (++argv, --argc; *argv && **argv=='-'; ++argv, --argc) {
- X char *p;
- X
- X for (p=1+*argv; *p; ++p) {
- X switch (*p) {
- X case 'v':
- X ++vflag;
- X continue;
- X default:
- X fprintf (stderr, "%s: no such option: %c",
- X progname, *p);
- X usage ();
- X }
- X }
- X }
- X if (*argv)
- X dbname = *argv++;
- X if (*argv)
- X usage ();
- X
- X /* Open dev/inode to file name conversion database */
- X hi.bsize = 512; /* page size */
- X hi.cachesize = 200*512; /* cache size */
- X hi.hash = fsrechash; /* hash function */
- X hi.lorder = 0; /* byte order */
- X hi.ffactor = 64; /* fill factor */
- X db = hash_open (dbname, O_RDONLY, 0, &hi);
- X if (! db) {
- X fprintf (stderr, "%s: cannot read %s", progname, dbname);
- X exit (-1);
- X }
- X dump ();
- X
- X return (0);
- X}
- END-of-fsdumpdb.c
- echo x - fsmakedb.1
- sed 's/^X//' >fsmakedb.1 << 'END-of-fsmakedb.1'
- X.\" Copyright (C) 1992 Sergey Vakulenko, <vak@kiae.su>.
- X.\" Permission to use and distribute this software is permitted
- X.\" without fee, provided that this copyright notice is not changed.
- X.Dd November 16, 1992
- X.Dt FSMAKEDB 8
- X.Os BSD 3
- X.Sh NAME
- X.Nm fsmakedb
- X.Nd create file name database for fs(1) utility
- X.Sh SYNOPSIS
- X.Nm fsmakedb
- X.Op Ar dbfile
- X.Sh DESCRIPTION
- XThe
- X.Nm fsmakedb
- Xutility creates the database of all files in the filesystem.
- X.Pp
- XThe
- X.Ar dbfile
- Xis the database name to create, default
- X.Ql /var/db/fs.db .
- X.Pp
- XIn order to have read/chdir access to all directories, the
- X.Nm fsmakedb
- Xutility should run setuid root.
- X.Sh SEE ALSO
- X.Xr fs 1 .
- END-of-fsmakedb.1
- echo x - fsmakedb.c
- sed 's/^X//' >fsmakedb.c << 'END-of-fsmakedb.c'
- X/*
- X * Create the file info database for the fs(1) utility.
- X *
- X * Copyright (C) 1992 Sergey Vakulenko, <vak@kiae.su>.
- X * Permission to use and distribute this software is permitted
- X * without fee, provided that this copyright notice is not changed.
- X */
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <db.h>
- X#include <dirent.h>
- X#include <sys/stat.h>
- X#include <fcntl.h>
- X#include "fs.h"
- X
- XDB *db;
- Xchar *progname;
- Xint vflag = 0;
- X
- Xextern char *strrchr ();
- X
- X/* VARARGS1 */
- Xvoid fatal (msg, a, b, c, d)
- Xchar *msg;
- Xlong a, b, c, d;
- X{
- X fprintf (stderr, "%s: ", progname);
- X fprintf (stderr, msg, a, b, c, d);
- X fprintf (stderr, "\n");
- X exit (-1);
- X}
- X
- Xvoid store (dev, inode, name, pdev, pinode)
- Xchar *name;
- X{
- X DBT key, val;
- X struct fskey keyrec;
- X struct fsrec valrec;
- X
- X keyrec.dev = dev;
- X keyrec.inode = inode;
- X key.data = (char *) &keyrec;
- X key.size = sizeof (keyrec);
- X
- X valrec.pdev = pdev;
- X valrec.pinode = pinode;
- X strcpy (valrec.filename, name);
- X val.data = (char *) &valrec;
- X val.size = (char *) &valrec.filename - (char *) &valrec +
- X strlen (name) + 1;
- X
- X if (vflag)
- X printf ("%d/%d -> %s\n", dev, inode, name);
- X if ((*db->put) (db, &key, &val, R_PUT) != 0)
- X fprintf (stderr, "error storing new record\n");
- X}
- X
- Xvoid scan (dir, pst)
- Xchar *dir;
- Xstruct stat *pst;
- X{
- X DIR *dird;
- X struct dirent *d;
- X struct stat st;
- X
- X if (chdir (dir) < 0) {
- X perror (dir);
- X return;
- X }
- X dird = opendir (".");
- X if (! dird) {
- X perror (dir);
- X chdir ("..");
- X return;
- X }
- X for (d=readdir(dird); d; d=readdir(dird)) {
- X if (d->d_name[0] == '.' && (d->d_name[1] == 0 ||
- X d->d_name[1] == '.' && d->d_name[2] == 0))
- X continue;
- X if (lstat (d->d_name, &st) < 0) {
- X perror (d->d_name);
- X continue;
- X }
- X store (st.st_dev, st.st_ino, d->d_name, pst->st_dev, pst->st_ino);
- X if ((st.st_mode & S_IFMT) == S_IFDIR)
- X scan (d->d_name, &st);
- X }
- X closedir (dird);
- X chdir ("..");
- X}
- X
- Xint fsrechash (a, sz)
- Xstruct fskey *a;
- X{
- X return (a->inode);
- X}
- X
- Xint main (argc, argv)
- Xchar **argv;
- X{
- X char *dbname = FSDBFILE;
- X struct stat st;
- X HASHINFO hi;
- X
- X /* Store the program name for message printing. */
- X progname = strrchr (*argv, '/');
- X if (! progname)
- X progname = *argv;
- X
- X /* Parse options. */
- X for (++argv, --argc; *argv && **argv=='-'; ++argv, --argc) {
- X char *p;
- X
- X for (p=1+*argv; *p; ++p) {
- X switch (*p) {
- X case 'v':
- X ++vflag;
- X break;
- X default:
- X fatal ("no such option: %c", *p);
- X }
- X }
- X }
- X if (*argv)
- X dbname = *argv++;
- X if (*argv)
- X fatal ("usage: %s [dbfile]", progname);
- X
- X /* Open dev/inode to file name conversion database */
- X hi.bsize = 512; /* page size */
- X hi.cachesize = 200*512; /* cache size */
- X hi.hash = fsrechash; /* hash function */
- X hi.lorder = 0; /* byte order */
- X hi.ffactor = 64; /* fill factor */
- X db = hash_open (dbname, O_RDWR|O_CREAT|O_TRUNC, 0644, &hi);
- X if (! db)
- X fatal ("cannot create %s", dbname);
- X
- X if (lstat ("/", &st) < 0) {
- X perror ("/");
- X return (-1);
- X }
- X
- X /* Scan all files recursively beginning from the root. */
- X store (st.st_dev, st.st_ino, "", st.st_dev, st.st_ino);
- X scan ("/", &st);
- X
- X dbm_close (db);
- X return (0);
- X}
- END-of-fsmakedb.c
- exit
-