CarterA/Tribo — pull request #33 by CarterA (2012-03-07 05:11:22+00:00)
Title: Publishing via SFTP or FTP

This branch implements publishing via SFTP and FTP. The two protocols are implemented in separate classes (although each are subclasses of the abstract base class `TBPublisher`).

SFTP support is provided by Rsync, forked out via an `NSTask`. Quite a bit of complexity is required here, as Rsync authentication is done through SSH, and SSH command line authentication must be done through a separate process. This necessitated the creation of a separate tool, the aptly-named Tribo Authentication Tool, which handles all of those requirements. Overall, using Rsync is not optimal, but it is *fast*. Not only is the initial upload quite fast, but re-publishing after a minor change is practically instant. This speed is a product of the Rsync algorithm, and it is the biggest reason why I'd like to stick with Rsync until we can implement the same algorithm natively.

FTP support is provided by libcurl and [CurlHandle](https://github.com/CarterA/CurlHandle). This is the best FTP implementation I was able to come up with, and believe me, I tried a several:

- ConnectionKit would likely work, but it is massive and I really don't want such a huge dependency with so many unnecessary files.
- CFNetwork has barebones FTP API calls, but they don't allow sending custom commands. It almost worked, but because it doesn't have built-in support for permission modification (the "SITE CHMOD" FTP command), it couldn't fulfill all our needs.
- ACConnect, while it is a well-done wrapper around CFNetwork, inherits the same problem that I listed for pure CFNetwork usage.

Using libcurl seems like it'll work out quite well. Curl is battle-tested, and as an added bonus, it is included as a .dylib in OS X and iOS, meaning we don't have to include all the code. Oh, and see how I listed iOS there? Yeah, iOS is supported by Curl as well, meaning we can use the FTP publisher in the theoretical iOS app someday. I can't say the same for Rsync, sadly.

I'd appreciate a bit of code review on this, but there is *a lot* of new code, so I don't expect anyone to read all of it.