Question

Given a mounted cifs file system /network/cifs which is case insensitive, how do I obtain the case sensitive path using C?

For example, the fs has a file /network/cfis/Adena/t.txt. Given /network/cfis/AdEnA/T.txt (which properly resolves), I want /network/cfis/Adena/t.txt.

I know one way to do it is to recursively iterate over the path, match them in all lower case, and get the actual case returned by the directory iteration. However, this involves a lot of syscalls that I would rather not do.

Changing the mount options is not a solution.

If this is not possible, is it possible to determine if a path is on a case insensitive file system? This way I could avoid doing recursive directory iteration unless required.

Was it helpful?

Solution

That question just came up last night in IRC; my answer was you have to iterate, and the reason is that getcwd (which may be implemented by just looking at /proc/N/ files in Linux) is not reliable to determine the canonical name. The Linux CIFS kernel module will fake up inodes on the fly with the casing that you asked for:

ls -dli /mnt/foo /mnt/foO /mnt/fOo /mnt/FOo /mnt/FOO

can show very different values, and as such, /proc/self/cwd will reflect one of these inodes, not necessarily the one with the canonical naming.

OTHER TIPS

A possible solution might be to open the file for reading, getting a file descriptor, for instance 23, then to readlink the pseudo-file /proc/self/fd/23 (but perhaps that trick won't work well, I did not try it)

For what it's worth, here is a way that works on OSX (but apparently not Linux):

#include <stdlib.h>
char case_sensitive_path[1024];
realpath("/network/cfis/AdEnA/T.txt", case_sensitive_path);
// case_sensitive_path is now "/network/cfis/Adena/t.txt"
#include <stdlib.h>
#include <stdio.h>  /* defines FILENAME_MAX */
#ifdef WINDOWS
    #include <direct.h>
    #define GetCurrentDir _getcwd
#else
    #include <unistd.h>
    #define GetCurrentDir getcwd
 #endif


int main(void)
{
   char buffer[FILENAME_MAX];

   chdir("/network/cfis/AdEnA");
   if (NULL == GetCurrentDir(buffer, FILENAME_MAX))
      perror("getcwd error");
   printf("The current directory is %s.\n", buffer);
   return 0;

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top