As you know, IBM is maintaining lists of program temporary fixes (PTFs) that are required to run SAP on IBM i smoothly. These PTF lists are updated from time to time, as new PTFs are created and found to be useful for SAP users. SAP has provided tools to compare the contents of those lists with the PTFs that are actually installed on the host where the SAP system is running, among them the kernel command CHKR3PTF and the function Diagnostics → PTF Check in SAP transaction DBACockpit. Some SAP installation tools execute the PTF check before they perform the requested installation. For each of these, the PTF list must be stored in subdirectory config of the SAP transport directory. The PTF list file is named infoapar.<vrm>, where <vrm> is replaced with the version, release and modification number of the operating system. A typical name in IBM i 7.4 would be /usr/sap/trans/config/infoapar.740. By default, the file is being shipped with SAP kernel patches and copied into the directory when a new SAP kernel is installed.

Obviously, the method of shipping the PTF list with the kernel can result in quite outdated lists. Wouldn’t it be nice to download that list immediately from the IBM web page after it has been published without waiting for the next SAP kernel update? At the end of this article, you will find the source code of an ABAP program named ZIBMGETPTFLIST4I that you can copy into your system and execute. The program has been tested in SAP NetWeaver releases 7.02 and higher. If you like, you can schedule the program to be executed once every night so that you have a very short delay when the PTF lists got updated by IBM. This provides you with a reliable status indicator in transaction DBACockpit and other SAP PTF check tools.

To run the program successfully, your system must be enabled to access the internet through the HTTPS protocol. If your system is configured to download SAP Notes from SAP or use APAP open source projects through abapGit, you probably don’t have to do much. If this is the first time you are trying to access the internet from your SAP application server, you need to check the following settings:

  1. Start transaction SMICM and verify through menu path Goto → Services that the HTTPS service has been started:Transaction%20SMICM%20-%20Services
  2. Execute transaction STRUST and check if certificates for the areas System PSE and SSL client SSL Client (Standard) exist. A folder symbol indicates that certificates exist, a red X indicates that no certificate has been defined:STRUST%20Certificate%20List
  3. For the section SSL client SSL Client (Standard), the certificate DigiCert Global Root CA needs to be installed. If you don’t have it installed yet, you can download the file DigiCertGlobalRootCA.crt from https://www.digicert.com/kb/digicert-root-certificates.htm to your local workstation and import it from there into your SAP system with transaction STRUST.
  4. If you needed to make any changes in the previous steps, you need to restart the Internet Communication Manager so that the changes become active. This can be done in transaction SMICM through menu path Administration → ICM → Exit Soft → Local.
  5. In SAP releases 7.3x and earlier, it may be necessary to specify the following profile parameter (see SAP Note 510007):ssl/client_ciphersuites = 150:PFS:HIGH::EC_X25519:EC_P256:EC_HIGH

Source of program ZIBMGETPTFLIST4I

Below you can find the source of the program to download the IBM PTF lists to your local SAP host. SAP or IBM do not offer support for this program, and there is no guarantee that the program does not cause damage or fulfills a specific purpose. You can use it on an as-is basis and modify it according to your needs.

*&---------------------------------------------------------------------*
*& Report ZIBMGETPTFLIST4I
*&---------------------------------------------------------------------*
*&
*& Download IBM maintained list of required PTFs for SAP on IBM i
*& to a streamfile, so that it can be used by SAP tools like CHKR3PTF
*& or transaction DB4PTFCHK to check the currency of the code level.
*&
*& Prerequisites:
*&   - SAP NetWeaver 7.02 or higher
*&   - If necessary, activate service HTTPS in ICM, e.g. by profile parameter
*&     icm/server_port_<n> = PROT=HTTPS,PORT=443$$,PROCTIMEOUT=600,TIMEOUT=600
*&   - A certificate must be created in transaction STRUST for System PSE
*&   - A certificate must be created in transaction STRUST for SSL client
*&     SSL Client Standard)
*&   - A certificate "DigiCert Global Root CA" must be downloaded from
*&     https://www.digicert.com/digicert-root-certificates.htm
*&   - The "DigiCert Global Root CA" must be uploaded for SSL client (Standard)
*&     SSL Client (Standard).
*&   - Up to and includung SAP NetWeaver release 7.3x, the following profile
*&     parameter must be specified:
*&     ssl/client_ciphersuites = 150:PFS:HIGH::EC_X25519:EC_P256:EC_HIGH
*&
*& Input parameters:
*&   - Release: Operating system release, for which the PTF list is
*&              to be obtained. Currently supported values are V7R2M0,
*&              V7R3M0, V7R4M0 and V7R5M0. Default is the operating system
*&              release level of the application server.
*&   - Outfile: Path to the output file as seen from the application
*&              server, e.g. /usr/sap/trans/config/infoapar.740
*&              Default: $(DIR_TRANS)/config/infoapar.<vrm>
*&   - Pattern: Pattern that identifies the text file version of the
*&              PTF list within the HTML document. Default is "*/INFOAPAR.*"
*&
*& Error information:
*&   - Check transaction SMICM -> Goto -> Trace File -> Display All
*&
*&---------------------------------------------------------------------*
REPORT ZIBMGETPTFLIST4I.

  data: lv_os_release_short      type string,
        lv_os_release_long       type string,
        lv_local_filename        type string,
        lv_trans_dir             type aparpath,
        lv_ptf_document_url      type string,
        lv_ptf_document_contents type string,
        lv_ptf_list_url          type string,
        lt_embedded_urls         type standard table of string,
        lv_selected_url          type string,
        lv_ptf_list_text         type string,
        lv_ptf_list_text_clean   type string,
        lv_abap_codepage         type tcp00-cpcodepage,
        lv_replacement_char_x    type xstring,
        lv_replacement_char      type string,
        lv_url_end               type i,
        lv_error_message         type string,
        lo_http_client           type ref to if_http_client,
        l_as4_api_exception      type ref to cx_as4_api_exception.

  parameters: Release type string default ' ',
              Outfile type string lower case default ' ',
              Pattern type string lower case default '*/INFOAPAR.*'.

  if Release is initial.
    try.
      call method cl_as4_api=>call_api_getsysval
        exporting
          hostname = sy-host
        receiving
          value    = lv_os_release_long.
      catch cx_as4_api_exception into l_as4_api_exception.
        call method cl_as4_api=>handle_api_exception
          exporting
            error_code = l_as4_api_exception->api_rc
            error_text = l_as4_api_exception->error_text.
    endtry.
  else.
    lv_os_release_long = Release.
  endif.
  lv_os_release_short = lv_os_release_long.
  translate lv_os_release_short using 'V R M '.
  condense lv_os_release_short no-gaps.

  if ( lv_os_release_short = '720' ).
    lv_ptf_document_url = 'https://www.ibm.com/support/pages/sap-support-required-ptf-list-ibm-i-72'.
  elseif ( lv_os_release_short = '730').
    lv_ptf_document_url = 'https://www.ibm.com/support/pages/sap-support-required-ptf-list-ibm-i-73'.
  elseif ( lv_os_release_short = '740' ).
    lv_ptf_document_url = 'https://www.ibm.com/support/pages/sap-support-required-ptf-list-ibm-i-74'.
  elseif ( lv_os_release_short = '750' ).
    lv_ptf_document_url = 'https://www.ibm.com/support/pages/sap-support-required-ptf-list-ibm-i-75'.
  else.
    write: / 'Local release', lv_os_release_long, 'is not supported by this program.'.
    return.
  endif.

  cl_http_client=>create_by_url(
    exporting
      url = lv_ptf_document_url
    importing
      client = lo_http_client
    exceptions
      argument_not_found = 1
      plugin_not_active  = 2
      internal_error     = 3
      others             = 4
    ).
  if sy-subrc <> 0.
    write: / 'Unable to access url', lv_ptf_document_url.
    write: / 'sy-subrc =', sy-subrc.
    return.
  endif.
  lo_http_client->send(
    exceptions
      http_communication_failure = 1
      http_invalid_state         = 2
      http_processing_failed     = 3
      others                     = 4
  ).
  if sy-subrc <> 0.
    write: / 'Failure sending http request to url', lv_ptf_document_url.
    write: / 'sy-subrc =', sy-subrc.
    return.
  endif.
  call method lo_http_client->receive
    exceptions
      http_communication_failure = 1
      http_invalid_state         = 2
      http_processing_failed     = 3
      others                     = 4.
  if sy-subrc <> 0.
    write: / 'Unable to receiv data from', lv_ptf_document_url.
    write: / 'sy-subrc =', sy-subrc.
    return.
  endif.
  lv_ptf_document_contents = lo_http_client->response->get_cdata( ).
  split lv_ptf_document_contents at 'href=' into table lt_embedded_urls.
  loop at lt_embedded_urls into lv_selected_url.
    if lv_selected_url cp pattern.
      shift lv_selected_url by 1 places.
      find '"' in lv_selected_url match offset lv_url_end.
      lv_selected_url = substring( val = lv_selected_url len = lv_url_end ).
      concatenate 'https://www.ibm.com' lv_selected_url into lv_selected_url.
      exit.
    else.
      clear lv_selected_url.
    endif.
  endloop.
  if lv_selected_url is initial.
    write: / 'Document at', lv_ptf_document_url, 'did not contain a PTF list.'.
    return.
  endif.
  call method lo_http_client->close( ).
  cl_http_client=>create_by_url(
    exporting
      url = lv_selected_url
    importing
      client = lo_http_client
    exceptions
      argument_not_found = 1
      plugin_not_active  = 2
      internal_error     = 3
      others             = 4
    ).
  if sy-subrc <> 0.
    write: / 'Unable to access url', lv_selected_url.
    write: / 'sy-subrc =', sy-subrc.
    return.
  endif.
  lo_http_client->send(
    exceptions
      http_communication_failure = 1
      http_invalid_state         = 2
      http_processing_failed     = 3
      others                     = 4
  ).
  if sy-subrc <> 0.
    write: / 'Failure sending http request to url', lv_selected_url.
    write: / 'sy-subrc =', sy-subrc.
    return.
  endif.
  call method lo_http_client->receive
    exceptions
      http_communication_failure = 1
      http_invalid_state         = 2
      http_processing_failed     = 3
      others                     = 4.
  if sy-subrc <> 0.
    write: / 'Unable to receiv data from', lv_selected_url.
    write: / 'sy-subrc =', sy-subrc.
    return.
  endif.
  lv_ptf_list_text = lo_http_client->response->get_cdata( ).

  if Outfile is initial.
* build up as4_filename like '/usr/sap/trans/config/infoapar.xxx
    call 'C_SAPGPARAM'  id 'NAME'  field 'DIR_TRANS'
                        id 'VALUE' field lv_trans_dir. "#EC CI_CCALL
    concatenate lv_trans_dir '/config/infoapar.' lv_os_release_short
                into lv_local_filename.
  else.
    lv_local_filename = Outfile.
  endif.
  call function 'SCP_GET_CODEPAGE_NUMBER'
    EXPORTING database_also = space
    IMPORTING appl_codepage = lv_abap_codepage
    EXCEPTIONS others = 1.
  if sy-subrc <> 0.
    write: / 'Function SCP_GET_CODEPAGE_NUMBER could not retrieve code page, sy-subrc =', sy-subrc.
    return.
  endif.
  if lv_abap_codepage = '4102'.
    lv_replacement_char_x = 'FFFD'.
    lv_replacement_char = cl_abap_codepage=>convert_from( source = lv_replacement_char_x codepage = 'UTF-16' ).
    lv_ptf_list_text = condense( val = lv_ptf_list_text from = lv_replacement_char ).
  endif.
  lv_replacement_char_x = '0D'.
  lv_replacement_char = cl_abap_codepage=>convert_from( source = lv_replacement_char_x codepage = 'UTF-8' ).
  lv_ptf_list_text_clean = condense( val = lv_ptf_list_text from = lv_replacement_char ).
  open dataset lv_local_filename for output in text mode encoding non-unicode message lv_error_message.
  if sy-subrc <> 0.
    write: / 'Open dataset', lv_local_filename, 'failed with sy-subrc =', sy-subrc.
    write: / lv_error_message.
    return.
  endif.
  transfer lv_ptf_list_text_clean to lv_local_filename.
  close dataset lv_local_filename.
  write: / 'Contents of', lv_selected_url, 'where written to', lv_local_filename.
  call method lo_http_client->close( ).
Sara Sampaio

Sara Sampaio

Author Since: March 10, 2022

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x