I would like to know how an absolute path of a symbolic link can be converted to relative based on a given directory (that includes the linked file) in c language on linux (Ubuntu) OS.
I thought searching for the sub-string of the relative path, but what if it already exists higher in the folder's hierarchy?
Here is a more specific description of what I want to do: Relative path:
folder/folder1/folder2
Absolut path:
/home/giorgos/Desktop/folder/folder1/folder2/a.pdf
changed to
/home/giorgos/Desktop/myfolder/folder1/folder2/a.pdf
Obviously I cant' simply search for and replace "folder/", consider this case:
/home/giorgos/Desktop/folder/folder/folder/folder1/folder2/a.pdf
It can be searched both forwards and backwards and if replaced it still gives a wrong output Only if I knew the relative path I could search the absolute backwards and replace it, then the output would be correct:
/home/giorgos/Desktop/folder/myfolder/folder/folder1/folder2/a.pdf
I'd be seriously tempted to make the decision, if I were writing this tool, that absolute symbolic links should have the same value when moved somewhere else in the filesystem -- the user wanted a very specific file. And, relative symbolic links should have the same value when moved somewhere else in the filesystem -- the user wanted the links to work regardless of where the directory tree was rooted.
But if the two types of links were intermixed, then you'd have some more work to do -- which is where I assume you are now. (Unix programs are often not that forgiving about guessing a user's intent; if you just readlink(2)
and symlink(2)
exactly what the filesystem says, your program will never be surprising.)
rsync(1)
might have some source code you can use -- or at least learn from. The --safe-links
command line option causes rsync
to ignore absolute symbolic links and relative symbolic links that point outside the trees it was instructed to copy. This isn't canonicalizing paths to relative as you wish but it may provide sufficient code for discovering which links point outside the directory tree in question.
Slightly related; the Linux-specific symlinkat(2)
system call may make it easier for you to create your symbolic links. (The family of ...at()
system calls are something like providing a process with multiple "current working directories" without forcing you to make all the fchdir(2)
calls yourself.)