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.
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:
- a new web application
- changes to every existing program
- months of development
- a large modernization budget
- replacing a process that already works
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:
- process a selected spooled file
- convert it to PDF
- determine the appropriate recipient
- email the document
- handle logging and errors
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:
- why the spooled file had to be moved
- which printer queue had to be selected
- what the options on the additional panels meant
- how the printer queue triggered the email process
- what to do when a printer session ended abnormally
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:
- selected the wrong option
- moved the wrong spooled file
- selected the wrong printer queue
- became stuck on an unfamiliar panel
- ended printer-related sessions abnormally
- submitted the same request more than once
- contacted IT because they were unsure what to do next
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:
- no new application to learn
- no new menu to navigate
- no new URL or sign-in
- no change to the programs creating the spooled files
- no replacement of the existing PDF and email process
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:
- Receive the selected action.
- Receive the identity of the selected spooled file.
- Validate the request.
- Pass the identity to the existing processing program.
- 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:
- reusing an action that is already assigned
- registering a duplicate program unnecessarily
- interfering with an existing product
- removing the wrong registration later
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:
- spooled-file retrieval
- PDF conversion
- email-address lookup
- recipient validation
- email delivery
- retry logic
- logging
- error notification
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:
- expected report size
- conversion time
- email-processing time
- request volume
- existing application design
- user expectations
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:
- whether the user owns the spooled file
- authority to the output queue
- authority to process the selected report
- whether the report contains sensitive information
- how the recipient email address is determined
- whether users may override the recipient
- whether the action should be limited by user, group, or output queue
- logging who requested the document
- duplicate-request prevention
- failure notification
- retry behavior
- retention of the generated PDF
- cleanup of temporary PDF or IFS objects
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:
- one focused exit program
- one exit-point registration
- integration with existing conversion and email logic
- appropriate testing
- a small amount of user communication
But the operational impact was much larger.
The improvement helped deliver:
- fewer incorrect spool movements
- fewer user errors
- fewer abnormal printer-session problems
- fewer IT support tickets
- less user training
- faster delivery of reports
- a simpler and more consistent workflow
- continued reuse of the existing IBM i investment
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.
Comments
Share your thoughts, questions, or real-world IBM i experiences related to this article.