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