Function FTP_Services(@Service, @Params) /*********************************************************************************************************************** This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written permission from SRP Computer Solutions, Inc. Name : FTP_Services Description : Handler program for all FTP services. Notes : See the following URLs for a list of FTP/SFTP commands: - http://www.nsftools.com/tips/MSFTP.htm - https://the.earth.li/~sgtatham/putty/0.70/puttydoc.txt Parameters : Service [in] -- Name of the service being requested Param1-10 [in/out] -- Additional request parameter holders Response [out] -- Response to be sent back to the Controller (MCP) or requesting procedure Metadata : History : (Date, Initials, Notes) 07/10/18 dmb Original programmer. 11/13/24 djm Add ListDirectory service. 01/08/24 djm Changed ListDirectory to preserve host error message and set Error_Services. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler $insert LOGICAL $insert SERVICE_SETUP $insert FTP_REQUESTS_EQUATES $insert NOTIFICATION_EQUATES Equ CRLF$ to \0D0A\ Equ Tab$ to Char(9) Declare function FTP_Services, Memory_Services, Logging_Services, SRP_Path, SRP_Decode, RTI_CreateGUID Declare function Environment_Services, Database_Services, Utility, SRP_Run_Command Declare subroutine FTP_Services, Memory_Services, Logging_Services, SRP_Run_Command, GetTempPath, GetTempFileName Declare subroutine Database_Services, RList, Obj_Notes, Shipment_Services LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\FTP' LogDate = Oconv(Date(), 'D4/') LogTime = Oconv(Time(), 'MTS') LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : '.log' Headers = 'Logging DTM' : @FM : 'Activity' : @FM : 'Host' : @FM : 'FTP Request ID or Local/Remote File' : @FM : 'Remote Directory' : @FM : 'Error' ColumnWidths = 20 : @FM : 20 : @FM : 30 : @FM : 75 : @FM : 50 : @FM : 100 objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ' ', Headers, ColumnWidths, False$, False$) LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM GoToService else Error_Services('Add', Service : ' is not a valid service request within the ' : ServiceModule : ' module.') end Return Response OR '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Service Parameter Options //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Options BOOLEAN = True$, False$ Options HOSTS = '10.131.104.18', 'ftp3.vis.com.tw', 'ftp1.towersemi.com', '10.72.176.48', '172.23.28.185', '172.28.150.80' Options COMMANDS = 'put', 'append', 'get' Options SERVERS = 'MESSA005', 'MESSA01EC' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Services //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //---------------------------------------------------------------------------------------------------------------------- // SendFile // // Host - FTP server name or IP. - [Required] // LocalFile - Local file to send to the FTP server. - [Required if EncodedData is empty] // EncodedData - Base64 encoded to send to the FTP server. - [Required if LocalFile is empty] // Username - Username to authenticate against the FTP server. - [Optional] // Password - Password to authenticate against the FTP server. - [Optional] // LocalDirectory - Required working directory of the local computer. Used with the "lcd" FTP command. - [Optional] // RemoteDirectory - Required working directory of the remote computer. Used with the "cd' FTP command. - [Optional] // RemoteFile - Remote file that will be created on the FTP server. - [Optional] // ScriptPath - Local directory and/or file name to use for the script file. - [Optional] // DeleteScript - Boolean flag to indicate if the script file should be deleted after being ran. - [Optional] // SSH - Boolean flag to indicate if SSH (Secure FTP) is required. Default is False. - [Optional] // // Sends the indicated local file or encoded data to the indicated host. //---------------------------------------------------------------------------------------------------------------------- Service SendFile(Host=HOSTS, LocalFile, EncodedData, Username, Password, LocalDirectory, RemoteDirectory, RemoteFile, ScriptPath, DeleteScript=BOOLEAN, SSH=BOOLEAN) LogData = '' LogData<1> = LoggingDTM LogData<2> = 'Start ' : Service LogData<3> = Host LogData<4> = LocalFile LogData<5> = RemoteDirectory Logging_Services('AppendLog', objLog, LogData, @RM, @FM) If (Host NE '') AND ((LocalFile NE '') OR (EncodedData NE '')) then If LocalFile EQ '' then // Data to send to the FTP server is coming in as Base64 string rather than a path to a local file. Decode the // string and create a temp file. LocalFile = FTP_Services('ConvertEncodedData', EncodedData) end ScriptPath = FTP_Services('CreateScript', ScriptPath, Host, LocalFile, Username, Password, LocalDirectory, RemoteDirectory, RemoteFile, 'put', SSH) If Error_Services('NoError') then FTP_Services('RunScript', ScriptPath, Host, Username, Password, LocalFile, RemoteDirectory, DeleteScript, SSH) end If EncodedData NE '' then OSDelete LocalFile end end else Error_Services('Add', 'Host, LocalFile, or EncodedData argument was missing from the ' : Service : ' service.') end ServiceError = Error_Services('GetMessage') LogData<1> = LoggingDTM LogData<2> = 'Stop ' : Service LogData<3> = Host LogData<4> = LocalFile LogData<5> = RemoteDirectory LogData<6> = Error_Services('GetMessage') Logging_Services('AppendLog', objLog, LogData, @RM, @FM) Error_Services('Set', ServiceError) end service //---------------------------------------------------------------------------------------------------------------------- // AppendFile // // Host - FTP server name or IP. - [Required] // LocalFile - Local file to send to the FTP server. - [Required if EncodedData is empty] // EncodedData - Base64 encoded to send to the FTP server. - [Required if LocalFile is empty] // Username - Username to authenticate against the FTP server. - [Optional] // Password - Password to authenticate against the FTP server. - [Optional] // LocalDirectory - Required working directory of the local computer. Used with the "lcd" FTP command. - [Optional] // RemoteDirectory - Required working directory of the remote computer. Used with the "cd' FTP command. - [Optional] // RemoteFile - Remote file that will be appended on the FTP server. - [Optional] // ScriptPath - Local directory and/or file name to use for the script file. - [Optional] // DeleteScript - Boolean flag to indicate if the script file should be deleted after being ran. - [Optional] // SSH - Boolean flag to indicate if SSH (Secure FTP) is required. Default is False. - [Optional] // // Appends the indicated local file or encoded data to the indicated host. //---------------------------------------------------------------------------------------------------------------------- Service AppendFile(Host=HOSTS, LocalFile, EncodedData, Username, Password, LocalDirectory, RemoteDirectory, RemoteFile, ScriptPath, DeleteScript=BOOLEAN, SSH=BOOLEAN) LogData = '' LogData<1> = LoggingDTM LogData<2> = 'Start ' : Service LogData<3> = Host LogData<4> = LocalFile LogData<5> = RemoteDirectory Logging_Services('AppendLog', objLog, LogData, @RM, @FM) If (Host NE '') AND ((LocalFile NE '') OR (EncodedData NE '')) then If LocalFile EQ '' then // Data to send to the FTP server is coming in as Base64 string rather than a path to a local file. Decode the // string and create a temp file. LocalFile = FTP_Services('ConvertEncodedData', EncodedData) end If SSH EQ True$ then // SFTP does not support the append command. To simulate, the file must first be retrieved using the get // command and then appended locally. The resulting file is then sent back using the put command. TempFile = FTP_Services('GetTempFile') If TempFile NE '' then // Use a temp file to hold the file from the host. TempFileName = SRP_Path('GetFilename', TempFile) TempFilePath = SRP_Path('GetDirectory', TempFile) // The name of the remote file is indicated in the append command or it simply defaults to the local file. If RemoteFile NE '' then TempRemoteFile = RemoteFile end else TempRemoteFile = LocalFile end // Perform the get command. This will put any remote file retrieved into the temp file location. FTP_Services('GetFile', Host, TempRemoteFile, TempFileName, Username, Password, TempFilePath, RemoteDirectory, '', True$, SSH) If Error_Services('NoError') then // Read the remote file and the local file data and append. OSRead OrigFile from TempFile else OrigFile = '' OSRead AppendFile from LocalFile else AppendFile = '' OrigFile := AppendFile OSWrite OrigFile to LocalFile // Delete the temp file. OSDelete TempFile // Put the newly appended local file to the host server. ScriptPath = FTP_Services('CreateScript', ScriptPath, Host, LocalFile, Username, Password, LocalDirectory, RemoteDirectory, RemoteFile, 'put', SSH) If Error_Services('NoError') then FTP_Services('RunScript', ScriptPath, Host, Username, Password, LocalFile, RemoteDirectory, DeleteScript, SSH) end end end else Error_Services('Add', 'Error getting a temp file in the ' : Service : ' service.') end end else ScriptPath = FTP_Services('CreateScript', ScriptPath, Host, LocalFile, Username, Password, LocalDirectory, RemoteDirectory, RemoteFile, 'append', SSH) If Error_Services('NoError') then FTP_Services('RunScript', ScriptPath, Host, Username, Password, LocalFile, RemoteDirectory, DeleteScript, SSH) end end If EncodedData NE '' then OSDelete LocalFile end end else Error_Services('Add', 'Host, LocalFile, or EncodedData argument was missing from the ' : Service : ' service.') end ServiceError = Error_Services('GetMessage') LogData<1> = LoggingDTM LogData<2> = 'Stop ' : Service LogData<3> = Host LogData<4> = LocalFile LogData<5> = RemoteDirectory LogData<6> = Error_Services('GetMessage') Logging_Services('AppendLog', objLog, LogData, @RM, @FM) Error_Services('Set', ServiceError) end service //---------------------------------------------------------------------------------------------------------------------- // GetFile // // Host - FTP server name or IP. - [Required] // RemoteFile - Remote file that will be retrieved from the FTP server. - [Required] // LocalFile - Local file to direct the remote file to. - [Optional] // Username - Username to authenticate against the FTP server. - [Optional] // Password - Password to authenticate against the FTP server. - [Optional] // LocalDirectory - Required working directory of the local computer. Used with the "lcd" FTP command. - [Optional] // RemoteDirectory - Required working directory of the remote computer. Used with the "cd' FTP command. - [Optional] // ScriptPath - Local directory and/or file name to use for the script file. - [Optional] // DeleteScript - Boolean flag to indicate if the script file should be deleted after being ran. - [Optional] // SSH - Boolean flag to indicate if SSH (Secure FTP) is required. Default is False. - [Optional] // // Gets the indicated remote file from the indicated host. //---------------------------------------------------------------------------------------------------------------------- Service GetFile(Host=HOSTS, RemoteFile, LocalFile, Username, Password, LocalDirectory, RemoteDirectory, ScriptPath, DeleteScript=BOOLEAN, SSH=BOOLEAN) LogData = '' LogData<1> = LoggingDTM LogData<2> = 'Start ' : Service LogData<3> = Host LogData<4> = LocalFile LogData<5> = RemoteDirectory Logging_Services('AppendLog', objLog, LogData, @RM, @FM) If (Host NE '') AND (RemoteFile NE '') then ScriptPath = FTP_Services('CreateScript', ScriptPath, Host, LocalFile, Username, Password, LocalDirectory, RemoteDirectory, RemoteFile, 'get', SSH) If Error_Services('NoError') then FTP_Services('RunScript', ScriptPath, Host, Username, Password, LocalFile, RemoteDirectory, DeleteScript, SSH) end end else Error_Services('Add', 'Host or RemoteFile argument was missing from the ' : Service : ' service.') end ServiceError = Error_Services('GetMessage') LogData<1> = LoggingDTM LogData<2> = 'Stop ' : Service LogData<3> = Host LogData<4> = LocalFile LogData<5> = RemoteDirectory LogData<6> = Error_Services('GetMessage') Logging_Services('AppendLog', objLog, LogData, @RM, @FM) Error_Services('Set', ServiceError) end service //---------------------------------------------------------------------------------------------------------------------- // DeleteFile // // Host - FTP server name or IP. - [Required] // RemoteFile - Remote file that will be retrieved from the FTP server. - [Required] // Username - Username to authenticate against the FTP server. - [Optional] // Password - Password to authenticate against the FTP server. - [Optional] // RemoteDirectory - Required working directory of the remote computer. Used with the "cd' FTP command. - [Optional] // ScriptPath - Local directory and/or file name to use for the script file. - [Optional] // DeleteScript - Boolean flag to indicate if the script file should be deleted after being ran. - [Optional] // SSH - Boolean flag to indicate if SSH (Secure FTP) is required. Default is False. - [Optional] // // Deletes the indicated remote file from the indicated host. //---------------------------------------------------------------------------------------------------------------------- Service DeleteFile(Host=HOSTS, RemoteFile, Username, Password, RemoteDirectory, ScriptPath, DeleteScript=BOOLEAN, SSH=BOOLEAN) LogData = '' LogData<1> = LoggingDTM LogData<2> = 'Start ' : Service LogData<3> = Host LogData<4> = RemoteFile LogData<5> = RemoteDirectory Logging_Services('AppendLog', objLog, LogData, @RM, @FM) If (Host NE '') AND (RemoteFile NE '') then ScriptPath = FTP_Services('CreateScript', ScriptPath, Host, '', Username, Password, '', RemoteDirectory, RemoteFile, 'delete', SSH) If Error_Services('NoError') then FTP_Services('RunScript', ScriptPath, Host, Username, Password, LocalFile, RemoteDirectory, DeleteScript, SSH) end end else Error_Services('Add', 'Host or RemoteFile argument was missing from the ' : Service : ' service.') end ServiceError = Error_Services('GetMessage') LogData<1> = LoggingDTM LogData<2> = 'Stop ' : Service LogData<3> = Host LogData<4> = RemoteFile LogData<5> = RemoteDirectory LogData<6> = Error_Services('GetMessage') Logging_Services('AppendLog', objLog, LogData, @RM, @FM) Error_Services('Set', ServiceError) end service //---------------------------------------------------------------------------------------------------------------------- // RunScript // // ScriptPath - Local directory and/or file name to use for the script file. - [Required] // Host - FTP server name or IP. Used only for error reporting. - [Optional] // Username - Username to authenticate against the FTP server. - [Optional] // Password - Password to authenticate against the FTP server. - [Optional] // LocalFile - Local file to direct the remote file to. Used only for error reporting. - [Optional] // RemoteDirectory - Required working directory of the remote computer. Used with the "cd' FTP command. Used only for // error reporting. - [Optional] // DeleteScript - Boolean flag to indicate if the script file should be deleted after being ran. Used only for error // reporting. - [Optional] // SSH - Boolean flag to indicate if SSH (Secure FTP) is required. Default is False. - [Optional] // // Runs the indicated FTP script. //---------------------------------------------------------------------------------------------------------------------- Service RunScript(ScriptPath, Host, Username, Password, LocalFile, RemoteDirectory, DeleteScript, SSH) If ScriptPath NE '' then Output = 'VAR' ; // Use when running in production. * Output = 'DOSOPEN' ; // Use only for debugging the console. If SSH EQ True$ then Command = 'psftp' If Username NE '' then If Host NE '' then Command := ' ' : Username : '@' : Host end else If Host NE '' then Command := ' ' : Host end If Password NE '' then Command := ' -pw ' : Password end Command := ' -b ' : ScriptPath end else Command = 'ftp -i -n -s:' : ScriptPath end SRP_Run_Command(Command, Output, '', '') If DeleteScript EQ True$ then OSDelete ScriptPath end If Output NE 'DOSOPEN' then Swap \0D0A\ with @FM in Output Begin Case Case IndexC(Output, 'Connection timed out', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. Connection timed out: ' : Quote(Host) : '.') Case IndexC(Output, 'Connection refused', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. Connection refused at host: ' : Quote(Host) : '.') Case IndexC(Output, 'Server unexpectedly closed network connection', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. Connection refused at host: ' : Quote(Host) : '.') Case IndexC(Output, 'File not found', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. Local file not found: ' : Quote(LocalFile) : '.') Case IndexC(Output, 'User cannot log in', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. Username or password invalid.') Case IndexC(Output, 'The system cannot find the file specified', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. Remote file cannot be found: ' : Quote(RemoteDirectory) : '.') Case IndexC(Output, 'No such file or folder', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. Remote file cannot be found: ' : Quote(RemoteDirectory) : '.') Case IndexC(Output, 'open for read: failure', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. Remote file cannot be found: ' : Quote(RemoteDirectory) : '.') Case IndexC(Output, 'unrecognised option', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. Unrecognised option.') Case IndexC(Output, 'The parameter is incorrect', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. A parameter is incorrect.') Case IndexC(Output, 'failure', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. Unknown failure.') Case IndexC(Output, 'unable to open', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. Local file not found: ' : Quote(LocalFile) : '.') Case IndexC(Output, 'FATAL ERROR', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. FATAL ERROR: ' : Quote(LocalFile) : '.') Case IndexC(Output, 'Access Denied', 1) ; Error_Services('Add', 'Error in ' : Service : ' service. FATAL ERROR: ' : Quote(LocalFile) : '.') End Case end end else Error_Services('Add', 'ScriptPath argument was missing from the ' : Service : ' service.') end end service //---------------------------------------------------------------------------------------------------------------------- // CreateScript // // ScriptPath - Local directory and/or file name to use for the script file. - [Optional] // Host - FTP server name or IP. - [Optional] // LocalFile - Local file to send to the FTP server. - [Optional] // Username - Username to authenticate against the FTP server. - [Optional] // Password - Password to authenticate against the FTP server. - [Optional] // LocalDirectory - Required working directory of the local computer. Used with the "lcd" FTP command. - [Optional] // RemoteDirectory - Required working directory of the remote computer. Used with the "cd' FTP command. - [Optional] // RemoteFile - Remote file that will be created on the FTP server. - [Optional] // Command - FTP file command. - [Optional] // SSH - Boolean flag to indicate if SSH (Secure FTP) is required. Default is False. - [Optional] // // Creates a script file based on the indicated arguments. This will be writen to the resulting script path. //---------------------------------------------------------------------------------------------------------------------- Service CreateScript(ScriptPath, Host, LocalFile, Username, Password, LocalDirectory, RemoteDirectory, RemoteFile, Command=COMMANDS, SSH) // First, create the script list of commands based on the indicated arguments. Script = '' If SSH EQ True$ then // PSFTP requires credentials to be entered in the command line rather than in the script. end else If Host NE '' then Script := 'open ' : Host : @FM If Username NE '' then Script := 'user' : @FM Script := Username : @FM end If Password NE '' then Script := Password : @FM end end If LocalDirectory NE '' then Script := 'lcd ' : LocalDirectory : @FM end If RemoteDirectory NE '' then Script := 'cd ' : RemoteDirectory : @FM end Begin Case Case Command _EQC 'put' OR Command _EQC 'append' If SSH EQ True$ then Script := 'put' If Command _EQC 'append' then Script := ' -append' end Script := ' ' : LocalFile end else Script := command : ' ' : LocalFile end If RemoteFile NE '' then Script := ' ' : RemoteFile end Case Command _EQC 'get' Script := command : ' ' : RemoteFile If LocalFile NE '' then Script := ' ' : LocalFile end Case Command _EQC 'delete' If SSH EQ True$ then Script := 'del ' : RemoteFile end else Script := command : ' ' : RemoteFile end Case Command _EQC 'list' Script := 'ls ' If RemoteFile NE '' then Script := ' ' : RemoteFile end End Case Script := @FM Script := 'quit' Swap @FM with CRLF$ in Script // Second, validate the script path. Use the specific directory and/or filename provided in the ScriptPath argument // if possible. Otherwise use temp names. ScriptDirectory = '' ScriptFile = '' If ScriptPath NE '' then If SRP_Path('IsDirectory', ScriptPath) then // Directory is valid, which means no filename. ScriptDirectory = ScriptPath end else // Check to see if there is a directory with a filename. ScriptDirectory = SRP_Path('GetDirectory', ScriptPath) If SRP_Path('IsDirectory', ScriptDirectory) then ScriptFile = SRP_Path('GetFilename', ScriptPath) end else ScriptDirectory = '' ScriptFile = ScriptPath end end end If ScriptDirectory EQ '' then ScriptDirectory = Str(\00\, 1024) GetTempPath(Len(ScriptDirectory), ScriptDirectory) Convert \00\ to '' in ScriptDirectory end If ScriptFile EQ '' then ScriptFile = Str(\00\, 1024) GetTempFileName(ScriptDirectory : \00\, \00\, 0, ScriptFile) OSDelete ScriptFile ScriptPath = SRP_Path('RenameExtension', ScriptFile, 'scr') end else ScriptPath = SRP_Path('Combine', ScriptDirectory, ScriptFile) end // Finally, create the script file in the indicated ScriptPath. Status() = 0 OSWrite Script to ScriptPath If Status() then Error_Services('Add', 'Error creating ' : ScriptPath : ' in the ' : Service : ' service. Description: ' : Field('Bad OS filename.,Access denied by operating system.,Disk or directory full.,File does not exist.,Unknown error.,Attempt to write to a read-only file.', ',', Status())) end Response = ScriptPath end service //---------------------------------------------------------------------------------------------------------------------- // ConvertEncodedData // // EncodedData - Base64 encoded data. - [Required] // // Converts Base64 encoded data to plaint text and writes to a temporary file. //---------------------------------------------------------------------------------------------------------------------- Service ConvertEncodedData(EncodedData) LocalFile = '' If EncodedData NE '' then Data = SRP_Decode(EncodedData, 'BASE64') If Data NE '' then LocalFile = FTP_Services('GetTempFile') If LocalFile NE '' then OSWrite Data to LocalFile If Status() then Error_Services('Add', 'Error creating ' : LocalFile : ' in the ' : Service : ' service. Description: ' : Field('Bad OS filename.,Access denied by operating system.,Disk or directory full.,File does not exist.,Unknown error.,Attempt to write to a read-only file.', ',', Status())) end end else Error_Services('Add', 'Error getting a temp file in the ' : Service : ' service.') end end else Error_Services('Add', 'Error decoding the EncodedData argument in the ' : Service : ' service.') end end else Error_Services('Add', 'EncodedData argument was missing from the ' : Service : ' service.') end Response = LocalFile end service //---------------------------------------------------------------------------------------------------------------------- // GetTempFile // // Returns the path to a newly created temporary file. //---------------------------------------------------------------------------------------------------------------------- Service GetTempFile() TempFile = '' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempFile = Str(\00\, 1024) GetTempFileName(TempDirectory : \00\, \00\, 0, TempFile) Response = TempFile end service //---------------------------------------------------------------------------------------------------------------------- // PostRequest // // Command - FTP file command. - [Required] // Host - FTP server name or IP. - [Required] // Server - Name of the local server responsible for processing this FTP request. - [Required] // LocalFile - Local file to send to the FTP server. - [Required if EncodedData is empty] // EncodedData - Base64 encoded to send to the FTP server. - [Required if LocalFile is empty] // Username - Username to authenticate against the FTP server. - [Optional] // Password - Password to authenticate against the FTP server. - [Optional] // LocalDirectory - Required working directory of the local computer. Used with the "lcd" FTP command. - [Optional] // RemoteDirectory - Required working directory of the remote computer. Used with the "cd' FTP command. - [Optional] // RemoteFile - Remote file that will be created on the FTP server. - [Optional] // ScriptPath - Local directory and/or file name to use for the script file. - [Optional] // DeleteScript - Boolean flag to indicate if the script file should be deleted after being ran. - [Optional] // SSH - Boolean flag to indicate if SSH (Secure FTP) is required. Default is False. - [Optional] // ProcessDirectory - Local direcotry to move the local file into after it has been sent to the FTP server. - [Optional] // NumberAttempts - Number of attempts that should be made to process this request before quitting. Default is 1. // - [Optional] // DeleteLocalFile - Boolean flag to indicate if the local file should be deleted after the request has been processed. // Default is False. - [Optional] // // Posts the FTP request into the FTP_REQUESTS database table for future processing. //---------------------------------------------------------------------------------------------------------------------- Service PostRequest(Command=COMMANDS, Host=HOSTS, Server=SERVERS, LocalFile, EncodedData, Username, Password, LocalDirectory, RemoteDirectory, RemoteFile, ScriptPath, DeleteScript=BOOLEAN, SSH=BOOLEAN, ProcessDirectory, NumberAttempts, DeleteLocalFile) LogData = '' LogData<1> = LoggingDTM LogData<2> = 'Start ' : Service LogData<3> = Host LogData<4> = Command : ' ' : LocalFile LogData<5> = RemoteDirectory Logging_Services('AppendLog', objLog, LogData, @RM, @FM) FTPRequestID = '' If (Command NE '') AND (Host NE '') AND (Server NE '') AND ((LocalFile NE '') OR (EncodedData NE '')) then RequestDate = Date() RequestTime = Time() FTPRequestID = RequestDate : '-' : RequestTime : '-' SeqCounter = 1 ; // Start the counter always at 1 Loop HaveLock = Database_Services('GetKeyIDLock', 'FTP_REQUESTS', FTPRequestID : SeqCounter, False$) If HaveLock EQ True$ then FTPRequest = Database_Services('ReadDataRow', 'FTP_REQUESTS', FTPRequestID : SeqCounter) If Error_Services('NoError') then // FTP request already exists. Unlock the Key ID and attempt the next sequential counter. Database_Services('ReleaseKeyIDLock', 'FTP_REQUESTS', FTPRequestID : SeqCounter) HaveLock = False$ end else // Clear the error as this means the FTP request does not exist. Error_Services('Clear') end end Until HaveLock OR Error_Services('HasError') SeqCounter += 1 Repeat If Error_Services('NoError') then FTPRequestID := SeqCounter FTPRequestRow = '' FTPRequestRow = RequestDate FTPRequestRow = RequestTime FTPRequestRow = Command FTPRequestRow = Host FTPRequestRow = LocalFile FTPRequestRow = EncodedData FTPRequestRow = Username FTPRequestRow = Password FTPRequestRow = LocalDirectory FTPRequestRow = RemoteDirectory FTPRequestRow = RemoteFile FTPRequestRow = ScriptPath FTPRequestRow = DeleteScript FTPRequestRow = SSH FTPRequestRow = ProcessDirectory FTPRequestRow = Server If NumberAttempts LE 0 then NumberAttempts = 1 FTPRequestRow = NumberAttempts If DeleteLocalFile NE True$ then DeleteLocalFile = False$ FTPRequestRow = DeleteLocalFile Database_Services('WriteDataRow', 'FTP_REQUESTS', FTPRequestID, FTPRequestRow, True$, False$, True$) If Error_Services('NoError') then Database_Services('ReleaseKeyIDLock', 'FTP_REQUESTS', FTPRequestID) end end end else Error_Services('Add', 'Command, Host, Server, LocalFile, or EncodedData argument was missing from the ' : Service : ' service.') end ServiceError = Error_Services('GetMessage') LogData<1> = LoggingDTM LogData<2> = 'Stop ' : Service LogData<3> = Host LogData<4> = Command : ' ' : LocalFile : ' : ' : FTPRequestID LogData<5> = RemoteDirectory LogData<6> = Error_Services('GetMessage') Logging_Services('AppendLog', objLog, LogData, @RM, @FM) Error_Services('Set', ServiceError) Response = FTPRequestID end service //---------------------------------------------------------------------------------------------------------------------- // ProcessRequest // // FTPRequestID - Key ID to the FTP_REQUESTS database table. - [Required] // // Processes the FTP request specified by the FTPRequestID. //---------------------------------------------------------------------------------------------------------------------- Service ProcessRequest(FTPRequestID) If (FTPRequestID NE '') then FTPRequestRow = Database_Services('ReadDataRow', 'FTP_REQUESTS', FTPRequestID) If Error_Services('NoError') then Server = FTPRequestRow * If Server EQ 'MESSA01EC' THEN Debug ThisServer = Environment_Services('GetServer') If Server _EQC ThisServer then // This is the designated server to process this request. LogData = '' LogData<1> = LoggingDTM LogData<2> = 'Start ' : Service LogData<3> = '' LogData<4> = FTPRequestID LogData<5> = '' Logging_Services('AppendLog', objLog, LogData, @RM, @FM) RequestDate = FTPRequestRow RequestTime = FTPRequestRow Command = FTPRequestRow Host = FTPRequestRow LocalFile = FTPRequestRow EncodedData = FTPRequestRow Username = FTPRequestRow Password = FTPRequestRow LocalDirectory = FTPRequestRow RemoteDirectory = FTPRequestRow RemoteFile = FTPRequestRow ScriptPath = FTPRequestRow DeleteScript = FTPRequestRow SSH = FTPRequestRow ProcessDirectory = FTPRequestRow DeleteLocalFile = FTPRequestRow Begin Case Case Command _EQC 'put' FTP_Services('SendFile', Host, LocalFile, EncodedData, Username, Password, LocalDirectory, RemoteDirectory, RemoteFile, ScriptPath, DeleteScript, SSH) Case Command _EQC 'append' FTP_Services('AppendFile', Host, LocalFile, EncodedData, Username, Password, LocalDirectory, RemoteDirectory, RemoteFile, ScriptPath, DeleteScript, SSH) Case Command _EQC 'get' FTP_Services('GetFile', Host, RemoteFile, LocalFile, Username, Password, LocalDirectory, RemoteDirectory, ScriptPath, DeleteScript, SSH) Case Command _EQC 'delete' FTP_Services('DeleteFile', Host, RemoteFile, Username, Password, RemoteDirectory, ScriptPath, DeleteScript, SSH) End Case If Error_Services('NoError') then Result = 'Success' Shipment_Services('ClearMONACritical', 'FILE_TRANSMISSION') If (ProcessDirectory NE '') AND (LocalFile NE '') then // Move the local file to the process directory. ProcessFile = SRP_Path('Combine', ProcessDirectory, SRP_Path('GetFilename', LocalFile)) // Work around for the Combine service. This has been fixed, but not yet installed at Infineon. If ProcessFile[1, 1] EQ '\' And ProcessFile[1, 2] NE '\' then ProcessFile = '\' : ProcessFile Success = Utility('COPYFILE', LocalFile, ProcessFile) If (Success EQ True$) AND (DeleteLocalFile EQ True$) then OSDelete LocalFile end end else If DeleteLocalFile EQ True$ then OSDelete LocalFile end end end else Result = Error_Services('GetMessage') Shipment_Services('SetMONACritical', 'FILE_TRANSMISSION', Result) Recipients = XLATE('NOTIFICATION','COC_DELIVERY',NOTIFICATION_USER_ID$,'X') SendFrom = 'System' Subject = 'COC FTP Delivery Failue.' AttachWindow = '' AttachKey = '' SendToGroup = '' MessageParms = Recipients:@RM:SendFrom:@RM:Subject:@RM:Result:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup obj_Notes('Create',MessageParms) end // Update the FTP request with the latest attempt details. AttemptCount = FTPRequestRow AttemptCount += 1 FTPRequestRow = AttemptCount FTPRequestRow = Date() FTPRequestRow = Time() FTPRequestRow = Result Database_Services('WriteDataRow', 'FTP_REQUESTS', FTPRequestID, FTPRequestRow, True$, False$, True$) LogData<1> = LoggingDTM LogData<2> = 'Stop ' : Service LogData<3> = '' LogData<4> = FTPRequestID LogData<5> = '' LogData<6> = Result Logging_Services('AppendLog', objLog, LogData, @RM, @FM) Error_Services('Set', ServiceError) end end end else Error_Services('Add', 'FTPRequestID argument was missing from the ' : Service : ' service.') end end service //---------------------------------------------------------------------------------------------------------------------- // ProcessRequests // // Processeses the pending FTP requests. //---------------------------------------------------------------------------------------------------------------------- Service ProcessRequests() hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') Lock hSysLists, ServiceKeyID then rv = Set_Status(0) RowCount = 0 // 11/02/18 - djs // Use new select statement when deploying new OBJ_SAP build, which uses FTP_SERVICES // to ensure that we process the FTP requests in chronological order. SelectStatement = 'SELECT FTP_REQUESTS WITH STATUS EQ "Pending" BY REQUEST_ID' *SelectStatement = 'SELECT FTP_REQUESTS WITH STATUS EQ "Pending"' RList(SelectStatement, 5) If (@List_Active EQ 3) AND (@RecCount GT 0) then EOF = False$ Loop ReadNext FTPRequestID else EOF = True$ Until EOF EQ True$ FTP_Services('ProcessRequest', FTPRequestID) Repeat end ClearSelect 0 Unlock hSysLists, ServiceKeyID else Null end end service //---------------------------------------------------------------------------------------------------------------------- // ListDirectory // // Host - FTP server name or IP. - [Required] // Query - Specify wildcard query. - [Optional] // Username - Username to authenticate against the FTP server. - [Optional] // Password - Password to authenticate against the FTP server. - [Optional] // RemoteDirectory - Required working directory of the remote computer. Used with the "cd' FTP command. - [Optional] // ScriptPath - Local directory and/or file name to use for the script file. - [Optional] // DeleteScript - Boolean flag to indicate if the script file should be deleted after being ran. - [Optional] // SSH - Boolean flag to indicate if SSH (Secure FTP) is required. Default is False. - [Optional] // OutputPath - Path to output file list to file. - [Optional] // // Gets the indicated remote file from the indicated host. Functions as 'mls' command. //---------------------------------------------------------------------------------------------------------------------- Service ListDirectory(Host=HOSTS, Username, Password, RemoteDirectory, Query, ScriptPath, DeleteScript=BOOLEAN, SSH=BOOLEAN, OutputPath) LogData = '' LogData<1> = LoggingDTM LogData<2> = 'Start ' : Service LogData<3> = Host LogData<4> = '' LogData<5> = RemoteDirectory Logging_Services('AppendLog', objLog, LogData, @RM, @FM) If (Host NE '') AND (RemoteDirectory NE '') then ScriptPath = FTP_Services('CreateScript', ScriptPath, Host, '', Username, Password, '', RemoteDirectory, Query, 'list', SSH) If Error_Services('NoError') then If SSH EQ True$ then Command = 'psftp' If Username NE '' then If Host NE '' then Command := ' ' : Username : '@' : Host end else If Host NE '' then Command := ' ' : Host end If Password NE '' then Command := ' -pw ' : Password end Command := ' -b ' : ScriptPath end else Command = 'ftp -i -n -s:' : ScriptPath end DirectoryList = SRP_Run_Command(Command, 'VAR') If Count(DirectoryList, 'ftpadmin') NE 0 then Gosub LsToMls end else Error_Services('Add', DirectoryList) end Response = DirectoryList If OutputPath NE '' then OutputDirectoryList = DirectoryList Swap @FM with CRLF$ in OutputDirectoryList OSWrite OutputDirectoryList to OutputPath end end end else Error_Services('Add', 'Host or RemoteFile argument was missing from the ' : Service : ' service.') end If DeleteScript EQ True$ then OSDelete ScriptPath end ServiceError = Error_Services('GetMessage') LogData<1> = LoggingDTM LogData<2> = 'Stop ' : Service LogData<3> = Host LogData<4> = '' LogData<5> = RemoteDirectory LogData<6> = Error_Services('GetMessage') Logging_Services('AppendLog', objLog, LogData, @RM, @FM) Error_Services('Set', ServiceError) end service //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //---------------------------------------------------------------------------------------------------------------------- // LsToMls // // Parse output of ls command to remove directory paths and other unneccessary metadata. Functions as mls command. //---------------------------------------------------------------------------------------------------------------------- LsToMls: OldDirectoryList = DirectoryList DirectoryList = '' // Skip the first period because it is related to username. FileCount = Count(OldDirectoryList, '.') - 1 // Index starts at 5 because that CRLF$ Field is the first containing a file name. FieldIndex = 5 For FileIndex = 1 to FileCount FileName = Field(OldDirectoryList, CRLF$, FieldIndex) SpaceCount = DCount(FileName, ' ') FileName = Field(FileName, ' ', SpaceCount) DirectoryList<-1> = FileName FieldIndex += 1 Next FileIndex return