26
Fri, Apr
1 New Articles

Real Life APIs

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

See how a great utility can be made even better using APIs

In the April 1991 issue, Ernie Malaga provided a useful utility program that printed a library-size report. I created the utility, ran it, and was able to spot some objects that were taking up too much space. As Ernie pointed out, the utility takes a good while to run -- elapsed times of more than an hour were common on my system. At the end of the article, Ernie alluded to the possibilities of improving the performance of the utility with the new Release 3.0 system APIs.

That set me to work with the dual purpose of investigating the APIs and improving the utility. The results of my experiments were somewhat surprising. Although we will have much more to say about system APIs in the future, you can begin now with this article. This is a good example of how to learn a lot by taking an existing function and modifying it. The concepts that are described in this article cover the basics of what you will need to know to use other APIs.

What are APIs?

An API (Application Programming Interface) is IBM's way of giving us more direct access to some of the components of OS/400 and other products such as Office/400. To be useful, an API consists of two components: the machine component that actually performs the function, and the documentation component that describes precisely how to use the function. The machine components are provided as part of OS/400. The documentation consists of the System Programmer's Interface Reference (SC21-8223) and PTF SF06260.

Unfortunately, the documentation component is not that useful for a "first look" at APIs. There are several errors in the sample programs in the book, resulting in programs that fail to compile, and mistakes in the data structures provided in the QUSRTOOL library that make learning about APIs through experimentation a trying experience.

The Function of an API

For the example program shown here, the function of the API is to replace the DSPOBJD (Display Object Description) command, with OUTFILE processing, as described in the April 1991 article. The program first had to generate a list of library objects, then generate a list of all objects in each library. Finally, a program was called to process the OUTFILE, summing the size of objects in the library and determining the largest object in each library. As Ernie correctly surmised, there's a performance penalty to generating the OUTFILE, then reading it in the RPG program. The equivalent function can be programmed with APIs.

In order to program this function, you need to use three APIs in RPG, and four if you choose to process using pointers in a pointer-capable language (C, PL/I, PASCAL). The APIs you use are the Create User Space API, the List Objects API, and the Retrieve User Space API. For pointer-capable languages, you also use the Pointer to User Space API.

Using APIs in the Program

The API that does "the work" in the program is the List Objects API. This generates a list of data about objects that we specify, and takes the place of the DSPOBJD command with the OUTFILE. The question is, where is this list generated, and how do we access it?

The List Object API puts the list data in a User Space object. A User Space is, more or less, a named collection of bytes. It differs from a file, in that there are no record formats associated with the space, and no concept of processing it as a file (sequential read or random retrieval). Although the system does not specify a processing method for a user space, your program does. As you will see in this example, the program practically uses the user space as a file, since we apply a program-defined record format to the space and move sequentially through the space.

Prior to using the List Object API, you use the Create User Space API. This tells the system to create the user space object with the name you supply in the library that you specify. You also provide an initial size for the space, and some other object-type information. To get at the list data, you use the Retrieve User Space API, which returns 1 or more bytes to your program from the user space.

API Support

When I began experimenting with APIs, I was in the book constantly. The book has several charts that show the format of data and parameters used by the APIs, in terms of the length of the parameter and the offset from the beginning of the parameter list. Supposedly, the source members provided in the QUSRTOOL library could be used as the formats; however, I found several errors in the RPG formats. Because I also wanted to try the APIs in PL/I and C, I decided to create definitions for API parameter lists as external files, then include the definitions in my programs. The definitions that you'll need for the example are shown in Figures 1 through 4. To create these, you simply enter them as externally described physical files. These are not data files, simply lists of fields used in API parameters.

The OBJL0700 format, used with the List Objects API, needs some explanation. The List Objects API lets you specify the level of detail you want to retrieve for each object in the list. Supposedly, performance of the API is best when you retrieve the least information, and worsens as you retrieve more. The List Objects API defines seven formats of information that you can retrieve, in an "additive" fashion. That means that you can start with format OBJL0100, object name information. That returns the object name, library and object type only. You can then supplement that with OBJL0200, and get the extended attribute (e.g., PF, LF for files) and text, and so on. Each additional format adds more information to the previous formats. You cannot retrieve the "higher format" information alone; in our example, using the OBJL0700 format gets all of the preceding formats.

I created the OBJL0700 format, and will probably always use that. If you think you will use the List Objects API and need less information, you can use the source member shown here as a basis for creating the less-extensive formats.

APIs in a Program

After you examine the API parameter formats, you can turn your attention to the sample program. This program replaces the LIB002RG and LIB002RGA programs in the April 1991 article. Keep in mind that the program needs to get a list of libraries, then a list of all objects in each library. With the list for each library, the total is accumulated, and the largest object name and size is recorded. All of this information is written to the work file record. The work file is then passed to a program to print the report. We have kept the printing program (LIB002RGB) rather than incorporate it into this program.

Looking at the RPG source, you see that we have included the parameter formats as externally described data structures. In the main routine, the first significant section of code retrieves the list of libraries. It does this by first creating a user space to contain the list, then calling the List Objects API to list libraries into the user space. We tell the List Objects API to generate the list with the OBJL0700 format, which puts the maximum amount of information for each library object into the list. We need to specify this because the object size is at the very end of the OBJL0700 format (the object size, for a library, is shown as the "directory size" on the report).

The next section of code retrieves the list of all objects in each library, in turn. This section starts with a call to the Retrieve User Space API, which retrieves data for a library from the user space. The DSPLIB subroutine is then called, which works like the just-executed routine to get the libraries.

And that's really all there is to it. As you can see, there are no references to files, other than the work file that is used in the print program. The list is created into the user space, and the program retrieves data with CALLs to system APIs.

Performance

One of the touted virtues of system APIs is that you can improve performance for these types of applications. You might intuitively think, as I did, that using a user space and program CALLs would be faster than using the DSPOBJD with an OUTFILE approach.

The results of several experiments on our B10 system are shown in the table in 5. There are two sections to this table. In the first test suite, I simply ran the program to accomplish the same results as the April 1991 program: get a summation of object size for all libraries on the system. As the table shows, using the APIs improved performance by 1.3 percent, as shown by CPU time used. When dealing with a program that runs for an elapsed time of over an hour, this improvement is unnoticeable.

The results of several experiments on our B10 system are shown in the table in Figure 5. There are two sections to this table. In the first test suite, I simply ran the program to accomplish the same results as the April 1991 program: get a summation of object size for all libraries on the system. As the table shows, using the APIs improved performance by 1.3 percent, as shown by CPU time used. When dealing with a program that runs for an elapsed time of over an hour, this improvement is unnoticeable.

Somewhat more significant was the PL/I test in which I used the pointer to the user space method to retrieve data from the user space, rather than calls to the Retrieve User Space API. This improved performance 22.1 percent, which is significant.

In terms of the usefulness of the program, though, a very simple change can be made to the original April 1991 source: don't get the object list for library QSYS. The reason for omitting this is that you probably won't be able to do much about anything in QSYS, other than spool file members. So if you run the report once, just to see the QSYS size, you can then change the program (or control it via a parameter) so that QSYS is no longer included.

This simple change cut in half the length of CPU time for the RPG program, and approximately halved the PL/I program. The elapsed time was also halved, to about half an hour.

One interesting experiment I conducted with the RPG version involved the "object size" and the "object size multiplier." These are the last two entries in the OBJL0700 format, and are used to calculate the size of the object. The documentation for the API states that the object size multiplier will be a value of 1, or 1024 or 1048576. This is apparently used for large objects, where the object size will not fit into the object size field. Since most object size multipliers will be 1, there's no need to perform the multiplication to arrive at the object size for most objects. This is shown in the RPG program, where the test is made for object size multipliers greater than 1. Only performing the multiply when needed, rather than performing it for every object, resulted in a 1.8 percent CPU time saving. Since this was not performed for 5752 objects, it appears that the B10 multiply takes .0013908 seconds. Obviously, this is not significant when the number of multiplies is small, but you can see how, in a "batch"-type situation, the penalty for unneeded operations mounts up.

So what is the conclusion? Given that the system APIs did not result in significant gains, what is the point of even considering using them? One reason might be to learn more about a very important topic of the AS/400 -- APIs. We will be exploring APIs more in future issues, and developing other applications that use APIs. Also, we will take an in- depth look at the user space, since this object is used by many of the system APIs.


Real Life APIs

Figure 1 Create User Space API parms (PF ##0015PF)

 A***************************************************************** A* QUSCRTUS: CREATE USER SPACE LAYOUT A***************************************************************** A* A R CRTUS TEXT('Create User Space layout ') A CSQLSN 20 TEXT('Qualified Space name ') A CSEXTA 10 TEXT('Extended attribute ') A CSINSZ 9B 0 TEXT('Initial size ') A CSINVL 1 TEXT('Initial value ') A CSPAUT 10 TEXT('Public authority ') A CSTEXT 50 TEXT('Text description ') 
Real Life APIs

Figure 10 Revised command PRTLIBSIZ (PRTLIBSIZA)

 PRTLIBSIZ: CMD PROMPT('Print Library Sizes') PARM KWD(SORT) TYPE(*CHAR) LEN(5) RSTD(*YES) + DFT(*NAME) VALUES(*NAME *SIZE) + PROMPT('Sort option') PARM KWD(VERSION) TYPE(*CHAR) LEN(4) RSTD(*YES) + DFT(*RPG) VALUES(*PLI *RPG) PROMPT('Version') 
Real Life APIs

Figure 2 Retrieve User Space API parms (PF ##0016PF)

 A***************************************************************** A* QUSRTVUS: RETRIEVE USER SPACE GENERIC LAYOUT A***************************************************************** A* A R RTVUS TEXT('Retrieve User Space layout ') A RSRSCL 64 TEXT('Reserved for caller ') A RSHDSZ 9B 0 TEXT('Size of generic header ') A RSSTLV 4 TEXT('Structure level ') A RSFMTN 8 TEXT('Format name ') A RSPGM 10 TEXT('Pgm/API generating list ') A RSLSDT 13 TEXT('List written date/time ') A RSINST 1 TEXT('Information status ') A RSUSSZ 9B 0 TEXT('Total size of space used ') A RSOFIP 9B 0 TEXT('Offset - input parms ') A RSSZIP 9B 0 TEXT('Size - input parms ') A RSOFHD 9B 0 TEXT('Offset - header ') A RSSZHD 9B 0 TEXT('Size - header ') A RSOFLS 9B 0 TEXT('Offset - list data ') A RSSZLS 9B 0 TEXT('Size - list data ') A RSCTLS 9B 0 TEXT('Count - list data ') A RSSZEN 9B 0 TEXT('Size - each entry ') 
Real Life APIs

Figure 3 List Objects API parms (PF ##0017PF)

 A***************************************************************** A* QUSLOBJ: List Objects Parms A***************************************************************** A* A R LOBJ TEXT('List Objects parms ') A LOQLSN 20 TEXT('Qualified Space Name ') A LOFMTN 8 TEXT('Format name ') A LOOBLI 20 TEXT('Object/Library to list ') A LOOTYP 10 TEXT('Object type to list ') 
Real Life APIs

Figure 4 List Objects API returned data (PF ##0018PF)

 A***************************************************************** A* QUSLOBJ: FORMAT OBJL0700 A***************************************************************** A R OL0700 TEXT('QUSLOBJ, FORMAT OBJL0700 ') A***************************************************************** A* ..format OBJL0100: name information A***************************************************************** A O7ONAM 10 TEXT('Object name ') A O7LNAM 10 TEXT('Library name ') A O7OTYP 10 TEXT('Object type ') A***************************************************************** A* ..format OBJL0200: name, extended atr, text A***************************************************************** A O7OSTS 1 TEXT('Object status ') A O7EXAT 10 TEXT('Extended attribute ') A O7TEXT 50 TEXT('Text description ') A O7RS01 17 TEXT('Reserved ') A***************************************************************** A* ..format OBJL0300: basic object information A***************************************************************** A O7AUXP 9B 0 TEXT('Auxiliary storage pool ') A O7OWNR 10 TEXT('Owner ') A O7DOMN 2 TEXT('Domain - *S=System, *U=User') A O7DTCR 8 TEXT('Date, creation ') A O7DTCG 8 TEXT('Date, change ') A O7STOR 10 TEXT('Storage ') A O7RS02 22 TEXT('Reserved ') A***************************************************************** A* ..format OBJL0400: creation information A***************************************************************** A O7SRCF 10 TEXT('Source file name ') A O7SRCL 10 TEXT('Source file library ') A O7SRCM 10 TEXT('Source file member ') A O7SRCU 13 TEXT('Source file update date/time') A O7CRET 10 TEXT('Creator ') A O7SYSC 8 TEXT('System created on ') A O7SYSL 9 TEXT('System level ') A O7COMP 16 TEXT('Compiler ') A O7OBLV 8 TEXT('Object level ') A O7USCG 1 TEXT('User changed ') A O7LCPG 16 TEXT('Licensed program ') A O7PTF 10 TEXT('PTF ') A O7APAR 10 TEXT('APAR ') A O7RS03 21 TEXT('Reserved ') A***************************************************************** A* ..format OBJL0500: save/restore information A***************************************************************** A O7DTSV 8 TEXT('Date, save ') A O7DTRS 8 TEXT('Date, restore ') A O7SVSZ 9B 0 TEXT('Save size ') A O7SVMU 9B 0 TEXT('Save size multiplier ') A O7SVSQ 9B 0 TEXT('Save sequence number ') A O7SVCM 10 TEXT('Save command ') A O7SVVL 71 TEXT('Save volume IDs ') A O7SVDV 10 TEXT('Save device ') A O7SVFI 10 TEXT('Save file ') A O7SVFL 10 TEXT('Save file library ') A O7SVLB 17 TEXT('Save label ') A O7RS04 52 TEXT('Reserved ') A***************************************************************** A* ..format OBJL0600: usage information A***************************************************************** A O7DTLU 8 TEXT('Date, last used ') A O7DTRE 8 TEXT('Date, reset ') A O7USCT 9B 0 TEXT('Usage count ') A O7USUP 1 TEXT('Usage updated ') A O7RS05 23 TEXT('Reserved ') A***************************************************************** A* ..format OBJL0700: size information A***************************************************************** A O7OSIZ 9B 0 TEXT('Object size ') A O7OSMU 9B 0 TEXT('Object size multiplier ') 
Real Life APIs

Figure 5 Program run times

 Figure 5: Program Run Times Program Type CPU Time Percent RPG, Outfile, with QSYS 930 100.0 RPG, APIs, with QSYS 918 98.7 PL/I, APIs, with QSYS 725 77.9 RPG, APIs, without QSYS 458 PL/I, APIs, without QSYS 384 RPG, APIs, without QSYS 466 Multiply all sizes 
Real Life APIs

Figure 6 RPG program ##006RG

 ***************************************************************** * LIST LIBRARY PROGRAM ***************************************************************** FLIB002WFO E DISK A I 'DLTUSRSPC QTEMP/LST1'C USPC1 I 'DLTUSRSPC QTEMP/LST2'C USPC2 IOL0700 E DS##0018PF IQRTVUS E DS##0016PF IQCRTUS E DS##0015PF IQLOBJ E DS##0017PF I DS I***************************************************************** I* PARMS TO QUSRTVUS PGM I* I* RSSTRP - START POSITION I* RSLEND - LENGTH OF DATA I***************************************************************** I B 1 40RSSTRP I B 5 80RSLEND C SETON LR C* C***************************************************************** C* GET LIST OF LIBRARIES C***************************************************************** C* C MOVEL'LST1' CSSPNM 10 *SPACE NAME C MOVEL'QTEMP' CSSPLB 10 *SPACE LIBRARY C MOVELUSPC1 DLTSPC 20 *DLTUSRSPC C* C EXSR CRTSPC C EXSR INTLST C* C MOVELCSQLSN LOQLSN *SPACE/LIB C MOVEL'OBJL0700'LOFMTN *LIST FORMAT C MOVEL'*ALL' LOOBLI *OBJ/LIB C MOVEL*BLANKS W10 C MOVEL'QSYS' W10 10 *OBJ LIB C MOVE W10 LOOBLI *OBJ/LIB C MOVEL'*LIB' LOOTYP *OBJ TYPE C* C EXSR GETLST C* C***************************************************************** C* RETRIEVE EACH LIBRARY ENTRY FROM LIST C***************************************************************** C* C 1 DO RSCTLS N 50 C CALL 'QUSRTVUS' C PARM LOQLSN C PARM RSSTRP C PARM RSLEND C PARM OL0700 C* C CLEARWFREC *INIT WORKFILE C* C MOVELO7ONAM WFLIB *LIBRARY C MOVELO7TEXT WFTEXT *LIB TEXT C O7OSIZ MULT O7OSMU WFLBSZ *LIB SIZE C Z-ADDWFLBSZ WFTSIZ *TOTAL LIB SIZE C* C WFLIB IFNE 'QSYS' C EXSR DSPLIB C END C* C ADD RSSZEN RSSTRP C END C***************************************************************** C* FOR EACH LIBRARY, GET OBJECTS IN THAT LIBRARY C***************************************************************** C* C DSPLIB BEGSR C* *************** C* C***************************************************************** C* SAVE LIST API VALUES C***************************************************************** C* C *LIKE DEFN RSCTLS SVCTLS C *LIKE DEFN RSSZEN SVSZEN C *LIKE DEFN RSSTRP SVSTRP C *LIKE DEFN RSLEND SVLEND C *LIKE DEFN LOQLSN SVQLSN C* C Z-ADDRSCTLS SVCTLS C Z-ADDRSSZEN SVSZEN C Z-ADDRSSTRP SVSTRP C Z-ADDRSLEND SVLEND C MOVELLOQLSN SVQLSN C* C***************************************************************** C* GET LIST OF OBJECTS IN A LIBRARY C***************************************************************** C* C MOVEL'LST2' CSSPNM *SPACE NAME C MOVEL'QTEMP' CSSPLB *SPACE LIBRARY C MOVELUSPC2 DLTSPC *DLTUSRSPC C* C EXSR CRTSPC C EXSR INTLST C* C MOVELCSQLSN LOQLSN *SPACE/LIB C MOVEL'OBJL0700'LOFMTN *LIST FORMAT C MOVEL'*ALL' LOOBLI *OBJ/LIB C MOVEL*BLANKS W10 C MOVELO7ONAM W10 *OBJ/LIB C MOVE W10 LOOBLI *OBJ/LIB C MOVEL'*ALL' LOOTYP *OBJ TYPE C* C EXSR GETLST C* C***************************************************************** C* RETRIEVE EACH OBJECT ENTRY FROM LIST C***************************************************************** C* C 1 DO RSCTLS K 50 C CALL 'QUSRTVUS' C PARM LOQLSN C PARM RSSTRP C PARM RSLEND C PARM OL0700 C* C ADD RSSZEN RSSTRP *NEXT START POS C* C***************************************************************** C* CACLULATE OBJECT SIZE, ACCUMULATE TOTALS, SAVE LARGEST OBJ C***************************************************************** C* C*** Z-ADDO7OSIZ OBJSIZ 110 *OBJECT SIZE C* C*** O7OSMU IFGT 1 C O7OSIZ MULT O7OSMU OBJSIZ 110 *OBJECT SIZE C*** END C* C ADD OBJSIZ WFOBSZ *TOT OBJS SIZE C* C OBJSIZ IFGT WFLRGS *LARGEST SIZE C Z-ADDOBJSIZ WFLRGS *LARGEST SIZE C MOVELO7ONAM WFLRGN *NAME C MOVELO7OTYP WFLRGT *OBJ TYPE C MOVELO7EXAT WFLRGA *OBJ ATTR C END C END C* C ADD WFOBSZ WFTSIZ *TOT LIB SIZE C Z-ADDRSCTLS WFOBJS *OBJ COUNT C* C WRITEWFREC C* C***************************************************************** C* RESTORE LIST API VALUES C***************************************************************** C* C Z-ADDSVCTLS RSCTLS C Z-ADDSVSZEN RSSZEN C Z-ADDSVSTRP RSSTRP C Z-ADDSVLEND RSLEND C MOVELSVQLSN LOQLSN C ENDSR C***************************************************************** C* CREATE A NEW USER SPACE C***************************************************************** C* C CRTSPC BEGSR C* *************** C* C***************************************************************** C* ..DELETE EXISTING USER SPACE C***************************************************************** C* C MOVELDLTSPC PMCMD 20 C Z-ADD20 PMLEN 155 C* C CALL 'QCMDEXC' 99 *99 - ERROR C PARM PMCMD C PARM PMLEN C* C***************************************************************** C* ..CREATE NEW USER SPACE C***************************************************************** C* C MOVEL*BLANKS CSQLSN C MOVELCSSPNM CSQLSN *SPACE NAME C MOVE CSSPLB CSQLSN *SPACE LIB C MOVEL'USPACE' CSEXTA *EXTENDED ATTR C Z-ADD100000 CSINSZ *INIT SIZE C MOVEL*BLANKS CSINVL *INIT VALUE C MOVEL'*ALL' CSPAUT *PUB AUTHORITY C MOVEL*BLANKS CSTEXT *TEXT DESC C* C CALL 'QUSCRTUS' C PARM CSQLSN C PARM CSEXTA C PARM CSINSZ C PARM CSINVL C PARM CSPAUT C PARM CSTEXT C ENDSR C***************************************************************** C* GET LIST, LIST HEADER C***************************************************************** C* C GETLST BEGSR C* *************** C* C CALL 'QUSLOBJ' C PARM LOQLSN C PARM LOFMTN C PARM LOOBLI C PARM LOOTYP C* C***************************************************************** C* GET OFFSET, SIZE OF EACH ENTRY, NUMBER OF ENTRIES C***************************************************************** C* C Z-ADD1 RSSTRP *START POSN C Z-ADD140 RSLEND *LENGTH OF DATA C* C CALL 'QUSRTVUS' C PARM LOQLSN C PARM RSSTRP C PARM RSLEND C PARM QRTVUS C* C RSOFLS ADD 1 RSSTRP *START POSN C Z-ADDRSSZEN RSLEND *LENGTH OF DATA C ENDSR C***************************************************************** C* INITIALIZE 'GET LIST' PARM VALUES C***************************************************************** C* C INTLST BEGSR C* *************** C* C MOVEL*BLANKS LOQLSN C MOVEL*BLANKS LOFMTN C MOVEL*BLANKS LOOBLI C MOVEL*BLANKS LOOTYP C ENDSR 
Real Life APIs

Figure 7 CL program ##0004CL (revised LIB002CL)

 ##0004CL: + PGM PARM(&SORT) DCL VAR(&SORT) TYPE(*CHAR) LEN(5) CLRPFM FILE(LIB002WF) CALL PGM(##0006RG) OVRPRTF FILE(QPDSPSTS) HOLD(*YES) WRKSYSSTS OUTPUT(*PRINT) CRTPF FILE(QTEMP/SYSSTS) RCDLEN(132) CPYSPLF FILE(QPDSPSTS) TOFILE(QTEMP/SYSSTS) DLTOVR FILE(QPDSPSTS) DLTSPLF FILE(QPDSPSTS) IF COND(&SORT *EQ '*SIZE') THEN(DO) OVRDBF FILE(LIB002WF) SHARE(*YES) OPNQRYF FILE((LIB002WF)) QRYSLT(*ALL) KEYFLD((WFTSIZ + *DESCEND) (WFLIB *ASCEND)) ENDDO CALL PGM(LIB002RGB) IF COND(&SORT *EQ '*SIZE') THEN(DO) CLOF OPNID(LIB002WF) DLTOVR FILE(LIB002WF) ENDDO DLTF FILE(QTEMP/SYSSTS) CLRPFM FILE(LIB002WF) ENDPGM 
Real Life APIs

Figure 8 Revised program LIB002RG (LIB002RGB)

 FLIB002WFIF E K DISK FSYSSTS IF F 132 DISK FLIB002P1O E 99 PRINTER * ISYSSTS NS I 96 1020STGMB * C Z-ADD*ZERO AUXSTG C Z-ADD*ZERO STGUSE C Z-ADD*ZERO PCTUSE C WRITEHEADER * C READ LIB002WF 90 B001 C *IN90 DOWEQ'0' C MOVELWFTEXT TEXT40 B002 C *IN99 IFEQ '1' C WRITEHEADER C MOVE '0' *IN99 E002 C END C WRITEDETAIL C ADD WFTSIZ STGUSE C READ LIB002WF 90 E001 C END * C 3 CHAINSYSSTS 90 C STGMB MULT 1000000 AUXSTG C STGUSE MULT 100 TEMP 150 C TEMP DIV AUXSTG PCTUSE C WRITETOTAL * C MOVE '1' *INLR 
Real Life APIs

Figure 9 Work file LIB002WF

 A UNIQUE A R WFREC A WFLIB 10 ALIAS(LIBRARY_NAME) A WFTEXT 50 ALIAS(LIBRARY_TEXT) A WFLBSZ 10P 0 ALIAS(LIBRARY_SIZE) A EDTCDE(1) A WFOBSZ 12P 0 ALIAS(OBJECTS_TOTAL_SIZE) A EDTCDE(1) A WFTSIZ 12P 0 ALIAS(TOTAL_SIZE) A EDTCDE(1) A WFOBJS 9P 0 ALIAS(NUMBER_OF_OBJECTS) A EDTCDE(1) A WFLRGN 10 ALIAS(LARGEST_OBJECT_NAME) A WFLRGT 10 ALIAS(LARGEST_OBJECT_TYPE) A WFLRGA 10 ALIAS(LARGEST_OBJECT_ATTRIBUTE) A WFLRGS 10P 0 ALIAS(LARGEST_OBJECT_SIZE) A EDTCDE(1) A K WFLIB 
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: