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}
/