grt@twitch.UUCP ( G.R.Tomasevich) (05/07/87)
This is a subsidiary to the 'more' discussion. I partly tested a method on Sys V R2, VAX 11/785. One can fstat(2) to get the inode value and the block-special identity. One must find out the name of the device, perhaps from stat'ting the disk devices until finding the right one (untested). One then generates and runs a command "/etc/ncheck -i inode blockdevice". On twitch one must be super-user to do that; I tried a file, and it took several minutes for ncheck to find the name. One then needs /etc/mount to associate the device with the proper mount directory. Whew! Is there a better way? Someone suggested walking down from /. How would he find out the correct file system, assuming more than one file matched the inode number? -- George Tomasevich, ihnp4!twitch!grt AT&T Bell Laboratories, Holmdel, NJ
mpl@sfsup.UUCP (05/11/87)
In article <710@twitch.UUCP>, grt@twitch.UUCP writes: > .... > One then generates and runs a command "/etc/ncheck -i inode blockdevice". > On twitch one must be super-user to do that; I tried a file, and it took > several minutes for ncheck to find the name. One then needs /etc/mount > .... On the last project I worked on, someone (Larry Feigen to give him credit) wrote a program called "fdcheck". It does the following for each file descriptor of interest: runs /etc/mount to get the mount points of all mounted file systems does a stat to get the device number for each mounted file system does an fstat on the file descriptor(s) to get the device/inode number(s) does a "find dir -print | xargs ls -i | sed -e ...." to pick out the path names of interest. This method is surprisingly fast (takes a minute or 2 on our 3B20s with big disks - a little longer on slower machines), and if you give the program some hints as to where you think the files might be (he has a way of passing it a file with a table of such info in it), it can get by in just a few seconds! Mike Lindner
jfh@killer.UUCP (John Haugh) (05/13/87)
I opened my mouth and said it could be done. I refuse to write C code on my lunch hour so you will have to take what you get. Refer to ftw(3), fstat(2) and stat(2) for all of the information you should need. You don't REALLY need ncheck, find, /etc/mnttab or any of that other stuff. stat(2) and fstat(2) return plenty enough information. You _can_ make things go faster by finding the correct root directory. main find_file_name ("/", your_fstat_structure) -- start from root directory -- with fstat(2) values. end procedure find_file_name (current_directory, file_fstat) if current_directory.file_stat = file_fstat then -- was FD this directory? putstring (current_directory) return fi for each file_entry in current_directory -- stat(2) each slot if file_entry.file_type = directory_type then -- recursively call directories find_file_name (current_directory + file_entry.file_name, file_fstat) elif file_entry.file_stat = file_fstat then -- else check to see if it is the file -- by checking st_ino and st_dev fields. putstring (current_directory + file_entry.file_name) -- and print the name if you found one. return fi end There you have it. All accessible files are checked, which should include yourown since you should be able to read you own directory. The ones you can't access can't be accessed :-(. st_ino and st_dev are all you need to compare to see if the files are the same ones. This should (once written in C or something) be as fast or faster than find(1) since find(1) has atleast this much work to do. - John. Disclaimer - I speak for myself. My boss pays me money when he wants me to speak for him.
jgy@hropus.UUCP (John Young) (05/19/87)
> main > find_file_name ("/", your_fstat_structure) -- start from root directory > -- with fstat(2) values. > end > > procedure find_file_name (current_directory, file_fstat) > > if current_directory.file_stat = file_fstat then > -- was FD this directory? > putstring (current_directory) > return > fi > for each file_entry in current_directory -- stat(2) each slot > if file_entry.file_type = directory_type then > -- recursively call directories > find_file_name (current_directory + file_entry.file_name, > file_fstat) > elif file_entry.file_stat = file_fstat then > -- else check to see if it is the file > -- by checking st_ino and st_dev fields. > putstring (current_directory + file_entry.file_name) > -- and print the name if you found one. > return > fi > end > > > There you have it. All accessible files are checked, which should include > yourown since you should be able to read you own directory. The ones you > can't access can't be accessed :-(. st_ino and st_dev are all you need to > compare to see if the files are the same ones. This should (once written > in C or something) be as fast or faster than find(1) since find(1) has atleast > this much work to do. > > - John. > This doesn't seem to handle the case of having a filesystem mounted on anything but a root level directory. - John Young
jda@mas1.UUCP (05/20/87)
Several pointed out that a file with no links has no name. But Ultrix 1.0 (and presumably also 4.2BSD) often makes NO change to the directory entry when a file is unlinked. (The preceding entry has its d_reclen incremented to render the obsolete entry "invisible". Presumably the obsolete entries are destroyed only when the directory is about to grow by a block.) You will need a special version of readdir(3) which returns "erased" entries. It should be fun to write since the obsoleted entries can be in various stages of obliteration! :-) BTW, has anyone written a real "unrm" program? -- James D. Allen
gwyn@brl-smoke.UUCP (05/20/87)
In article <513@mas1.UUCP> jda@mas1.UUCP (James Allen) writes: >You will need a special version of readdir(3) which returns "erased" >entries. What good would that do you? You couldn't open the inode anyway.
matt@oddjob.UChicago.EDU (Keeper of the Sacred Tablets) (05/21/87)
gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: ) In article <513@mas1.UUCP> jda@mas1.UUCP (James Allen) writes: ) >You will need a special version of readdir(3) which returns "erased" ) >entries. ) ) What good would that do you? You couldn't open the inode anyway. And the block pointers have all been zeroed out. (This makes fsck happier.) Oh well, if he just wants the name of the file that's gone, much good may it do him. ________________________________________________________ Matt University matt@oddjob.uchicago.edu Crawford of Chicago {astrovax,ihnp4}!oddjob!matt
dhesi@bsu-cs.UUCP (05/22/87)
Following up on the discussion of how to find a name given a file descriptor, I want to point out that the ttyname() library function already does that to a limited extent. It accepts a file descriptor and returns the name of the terminal device corresponding to it. Presumably it only searches /dev. And the name it finds that may not be the one that is needed. Using cu under Microport System V/AT when multiple links exist to the same serial device, I find that cu creates the lock file /usr/spool/uucp/LCK..tty0 when it is invoked, because /dev/tty0 is the default device for cu. But when it exits, it does not use the same name, because it apparently calls ttyname() and uses whatever name is returned. In my case it tries to then remove the lock file /usr/spool/uucp/LCK..ttycg and fails to find it and complains. This was clearly an oversight on part of the author, who assumed that there would be only one link to a serial device. The right thing to do would be to always use ttyname(), so no matter how many links exist, the same lock file will be used for the same physical device. I found similar strange things happening under 4.3BSD if there was more than one link to a terminal in /dev, though I don't remember which program (tip or cu or uucico) was affected. -- Rahul Dhesi UUCP: {ihnp4,seismo}!{iuvax,pur-ee}!bsu-cs!dhesi
jfh@killer.UUCP (John Haugh) (05/27/87)
In article <3792@oddjob.UChicago.EDU>, matt@oddjob.UChicago.EDU (Keeper of the Sacred Tablets) writes: > And the block pointers have all been zeroed out. (This makes > fsck happier.) Oh well, if he just wants the name of the file > that's gone, much good may it do him. Those block pointers had better be someplace or anyone trying to read/write the file is gonna' be in _BIG_ trouble. There is still the inode table, you if you _really_ want to, you can open /dev/kmem and go looking for the inode there. Bmap() still needs the 13 inode (last time I looked :-)) addresses - and the *-indirect blocks still have to have their addresses. - John. Disclaimer - No disclaimer. Whatcha gonna do, sue me?