Best way to resolve a soft link?

This forum is for general developer support questions.
colinward
Beta Tester
Beta Tester
Posts: 8
Joined: Sun Jan 06, 2013 9:29 am

Re: Best way to resolve a soft link?

Post 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?
joerg
Posts: 371
Joined: Sat Mar 01, 2014 5:42 am

Re: Best way to resolve a soft link?

Post 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.
User avatar
colinw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 186
Joined: Mon Aug 15, 2011 9:20 am
Location: Brisbane, QLD. Australia.

Re: Best way to resolve a soft link?

Post 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.
User avatar
Calgor
Beta Tester
Beta Tester
Posts: 319
Joined: Mon Dec 20, 2010 4:42 pm

Re: Best way to resolve a soft link?

Post 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.
Amiga 4000T: CSPPC 604e@233/060@50 146MB RAM/CVPPC/Mediator/Radeon 256MB/Realtek 8029AS/TerraTec Solo1-N/Picasso IV (Paloma Pablo Concierto)/Deneb/ZorRAM 256MB/Indivision AGA MKII/OS4.xBETA/OS4.1u4/OS3.9BB2
AmigaONE X1000: Nemo 2.1 PA6T-1682M@1.8 2GB RAM/Radeon HD 4770 512MB/Catweasel MK4+/Audigy 2 ZS/Realtek 8139D/OS4.xBETA/OS4.1u5
joerg
Posts: 371
Joined: Sat Mar 01, 2014 5:42 am

Re: Best way to resolve a soft link?

Post 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.
User avatar
colinw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 186
Joined: Mon Aug 15, 2011 9:20 am
Location: Brisbane, QLD. Australia.

Re: Best way to resolve a soft link?

Post 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.
joerg
Posts: 371
Joined: Sat Mar 01, 2014 5:42 am

Re: Best way to resolve a soft link?

Post 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.
joerg
Posts: 371
Joined: Sat Mar 01, 2014 5:42 am

Re: Best way to resolve a soft link?

Post 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.
Post Reply