IBM i Field Notes

IBM i Exit Points in Practice: Adding P=Print to Email Spooled Files

A practical IBM i case study showing how a small exit-point program replaced a confusing multi-screen spooled-file process with one simple P=Print action.

IBM iExit PointsSpooled FilesWRKSPLFWRKOUTQQIBM_QSP_SPLF_LSTACTRPGUser ExperienceAutomation

A business user should not need to understand printer queues, spooled-file attributes, or an internal email-delivery process just to receive a report. A small IBM i exit-point program reduced the entire workflow to one action: P=Print.

Some of the most effective IBM i improvements do not require a major rewrite.

They do not always require:

Sometimes the best improvement is simply removing unnecessary friction from an existing workflow.

This is one such example.

The original business requirement

Users regularly needed to receive IBM i spooled files by email.

The back-end capability already existed.

There were programs in place that could:

The technical process worked.

The problem was how business users had to initiate it.

The original user process

Users were instructed to perform a sequence similar to this:

1. Locate the required spooled file.
2. Enter option 9 beside the spooled file.
3. Move to another green-screen panel.
4. Enter option 2.
5. Move the spooled file to the appropriate printer queue.
6. Allow the existing process to convert and email it.

From an IBM i developer or administrator’s perspective, that may not sound overly complicated.

For a business user, however, it was too technical.

The user did not want to understand:

The user simply wanted to say:

Send this report to me by email.

The operational impact

The multi-step process created problems for both users and the IT team.

Users sometimes:

The IT team received repeated support tickets for what should have been a simple request.

Additional instructions might have reduced some mistakes.

More training might also have helped temporarily.

But neither would have addressed the real design problem:

We were asking business users to understand an internal technical workflow.

The better solution was to remove that requirement.

The idea: add P=Print

The proposed experience was much simpler.

From the existing spooled-file screen, the user would enter:

P

beside the required spooled file and press Enter.

The complete user process would become:

Locate the spooled file.
Enter P.
Press Enter.

Behind the scenes, the P action would route the selected spooled file to the existing PDF-conversion and email-delivery programs.

The business action was presented as:

P = Print

The implementation could then decide how the document was delivered.

For this particular process, the selected report was converted to PDF and sent to the user by email.

The design principle

Do not make users follow the internal technical workflow. Let the system translate a simple business action into the required technical steps.

Why an IBM i exit point was a good fit

IBM i provides the UIM Spooled File User-defined List Action exit point:

QIBM_QSP_SPLF_LSTACT

Its format is:

LASP0100

This exit point allows custom single-character actions to be used on several familiar green-screen spooled-file interfaces, including:

WRKSPLF
WRKOUTQ
WRKJOB OPTION(*SPLF)

Instead of building a separate application, we could extend the interface users were already using.

That meant:

We only needed a small program that connected the new P action to the existing back-end process.

The solution architecture

The final design was intentionally small.

User enters P beside a spooled file

IBM i invokes QIBM_QSP_SPLF_LSTACT

The exit program receives the LASP0100 information

The exit program validates the P action

The selected spooled-file identity is extracted

The identity is passed to the existing program

The existing process converts the spool file to PDF

The existing process emails the PDF

The exit program did not need to become another large printing or email application.

Its responsibilities were limited:

  1. Receive the selected action.
  2. Receive the identity of the selected spooled file.
  3. Validate the request.
  4. Pass the identity to the existing processing program.
  5. Return appropriate feedback when necessary.

That kept the implementation focused and low risk.

What IBM i passes to the exit program

IBM documents five parameters for the exit program:

1. Exit-point name
2. Format name
3. User-defined action
4. Spooled-file identity
5. Length of the spooled-file identity

For this implementation, the expected values are:

Exit-point name: QIBM_QSP_SPLF_LSTACT
Format name:     LASP0100
User action:     P

The LASP0100 spooled-file identity includes:

Spooled-file job name
Spooled-file user name
Spooled-file job number
Spooled-file name
Spooled-file number
Job system name
Spooled-file creation date
Spooled-file creation time
Output queue name
Output queue library

The complete identity is important because the spooled-file name by itself may not uniquely identify a report.

Several jobs can create spooled files with names such as:

QPRINT
QSYSPRT
INVOICE
REPORT

The qualified job information and spooled-file number identify the exact file selected by the user.

Step 1: Check existing registrations

Before adding a new custom option, check which programs are already registered against the exit point.

Run:

WRKREGINF EXITPNT(QIBM_QSP_SPLF_LSTACT)

On the Work with Registration Information panel, use:

8 = Work with exit programs

This displays the programs already registered against the exit point.

A system may already have custom actions such as:

C = Copy
D = Duplicate
E = Edit or Email
F = Fax
S = Send

Each custom action is typically registered separately.

Our requirement was to add:

P = Print

Checking the existing registrations helps avoid:

Step 2: Define the LASP0100 structure

The Cobwebb guide shows the key fields needed to identify a selected spooled file:

Job name
User name
Job number
Spooled-file name
Spooled-file number

IBM’s full LASP0100 format also contains the system, creation timestamp, and output queue information.

An RPG template for the structure can be defined like this:

**free

dcl-ds SplfIdentity_t qualified template;
   JobName        char(10) pos(1);
   UserName       char(10) pos(11);
   JobNumber      char(6)  pos(21);
   SplfName       char(10) pos(27);
   SplfNumber     int(10)  pos(37);
   JobSystemName  char(8)  pos(41);
   CreateDate     char(7)  pos(49);
   CreateTime     char(6)  pos(56);
   OutqName       char(10) pos(62);
   OutqLibrary    char(10) pos(72);
end-ds;

The structure occupies 81 bytes.

The binary spooled-file number begins at position 37 and occupies four bytes.

Step 3: Create the exit program

The following is an illustrative free-format RPG structure.

The final call to the existing PDF/email program must be adjusted to match the application being used in your environment.

Illustrative source

This example demonstrates the exit-program interface and routing pattern. Replace the SPLFEMAIL prototype, authority checks, logging, messages, and processing logic with the programs and standards used in your environment.

**free

ctl-opt dftactgrp(*no)
        actgrp(*caller)
        option(*srcstmt : *nodebugio);

// -------------------------------------------------------------------------
// LASP0100 spooled-file identity
// -------------------------------------------------------------------------
dcl-ds SplfIdentity_t qualified template;
   JobName        char(10) pos(1);
   UserName       char(10) pos(11);
   JobNumber      char(6)  pos(21);
   SplfName       char(10) pos(27);
   SplfNumber     int(10)  pos(37);
   JobSystemName  char(8)  pos(41);
   CreateDate     char(7)  pos(49);
   CreateTime     char(6)  pos(56);
   OutqName       char(10) pos(62);
   OutqLibrary    char(10) pos(72);
end-ds;

// -------------------------------------------------------------------------
// Replace this prototype with the existing routing program used in your
// environment.
// -------------------------------------------------------------------------
dcl-pr RouteSpooledFile extpgm('SPLFEMAIL');
   JobName       char(10) const;
   UserName      char(10) const;
   JobNumber     char(6)  const;
   SplfName      char(10) const;
   SplfNumber    int(10)  const;
end-pr;

// -------------------------------------------------------------------------
// Exit-program parameters
// -------------------------------------------------------------------------
dcl-pi *n;
   ExitPointName char(20)                   const;
   FormatName    char(8)                    const;
   UserAction    char(1)                    const;
   SelectedSplf  likeds(SplfIdentity_t)     const;
   IdentityLen   int(10)                    const;
end-pi;

// -------------------------------------------------------------------------
// Validate the exit-point call
// -------------------------------------------------------------------------
if %trim(ExitPointName) <> 'QIBM_QSP_SPLF_LSTACT';
   *inlr = *on;
   return;
endif;

if %trim(FormatName) <> 'LASP0100';
   *inlr = *on;
   return;
endif;

if UserAction <> 'P';
   *inlr = *on;
   return;
endif;

// LASP0100 currently requires 81 bytes.
if IdentityLen < 81;
   // Replace with the application's normal error handling.
   *inlr = *on;
   return;
endif;

// -------------------------------------------------------------------------
// Route the exact selected spooled file to the existing process.
// -------------------------------------------------------------------------
monitor;

   RouteSpooledFile(
      SelectedSplf.JobName:
      SelectedSplf.UserName:
      SelectedSplf.JobNumber:
      SelectedSplf.SplfName:
      SelectedSplf.SplfNumber
   );

on-error;

   // Add the application's normal logging and user-message handling here.

endmon;

*inlr = *on;
return;

This source is intentionally a routing example.

It does not attempt to recreate the existing PDF-conversion or email-delivery functionality.

The actual program can continue handling:

Keep the exit program small

The exit program should identify and route the selected spooled file. Reuse the existing conversion and email programs rather than rebuilding that logic inside the exit point.

Step 4: Compile the program into your own library

The Cobwebb guide advises copying or compiling customized source into a separate application library.

Do not place locally customized objects in a vendor product library where they could be replaced during an upgrade.

For example:

CRTBNDRPG PGM(MYLIB/MYSPLFEXIT)
           SRCFILE(MYLIB/QRPGLESRC)
           SRCMBR(MYSPLFEXIT)
           DBGVIEW(*SOURCE)

Replace:

MYLIB
MYSPLFEXIT

with the actual library and program names.

Step 5: Register the P option

Register the exit program with ADDEXITPGM.

The Cobwebb guide uses the following registration pattern for each custom action:

ADDEXITPGM EXITPNT(QIBM_QSP_SPLF_LSTACT) +
           FORMAT(LASP0100) +
           PGMNBR(*LOW) +
           PGM(MYLIB/MYSPLFEXIT) +
           PGMDTA(*JOB 1 P)

The important portion for this custom action is:

PGMDTA(*JOB 1 P)

This associates the program registration with the P action.

Replace:

MYLIB/MYSPLFEXIT

with the qualified name of the exit program.

The user registering the program needs the special authorities required by the registration command, including:

*ALLOBJ
*SECADM

After registration, confirm the entry using:

WRKREGINF EXITPNT(QIBM_QSP_SPLF_LSTACT)

Then use option 8 to review the registered exit programs.

A note about displaying P=Print

The custom action may work even if:

P=Print

is not displayed automatically in the standard list of options at the top of the panel.

IBM’s sample notes that user-defined options can be entered in the option field even when their descriptions are not shown with the standard actions.

For that reason, users should be informed that:

P = Print and email the selected report

A short message, help-text update, quick-reference document, or internal training note may be sufficient.

The important improvement is that the operational process itself has been reduced to one action.

Step 6: Test the custom option

Test the new action from every supported interface used by the organization.

For example:

WRKSPLF
WRKOUTQ
WRKJOB OPTION(*SPLF)

A basic successful test should confirm:

1. The user enters P beside the intended spooled file.
2. IBM i invokes the registered exit program.
3. The program receives user action P.
4. The program receives the complete LASP0100 identity.
5. The correct existing PDF/email process is called.
6. The correct spooled file is converted.
7. The report is delivered to the intended recipient.
8. Any success or failure is recorded appropriately.

Test more than one spooled file named QPRINT.

The implementation must distinguish files using:

Job name
User name
Job number
Spooled-file name
Spooled-file number

Testing only by spooled-file name could result in the wrong report being processed.

Additional test scenarios

The implementation should also be tested with:

A normal spooled file
Multiple spooled files with the same name
Different spooled-file numbers
A spooled file from a completed job
A large spooled file
A held spooled file
A spooled file moved before processing
A spooled file deleted before processing
An unauthorized user
An invalid user-defined action
A duplicate P request
A PDF-conversion failure
An email-delivery failure
An unavailable recipient email address

Also confirm that the custom registration does not interfere with the standard options on the panel.

Synchronous or submitted processing

PDF conversion and email delivery may take time.

Running the entire process interactively could make the user’s green-screen session appear unresponsive.

A scalable design may allow the exit program to:

Validate the request
Capture the spooled-file identity
Write or submit a processing request
Return control to the user
Process the PDF and email asynchronously

The correct approach depends on:

For a very fast existing process, a direct call may be appropriate.

For longer processing, submitting the work or placing a request on a data queue can keep the interactive experience responsive.

Security and operational considerations

A convenient one-character option should not bypass existing controls.

Consider:

The new interface should simplify the user action without weakening the controls behind it.

Removing the P option

If the option is no longer required, first locate the exact registration number:

WRKREGINF EXITPNT(QIBM_QSP_SPLF_LSTACT)

Use:

8 = Work with exit programs

After confirming the correct program number, remove the registration:

RMVEXITPGM EXITPNT(QIBM_QSP_SPLF_LSTACT) +
           FORMAT(LASP0100) +
           PGMNBR(entry-number)

Be careful when several custom actions are registered against the same exit point.

Removing the wrong program number may disable another application or custom action.

IBM’s sample program

IBM provides a sample UIM spooled-file options program in QUSRTOOL.

The information can be reviewed using:

WRKMBRPDM FILE(QUSRTOOL/QATTINFO) MBR(TSPUIMLI)

or:

STRSEU SRCFILE(QUSRTOOL/QATTINFO) SRCMBR(TSPUIMLI)

The IBM sample demonstrates:

S = Invoke SNDTCPSPLF
C = Invoke CPYSPLF

The same exit point and registration pattern can be adapted for another action such as:

P = Route the selected spooled file to an existing PDF/email process

The sample also demonstrates that each action is registered separately.

The Cobwebb sample

The Cobwebb guide describes its COBSPLFEP exit program, which routes different user-defined actions to different commands.

Examples described in the guide include:

C = Create PPD output
D = Duplicate a spooled file
E = Edit a spooled file
F = Send a spooled file as a fax

For Cobwebb Server version 6.2.81 and later, the guide says the source is available in:

Library:     CPPD
Source file: QUSRTOOLLE
Program:     COBSPLFEP

The guide also recommends compiling customized versions into a separate library so they are not lost during a product upgrade.

Even when the Cobwebb program is not used directly, the guide provides a useful example of the design pattern:

Register one custom option
Receive the selected spooled-file identity
Route the request to the appropriate existing command or program

Before and after

Before

User locates the spooled file.
User enters option 9.
User moves to another panel.
User enters option 2.
User identifies the correct printer queue.
User moves the spooled file.
The existing process converts and emails it.
The user contacts IT when something goes wrong.

After

User locates the spooled file.
User enters P.
User presses Enter.
The existing process converts and emails it.

The underlying conversion and email capability did not fundamentally change.

The user experience changed completely.

The business impact

This was a relatively small project.

It required:

But the operational impact was much larger.

The improvement helped deliver:

This was a low-effort and low-cost improvement with a significant result.

A practical modernization lesson

The IBM i application already worked.

The spooled-file interface already worked.

The PDF-conversion program already worked.

The email process already worked.

The missing piece was a user-friendly connection between them.

That is why this is a useful IBM i modernization example.

It did not replace the platform.

It used a capability of the platform to make an existing business process easier.

Modernization does not always mean replacement.

Sometimes modernization means removing unnecessary steps, reusing proven logic, and making technical complexity disappear for the user.

Final takeaway

A business user should not need to understand printer queues or internal spool-processing rules just to receive a report by email.

Using the IBM i spooled-file user-defined list-action exit point, we reduced a confusing multi-screen process to:

P + Enter

The implementation was small.

The existing programs were reused.

The cost and effort were low.

But the impact on users and the support team was significant.

That is the kind of IBM i improvement worth looking for:

Find the repeated point of friction. Extend what already works. Make the technical complexity disappear for the user.

References

Comments

Share your thoughts, questions, or real-world IBM i experiences related to this article.