Last active
September 24, 2020 02:15
-
-
Save cflove/4bac3a0e0d1ed0f430b92738640b354e to your computer and use it in GitHub Desktop.
ColdFusion custom tag to work with WinSCP / sftp. This use external files and write hostkey and script file in the same dir location of the custom tag template. Change default attributes. This need WinSCP installed in the server.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--- | |
<cf_WinSCP action ="listdir" | |
username ="" | |
password ="" | |
host ="" | |
name ="qryDirectory" | |
directory ="" /> | |
<cf_WinSCP action="exists" | |
username ="" | |
password ="" | |
host ="" | |
item =""/> | |
<cfif val(exists)>File Exists </cfif> | |
<cf_WinSCP action="getFile" | |
username ="" | |
password ="" | |
host ="" | |
localFile ="" | |
remoteFile ="" /> | |
<cf_WinSCP action="rename" | |
overwrite = "true" | |
username ="" | |
password ="" | |
host ="" | |
existing ="" | |
new =""/> | |
<cf_WinSCP action="remove" | |
username ="" | |
password ="" | |
host ="" | |
item ="" /> | |
<cf_WinSCP action ="putFile" | |
username = "" | |
password = "" | |
host = "" | |
localFile = "" | |
remoteDirectory = "" | |
remoteFile = "" /> | |
---> | |
<cfswitch expression="#ThisTag.ExecutionMode#"> | |
<cfcase value="Start"> | |
<cfparam name="attributes.hostkey" default=""> | |
<cfparam name="attributes.WinSCPPath" default="C:\Program Files (x86)\WinSCP\WinSCP.com"> | |
<cfparam name="attributes.timeOut" default="120"> | |
<cfparam name="attributes.chmod" default="644"> | |
<cfparam name="attributes.secure" default="yes"> | |
<cfset tempDir = "#GetDirectoryFromPath(GetCurrentTemplatePath())#WinSCP\"> | |
<cfif not directoryExists(tempDir)> | |
<cfdirectory action = "Create" directory = "#tempDir#" /> | |
</cfif> | |
<!--- ************************************************************************ ---> | |
<!--- check do we have hostkey saved ---> | |
<!--- ************************************************************************ ---> | |
<cfif not len(attributes.hostkey) and booleanFormat(attributes.secure)> | |
<cfif not fileExists("#tempDir##attributes.host#")> | |
<!--- get the host key and save it for later use ---> | |
<cfexecute | |
name = "#attributes.WinSCPPath#" | |
arguments = '/command "open sftp://#attributes.username#:#attributes.password#@#attributes.host#' | |
timeout = "#attributes.timeOut#" | |
variable = "return"> | |
</cfexecute> | |
<cfset s = findNoCase("Host key fingerprint is", return)> | |
<cfif val(s)> | |
<cfset attributes.hostkey = listFirst( removeChars(return, 1,s+23) ,'.')> | |
<cfif len(attributes.hostkey)> | |
<cffile action = "Write" file = "#tempDir##attributes.host#" output = "#trim(attributes.hostkey)#" /> | |
</cfif> | |
</cfif> | |
<cfelse> | |
<cffile action = "read" file = "#tempDir##attributes.host#" variable = "attributes.hostkey" /> | |
</cfif> | |
</cfif> | |
<cfswitch expression = "#attributes.action#"> | |
<!--- ************************************************************************ ---> | |
<!--- get directory listing ---> | |
<!--- ************************************************************************ ---> | |
<cfcase value = "listdir"> | |
<!--- ************************************************************************ ---> | |
<!--- Save the listing script for the first time ---> | |
<!--- ************************************************************************ ---> | |
<cfif not fileExists("#tempDir#listDir.cfm")> | |
<cfset Content = '##<cfabort>#chr(10)#open sftp://%1%:%2%@%3% -hostkey="%5%"#chr(10)#ls "%4%"#chr(10)#exit'> | |
<cffile action = "Write" file = "#tempDir#listDir.cfm" output = "#trim(Content)#" /> | |
</cfif> | |
<cfexecute | |
name = "#attributes.WinSCPPath#" | |
arguments = '/script=#tempDir#listDir.cfm /parameter "#attributes.username#" "#attributes.password#" "#attributes.host#" "#attributes.directory#" "#attributes.hostkey#"' | |
timeout ="#attributes.timeOut#" | |
variable = "return"> | |
</cfexecute> | |
<!--- ************************************************************************ ---> | |
<!--- Get the body ---> | |
<!--- ************************************************************************ ---> | |
<cfset start = findNoCase("Active session:", return)> | |
<cfif not val(start)> | |
<!--- ************************************************************************ ---> | |
<!--- We have an error. show it ---> | |
<!--- ************************************************************************ ---> | |
<cfthrow type="Application" message="#listLast(return,chr(10))#" detail="#return#"> | |
<cfexit method = "exitTag"> | |
</cfif> | |
<cfset start = find(chr(10), return, start)> | |
<cfset body = trim(RemoveChars(return, 1, start))> | |
<cfset body = listToArray(body, chr(10))> | |
<!--- ************************************************************************ ---> | |
<!--- format the body into a query ---> | |
<!--- ************************************************************************ ---> | |
<cfset q = QueryNew('longname,attributes,hardlinks,owner,name,length,lastModified,isdirectory')> | |
<cfloop array = "#body#" index = "i"> | |
<cfset QueryAddRow(q)> | |
<cfset i = trim(i)> | |
<cfset QuerySetCell(q, 'longname', i)> | |
<cfset QuerySetCell(q, 'attributes', listGetAt(i,1,' '))> | |
<cfset QuerySetCell(q, 'hardlinks', listGetAt(i,2,' '))> | |
<cfset QuerySetCell(q, 'owner', listGetAt(i,3,' '))> | |
<cfset QuerySetCell(q, 'name', listlast(i,' '))> | |
<cfset QuerySetCell(q, 'length', listGetAt(i,5,' '))> | |
<cfif left(i,1) eq '-'> | |
<cfset QuerySetCell(q, 'isdirectory', false)> | |
<cfelse> | |
<cfset QuerySetCell(q, 'isdirectory', true)> | |
</cfif> | |
<cfset QuerySetCell(q, 'lastModified', ParseDateTime('#listGetAt(i,6,' ')# #listGetAt(i,7,' ')# #listGetAt(i,9,' ')# #listGetAt(i,8,' ')#'))> | |
</cfloop> | |
<cfset caller[attributes.name] = q> | |
<cfset caller.WinSCP = return> | |
</cfcase> | |
<!--- ************************************************************************ ---> | |
<!--- getFile ---> | |
<!--- ************************************************************************ ---> | |
<cfcase value = "getFile"> | |
<!--- ************************************************************************ ---> | |
<!--- Save the get script for the first time ---> | |
<!--- ************************************************************************ ---> | |
<cfif not fileExists("#tempDir#getFile.cfm")> | |
<cfset Content = '##<cfabort>#chr(10)#option transfer binary#chr(10)#open sftp://%1%:%2%@%3% -hostkey="%4%"#chr(10)#get %5% %6%#chr(10)#exit'> | |
<cffile action = "Write" file = "#tempDir#getFile.cfm" output = "#trim(Content)#" /> | |
</cfif> | |
<cfexecute | |
name = "#attributes.WinSCPPath#" | |
arguments = '/script=#tempDir#getFile.cfm /parameter "#attributes.username#" "#attributes.password#" "#attributes.host#" "#attributes.hostkey#" "#attributes.remoteFile#" "#attributes.localFile#"' | |
timeout ="#attributes.timeOut#" | |
variable = "return"> | |
</cfexecute> | |
<cfset caller.WinSCP = return> | |
</cfcase> | |
<!--- ************************************************************************ ---> | |
<!--- putfile ---> | |
<!--- ************************************************************************ ---> | |
<cfcase value = "putFile"> | |
<cfif structKeyExists(attributes,'remoteFile')> | |
<cfif not right(attributes.remoteDirectory,'1') eq '/'> | |
<cfset attributes.remoteDirectory = attributes.remoteDirectory & '/'> | |
</cfif> | |
<cfset attributes.remoteDirectory = attributes.remoteDirectory & attributes.remoteFile> | |
</cfif> | |
<cfset attributes.localFile = replace(attributes.localFile,'/','\','all')> | |
<!--- ************************************************************************ ---> | |
<!--- Save the get script for the first time ---> | |
<!--- ************************************************************************ ---> | |
<cfif yesNoFormat(attributes.secure)> | |
<cfif not fileExists("#tempDir#putFile.cfm")> | |
<cfset Content = '##<cfabort>#chr(10)#option transfer binary#chr(10)#open sftp://%1%:%2%@%3% -hostkey="%4%"#chr(10)#put %5% %6%#chr(10)#chmod %7% %6%#chr(10)#exit'> | |
<cffile action = "Write" file = "#tempDir#putFile.cfm" output = "#trim(Content)#" /> | |
</cfif> | |
<cfset args = '/script=#tempDir#putFile.cfm /parameter "#attributes.username#" "#attributes.password#" "#attributes.host#" "#attributes.hostkey#" "#attributes.localFile#" "#attributes.remoteDirectory#" "#attributes.chmod#"'> | |
<cfelse> | |
<!--- ************************************************************************ ---> | |
<!--- ftp ---> | |
<!--- ************************************************************************ ---> | |
<cfif not fileExists("#tempDir#putFile_ftp.cfm")> | |
<cfset Content = '##<cfabort>#chr(10)#option transfer binary#chr(10)#open ftp://%1%:%2%@%3% #chr(10)#put %4% %5%#chr(10)#exit'> | |
<cffile action = "Write" file = "#tempDir#putFile_ftp.cfm" output = "#trim(Content)#" /> | |
</cfif> | |
<cfset args = '/script=#tempDir#putFile_ftp.cfm /parameter "#attributes.username#" "#attributes.password#" "#attributes.host#" "#attributes.localFile#" "#attributes.remoteDirectory#"'> | |
</cfif> | |
<cfexecute | |
name = "#attributes.WinSCPPath#" | |
arguments = '#args#' | |
timeout = "#attributes.timeOut#" | |
variable = "return"> | |
</cfexecute> | |
<cfset caller.WinSCP = return> | |
</cfcase> | |
<!--- ************************************************************************ ---> | |
<!--- rename file ---> | |
<!--- ************************************************************************ ---> | |
<cfcase value = "rename"> | |
<cfif not fileExists("#tempDir#rename.cfm")> | |
<cfset Content = '##<cfabort>#chr(10)#open sftp://%1%:%2%@%3% -hostkey="%4%"#chr(10)#mv %5% %6%#chr(10)#exit'> | |
<cffile action = "Write" file = "#tempDir#rename.cfm" output = "#trim(Content)#" /> | |
</cfif> | |
<cfif structKeyExists(attributes,'overwrite') and yesNoFormat(attributes.overwrite)> | |
<cfset attributes.item = attributes.new> | |
<cfset remove(attributes)> | |
</cfif> | |
<cfexecute | |
name = "#attributes.WinSCPPath#" | |
arguments = '/script=#tempDir#rename.cfm /parameter "#attributes.username#" "#attributes.password#" "#attributes.host#" "#attributes.hostkey#" "#attributes.existing#" "#attributes.new#"' | |
timeout ="#attributes.timeOut#" | |
variable = "return"> | |
</cfexecute> | |
<cfset caller.WinSCP = return> | |
</cfcase> | |
<!--- ************************************************************************ ---> | |
<!--- remove file ---> | |
<!--- ************************************************************************ ---> | |
<cfcase value = "remove"> | |
<cfset caller.WinSCP = remove(attributes)> | |
</cfcase> | |
<!--- ************************************************************************ ---> | |
<!--- check file exists ---> | |
<!--- ************************************************************************ ---> | |
<cfcase value = "exists"> | |
<cfset r = exists(attributes)> | |
<cfset caller.exists = r.exists> | |
<cfset caller.WinSCP = r.WinSCP> | |
</cfcase> | |
</cfswitch> | |
<!--- ************************************************************************ ---> | |
<!--- functions we need ---> | |
<!--- ************************************************************************ ---> | |
<cffunction name = "exists" access= "Public" output = "No" returntype= "Any"> | |
<cfargument name= "a" required= "Yes" type= "any" /> | |
<cfif not fileExists("#tempDir#exists.cfm")> | |
<cfset Content = '##<cfabort>#chr(10)#option failonnomatch on#chr(10)#open sftp://%1%:%2%@%3% -hostkey="%4%"#chr(10)#stat %5%#chr(10)#exit'> | |
<cffile action = "Write" file = "#tempDir#exists.cfm" output = "#trim(Content)#" /> | |
</cfif> | |
<cfexecute | |
name = "#attributes.WinSCPPath#" | |
arguments = '/script=#tempDir#exists.cfm /parameter "#attributes.username#" "#attributes.password#" "#attributes.host#" "#attributes.hostkey#" "#attributes.item#"' | |
timeout ="#attributes.timeOut#" | |
variable = "return"> | |
</cfexecute> | |
<cfset r.WinSCP = return> | |
<cfif findNoCase("No such file or directory", return)> | |
<cfset r.exists = 0> | |
<cfelse> | |
<cfset r.exists = 1> | |
</cfif> | |
<cfreturn r> | |
</cffunction> | |
<cffunction name = "remove" access= "Public" output = "No" returntype= "Any"> | |
<cfargument name= "a" required= "Yes" type= "any" /> | |
<cfif val( exists(arguments.a).exists )> <!--- file have to be exists for us to delete it ---> | |
<cfif not fileExists("#tempDir#remove.cfm")> | |
<cfset Content = '##<cfabort>#chr(10)#open sftp://%1%:%2%@%3% -hostkey="%4%"#chr(10)#rm %5%#chr(10)#exit'> | |
<cffile action = "Write" file = "#tempDir#remove.cfm" output = "#trim(Content)#" /> | |
</cfif> | |
<cfexecute | |
name = "#attributes.WinSCPPath#" | |
arguments = '/script=#tempDir#remove.cfm /parameter "#attributes.username#" "#attributes.password#" "#attributes.host#" "#attributes.hostkey#" "#attributes.item#"' | |
timeout ="#attributes.timeOut#" | |
variable = "return"> | |
</cfexecute> | |
<cfreturn return> | |
</cfif> | |
<cfreturn ''> | |
</cffunction> | |
</cfcase> | |
</cfswitch> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment