Skip to content

Instantly share code, notes, and snippets.

@ianosullivan
Last active June 14, 2018 16:21
Show Gist options
  • Save ianosullivan/10475307 to your computer and use it in GitHub Desktop.
Save ianosullivan/10475307 to your computer and use it in GitHub Desktop.
Coldfusion SFTP folder and all its contents (recursively)
cfftp tag in Coldfusion will only put 1 file at a time. Use this component to SFTP a folder and all it's contents including subdirectories and subdirectory contents!!
NOTE: For SFTP you need to get the SSH server fingerprint to be able to connect. I got the fingerprint using Bitvise Tunnelier.
<cfcomponent>
<cffunction name="SFTPFolder" description="Create an SFTP Connection and then call function to SFTP the FOLDER and all it's contents to a remote location. Remote sub folders are created if necessary"
hint="This is only for SFTP" returntype="boolean">
<cfargument name="username" required="true" type="string">
<cfargument name="password" required="true" type="string">
<cfargument name="server" required="true" type="string">
<cfargument name="fingerprint" required="true" type="string">
<cfargument name="timeout" required="true" type="numeric" default="300">
<cfargument name="local_path" required="true" type="string" default="">
<cfargument name="remote_path" required="true" type="string" default="">
<cfargument name="create_remote_folder" required="true" type="string" default="">
<!--- Open an SFTP connection --->
<cfftp action = "open"
connection = "MyConnection"
username = "#username#"
password = "#password#"
fingerprint = "#fingerprint#"
server = "#server#"
timeout = "#timeout#"
secure = "yes"
stopOnError = "No">
<!--- If an SFTP connection has been made --->
<cfif cfftp.Succeeded EQ "YES">
<!--- SFTP folder contents --->
<cfset application.cfcs.sftp.SFTPFolderContents(
local_path = "#local_path#",
remote_path = "#remote_path#",
create_remote_folder = "#create_remote_folder#"
)>
<cfreturn true>
<cfelse>
<cfreturn false>
</cfif>
</cffunction>
<cffunction name="SFTPFolderContents" description="SFTP a FOLDER and all it's contents to a remote location. Remote folders are created if necessary" hint="This is only for SFTP">
<cfargument name="local_path" required="true" type="string" default="">
<cfargument name="remote_path" required="true" type="string" default="">
<cfargument name="create_remote_folder" required="true" type="string" default="">
<!--- Add slash to end of local path if necessary --->
<cfif Right(local_path, 1) NEQ "\">
<cfset local_path = local_path & "\">
</cfif>
<!--- Add slash to end of remote path if necessary --->
<cfif Right(remote_path, 1) NEQ "/">
<cfset remote_path = remote_path & "/">
</cfif>
<!--- Get the local directory contents --->
<cfdirectory directory="#local_path#" name="local_dir_contents" action="list">
<!--- Check if create_remote_folder exists --->
<cfftp action="existsDir"
connection="MyConnection"
directory="#remote_path##create_remote_folder#"
stopOnError = "No">
<!--- If it doesn't exist create it --->
<cfif cfftp.succeeded NEQ "YES">
<!--- Create directory --->
<cfftp action="createDir"
connection="MyConnection"
directory="#remote_path##create_remote_folder#"
stopOnError = "No">
</cfif>
<!--- Loop through contents and put the file on the SFTP server --->
<cfloop query="local_dir_contents">
<cfif local_dir_contents.type EQ "File">
<!--- Put the file on the server --->
<cfftp action="putFile"
connection="MyConnection"
localFile="#local_path##local_dir_contents.name#"
remoteFile="#remote_path##create_remote_folder#/#local_dir_contents.name#">
<cfelse>
<!--- Recursively call THIS function with the new directory --->
<!--- Recursively call THIS function with the new directory --->
<cfset SFTPFolderContents(
local_path = "#local_path#\#local_dir_contents.name#\",
remote_path = "#remote_path#/#create_remote_folder#",
create_remote_folder = "/#local_dir_contents.name#"
)>
<!--- Recursively call THIS function with the new directory --->
<!--- Recursively call THIS function with the new directory --->
</cfif>
</cfloop>
</cffunction>
</cfcomponent>
<cfset success = application.cfcs.sftp.SFTPFolder(
username = "************",
password = "************",
fingerprint = "**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**",
server = "********",
local_path = "C:\Users\ian.osullivan\Desktop\temp\",
remote_path = "/cygdrive/d/Domains/_temp/",
create_remote_folder = "remote_folder_123456789"
)>
<cfdump var="#success#">
@bsorge
Copy link

bsorge commented Oct 7, 2015

Hi Ian,
I am trying to use this CFC (well written BTW), and the issue that I am having is that it will upload the first file, then create the directory (which is the second item in the CFDIrectory result list), add all the appropriate files to that folder, and then it jumps out of the folder, but it's keeping the name of the last HTML file that was uploaded into the previous folder and trying to FTP that, and of course errors out. I am assuming that once a subfolders contents are FTP'd, then it's supposed to jump out of that folder, and if it encounters another sub-folder, create that one, upload the files, etc... Has anyone else encountered this? The only change I made to the CFC was line 30. I changed <cfset application.cfcs.sftp.SFTPFolderContents( to <cfset SFTPFolderContents( because I was receiving the error. Element CFCS.SFTP is undefined in a Java object of type class [Ljava.lang.String; referenced as ''. Thanks, Bruce

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment