Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Modifying a directory file

by davidgl (Novice)
on Jan 05, 2018 at 13:26 UTC ( #1206751=perlquestion: print w/replies, xml ) Need Help??

davidgl has asked for the wisdom of the Perl Monks concerning the following question:

I'm asking this as a result of someone who has an 'impossible' problem on their Mac asking on a Mac list.

They have a file that originated before MacOS X, that is before the Mac OS became Unix based. The first three characters of the filename are NULLs. Needless to say, any Unix function that tries to manipulate that file fails at the name -> inode lookup stage because the filename string terminates at the first char.

I fixed a similar problem around 35 years ago by doing a binary edit on the directory file, but that option is no-longer available, especially on a Mac, so I'm looking at Perl. I am reasonably familiar with Perl, but not an expert.

In Perl I can opendir() and readdir() to find the entry but that doesn't give me the rest of the directory entry structure. If I had that, I could change the name and hopefully re-write the directory file.

Does anyone have any pointers? I can't think of any other group where I would find real 'bit twiddlers'.

Thanks, David

Replies are listed 'Best First'.
Re: Modifying a directory file
by dave_the_m (Monsignor) on Jan 05, 2018 at 22:10 UTC
    If it was me, I would just move/rename the directory itself somewhere out of the way on the same filesystem, then create a new dir with the correct name and permissions, and move all the files, except the impossible one, back to the new directory.

    If you *really* need to actually fix the directory entry, then a quick+dirty solution would be to treat the filesystem's raw device as a block file (i.e. the OSX equivalent of Linux's /dev/sda, whatever that is), then if the file name is distinct enough (e.g. "\0\0\0\0some_long_name"), search for that text within the device, and if it's only found once, then rewrite the block holding that string with the \0's replaced with X or whatever (Preferably done with the filesystem unmounted).

    Dave.

Re: Modifying a directory file
by soonix (Abbot) on Jan 05, 2018 at 18:38 UTC
    Did you try good old fsck? I am not sure if it will help, but it's at least worth a try.
Re: Modifying a directory file
by Eily (Monsignor) on Jan 05, 2018 at 14:08 UTC

    If perl is better at seeing that file than others, did you try rename or File::Copy?

    Edit: I realized I misread your post and thought you could open the file. Still worth a try I guess?

      I can't use anything that specifies the file by name as the name is effectively null. Perl tends to have more direct access to system calls and system library functions. I haven't written in C for around 25 years, and never on a Mac, so Perl would be easier.

      The approaches I can see are:

      a) rename the file

      b) remove the inode-equivalent from the directory entry and let fsck fix it. (FS is Apple's HFS+)

      c) set the inode use count to zero and let fsck tidy it. (Can a stat() structure be re-written to do that, or is that trapped?)

      Thanks, David
Re: Modifying a directory file
by virtualsue (Vicar) on Jan 05, 2018 at 14:58 UTC
    Do you know why this person has a file which sounds like it is, frankly, corrupt? If its filename starts with 3 null characters, then I wouldn't necessarily expect the file to contain anything useful. I would immediately suspect that the transfer process, whatever it was, has gone tragically wrong. :-)
      The file is a hang-over from when his data tree was on a MacOS9 system. Under that OS and earlier the string delimiter was other than NULL, so it would be a legal filename back then. He just wants to delete the file. It is currently in his 'Trash' ( = 'Recycle bin') and emptying it fails. Unfortunately he has been able to create another file of the same name by using the Finder to copy and paste the name, but once set it cannot be replaced.

      I don't know how the file was copied from the old OS9 system, but any raw inode level copy would work. It could even be the old OS9 Mac drive.

      David

        Now that you say that the goal is to remove the file, I would try deleting it by inode, bypassing the filename altogether. A combination of ls & find will probably do the job. Web searches should turn up a useful recipe. If that failed, I would cheerfully ignore it in the knowledge that the drive is going to die some day. I'm mildly curious as to how it got to Trash (since files don't tend to originate there, so it was moved there by something). Not curious enough to experiment though. I have a list of quixotic tasks I'm working on already.
Re: Modifying a directory file
by Anonymous Monk on Jan 05, 2018 at 15:33 UTC
    Per uses regular system calls. It passes null to system call which ignores everything after null
      That's why the file has to be specified by inode (HFS+ equivalent) number or as the only entry in a directory. I suppose I need a directory entry structure reader/writer for HFS+. Maybe Perl doesn't have one either.

      Thanks, David

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1206751]
Approved by hippo
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2020-01-20 14:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?