[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: HTTPAPI IFS file lock



So far the only option to make HTTPAPI keep the stream file open is to let the program crash. When the program crashes due to an unexpected error after having opened the file, procedure cleanup() is not being called. Hence the stream file stays open.

I changed the attached version of HTTPCMDR4 to register an error handler that calls cleanup() for unexpected errors. Maybe it is worth to get into the official version of HTTPAPI.

Thomas.

Am 17.02.2012 18:07, schrieb Stone, Joel:
    Help!!


    I am using the following HTTPAPI and it works perfectly.



    HTTPAPI    URL(&URL) DOWNLOAD(&TOIFSFILE)


    The DOWNLOAD file appears intact in windows explorer and in System I
    navigator.


    However, my next command fails:


    For some reason (and randomly) the DOWNLOADed file is in use and
    CPYFRMSTMF command is NOT able to copy it.


    CPYFRMSTMF FROMSTMF('/gig/incoming/Official 02-17-12
    H10M43S00.xml')

           TOMBR('/QSYS.LIB/QTEMP.LIB/ifsinfo.FILE/ifsinfo.MBR')
    MBROPT(*REPLACE)      ENDLINFMT(*FIXED) TABEXPN(*NO)


    Object in use.  Object is /gig/incoming/Official 02-17-12
    H10M43S00.xml.


    Stream file not copied.


    CPFA095 received


    Most times I receive the "Object in use" message, but other times the
    CPYFRMSTMF works just fine.


    If it fails (with the "Object in use"), it appears to NEVER be
    available until I log off - which seems to release the lock.


    1)      Is there a command like WRKOBJLCK to view an IFS file lock?

    2)      How can I release this nasty lock so a CPYFRMSTMF can function
    properly?


    Thanks so much in advance!!




    [cid:image001.png@01CCED62.EC347320]

    ______________________________________________________________________
    This outbound email has been scanned for all viruses by the MessageLabs
    Skyscan service.
    For more information please visit http://www.symanteccloud.com
    ______________________________________________________________________




-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------
     /*-                                                                            +
      * Copyright (c) 2008-2012 Scott C. Klement                                    +
      * All rights reserved.                                                        +
      *                                                                             +
      * Redistribution and use in source and binary forms, with or without          +
      * modification, are permitted provided that the following conditions          +
      * are met:                                                                    +
      * 1. Redistributions of source code must retain the above copyright           +
      *    notice, this list of conditions and the following disclaimer.            +
      * 2. Redistributions in binary form must reproduce the above copyright        +
      *    notice, this list of conditions and the following disclaimer in the      +
      *    documentation and/or other materials provided with the distribution.     +
      *                                                                             +
      * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ''AS IS'' AND      +
      * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE       +
      * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  +
      * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE     +
      * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  +
      * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS     +
      * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)       +
      * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  +
      * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY   +
      * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF      +
      * SUCH DAMAGE.                                                                +
      *                                                                             +
      */                                                                            +

     /*
      * HTTPCMDR4 -- Command-line & CL interface to HTTPAPI
      *   (also serves as a back-end to the QSH interface)
      *
      *  This program is intended to be called via the HTTPAPI
      *  command, or the httpapi QShell command. Please don't
      *  call it directly.
      */

     H COPYRIGHT('Copyright (c) 2008-2012 Scott C. Klement.  All +
     H rights reserved.  A member called "LICENSE" was included with +
     H this distribution, and contains important license information.')

      /copy ifsio_h
      /copy httpapi_h
      /copy errno_h
      /copy httpcmd_h
      /copy private_h

     D HTTPCMDR4       PI
     D   peUrl                    32767a   varying const
     D   peDownload                 256a   varying const
     D   peReqType                    5a           const
     D   peUpload                   256a   varying const
     D   peType                      64a   varying const
     D   peUser                      80a   varying const
     D   pePass                    1024a   varying const
     D   peRedir                      4a           const
     D   peProxy                    256a   varying const
     D   peProxyUser                 80a   varying const
     D   peProxyPass               1024a   varying const
     D   peDebug                    256a   varying const
     D   peSSLID                    100a   varying const
     D   peCookies                  256a   varying const
     D   peSessCook                   4a           const
     D   peErrMsg                    80a   varying options(*nopass)
     D   peExitSts                   10i 0         options(*nopass)

     D printError      PR
     D   inMsg                       80a   const options(*nopass)
     D memwriter       PR            10i 0
     D   fd                          10i 0 value
     D   data                     65535a   options(*varsize)
     D   len                         10u 0 value
     D memreader       PR            10i 0
     D   fd                          10i 0 value
     D   data                     65535a   options(*varsize)
     D   len                         10u 0 value
     D readupload      PR            10i 0
     D   fd                          10i 0 value
     D cleanup         PR
     D   exitstatus                  10i 0 value
     D basename        PR         32767a   varying
     D   pathname                 32767a   varying const
     D abnEndHandler   PR                                                                     RADDAT
     D  i_rtxToken                     *   const                                              RADDAT
                                                                                              RADDAT
      *  Register Call Stack Entry Termination User Exit Procedure (CEERTX)                   RADDAT
     D CEERTX...                                                                              RADDAT
     D                 PR                         extproc('CEERTX')                           RADDAT
     D  i_procPtr                      *   const  procptr                                     RADDAT
     D  i_rtxToken                     *   const  options(*omit)                              RADDAT
     D  o_fc                         12A          options(*omit)                              RADDAT
                                                                                              RADDAT
     D isAbnEnd        s               N   inz(*off)                                          RADDAT

     D FD_STDIN        c                   0
     D FD_STDOUT       c                   1

     D memdata         s               *   inz(*null)
     D memlen          s             10i 0 inz(0)
     D memalloc        s             10i 0 inz(0)
     D upldata         s               *   inz(*null)
     D upllen          s             10i 0 inz(0)
     D uplleft         s             10i 0 inz(0)
     D upl             s          65535a   based(uplpos)

     D reqtype         s              5a
     D uploadfd        s             10i 0 inz(-1)
     D downloadfd      s             10i 0 inz(-1)
     D x               s             10i 0
     D rc              s             10i 0
     D URL             s          32767a   varying
     D type            s             64a   varying
     D                                     inz(HTTP_CONTTYPE)
     D user            s             80a   varying
     D pass            s           1024a   varying
     D proxy           s            256a   varying
     D proxyport       s             10i 0 inz(8080)
     D proxyuser       s             80a   varying
     D proxypass       s           1024a   varying
     D debug           s            256a   varying
     D sslid           s            100a   varying
     D redir           s              4a   varying inz('*YES')
     D upload          s          32767A   varying inz('-')
     D download        s          32767A   varying inz('-')
     D cookies         s            256a   varying
     D sesscook        s              1n   inz(*OFF)
     D inputlen        s             10i 0
     D pos             s             10i 0
     D RTN_ERROR       s              1n   inz(*OFF)
     D LastMsg         s             80a   varying

      /free

       //-----------------------------------------------------------
       //  Interpret Parameters
       //-----------------------------------------------------------

       if %parms < 15;
          printError('Parameter mismatch');
          cleanup(1);
          return;
       endif;
       if %parms >= 17;
          RTN_ERROR = *ON;
       endif;

       url      = %trim(peURL);
       reqtype  = %xlate('getpos':'GETPOS':peReqType);
       redir    = %xlate('yesno':'YESNO':peRedir);
       type     = peType;

       if (peDownload = '*BASENAME');
          download = basename(url);
       else;
          download = %trim(peDownload);
       endif;

       if (peUpload = '*NONE');
          upload = '';
       else;
          upload = %trim(peUpload);
       endif;

       if (peUser = '*NONE');
          user='';
       else;
          user = %trim(peUser);
       endif;

       if (pePass = '*NONE');
          pass='';
       else;
          pass = %trim(pePass);
       endif;

       if (peProxy = '*NONE');
          proxy='';
       else;
          proxy = %trim(peProxy);
       endif;

       if (peProxyUser = '*NONE');
          proxyuser='';
       else;
          proxyuser = %trim(peProxyUser);
       endif;

       if (peProxyPass = '*NONE');
          proxypass='';
       else;
          proxypass = %trim(peProxyPass);
       endif;

       if (peDebug = '*NONE');
          debug = '';
       else;
          debug = %trim(peDebug);
       endif;

       if (peSSLID = '*DFT');
          sslid = '';
       else;
          sslid = %trim(peSSLID);
       endif;

       if (peCookies = '*NONE');
          cookies = '';
       else;
          cookies = %trim(peCookies);
       endif;

       if (peSessCook = '*YES');
          sesscook = *ON;
       endif;


       //-----------------------------------------------------------
       //  Verify that all needed parameters were passed
       //-----------------------------------------------------------

       if ( peReqType <> '*GET'
            and peReqType <> '*POST' );
          printError('Unknown request type: ' + peReqType);
          cleanup(1);
          return;
       endif;

       if %len(%trim(peURL)) < 5;
          printError('Invalid URL: ' + URL);
          cleanup(1);
          return;
       endif;

       if peRedir<>'*YES' and peRedir<>'*NO';
          printError('Invalid redirect value.');
          cleanup(1);
          return;
       endif;

       if peSessCook<>'*YES' and peSessCook<>'*NO';
          printError('Invalid SESSCOOK value.');
          cleanup(1);
          return;
       endif;


       //-----------------------------------------------------------
       //  Set options specified by the parameters.
       //-----------------------------------------------------------

       if %len(debug)>0;
          http_debug(*ON:debug);
       endif;

       if %len(cookies)>0;
          http_cookie_file(cookies:sesscook);
       endif;

      /if defined(HAVE_SSLAPI)
       if %len(sslid)>0;
          https_init(sslid);
       endif;
      /endif

       if %len(user)>0 or %len(pass)>0;
          http_setauth( HTTP_AUTH_BASIC : user: pass);
       endif;

       if %len(proxy)>0;
          pos = %scan(':': proxy);
          if (pos>1 and pos<%len(proxy) );
             proxyport = atoi(%subst(proxy:pos+1));
             proxy     = %subst(proxy:1:pos-1);
          endif;
          if http_setproxy(proxy:proxyport) = -1;
             printError();
             cleanup(2);
             return;
          endif;
       endif;

       if %len(proxyuser)>0 or %len(proxypass)>0;
          if http_proxy_setauth( HTTP_AUTH_BASIC
                               : proxyuser
                               : proxypass ) = -1;
             printError();
             cleanup(2);
             return;
          endif;
       endif;
                                                                                            //RADDAT
       CEERTX(%paddr(abnEndHandler): *null: *);                                             //RADDAT

       if peReqType = '*POST';
          if upload='-';
             uploadfd = FD_STDIN;
          else;
             uploadfd = open( %trimr(upload) : O_RDONLY );
             if uploadfd = -1;
                printError( %trimr(upload) + ': '
                          + %str(strerror(errno)) );
                cleanup(3);
                return;
             endif;
          endif;
       endif;

       if download='-';
          downloadfd = FD_STDOUT;
       else;
          downloadfd = open( %trimr(download)
                           : O_WRONLY + O_CREAT + O_TRUNC + O_CCSID
                           : HTTP_IFSMODE
                           : HTTP_CCSID );
          if downloadfd = -1;
             printError( %trimr(download) + ': '
                       + %str(strerror(errno)) );
             cleanup(3);
             return;
          endif;
       endif;


       //-----------------------------------------------------------
       //  Do the POST/GET request
       //-----------------------------------------------------------

       if peReqType='*GET';
           rc = http_url_get_raw( URL
                                : downloadfd
                                : %paddr(memwriter) );
       else;
           readupload(uploadfd);
           rc = http_url_post_raw2( URL
                                  : uploadfd
                                  : %paddr(memreader)
                                  : upllen
                                  : downloadfd
                                  : %paddr(memwriter)
                                  : HTTP_TIMEOUT
                                  : HTTP_USERAGENT
                                  : type );
       endif;


       //-----------------------------------------------------------
       //  Handle any redirects.
       //-----------------------------------------------------------

       if redir='*YES' and rc=302;

          x=0;
          dou rc<>302 or x=5;
             memlen = 0;
             rc = http_url_get_raw( http_redir_loc()
                                  : downloadfd
                                  : %paddr(memwriter) );
             x = x + 1;
          enddo;

          if rc = 302;
             printError('More than five redirects.');
             cleanup(4);
             return;
          endif;

       endif;


       //-----------------------------------------------------------
       //  Check for errors
       //-----------------------------------------------------------

       if rc <> 1;
          printError();
          cleanup(5);
          return;
       endif;

       if (memlen > 0);
          callp write( downloadfd: memdata: memlen);
       endif;

       cleanup(0);
       return;

      /end-free


      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      *  printError():  Set an error message
      *
      *    inMsg = (input/optional) error message to print
      *              if not given, the msg will be retrieved
      *              by calling http_error()
      *
      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     P printError      B
     D printError      PI
     D   inMsg                       80a   const options(*nopass)
     D  msg            s             80a
     D msgno           s             10i 0

      /free
        if %parms>= 1;
           msg = %trimr(inMsg) + x'25';
        else;
           msg = http_error(msgno);
           msg = %char(msgno) + ' ' + msg + x'25';
        endif;

        LastMsg = msg;

      /end-free
     P                 E


      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      *  memwriter(): Write HTTP response into memory
      *
      *  the memory addressed by the "memdata" pointer is intended
      *  to automatically "grow" in size as needed to store the
      *  received data.
      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     P memwriter       B
     D memwriter       PI            10i 0
     D   fd                          10i 0 value
     D   data                     65535a   options(*varsize)
     D   len                         10u 0 value

     D CHUNK_SIZE      c                   131072

     D newlen          s             10i 0 static
     D newdata         s          65535a   based(p_newdata)
      /free
         newlen = memlen + len;

         dow (newlen > memalloc);
            memalloc = memalloc + CHUNK_SIZE;
            if (memdata = *null);
               memdata = TS_malloc(memalloc);
            else;
               memdata = TS_realloc(memdata: memalloc);
            endif;
         enddo;

         p_newdata = memdata + memlen;
         %subst(newdata:1:len) = %subst(data:1:len);
         memlen = newlen;

         return len;
      /end-free
     P                 E


      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      *  memreader(): Read POST data from memory
      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     P memreader       B
     D memreader       PI            10i 0
     D   fd                          10i 0 value
     D   data                     65535a   options(*varsize)
     D   len                         10u 0 value
      /free

         if (len >= uplleft);
            len = uplleft;
            %subst(data:1:len) = %subst(upl:1:len);
            uplleft = 0;
         else;
            %subst(data:1:len) = %subst(upl:1:len);
            uplleft = uplleft - len;
            uplpos  = uplpos  + len;
         endif;

         return len;
      /end-free
     P                 E



      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      *  readupload(): Read all of upload file into memory
      *
      *  the memory addressed by the "memdata" pointer is intended
      *  to automatically "grow" in size as needed to store the
      *  received data.
      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     P readupload      B
     D readupload      PI            10i 0
     D   fd                          10i 0 value

     D savememdata     s                   like(memdata)
     D savememlen      s                   like(memlen)
     D savememalloc    s                   like(memalloc)

     D buf             s          65535a
     D newlen          s             10i 0 static
      /free
         savememdata  = memdata;
         savememlen   = memlen;
         savememalloc = memalloc;

         memdata      = *null;
         memlen       = 0;
         memalloc     = 0;

         newlen = read(fd: %addr(buf): %size(buf));
         dow newlen > 0;
           memwriter(fd: buf: newlen);
           newlen = read(fd: %addr(buf): %size(buf));
         enddo;

         upldata  = memdata;
         uplpos   = memdata;
         upllen   = memlen;
         uplleft  = memlen;
         memdata  = savememdata;
         memlen   = savememlen;
         memalloc = savememalloc;

         return upllen;
      /end-free
     P                 E
                                                                                              RADDAT
                                                                                              RADDAT
      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++                          RADDAT
      *  abnEndHandler(): Handle unexpected errors                                            RADDAT
      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++                          RADDAT
     P abnEndHandler   B                                                                      RADDAT
     D abnEndHandler   PI                                                                     RADDAT
     D  i_rtxToken                     *   const                                              RADDAT
      /free
         if (isAbnEnd); // prevent recursion in cleanup() proc                              //RADDAT
            return;                                                                         //RADDAT
         endif;                                                                             //RADDAT
         monitor;                                                                           //RADDAT
            printError('** Unexpected error. Check job log. **');                           //RADDAT
            http_dmsg('** Unexpected error. Check job log. **');                            //RADDAT
         on-error;                                                                          //RADDAT
         endmon;                                                                            //RADDAT
         isAbnEnd = *ON;                                                                    //RADDAT
         cleanup(6);                                                                        //RADDAT
      /end-free
     P                 E                                                                      RADDAT


      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      *  cleanup():  Clean up any open resources before ending
      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     P cleanup         B
     D cleanup         PI
     D   exitstatus                  10i 0 value

     D QMHSNDPM        PR                  ExtPgm('QMHSNDPM')
     D   MessageID                    7A   Const
     D   QualMsgF                    20A   Const
     D   MsgData                     80A   Const
     D   MsgDtaLen                   10I 0 Const
     D   MsgType                     10A   Const
     D   CallStkEnt                  10A   Const
     D   CallStkCnt                  10I 0 Const
     D   MessageKey                   4A   const
     D   ErrorCode                    8a   const
      /free

         if uploadfd > FD_STDIN;
            callp close(uploadfd);
         endif;

         if downloadfd > FD_STDOUT;
            callp close(downloadfd);
         endif;

         if memdata <> *null;
            TS_free(memdata);
         endif;

         if upldata <> *null;
            TS_free(upldata);
         endif;

         select;
         when RTN_ERROR = *ON;
            peErrMsg  = lastMsg;
            peExitSts = exitStatus;
         when exitStatus <> 0
           and %len(lastMsg) > 0;
            QMHSNDPM( 'CPF9897'
                    : 'QCPFMSG   *LIBL'
                    : lastMsg
                    : %len(lastMsg)
                    : '*ESCAPE'
                    : '*PGMBDY'
                    : 1
                    : *blanks
                    : x'0000000000000000');
         endsl;

         *INLR = *ON;
         return;
      /end-free
     P                 E


      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      *  basename(): Remove directory/prefix from filename
      *
      *     pathname = (input) IFS pathname to get basename of
      *
      * returns '' if no path, or only directories, provided.
      *         else returns the basename
      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     P basename        B
     D                 PI         32767a   varying
     D   pathname                 32767a   varying const

     D pos             s             10i 0 inz(0)
     D str             s             10i 0 inz(-1)
     D result          s          32767a   varying
      /free
       if %len(pathname) > 0;
          dou pos=0 or pos>=%len(pathname);
             pos = %scan('/': pathname: pos+1);
             if (pos>0 and pos<%len(pathname));
                str = pos + 1;
             endif;
          enddo;
       endif;
       if str = -1;
          return '';
       endif;
       result = %subst(pathname:str);
       dow %len(result)>0 and %subst(result:%len(result):1)='/';
         %len(result) = %len(result) - 1;
       enddo;
       if %len(result)=0 or result=*blanks;
          return '';
       endif;
       return result;
      /end-free
     P                 E

      /define ERRNO_LOAD_PROCEDURE
      /copy errno_h
-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------