_FS: A FILE STATUS UTILITY FOR UNIX_ by Jeff Reagen [LISTING ONE] /* Copyright (c) 1991 Jeff Reagen ALL RIGHTS RESERVED. */ #include "sys/types.h" #include "sys/fcntl.h" #include "sys/param.h" #include "sys/immu.h" #include "sys/fs/s5dir.h" #include "sys/signal.h" #include "sys/user.h" #include "sys/errno.h" #include "sys/cmn_err.h" #include "sys/buf.h" #include "nlist.h" #include "sys/stat.h" #include "sys/region.h" #include "sys/proc.h" #include "sys/var.h" #include "sys/sysmacros.h" #include "sys/file.h" #include "sys/inode.h" #include "sys/utsname.h" long lseek(); /* Symbols fs will request from the kernel. */ struct nlist kern_syms[] = { "v", 0, 0, 0, 0, 0, "file", 0, 0, 0, 0, 0, "", 0, 0, 0, 0, 0 }; struct nlist *pinfo; struct var v; int fd; int inofd; /* file pointer for inode lookup */ [LISTING TWO] /* Copyright (c) 1991 Jeff Reagen ALL RIGHTS RESERVED. */ main () { int i; long res; struct utsname name; char realname[10]; /* Obtain name of current kernel. It's not necessarily /unix! */ if (uname (&name) < 0) { printf ("Cannot identify the current Unix system!\n"); exit (1); } /* Prefix name of kernel with a "/" */ sprintf (realname, "/%s", name.sysname); if (nlist (realname, kern_syms) < 0) { printf ("Could not get name list\n"); exit (1); } pinfo = &kern_syms[0]; /* Check value of proc symbol. */ if (pinfo->n_value == 0) { printf ("nlist call failed.\n"); exit (2); } if ( (fd = open ("/dev/kmem", O_RDONLY)) < 0) { printf ("Cannot open /dev/kmem.\n"); exit (3); } if ( (inofd = open ("/dev/kmem", O_RDONLY)) < 0) { printf ("Cannot open /dev/kmem.\n"); exit (3); } /* Get Unix system variable structure. */ if ( (res=lseek (fd, (long)kern_syms[0].n_value, 0)) == -1) { printf ("Can't seek /dev/kmem.\n"); exit (4); } if (read (fd, &v, sizeof (struct var)) < 0) { printf ("Can't read sysinfo struct from /dev/kmem.\n"); exit (5); } /* Display system information. */ file_entry(); } [LISTING THREE] /* Copyright (c) 1991 Jeff Reagen ALL RIGHTS RESERVED. */ /* Examine each entry in the Unix file table. */ file_entry() { int res; int fno; struct file file; /* Position to base of file table. */ if ( (res=lseek (fd, (long)kern_syms[1].n_value, 0)) == -1) { printf ("Can't seek /dev/kmem.\n"); exit (4); } /* read each entry one after the other. */ for (fno = 0; fno < v.v_file; fno++) { /* get next slot. */ if (read (fd, &file, sizeof (struct file)) < 0) { printf ("Can't read file slot.\n"); exit (5); } /* Display entry info. iff referenece count indicates file entry is valid. */ if (!file.f_count) { continue; /* abort this entry! */ } printf ("Contents of file table entry #%d\n",fno); printf ("\tFile operation flag ................. "); switch (file.f_flag) { case FOPEN: printf ("File is opened\n"); break; case FREAD: printf ("File is being read\n"); break; case FWRITE: printf ("File is being written\n"); break; case FREAD|FWRITE: printf ("File opened for read/write\n"); break; case FWRITE|FAPPEND: printf ("File opened for write append\n"); break; case FREAD|FWRITE|FAPPEND: printf ("File opened for read/write appends\n"); break; case FNDELAY: printf ("File operating in delayed mode\n"); break; case FAPPEND: printf ("File opened for appended operation\n"); break; case FSYNC: printf ("File writes are synchronous\n"); break; case FMASK: printf ("File masked ?????\n"); break; default: printf ("%x\n",file.f_flag); break; } printf ("\tReference count ..................... %d\n", file.f_count); printf ("\tFile pointer position .............. %lx\n", file.f_un.f_off); /* process the inode */ inode_entry (file); /* Pause so user can read the output. */ getchar(); printf("\n\n"); } } [LISTING FOUR] /* Copyright (c) 1991 Jeff Reagen ALL RIGHTS RESERVED. */ /* Get the inode associated with the current file table entry. */ inode_entry (file) struct file file; { int res; struct inode inode; /* current core inode */ if ( (res=lseek (inofd, (long)file.f_up.f_uinode, 0)) == -1) { printf ("Can't seek /dev/kmem for inode.\n"); exit (4); } if (read (inofd, &inode, sizeof (struct inode)) < 0) { printf ("Can't read in core inode.\n"); exit (5); } printf ("\tInode number ........................ %d\n", inode.i_number); printf ("\tFile type ........................... "); switch (inode.i_ftype) { case IFDIR: printf ("Directory\n"); break; case IFCHR: printf ("Character device (Maj %d/Min %d)\n", major(inode.i_rdev),minor(inode.i_rdev)); break; case IFBLK: printf ("Block device\n"); printf ("\tBlock device .... %d\n",inode.i_dev); break; case IFREG: printf ("Regular file\n"); printf ("\tFile exists on Major/Minor device ... %d/%d\n", major(inode.i_dev), minor(inode.i_dev) ); break; case IFIFO: printf ("FIFO special\n"); break; case IFMPC: printf ("Multiplexed Character special\n"); break; case IFMPB: printf ("Multiplexed Block special\n"); break; case IFNAM: printf ("Special Named file\n"); } printf ("\tFile size ........................... %d\n",inode.i_size); printf ("\tUser id ............................. %d\n", inode.i_uid); printf ("\tGroup id ............................ %d\n", inode.i_gid); }