@@ -15,23 +15,7 @@ function d($dieOutput = 'x')
15
15
}
16
16
die ($ str );
17
17
}
18
- // return value from toolkit config file,
19
- // or a default value, or false if not found.
20
- /*function getConfigValue($heading, $key, $default = null) {
21
- // TODO store once in a registry or the like
22
-
23
- // true means use headings
24
- $config = parse_ini_file(CONFIG_FILE, true);
25
- if (isset($config[$heading][$key])) {
26
- return $config[$heading][$key];
27
- } elseif (isset($default)) {
28
- return $default;
29
- } else {
30
- return false;
31
- }
32
-
33
- } //(getConfigValue)
34
- */
18
+
35
19
// create unique IPC code
36
20
function makeIpc ($ user , $ connNum = 0 ) {
37
21
$ ipcUser = ($ user ) ? $ user : DB2_DEFAULT_USER ;
@@ -46,16 +30,6 @@ function makeIpc($user, $connNum = 0) {
46
30
} //(makeIpc)
47
31
48
32
49
- /*function logThis($msg) {
50
- $logFile = getConfigValue('log','logfile');
51
- if ($logFile) {
52
- // it's configured so let's write to it. ("3" means write to a specific file)
53
- $formattedMsg = "\n" . microDateTime() . ' ' . $msg;
54
- error_log($formattedMsg, 3, $logFile);
55
- }
56
- } //(logThis)
57
- */
58
-
59
33
function splitLibObj ($ objName , $ defaultLib = '' ) {
60
34
// given an object name that MAY be qualified by a library and slash and perhaps a function,
61
35
// such as "xxx/yyy(zzzz)".
@@ -141,7 +115,7 @@ function i5CpfError($errMsg = '', $errDesc = '')
141
115
*/
142
116
function noError ()
143
117
{
144
- // Shortcut (fewer params) when have an IBM i (AS400) code and message .
118
+ // Clear any error information .
145
119
i5ErrorActivity (I5_ERR_OK , 0 , '' , '' );
146
120
147
121
} //(noError)
@@ -284,18 +258,20 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
284
258
} //(if (isset($options[CW_EXISTING_TRANSPORT_CONN])))
285
259
286
260
261
+
287
262
// check and store CW_TRANSPORT_TYPE, if given. It's optional.
288
263
$ transportType = '' ; // empty is ok.
289
- if (isset ( $ options [CW_TRANSPORT_TYPE ])) {
290
- $ validTransports = array ('ibm_db2 ' , 'odbc ' );
291
- if (!in_array ($ options [CW_TRANSPORT_TYPE ], $ validTransports )) {
264
+ $ iniTransportType = isset ( $ options [CW_TRANSPORT_TYPE ]) ? $ options [CW_TRANSPORT_TYPE ] : getConfigValue ('transport ' , 'transportType ' , 'ibm_db2 ' );
265
+ if ($ iniTransportType ) {
266
+ $ validTransports = array ('ibm_db2 ' , 'odbc ' , 'http ' );
267
+ if (!in_array ($ iniTransportType , $ validTransports )) {
292
268
// invalid transport specified.
293
- $ errmsg = "Invalid CW_TRANSPORT_TYPE option ( {$ options [ CW_TRANSPORT_TYPE ] }). Omit or choose between " . explode (', ' , $ validTransports ) . ". " ;
269
+ $ errmsg = "Invalid CW_TRANSPORT_TYPE option ( {$ iniTransportType }). Omit or choose between " . explode (', ' , $ validTransports ) . ". " ;
294
270
i5ErrorActivity ( I5_ERR_PHP_TYPEPARAM , I5_CAT_PHP , $ errmsg , $ errmsg );
295
271
return false ;
296
272
} else {
297
273
// valid transport
298
- $ transportType = $ options [ CW_TRANSPORT_TYPE ] ;
274
+ $ transportType = $ iniTransportType ;
299
275
} // (if (!is_resource))
300
276
} //(if (isset($options[CW_EXISTING_TRANSPORT_CONN])))
301
277
@@ -333,9 +309,10 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
333
309
// user/pw rules
334
310
// TODO share these with i5_adopt_authority
335
311
336
- // forbid QSECOFR and usernames starting with *. (dont want *CURRENT, etc.)
312
+ // forbid QSECOFR and usernames starting with *. (don't want *CURRENT, etc.)
313
+ // TODO Actually, not sure if QSECOFR and special profiles should be forbidden. Check again with old toolkit.
337
314
if ((strtoupper ($ user ) == 'QSECOFR ' ) || (substr ($ user , 0 , 1 ) == '* ' ) || empty ($ password ) || (substr ($ password , 0 , 1 ) == '* ' )) {
338
- i5ErrorActivity (I5_ERR_WRONGLOGIN , I5_CAT_PHP , 'Bad login user or password ' , 'Cannot adopt authority to QSECOFR or special profiles ' );
315
+ i5ErrorActivity (I5_ERR_WRONGLOGIN , I5_CAT_PHP , 'Bad login user or password ' , 'Cannot connect with QSECOFR, blank password, or special profiles ' );
339
316
return false ;
340
317
} //(if QSECOFR)
341
318
@@ -352,6 +329,11 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
352
329
$ tkit = ToolkitServiceCw::getInstance ($ dbname , $ user , $ password , $ transportType , $ isPersistent );
353
330
} //(if ($existingTransportResource))
354
331
332
+ // if getInstance() returned false (unlikely)
333
+ if (!$ tkit ) {
334
+ setError (I5_ERR_NOTCONNECTED , I5_CAT_PHP , 'Cannot get a connection ' , 'Cannot get a connection ' );
335
+ } //(if (!$tkit))
336
+
355
337
} catch (Exception $ e ) {
356
338
357
339
// If user or password is wrong, give errNum I5_ERR_WRONGLOGIN with category I5_CAT_PHP.
@@ -380,6 +362,10 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
380
362
return false ;
381
363
}
382
364
365
+ // successfully instantiated toolkit connection and instance. Mark it as CW.
366
+ $ tkit ->setIsCw (true );
367
+
368
+
383
369
// override toolkit settings if nec.
384
370
$ sbmjobParams = getConfigValue ('system ' , 'sbmjob_params ' );
385
371
$ xmlServiceLib = getConfigValue ('system ' , 'XMLServiceLib ' , 'ZENDSVR ' );
@@ -407,6 +393,7 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
407
393
$ ipc = '' ;
408
394
logThis ("Running stateless; no IPC needed. CW version $ cwVersion. Service library: $ xmlServiceLib " );
409
395
} else {
396
+ // TODO does this make sense? Not stateless but not private? Any purpose to stateless setting in INI file?
410
397
// Not stateless, so create an IPC
411
398
// TODO this will change based on persistent/nonpersistent logic
412
399
// IPC to use in separate toolkit job using just user id and unique additions in makeIpc
@@ -461,7 +448,7 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
461
448
462
449
// set IPC and other settings
463
450
464
- $ serviceParams = array ('InternalKey ' => $ ipc ,
451
+ $ serviceParams = array ('internalKey ' => $ ipc ,
465
452
'stateless ' => $ stateless );
466
453
467
454
// additional settings
@@ -473,8 +460,11 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
473
460
$ serviceParams ['sbmjobParams ' ] = $ sbmjobParams ;
474
461
}
475
462
476
- // these will be in addition to / overriding any params set in toolkit service constructor.
477
- $ tkit ->setToolkitServiceParams ($ serviceParams );
463
+ // CW always retains data structure hierarchy (integrity) in parameters.
464
+ $ serviceParams ['dataStructureIntegrity ' ] = true ;
465
+
466
+ // these will be in addition to, or overriding, any params set in toolkit service constructor.
467
+ $ tkit ->setOptions ($ serviceParams );
478
468
479
469
// initialize
480
470
$ cmdArray = array ();
@@ -610,9 +600,10 @@ function i5_adopt_authority($user, $password, $connection = null)
610
600
$ user = strtoupper ($ user );
611
601
$ password = strtoupper ($ password );
612
602
603
+
613
604
// check that username and password vars are OK.
614
- // forbid QSECOFR; and forbid usernames/pwds starting with *. (dont want *CURRENT, etc. )
615
- if ((strtoupper ($ user ) == 'QSECOFR ' ) || ( substr ( $ user , 0 , 1 ) == ' * ' ) || empty ($ password) || ( substr ( $ password , 0 , 1 ) == ' * ' )) {
605
+ // forbid QSECOFR and empty password (though special values such as *NOPWDCHK are OK )
606
+ if ((strtoupper ($ user ) == 'QSECOFR ' ) || empty ($ password )) {
616
607
i5ErrorActivity (I5_ERR_WRONGLOGIN , I5_CAT_PHP , 'Bad login user or password ' , '' );
617
608
return false ;
618
609
} //(if QSECOFR)
@@ -635,13 +626,23 @@ function i5_adopt_authority($user, $password, $connection = null)
635
626
<data var='handleOut' type='12b' comment='really binary data not character' />
636
627
</parm> \n" .
637
628
// param number 4
638
- ToolkitServiceCw::getErrorDataStructXml (4 ) . "\n" .
629
+ ToolkitServiceCw::getErrorDataStructXml (4 ) . "\n" ;
630
+
631
+ if (substr ($ password , 0 , 1 ) != '* ' ) {
632
+ /* No asterisk at the start, so this is an attempt at a real password,
633
+ * not a special pw value starting with an asterisk such as *NOPWD, *NOPWDCHK, or *NOPWDSTS.
634
+ * Therefore, include pw len and CCSID, which must be omitted if pw is a special "*" value.
635
+ */
636
+ $ paramXml .=
639
637
"<parm io='both' comment='5. length of password. Must be equal to the actual pw length. '>
640
638
<data var='pwLen' type='10i0'> $ pwLen</data>
641
639
</parm>
642
640
<parm io='in' comment='6. CCSID of password'>
643
641
<data var='pwCcsid' type='10i0'> $ pwCcsid</data>
644
642
</parm> " ;
643
+
644
+ } // (if (substr($password, 0, 1) != '*'))
645
+
645
646
646
647
647
648
// In case of error, look for CPFs generated by specific other programs.
@@ -895,8 +896,9 @@ function i5_command($cmdString, $input = array(), $output = array(), $connection
895
896
896
897
// Use slower but improved "result" (REXX) technique
897
898
$ result = $ connection ->ClCommandWithOutput ($ finalCmdString );
898
-
899
+
899
900
if ($ result ) {
901
+
900
902
// Command succeeded. Set and export output variables.
901
903
$ exportedThem = $ connection ->setOutputVarsToExport ($ simpleParmVarArray , $ result );
902
904
} else {
@@ -2050,34 +2052,28 @@ function i5_data_area_read($name, $offsetOrConnection = null, $length = null, $c
2050
2052
return false ;
2051
2053
}
2052
2054
2055
+
2053
2056
// params OK at this point
2057
+
2058
+ // adjust length for "all"
2059
+ $ lengthToUse = $ length ;
2060
+ if (!$ length || ($ length <= 0 )) {
2061
+ // length not provided or 0 or -1: use *ALL
2062
+ $ lengthToUse = '*ALL ' ;
2063
+ } //(length absent or <= 0)
2064
+
2054
2065
2055
2066
// If a library (optional--slash delimited), separate it.
2056
- // use *CURLIB if no library specified
2067
+ // use *LIBL if no library specified
2057
2068
$ name = strtoupper ($ name );
2058
- $ libAndObj = splitLibObj ($ name , '*CURLIB ' );
2069
+ $ libAndObj = splitLibObj ($ name , '*LIBL ' );
2059
2070
2060
2071
try {
2061
- if ($ length ) {
2062
-
2063
2072
$ dataAreaObj = new DataArea ($ connection );
2064
2073
$ dataAreaObj ->setDataAreaName ($ libAndObj ['obj ' ], $ libAndObj ['lib ' ]);
2065
2074
2066
- $ value = $ dataAreaObj ->readDataArea ($ offset , $ length );
2067
- } else {
2068
- // use cl command that can tolerate *ALL (full length) as an option
2069
- $ cmdString = "RTVDTAARA DTAARA( {$ libAndObj ['lib ' ]}/ {$ libAndObj ['obj ' ]} *ALL) " ;
2070
- $ input = array ();
2071
- $ output = array ('rtnvar ' =>'dataAreaValue ' );
2072
-
2073
- $ commandSuccessful = i5_command ($ cmdString , $ input , $ output );
2074
- if ($ commandSuccessful ) {
2075
-
2076
- extract (i5_output ()); //creates $dataAreaValue
2077
- $ value = $ dataAreaValue ;
2078
- }
2075
+ $ value = $ dataAreaObj ->readDataArea ($ offset , $ lengthToUse );
2079
2076
2080
- }
2081
2077
} catch (Exception $ e ) {
2082
2078
i5CpfError ('Error reading from data area ' , $ e ->getMessage ());
2083
2079
return false ;
@@ -2144,9 +2140,9 @@ function i5_data_area_write($name, $value, $offsetOrConnection = null, $length =
2144
2140
// (This could be left up to users, but it's easy for us to do. See how this goes.)
2145
2141
$ value = "' " . trim ($ value , "' " ) . "' " ;
2146
2142
2147
- // Split library (use *CURLIB if no library specified) and program names
2143
+ // Split library (use *LIBL if no library specified) and program names
2148
2144
$ name = strtoupper ($ name );
2149
- $ libAndObj = splitLibObj ($ name , '*CURLIB ' );
2145
+ $ libAndObj = splitLibObj ($ name , '*LIBL ' );
2150
2146
2151
2147
$ dataAreaObj = new DataArea ($ connection );
2152
2148
$ dataAreaObj ->setDataAreaName ($ libAndObj ['obj ' ], $ libAndObj ['lib ' ]);
@@ -2182,8 +2178,8 @@ function i5_data_area_delete($name, $connection = null)
2182
2178
2183
2179
// params OK at this point
2184
2180
2185
- // Split library (use *CURLIB if no library specified) and program names
2186
- $ libAndObj = splitLibObj ($ name , '*CURLIB ' );
2181
+ // Split library (use *LIBL if no library specified) and program names
2182
+ $ libAndObj = splitLibObj ($ name , '*LIBL ' );
2187
2183
2188
2184
$ dataAreaObj = new DataArea ($ connection );
2189
2185
try {
@@ -2596,13 +2592,17 @@ function i5_objects_list($library, $name = '*ALL', $type = '*ALL', $connection =
2596
2592
// now call it!
2597
2593
// pass param xml directly in.
2598
2594
$ retPgmArr = $ connection ->PgmCall ($ apiPgm , $ apiLib , $ paramXml );
2599
-
2595
+ //var_dump($retPgmArr);
2596
+ //die;
2597
+ // there's a problem parsing the output xml.
2598
+
2599
+
2600
2600
if ($ connection ->getErrorCode ()) {
2601
2601
i5ErrorActivity (I5_ERR_PHP_AS400_MESSAGE , I5_CAT_PHP , $ connection ->getErrorCode (), $ connection ->getErrorMsg ());
2602
2602
return false ;
2603
2603
}
2604
2604
2605
-
2605
+
2606
2606
$ retArr = $ retPgmArr ['io_param ' ]['listinfo ' ]; // 'listinfo' defined in getListInfoApiXml()
2607
2607
$ totalRecords = $ retArr ['totalRecords ' ];
2608
2608
$ requestHandle = $ retArr ['requestHandle ' ];
@@ -2799,7 +2799,7 @@ function i5_objects_list_close(&$list)
2799
2799
Return Values: Resource if OK, false if failed.
2800
2800
Arguments:
2801
2801
$name - The queue name
2802
- $description - Data description in format defined by program¬_prepare . For more, see PHP Toolkit Data Description.
2802
+ $description - Data description in format defined by program_prepare . For more, see PHP Toolkit Data Description.
2803
2803
[$key - key size - for keyed DataQ (can be omitted)]
2804
2804
[$connection - Connection - result of i5_connect]
2805
2805
*/
@@ -3565,9 +3565,9 @@ function i5_output() {
3565
3565
3566
3566
3567
3567
/**
3568
- * Return version number of CW
3568
+ * Return version number of CW and PHP toolkit front-end.
3569
3569
*/
3570
3570
function i5_version () {
3571
- return ToolkitServiceCw:: getVersion ();
3571
+ return ToolkitService:: getFrontEndVersion ();
3572
3572
}
3573
3573
0 commit comments