· May 12, 2020

How does Enslib.FTP use %Net.FtpSession for file listing?

I have been using %Net.FtpSession and while it works, its handling of file/directory listings from an FTP server is less than ideal and, while this is due to the FTP protocol itself, the class could be written to handle this as would an FTP client such as FileZilla and command line/class FTP handlers for other languages.  I was wondering if anyone knows how the Ensemble adaptor works with this in case it provides code that would help, though the source does not seem to be available.  Below are the issues I see in FTP, some are based on past experience writing our own FTP handler in the past, and how that affects the class.

There are 2 methods available:

This issues an NLST command to the FTP server to get a list of filenames back.  The description says "will return an array of filenames including their path".
There are several issues with this.  Firstly, the returned list may or may not include the directory even though the class says it will and there is no code to check or enforce it in the class.  Secondly, some FTP servers will include directory names and others will not and there is no indicator to say if an entry is a directory or not.  Lastly, there are no file details returned with the list so to get size or datetime you issue additional FTP commands that can be performed by additional class methods, however, not all FTP servers support these commands.
So, inconsistencies and limited information make this a poor choice but possible lack of support for additional commands make it worse.

The good news is all FTP servers support the LIST command used and it returns file details along with the file list, the bad news is it returns a human readable string for each entry and different FTP servers format this in different ways.  This means that the code needs to have knowledge of the different formats and be able to decode them to turn the string information into something usable.

For an example, FileZilla,a very popular FTP client, uses LIST and decodes it, as can be seen if you turn on raw directory listings in the debug options.

I have wriitten code that deals with this by decoding LIST responses but this means I have to maintain it while I had expected that an FTP class might be aware of, and deal with, these issues and I assume the Ensemble adaptor must do this.

Discussion (2)3
Log in or sign up to continue

Hi David.

Source code for EnsLib.FTP.InboundAdapter is available in the installation.

EnsLib.FTP.InboundAdapter calls method %Net.FtpSession:List to get files. And that method uses "LIST" command.

EnsLib.FTP.InboundAdapter:OnTask executes following resultSet to get files:

Set tSC=..%CurrResultSet.Execute($this,..FilePath,..FileSpec,..SubdirectoryLevels,$S(..%isSFTP:"FileListSSH",1:"FileList"),..SemaphoreSpec)  Quit:$$$ISERR(tSC)

And in OnInit, ..%CurrResultSet is initialized as follows:

Set ..%CurrResultSet=##class(%ResultSet).%New($$$CurrentClass_":DeepList")

Query DeepList is defined in EnsLib.File.Common, and it's just a proxy for the query that is passed as 5th parameter to the Execute -- FileList in this case.

And EnsLib.FTP.Common:FileList calls %Net.FtpSession:List.

Hello Alexander,

I did eventually find that, we don't use Ensemble and I had expected some central classes but they are only available in an Ensemble enabled namespace.

It does look like the EnsLib.FTP.InboundAdaptor eventually breaks down the strings from LIST using expressions defined in OnInit based on the remote OS which I assume they get using SYST.

I still don't understand why this isn't part of %Net.FtpSession as I cannot use this without Ensemble and Ensemble namespaces have their own complications, such as 2 extra databases, we currently avoid.

I think I will raise a WRC to request this.

Thanks for the help.