home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume19
/
backup
/
ilw.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-06-29
|
3KB
|
135 lines
/*
* i-list-walker -- apply a specified function to all inodes on a filesystem
*
* Based on original routines by Larry Philps. This reimplementation is
* Copyright 1988 by Rayan Zachariassen, solely to prevent you from selling
* it or putting your name on it. Free (gratis) redistribution is encouraged.
*/
#include <stdio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/vnode.h>
#include <ufs/inode.h>
#include <ufs/fs.h>
extern char *progname; /* must be supplied by main program */
static char errmsgbuf[30];
#define EMSG(x) (errno < sys_nerr ? sys_errlist[x] : \
(sprintf(errmsgbuf, "unknown error %d", errno), errmsgbuf))
extern int errno, sys_nerr;
extern char *sys_errlist[];
extern off_t lseek();
int
bread(fd, bno, buf, cnt)
daddr_t bno;
char *buf;
long cnt;
{
if (lseek(fd, (off_t) bno * DEV_BSIZE, L_SET) == -1) {
fprintf(stderr, "%s: bread: lseek: %s\n",
progname, EMSG(errno));
return -2;
}
if (read(fd, buf, (int) cnt) != cnt) {
fprintf(stderr, "%s: read error at block %u: %s\n",
progname, bno, EMSG(errno));
return -1;
}
return 0;
}
int
bwrite(fd, bno, buf, cnt)
daddr_t bno;
char *buf;
long cnt;
{
if (lseek(fd, (off_t) bno * DEV_BSIZE, L_SET) == -1) {
fprintf(stderr, "%s: bwrite: lseek: %s\n",
progname, EMSG(errno));
return -2;
}
if (write(fd, buf, (int) cnt) != cnt) {
fprintf(stderr, "%s: write error at block %u: %s\n",
progname, bno, EMSG(errno));
return -1;
}
return 0;
}
/*
* i-list-walker
*
* Opens the raw device indicated, and calls the function fn with an inode
* pointer for every inode on the device. If the function returns non-zero,
* the inode on the disk is updated, unless the readonly flag is set.
*
* Return -1 in case of error, +ve if inodes were updated, 0 otherwise.
*/
ilw(rawdev, fn, readonly)
char *rawdev;
int (*fn)();
int readonly;
{
register u_int ino;
register int fd, j, nfiles, changed, touched;
struct dinode *ip;
daddr_t iblk;
struct dinode itab[MAXBSIZE/sizeof(struct dinode)];
union {
struct fs u_sblock;
char dummy[SBSIZE];
} sb_un;
#define sblock sb_un.u_sblock
if ((fd = open(rawdev, readonly ? O_RDONLY : O_RDWR, 0)) < 0) {
fprintf(stderr, "%s: open(%s): %s\n",
progname, rawdev, EMSG(errno));
return -1;
}
/*
* Don't bother stat'ing the device, we might want to do this on
* real files some day.
*/
/* printf ("starting filesystem %s\n", rawdev); */
sync();
if (bread(fd, SBLOCK, (char *)&sblock, (long) SBSIZE) < 0) {
close(fd);
return -1;
}
nfiles = sblock.fs_ipg * sblock.fs_ncg;
touched = 0;
for (ino = 0; ino < nfiles; touched += changed) {
iblk = fsbtodb(&sblock, itod(&sblock, ino));
if (bread(fd, iblk, (char *)itab, sblock.fs_bsize) < 0) {
(void) close(fd);
return -1;
}
changed = 0;
for (j = 0; j < INOPB(&sblock) && ino < nfiles; j++, ino++) {
ip = &itab[j];
if ((ino < ROOTINO) || ((ip->di_mode&IFMT) == 0))
continue;
if ((*fn)(ip, ino))
++changed;
}
if (!changed)
continue;
if (readonly)
printf("replacing block %d with %d changes\n",
iblk, changed);
else if (bwrite(fd, iblk, (char *)itab, sblock.fs_bsize) < 0) {
(void) close(fd);
return -1;
}
}
return touched;
}