2

I'm just trying to recover a file in C on an HFS+ formatted Volumn. According to

man undelete

NAME undelete -- attempt to recover a deleted file

LIBRARY Standard C Library (libc, -lc)

SYNOPSIS #include

 int
 undelete(const char *path);

DESCRIPTION

The undelete() system call attempts to recover the deleted file named by path. Currently, this works only when the named object is a whiteout in a union file system. The system call removes the whiteout causing any objects in a lower layer of the union stack to become visible once more.

Eventually, the undelete() functionality may be expanded to other file systems able to recover deleted files such as the log-structured file system.

RETURN VALUES

The undelete() function returns the value 0 if successful; otherwise the value -1 is returned and the global variable errno is set to indicate the error.

so the Program is simple:

The current directory (pwd) is /Users/Leo/Desktop/ and I'm on a Mac 10.7.2 with HFS+ Filesystem.

#include <unistd.h>
int main()
{
    char a="/Users/Leo/Desktop/test/a.out";//I delete a.out using rm for testing
    const char* pa=&a;
    return undelete(pa);
}

But when I run the program, I got shell returned 255.

Any idea? Thanks

glglgl
  • 89,107
  • 13
  • 149
  • 217
YankeeWhiskey
  • 1,522
  • 4
  • 20
  • 32
  • 3
    the man page tells you that undelete sets errno. So call perror to see what the error is. – William Pursell Nov 04 '11 at 18:24
  • 2
    Note the documentation says "Currently, this works only when the named object is a whiteout in a union file system.". This is a fairly exotic configuration to have, so this probably isn't the case for you. – Random832 Nov 04 '11 at 18:47
  • `char a="/Users/Leo/Desktop/test/a.out";` <- invalid char value. You're also using the wrong type. String literals must be either a pointer to const chars (`const char *a = "...";`), or an array of const chars (`const char a[] = "...";`) – jweyrich Nov 04 '11 at 18:59

2 Answers2

1

undelete is failing. To find out why, check errno. For example:

#include <unistd.h>
int main( int argc, char **argv )
{
    char *path = argc > 1 ? argv[ 1 ] : "a.out";

    if( undelete(path))
        perror( path );
    return 0;
}

Although it appears your problem is that you have a char instead of a char pointer. You should have gotten a compiler warning.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • I tried your code and the errno says /Users/Leo/Desktop/test/test: No such file or directory. Actually I created and removed file "test" for testing – YankeeWhiskey Nov 04 '11 at 19:18
  • Read http://lwn.net/Articles/325369/. You need a directory entry for undelete to work. Simply using rm on the path will certainly not work if your filesystem is not a union file system. – William Pursell Nov 04 '11 at 19:29
1

First, you need to check the return value and evaluate it. If it is -1 then print an error message, for example with perror or by formatting an error message and using strerror(errno).

But you've also got a major bug before you even attempt to call undelete:

char a="/Users/Leo/Desktop/test/a.out";
const char* pa=&a;

This will first assign a value (the pointer to your string) to a char, a single byte value. The compiler even warns about that with warning: initialization makes integer from pointer without a cast. In my case, a then had the value D/0x44, but it could have been anything. You then store the pointer to that single byte in pa. What you want instead is:

const char* pa="/Users/Leo/Desktop/test/a.out";
DarkDust
  • 90,870
  • 19
  • 190
  • 224
  • Thanks. I got it. But the program still don't work after I correct such dumb mistake. errno display /Users/Leo/Desktop/test/test: No such file or directory. Actually I created and removed file "test" for testing. Any further information? thanks – YankeeWhiskey Nov 04 '11 at 19:21
  • The man page says: *Currently, this works only when the named object is a whiteout in a union file system.* This means it'll only work with a union mount (see for example [this article](http://aplawrence.com/foo-mac/union-mounts.html) on how to set one up). It will not work on your usual HFS+ mount points. – DarkDust Nov 04 '11 at 19:31