23
Tue, Apr
1 New Articles

Change the Last-Used Date of an IBM i System Object Arbitrarily

RPG
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

A practical tool program can achieve that goal.

 

When issuing a DSPOBJD DETAIL(*FULL) command on an IBM i object, you might have noticed the Last used date field in the Change/Usage Information portion of the result display. As its name indicates, the Last used date attribute is the date on which the object was used the last time. As you probably know, the last-used date attribute is not stored in the Object Information Repository (OIR) space of the context in which the object resides. Instead, it's stored in the EPA header of an MI object as a 2-byte field. The last-used date attribute of an external object can be retrieved via the Retrieve Object Description (QUSROBJD) API, and the last-used date attribute of an MI object can be retrieved via the Materialize System Object (MATSOBJ) MI instruction. The Change Object Description (QLICOBJD) API can be used to update the last-used date of an external object to the current system date.

 

However, there is no interface that allows a user program to change the last-used date attribute of an object arbitrarily. This article introduces a technique to achieve that goal so that you can add another practical tool to your toolkit. Many thanks to Gene Gaunt who introduced this technique!

 

The following is quoted from a post by Gene in a discussion thread back in 2002 in the MI400 mailing list, Re: Update Last Day used of a program:

 

Yes MI can change an object last used date. MODSOBJ is the instruction. Operand one is a system pointer to target object. Operand two is a modification options character scalar.

 

If the options position 1, bit X'10', is on, then if the options position 17, bit X'40', is on, then the two bytes in position 27 and 28 are the

first two bytes of an 8-byte system date/time stamp of the last used date that you want. For example, X'8527' = 11/15/2002, and X'8529' =

11/16/2002, get it. Here is an MI example:

 

DCL SYSPTR ?OBJECT   AUTO;

DCL DD     OPTIONS   AUTO CHAR(64);

DCL DD     STAMP2   AUTO CHAR(2);

 

CPYBREP   OPTIONS, X"00";

OR(S)     OPTIONS(1:1), X"10";

OR(S)     OPTIONS(17:1), X"40";

CPYBLA     OPTIONS(27:2), STAMP2;

MODSOBJ   ?OBJECT, OPTIONS;

 

Of course you need code above this to:

(1) Fill ?OBJECT with a system pointer to your target object (RSLVSP is one way).

(2) Fill STAMP2 with the first two bytes of a system date/time stamp of the last used date that you want (QWCCVTDT API with output format '*DTS' is one way).

 

If the translator state blocks MODSOBJ from compiling, then change MODSOBJ to SETDPAT, and compile. SETDPAT generates similar code to MODSOBJ, one byte different. The system call vectored number for SETDPAT is X'0043', for MODSOBJ is X'00A3'. With some tool like Display/Alter/Dump, change the appropriate X'0043' to X'00A3', and there you have a Change Object Last Used Date utility!

 

Gene's technique can be concluded as the following steps:

  1. Resolve a system pointer to the target MI object.
  2. Calculate the 2-byte date value to set as the last-used date of the target MI object.
  3. Prepare the 64-byte modification template (OPTIONS) to pass to the Modify System Object (MODSOBJ) MI instruction, which is a blocked MI instruction.
  4. Replace the MODSOBJ MI instruction in the source code with a Set Data Pointer Attribute (SETDPAT) MI instruction to allow the source program get compiled.
  5. Note: The operands of these two MI instructions are the same, while the SETDPAT instruction is a non-blocked instruction.
  6. In the RISC instruction stream of the created program object, replace the SCV call (with operand 10) function number for the SETDPAT MI instruction (hex 43) with the SCV 10 function number for the MODSOBJ MI instruction (hex A3).

 

To allow the modified program that invokes the MODSOBJ MI instruction to run at security level 40 or above, change the program state of the program from user state to system state, since MODSOBJ is a blocked MI instruction.

 

This article discusses the above-shown technique in detail. A complete example RPG program following Gene's technique is provided at the end of article.

The 2-Byte Date Value

The last-used date field of an MI object is a 2-byte field in the EPA header of the MI object at offset hex B0 from the start of the EPA header (i.e., offset hex D0 from the beginning of the MI object). In the SST dump of an MI object, the last-used date field is named USDAY. After a successful invocation of the MODSOBJ MI instruction on an MI object in order to change the last-used date attribute of the MI object, the USDAY field in the EPA header (EPA.USDAY) of the MI object is set to the 2-byte field in the modification template of MODSOBJ at position 27. The EPA.USDAY field is the first two bytes of an 8-byte system time-stamp in the Standard Time Format. A binary 1 in bit 48 of the system time-stamp is equal to 8 microseconds. Therefore, the minimum time interval that can be represented by a 2-byte date value (i.e., hex 0001) can be calculated via the following formula:

 

min-time-interval = hex 0001,0000,0000,0000 >> 15 * 8 (microseconds)

 

The result is about 19 hours. As you might have noticed, it is possible for a specific date to be represented by two different 2-byte date values.

 

As Gene suggested in his post, such a 2-byte date value can be obtained by calling the QWCCVTDT API with output format '*DTS'. Another possible way is to convert a time-stamp value into the system time-stamp via the Convert Timestamp (CVTTS) MI instruction (please refer to t173.rpgle for an example of using the CVTTS instruction). Since the maximum time interval represented by the truncated 6 bytes of the original 8-byte system time-stamp cannot exceed 20 hours, it's reasonable to set the time portion of the input time-stamp value to QWCCVTDT or CVTTS to 20:00:00. The following piece of RPG code is an example of how to obtain a 2-byte date value via the Convert Date and Time Format (QWCCVTDT) API.

 

     d dat2           s             2a

      *   Value of the input time-stamp in *YMD format is:

     * 1999-12-31.20.00.00.000000

     c                   eval     input = '0991231200000000'

     c                   call     'QWCCVTDT'

     c                   parm     '*YMD'       in_fmt          10

     c                   parm                   input           16

     c                   parm     '*DTS'       out_fmt         10

     c                   parm                   sys_clock         8

     c                   parm     *allx'00'     ec               8

     c                   movel     sys_clock     dat2

 

Blocked MI Instructions

The key of the technique being discussed here is the MODSOBJ MI instruction, which is one of the blocked MI instructions. An attempt to execute a blocked instruction at security level 40 or above will raise a hex 4401 (Object Domain or Hardware Storage Protection Violation) exception (aka MCH6801). I'm too young to know when and how this limit on the user programs was added. But the forum posts and work of several IBM i (AS/400) gurus reveal some details. Simon Coulter wrote in his post in a discussion thread named AS/400 STILL wearing the undeserved "closed system" moniker in the MIDRANGE-L mailing list in 2001:

 

Lets say you wanted to write your own operating system to replace OS/400. What kind of hoops would you have to jump through to get THAT kind of info from IBM? Or couldn't get them at all?

 

This was certainly possible on the S/38 where documentation in the form of  the S/38 Functional Concepts manual, S/38 Functional Reference Vol 1, and  S/38 Functional Reference Vol 2 would have provided most, if not all, you need to know about the MI level. The proviso is that you would build your OS on top of the LIC.

 

It is harder on the AS/400 because Rochester have blocked the MI instructions they feel we don't need to know about (e.g., source/sink instructions so that pretty much buggers up any I/O routines) and privide only an expurgated version of the MI reference.

 

In Chapter 18, (SCV) Supervisor Call Vectored, of the AS/400 Machine Level Programming e-book, Leif Svalgaard gave an in-depth discussion about how blocked MI instructions are getting stopped when being invoked from a user-state program at security level 40 or above.

SCV 10

According to Leif's AS/400 Machine Level Programming e-book:

 

For the AS/400 implementation IBM introduced two additional (and undocumented) instructions for the PowerPC to allow an efficient way for one SLIC routine to call another or for a user program to call a SLIC routine. These instructions are called "Supervisor Call Vectored" (SCV) and "Return From Supervisor Call Vectored" (RFSCV).

 

When the SCV (Supervisor Call Vectored) instruction is executed with an operand of 10, General Purpose Register 10 holds the function number. ... Most complicated MI-instructions are implemented as SCV calls.

 

The vector with selector value 10 is by far the most common SCV call. Registers from R3 and up are used to pass parameters to the call. Register R10 has a special purpose, as it holds the number of the function to be executed.

 

Leif also provided the function numbers (in R10) for different MI instructions in appendix E, SCV 10 Function Numbers. For example, the SCV 10 function number is 163 (hex A3) for the MODSOBJ MI instruction, 31 (hex 1F) for the Modify Space (MODS1) MI instruction.

 

Leif pointed out that: "There are only a few cases where a function that was earlier executed through SCV 10 is now done differently." And the SETDPAT MI instruction chosen by Gene in his post was one of those "few cases." (Today, the RISC instructions generated for a SETDPAT instruction do not use a SCV call anymore.) Thus in the example shown below, one of the MODS MI instructions (MODS1, MODS2) will be chosen instead of SETDPAT.

A Real RPG Example Program: LASTU

Now let's implement an actual tool program that can be used to set the last-used date of an object arbitrarily following Gene's technique. The following is an ILE RPG program, lastu.rpgle, that accepts a qualified object name, a CHAR(10) object type name, and a 8-byte date value in MMDDYYYY format as its input parameters.

 

LASTU

     /**

     * @file lastu.rpgle

     *

     * Change the last-used date attribute   of an object.

     *

     * Parameters:

     *   - CHAR(20) qualified object name. e.g. 'OBJNAME   *LIBL       '

     *   - CHAR(10) object type. e.g. '*USRSPC     '

     *   - CHAR(8) date in form of 'MMDDYYYY'

     *

     * @remark Make sure that the LASTU   program uses a unique

     *         activation group.

     */

 

     /if defined(*crtbndrpg)

     h dftactgrp(*no) actgrp('LASTU')

     /endif

 

     /copy mih-ptr

     /copy mih-undoc

     /copy mih-spc

 

     * Qualified objat name

     d qual_obj_t     ds                 qualified

     d     obj                         10a

     d     lib                         10a

 

     * Propotype of the main procedure

     d i_main         pr                 extpgm('LASTU')

     d     obj                                 likeds(qual_obj_t)

     d     obj_type                   10a

     d     last_used_dt                 8a

 

     * Prototype of procedure rslv_obj()

     d rslv_obj       pr             n

     d     obj                                 likeds(qual_obj_t)

     d     obj_type                   10a

     d     obj@                         *

 

     * Prototype of the QWCCVTDT API

     d QWCCVTDT       pr                 extpgm('QWCCVTDT')

     d     in_fmt                     10a

     d     in_var                       1a     options(*varsize)

     d     out_fmt                     10a

     d     out_var                     1a     options(*varsize)

     d     ec                          8a     options(*varsize)

 

     d mdyy_fmt       s             10a     inz('*MDYY')

     d dts_fmt         s             10a     inz('*DTS')

     d mdyy_date       s             17a

     d sys_ts         ds

     d STAMP2                        2a     overlay(sys_ts:1)

     d ec             s             8a     inz(*allx'00')

     d obj@           s               *

     d mod_opt         s             64a

 

     d i_main         pi

     d     obj                                 likeds(qual_obj_t)

     d     obj_type                   10a

     d     last_used_dt                 8a

 

     /free

           // [1] Resolve target MI object

           if not rslv_obj(obj : obj_type :   obj@);

               // Error handling

               *inlr = *on;

               return;

           endif;

 

           // [2] Convert input date value to   8-byte system time-stamp

           %subst(mdyy_date:1:8) =   last_used_dt;

           %subst(mdyy_date:9:9) =   '200000000'; // 20:00:00

           QWCCVTDT( mdyy_fmt

                  : mdyy_date

                   : dts_fmt

                   : sys_ts

                   : ec );

 

           // [3] Modify the last-used date   of target MI object

           mod_opt = *allx'00';

           %subst(mod_opt:1:1) = x'10';

          %subst(mod_opt:17:1) = x'40';

           %subst(mod_opt:27:2) = STAMP2;

           mods2(obj@:mod_opt); // STMT   NUM=940

 

           *inlr = *on;

     /end-free

 

     p rslv_obj       b

 

     * Prototype of the QLICVTTP API

     d QLICVTTP       pr                  extpgm('QLICVTTP')

     d     cvn                         10a

     d     sym_type                   10a

     d     mi_type                     2a

     d     ec                           8a

 

     d LIBL           c                   '*LIBL'

     d LIB_QTEMP       c                   'QTEMP'

     d ec             s             8a     inz(*allx'00')

     d cvn             s             10a     inz('*SYMTOHEX')

     d mi_type         s             2a

     d ctx             s               *

     d rtn             s               n   inz(*on)

 

     d rslv_obj       pi             n

     d     obj                                 likeds(qual_obj_t)

     d     obj_type                   10a

     d     obj@                         *

 

     /free

           // [1.1] Convert symbolic object   type to hex MI object type

           QLICVTTP( cvn

                   : obj_type

                   : mi_type

                   : ec );

 

           // [1.2] Resolve target MI object

           monitor;

               if obj.lib = LIBL;

                   rslvsp_tmpl.obj_type =   mi_type;

                   rslvsp_tmpl.obj_name =   obj.obj;

                   rslvsp2(obj@ :   rslvsp_tmpl);

               else;

                   if obj.lib = LIB_QTEMP;

                       ctx = qtempptr();

                   else;

                       rslvsp_tmpl.obj_type =   x'0401';

                       rslvsp_tmpl.obj_name =   obj.lib;

                       rslvsp2(ctx :   rslvsp_tmpl);

                   endif;

                   rslvsp_tmpl.obj_type =   mi_type;

                   rslvsp_tmpl.obj_name =   obj.obj;

                   rslvsp4(obj@ : rslvsp_tmpl   : ctx);

               endif;

           on-error;

               rtn = *off;

           endmon;

 

           return rtn;

     /end-free

     p                 e

 

Notes

  • [1] Resolve a system pointer (obj@) to the target MI object via the input qualified object name.
  • [1.1] Convert the input symbolic object type name to a 2-byte MI object type code via the Convert Type (QLICVTTP) API.
  • [1.2] Actually resolve the target MI object via the Resolve System Pointer (RSLVSP) MI instruction.
  • [2] Convert the input date value to an 8-byte system time-stamp, the leftmost 2 bytes of which is used as the 2-byte date value to set on the target MI object.
  • [3] Set the 2-byte date value on the target MI object.

 

Note that the MODS2 MI instruction is used here to allow the LASTU program to get compiled. The invocation to MODS2 will be replaced by an invocation to the MODSOBJ MI instruction later. System built-in _MODS2 is prototyped in mih-spc.rpgle.

The SCV 10 Function Number Generated for the MODS2 MI Instruction

A quick way to obtain the SCV 10 function number generated for the MODS2 MI instruction is:

  1. Get a program that issues MODS2 compiled.
  2. Inspect the RISC instruction stream of the program and check the SCV 10 function number generated for MODS2.

 

For example, compile the following tiny ILE C program (scv10mods2.c):

 

# include <stdlib.h>

 

# pragma linkage(_MODS1,   builtin)

void _MODS1(void**, void*);

 

# pragma linkage(_MODS2,   builtin)

void _MODS2(void**,   void*);

 

int main() {

void* p = NULL;

void* a = NULL;

 

_MODS1(&p, p); // stmt num: 3

_MODS2(&p, p); // stmt num: 4

 

return 0;

}

 

Start a System Service Tools (SST) session and choose the following menu items:

 

1. Start a service tool

4. Display/Alter/Dump

1. Display/Alter storage or 2. Dump to printer

1. Machine Interface (MI) object

2. Program (02)

1. Find by object name and context name

 

Enter the program name and library (context) name in the Find by Object Name and Context Name display:

 

                     Find By Object Name And   Context Name

 

Output device . . . . . . :   Display

 

Type choices, press Enter.

 

   Object:

     Type . . . . . . . . . :   (02) - Program

     Name . . . . . . . . . .   ______________________

     Subtype   . . . . . . . .   01   00-FF

 

   Context:                     ______________________

     Name . . . . . . . . . .

     Subtype   . . . . . . . .   01   00-FF

 

   Auxiliary Storage Pool:

     Number . . . . . . . . .     1     1-255

 

Choose menu item 3, Disassembled code, in the Select Format display.

 

Search for RISC INSTRUCTIONS (main to find the RISC instructions generated for the main() procedure of the compiled program in the SST dump result. The RISC instructions generated for the invocations of _MODS1 and _MODS2 (in statements 3 and 4, respectively) might look like the following:

 

RISC INSTRUCTIONS (MAIN ...   ...

LOCATION   OBJECT TEXT       SOURCE STATEMENT                       STATEMENT NUMBERS  BREAKPOINT NUMBERS

... ...

000050     3B9FFFE0         ADDI   28,31,-32                       3                     3

000054     63830000         ORI 3,28,0

000058     E35FFFE6         LQ   26,0XFFE0(31),6

00005C   7B64049C         SELRI 4,27,0,41

000060     3940001F         ADDI 10,0,31

000064     44000141         SCV 10

000068     3B9FFFE0         ADDI   28,31,-32                       4                     4

00006C   63830000         ORI 3,28,0

000070     E35FFFE6         LQ 26,0XFFE0(31),6

000074     7B64049C         SELRI 4,27,0,41

000078     39400138         ADDI 10,0,312

00007C   44000141         SCV 10

 

 

For the MODS1 MI instruction, SCV 10 function number 31 is set into General Purpose Register (GPR) 10 via the Add Immediate (addi) RISC instruction addi 10,0,31 before the SCV 10 call is issued. For the MODS2 MI instruction, SCV 10 function number 312 is set into GPR 10 via an addi 10,0,312 instruction before the SCV 10 call is issued. Now we know the SCV 10 function number for MODS2 is 312 (hex 138).

 

All PowerPC instructions are 4 bytes long and word-aligned (aligned to 4-byte boundaries). The format of the addi instruction is the following:

 

addi   RT,RA,SI

  • bits 0-5: 14 (hex 0E, 00001110b)
  • bits 6-10: RT. Target GPR
  • bits 11-15: RA. Source GPR
  • bits 16-31: SI. An immediate value that represents a 16-bit signed integer.

 

The sum of (RA|0) + SI is placed into register RT. (RA|0) means the contents of register RA if the RA field has the value 1-31, or the value 0 if the RA field is 0.

 

Therefore, an addi 10,0,312 instruction can be assembled like this:

 

  • Opcode of addi: 001110b
  • RT field with the value 10 (hex 0A): 01010b
  • RA field with the value 0: 00000b
  • SI field with the value 312 (hex 0138): 0000000100111000b

 

The resulting 4-byte PowerPC instruction is 0011,1001,0100,0000,0000,0001,0011,1000b (hex 39400138).

 

Replacing the SCV 10 function number for MODS2 (hex 0138) with the function number for MODSOBJ (hex 00A3) in the addi 10,0,312 instruction will cause the MODSOBJ MI instruction to be invoked when the program is being run. The replacement for the addi 10,0,312 (hex 39400138) instruction should be addi 10,0,163 (hex 394000A3).

Modify the LASTU Program via the SST

The final step to complete our tool program is to modify two places in the LASTU program using the SST. We need to:

  • Replace the invocation to the MODS2 MI instruction in statement 940 of LASTU to an invocation to the MODSOBJ instruction by changing the SCV 10 function number for MODS2 to the SCV 10 function number for MODSOBJ.
  • Change the program state attribute of LASTU from user state to system state since the invocation to a blocked MI instruction at runtime from a user-state program at security level 40 or above will raise a 4401 exception (MCH6801). It has been mentioned several times in the early 2000s in the MI400 mailing list that the program state field is a 2-byte field at offset hex 105C from the beginning of the program object (or in other words, at offset hex 5C from the beginning of the program header of the program object). The value hex 01 in the lower byte of the state field means user state, and the value hex 80 in the lower byte of the program state field means system state.

 

Now start an SST session and locate the LASTU program as described in the previous section. Choose menu item 3, Disassembled code, in the Select Format display. In the SST dump result, search for RISC INSTRUCTIONS (LASTU to locate the PowerPC instruction stream generated for the main procedure of the LASTU program. The PowerPC instructions generated for the invocation to the MODS2 MI instruction (in statement 940, mods2(obj@:mod_opt);) might look like the following:

 

RISC INSTRUCTIONS (LASTU   ... ...

     ADDRESS       LOCATION   OBJECT TEXT       SOURCE STATEMENT                       STATEMENT NUMBERS   BREAKPOINT NUMBERS

1234567890 0045B4     000CB4     E21E1226         LQ   16,0X1220(30),6                     940                   940

... ...

1234567890 004644     000D44     62630000         ORI 3,19,0

1234567890 004648     000D48     62840000         ORI 4,20,0

1234567890 00464C     000D4C   39400138         ADDI 10,0,312

1234567890 004650     000D50     44000141         SCV 10

... ...

 

As described in the previous section, to change the SCV 10 function number for MODS2 to the function number for MODS, simply replace the addi 10,0,312 PowerPC instruction (hex 39400138) at address 1234567890-00464C to an addi 10,0,163 instruction (hex 394000A3).

 

In an SST session, choose the following menu items:

 

1. Start a service tool

4. Display/Alter/Dump

1. Display/Alter storage

5. Starting address

 

At the Specify Address display, enter the address of the addi instruction, say 1234567890-00464C, and press the ENTER key. Then change the addi instruction from hex 39400138 to hex 394000A3 at address 1234567890-00464C.

 

Control . . . . . . .   _______

Address . . . . . . .   1234567890 00464C

 

4640   3A7E0430   62630000     62840000 394000A3

 

Next, change the lower byte of the program state field at offset 105C from hex 01 to hex 80 to change the LASTU program to system state.

 

Control . . . . . . .   _______

Address . . . . . . .   1234567890 00105C

 

1050   31BD89BB 9D002567     000000E0 0080C000

 

Now, test the LASTU program by calling it to modify the last-used date of some different types of system objects. For example, the following command changes the last-used date of a save file called OLDMEMORY to May 1, 1990:

 

CALL PGM(LASTU) PARM('OLDMEMORY *LIBL' *FILE '05011990')

 

Issue a DSPOBJD OBJ(OLDMEMORY) OBJTYPE(*FILE) DETAIL(*FULL) command, and the Change/Usage information in the output might look like this:

 

Change/Usage information:

   Change date/time . . . . . . . . . .   :   05/31/13 17:05:15

   Usage data collected . . . . . . . .   :   YES

   Last used date . . . . . . . . . . .   :   05/01/90

   Days used count . . . . . . . . . . :   0

     Reset date . . . . . . . . . . . . :

   Allow change by program . . . . . . :   YES

 

Similar tests can be done on other object types, e.g.:

 

CALL LASTU ('SPCB     *LIBL' *USRSPC '05011990') /* 1934 *USRSPC */

CALL LASTU ('DTAQ01   QGPL' *DTAQ '05021990') /* 0A01 *DTAQ */

CALL LASTU ('DSPF01   QGPL' *FILE '05031990') /* Display file */

/* ... ... */

 

Also as an interesting test, you can call the LASTU program to modify the last-used date of LASTU itself, or you can call LASTU from within a program that changes the last-used date of the program itself.

 

Note that for external objects built from multiple MI objects, the LASTU program only changes the last-used date attribute of one of the MI objectsfor example, the last-used date attribute of the *FILE (MI space) object (with MI object type code hex 1901) in a database or device file. Also note that changes to the last-used date attribute (stored in the EPA.USDAY field) of a 1901 *FILE object of a database file would not change the last-used date attribute of the database file (as an external object).

 

So how can we change the last-used date attribute of a database file? I'm not absolutely sure. However the documentation of the QLICOBJD API gives out a useful suggestion:

 

For database files, the last used date and number of days used count are updated for all members in the file.

 

A couple of experiments (in VRM540) on a simple physical file PF01 and a simple logical file LF01 that both have multiple members show that:

  • To set the last-used date attribute of PF01, the EPA.USDAY fields of all data space objects contained in PF01 should be set to the same 2-byte date value that represents the last-used date of PF01.
  • To set the last-used date attribute of LF01, the EPA.USDAY fields of all cursor objects (file members) contained in LF01 should be set to the same 2-byte date that represents the last-used date of LF01.

 

Junlei Li

Junlei Li is a programmer from Tianjin, China, with 10 years of experience in software design and programming. Junlei Li began programming under i5/OS (formerly known as AS/400, iSeries) in late 2005. He is familiar with most programming languages available on i5/OS—from special-purpose languages such as OPM/ILE RPG to CL to general-purpose languages such as C, C++, Java; from strong-typed languages to script languages such as QShell and REXX. One of his favorite programming languages on i5/OS is machine interface (MI) instructions, through which one can discover some of the internal behaviors of i5/OS and some of the highlights of i5/OS in terms of operating system design.

 

Junlei Li's Web site is http://i5toolkit.sourceforge.net/, where his open-source project i5/OS Programmer's Toolkit (https://sourceforge.net/projects/i5toolkit/) is documented.

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$0.00 Raised:
$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: