Path: utzoo!utgpu!jarvis.csri.toronto.edu!torsqnt!tmsoft!robohack!eci386!clewis From: clewis@eci386.uucp (Chris Lewis) Newsgroups: comp.unix.wizards Subject: RFS/NFS file detection - possible solution Message-ID: <1990Feb22.222846.6656@eci386.uucp> Date: 22 Feb 90 22:28:46 GMT Reply-To: clewis@eci386 (Chris Lewis) Organization: Elegant Communications Inc., Toronto, Canada Lines: 137 For those of you who've expressed some interest in detecting RFS/NFS files, I got a couple of leads by mail, plus I've discovered a few things on my own, plus I have some testcode if you're interested.... This was from Larry Wall: > I don't know that it's documented either, but everywhere I've looked the > dev of NFS is negative (treating it as a signed value). This includes > Vaxen, Suns, Masscomps and Pyramids. I suspect that anyone that uses > Sun's code will end up doing this, unless they've already reserved > negative devices for some other purpose. > If we make enough programs that rely on it, they might make it a standard. :-) > I have no idea about RFS. > Larry Wall > lwall@jpl-devvax.jpl.nasa.gov Thank you Larry! This was sort of what I expected. I also discovered on System VR3 (386/ix 1.0.6 specifically) and AIX that in /usr/include/sys/sysmacros.h (which is where major() and minor() is defined on System Vish systems), has some wierdishness that may imply similar functionality. On 386/ix major() returns a unsigned int that has bit 8 very carefully masked off: #define major(x) (int)((unsigned)((x)>>8)&0x7F) (older code (eg: SCO pre-286 days) had 0xFF) On AIX, they don't do the masking, but they define a "bmajor()" that does. (on 386/ix, bmajor and major are the same). On the system running AIX I've had access to, the following was true for files/directories on networked file systems: major(stb.st_dev) != bmajor(stb.st_dev) I have no access to a SVR3 with RFS actually running, but I suspect that the upper bit would be turned on. On HP9000, dev_t is a long, but they only use 8 bits for minor, and I believe 6 bits for major, and there are other bits that are set for NFS files. On HP9000, bmajor is defined, and I paraphrase: #define bmajor(x) major(x) /* Unsure of AT&T's intentions here, bmajor masked off bits in porting base */ I betcha that the following would be fairly universal without having to resort to individual #ifdef's for each variant of UNIX: if (makedev(major(stb.st_dev),minor(stb.st_dev)) != stb.st_dev) { aha - NFS/RFS file! } else { local disk file } Anywho, could I get a few people to try the following C program on their systems that have NFS and/or RFS partitions mounted on them and mail the results to me? This is what you would have to do: - unshar this file. - undef USG if you aren't a UNIX System V variant (if you get major or minor undefined messages from cc, you probably need to define USG) - compile the program ala: cc -o teststat teststat.c - Find the names of a couple of files on your local disks, plus a few of them on filesystems mounted from other systems, and run teststat with these file names as arguments. Eg: ./teststat / /etc To make the results perfectly clear, could you also include your teststat command line and the output of df from your system? Thank you very much #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'teststat.c' <<'END_OF_FILE' X/* %I% %E% */ X#define USG /* undef if you aren't some sort of System V */ X#include X X#include X#include X#ifdef USG X#include X#endif X Xstruct stat stb; X Xmain(argc, argv, envp) Xint argc; Xchar **argv; Xchar **envp; { Xint i = 1; X for (;argv[i]; i++) { X if (stat(argv[i], &stb) == 0) { X printf("file: %s dev: %x major: %x minor: %x\n", argv[i], X stb.st_dev, major(stb.st_dev), minor(stb.st_dev)); X if (makedev(major(stb.st_dev),minor(stb.st_dev)) != stb.st_dev) X printf("I think %s is a networked file\n", argv[i]); X else X printf("I don't think %s is a networked file\n", argv[i]); X } else X perror(argv[i]); X } X} END_OF_FILE if test 685 -ne `wc -c <'teststat.c'`; then echo shar: \"'teststat.c'\" unpacked with wrong size! fi # end of 'teststat.c' fi exit 0 -- Chris Lewis, Elegant Communications Inc, {uunet!attcan,utzoo}!lsuc!eci386!clewis Ferret mailing list: eci386!ferret-list, psroff mailing list: eci386!psroff-list