About FTP Use

Gen FTP commands are utility / convenience commands that are built on top of the tcllib ftp package.

Getting Set Up

To configure Gen for using certain FTP-related commands, you need to (A) add the following configuration code to your software, before you start using FTP commands, or (B) open src/gen-config.tcl and configure by hand the following (though beware of overwriting when you update your version of Gen):

  1. set GenNS::Ftp::Server [Required. ip address of your server]
  2. set GenNS::Ftp::Username [Required. username to log on that machine]
  3. set GenNS::Ftp::Password [Required. password to log on that machine]
  4. set GenNS::Ftp::OptionsList [Optional. list of options to use, see here for a list of options you can use.]
  5. set GenNS::Ftp::FileTransferType [Optional. ascii | binary | tenex -- How to transfer the files.]

The OptionsList should look something like this :

"-port 21 -mode active"

Note that you do not have to set OptionsList; you can leave it blank.

Note that for any FTP command which takes in an FTP handle as its first argument, you do not have to configure the above. You can manage the FTP connection yourself and use only a few utility commands to assist you with the rest of your code.

Main Use Cases

The main use cases for this software are for when:

  1. You are writing your own (Tcl) code and want simple file-transfer within it.
  2. The machine you will want to interact with has an FTP server, but (a) you do not know what type of machine it will be (Windows / UNIX) -and/or- (b) you cannot install your own software on it -and/or- (c) it does not have any other file sync software (e.g. rsync) installed on it for you to use.
  3. What you want to do is really pretty simple (e.g. just do a simple mirror or the equivalent of copy/paste).
  4. You do not want to work through the details of the ftp package yourself.
Otherwise you may want to look into a full-featured file sync program. Or, use something simple like this to get going and figure out what you want, and then adopt something else for more advanced usage.


The following are issues you may encounter, which this software cannot really do anything about. For other issues, see the following section.

Missing Features, For Possible Future Release

To Safely See What Would Happen: Dry Run Option

If you do the following :

set GenNS::Ftp::DryRun 1

Then when you run a command, it will print to each change that it would have made. The exception is when it would have had to make a directory and then switch into it to continue on a copy over the contents. At that point, Gen will not create the directory, but rather will skip on to the next item. For that scenario, if you want a complete dry run, you will have to set up the directories yourself, Gen will then recurse into it and continue the dry run as normal. (Possibly a future release could get past this limitation.)

When you are done with the dry run, and want to do things for real, do the following :

set GenNS::Ftp::DryRun 0


You can turn on debug info like this :

set GenNS::DebugOn 1

This is an internal feature, is not supported, and will likely change in the future. But it is currently available to help you with any issues you may have.

If You Need More Advanced Features

The FTP within Gen is intended to be simple and serve simple use cases. If you find you need something more, there are quite a few file synchronization programs out there. Personally, I have used unison with good success.


You may want to run the tests yourself. In that case, you will want to take a look at test/README-test-ftp.txt or test/README-test-ftp.html for details on how to get set up to do that. Running tests may be a good way to confirm that your set up is fine and there are no issues there.

Error Handling

We try to check every FTP command used for a return code and then throw an error if the call was unsuccessful. Have not, to this point, done extensive testing on failure scenarios where some commands succeed and then others fail in the middle.

Note that you may see something like "Error getting file size!" This is because the code tries to detect remote directories by getting the file size. For directories this fails for the systems tested so far. A more complex solution would seem to be to take the detailed file listing (using ftp::List) and determine what kind of system it is, use a parser for that type, and detect if it is a directory.