Page 2 of 2

Re: Best way to resolve a soft link?

Posted: Tue Jun 03, 2014 6:48 am
by colinward
Hello everyone.

I have been away so have not been able to get back to this thread for a while.

It seems my question was not understood, or at least I need to explain the idea behind what I want to do and why.

I am writing (actually have written) some backup software which mirrors a partition or directory onto another partition or directory. Currently is just skips any links that it finds but I want it to be able to recreate links on the target backup directory. A good example is the Amiga SDK - it contains about 15 or so softlinks. When I backed my AmigaOne hard drive up onto another hard drive for use on my new AmigaOne, the SDK did not work as the links had not been recreated. So I want to update my backup software to be able to handle these links. For example, in the SDK:gcc/bin directory we have the following files (among others):

$List SDK:gcc/bin/
Directory "SDK:gcc/bin" on Tuesday 03-Jun-14
ppc-amigaos-strip Link ----rwed 03-Nov-13 15:20:45
> DH2:SDK/gcc/bin/strip
ppc-amigaos-strings Link ----rwed 03-Nov-13 15:20:45
> DH2:SDK/gcc/bin/strings
ppc-amigaos-readelf Link ----rwed 03-Nov-13 15:20:45
> DH2:SDK/gcc/bin/readelf

I want these links to be recreated in the target directory. For this I can't just let DOS "take care of things" but must work with the links themselves directly. We have DOS->MakeLink() that can be used to create the link in the target directory, but I need to first find the target of the link in the source directory in order to know how to recreate it on the target.

I already perform an ExamineDir() loop and then check within this loop to see if a file is a link EXD_IS_LINK() and at this point I could get information about the target of the link. Unfortunately this is in a C++ abstraction layer that runs across three platforms (Amiga, Windows, Linux) allowing my code to be "write once, run anywhere" to an extent, so I do not want to modify this to save link information for every file. It would be easier to write a GetLinkInfo() function that works on Amiga, Windows and Linux and returns information about the target of the link. But for this there does not seem to be a way of doing this apart from using this old DOS->ReadSoftLink() function or by rescanning the directory with ExamineDir() which of course is inefficient. On Windows and Linux there are functions for this but not on Amiga that I can find.

So it seems that we have a small API deficiency here. Any other ideas?

Re: Best way to resolve a soft link?

Posted: Tue Jun 03, 2014 4:06 pm
by joerg
colinward wrote:So it seems that we have a small API deficiency here. Any other ideas?
The API would have been enough, ExamineDir() should return the target string of soft links in ExamineData->Link, but starting with dos.library 53.130 soft links were made unusable (see BUGS section of the MakeLink autodoc), ExamineData->Link is wrong now and as workaround you have to use ReadSoftLink() on each soft link to get the correct link target again, and for MakeLink() to work you have to use SFS 1.291 which includes a workaround for the dos.library soft link bugs (for MakeLink() only, not for ExamineDir() or any other dos.library function), on all other file systems MakeLink() is no longer usable for soft links because the target string is changed by dos.library before passing it to the file systems.
For other old, packet file systems you could use IDOS->DoPkt(port, ACTION_MAKE_LINK, ...) instead of IDOS->MakeLink() for creating the soft links, but I don't know if such a workaround is possible for new vector port file systems.

Re: Best way to resolve a soft link?

Posted: Wed Jun 04, 2014 3:32 am
by colinw
colinward wrote:Hello everyone.
[...]
So it seems that we have a small API deficiency here. Any other ideas?
Everything you need is already there, providing I understand exactly what you are asking for.
As I read it, you simply want to re-create all softlinks on the source volume into the destination volume as is,
to obtains a mirrored directory structure.

You also mentioned that you need additional information about the softlink target object too, I assume that's
just for statistics like target object type and size of file, protection, comments, etc...
The code to get the softlink target informations during a scan was supplied in reply #5 on the previous page.

To re-create the softlink on the destination volume, just use the ExamineDirData->Link target string as
the target string for the MakeLink() function, and the ExamineDirData->Name (relative to the destination)
for the link name. Nothing else required, just remember to specify EXF_LINK during the scan.

ie;
Strlcpy(linkname, "bla:destination_dir",sizeof(linkname));
AddPart(linkname, ExamineDirData->Name, sizeof(linkname))
MakeLink(linkname, ExamineDirData->Link, LINK_SOFT);

or;
oldcd = SetCurrentDir(destination_dir_cd);
MakeLink(ExamineDirData->Name, ExamineDirData->Link, LINK_SOFT);
SetCurrentDir(oldcd);

This will work properly for all situations when a dos.library update gets out to address the recent bug found.
Contrary to the apocalyptic catastrophe implied by others, just don't sacrifice your first born to a Volcano yet.
The only real problem was that the softlinks target descriptor always included a full DOS device name relative
path instead of just a root dir ":" path for relative specifications, this bug was only discovered recently when
someone tried to access a "backed up" softlink on the new volume and discovered it still referenced the original
target path on the old volume, rather than the path relative to the current one, this only affects creating of
relative softlinks when copied to a different volume and accessed from there, softlinks that are intensionally
created to a target that is a full DOS path to other volumes or devices are unaffected, this is why it took a while to find.

As you only want to "mirror" an existing volume for backup purposes, this shouldn't even be an issue for you.
But if you want an immediate "fix" for relative softlink targets, contact me again and I can supply a small patch
for the MakeLink() functions until a new dos.library gets released.

By the way, IDOS->ReadSoftLink() only returns exactly the same string as what is in ExamineData->Link,
so don't bother wasting your time messing with that function.

Re: Best way to resolve a soft link?

Posted: Wed Jun 04, 2014 7:14 am
by Calgor
colinw wrote:The only real problem was that the softlinks target descriptor always included a full DOS device name relative
path instead of just a root dir ":" path for relative specifications, this bug was only discovered recently when
someone tried to access a "backed up" softlink on the new volume and discovered it still referenced the original
target path on the old volume, rather than the path relative to the current one, this only affects creating of
relative softlinks when copied to a different volume and accessed from there, softlinks that are intensionally
created to a target that is a full DOS path to other volumes or devices are unaffected, this is why it took a while to find.
If I read this correctly, this may even be a contributing factor why Deniil's backup program backs up relative softlinks with full path on the destination (or has no option to copy relative paths as-is). Thanks for the info.

Re: Best way to resolve a soft link?

Posted: Wed Jun 04, 2014 7:17 am
by joerg
colinw wrote:To re-create the softlink on the destination volume, just use the ExamineDirData->Link target string as
the target string for the MakeLink() function, and the ExamineDirData->Name (relative to the destination)
for the link name. Nothing else required, just remember to specify EXF_LINK during the scan.
Even if ExamineDirData->Link is still correct, if it wasn't created by a version of MakeLink() with the 53.130+ bug but an older version of dos.library, copying relative soft links, i.e. 99% of all soft links, that way doesn't work any more (except with SFS 1.291) because the current version of MakeLink() will fail if the target doesn't exist (yet), which is often the case when copying directories, or even worse destroy the relative links, by replacing the target string with the result of DevNameFromLock(...,DN_ROOTPATH) + AddPath(), if it exits already.

Re: Best way to resolve a soft link?

Posted: Thu Jun 05, 2014 12:31 am
by colinw
Calgor wrote: If I read this correctly, this may even be a contributing factor why Deniil's backup program backs up relative softlinks with full path
on the destination (or has no option to copy relative paths as-is). Thanks for the info.
That would be quite likely, although I am not familiar with that particular piece of software, i'm sure he knows what he's doing,
he's been a prolific coder for some time on the Amiga scene, we should be gratefull for his contributions.

By encoding the target descriptor as a complete DOS path, either as an absolute path, or a root relative path (relative to the link volume),
it allows it to be relocated easily without additional references, especially in a "backup" situation, copying links and breaking them
while doing so, would be somewhat counter productive, at least link targets with a root directory relative path will always know where
a volumes root directory is at, so you always have consistency. Another caveat I had to consider was to also be able to move and rename
softlinks with the new filesystems.

Re: Best way to resolve a soft link?

Posted: Thu Jun 05, 2014 1:50 am
by joerg
Calgor wrote:If I read this correctly, this may even be a contributing factor why Deniil's backup program backs up relative softlinks with full path on the destination (or has no option to copy relative paths as-is).
Very unlikely since that wouldn't make any sense, a backup program which doesn't make a 1:1 copy but changes something while copying the data is broken, and it would be exactly the same bug as in the dos.library 53.130+ MakeLink() function.
To test if his backup program works correctly you have to test it with either dos.library <= 53.129 or with the target directory on a SFS 1.291 partition.

Re: Best way to resolve a soft link?

Posted: Thu Jun 05, 2014 1:59 am
by joerg
colinw wrote:Another caveat I had to consider was to also be able to move and rename softlinks with the new filesystems.
Problems with new vector port file systems, or even the new API, are no reason to break the soft link support on old packet file systems, where it's working without any such problems, as well.