Regarding:
How is it complicated?
For me, the complicated part is sub-sub-sub-subdirectories and getting back along the same path you came in on without missing anything. If this were my task, that's what I would see as the biggest challenge.
The thing is, with recursion, one doesn't need to worry about any level of the hierarchy other than the "current" one, and then making the recursive call at the right point. The act of recursing sorts out the rest of it automatically.
One trap I have seen people getting bogged down with when attempted something recursive is that they try to hold the entire "end result" in their heads (like traversing the sub-sub-sub-dirs), whereas there's simply no need. One only ever has to focus on getting one tier of that right, and then call the function itself again to process the next tier. All the nesting is handled / processed automatically by the recursion. I guess the trick is to be able to be clear in one's head what needs to be passed into the function - from any arbitrary point - to be fully capable of processing a single tier, and how to take that info and process it in such a way as to derive the information necessary for the next tier.
I guess with this requirement one needs to pass in the base file system dir, as well as the base FTP dir. Subsequent recursive "base" dirs can be contrived simply by appending a subdir's name onto the current base dirs and passing the result into the recursive function call.
To save needing to use recursion, one could use the <cfdirectory> tag's inbuilt recursive functionality, then doing a flat iteration over that recordset, using the paths from each record to contrive the FTP subdir. Then either creating the remote dir (if the current records is a dir), or FTPing the file (if it's a file).
Not really the one-fell-swoop BKBK is promising, but surely... not that complicated (although I hesitate to suggest such notions now).
--
Adam