XMLSERVICE Work

      * *java (1.9.2)               
      *    - start JVM allowing user classpath
      *      <cmd>ADDENVVAR ENVVAR(CLASSPATH) VALUE('$ours') 
      *           REPLACE(*YES)</cmd>
      *      <pgm>... calling my RPG w/JAVA ... </pgm>
      * *sqljava or *dbgjava (port 30000) (1.9.2)            
      *    - start JVM allowing DB2 classpath (no user control)
      *       SQLJ.INSTALL_JAR into schema
      *       /QIBM/UserData/OS400/SQLLib/Function/jar/(schema) 



      *****************************************************
     P PaseStart32     B                   export
     D PaseStart32     PI             1N
     D   myMax                       10i 0 value
     D   paseCtl                           likeds(paseRec_t)
      * vars
     Diarg             DS
     D ipgm                          30A   inz('/usr/lib/start32')
     D iarg1                           *   inz(*NULL)
     D iargend                         *   inz(*NULL)



      *****************************************************
      * JVM the RPG way
      *****************************************************
     P jvmRPG          B
     D jvmRPG          PI            10I 0
      *
     d rc              s             10i 0 inz(-1)
     D myfunc          S             10A   inz(*BLANKS)
     D propstr         S               O   CLASS(*JAVA:'java.lang.String')
     D makeString      PR              O   EXTPROC(*JAVA:'java.lang.String':
     D                                      *CONSTRUCTOR)
     D    bytes                    4096A   CONST VARYING
      /free
       Monitor;

       myfunc = 'jvmRPG';
       propstr = makeString('java.class.path');
       rc = 0;

       On-error;
         errsSevere(QP2_ERROR_ILECALL_FAIL:myfunc);
       Endmon;

       return rc;
      /end-free
     P                 E

Clark:

Solved my customer’s problem by setting FastCGI CCSID to 819 (latin), and having them tell the web browser to treat content as iso-8859–1, by using php’s header() function, as follows, at the top of their script, before any html output: header(‘Content-type: text/html; charset=iso-8859–1′);

Their data was indeed 7-bit ASCII, so the above took care of the problem.

The 819 for FastCGI took care of the data length, but characters were still displaying as black triangles with question marks. The header() function with correct charset solved the output part.

DRDA ports - https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/ddp/rbal1ports.htm

                Work with Relational Database Directory Entries

 Position to  . . . . . .                     

 Type options, press Enter.
   1=Add   2=Change   4=Remove   5=Display details   6=Print details

                             Remote
 Option  Entry               Location                  Text
   1     INUXME            
         M128584T            ut28p63.rch.stglabs.ib >  Entry added by system
         UT28P63             *LOCAL
         UT28P64             ut28p64.rch.stglabs.ib >
         UT28P65             ut28p65.rch.stglabs.ib >

                     Add RDB Directory Entry (ADDRDBDIRE)    

 Type choices, press Enter.

 Entry:
   Relational database  . . . . . > INUXME                   
   Relational database alias  . .   *NONE                    
 Remote location:
   Name or address  . . . . . . .   mylinux.ibm.com                             



   Type . . . . . . . . . . . . . > *IP           *SNA, *IP
 Port number or service program     *DRDA            
 Remote authentication method:
   Preferred method . . . . . . .   *USRENCPWD    *USRENCPWD, *USRID...
   Allow lower authentication . .   *ALWLOWER     *ALWLOWER, *NOALWLOWER

SQLRETURN tool_key_cmd_run(tool_struct_t * tool, tool_node_t ** curr_node) {
  SQLRETURN sqlrc = SQL_SUCCESS;
  SQLRETURN sqlrc1 = SQL_SUCCESS;
  int h = 0, i = 0, j = 0;
  int key = 0;
  char * val = NULL;
  int lvl = 0;
  int max = 0;
  int go = 1;
  char * cmd = NULL;
  int len = 0;
  int fetch_odd = 0;
  int fetch_recs = 0;
  int isRexx = 0;
  int isRexxError = 0;
  char * lastLF = NULL;
  char * posLF = NULL;
  int isQsh = 0;
  int isQshLen = 0;
  int isQshRow = 0;
  int isQshError = 0;
  char * qshVal = NULL;
  int save_conn_type = 0;
  SQLCHAR qshRow[50];
  SQLHANDLE hstmt = 0;
  SQLHANDLE hstmt2 = 0;
  SQLCHAR cmd_tmp[TOOL400_MAX_CMD_BUFF];
  SQLCHAR query_string[TOOL400_MAX_CMD_BUFF];
  SQLCHAR col_name[69];
  SQLCHAR col_val[69];
  SQLINTEGER col_len = 0;
  tool_key_conn_struct_t * tconn = (tool_key_conn_struct_t *) tool->tconn;
  tool_node_t * node = *curr_node;
  tool_key_cmd_struct_t * tcmd = (tool_key_cmd_struct_t *) node;
  /* current node (output) */
  tool->curr = node;

  /* ctor */
  tcmd->hstmt = 0;
  tcmd->cmd_len = 0;
  memset(tcmd->cmd_buff,0,sizeof(tcmd->cmd_buff));

  /* save conn type (not support in memory for rexx or qsh) */
  save_conn_type = tconn->conn_type;

  /* cmd attributes (parser order 1st) */
  for (i=0; i < TOOL400_ATTR_MAX && node->akey[i]; i++) {
    key = node->akey[i];
    val = node->aval[i];
    lvl = node->ord;
    tool_dump_attr(sqlrc, "cmd_run(a)", i, lvl, key, val);
    switch (key) {
    /* "exec":"CHGLIBL LIBL(DB2JSON QTEMP) CURLIB(DB2JSON)"
     */
    case TOOL400_CMD_EXEC:
      cmd = val;
      break;
    /* "rexx":"STRREXPRC SRCMBR(CMDIO) SRCFILE(DB2JSON/QREXSRC) PARM('456 RTVJOBA CCSID(?N) USRLIBL(?)')"
     * select * from qtemp/out456
     */
    case TOOL400_CMD_REXX:
      sqlrc = SQLAllocHandle(SQL_HANDLE_STMT, tconn->hdbc, &hstmt);
      isRexx = hstmt;
      sprintf(tcmd->cmd_buff,"STRREXPRC SRCMBR(CMDIO) SRCFILE(DB2JSON/QREXSRC) PARM('%d %s')",isRexx,val);
      cmd = tcmd->cmd_buff;
      /* in memory option? (not support rexx -- not work chroot) */
      if (tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_ILE || tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_PASE) {
        tconn->conn_type = TOOL400_CONN_TYPE_SET;
      }
      break;
    /* "qsh":"STRQSH CMD('ls -1 /home/adc')"
     * select * from qtemp/out456
     */
    case TOOL400_CMD_QSH:
      sqlrc = SQLAllocHandle(SQL_HANDLE_STMT, tconn->hdbc, &hstmt);
      isQsh = hstmt;
      cmd = qshVal = val;
      /* in memory option? (not support qsh -- not work chroot) */
      if (tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_ILE || tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_PASE) {
        tconn->conn_type = TOOL400_CONN_TYPE_SET;
      }
      break;
    default:
      break;
    }
  }
  /* output */
  tool_output_cmd_beg(tool, cmd);
  /* qsh */
  if (isQsh) {
    for (h=0;h<7;h++) {
      sqlrc = SQLAllocHandle(SQL_HANDLE_STMT, tconn->hdbc, &hstmt2);
      memset(tcmd->cmd_buff,0,sizeof(tcmd->cmd_buff));
      cmd = tcmd->cmd_buff;
      switch(h) {
      case 0:
        sprintf(cmd,"DLTF FILE(QTEMP/OUT%d)", isQsh);
        break;
      case 1:
        sprintf(cmd,"CRTSRCPF FILE(QTEMP/OUT%d) RCDLEN(80) MBR(OUT%d)", isQsh, isQsh);
       break;
      case 2:
        sprintf(cmd,"CLRPFM FILE(QTEMP/OUT%d) MBR(OUT%d)", isQsh);
        break;
      case 3:
        sprintf(cmd,"RMVENVVAR ENVVAR(QIBM_QSH_CMD_ESCAPE_MSG)");
        break;
      case 4:
        sprintf(cmd,"ADDENVVAR ENVVAR(QIBM_QSH_CMD_ESCAPE_MSG) VALUE('Y')");
        break;
      case 5:
        sprintf(cmd,"RMVENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT)");
        break;
      case 6:
        sprintf(cmd,"ADDENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT) VALUE('FILE=/qsys.lib/qtemp.lib/out%d.file/out%d.mbr')", isQsh, isQsh);
        break;
      default:
        break;
      }
      /* sql actual len cmd (ignore escape quotes) */
      tcmd->cmd_len = strlen(cmd);
      /* escape single quotes */
      memset(cmd_tmp,0,TOOL400_MAX_CMD_BUFF);
      for (i=0, j=0; i < tcmd->cmd_len && j < TOOL400_MAX_CMD_BUFF; i++, j++) {
        cmd_tmp[j] = cmd[i];
        /* found single quote, add another single quote */
        if (cmd_tmp[j] == '\'') {
          j++;
          cmd_tmp[j] = '\'';
        }
      }
      cmd = cmd_tmp;
      memset(tcmd->cmd_buff,0,sizeof(tcmd->cmd_buff));
      /* in memory option? */
      if (tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_ILE || tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_PASE) {
        sqlrc = iCall400Cmd(cmd, tcmd->cmd_len);
      } else {
        sprintf(tcmd->cmd_buff,"CALL QSYS2.QCMDEXC('%s',%d)", cmd, tcmd->cmd_len);
        sqlrc = SQLExecDirect(hstmt2, tcmd->cmd_buff, (SQLINTEGER)SQL_NTS);
      }
      sqlrc1 = SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);
    } /* loop h */
    /* STRQSH CMD */
    memset(tcmd->cmd_buff,0,sizeof(tcmd->cmd_buff));
    sprintf(tcmd->cmd_buff,"STRQSH CMD('%s')",qshVal);
    cmd = tcmd->cmd_buff;
  } /* isQsh */
  /* sql actual len cmd (ignore escape quotes) */
  tcmd->cmd_len = strlen(cmd);
  /* escape single quotes */
  memset(cmd_tmp,0,TOOL400_MAX_CMD_BUFF);
  for (i=0, j=0; i < tcmd->cmd_len && j < TOOL400_MAX_CMD_BUFF; i++, j++) {
    cmd_tmp[j] = cmd[i];
    /* found single quote, add another single quote */
    if (cmd_tmp[j] == '\'') {
      j++;
      cmd_tmp[j] = '\'';
    }
  }
  /* statement */
  sqlrc = SQLAllocHandle(SQL_HANDLE_STMT, (SQLHDBC) tconn->hdbc, &tcmd->hstmt);
  /* in memory option? */
  if (tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_ILE || tconn->conn_type == TOOL400_CONN_TYPE_MEMORY_PASE) {
    sqlrc = iCall400Cmd(cmd, tcmd->cmd_len);
  } else {
    cmd = cmd_tmp;
    memset(tcmd->cmd_buff,0,sizeof(tcmd->cmd_buff));
    sprintf(tcmd->cmd_buff,"CALL QSYS2.QCMDEXC('%s',%d)", cmd, tcmd->cmd_len);
    /* prepare */
    if (sqlrc == SQL_SUCCESS) {
      sqlrc = SQLPrepare((SQLHSTMT)tcmd->hstmt, (SQLCHAR*)tcmd->cmd_buff, (SQLINTEGER)SQL_NTS);
    }
    sqlrc = tool_sql_errors(tool, tcmd->hstmt, SQL_HANDLE_STMT, sqlrc);
    /* execute */
    if (sqlrc == SQL_SUCCESS) {
      sqlrc = SQLExecute((SQLHSTMT)tcmd->hstmt);
    }
    sqlrc = tool_sql_errors(tool, tcmd->hstmt, SQL_HANDLE_STMT, sqlrc);
  }
  /* ======
   * qsh output 
   */
  if (isQsh && sqlrc == SQL_SUCCESS) {
    /* query QTEMP.OUT456 */
    memset(query_string,0,sizeof(query_string));
    sprintf(query_string,"select SRCDTA from QTEMP.OUT%d",isQsh);
    sqlrc = SQLExecDirect(hstmt, query_string, (SQLINTEGER)SQL_NTS);
    col_len = sizeof(col_val);
    memset(col_val,0,sizeof(col_val));
    sqlrc = SQLBindCol((SQLHSTMT)hstmt,
                         1,
                         SQL_CHAR, 
                         col_val,
                         col_len,
                         &col_len);
    /* fetch */
    memset(cmd_tmp,0,sizeof(cmd_tmp));
    sqlrc = SQL_SUCCESS;
    tool_output_record_array_beg(tool);
    while (sqlrc == SQL_SUCCESS) {
      col_len = sizeof(col_val);
      memset(col_val,0,sizeof(col_val));
      sqlrc = SQLFetch(hstmt);
      if (sqlrc == SQL_NO_DATA_FOUND || sqlrc < SQL_SUCCESS ) {
        if (!fetch_recs) {
          tool_output_record_no_data_found(tool, 0);
        } else {
          sqlrc = SQL_SUCCESS;
        }
        break;
      }
      fetch_recs += 1;
      strcat(cmd_tmp,col_val);
      /* find LF for rows */
      lastLF = cmd_tmp;
      posLF = ile_pgm_find_new_line(lastLF, FLAG_STR_COMPILE);
      while (posLF) {
        isQshRow++;
        memset(qshRow,0,sizeof(qshRow));
        sprintf(qshRow,"R%d", isQshRow);
        posLF[0] = '\0';
        isQshLen = strlen(lastLF);
        tool_output_record_row_beg(tool);
        tool_output_record_name_value(tool, qshRow, lastLF, SQL_CHAR, isQshLen);
        tool_output_record_row_end(tool);
        lastLF = posLF + 1;
        posLF = ile_pgm_find_new_line(lastLF, FLAG_STR_COMPILE);
      }
      /* shift remain data */
      posLF = lastLF;
      lastLF = cmd_tmp + sizeof(cmd_tmp);
      if (posLF < lastLF) {
        strcpy(cmd_tmp, posLF);
        posLF = cmd_tmp;
        isQshLen = strlen(posLF);
        posLF = cmd_tmp + isQshLen;
        memset(posLF, 0, sizeof(cmd_tmp) - isQshLen);
      }
    } /* fetch loop */
    /* out remain data */
    ile_pgm_trim(cmd_tmp, sizeof(cmd_tmp), FLAG_STR_COMPILE);
    lastLF = cmd_tmp;
    isQshLen = strlen(lastLF);
    if (isQshLen) {
      posLF = cmd_tmp + isQshLen;
      isQshRow++;
      memset(qshRow,0,sizeof(qshRow));
      sprintf(qshRow,"R%d", isQshRow);
      posLF[0] = '\0';
      tool_output_record_row_beg(tool);
      tool_output_record_name_value(tool, qshRow, lastLF, SQL_CHAR, isQshLen);
      tool_output_record_row_end(tool);
    }
    tool_output_record_array_end(tool);
  }
  /* ======
   * rexx output 
   */
  else if (isRexx && sqlrc == SQL_SUCCESS) {
    /* query QTEMP.OUT456 */
    memset(query_string,0,sizeof(query_string));
    sprintf(query_string,"select SRCDTA from QTEMP.OUT%d",isRexx);
    sqlrc = SQLExecDirect(hstmt, query_string, (SQLINTEGER)SQL_NTS);
    col_len = sizeof(col_val);
    memset(col_val,0,sizeof(col_val));
    sqlrc = SQLBindCol((SQLHSTMT)hstmt,
                         1,
                         SQL_CHAR, 
                         col_val,
                         col_len,
                         &col_len);
    /* fetch */
    memset(cmd_tmp,0,sizeof(cmd_tmp));
    sqlrc = SQL_SUCCESS;
    tool_output_record_array_beg(tool);
    while (sqlrc == SQL_SUCCESS) {
      col_len = sizeof(col_val);
      memset(col_val,0,sizeof(col_val));
      sqlrc = SQLFetch(hstmt);
      if (sqlrc == SQL_NO_DATA_FOUND || sqlrc < SQL_SUCCESS ) {
        if (!fetch_recs) {
          tool_output_record_no_data_found(tool, 0);
        } else {
          sqlrc = SQL_SUCCESS;
        }
        break;
      }
      fetch_recs += 1;
      /* start name ("name":"value") */
      if (col_val[7]==':') {
        /* DEADBEE: remove */
        memcpy(col_val,&col_val[8],sizeof(col_val)-9);
        if (fetch_odd > 1) {
          tool_output_record_row_beg(tool);
          tool_output_record_name_value(tool, col_name, cmd_tmp, SQL_CHAR, col_len);
          tool_output_record_row_end(tool);
          /* rexx error? */
          if (!strcmp(col_name,"error")) {
            isRexxError = 1;
          }
        }
        fetch_odd = 1;
        memcpy(col_name, col_val, sizeof(col_val));
        ile_pgm_trim(col_name, sizeof(col_val), FLAG_STR_COMPILE);
        memset(cmd_tmp,0,sizeof(cmd_tmp));
      } else {
        /* DEADBEEF remove */
        memcpy(col_val,&col_val[8],sizeof(col_val)-9);
        fetch_odd += 1;
        strcat(cmd_tmp,col_val);
        ile_pgm_trim(cmd_tmp, sizeof(cmd_tmp), FLAG_STR_COMPILE);
      }
    } /* fetch loop */
    tool_output_record_array_end(tool);
  }
  /* rexx or qsh errors ? */
  if (isRexxError || isQshError) {
    sqlrc = tool_sql_errors(tool, hstmt, SQL_HANDLE_STMT, SQL_ERROR);
  }
  /* output */
  tool_output_cmd_end(tool);
  /* close */
  if (tcmd->hstmt) {
    sqlrc1 = SQLFreeHandle(SQL_HANDLE_STMT, tcmd->hstmt);
  }
  tcmd->hstmt = 0;
  if (hstmt) {
    /* maybe should ... DLTF FILE(QTEMP/OUT) */
    sqlrc1 = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
  }
  hstmt = 0;

  /* restore conn type (not support in memory for rexx or qsh) */
  tconn->conn_type = save_conn_type;

  return sqlrc;
}

IBM CVE-2017-5638

quifax, Apache Struts, & CVE-2017-5638 Vulnerability

Apache 2.4 vulnerabilities


<?php

$conn = db2_connect (  'IDEVU016', 'alan' , 'password' );
$sql = 'SELECT * FROM sysibm.tables  LIMIT ? OFFSET 20';
$stmt = db2_prepare($conn, $sql);



try {
    $result = db2_execute($stmt, [10]);
} catch(\Exception $e) {
    echo $e->getCode() . ' - ' . $e->getMessage() . '\n';
}

echo db2_stmt_error() . ' - ' . db2_stmt_errormsg();
var_dump($result);

die();
?>

SQLDescribeParam returns correct type for the LIMIT parameter:BIGINTEGER type 19
SQLBindParameter sends correct parameter value of 10
---
CLI TRACE:

SQLPrepare.78214.1508249757.1.tbeg +++success+++
SQLPrepare.78214.1508249757.1.walk dump_SQLPrepare (0 3 201634d4 2e)
SQLPrepare.78214.1508249757.1.walk SQLPrepare (3 201634d4 2e)
SQLPrepare.78214.1508249757.1.walk _php_db2_do_prepare (2 201634d4 2010c150 2e 0)
SQLPrepare.78214.1508249757.1.walk zif_db2_prepare (2 2010ace8 200f1984 0 1)
SQLPrepare.78214.1508249757.1.walk zend_do_fcall_common_helper_SPEC (?)
SQLPrepare.78214.1508249757.1.walk execute_ex (?)
SQLPrepare.78214.1508249757.1.walk zend_execute (?)
SQLPrepare.78214.1508249757.1.walk zend_execute_scripts (?)
SQLPrepare.78214.1508249757.1.walk php_execute_script (?)
SQLPrepare.78214.1508249757.1.walk do_cli (?)
SQLPrepare.78214.1508249757.1.walk main (?)
SQLPrepare.78214.1508249757.1.retn SQLRETURN sqlrc 0x0 (0) SQL_SUCCESS
SQLPrepare.78214.1508249757.1.parm SQLHSTMT hstmt 0x3 (3)
SQLPrepare.78214.1508249757.1.parm SQLCHAR* szSqlStr 0x201634d4 (538326228)
SQLPrepare.78214.1508249757.1.phex         201634d4 : 53454c454354202a2046524f4d207379 >SELECT * FROM sy<
SQLPrepare.78214.1508249757.1.phex         201634e4 : 7369626d2e7461626c657320204c494d >sibm.tables  LIM<
SQLPrepare.78214.1508249757.1.phex         201634f4 : 4954203f204f46465345542032300000 >IT ? OFFSET 20..<
SQLPrepare.78214.1508249757.1.phex         20163504 : 10617cad000000052016351020163504 >.a|..... .5. .5.<
SQLPrepare.78214.1508249757.1.phex         20163514 : 20163530201634b00000000000000000 > .50 .4.........<
SQLPrepare.78214.1508249757.1.parm SQLINTEGER cbSqlStr 0x2e (46)
SQLPrepare.78214.1508249757.1.tend +++success+++
SQLFreeStmt.78214.1508249757.1.tbeg +++success+++
SQLFreeStmt.78214.1508249757.1.walk dump_SQLFreeStmt (0 3 0)
SQLFreeStmt.78214.1508249757.1.walk SQLFreeStmt (3 0)
SQLFreeStmt.78214.1508249757.1.walk zif_db2_execute (2 2010c23c 200f1954 0 1)
SQLFreeStmt.78214.1508249757.1.walk zend_do_fcall_common_helper_SPEC (?)
SQLFreeStmt.78214.1508249757.1.walk execute_ex (?)
SQLFreeStmt.78214.1508249757.1.walk zend_execute (?)
SQLFreeStmt.78214.1508249757.1.walk zend_execute_scripts (?)
SQLFreeStmt.78214.1508249757.1.walk php_execute_script (?)
SQLFreeStmt.78214.1508249757.1.walk do_cli (?)
SQLFreeStmt.78214.1508249757.1.walk main (?)
SQLFreeStmt.78214.1508249757.1.retn SQLRETURN sqlrc 0x0 (0) SQL_SUCCESS
SQLFreeStmt.78214.1508249757.1.parm SQLHSTMT hstmt 0x3 (3)
SQLFreeStmt.78214.1508249757.1.parm SQLSMALLINT fOption 0x0 (0)
SQLFreeStmt.78214.1508249757.1.tend +++success+++
SQLNumParams.78214.1508249757.1.tbeg +++success+++
SQLNumParams.78214.1508249757.1.walk dump_SQLNumParams (0 3 2ff20b7c)
SQLNumParams.78214.1508249757.1.walk SQLNumParams (3 2ff20b7c)
SQLNumParams.78214.1508249757.1.walk zif_db2_execute (2 2010c23c 200f1954 0 1)
SQLNumParams.78214.1508249757.1.walk zend_do_fcall_common_helper_SPEC (?)
SQLNumParams.78214.1508249757.1.walk execute_ex (?)
SQLNumParams.78214.1508249757.1.walk zend_execute (?)
SQLNumParams.78214.1508249757.1.walk zend_execute_scripts (?)
SQLNumParams.78214.1508249757.1.walk php_execute_script (?)
SQLNumParams.78214.1508249757.1.walk do_cli (?)
SQLNumParams.78214.1508249757.1.walk main (?)
SQLNumParams.78214.1508249757.1.retn SQLRETURN sqlrc 0x0 (0) SQL_SUCCESS
SQLNumParams.78214.1508249757.1.parm SQLHSTMT hstmt 0x3 (3)
SQLNumParams.78214.1508249757.1.parm SQLSMALLINT* pcpar 0x2ff20b7c (804391804)
SQLNumParams.78214.1508249757.1.phex         2ff20b7c : 0001000000000000200e22d82ff20bd0 >........ ."./...<
SQLNumParams.78214.1508249757.1.phex         2ff20b8c : 2010bdc010033fc02010a140200f19c0 > .....?. ..@ ...<
SQLNumParams.78214.1508249757.1.phex         2ff20b9c : 200e22d8202bee70ffffff90200f1950 > .". +.p.... ..P<
SQLNumParams.78214.1508249757.1.phex         2ff20bac : 000000002ff20c18200e22d810064640 >..../... ."...F@<
SQLNumParams.78214.1508249757.1.phex         2ff20bbc : 2010b53c200f1a18200bf79000000002 > ..< ... .......<
SQLNumParams.78214.1508249757.1.tend +++success+++
SQLDescribeParam.78214.1508249757.1.tbeg +++success+++
SQLDescribeParam.78214.1508249757.1.walk dump_SQLDescribeParam (0 3 10001 2ff20a88 2ff20a8c 2ff20a90 2ff20a92)
SQLDescribeParam.78214.1508249757.1.walk SQLDescribeParam (3 10001 2ff20a88 2ff20a8c 2ff20a90 2ff20a92)
SQLDescribeParam.78214.1508249757.1.walk _php_db2_execute_helper (2010c150 2010c200 0 1)
SQLDescribeParam.78214.1508249757.1.walk zif_db2_execute (2 2010c23c 200f1954 0 1)
SQLDescribeParam.78214.1508249757.1.walk zend_do_fcall_common_helper_SPEC (?)
SQLDescribeParam.78214.1508249757.1.walk execute_ex (?)
SQLDescribeParam.78214.1508249757.1.walk zend_execute (?)
SQLDescribeParam.78214.1508249757.1.walk zend_execute_scripts (?)
SQLDescribeParam.78214.1508249757.1.walk php_execute_script (?)
SQLDescribeParam.78214.1508249757.1.walk do_cli (?)
SQLDescribeParam.78214.1508249757.1.walk main (?)
SQLDescribeParam.78214.1508249757.1.retn SQLRETURN sqlrc 0x0 (0) SQL_SUCCESS
SQLDescribeParam.78214.1508249757.1.parm SQLHSTMT hstmt 0x3 (3)
SQLDescribeParam.78214.1508249757.1.parm SQLSMALLINT ipar 0x1 (1)
SQLDescribeParam.78214.1508249757.1.parm SQLSMALLINT* pfSqlType 0x2ff20a88 (804391560)
SQLDescribeParam.78214.1508249757.1.phex         2ff20a88 : 0013ed7000000008000000012010ace8 >...p........ ...<
SQLDescribeParam.78214.1508249757.1.phex         2ff20a98 : 2ff20ab00000001e00000000ffffff90 >/...............<
SQLDescribeParam.78214.1508249757.1.phex         2ff20aa8 : 200f19502ff20ab02ff20bb02010bdc0 > ..P/.../... ...<
SQLDescribeParam.78214.1508249757.1.phex         2ff20ab8 : df8a69b00000000000000000f189dac8 >..i.............<
SQLDescribeParam.78214.1508249757.1.phex         2ff20ac8 : 2010c1502010c2000000000000000001 > ..P ...........<
SQLDescribeParam.78214.1508249757.1.parm SQLINTEGER* pcbColDef 0x2ff20a8c (804391564)
SQLDescribeParam.78214.1508249757.1.phex         2ff20a8c : 00000008000000012010ace82ff20ab0 >........ .../...<
SQLDescribeParam.78214.1508249757.1.phex         2ff20a9c : 0000001e00000000ffffff90200f1950 >............ ..P<
SQLDescribeParam.78214.1508249757.1.phex         2ff20aac : 2ff20ab02ff20bb02010bdc0df8a69b0 >/.../... .....i.<
SQLDescribeParam.78214.1508249757.1.phex         2ff20abc : 0000000000000000f189dac82010c150 >............ ..P<
SQLDescribeParam.78214.1508249757.1.phex         2ff20acc : 2010c200000000000000000100000001 > ...............<
SQLDescribeParam.78214.1508249757.1.parm SQLSMALLINT* pibScale 0x2ff20a90 (804391568)
SQLDescribeParam.78214.1508249757.1.phex         2ff20a90 : 000000012010ace82ff20ab00000001e >.... .../.......<
SQLDescribeParam.78214.1508249757.1.phex         2ff20aa0 : 00000000ffffff90200f19502ff20ab0 >........ ..P/...<
SQLDescribeParam.78214.1508249757.1.phex         2ff20ab0 : 2ff20bb02010bdc0df8a69b000000000 >/... .....i.....<
SQLDescribeParam.78214.1508249757.1.phex         2ff20ac0 : 00000000f189dac82010c1502010c200 >........ ..P ...<
SQLDescribeParam.78214.1508249757.1.phex         2ff20ad0 : 0000000000000001000000010000001e >................<
SQLDescribeParam.78214.1508249757.1.parm SQLSMALLINT* pfNullable 0x2ff20a92 (804391570)
SQLDescribeParam.78214.1508249757.1.phex         2ff20a92 : 00012010ace82ff20ab00000001e0000 >.. .../.........<
SQLDescribeParam.78214.1508249757.1.phex         2ff20aa2 : 0000ffffff90200f19502ff20ab02ff2 >...... ..P/.../.<
SQLDescribeParam.78214.1508249757.1.phex         2ff20ab2 : 0bb02010bdc0df8a69b0000000000000 >.. .....i.......<
SQLDescribeParam.78214.1508249757.1.phex         2ff20ac2 : 0000f189dac82010c1502010c2000000 >...... ..P .....<
SQLDescribeParam.78214.1508249757.1.phex         2ff20ad2 : 000000000001000000010000001e0000 >................<
SQLDescribeParam.78214.1508249757.1.tend +++success+++
SQLBindParameter.78214.1508249757.1.tbeg +++success+++
SQLBindParameter.78214.1508249757.1.walk dump_SQLBindParameter (0 3 10001 10001 10001 130013 8 0)
SQLBindParameter.78214.1508249757.1.walk SQLBindParameter (3 10001 10001 10001 130013 8 0 2010bc0c)
SQLBindParameter.78214.1508249757.1.walk _php_db2_bind_data (2010c150 2010c100 2010c200)
SQLBindParameter.78214.1508249757.1.walk _php_db2_execute_helper (2010c150 2010c200 0 1)
SQLBindParameter.78214.1508249757.1.walk zif_db2_execute (2 2010c23c 200f1954 0 1)
SQLBindParameter.78214.1508249757.1.walk zend_do_fcall_common_helper_SPEC (?)
SQLBindParameter.78214.1508249757.1.walk execute_ex (?)
SQLBindParameter.78214.1508249757.1.walk zend_execute (?)
SQLBindParameter.78214.1508249757.1.walk zend_execute_scripts (?)
SQLBindParameter.78214.1508249757.1.walk php_execute_script (?)
SQLBindParameter.78214.1508249757.1.walk do_cli (?)
SQLBindParameter.78214.1508249757.1.walk main (?)
SQLBindParameter.78214.1508249757.1.retn SQLRETURN sqlrc 0x0 (0) SQL_SUCCESS
SQLBindParameter.78214.1508249757.1.parm SQLHSTMT hstmt 0x3 (3)
SQLBindParameter.78214.1508249757.1.parm SQLSMALLINT ipar 0x1 (1)
SQLBindParameter.78214.1508249757.1.parm SQLSMALLINT fParamType 0x1 (1)
SQLBindParameter.78214.1508249757.1.parm SQLSMALLINT fCType 0x1 (1)
SQLBindParameter.78214.1508249757.1.parm SQLSMALLINT fSQLType 0x13 (19)
SQLBindParameter.78214.1508249757.1.parm SQLINTEGER pLen 0x8 (8)
SQLBindParameter.78214.1508249757.1.parm SQLSMALLINT pScale 0x0 (0)
SQLBindParameter.78214.1508249757.1.parm SQLPOINTER pData 0x2010bc0c (537967628)

====
IBM i DB2 APAR -- should have implicit convert of BIGINT '10' to bigint (number)
====

SQLBindParameter.78214.1508249757.1.phex         2010bc0c : 313000506c7400000000010900000011 >10.Plt..........<
SQLBindParameter.78214.1508249757.1.phex         2010bc1c : 2010bd242010c0dc200ef78400000000 > ..$ ... .......<
SQLBindParameter.78214.1508249757.1.phex         2010bc2c : 00000000000000000000000000000000 >................<
SQLBindParameter.78214.1508249757.1.phex         2010bc3c : 00000000000000000000000000000000 >................<
SQLBindParameter.78214.1508249757.1.phex         2010bc4c : 00000000000000000000000000000000 >................<
SQLBindParameter.78214.1508249757.1.parm SQLINTEGER cbValueMax 0x3 (3)
SQLBindParameter.78214.1508249757.1.parm SQLINTEGER* pcbValue 0x2010c110 (537968912)
SQLBindParameter.78214.1508249757.1.phex         2010c110 : fffffffd000000000000000000000001 >................<
SQLBindParameter.78214.1508249757.1.phex         2010c120 : 00000001000000002010bf9800000000 >........ .......<
SQLBindParameter.78214.1508249757.1.phex         2010c130 : 00000019000000390000000a00000010 >.......9........<
SQLBindParameter.78214.1508249757.1.phex         2010c140 : 00000000000000000000004d00000019 >...........M....<
SQLBindParameter.78214.1508249757.1.phex         2010c150 : 00000002000000030000000100000000 >................<
SQLBindParameter.78214.1508249757.1.tend +++success+++
SQLExecute.78214.1508249757.1.tbeg ---error---
SQLExecute.78214.1508249757.1.walk dump_SQLExecute (ffffffff 3)
SQLExecute.78214.1508249757.1.walk SQLExecute (3)
SQLExecute.78214.1508249757.1.walk zif_db2_execute (2 2010c23c 200f1954 0 1)
SQLExecute.78214.1508249757.1.walk zend_do_fcall_common_helper_SPEC (?)
SQLExecute.78214.1508249757.1.walk execute_ex (?)
SQLExecute.78214.1508249757.1.walk zend_execute (?)
SQLExecute.78214.1508249757.1.walk zend_execute_scripts (?)
SQLExecute.78214.1508249757.1.walk php_execute_script (?)
SQLExecute.78214.1508249757.1.walk do_cli (?)
SQLExecute.78214.1508249757.1.walk main (?)
SQLExecute.78214.1508249757.1.retn SQLRETURN sqlrc 0xffffffff (-1) SQL_ERROR
SQLExecute.78214.1508249757.1.parm SQLHSTMT hstmt 0x3 (3)
SQLExecute.78214.1508249757.1.tend ---error---
SQLGetDiagRec.78214.1508249757.1.tbeg +++success+++
SQLGetDiagRec.78214.1508249757.1.walk dump_SQLGetDiagRec (0 30003 3 10001 2ff20870 2ff20a88 2ff2066c 2010201)
SQLGetDiagRec.78214.1508249757.1.walk SQLGetDiagRec (30003 3 10001 2ff20870 2ff20a88 2ff2066c 2010201 2ff20a8c)
SQLGetDiagRec.78214.1508249757.1.walk _php_db2_check_sql_errors (3 3c200 ffffffff 1 0 ffffffff 1ffff)
SQLGetDiagRec.78214.1508249757.1.walk zif_db2_execute (2 2010c23c 200f1954 0 1)
SQLGetDiagRec.78214.1508249757.1.walk zend_do_fcall_common_helper_SPEC (?)
SQLGetDiagRec.78214.1508249757.1.walk execute_ex (?)
SQLGetDiagRec.78214.1508249757.1.walk zend_execute (?)
SQLGetDiagRec.78214.1508249757.1.walk zend_execute_scripts (?)
SQLGetDiagRec.78214.1508249757.1.walk php_execute_script (?)
SQLGetDiagRec.78214.1508249757.1.walk do_cli (?)
SQLGetDiagRec.78214.1508249757.1.walk main (?)
SQLGetDiagRec.78214.1508249757.1.retn SQLRETURN sqlrc 0x0 (0) SQL_SUCCESS
SQLGetDiagRec.78214.1508249757.1.parm SQLSMALLINT hType 0x3 (3)
SQLGetDiagRec.78214.1508249757.1.parm SQLINTEGER hndl 0x3 (3)
SQLGetDiagRec.78214.1508249757.1.parm SQLSMALLINT rcdNum 0x1 (1)
SQLGetDiagRec.78214.1508249757.1.parm SQLCHAR* SQLstate 0x2ff20870 (804391024)
SQLGetDiagRec.78214.1508249757.1.phex         2ff20870 : 303730303600ff900000000000000000 >07006...........<
SQLGetDiagRec.78214.1508249757.1.phex         2ff20880 : 00000000000000000000000000000000 >................<
SQLGetDiagRec.78214.1508249757.1.phex         2ff20890 : 00000000000000000000000000000000 >................<
SQLGetDiagRec.78214.1508249757.1.phex         2ff208a0 : 00000000000000000000000000000000 >................<
SQLGetDiagRec.78214.1508249757.1.phex         2ff208b0 : 00000000000000000000000000000000 >................<
SQLGetDiagRec.78214.1508249757.1.parm SQLINTEGER* SQLcode 0x2ff20a88 (804391560)
SQLGetDiagRec.78214.1508249757.1.phex         2ff20a88 : fffffed3002a0008000000012010ace8 >.....*...... ...<
SQLGetDiagRec.78214.1508249757.1.phex         2ff20a98 : 2ff20ab00000001effffffffffffff90 >/...............<
SQLGetDiagRec.78214.1508249757.1.phex         2ff20aa8 : 200f19502ff20ab02ff20bb02010bdc0 > ..P/.../... ...<
SQLGetDiagRec.78214.1508249757.1.phex         2ff20ab8 : df8a6c740000000000000000f189dac8 >..lt............<
SQLGetDiagRec.78214.1508249757.1.phex         2ff20ac8 : 000000030003c200ffffffff00000001 >................<
SQLGetDiagRec.78214.1508249757.1.parm SQLCHAR* msgText 0x2ff2066c (804390508)
SQLGetDiagRec.78214.1508249757.1.phex         2ff2066c : 496e707574207661726961626c65202a >Input variable *<
SQLGetDiagRec.78214.1508249757.1.phex         2ff2067c : 4e206f7220617267756d656e74203120 >N or argument 1 <
SQLGetDiagRec.78214.1508249757.1.phex         2ff2068c : 6e6f742076616c69642e000000000000 >not valid.......<
SQLGetDiagRec.78214.1508249757.1.phex         2ff2069c : 00000000000000000000000000000000 >................<
SQLGetDiagRec.78214.1508249757.1.phex         2ff206ac : 00000000000000000000000000000000 >................<
SQLGetDiagRec.78214.1508249757.1.parm SQLSMALLINT bLength 0x201 (513)
SQLGetDiagRec.78214.1508249757.1.parm SQLSMALLINT* sLength 0x2ff20a8c (804391564)
SQLGetDiagRec.78214.1508249757.1.phex         2ff20a8c : 002a0008000000012010ace82ff20ab0 >.*...... .../...<
SQLGetDiagRec.78214.1508249757.1.phex         2ff20a9c : 0000001effffffffffffff90200f1950 >............ ..P<
SQLGetDiagRec.78214.1508249757.1.phex         2ff20aac : 2ff20ab02ff20bb02010bdc0df8a6c74 >/.../... .....lt<
SQLGetDiagRec.78214.1508249757.1.phex         2ff20abc : 0000000000000000f189dac800000003 >................<
SQLGetDiagRec.78214.1508249757.1.phex         2ff20acc : 0003c200ffffffff0000000100000000 >................<
SQLGetDiagRec.78214.1508249757.1.tend +++success+++




   IBM's CLI findings:
                            In regards to the SQ99999 code 9 My CLI expert
                 states:

                            The SQ99999 RC9 Argument out of range
                 indicates that the third
                            or second
                            argument into SQLSetConnectAttr: PROC
                 (CONNHNDL,ATT,VAL,LEN) is
                            invalid
                            (either the value is invalid or the length is
                 invalid)

                            What I see in the CLI traces are a number of
                 these:

                            [0000426E:0000000000000288][06-14-17
                 07:03:49.373424]

                            ENTER: SQLSetConnectAttr

                              SQLHDBC       2

                              SQLINTEGER    10204 (UNKNOWN)

                              SQLPOINTER
                 80000000000000000000800080247370 (0)

                              SQLINTEGER    -3

                            -

                            [0000426E:0000000000000288][06-14-17
                 07:03:49.379752](0.006328)

                            EXIT:  SQLSetConnectAttr with return code -1
                 (SQL_ERROR)

                              SQLHDBC       2

                              SQLINTEGER    10204 (UNKNOWN)

                              SQLPOINTER
                 80000000000000000000800080247370 (0)

                              SQLINTEGER    -3



                            These would cause errors such as we see in the
                 job log:

                            SQ99999    Diagnostic              30
                 11/06/17
                            10:29:09.691779  QSQCLI
                            QSYS        *STMT    QP2USER2    QSYS
                 *STMT

                                                                From
                            module . . . . . . . . :
                                                                SQLSCA

                                                                From
                            procedure  . . . . . . :
                            SQLSetConnectAttr


                            Statement . . . . . . . . . :
                                                                13181

                                                                To
                            module . . . . . . . . . :
                                                                QP2API

                                                                To
                            procedure  . . . . . . . :
                            runpase_common__FiPvT2


                            Statement . . . . . . . . . :   5


                 Message . . . . :   Error
                            occurred
                                                                in
                            SQL Call Level Interface


                 Cause . . . . . :   A
                            procedure call
                            encountered an error.  The error code is 9. 9
                 - Argument value
                            not valid.

                            Here is the list of SQLCLI connection
                 attributes:


                 https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/cli/rzadphdhed.htm


                            10204 is not listed. It looks like 10119 is
                 about the highest
                            integer
                            value we support. What connection attribute is
                 Zend trying to
                            set when
                            that
                            failure occurs?

                            It seems they are trying to set some
                 connection attribute that
                            is not
                            supported by SQL CLI.

Cool ... in/out parms ... RPG writing into your php $vars (correct ccsid both ends) ... tee hee, says mad ranger scientist, let's see java try that with type rpg o (no way dudes). I will try to get project open soon.

======
run via pase shell (ssh)
======
bash-4.3$ system 'call vlang/test0001'
before ILE call ... hi from php
after ILE call ... hi from ILE RPG free. The most wonderful.


======
php - ilehello.php
======
<?php
$ile = extension_loaded ('ile');
if (!$ile) {
  echo "ile extension not loaded.\n";
}
$inout = "hi from php";
echo "before ILE call ... $inout\n";
ile_callback("IleCallMe",$inout);
echo "after ILE call ... $inout\n";

?>

===
rpg - test0001
===
     H AlwNull(*UsrCtl)

      /copy virt_h
      /copy vphp_h

       // *************************************************
       // php script to run
       // *************************************************
       DCL-C PHP_HELLO CONST('include "/usr/local/zendsvr6/share+
       /vlang/php/helloile.php";');

       // *************************************************
       // internal
       // *************************************************
       dcl-pr IleCallMe;
          hi CHAR(100);
          rpgVer FLOAT(8);
          me CHAR(50);
          meVer INT(10);
       end-pr;

       // *************************************************
       // main program
       // *************************************************
       PHPStart32();
       VirtualAddCallBack('IleCallMe':%paddr(IleCallMe));
       VirtualAddCallBackDesc('IleCallMe':VIRT_CHAR:100:0:VIRT_IO_BOTH);
       VirtualAddCallBackDesc('IleCallMe':VIRT_FLOAT8:0:0:VIRT_IO_BOTH);
       VirtualAddCallBackDesc('IleCallMe':VIRT_CHAR:50:0:VIRT_IO_BOTH);
       VirtualAddCallBackDesc('IleCallMe':VIRT_INT10:0:0:VIRT_IO_BOTH);
       PHPScript32(PHP_HELLO);
       PHPStop();
       return;

       // *************************************************
       // PHP callback location
       // *************************************************
       dcl-proc IleCallMe export;
         dcl-pi *N;
          hi CHAR(100);
          rpgVer FLOAT(8);
          me CHAR(50);
          meVer INT(10);
         end-pi;

         hi = 'hi from ILE RPG free.';
         rpgVer = 4.0;
         me = 'VLANG';
         meVer = 1;

       end-proc; 




vphp.rpgle:



       // *************************************************
       // PHP API -- start 32bit php
       // *************************************************
       dcl-proc PHPStart32 export;
         dcl-pi *N IND;
          ini CHAR(65500) VALUE options (*nopass);
         end-pi;
         DCL-S rcb IND INZ(*OFF);
         dcl-s pgm CHAR(65500) inz(*BLANKS);
         dcl-s arg CHAR(65500) dim(8) inz(*BLANKS);
         dcl-s env CHAR(65500) dim(8) inz(*BLANKS);

         pgm = PHP_ARG0_PGM;

         arg(1) = PHP_ARG1_CHAT;
         // TBD
         // arg(2) -c
         // arg(3) /path/php.ini

         env(1) = PHP_ENV1_PATH;
         env(2) = PHP_ENV2_LIBPATH;
         env(3) = PHP_ENV3_ATTACH;

         rcb = PaseStart32(pgm:arg:env);

         VirtualSetLanguage(%paddr(PHPVirtualCall32));

         return rcb;
       end-proc; 



       // *************************************************
       // PHP API -- PASE lang callback copy
       // *************************************************
       dcl-proc PHPVirtualCall32 export;
         dcl-pi *N IND;
          iCall POINTER(*PROC) VALUE;
          argc INT(10) VALUE;
          argv POINTER dim(VIRT_CALLARG_MAX) VALUE;
          ileDesc likeds(virtVar_t) dim(VIRT_CALLARG_MAX);
          paseDesc likeds(virtVar_t) dim(VIRT_CALLARG_MAX);
         end-pi;
         dcl-s rcb IND INZ(*ON);
         dcl-pr ClientCallBack IND EXTPROC(iCall);
          arg1 POINTER VALUE;
          arg2 POINTER VALUE;
          arg3 POINTER VALUE;
          arg4 POINTER VALUE;
          arg5 POINTER VALUE;
          arg6 POINTER VALUE;
          arg7 POINTER VALUE;
          arg8 POINTER VALUE;
          arg9 POINTER VALUE;
          arg10 POINTER VALUE;
          arg11 POINTER VALUE;
          arg12 POINTER VALUE;
          arg13 POINTER VALUE;
          arg14 POINTER VALUE;
          arg15 POINTER VALUE;
          arg16 POINTER VALUE;
          arg17 POINTER VALUE;
          arg18 POINTER VALUE;
          arg19 POINTER VALUE;
          arg20 POINTER VALUE;
          arg21 POINTER VALUE;
          arg22 POINTER VALUE;
          arg23 POINTER VALUE;
          arg24 POINTER VALUE;
          arg25 POINTER VALUE;
          arg26 POINTER VALUE;
          arg27 POINTER VALUE;
          arg28 POINTER VALUE;
          arg29 POINTER VALUE;
          arg30 POINTER VALUE;
          arg31 POINTER VALUE;
          arg32 POINTER VALUE;
         end-pr;
         dcl-s rc INT(10) inz(0);
         dcl-s i INT(10) inz(0);
         dcl-s ilev POINTER dim(VIRT_CALLARG_MAX) INZ(*NULL);
         dcl-s ileCCSID INT(10) inz(0);
         dcl-s paseCCSID INT(10) inz(0);

         // TBD set the CCSID
         ileCCSID = 0;
         paseCCSID = PaseLstCCSID();

         // copy in
         for i = 1 to argc;
           rc = convToILE(argv(i):%addr(ilev(i))
                :ileDesc(i):paseDesc(i)
                :ileCCSID:paseCCSID);
         endfor;

         // make call
         rcb = ClientCallBack(
          ilev(1):ilev(2):ilev(3):ilev(4):ilev(5):
          ilev(6):ilev(7):ilev(8):ilev(9):ilev(10):
          ilev(11):ilev(12):ilev(13):ilev(14):ilev(15):
          ilev(16):ilev(17):ilev(18):ilev(19):ilev(20):
          ilev(21):ilev(22):ilev(23):ilev(24):ilev(25):
          ilev(26):ilev(27):ilev(28):ilev(29):ilev(30):
          ilev(21):ilev(22));

         // copy in
         for i = 1 to argc;
           rc = convToPase(%addr(argv(i)):ilev(i)
                :ileDesc(i):paseDesc(i)
                :ileCCSID:paseCCSID);
         endfor;

         return *ON;
       end-proc; 



https://github.com/alanseiden


     P cpyInDec        B
     D cpyInDec        PI             1N
     D   valPtrP                       *
     D   node                              likeds(xmlNode_t)
      * vars
     D rc              s              1N   inz(*OFF)
     D f64             s              8f   inz(0.0)
     D ptrP            s               *   inz(*NULL)
     D sz              s             10i 0 inz(0)
     D strP            s               *   inz(*NULL)
     D strSz           s             10i 0 inz(0)
      /free
       // copy in faster way ...
       rc = cacScanF64(*OFF:CAC_F64_SCAN_STR_SAME:valPtrP
                   :f64:ptrP:sz:strP:strSz
                   :node.xmlStrP
                   :node.xmlStrSz
                   :node.xmlAttr
                   :node.xmlDigits
                   :node.xmlFrac
                   :node.pgmValSz);
       if rc = *ON;
         cpybytes(valPtrP:ptrP:sz);
         return *ON;
       endif;

       // copy in slower way ...
       f64 = %float(%str(node.xmlStrP:node.xmlStrSz));

       // call ILE converter ...
       select;
       // packed decimal
       when node.xmlAttr = XML_ATTR_VAL_P;
         QXXDTOP(valPtrP:node.xmlDigits:node.xmlFrac:f64);
       // zoned decimal
       when node.xmlAttr = XML_ATTR_VAL_S;
         QXXDTOZ(valPtrP:node.xmlDigits:node.xmlFrac:f64);
       // other?
       other;
       endsl;

       // save for faster way ...
       cacAddF64(*OFF:valPtrP:f64
                   :node.xmlStrP
                   :node.xmlStrSz
                   :node.xmlAttr
                   :node.xmlDigits
                   :node.xmlFrac
                   :node.pgmValSz);

       return *ON;
      /end-free
     P                 E

https://bitbucket.org/litmis/ibmichroot


// This uses the submitting JOBD but overrides jobq
$conn->setOptions(array("sbmjobCommand"=>"SBMJOB CMD(CALL PGM(ZENDSVR/XMLSERVICE) PARM('/tmp/EBIZDEV2')) JOB(XTKITDEV) JOBQ(zendsvr/zsvr_jobq)");

<script>
<sbmjob>SBMJOB CMD(CALL PGM(ZENDSVR/XMLSERVICE) PARM('/tmp/EBIZDEV2')) JOB(XTKITDEV) JOBQ(zendsvr/zsvr_jobq)</sbmjob>
<pgm name....
</script>

QP0ZSPWP QSECOFR BCI .0 PGM-authme THDW (wrkactjob)
> xlc -g -o authme authme.c 
> chown qsecofr authme
> chmod +s authme
> authme

QP0ZSPWP ADC BCI .0 PGM-authmenot THDW (wrkactjob)
> xlc -g -o authmenot authme.c
> chown ranger authmenot
> authmento

ls -l
-rwsr-sr-x    1 qsecofr  0              6953 Sep  9 12:02 authme
-rwxr-xr-x    1 ranger   0              6953 Sep  9 12:07 authmenot

e authme.c
#include <stdio.h>
int main(int argc, char * argv[]){
  printf("I am a super program, i am.\n");
  sleep(30);
}

>> Unsolicited hint … i have used XMLSERVICE XMLCGI with Apache https many times before, but there is a PHP trick in itoolkit.php … adding … verify_peer / verify_peer_name

    public function restcall() {
        /*Call xmlservice with accumulated input XML.

        Args:
          none

        Returns:
          none
        */
        $postdata = http_build_query(
        array(
        'db2'=>$this->db2,
        'uid'=>$this->uid,
        'pwd'=>$this->pwd,
        'ipc'=>$this->ipc,
        'ctl'=>$this->ctl + " *cdata",
        'xmlin'=>$this->xml_in(),
        'xmlout'=>$this->siz
        )
       );
       $opts=array('http'=>
        array(
        'method'=>'POST',
        'header'=>'Content-type: application/x-www-form-urlencoded',
        'content'=>$postdata
        ),
       );
       if (strpos($this->url,"ttps") > 0) {
         $opts['ssl'] = array(
          "verify_peer"=>false,
          "verify_peer_name"=>false);
       }
       $context = stream_context_create($opts);
       $this->domo = file_get_contents($this->url, false, $context);
    }

‘sbmjobParams’ => ‘’, // XMLSERVICE itself will provide good defaults in most cases (in production ZENDSVR(6)/ZSVR_JOBD/XTOOLKIT. In test mode, QSYS/QSRVJOB/XTOOLKIT). See PLUGCONF1 and 2

‘sbmjobCommand’ => ‘’, // optional complete override of SBMJOB command when new toolkit job is submitted

      *----------------------------------------------------
      * -- override default XMLSERVICE client/server spawn child behaviour
      * *sbmjob[(lib/jobd/job/asp)] 
      *    - sbmjob job (instead of XMLSERVICE default spawn)
      *      example: $ctl="*sbmjob";
      *      example: $ctl="*sbmjob(QSYS/QSRVJOB/XTOOLKIT)";
      *      example: $ctl="*sbmjob(ZENDSVR/ZSVR_JOBD/XTOOLKIT)";
      *      - default values provided plugconf.rpgle
      *      - optional asp INLASPGRP(ASP1) (added 1.6.5)
      *      -- Notes: 
      *         - See embedded XML overrides for user full control
      *           of XMLSERVICE start behavior SBMJOB settings


      *****************************************************
      * embedded XML control overrides and function
      *****************************************************
      * sbmjob full user override of SBMJOB for XMLSERVICE start-up  -- (1.7.0+)
      *  <sbmjob>SBMJOB CMD(CALL PGM(ZENDSVR/XMLSERVICE) PARM('/tmp/override'))</sbmjob>      
      *  Where SBMJOB can be any user settings (cut/paste green screen command) ...
      *   ... required parameters for for XMLSERVICE to start CALL + PARM
      *   example:
      *       CMD(CALL PGM(ZENDSVR/XMLSERVICE) PARM('/tmp/xxxxxx')) <-- xmlservice test lib
      *       -- or --
      *       CMD(CALL PGM(ZENDSVR/XMLSERVICE) PARM('/tmp/xxxxxx')) <-- Zend Server production lib
      *       -- all other sbmjob parms at your control --
      *   Note: 
      *   - SBMJOB full control allows user to set any type of LIBL,
      *     or SBMJOB options, or even custom PGM to call XMLSERVICE
      *****************************************************


       if sUsrSbmJob <> *BLANKS;
         // user set SBMJOB
         cmdstr = sUsrSbmJob;
       else;
         // -------------
         // execute command
         // SBMJOB CMD(CALL PGM(PLUGSBMLIB/PLUGSBMPGM)
         //   PARM('/tmp/ranger')) JOBD(ZENDSVR/ZSVR_JOBD)
         //   PRTDEV(*JOBD) OUTQ(*JOBD) INLLIBL(*JOBD) 
         //   INLASPGRP(*JOBD) SPLFACN(*JOBD)
         mylib = confSBMLIB();
         mypgm = confSBMPGM();
         cmdstr = 'SBMJOB CMD(CALL PGM(' 
              + %trim(mylib) 
              + '/' 
              + %trim(mypgm) 
              + ')'
              + ' PARM('
              + '''' 
              + %trim(ipcPathBlk) 
              + '''' 
              + '))'
              + ' JOB('
              + %trim(ipcDoFlags.doSbmNam) 
              + ')'
              + ' JOBD('
              + %trim(ipcDoFlags.doSbmLib) 
              + '/' 
              + %trim(ipcDoFlags.doSbmJobd);
         // INLASPGRP(ASP1) (1.6.5)
         if ipcDoFlags.doSbmAsp <> *BLANKS;
           cmdstr = %trim(cmdstr)
              + ' INLASPGRP('
              + %trim(ipcDoFlags.doSbmAsp) 
              + ')';
         endif;
         cmdstr = %trim(cmdstr) + ')';
         // add options for SBMJOB
         for i = 1 to SBMNBR;
           cmdstr = %trim(cmdstr) + ' ' + %trim(SBMARRAY(i));
         endfor;
       endif;
       len = %len(%trim(cmdstr));
       cmdexec(cmdstr:len);



     DSBMOPTS          ds
     D sbm1                          50    inz('CURLIB(*CURRENT)')
     D                               50    inz('INLLIBL(*CURRENT)')
     D                               50    inz('SRTSEQ(*CURRENT)')
     D                               50    inz('LANGID(*CURRENT)')
     D                               50    inz('CNTRYID(*CURRENT)')
     D                               50    inz('CCSID(*CURRENT)')
     D SBMNBR          c                   %div(%size(SBMOPTS):%size(sbm1)) 
     D pSBMOPTS        s               *   inz(%addr(SBMOPTS))
     D SBMARRAY        s             50    dim(SBMNBR) based(pSBMOPTS)


Working on chroot RPMs

older info

    1)      I can (and do) authenticate in the apache server using Kerberos.  (Doesn’t the Apache Server run in the PASE environment?)

    2)      After authenticating, my credentials are stored in php in the $_SERVER array.  

        a.      Apache Config: <Directory /> 
          Require valid-user 
              AuthType KERBEROS
            PasswdFile %%KERBEROS%%
            UserID %%CLIENT%%
            ProfileToken on
            Options None
            Order deny,allow
            Allow From ALL   <LimitExcept GET HEAD OPTIONS TRACE POST> 
              </LimitExcept> </Directory>

        b.      PHP Script:
        <?php 
            while (list($var,$value) = each ($_SERVER)) {
            echo "$var => $value <br>";
            } ?>

            c.      Results:
            ZendEnablerConfig => /www/zendsvr6/conf/fastcgi.conf
            PHPRC => /usr/local/zendsvr6/etc/
            PHP_FCGI_CHILDREN => 10
            PHP_FCGI_MAX_REQUESTS => 0
            CCSID => 1208
            LANG => C
            INSTALLATION_UID => 100313092601
            LDR_CNTRL => MAXDATA=0x40000000
            ZEND_TMPDIR => /usr/local/zendsvr6/tmp
            TZ => 6,M3.2.0,M11.1.0
            LIBPATH => /usr/local/zendsvr6/lib
            DB2NOEXITLIST => TRUE
            HTTP_AUTHORIZATION => Negotiate YIIGhwYGKwYBBQUCoIIGezCCBnegMDAuBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICHgYKKwYBBAGCNwICCqKCBkEEggY9YIIGOQYJKoZIhvcSAQICAQBuggYoMIIGJKADAgEFoQMCAQ6iBwMFACAAAACjggSrYYIEpzCCBKOgAwIBBaENGwtGQVJFV0FZLkNPTaIjMCGgAwIBAqEaMBgbBEhUVFAbEGMzcG8uZmFyZXdheS5jb22jggRmMIIEYqADAgEXoQMCAQOiggRUBIIEUFf6YU4yVNAx6PPsnun67mFldaSUuKRfQveQNFOIJ8n8nxVdKpxkF9VkPriWMF8aImdY9xB3eZYdCJTJmtAMp4WMLdGIC0GZHu/aBo5kYiPI/Ysg8H05/mL7seUT5gdl16Z/PsbV3UEiwO7F1QqAvCghzU8ncbjI4rtv1E6b31MqtDqoyozhybb8Cb+7z7M9S06nqQKaTE30BmNa8g6kmS+vcPE6CxXKeoKRNsn2Mls470pQUGxpoiOQWhL0c5Bv/bP6QQDnZG9A2CEqcY3V86nvf3q5Z5rLon6rf+U4aM9Jm4a25yi1JaxU5Mq1ZWNTrtNYlmS1X5iw/sZwxpgG2TIbicCu8PQkhcZa7OSfSU4BSWeO0Thji7IKxmevG3CJRjWfDSB1Vt26ao2N1P21a8ZzqacCyZUehMyUpVPTcLdEhCZ+8OdRqPix55bnUWg7HHcOj5WcvKQKQcfphoIuhkHZaE5pRd/TulB/J/nE26aqudoF076SfmLmEYhL7PZdM0/p4HiK5VFk++Q3YN/4ZEEVs/sjR6FGc15fxM814BotBY7yEoVyWoeGSnlIQjOQjrK1XJAQeGQZ6lXFy+mn0QAdzmBMWa3VBQVU3YVjclpmhcQi8E3d3D3+YSj9WrFsAfUslsic1NF/F0DhokeAXlB4jTk7Ao001FeDPom+P445C/EWMF3YW2Q0hnKhLe elaQYgQzaJI4AR68abXwG4IwBRGC0DOWaNG/zxQuiZNbBo6Yj5OKCTabNJKGXbADr9TndhSxkYUZlDzOYd4zniI4NkPUWewg6BlSRYcIJRM3PTZo8iwKkVcp0ZunPVZvBRfWIdclglKu46S183jjeD5fcrgs78OvIo6lJ0djL6QnAjjCXtTgjBCWNitdsFkK0CEISRSqlQQTqtzZeLwV/oFD1MrD6WZDJupozdrGak3Tq/6AhX5ckRq1pykLF/rnODtnwUK1/OqkJa8t/JprfJtFpTKFi4e7AuGzkyWjmOoInWA5CV9IFp9yScpwbXBdwe//ETnvOQ1Iw3cvAanDAK5qY2vB3k6Tlab6rqQx4c28WbSk7ZF5oAqVM0Zl2Ul19vCn/mCoxgL32cc7UbDuEheneORDbHiMeiOzbud18q32W7hNS+NwKVU1ojEDEg7B6Tz6uHoRdnwSdEF4q8Y+TcrLg2AgEYcfzQJQ1MzQqklzawxpKyxsYarMMtYeIbqdimJnPvfgdJTc3TSsTiYKHQQmyjCKgISbGcN0uWtba8al2qcBELCUwqM2BORynJnMf9s1cwVHCwNCWXwzaafvrIqH7afDMqebn8pSsCFmhgO/MqSFQUV8FNjrhrP3mp5yh/kyZuGJAXlShr4VVF6V/GP5bclkaVsWulwm/BWdSiOOGoTNUc5SWd/5z5g6RRO9EQuTBD+/nKs90pW+epCt3K10WK5N56QFF3VVVxasAPFgZeTPXmawdi9vA4Iv34wkA3rKSCAV4wggFaoAMCAReiggFRBIIBTYwT1FquP0cgixWawHSWLpUDApcd1MLc0AvoAmGPVVS3qKqhK+QuuUtkaXmF4cMHHSV8fb+GU8iJ7F34G7ghZqeMSa9QmZuhn6HH/C7N1G03HzP6uTixihXW4gIeflhhezWc9c4URVfAftS2usc9F0qH2UURPgFF/LBCLeFqjzNTB1nbS3F85cmIHZcfDwMY v2E7jD/PFa4ksmBz+9yMteEQECqI4G0v4CD95r0nIZjR6GCwb39S2GOuOQV2wzuniCXWSAhtyYeG1tfbxXUedJ4V3PWope2kLM9AtzbgNa3GsCQYQPw+XHCw6eCWjb7vtxRaal5Df4NHRbR50GykQa5WLY6aIo0UGnb4769wg79kNn4rKzt/HdQ7fA9EgOGGpaJfFTstNwXS41VyAwSJd2fn0gFBi4EDSWEKmg1O0dzDRLVld7rMUX8M/FmJKQ==
            RULE_FILE => conf/httpd.conf
            DOCUMENT_URI => /printserver.php
            SCRIPT_NAME => /printserver.php
            REQUEST_URI => /printserver.php
            QUERY_STRING =>
            REQUEST_METHOD => GET
            SERVER_PROTOCOL => HTTP/1.1
            GATEWAY_INTERFACE => CGI/1.1
            AUTH_TYPE => Kerberos
   REMOTE_USER => jstagliano@FAREWAY.COM 
            REMOTE_PORT => 51651
            DOCUMENT_NAME => /usr/local/zendsvr6/var/apps/http/c3po.fareway.com/10980/_docroot_/printserver.php
            SCRIPT_FILENAME => /usr/local/zendsvr6/var/apps/http/c3po.fareway.com/10980/_docroot_/printserver.php
            SERVER_ADMIN => [no address given]
            DOCUMENT_ROOT => /usr/local/zendsvr6/var/apps/http/c3po.fareway.com/10980/_docroot_
            REMOTE_ADDR => 10.55.0.106
            SERVER_PORT => 10980
            SERVER_ADDR => 10.40.0.153
            SERVER_NAME => c3po.fareway.com
            SERVER_SOFTWARE => Apache
            SERVER_SIGNATURE =>
            PATH => /bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin
   HTTP_AS_AUTH_PROFILETKN => K5NuWpSDzMCp+ZPk81m/429/6z1J6yUa6le1QQj2ZL4=
            HTTP_COOKIE => SmurfID=00204a02b8b24a78a71a0417a990b9280aff7d6b29dbad8df7100ecf744e2206; CSUUID_EC=f9cb1b2a-efda-368c-f064-2ebfe4f4bb1c; PHPSESSID=gtkj33p9u5crn98vlbh5f3bmgdjfoqit
            HTTP_ACCEPT_LANGUAGE => en-US,en;q=0.8
            HTTP_ACCEPT_ENCODING => gzip, deflate, sdch
            HTTP_USER_AGENT => Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36
            HTTP_ACCEPT => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
            HTTP_CACHE_CONTROL => max-age=0
            HTTP_CONNECTION => keep-alive
            HTTP_HOST => c3po.fareway.com:10980
            QIBM_USE_DESCRIPTOR_STDIO => Y
            UNIQUE_ID => VX881AooAJkAAZtTvRoAAANp
            HTTPS => OFF
            FCGI_ROLE => RESPONDER
            PHP_SELF => /printserver.php
            REQUEST_TIME_FLOAT => 1434402004.4439
            REQUEST_TIME => 1434402004 

kerberos

>> The new version of ibm_db2-1.9.7 has been released, you can find the release note at http://marc.info/?l=pecl-dev&m=143249326120494&w=2
Great. I will tell Zend to stop using my tests code.

>>  PHP_OS ...
i require a small modification to connection.inc (see red), as IBM i may report 'AIX' (PASE binaries are AIX binaries at compile)
// IBM i (PASE)
// PHP_OS reports 'AIX' on IBM i (AIX binary)
$myos = PHP_OS;
if (strpos('x'.$myos,'AIX') > 0) {
  $myos = `uname`;
}

>> test_240_FieldWidthPosName_01.php ... thanks, i must have edited wrong test file by accident. 
BTW -- Reminder, LUW version ODBC 3, IBM i version ODBC 2, therefore 'length tests' may calculate different (contact Kevin Adler CLI full details - kadler@us.ibm.com). 


>> Details of operator 'large IBM i system' changes as seen ibm_db2.ini (blue changed) ...

==========
ibm_db2.ini:
==========
ibm_db2.i5_allow_commit=n
0 - DB2_I5_TXN_NO_COMMIT - Commitment control is not used (no journal)
1 - DB2_I5_TXN_READ_UNCOMMITTED - Dirty reads. 
2 - DB2_I5_TXN_READ_COMMITTED - Dirty reads are not possible.
3 - DB2_I5_TXN_REPEATABLE_READ - Dirty reads and nonrepeatable reads are not possible. 
4 - DB2_I5_TXN_SERIALIZABLE - Dirty reads, non-repeatable reads, and phantoms are not possible

ibm_db2.i5_dbcs_alloc
0 - normal allocations
1 - expanded allocations for conversion

ibm_db2.i5_all_pconnect
0 - normal db2_connect
1 - force db2_connect to db2_pconnect

ibm_db2.i5_ignore_userid
0 - normal user/pwd (QSQSRVR)
1 - force ignore user/pwd (when possible, no QSQSRVR) 

ibm_db2.i5_job_sort
0 - normal sort order
1 - profile sort order

ibm_db2.i5_override_ccsid
1208 - default ccsid (new 1.9.7)
!0 - other pase ccsid

ibm_db2.i5_blank_userid
0 - normal no blank user/pwd db2 connect
1 - allow blank user/pwd db2 connect

ibm_db2.i5_log_verbose
0 - normal php.log message
1 - expanded php.log messages

ibm_db2.i5_max_pconnect
0 - normal nomax db2 persistent connection
!0 - use count recycle db2 persistent connection

ibm_db2.i5_check_pconnect
0 - normal no-check db2 persistent connection
1 - get conn attribute test
2 - get conn meta test
3 - create stmt test
4 - exec/fetch test

ibm_db2.i5_sys_naming
0 - sql naming (schema.table)
1 - system naming (*libl/file)

ibm_db2.i5_servermode_subsystem (*)
null - normal default susbsystem QSQSRVR jobs
'name' - named subsystem QSQSRVR jobs (prestart)
> crtlib adc                                     
> CRTSBSD SBSD(ADC/ADC) POOLS((1 *BASE)) TEXT('tony subsystem descr')
> CRTJOBD JOBD(ADC/ADC) TEXT('tony job descr')   
> CRTCLS CLS(ADC/ADC) TEXT('tony class')              
> ADDPJE SBSD(ADC/ADC) PGM(QSYS/QSQSRVR) MAXJOBS(*NOMAX)
> strsbs adc/adc

ibm_db2.i5_guard_profile
0 - normal no monitor use db2 connection
1 - before use, assure connect profile (switch user monitor)


>> details changes LUW to IBM i via DB2 Connect 10.5+bash-4.3$ grep I5 *.h
php_ibm_db2.h:#define DB2_I5_NAMING_ON  SQL_TRUE
php_ibm_db2.h:#define DB2_I5_NAMING_OFF SQL_FALSE
php_ibm_db2.h:#define DB2_I5_TXN_NO_COMMIT SQL_TXN_NO_COMMIT
php_ibm_db2.h:#define DB2_I5_TXN_READ_UNCOMMITTED SQL_TXN_READ_UNCOMMITTED
php_ibm_db2.h:#define DB2_I5_TXN_READ_COMMITTED SQL_TXN_READ_COMMITTED
php_ibm_db2.h:#define DB2_I5_TXN_REPEATABLE_READ SQL_TXN_REPEATABLE_READ
php_ibm_db2.h:#define DB2_I5_TXN_SERIALIZABLE SQL_TXN_SERIALIZABLE
php_ibm_db2.h:#define DB2_I5_FMT_ISO SQL_IBMi_FMT_ISO
php_ibm_db2.h:#define DB2_I5_FMT_USA SQL_IBMi_FMT_USA
php_ibm_db2.h:#define DB2_I5_FMT_EUR SQL_IBMi_FMT_EUR
php_ibm_db2.h:#define DB2_I5_FMT_JIS SQL_IBMi_FMT_JIS
php_ibm_db2.h:#define DB2_I5_FMT_MDY SQL_IBMi_FMT_MDY
php_ibm_db2.h:#define DB2_I5_FMT_DMY SQL_IBMi_FMT_DMY
php_ibm_db2.h:#define DB2_I5_FMT_YMD SQL_IBMi_FMT_YMD
php_ibm_db2.h:#define DB2_I5_FMT_JUL SQL_IBMi_FMT_JUL
php_ibm_db2.h:#define DB2_I5_FMT_JOB SQL_IBMi_FMT_JOB
php_ibm_db2.h:#define DB2_I5_FMT_HMS SQL_IBMi_FMT_HMS
php_ibm_db2.h:#define DB2_I5_SEP_SLASH SQL_SEP_SLASH
php_ibm_db2.h:#define DB2_I5_SEP_DASH SQL_SEP_DASH
php_ibm_db2.h:#define DB2_I5_SEP_PERIOD SQL_SEP_PERIOD
php_ibm_db2.h:#define DB2_I5_SEP_COMMA SQL_SEP_COMMA
php_ibm_db2.h:#define DB2_I5_SEP_BLANK SQL_SEP_BLANK
php_ibm_db2.h:#define DB2_I5_SEP_COLON SQL_SEP_COLON
php_ibm_db2.h:#define DB2_I5_SEP_JOB SQL_SEP_JOB
php_ibm_db2.h:#define DB2_I5_FETCH_ON SQL_TRUE
php_ibm_db2.h:#define DB2_I5_FETCH_OFF SQL_FALSE
php_ibm_db2.h:#define DB2_I5_JOB_SORT_ON  SQL_TRUE
php_ibm_db2.h:#define DB2_I5_JOB_SORT_OFF SQL_FALSE
php_ibm_db2.h:#define DB2_I5_DBCS_ALLOC_ON  SQL_TRUE
php_ibm_db2.h:#define DB2_I5_DBCS_ALLOC_OFF SQL_FALSE




LUW remote to IBM i added IBM i attributes (avail DB2 Connect 10.5+)
require_once('connection.inc');

$all = array();

$conn1 = db2_connect($database, $user, $password, 
array(
'i5_naming'=>DB2_I5_NAMING_ON, 
'i5_libl'=>"$user", 
'i5_curlib'=>"$user"
)
);
if (!$conn1) die("connect\n".db2_stmt_errormsg()."\n");

//Drop the dateme table, in case it exists
$drop = "DROP TABLE DATEME";
$res = @db2_exec($conn1, $drop);
echo "drop\n".db2_stmt_errormsg()."\n";

// Create the dateme table
$create = "CREATE TABLE DATEME (ID DECIMAL(7, 2), col1 DATE DEFAULT CURRENT DATE, col2 TIME DEFAULT CURRENT TIME)";
$res = db2_exec($conn1, $create);
if (!$res) die("create\n".db2_stmt_errormsg()."\n");

//Populate the dateme table
$insert = "INSERT INTO DATEME (ID) values(?)";
$sth = db2_prepare($conn1, $insert);
if (!$sth) die("prepare\n".db2_stmt_errormsg()."\n");
for($i=0;$i<9;$i++){
   $res = db2_execute($sth, array(10000 + $i+(.11*$i)));
   if (!$res) die("execute insert\n".db2_stmt_errormsg()."\n");
}
$stmt = db2_exec( $conn1, "SELECT ID,col1,col2 FROM DATEME" );
if (!$stmt) die("stmt\n".db2_stmt_errormsg()."\n");
while ($row = db2_fetch_array($stmt)) {
// var_dump($row);
$all[0][]=implode(" ",$row);
}

$conn2 = db2_connect($database, $user, $password, 
array(
'i5_naming'=>DB2_I5_NAMING_ON, 
'i5_libl'=>"$user", 
'i5_curlib'=>"$user",
'i5_date_fmt'=>DB2_I5_FMT_DMY,
'i5_date_sep'=>DB2_I5_SEP_SLASH,
'i5_time_fmt'=>DB2_I5_FMT_HMS,
'i5_time_sep'=>DB2_I5_SEP_BLANK
)
);
if (!$conn2) die("connect\n".db2_stmt_errormsg()."\n");
$stmt = db2_exec( $conn2, "SELECT ID,col1,col2 FROM DATEME" );
if (!$stmt) die("stmt\n".db2_stmt_errormsg()."\n");
while ($row = db2_fetch_array($stmt)) {
// var_dump($row);
$all[1][]=implode(" ",$row);
}

$conn3 = db2_connect($database, $user, $password, 
array(
'i5_naming'=>DB2_I5_NAMING_ON, 
'i5_libl'=>"$user", 
'i5_curlib'=>"$user",
'i5_date_fmt'=>DB2_I5_FMT_EUR,
'i5_time_fmt'=>DB2_I5_FMT_USA
)
);
if (!$conn3) die("connect\n".db2_stmt_errormsg()."\n");
$stmt = db2_exec( $conn3, "SELECT ID,col1,col2 FROM DATEME" );
if (!$stmt) die("stmt\n".db2_stmt_errormsg()."\n");
while ($row = db2_fetch_array($stmt)) {
// var_dump($row);
$all[2][]=implode(" ",$row);
}


for ($i=0;$i<9;$i++) {
  if ($all[0][$i] == $all[1][$i]) {
    die("fail {$all[0][$i]} {$all[1][$i]}\n");
  }
  if ($all[0][$i] == $all[2][$i]) {
    die("fail {$all[0][$i]} {$all[2][$i]}\n");
  }
  if ($all[1][$i] == $all[2][$i]) {
    die("fail {$all[0][$i]} {$all[1][$i]}\n");
  }
  echo("good {$all[0][$i]} {$all[1][$i]} {$all[2][$i]}\n");
}
echo "success\n";
?>

      *************************************************************************
      * 1) call i CMD:
      * {"cmd":"name",
      *  "execute":"*CMD",
      *  "options": 
      *   {"exec:"cmd|system|rexx",
      *    "hex":"on",
      *    "before":"cc1/cc2/cc3/cc4",
      *    "after":"cc4/cc3/cc2/cc1",
      *    "error":"on|off|fast"
      *   }
      * }
      * "cmd":        - command name (id)
      * "execute":    - IBM i *CMD (5250 - cut/paste)
      * "options":
      *  "exec": 
      *     "cmd"     - qcmdexe only return true/false (default)
      *     "system"  - system utility return CPFxxxx
      *     "rexx"    - rexx output parms and return CPFxxxx
      *                 (?) character type
      *                 (?N) explicit cast numeric
      *  "hex":
      *     "on"      - input character hex (5147504C20202020)
      *  "before":
      *     "cc(n)"   - input ccsid1->ccsid2->ccsid3->ccsid4
      *  "after":
      *     "cc(n)"   - output ccsid1->ccsid2->ccsid3->ccsid4 
      *  "error":
      *     "on"      - script stops, full error report
      *     "off"     - script continues, job error log (default)
      *     "fast"    - script continues, brief error log
      *
      * Example 1:
      *  {"cmd":"chglibl",
      *   "execute":"CHGLIBL LIBL(QTEMP XMLSER) CURLIB(XMLSER)"
      *  }
      *
      * Example 2:
      *  {"cmd":"rtvjoba,
      *   "execute":"RTVJOBA CCSID(?N) OUTQ(?)",
      *   "options":{"exec":"rexx"}
      *  }
      *************************************************************************

If a new PID for each query, could this give us “asynch DB2 queries”? http://gonzalo123.com/2010/10/11/speed-up-php-scripts-with-asynchronous-database-queries/

http://php.net/manual/en/book.xmlreader.php

http://www.youngiprofessionals.com/Samples/Toolkit/CallPgm_w_DS_params.php



; Data Structure integrity
; Whether to retain the tree-like hierarchy of data structures (dataStructureIntegrity = true)
; or to ignore DSes, flattening out all data elements to a single level (dataStructureIntegrity = false)
; Starting in Zend Server 6, the default here will be true.
; For backward compatibility with pre-1.4.0 behavior, change one or both to false.
dataStructureIntegrity = true
; Array Integrity
; Allow true array parameters with better functionality. 
; For backward compatibility with pre-1.4.0, set to false.
arrayIntegrity = true



Building the form...
    public function gradeItStudioAction()
    {
        $viewParameters = new \ArrayObject([
                'testNumber' => $this->params('testNumber', '0'),
                'pageTitle' => 'Grade It Studio',
                'lotTestInfo' => $this->coAModel->getCoAInfo($this->params('testNumber', 0)),
        ]);

        if ($this->serviceLocator->has('ranAllTests')) {
            $viewParameters->offsetSet('testResults', $this->serviceLocator->get('ranAllTests'));
            $viewParameters->offsetSet('pageTitle', 'Results of Run All Tests');
        }

        $form = new Form('grade-it-results');
        $element = new Element('submit');
        $element->setAttributes([
            'value' => 'Test & Save',
            'id' => 'submitButton',
            'title' => 'Run All Tests w/o Grade It',
        ]);
        $form->add($element);

        foreach ($viewParameters['lotTestInfo']['detailRecords'] as $test) {
            $element = new Element('result' . $test['LineNumber']);
            $element->setAttributes([
                'type' => 'text',
                'value' => $test['Result'],
                'maxlength' => '50',
                'size' => '24',
            ]);
            $form->add($element);
        }
        unset($test, $element);

        $viewParameters['resultsForm'] = $form;
        $view = new ViewModel($viewParameters);
        return $view;
    }

$param[]= $this->toolkitModel->toolkit->AddDataStruct($ds, 'LotDs')->setParamDimension(100)->setParamLabelCounted('dscounter');

<?php
namespace Application\Model;

class RunAllTestsModel
{
    public $toolkitModel = null;

    public function runAllTests($testNumber, $formData)
    {
        $sequenceNumbers = array_keys($formData);
        $tests = [];
        foreach ($sequenceNumbers as $key) {
            $matches = [];
            if (0 == preg_match('/result(\d{1,4})/', $key, $matches)) {
                continue;
            };
            $tests[] = [
                'lineNumber' => str_pad($matches[1], 4,'0', STR_PAD_LEFT),
                'result' => $formData[$key],
            ];
        }
        unset($key, $matches, $sequenceNumbers);

        $numTests = count($tests);
        $ds = [];
        $param = [];
        $outParams = [];
        $returnParam = [];

        $i = 0;
        foreach ($tests as $test) {
            $ds[] = $this->toolkitModel->toolkit->AddParameterChar('both', 4,   'LineNum', 'LineNum' . $i, $test['lineNumber']);
            $ds[] = $this->toolkitModel->toolkit->AddParameterChar('both', 50,  'Result',  'Result' . $i,  $test['result']);
            $ds[] = $this->toolkitModel->toolkit->AddParameterChar('both', 80,  'Message', 'Message' . $i, ' ');
            $ds[] = $this->toolkitModel->toolkit->AddParameterChar('both', 1,   'PFFlag',  'PFFlag' . $i,  ' ');
            $ds[] = $this->toolkitModel->toolkit->AddParameterChar('both', 1,   'ResFlag', 'ResFlag' . $i, ' ');
            $i++;
        }
        unset($test, $i);

        // Initialize remaining records to blanks, for PROCRESSTUDIO to be happy
        $ds[] = $this->toolkitModel->toolkit->AddParameterChar('both', 4,   'LineNum', 'LineNum', ' ');
        $ds[] = $this->toolkitModel->toolkit->AddParameterChar('both', 50,  'Result',  'Result',  ' ');
        $ds[] = $this->toolkitModel->toolkit->AddParameterChar('both', 80,  'Message', 'Message', ' ');
        $ds[] = $this->toolkitModel->toolkit->AddParameterChar('both', 1,   'PFFlag',  'PFFlag',  ' ');
        $ds[] = $this->toolkitModel->toolkit->AddParameterChar('both', 1,   'ResFlag', 'ResFlag', ' ');

        $param[] = $this->toolkitModel->toolkit->AddParameterChar('both', 10, 'Ptestnuma', 'Ptestnuma', $testNumber);
        $param[] = $this->toolkitModel->toolkit->AddDataStruct($ds, 'Presults')->setParamLabelCounted('Pcnt');
        $param[] = $this->toolkitModel->toolkit->AddParameterZoned('both', 5, 0, 'Pcnt', 'Pcnt', 0)->setParamLabelCounter('Pcnt');
        $param[] = $this->toolkitModel->toolkit->AddParameterChar('both', 80, 'Pmessage', 'Pmessage', ' ');

        $returnParam[] = $this->toolkitModel->toolkit->AddParameterChar('out', 1, "ProcResStudio_result", "ProcResStudio_result", ' ');

        $outParams = $this->toolkitModel->toolkit->PgmCall(
            'PHP700P',
            'PROYPGM',
            $param,
            $returnParam,
            ['func'=>'PROCRESSTUDIO']
        );
//file_put_contents('/usr/local/zendsvr6/var/log/run-all-tests.out', print_r($outParams, true) . PHP_EOL, FILE_APPEND);

        return [
            'testNumber'  => trim($outParams['io_param']['Ptestnuma']),
            'testResults' => array_slice($outParams['io_param']['Presults'], 0, -5, true),
            'recordCount' => trim($outParams['io_param']['Pcnt']),
            'message'     => trim($outParams['io_param']['Pmessage']),
            'status'      => $outParams['retvals']['ProcResStudio_result'],
        ];
    }

    public function setToolkit($toolkitModel)
    {
        $this->toolkitModel = $toolkitModel;
    }

}
/QOpenSys/home/rwatkin/openssl-1.0.1l.i5os

[adc@oc7083008330 ~]$ ssh -X lp0364d
adc@lp0364d's password: 
Welcome to LP0364D.rchland.ibm.com
$ bash
bash-4.2$ cd /home/ADC/ruby_andrea
bash-4.2$ export PATH=/PowerRuby/prV2R0/bin:$PATH
bash-4.2$ export LIBPATH=/PowerRuby/prV2R0/lib      
bash-4.2$ ruby zzaes.rb &
[1] 282460
bash-4.2$ ps
    PID    TTY  TIME CMD
 282423  pts/3  0:00 -bsh 
 282425  pts/3  0:00 bash 
 282460  pts/3  0:00 ruby zzaes.rb 
 282461  pts/3  0:00 ps 
bash-4.2$ dbx -d 100 -a 282460
Waiting to attach to process 282460 ...
Successfully attached to /PowerRuby/prV2R0/bin/ruby.
Type 'help' for help.
reading symbolic information ...internal error: assertion failed at line 5562 in file object.c
internal error: assertion failed at line 5562 in file object.c
(ignore errors)

(dbx) cont

Segmentation fault in bn_lib.BN_num_bits@AF35_29 [/usr/lib/libcrypto.a] at line 235 in file "" ($t1)
couldn't read "bn_lib.c"
(dbx)

(dbx) sh find /QOpenSys/home/rwatkin/openssl-1.0.1l.i5os/. -name "bn_lib.c" -print

(dbx) file /QOpenSys/home/rwatkin/openssl-1.0.1l.i5os/./crypto/bn/bn_lib.c
(dbx) 

(dbx) where    #Note: do this twice 1st - junk, 2nd-pretty 
bn_lib.BN_num_bits@AF35_29(0x4f70656e, 0x4d4d307c), line 235 in "bn_lib.c"

(dbx) registers
  $r0:0xdf7c3088  $stkp:0x2ff21c20   $toc:0xf1dde714    $r3:0x4f70656e  
  $r4:0x4d4d307c    $r5:0x2ff21d40    $r6:0x6a6983e0    $r7:0xf1dd231c  
  $r8:0xf1dd231c    $r9:0x00000000   $r10:0xf1dfb77c   $r11:0x00000000  
 $r12:0xf1dd4e54   $r13:0x200c2fc0   $r14:0x203fe5b0   $r15:0x00000020  
 $r16:0x3fffffff   $r17:0xc0000000   $r18:0x200c2fc0   $r19:0xfffffffc  
 $r20:0x00000006   $r21:0x00000001   $r22:0x00000003   $r23:0xf1dc5504  
 $r24:0xf1dc5504   $r25:0x00000000   $r26:0xffffffff   $r27:0x00000000  
 $r28:0x00000000   $r29:0x00000000   $r30:0xdf8ee008   $r31:0x00000000  
 $iar:0xdf747178   $msr:0x0000f032    $cr:0x42008424  $link:0xdf7c3088  
 $ctr:0xdf7470e0   $xer:0x02000010    $mq:0x00000000  
          Condition status = 0:g 1:e 4:l 5:g 6:e 7:g 
        [unset $noflregs to view floating point registers]
        [unset $novregs to view vector registers]
in bn_lib.BN_num_bits@AF35_29 [/usr/lib/libcrypto.a] at line 235 in file "/QOpenSys/home/rwatkin/openssl-1.0.1l.i5os/./crypto/bn/bn_lib.c" ($t1)
0xdf747178 (BN_num_bits@AF35_29+0x18) 7c63202e        lwzx   r3,r3,r4

(dbx) dump
bn_lib.BN_num_bits@AF35_29(0x4f70656e, 0x4d4d307c), line 235 in "bn_lib.c"
(dbx) list
    1   /* crypto/bn/bn_lib.c */
    2   /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)


(dbx) list 142
  142   int BN_num_bits_word(BN_ULONG l)
(dbx) list
  143           {
  144           static const unsigned char bits[256]={
  145                   0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
  146                   5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  147                   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  148                   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  149                   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,


(dbx) list 229
  229   int BN_num_bits(const BIGNUM *a)
(dbx) list
  230           {
  231           int i = a->top - 1;
  232           bn_check_top(a);
  233   
  234           if (BN_is_zero(a)) return 0;
  235           return ((i*BN_BITS2) + BN_num_bits_word(a->d[i]));
  236           }
  237   
  238   void BN_clear_free(BIGNUM *a)
  239           {

(dbx) print a
0x200c2fc0 
(dbx) print i
804396528 

(dbx) 0x200c2fc0 / 10 X
0x200c2fc0:  204160e8 20043030 20414bd0 00000291
0x200c2fd0:  2011f240 00000004 20415544 00000000
0x200c2fe0:  00000000 00000000
(dbx) 

(dbx) print *a
(pad = 541155560, version = 537145392, meth = 0x20414bd0, engine = 0x00000291, n = 0x2011f240, e = 0x00000004, 
d = 0x20415544, p = (nil), q = (nil), dmp1 = (nil), dmq1 = 0x201dc2d0, iqmp = 0x20043018, 
ex_data = (sk = 0x201dbf50, dummy = 833), references = 538047040, flags = 4, 
_method_mod_n = 0x201dc294, _method_mod_p = (nil), _method_mod_q = (nil), 
bignum_data = (nil), blinding = (nil), mt_blinding = (nil)) 

????????
????????
????????
bn/bn.h:typedef struct bignum_st BIGNUM;
bn/bn.h:struct bignum_st
rsa/rsa.h:      BN_BLINDING *mt_blinding;

Why does dbx think struct rsa_st not struct bignum_st (typedef struct bignum_st BIGNUM)???

????????
????????
????????

(dbx) set $hexints

(dbx) print *(BIGNUM *) a
(d = 0x204160e8, top = 0x20043030, dmax = 0x20414bd0, neg = 0x291, flags = 0x2011f240) 


(dbx) print *(struct rsa_st *) a
(pad = 0x204160e8, version = 0x20043030, meth = 0x20414bd0, engine = 0x00000291, 
n = 0x2011f240, e = 0x00000004, d = 0x20415544, p = (nil), q = (nil), 
dmp1 = (nil), dmq1 = 0x201dc2d0, iqmp = 0x20043018, ex_data = (sk = 0x201dbf50, dummy = 0x341), 
references = 0x2011f240, flags = 0x4, _method_mod_n = 0x201dc294, _method_mod_p = (nil), 
_method_mod_q = (nil), bignum_data = (nil), blinding = (nil), mt_blinding = (nil)) 


====
bn/bn.h
====
struct bignum_st
	{
	BN_ULONG *d;	/* Pointer to an array of 'BN_BITS2' bit chunks. */
	int top;	/* Index of last used d +1. */
	/* The next are internal book keeping for bn_expand. */
	int dmax;	/* Size of the d array. */
	int neg;	/* one if the number is negative */
	int flags;
	};

===
rsa/rsa.h
===
struct rsa_st
	{
	/* The first parameter is used to pickup errors where
	 * this is passed instead of aEVP_PKEY, it is set to 0 */
	int pad;
	long version;
	const RSA_METHOD *meth;
	/* functional reference if 'meth' is ENGINE-provided */
	ENGINE *engine;
	BIGNUM *n;
	BIGNUM *e;
	BIGNUM *d;
	BIGNUM *p;
	BIGNUM *q;
	BIGNUM *dmp1;
	BIGNUM *dmq1;
	BIGNUM *iqmp;
	/* be careful using this if the RSA structure is shared */
	CRYPTO_EX_DATA ex_data;
	int references;
	int flags;

	/* Used to cache montgomery values */
	BN_MONT_CTX *_method_mod_n;
	BN_MONT_CTX *_method_mod_p;
	BN_MONT_CTX *_method_mod_q;

	/* all BIGNUM values are actually in the following data, if it is not
	 * NULL */
	char *bignum_data;
	BN_BLINDING *blinding;
	BN_BLINDING *mt_blinding;
	};

other stuff (not Ryan)


         // PASE call buffer memory
         if piAlloc = *NULL or paAlloc = 0;
           Monitor;
             paAlloc = 0;
             piAlloc = Qp2malloc(myMax:%addr(paAlloc));
           On-error;
             PaseStop();
           Endmon;
           if paAlloc = 0;
             errsCritical(QP2_ERROR_MALLOC_FAIL:%char(myMax));
             perfAdd(PERF_ANY_WATCH_PASESTART:*OFF);
             return *OFF;
           endif;
         endif;

     D memset          PR                  ExtProc('__memset')
     D  pTarget                        *   Value
     D  nChar                        10I 0 Value
     D  nBufLen                      10U 0 Value


D zname           PR                    EXTPGM('zname')         
D   MTH                      16383      CONST OPTIONS(*VARSIZE) 
D   MTHNAME                  32766      OPTIONS(*VARSIZE)       
D zname           PI                    OPDESC                  
D   MTH                      16383      CONST OPTIONS(*VARSIZE) 
D   MTHNAME                  32766      OPTIONS(*VARSIZE)       
C                   IF        MTH = '1'                         
C                   MOVE      'January'     MTHNAME             
C                   ENDIF                                       

See this link: http://iprodeveloper.com/no-topic/determining-rpg-exported-procedure-names

STRPGMEXP PGMLVL(*CURRENT)    
EXPORT SYMBOL('PREF_BUILD')   
ENDPGMEXP                     


     D pref_build      PR             5P 0 ExtProc('ProgramA')
     D  webuserid                          LIKE(DYLVVN)                         Web user id 64A 
     D  webpgmname                         LIKE(DYJDVN)                         Program name 10A 
     D  webprefid                          LIKE(DYXDNB)                         Preference id 
     D  webhdrpgm                          LIKE(DYJDVN)                         Header pref id 
     D  webpgmtype                    1A 




DSPSRVPGM SRVPGM(*LIBL/CM1090R) DETAIL(*PROCEXP)

STRPGMEXP PGMLVL(*CURRENT) LVLCHK(*YES)
   .
   .
EXPORT SYMBOL(p1)
EXPORT SYMBOL('p2')
EXPORT SYMBOL('P3')
   .
   .
ENDPGMEXP
   .

see something like:

                     Display Service Program Information                       
                                                                Display 1 of 1 
Service program  . . . . . . . . . . . . :   CM1090R                           
  Library  . . . . . . . . . . . . . . . :     CPPPGM                          
Owner  . . . . . . . . . . . . . . . . . :   PROGRAMMER                        
Service program attribute  . . . . . . . :   RPGLE                             
Detail . . . . . . . . . . . . . . . . . :   *PROCEXP                          

                              Procedure Exports:                               

Procedure Name                                                          ARGOPT 
submitorder                                                             *NO    
Ping                                                                    *NO    


                     Display Service Program Information                       
                                                                 Display 1 of 1 
 Service program  . . . . . . . . . . . . :   ZZSRV                             
   Library  . . . . . . . . . . . . . . . :     XMLSERVICE                      
 Owner  . . . . . . . . . . . . . . . . . :   ADC                               
 Service program attribute  . . . . . . . :   RPGLE                             
 Detail . . . . . . . . . . . . . . . . . :   *PROCEXP                          

 Procedure Name                                                          ARGOPT 
 DEBUGME                                                                 *NO    
 ZZARRAY                                                                 *NO    
 ZZARRAY2                                                                *NO    
 ZZARRBAD                                                                *NO    
 ZZBIG                                                                   *NO    
 ZZBIGI                                                                  *NO    
 ZZBINARY                                                                *NO    


0049.00 CRTRPGMOD MODULE(XMLSERVICE/ZZSRV) SRCFILE(XMLSERVICE/QRPGLESRC) +
0050.00   DBGVIEW(*SOURCE) OUTPUT(*PRINT) REPLACE(*YES)
0051.00 CRTSRVPGM SRVPGM(XMLSERVICE/ZZSRV) MODULE(XMLSERVICE/ZZSRV) +
0052.00   EXPORT(*ALL) ACTGRP(*CALLER)
0053.00 DLTMOD MODULE(XMLSERVICE/ZZSRV)


https://bitbucket.org/inext/xmlservice-rpg

http://github.com/zendtech/IbmiToolkit/pull/34/

var xt = require('../lib/itoolkit');
var conf = require('../../config.js');

// var option = {
        // host : conf.Host,
        // port : conf.Port,
        // path : conf.Path
// };
function cbJson(str) {console.log(JSON.stringify(xt.xmlToJson(str)));}
function cb(str) {console.log(str);}

var conn = new xt.iConn(conf.Database, conf.User, conf.Password);  // DB2 


var HatsDetail = function(callback, p1, p2) {
  // change libl
  conn.add(xt.iCmd("CHGLIBL LIBL("+conf.DemoLib+") CURLIB("+conf.DemoLib+")"));
  var sql = new xt.iSql();
  // sql.addQuery("CREATE TABLE CHAT(PROD INTEGER NOT NULL, CHAT VARCHAR(64) NOT NULL)");
  // sql.free();
  // add chat ?
  if (p2) {
    sql.addQuery("INSERT INTO CHAT (PROD, CHAT) VALUES("+p1+",'"+p2+"')");
    sql.free();
  }
  // chat back?
  sql.addQuery("SELECT CHAT FROM CHAT WHERE PROD = "+p1);
  sql.fetch({'error':'fast'});
  sql.free();
  // select product
  sql.addQuery("SELECT * FROM PRODUCTS WHERE PROD = "+p1);
  sql.fetch({'error':'fast'});
  sql.free();
  // complete xml document (input/request)
  var xmlIn = sql.toXML();
  conn.add(xmlIn);
  // console.log(xmlIn);
  // run (call xmlservice)
  conn.run(function (str) {
    // console.log(str);
    var jobj = xt.xmlToJson(str);
    jobj[1].result.forEach(function(jb) {
      console.log(jb);
    });
    var prod = 0;
    var cat = 0;
    var desc = "";
    var photo = "";
    var price = 0;
    var chatback = "";
    if (jobj && jobj[1] && jobj[1].result) {
      jobj[1].result.forEach(function(row) {
        if (row[0].desc == "CHAT") {
          chatback += ": " + row[0].value;
        } else {
          prod = row[0].value;
          cat = row[1].value;
          desc = row[2].value;
          photo = 'http://' + conf.Host + ':' + conf.Port + conf.DemoAsset + row[3].value;
          price = row[4].value;
        }
      });
    }
    // return to screen
    callback([prod,cat,desc,photo,price,chatback]);
  });
}


HatsDetail(cb,16,"nice hen");

Spoolfinder


try { 
  $connection = new PDO("ibm:C104853R", "stephanie", "pass", array(
    PDO::ATTR_PERSISTENT => TRUE, 
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
  ); 
}
catch (Exception $e) {
  echo($e->getMessage());
}

//$connection->setAttribute(PDO::I5_ATTR_DBC_SYS_NAMING, true);
//$connection->setAttribute(PDO::I5_ATTR_DBC_LIBL, "XL_WEBDEMO QTEMP");

$statement = $connection->prepare("select * from mu_custf where CMSTATE = :ststate");
$statement->execute(array(':ststate' => "CA"));
$row = $statement->fetch();


*PHP Fatal error:  Call to a member function prepare() on a non-object in /www/websmart/htdocs


$zre = new \ZRayExtension("xmltoolkit");
$XmlStorage = new XmltoolKit();

$zre->setMetadata(array(
    'logo' => base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'logo.png')),
));

//$zre->setIsEnabled(true);
$zre->setEnabledAfter("ToolkitService::getInstance");
//----------------------------------------------------------------
$zre->traceFunction("ToolkitService::__construct",           function(){}, array($XmlStorage, 'getConstructor'));

$zre->traceFunction("ToolkitService::pgmCall",               function(){}, array($XmlStorage, 'pgmCall'));                  
$zre->traceFunction("ToolkitService::CLCommand",             function(){}, array($XmlStorage, 'clCommand'));                // for all kind of CL
$zre->traceFunction("ToolkitService::ExecuteProgram",        function(){}, array($XmlStorage, 'execXMLStoredProcedure'));   // alias of sendXML -- for all kind of transport Type (Db2/ODBC)



namespace XmltoolKit;

class XmltoolKit{

    public function getConstructor($context, &$storage){
        // Whether exception is thrown (probably due a connections problems) we catch it! //
        $this->traceErrors($context, $storage);
        if(isset($context['locals']['exceptionThrown']))
            $error = $context['locals']['exceptionThrown'];
        else 
            $error = 'No error detected';
        //-----end exeption management-----------------------------------------------------//
        // to recover the XMLToolkit version server side: it execute an sendXml() call traced by this ZRay Extension
        $xmltoolkitVersion = $context['this']->getDiagnostics(); 
        $SubmitjobParams   = 'No defined';
        if (isset($context['locals']['serviceParams']['sbmjobParams'][0]))
            $SubmitjobParams = $context['locals']['serviceParams']['sbmjobParams'][0];

        // Recovery variables related to service parameters defined into the ToolkitService::__Construct
        $storage["Instance"][] =  array('DbName'                  => $context['locals']['databaseNameOrResource'],
                                        'Version Server Side'     => $xmltoolkitVersion,
                                        'Connection Persistent'   => $context['locals']['isPersistent'],
                                        'User/i5Naming'           => $context['locals']['userOrI5NamingFlag'],
                                        'Xml Service Lib'         => $context['locals']['xmlServiceLib'],
                                        'Debug'                   => $context['locals']['debug'],
                                        'Debug Log File'          => $context['locals']['debugLogFile'],
                                        'Encoding'                => $context['locals']['encoding'],
                                        'Parse Only'              => $context['locals']['parseOnly'],
                                        'Parse Debug Level'       => $context['locals']['parseDebugLevel'],
                                        'Transport Type'          => $context['locals']['serviceParams']['transportType'],
                                        'Submit job Params'       => $SubmitjobParams,
                                        'Transport Type'          => $context['locals']['serviceParams']['transportType'],
                                        'Times Called'            => $context['timesCalled'],
                                        'Exception'               => $error,                                                      
                                         );
    }



aJob = '*'
RtvJobInf(dsJOBI0400:%size(dsJOBI0400):'JOBI0400':aJob:*BLANKS:dsEC);

      * job info
     D RtvJobInf       PR                  ExtPgm('QUSRJOBI')
     D   RcvVar                   32766A   options(*varsize)
     D   RcvVarLen                   10I 0 CONST
     D   Format                       8A   CONST
     D   JobName                     26A   CONST
     D   IntJobID                    16A   CONST
     D   ErrorCode                32766A   options(*varsize)

http://youngiprofessionals.com/hats/master

<?php
// -----------------
// make the call
// -----------------
// see connection.inc param details ...
require_once('connection.inc');
// call IBM i
if ($i5persistentconnect) $conn = db2_pconnect($database,$user,$password);
else $conn = db2_connect($database,$user,$password);
$stmt = db2_prepare($conn, "call $procLib.iPLUGRC32K(?,?,?,?)");
if (!$stmt) die("Bad prepare: ".db2_stmt_errormsg());
// provide input
$buf = array (
getxml_part1(),
getxml_part2(),
getxml_part3(),
getxml_part4(),
getxml_part5(),
getxml_part6()
);
$count = count($buf);
foreach($buf as $partial) {
  $clobIn = $partial;
  $count--; // 0=run; >0=accumulate input xml
  $clobOut = "";
  $ret=db2_execute($stmt,array($ipc,$ctl,$clobIn,$count));
  if (!$ret) die("Bad execute: ".db2_stmt_errormsg());
}
// fetch output
while ($row = db2_fetch_array($stmt)){
  $clobOut .= $row[0];
}
$clobOut = trim($clobOut);
// -----------------
// output processing
// -----------------
$myName1 = 'Ranger';  // expected name
$myMax1  = 212;       // expected max
$myCount1= 212;       // expected count
$size = strlen($clobOut);
echo substr($clobOut,$size-400)."\n";
if ($size < 917000) die("Failed ($size < 917000)\n");
for ($i=0;$i<$myCount1;$i++) {
  // DS records expected
  $irpg     = $i+1;
  $dcMyName = ">".$myName1.$irpg."<";
  if (strpos($clobOut,$dcMyName)<1) die("Fail dcMyName $dcMyName missing\n");
  $dcMyRank = ">".(10+$irpg)."<";
  if (strpos($clobOut,$dcMyRank)<1) die("Fail dcMyRank $dcMyRank missing\n");
  $dcMyPay  = ">".sprintf("%1.2f", 13.42*$irpg)."<";
  if (strpos($clobOut,$dcMyPay)<1) die("Fail dcMyPay $dcMyPay missing\n");
}
// good
echo "Success ($size)\n";

function getxml_part1() {
$clob = <<<ENDPROC
<?xml version='1.0'?>
<script>
<cmd comment='addlible'>ADDLIBLE LIB(xyzlibxmlservicexyz) POSITION(*FIRST)</cmd>
<pgm name='ZZSRV' lib='xyzlibxmlservicexyz' func='ZZARRAY'>
ENDPROC;
return test_lib_replace($clob);
}

function getxml_part2() {
$clob = <<<ENDPROC
 <parm comment='search this name'>
  <data var='myName' type='10A'>Ranger</data>
 </parm>
ENDPROC;
return test_lib_replace($clob);
}

function getxml_part3() {
$clob = <<<ENDPROC
 <parm comment='max allowed return'>
  <data var='myMax' type='10i0'>212</data>
 </parm>
ENDPROC;
return test_lib_replace($clob);
}

function getxml_part4() {
$clob = <<<ENDPROC
 <parm comment='actual count returned'>
  <data var='myCount' type='10i0' enddo='mycount'>0</data>
 </parm>
ENDPROC;
return test_lib_replace($clob);
}

function getxml_part5() {
$clob = <<<ENDPROC
 <return>
  <ds var='dcRec_t' dim='999' dou='mycount'>
    <data var='dcMyName' type='10A'>na</data>
    <data var='dcMyJob' type='4096A'>na</data>
    <data var='dcMyRank' type='10i0'>0</data>
    <data var='dcMyPay' type='12p2'>0.0</data>
  </ds>
 </return>
ENDPROC;
return test_lib_replace($clob);
}

function getxml_part6() {
$clob = <<<ENDPROC
</pgm>
</script>
ENDPROC;
return test_lib_replace($clob);
}



cd /mylib
> ar -x /opt/freeware/lib/libiconv.a
> ls
oldname.so
> mv oldname.so libiconv.so.2
> ar -rv /opt/freeware/lib/libiconv.a libiconv.so.2



 exec(): 0509-036 Cannot load program gdb because of the following errors:                                
         0509-150   Dependent module /opt/freeware/lib/libiconv.a(libiconv.so.2) could not be loaded.     
         0509-022 Cannot load module /opt/freeware/lib/libiconv.a(libiconv.so.2).                         
         0509-026 System error: A file or directory in the path name does not exist.                      
         0509-021 Additional errors occurred but are not reported.                                        



rpm --ignoreos --ignorearch --nodeps --replacepkgs -hUv autoconf213-2.13-1.aix5.1.noarch.rpm

rpm --install gdb-7.7-1.aix5.1.ppc.rpm                   
error: failed dependencies:                              
        info is needed by gdb-7.7-1                      
        gettext is needed by gdb-7.7-1                   
        expat >= 2.0.0 is needed by gdb-7.7-1            
        python-libs >= 2.6.2 is needed by gdb-7.7-1      
        libiconv >= 1.14-2 is needed by gdb-7.7-1        
        /bin/sh   is needed by gdb-7.7-1                 
        libc.a(shr.o) is needed by gdb-7.7-1             
        libcurses.a(shr42.o) is needed by gdb-7.7-1      
        libexpat.a(libexpat.so.1) is needed by gdb-7.7-1 
        libiconv.a(libiconv.so.2) is needed by gdb-7.7-1 
        libintl.a(libintl.so.1) is needed by gdb-7.7-1   
        libpthdebug.a(shr.o) is needed by gdb-7.7-1      

(:quicktoc:)
>>round frame bgcolor=#ffffdd<<
!!! PHP Workpage Alan/Tony ...
>><<


Event address for panelists: https://common.webex.com/common/onstage/g.php?d=920148997&t=p 

[[ Attach:Shells.pdf | %blue%{Shells.pdf}%%]]


[[http://pic.dhe.ibm.com/infocenter/iadthelp/v9/index.jsp?topic=%2Fcom.ibm.etools.iseries.langref.doc%2Frzan5mst262.htm]]

[[http://194.196.36.29/support/knowledgecenter/ssw_ibm_i_71/rtref/setloc.htm]]

[@

Note:
1 The environment variables with names corresponding to locale categories are created by the user. 
The LANG environment variable is automatically created during job initiation 
when you specify a locale path name for either of the following:

    the LOCALE parameter in your user profile (see the CHGUSRPRF (Change User Profile) command information in the i5/OS™ Information Center).
    the QLOCALE system value (see the QLOCALE system value information in the i5/OS Information Center).

The locale environment variables are expected to contain a locale path name of the 
form /QSYS.LIB/<locname>.LOCALE or /QSYS.LIB/<libname>.LIB/<locname>.LOCALE. 
If your module is compiled with the LOCALETYPE(*LOCALEUTF) option, the environment variable will be 
ignored if the <locname> portion of the path exceeds 8 characters. This restriction exists because a 2 
character suffix must be appended to the locale name to get the name of the corresponding UTF locale.
       // copy out slow way sprintf ...
       fmt = '%1.' + %char(node.xmlFrac) + 'f' + x'00';
       valist.vp1 = fmtP;
       valist.vp2 = %addr(f64);
       strSz = sprintf(strP:fmtP:%addr(valist));

http://php-fpm.org/

system value QDECFMT

        URL = ‘http://i.myserver.com:10080/omni/mailhtml2.php?howmany=’
               + %trim(HowMany) + ‘&mike=‘ + %trim(Mike)
               + ‘&alan=‘ + %trim(Alan) + ‘&drew=‘ + %trim(Drew);
       Exec SQL Declare CsrC01 Cursor For
          Select  a.*
             From XMLTable(
                      ‘rootnode’
                      Passing XMLParse(DOCUMENT
                      HTTPGetCLOB(
                                  :URL,
                                  ‘’))
                Columns Message  VarChar(50) Path ‘message’
                                                             ) a;



   Select  a.*, Cast(Round(1.0/ExchgRate, 4) as Dec(11, 4)) ExchgRateI                                                  
      From XMLTable(                                                                                                    
         XMLNamespaces(DEFAULT                                                                                          
                       ‘http://www.ecb.int/vocabulary/2002-08-01/eurofxref’,                                            
                       ‘http://www.gesmes.org/xml/2002-08-01’ AS “gesmes”),                                             
         ‘gesmes:Envelope/Cube/Cube/Cube’                                                                               
         Passing XMLParse(DOCUMENT                                                                                      
                    HTTPGetCLOB(                                                                                        
             ‘http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml’,                                            
                                ‘’))                                                                                    
         Columns Subject   VarChar(30) Path ‘../../../gesmes:subject’,                                                  
                 Sender    VarChar(30) Path                                                                             
                                       ‘../../../gesmes:Sender/gesmes:name’,                                            
                 ExchgDate Date        Path ‘../@time’,                                                                 
                 Currency  Char(3)     Path ‘@currency’,                                                                
                 ExchgRate Dec(10, 4)  Path ‘@rate’      ) a;

http://ibmsystemsmag.blogs.com/i_can/database/

byval.jpg

??by value issue???

ZEND_BEGIN_MODULE_GLOBALS(ibm_db2)
long bin_mode;
:
char *i5_servermode_subsystem;
:
ZEND_END_MODULE_GLOBALS(ibm_db2)


/* ibm_db2.ini server mode subsystem  */
STD_PHP_INI_ENTRY("ibm_db2.i5_servermode_subsystem", 
 NULL, PHP_INI_SYSTEM, OnUpdateString,
 i5_servermode_subsystem, zend_ibm_db2_globals, 
 ibm_db2_globals)



Not clear to me why the argument value would not be valid, causing the SQ99999.
if (IBM_DB2_G(i5_servermode_subsystem) && IBM_DB2_G(i5_ignore_userid) < 1) 
{
  rc = _php_db2_SQLSetConnectAttr(
         (SQLHDBC)conn_res->hdbc, 
         SQL_ATTR_SERVERMODE_SUBSYSTEM, 
         (SQLPOINTER) IBM_DB2_G(i5_servermode_subsystem), 
         SQL_NTS);
}

SQLINTEGER _php_db2_SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER fOption, SQLPOINTER vParam, SQLINTEGER fStrLen) 
{
  int rc = SQL_ERROR;
  SQLPOINTER pvParam = vParam;
  if (COMPILE_IS_PASE && fStrLen != SQL_NTS) pvParam = (SQLPOINTER)&vParam;
  rc = SQLSetConnectAttr(hdbc,fOption,pvParam,fStrLen);
  return _php_db2_special_return(rc,fOption,NULL,0);
}
HTTP via DB2 on i
http://www.ibm.com/developerworks/ibmi/library/i-incorporating-web-service/index.html?ca=drs

<myscript>
<sh>catsplf > /tmp/file</sh>
<file type='a'>/tmp/file</file>
</myscript>


type='a -- special source
type='b' -- regular file binary (char hex encode like other data in toolkit)

    //Create the animal_pics table
    $create = 'CREATE TABLE ANIMAL_PICS (NAME VARCHAR(32), PICTURE BLOB(16K))';
    $res = db2_exec($conn, $create);

    //Populate the view table
    $animals = array(
        array('Spook', 'spook.png'),
        array('Helmut', 'pic1.jpg')
    );

    $insert = 'INSERT INTO ANIMAL_PICS (NAME, PICTURE) VALUES (?, ?)';
    $stmt = db2_prepare($conn, $insert);
    if(!$stmt){
       echo "Attempt to prepare statement failed.";
       return 0;
    }

    foreach($animals as $row){
       $name = $row[0];
       $picname = $row[1];
       $picture = dirname(__FILE__) . "/$picname";
       db2_bind_param($stmt, 1, "name", DB2_PARAM_IN);
       db2_bind_param($stmt, 2, "picture", DB2_PARAM_FILE, DB2_BINARY);
       $res = db2_execute($stmt);
    }

Check …

SELECT USER FROM SYSIBM/SYSDUMMY1


/* i5/OS DB2 Maid Service (monitor QSQSRVR jobs) */
else {
/* level 4: try conn new statement (check statement) */
if (conn_res->c_i5_check_pconnect >= 4) {
  try_stmt_res = _db2_new_stmt_struct(conn_res);
  rc = SQLAllocHandle(SQL_HANDLE_STMT, conn_res->hdbc, &(try_stmt_res->hstmt));
  if (rc == SQL_SUCCESS && conn_res->c_i5_sys_naming > 0) {
    rc = SQLExecDirect((SQLHSTMT)try_stmt_res->hstmt, try_sys, strlen(try_sys));
  } else {
    rc = SQLExecDirect((SQLHSTMT)try_stmt_res->hstmt, try_sql, strlen(try_sql));
  }
  /* bind col */
  if (rc == SQL_SUCCESS) {
    rc = SQLBindCol((SQLHSTMT)try_stmt_res->hstmt, 1, SQL_CHAR, try_date, strlen(try_date), &try_date_len);
  }
  /* fetch data */
  if (rc == SQL_SUCCESS) {
    rc = SQLFetch((SQLHSTMT)try_stmt_res->hstmt);
  }
  SQLFreeHandle( SQL_HANDLE_STMT, try_stmt_res->hstmt);
  _php_db2_free_result_struct(try_stmt_res);
/* level 3: try allocate new statement (check allocate) */
} else if (conn_res->c_i5_check_pconnect >= 3) {
  try_stmt_res = _db2_new_stmt_struct(conn_res);
  rc = SQLAllocHandle(SQL_HANDLE_STMT, conn_res->hdbc, &(try_stmt_res->hstmt));
  SQLFreeHandle( SQL_HANDLE_STMT, try_stmt_res->hstmt);
  _php_db2_free_result_struct(try_stmt_res);
/* level 2: try conn get info (check meta data) */
} else if (conn_res->c_i5_check_pconnect >=2 ) {
  memset(server, 0, sizeof(server));
  rc = _php_db2_SQLGetInfo(conn_res->hdbc, SQL_DBMS_NAME, (SQLPOINTER)server, 2048, NULL);
/* level 1: try conn get an attribute (check attribute) */
} else {
  rc = SQLGetConnectAttr(conn_res->hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)&conn_alive, 0, NULL);
}

Github https://github.com/zendtech/IbmiToolkit

Clark Everetts: http://files.zend.com/help/Zend-Server/zend-server.htm#session_clustering_concept.htm

Clark Everetts: http://framework.zend.com/manual/2.2/en/modules/zendtool.introduction.html



php.ini:extension_dir="/usr/local/zendsvr/lib/php_extensions"


bash-4.2$ grep -i PHP_API_VERSION *
fopen_wrappers.h:#if PHP_API_VERSION < 20100412
php.h:#define PHP_API_VERSION 20100412
bash-4.2$ 
bash-4.2$ grep -i PHP_EXTENSION_DIR *
build-defs.h:#define PHP_EXTENSION_DIR       "/usr/local/zendsvr6/lib/php/201005


bash-4.2$ pwd
/usr/local/zendsvr/include/php/main
bash-4.2$ grep 20090626 *
build-defs.h:#define PHP_EXTENSION_DIR       "/usr/local/zendsvr/lib/php/20090626"
php.h:#define PHP_API_VERSION 20090626
grep: Operation not supported on socket
bash-4.2$ pwd
/usr/local/zendsvr/include/php/main
bash-4.2$ 

Yips compile ibm_db2.so (2014–02–12)

==============
How to compile:
===============
look under /home/aseiden/ibm_db2-1.9.6 for the shell scripts.  Copy to my home dir to create. 
zzallzs5.sh for Zend Server 5.
zzallzs6.sh for Zend Server 6.
Note: PHP_HOME is the key to it.

now compile for zs5 (in special folder not production folder)
cd /home/aseiden/ibm_db2-1.9.6
zzallzs5.sh
binary is in  /usr/local/zendsvr/lib/php/20090626/

now compile for zs6 (in special folder not production folder)
zzallzs6.sh
binary is in: /usr/local/zendsvr6/lib/php/20100525/


===========
deploy test
==========
zs5 (production folder)
cp /usr/local/zendsvr/lib/php_extensions/ibm_db2.so /usr/local/zendsvr/lib/php_extensions/ibm_db2.so-backup1
cp /usr/local/zendsvr/lib/php/20090626/ibm_db2.so /usr/local/zendsvr/lib/php_extensions/ibm_db2.so

zs6 (production folder)
cp /usr/local/zendsvr6/lib/php_extensions/ibm_db2.so /usr/local/zendsvr6/lib/php_extensions/ibm_db2.so-backup1
cp /usr/local/zendsvr6/lib/php/20100525/ibm_db2.so /usr/local/zendsvr6/lib/php_extensions/ibm_db2.so

Copy will fail if Zend Server is running (busy file) ...
ENDTCPSVR SERVER(*HTTP) INSTANCE(ZENDSVR or ZENDSVR6)
perform copy (cp)
strTCPSVR SERVER(*HTTP) INSTANCE(ZENDSVR or ZENDSVR6)

Find production folder number (20100525) ...
ls /usr/local/zendsvr/lib/php
ls /usr/local/zendsvr6/lib/php

ibm_db2 RPG stored procedure issue (2014–02–12)

<?php
require "connection.inc";

$conn = db2_connect($db,$uid,$pwd);

/*
for ($i=0;$i<5;$i++) {
echo "$i ".getmypid();
sleep(4);
}
*/

$sql = "call XMLSERVICE.ZZ243P(?,?)";
$stmt = db2_prepare($conn, $sql);

//if i use '000000000' the call would work
$key=0;
// $key = '000000000';
$errors="";
db2_bind_param($stmt,1,"key",DB2_PARAM_INOUT);
db2_bind_param($stmt,2,"errors",DB2_PARAM_INOUT);
if (db2_execute($stmt)) {
  echo $errors;
}
else {
   echo db2_stmt_errormsg();
}
?>

#####################################
# ibm_db2.c
#####################################
if (nullterm) {
  /* Z_STRVAL_PP(bind_data)[origlen] = '\0'; where did this come from??? */
  Z_STRVAL_PP(bind_data)[curr->param_size] = '\0';
}

ibm_db2 Luca issue ignore_uid with commit (2014–2−12)

/* ibm_db2.ini 0=SQL_TXN_NO_COMMIT; !0=default isolation (SQL_ATTR_TXN_ISOLATION)    */
STD_PHP_INI_ENTRY("ibm_db2.i5_allow_commit", "-42", PHP_INI_SYSTEM, OnUpdateLong,
  i5_allow_commit, zend_ibm_db2_globals, ibm_db2_globals)

conn_res->c_i5_allow_commit = IBM_DB2_G(i5_allow_commit);

/* set ibm_db2.ini options (defaults appear before _php_db2_parse_options) */
if (COMPILE_IS_PASE) {
 if (IBM_DB2_G(i5_servermode_subsystem) && IBM_DB2_G(i5_ignore_userid) < 1 && IBM_DB2_G(i5_all_connect) < 1) {
   rc = _php_db2_SQLSetConnectAttr((SQLHDBC)conn_res->hdbc, SQL_ATTR_SERVERMODE_SUBSYSTEM, (SQLPOINTER) IBM_DB2_G(i5_servermode_subsystem),  SQL_NTS); 
 }
 if (conn_res->c_i5_allow_commit == 0) {
   SQLINTEGER nocommitpase = SQL_TXN_NO_COMMIT;
   rc = _php_db2_SQLSetConnectAttr((SQLHDBC)conn_res->hdbc, SQL_ATTR_TXN_ISOLATION, (SQLPOINTER) nocommitpase, SQL_IS_INTEGER);
 }
 if (conn_res->c_i5_job_sort > 0) {
   rc = _php_db2_SQLSetConnectAttr((SQLHDBC)conn_res->hdbc, SQL_ATTR_CONN_SORT_SEQUENCE, (SQLPOINTER) SQL_JOBRUN_SORT_SEQUENCE, SQL_IS_INTEGER);
 }
 if (conn_res->c_i5_sys_naming > 0) {
   rc = _php_db2_SQLSetConnectAttr((SQLHDBC)conn_res->hdbc, SQL_ATTR_DBC_SYS_NAMING, (SQLPOINTER) SQL_TRUE, SQL_IS_INTEGER);
 }
}
/* SQL_AUTOCOMMIT_ON ... mmm ... always (original design) */
rc = _php_db2_SQLSetConnectAttr((SQLHDBC)conn_res->hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) (conn_res->auto_commit), SQL_IS_INTEGER);
/* Set Options */
if ( options != NULL ) {
 rc = _php_db2_parse_options( options, SQL_HANDLE_DBC, conn_res TSRMLS_CC );
 if (rc != SQL_SUCCESS) {
 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Options Array must have string indexes");
 }
}

ibm_db2 - verbose add SQLState (2014–02–12)

static void _php_db2_check_sql_errors( ...
sprintf((char *)errMsg, "SQLSTATE=%s SQLCODE=%d %s", sqlstate, (int)sqlcode, msg);
if (IBM_DB2_G(i5_log_verbose) > 0) {
 php_error_docref(NULL TSRMLS_CC, E_WARNING, (char *)errMsg);
}

DB2 LIMIT workaround (old)

SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY key ASC) AS rownum, * FROM T) AS foo WHERE rownum > skip AND rownum <= (n+skip)


SELECT code, name, address
FROM ( 
  SELECT row_number() OVER ( ORDER BY code ) AS rid, code, name, address
  FROM contacts
  WHERE name LIKE '%Bob%' 
  ) AS t
WHERE t.rid BETWEEN 20 AND 25;

PCML big issues (old)

Attach: http://174.79.32.155/wiki/uploads/XMLSERVICE/pcml_sample.txt

RPG embedded PHP (old idea)

Based on RPG < call > PASE Running example RPG program loading PASE shared library and calling function (PASE libmy.a → accounts)


-------------

php.so -- php as a slave language
===============
Non-ILE example
===============
Precedent would be like Apache mod_php.so ...
Apache <branch and link> mod_php.so 
- load dlopen mod_php.so (linux/aix)
- single process (but usually threaded)
- API parms by memory 
- well documented apache interface 

=============================================
ILE interface (i5/OS PASE ILE Procedure APIs)
=============================================
PASE side: Similar to Apache but a new API php.so ...
- need some new APIS not as complex as mod_php.so Apache 
Example:
int runMyScript(char * name, char * buffer)
- name - name of script /www/zendsvr/htdocs/myscript.php
- buffer - input/output buffer (similar to stdout in apache mod_php)

ILE side: Apache<cgi>RPG/C ILE<qp2callpase> php.so
(see running example of potential ILE interface RPG < call > PASE) 
- qp2runpase /usr/lib/start32 (start pase and leave active in ILE process)
- qp2dlopen load php.so (PASE shared object load)
- qp2dlsym look-up call functions in php.so (runMyScript in php.so)
- qp2callpase to call the look-up symbol function
- qp2malloc use PASE seen memory for calls
- RPG CGI are rarely threaded (never)

=============
Moving parts:
==============
1) User: RPG *PGM/*SRVPGM -- CGI, green screen, etc.)
2) Zend: RPGPHP *SRVPGM -- ILE API to PHP (/copy rpgphp_h)
3) Zend: pecl ilecall.so -- PHP callback ILE API (string i_callback(...))
4) User: callback.php -- script doing things and calling back to ILE user program

===============
Simple Example:
===============
      (1)                    (2)                            (3)                          (4)
===== User RPG ========= === Zend RPGPHP (*SRVPGM) ===  === PHP pecl ilecall.so ===  === PHP script ===
myCall(...)              int zendCallBack(...)          string i_callback(...)

// php callbak.php
// call my function
// with parameters
// (max 64 parms)
---------------------->zendCallBack(
                          %addr(myCtl)                  // ILE callback(64 parms)
                          :'/path/php-cli'              // using php-cli for demo
                          :'/path/callback.php'         // calling script
                          :argv[]                       // with arguments (argv[])
                          :envp[]                       // and env vars   (envp[])
                          :paseCCSID                    // BUT missing php.so
                          );                            // to keep php alive
                          ----------------------------->php start (if needed)
                                                        ilecall.ini (ilecall.so)
                                                        ---------------------------->callback.php(argv[])
                                                                                     <?php
                                                                                     $p1 = "skip0";
                                                                                     // loop callback
                                                                                     while(1) {
// this case a simple 10a return                                                       // case very simple
// but could be very complex                                                           // strings, but
// RPG DS (data structure)                                                             // could be complex
// parms are coming from PHP                                                           // to map between
// also could be complex DS                                                            // $p(s) and $ds
D myCall          PI            10a <-----------------------------------------------   $ds = i_callback(
D  p1                           10a                                                      $p1);
select;                                                                                switch ($ds) {
when p1 = "skip0";                                                                       case "skip1":
  // php skip1                                                                             $p1 = "hop1"; // rpg hop1
  return "skip1";                                                                          break;
when p1 = "hop1";                                                                        case "skip2":
  // php skip2                                                                             $p1 = "hop2"; // rpg hop2
  return "skip2";                                                                          break;
when p1 = "hop2";                                                                        case "skip3":
  // php skip3                                                                             $p1 = "quit"; // rpg quit
  return "skip3";                                                                          break;
// ????                                                                                  // ????
other;                                                                                   default:
  return "quit";                                                                           break;        // script end
endsl;                                                                                 }
return "done";                                                                       }

#Anchor Name