1
0
Files
irix-657m-src/eoe/cmd/efs/ncheck/ncheck.c
2022-09-29 17:59:04 +03:00

352 lines
6.3 KiB
C

#ident "$Revision: 1.12 $"
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/* "@(#)ncheck:ncheck.c 1.13" */
/*
* ncheck -- obtain file names from reading filesystem
*/
/* number of inode blocks to process at a time */
#define NB 3000
/* number of directories per block */
#define NDIR (BBSIZE / sizeof(struct efs_direct))
#define HSIZE 32068
#include "libefs.h"
#include <ctype.h>
#include <diskinfo.h>
#include <mntent.h>
#include <signal.h>
char *fstab = "/etc/fstab";
struct efs_mount *mp;
struct htab
{
efs_ino_t h_ino;
efs_ino_t h_pino;
char *h_name;
} htab[HSIZE];
extent *ex;
int aflg;
int iflg;
int sflg;
efs_ino_t ino;
int nhent;
int nxfile;
int nerror;
char *progname;
efs_ino_t ilist[NB];
static void check(char *file);
static int dotname(struct efs_dent *dep);
static char *emalloc(int size);
static struct htab *lookup(efs_ino_t i, int ef);
static void nxtpass(int pass, efs_ino_t inode);
static void pass1(struct efs_dinode *dip);
static void pname(efs_ino_t i, int lev);
static void reinit(void);
int
main(int argc, char **argv)
{
int i;
FILE *fp;
long n;
progname = argv[0];
while (--argc) {
argv++;
if (**argv=='-')
switch ((*argv)[1]) {
case 'a':
aflg++;
continue;
case 'i':
for(i=0; i<NB;) {
if (argc == 1) {
if (i != 0)
break;
fprintf(stderr,
"%s: -i needs at least one inode number\n",
progname);
exit(2);
}
n = atol(argv[1]);
if(n == 0)
break;
ilist[i] = n;
iflg = ++i;
argv++;
argc--;
}
continue;
case 's':
sflg++;
continue;
default:
fprintf(stderr, "%s: bad flag %c\n", progname, (*argv)[1]);
nerror++;
} else
break;
}
if (nerror)
return(nerror);
nxfile = iflg;
ilist[nxfile] = 0;
if(argc) { /* arg list has file names */
while(argc-- > 0)
check(*argv++);
}
else { /* use default fstab */
struct mntent *me;
if ((fp = setmntent(fstab, "r")) == NULL) {
fprintf(stderr,"%s: can't open fstab file: %s\n",
progname, fstab);
exit(2);
}
while (me = getmntent(fp)) {
if (strcmp(MNTTYPE_EFS, me->mnt_type) == 0)
check(me->mnt_fsname);
}
endmntent(fp);
}
return(nerror);
}
static char *
emalloc(int size)
{
char *p;
p = malloc(size);
if (p == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
return (p);
}
static void
check(char *file)
{
int i, j;
struct efs_dinode *itab, *dip;
int pass;
char *rawpath;
/*
* Make sure that we have the character rather than block
* devices (since readb expects character devs)
*/
if ((rawpath = findrawpath(file)) == NULL) {
fprintf(stderr, "%s: cannot find character dev for %s\n",
progname, file);
return;
}
printf("%s:\n", file);
sync();
if ((mp = efs_mount(rawpath, 0)) == NULL) {
fprintf(stderr, "%s: problems reading %s, skipping...\n",
progname, file);
return;
}
/*
* For each cylinder group, read in its ilist and scan it.
*/
ino = 0;
for (i = 0; i < mp->m_fs->fs_ncg; i++) {
itab = dip = efs_igetcg(mp, i);
for (j = mp->m_fs->fs_cgisize * EFS_INOPBB; --j >= 0;
ino++, dip++) {
if (ino < 2)
continue;
pass1(dip);
}
free(itab);
}
ilist[nxfile] = 0;
for(pass = 2; pass <= 3; pass++) {
ino = 0;
for (i = 0; i < mp->m_fs->fs_ncg; i++) {
itab = dip = efs_igetcg(mp, i);
for (j = mp->m_fs->fs_cgisize * EFS_INOPBB; --j >= 0;
ino++, dip++) {
if (ino < 2)
continue;
if ((dip->di_mode & IFMT) == IFDIR)
nxtpass(pass, ino);
}
free(itab);
}
}
efs_umount(mp);
reinit();
}
static void
pass1(struct efs_dinode *dip)
{
if ((dip->di_mode & IFMT) != IFDIR) {
if (sflg != 1) return;
if (nxfile >= NB){
++sflg;
fprintf(stderr, "%s: too many special files\n",
progname);
return;
}
if (((dip->di_mode & IFMT) == IFBLK) ||
((dip->di_mode & IFMT) == IFCHR) ||
(dip->di_mode & (ISUID | ISGID)))
ilist[nxfile++] = ino;
return;
}
lookup(ino, 1);
}
static void
nxtpass(int pass, efs_ino_t inode)
{
EFS_DIR *dir;
struct efs_dent *dep;
int k;
struct htab *hp;
if ((dir = efs_opendiri(mp, inode)) == NULL) {
fprintf(stderr, "%s: could not open file for inode %d\n",
progname, ino);
return;
}
while ((dep = efs_readdir(dir)) != NULL) {
switch(pass) {
case 2:
if(((hp = lookup(EFS_GET_INUM(dep), 0)) == 0)
|| (dotname(dep)))
continue;
hp->h_pino = ino;
hp->h_name = emalloc(dep->d_namelen+1);
bcopy(dep->d_name, hp->h_name, dep->d_namelen);
hp->h_name[dep->d_namelen] = '\0';
break;
case 3:
if(aflg==0 && dotname(dep))
continue;
if(ilist[0] == 0 && sflg==0)
goto pr;
for(k=0; ilist[k] != 0; k++)
if(ilist[k] == EFS_GET_INUM(dep))
goto pr;
continue;
pr:
printf("%u ", EFS_GET_INUM(dep));
pname(ino, 0);
printf("%.*s", dep->d_namelen, dep->d_name);
if (lookup(EFS_GET_INUM(dep), 0))
printf("/.");
printf("\n");
}
}
efs_closedir(dir);
}
static int
dotname(struct efs_dent *dep)
{
if (dep->d_name[0]=='.')
if ((dep->d_namelen==1) ||
(dep->d_name[1]=='.' && dep->d_namelen==2))
return(1);
return(0);
}
static void
reinit(void)
{
struct htab *hp, *hplim;
hplim = &htab[HSIZE];
for(hp = &htab[0]; hp < hplim; hp++)
hp->h_ino = 0;
nxfile = iflg;
ilist[nxfile] = 0;
if(sflg)
sflg = 1;
}
static void
pname(efs_ino_t i, int lev)
{
struct htab *hp;
if (i==EFS_ROOTINO) {
printf("/");
return;
}
if ((hp = lookup(i, 0)) == 0) {
printf("???");
return;
}
if (lev > 10) {
printf("...");
return;
}
pname(hp->h_pino, ++lev);
printf("%s/", hp->h_name);
}
static struct htab *
lookup(efs_ino_t i, int ef)
{
struct htab *hp;
for (hp = &htab[i%HSIZE]; hp->h_ino;) {
if (hp->h_ino==i)
return(hp);
if (++hp >= &htab[HSIZE])
hp = htab;
}
if (ef==0)
return(0);
if (++nhent >= HSIZE) {
fprintf(stderr, "ncheck: out of core-- increase HSIZE\n");
exit(1);
}
hp->h_ino = i;
return(hp);
}
/*
* Print out a nice message when an i/o error occurs
*/
void
error(void)
{
int old_errno;
old_errno = errno;
fprintf(stderr, "%s: i/o error\n", progname);
errno = old_errno;
perror(progname);
exit(1);
}