• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2610
  • Last Modified:

VB INET FTP (JCL) to Mainframe --- how is it done?

I am successfully using VB inet icFTP protocol to put and get files from a PC and an IBM mainframe host (OS/390 tcp/ip communications server).  

However, there doesn't seem to be a way to send commands like "quote site filetype=jes" to the mainframe.  This is a requirement in order to have the file sent interpreted as a JCL jobstream.  This is my aim.

An interesting thing is that the "quote site filetype=jes" command, the "ascii" command and numerous other commands are accepted via an ftp session initiated in a DOS shell on my PC.  It also works on UNIX.

How is this done in VB?  Are there examples?  I realize that I may not be able to use INET.  I noticed the VERY SAME question heading in experts exchange, but the question/answer itself has been removed. Help@!

Thanks
0
jlhuber
Asked:
jlhuber
  • 3
  • 3
1 Solution
 
jlhuberAuthor Commented:
VB 6.0
0
 
Dang123Commented:
I am doing something similar at work. You are on the right track using "quote site".  Sorry to tell you though, all my stuff that would help answer you is at work. If this question is still open Monday, I'll see if I have anything that will help you.  

Could you post the code you are having trouble with?
0
 
jlhuberAuthor Commented:
Dan123,

Here is an example:

1. This is a sample of the code that is failing.  It hangs at the 1st Execute.  If the failing execute was simply a "put input ouput" it would have worked.

Private Sub cmdCL_Click()
Dim strData As String
On Error GoTo ftperr
MsgBox "FTP Started ", vbOKOnly

'go get the info needed to login
Inet1.RemoteHost = UCase(Text1.Text)
Inet1.UserName = UCase(Text2.Text)
Inet1.Password = UCase(Text3.Text)
Inet1.URL = "ftp://" & Inet1.UserName & ":" & Inet1.Password & "@" & Inet1.RemoteHost

Inet1.Execute Inet1.URL, "QUOTE SITE FILETYPE=JES"
Do While Inet1.StillExecuting
          DoEvents
Loop

Inet1.Execute Inet1.URL, "PUT c:\user\vb_projects\ct_vericut\FTPtest\test.jcl"
Do While Inet1.StillExecuting
          DoEvents
Loop

Inet1.Execute Inet1.URL, "QUIT"
Do While Inet1.StillExecuting
          DoEvents
Loop

MsgBox "FTP Ended", vbOKOnly
Unload Me
Exit Sub
ftperr:
    MsgBox Err.Description, vbOKOnly, "ERROR"
    Inet1.Cancel
    Do While Inet1.StillExecuting
          DoEvents
    Loop
Unload Me
Exit Sub
End Sub


Private Sub Form_Load()
Text1.Text = ""
Text2.Text = ""
Text3.Text = ""
End Sub


2. Here is an FTP that works from DOS.


230 BVEBO6 is logged on.  Working directory is "BVEBO6.".
ftp> quote site filetype=jes
200 SITE command was accepted
ftp> put c:/user/ftptest/test.jcl
200 Port request OK.
125 Sending Job to JES internal reader FIXrecfm 80
250-It is known to JES as JOB27564
250 Transfer completed successfully.
ftp: 200 bytes sent in 0.05Seconds 4.00Kbytes/sec.
ftp> dir
200 Port request OK.
125 List started OK
BVEBO6Y   JOB20347  OUTPUT    4 Spool Files
BVEBO6A   JOB25404  OUTPUT    3 Spool Files
BVEBO6A   JOB27564  INPUT
250 List completed successfully.
ftp: 222 bytes received in 1.92Seconds 0.12Kbytes/sec.
ftp>
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
Dang123Commented:
We are not using VB itself to do the FTP transfer, but it is controlling the process. Below is the process we are using, modified to match your example. You may need to adjust the log parsing to suite your needs.

I played with your code this morning for a while. The problem I believe you are encountering is that the INet control supports only a subset of the FTP commands, QUOTE is not one of them. They are listed in VB help under "Execute Method".  (I also tried "LITERAL", it is an FTP command that does the same as "QUOTE".) I think you would need to use winsock to get this to work entirely within VB, if you wish to peruse that method, a good page to look at would be http://www.vbip.com/



cmdCL_Click()
    On Error GoTo ErrorCode
   
    Dim hndFile         As Integer
    Dim strFTP          As String
    Dim strBAT          As String
    Dim strLOG          As String
    Dim strPath         As String
   
    Dim strContents     As String
    Dim intFTPCode      As Integer
   
    Dim strErrorMessage As String
   
    m_blnError = False
    strErrorMessage = ""
   
    If Dir$("c:\user\vb_projects\ct_vericut\FTPtest\test.jcl") = "" Then
        ReportError "JCL file does not exist on server.", , True
    End If
   
    strPath = "c:\user\vb_projects\ct_vericut\FTPtest\"
    strFTP = strPath & "PayrollFTP.FTP"
    strBAT = strPath & "PayrollFTP.BAT"
    strLOG = strPath & "PayrollFTP.LOG"
   
    hndFile = FreeFile
    Open strFTP For Output As #hndFile
    Print #hndFile, "open " & UCase(Text1.Text)
    Print #hndFile, "user " & UCase(Text2.Text)
    Print #hndFile, UCase(Text3.Text)
    Print #hndFile, "QUOTE SITE FILETYPE=JES"
    Print #hndFile, "PUT c:\user\vb_projects\ct_vericut\FTPtest\test.jcl"
    Print #hndFile, "QUIT"
    Close #hndFile
   
    hndFile = FreeFile
    Open strBAT For Output As #hndFile
    Print #hndFile, "ftp -n -s:""" & strFTP & """ > """ & strLOG & """"
    Close #hndFile
   
    WaitFor strBAT
   
    If Dir$(strLOG) <> "" Then
        strErrorMessage = ""
        hndFile = FreeFile
        Open strLOG For Input As #hndFile
        Do While Not EOF(hndFile)
            Line Input #hndFile, strContents
           
            m_LogFile.WriteToLog strContents
           
            intFTPCode = Val(Left$(strContents, 3))
            If (intFTPCode >= 400 And intFTPCode <= 599) _
             And (InStr(strContents, "does not exist") = 0) Then
                m_blnError = True
                strErrorMessage = strErrorMessage & "    " & strContents
            End If
        Loop
    End If
   
    Kill strFTP
    Kill strBAT
   
    If m_blnError Then
        ReportError Trim$(strErrorMessage)
        Exit Sub
    End If
   
    Exit Sub
ErrorCode:
    Select Case Err.Number
        Case Else
            Err.Raise Err.Number, , "clsProcessRequest UploadFileFTP - " & Err.Description
    End Select
End Sub



***** To support this, place this code in a bas module in your project. *********


Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Code module containing all logic to shell to another program                 '
'   Adapted from sample code found on VBnet (www.mvps.org/vbnet)               '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Const STILL_ACTIVE = &H103


'Constants for OpenProcess API (DesiredAccess)
Private Const PROCESS_ALL_ACCESS        As Long = &H1F0FFF  'Specifies all possible access flags for the process object.
Private Const PROCESS_CREATE_THREAD     As Long = &H2       'Enables using the process handle in the CreateRemoteThread function to create a thread in the process.
Private Const PROCESS_DUP_HANDLE        As Long = &H40      'Enables using the process handle as either the source or target process in the DuplicateHandle function to duplicate a handle.
Private Const PROCESS_QUERY_INFORMATION As Long = &H400     'Enables using the process handle in the GetExitCodeProcess and GetPriorityClass functions to read information from the process object.
Private Const PROCESS_SET_INFORMATION   As Long = &H200     'Enables using the process handle in the SetPriorityClass function to set the priority class of the process.
Private Const PROCESS_TERMINATE         As Long = &H1       'Enables using the process handle in the TerminateProcess function to terminate the process.
Private Const PROCESS_VM_OPERATION      As Long = &H8       'Enables using the process handle in the VirtualProtectEx and WriteProcessMemory functions to modify the virtual memory of the process.
Private Const PROCESS_VM_READ           As Long = &H10      'Enables using the process handle in the ReadProcessMemory function to read from the virtual memory of the process.
Private Const PROCESS_VM_WRITE          As Long = &H20      'Enables using the process handle in the WriteProcessMemory function to write to the virtual memory of the process.
Private Const SYNCHRONIZE               As Long = &H100000  'Enables using the process handle in any of the wait functions to wait for the process to terminate.

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  API Declarations                                                 '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Declare Function GetExitCodeProcess Lib "kernel32" _
    ( _
    ByVal hProcess As Long, _
    lpExitCode As Long _
    ) As Long

Private Declare Function OpenProcess Lib "kernel32" _
    ( _
    ByVal dwDesiredAccess As Long, _
    ByVal bInheritHandle As Long, _
    ByVal dwProcessId As Long _
    ) As Long

Private Declare Sub Sleep Lib "kernel32" _
    ( _
    ByVal dwMilliseconds As Long _
    )

Private Declare Function CloseHandle Lib "kernel32" _
    ( _
    ByVal hObject As Long _
    ) As Long

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  Public Module Subs/Functions                                     '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Sub WaitFor( _
    ByVal strFilePath As String _
    )
   
    '*****************************************************************************************
    '
    ' Parameters:       strFilePath - command to execute program
    '
    ' Global Updates:   None
    '
    ' Global Read:      None
    '
    ' Return:           None - Sub
    '
    ' Description:
    '   Shells a process and waits for it to complete.
    '
    '*****************************************************************************************
    If Not g_blnInDesign Then On Error GoTo ErrorCode

    Dim lngProcess  As Long     'Process handle
    Dim lngReturn   As Long     'Return value from shelled program
   
    'The next line launches the process in a normal window with focus and captures process ID
    lngProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, Shell(strFilePath, vbNormalFocus))
   
    Do
        Call GetExitCodeProcess(lngProcess, lngReturn)  'Get the status of the process
        Sleep 100                                       'Sleep and DoEvents both recommended
        DoEvents
    Loop While lngReturn = STILL_ACTIVE                 'Loop while the process is active
   
    Call CloseHandle(lngProcess)                        'Close handle to free memory structures
   
    Exit Sub
ErrorCode:
    Select Case Err.Number
        Case Else
            Err.Raise Err.Number, , "(basWaitFor-WaitFor)" & Err.Description
    End Select
End Sub
0
 
jlhuberAuthor Commented:
Dan123,

I believe that http://www.vbip.com/ is the right track.  I was able to use some of the code there as a base.  I had to drop "quote", and it worked.  For example:


    comd = "site filetype=jes"
    bRet = FtpCommand(hConnection, False, FTP_TRANSFER_TYPE_ASCII, comd, 0, hFile)
    If bRet = False Then
        MsgBox "Site Error " & Err.LastDllError, , "FtpPutFile"
        Send_Commands = 1
        Exit Function
    End If



Public Declare Function FtpCommand Lib "wininet.dll" Alias "FtpCommandA" _
  (ByVal hConnect As Long, ByVal fExpectResponse As Boolean, ByVal dwFlags As Long, _
    ByVal lpszCommand As String, ByVal lContext As Long, phFtpCommand As Long) As Boolean


I will try your approach too and let you know.
0
 
Dang123Commented:
jlhuber,
    It is interesting that you had to drop "quote", that is supposed to tell FTP to use the servers command interpreter for the rest of the line. The fact that it works without it must mean you are using the servers command interpreter by default, the opposite of the FTP client found at the DOS prompt.

    Thank you for posting the sample code above, it would form an excellent basis for the function you need (I will probably start experimenting with it also).

Dang123


0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now