crealpath

C program: determine which directory a file is in


What would be a good method to determine which directory a file is in? I would use realpath(), but that returns the absolute path of the file or directory to which a symlink is pointing.

For instance, if the argument is the basename of a file, and lstat() returns 0, I can confirm that the file exists. But for the purposes of the program I'm working on, I need to determine which directory that file is in.

The project is on GH, so I don't mind posting code here if it helps answer the question. Thanks!

UPDATE: Here are some specifics: The code is near L64. If the file, dir, or symlink is in .local/share/Trash.test/files/, I need to find the corresponding trashinfo file in .local/share/Trash.test/info/.trashinfo. Normally I truncate the return value realpath() at files/, then append info/, then append the basename and .trashinfo ext. and after that, it does what I need. But when I try to get the realpath of the symlink, the absolute path to it is returned, but it's the path to what the symlink points to (e.g. /home/andy/temp/.local/share/Trash.test/files/dnsmasq -> /usr/share/doc/dnsmasq


Solution

  • This is how I solved what I was trying to do.

    This does some boundary checking. Not relevant to the problem (I see I need to add another check or two though).

      buf_check (argv[restore_request], PATH_MAX);
    

    argv[restore_request] is the file to be restored. This can be an absolute or relative path, or it can just be a basename, depending on the current working directory.

      strcpy (file.relative_path, argv[restore_request]);
    
      file.base_name = basename (argv[restore_request]);
    

    This places a '\0' in the string: str[strlen(str) - strlen (file.base_name)], in effect, chopping off the basename.

      truncate_str (file.relative_path, strlen (file.base_name));
    

    I believe the remaining lines are self-explanatory

      strcpy (file.info, file.relative_path);
      strcat (file.info, "../info/");
      strcat (file.info, file.base_name);
      strcat (file.info, DOT_TRASHINFO);
    

    Now the path to the info file can be found, which was the desired result. I apologize that my question was not clear and didn't provide enough details to properly illustrate my goal. I will make it a point to write better questions in the future. Thanks to all who took the time to give me feedback.