[comp.os.minix] V7 ncheck

ast@cs.vu.nl (Andy Tanenbaum) (12/17/90)

echo x - ncheck.c
sed '/^X/s///' > ncheck.c << '/'
X/* ncheck   name check			  Author:  Raymond Michiels */
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <dirent.h>
X#include <string.h>
X#include <stdio.h>
X#include <limits.h>
X#include <ctype.h>
X
Xino_t *ilist;
Xint iflag = 0, aflag = 0, sflag = 0, nr_inodes = 0, opt, skip_len;
Xchar *progname, *filesystem = NULL, *mnt_point = NULL, path[PATH_MAX];
X
Xextern int optind, getopt();
Xextern char *optarg, *malloc();
X
Xvoid usage()
X{
X  printf("usage: %s [ -i numbers] [-s] [-a] file_system\n", progname);
X  myexit(1);
X}
X
X
Xvoid myexit(n)		/* maybe I could use something like _cleanup() */
Xint n;
X{
X  if (filesystem != NULL)
X	umount(filesystem);
X  if (mnt_point != NULL)
X	rmdir(mnt_point);
X  exit(n);
X}
X
X
Xvoid readilist(p)
Xchar *p;
X{
X  ilist = (ino_t *)malloc(strlen(p)/2+1);
X  if (ilist == NULL) {
X	printf("couldn't malloc i-node list\n");
X	myexit(1);
X  }
X  do {
X	if (*p == ',') p++;	/* skip comma's */
X	if (!isdigit(*p)) {
X		printf("malformed i-node list\n");
X		myexit(1);
X	}
X	ilist[nr_inodes++] = atoi(p);
X  } while ((p = strchr(p, ',')) != NULL);
X}
X
X
Xint inlist(inode)
Xino_t inode;
X{
X  int i;
X
X  for (i = 0; i < nr_inodes; i++) {
X	if (ilist[i] == inode)
X		return(1);
X  }
X  return(0);
X}
X
X
Xint dotfile(fullname)
Xchar *fullname;
X{
X  char *name;
X
X  name = strrchr(fullname, '/') + 1;
X
X  return(!(strcmp(name, ".") && strcmp(name, "..")));
X}
X
X
Xint toprint(statbuf, name)
Xstruct stat *statbuf;
Xchar *name;
X{
X#define S_SPECIAL (S_ISUID | S_ISGID | S_IFBLK | S_IFCHR)
X
X  return ((!iflag || inlist(statbuf->st_ino)) &&
X	(aflag || !dotfile(name)) &&
X	(!sflag || statbuf->st_mode & S_SPECIAL));
X}
X
X
Xtraverse(dirname)
Xchar *dirname;
X{
X  struct dirent *dirent;
X  DIR *dir;
X  struct stat statbuf;
X  int len;
X
X  len = strlen(dirname);
X  if (stat(dirname, &statbuf) < 0) {
X	printf("%s : could not stat\n", dirname);
X	return;
X  }
X  if (toprint(&statbuf, dirname))
X	printf("%5ld %s\n", (long) statbuf.st_ino, dirname+skip_len);
X
X  if (!dotfile(dirname) && S_ISDIR(statbuf.st_mode)) {
X	if ((dir = opendir(dirname)) == NULL) {
X		printf("%s : could not open\n", dirname);
X		return;
X	}
X	dirname[len++] = '/';
X	while ((dirent = readdir(dir)) != NULL) {
X		strcpy(dirname+len, dirent->d_name);
X		traverse(dirname);
X	}
X	closedir(dir);
X  }
X}
X
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X  progname = argv[0];
X
X  while ((opt = getopt(argc, argv, "i:as")) != EOF) {
X	switch (opt) {
X	case 'i':
X		if (nr_inodes > 0)
X			usage();
X		iflag = 1;
X		readilist(optarg);
X		break;
X	case 'a':
X		aflag = 1;
X		break;
X	case 's':
X		sflag = 1;
X		break;
X	}
X  }
X  if (optind > argc-1)
X	usage();
X  filesystem = argv[optind];
X
X  mnt_point = tmpnam(NULL);
X  mkdir(mnt_point, 0777);
X  if (mount(filesystem, mnt_point, 1) < 0) {
X	printf("could not mount %s\n", filesystem);
X	myexit(1);
X  }
X  strcpy(path, mnt_point);
X  skip_len = strlen(path);
X  
X  traverse(path);
X  myexit(0);
X}
/