02
Sat, Nov
2 New Articles

Back Up to the IFS

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

The backup process has grown increasingly important over the years. Ironically, when DASD was unreliable some 20 years ago, backup operations were standard operating procedure. Today, they still are on the iSeries platform but not so much so on the PC. When was the late time you backed up your PC data? I purchased a small 4 GB external hard drive that attaches to my PC via a USB 2.0 cable. I plug it in, launch my backup routine, and 5 or 10 minutes later, my entire library of data files is backed up. I unplug it, throw it in a secure location (front pants pocket), and I've got an offsite backup.

But what about AS/400 and iSeries backups? Wouldn't it be great if it were just as easy to connect simple storage devices to the iSeries as it is to the PC? Well, it can be.

If IBM would give us the ability to back up data to the IFS, we could then map the IFS folder to a network drive on the PC and back up that data just like any others. I could, for example, back up my small company's critical data to the IFS and then copy it to a DVD-RAM drive, a CD, or even a reusable external disk drive.

Well, I'm here to tell you they do give you that capability. But like all things on the iSeries, you have to work for it a little.

Saving to a PC Disk

There are two ways to save your iSeries data to a PC disk. Both techniques work with FTP, but only one works with Mapped Network Drive support:

  1. Save to a save file in any OS/400 library.
  2. Save to a save file and move the save file to the IFS.

The first option is fairly straightforward. You create a save file, save your data to it, and then FTP the data to your PC. The save file can be FTPed like a database file. Just use the .SAVF file extension when transferring the save files. For example:

BINARY
GET /qsys.lib/qgpl.lib/myback.savf

These two FTP commands do the following: The BINARY command sets up the FTP transfer so that the data is not sent as clear ASCII text (which is important if you ever need to send the save file back up to the iSeries; it can't be altered). The GET command retrieves the save file. The save file is stored on your PC in the current local directory. I'm never really sure which directory that is while running Windows, so I've created a directory called BACKUP just for my save files. In this case, I would first run the following FTP command:

LCD /backup

Today, placing things in a directory just off the root directory isn't very popular, so if you have some deeply nested Windows directory, you should specify that instead. Remember to prefix any long directory name with double quotes (") or you'll get FTP syntax errors. For example:

LCD  "C:Documents and SettingsCozziMy DocumentsMy iSeries Backup

The quotes in front of the path name allow FTP to ignore the embedded blanks in the path name.

Many shops do not allow FTP or do not allow it from most OS/400 libraries. So this first option may not be viable for everyone. Many shops do, however, allow FTP from directories on the IFS. So the solution is to move the save file over to the IFS and then FTP it from there.

To do this, you need to do the following:

  1. Create the save file.
  2. Save the data to the save file.
  3. Use CPYTOSTMF to copy the save file to the IFS.
  4. FTP the save file from the IFS to your PC.

Obviously, an automated way to accomplish the first three steps would be a nice feature. Listed below is a CL command that will do the first three of these steps for you. I've called it Save Objects to the IFS (SAVOBJIFS). This command saves data to a save file and then copies the save file to the specified IFS location. Here is the command definition source code:

 SAVOBJIFS:  CMD        PROMPT('Save objects to IFS as *SAVF')
             /*  Command processing program is: SAVOBJIFS   */
             PARM       KWD(SAVCMD) TYPE(*CMDSTR) LEN(2048) MIN(1) +
                          PROMPT('SAVxxx command to run')
             PARM       KWD(SAVFLR) TYPE(*PNAME) LEN(640) +
                          DFT('/BACKUP') EXPR(*YES) PROMPT('IFS +
                          folder location')
             PARM       KWD(STMF) TYPE(*CHAR) LEN(32) DFT(*SAVF) +
                          SPCVAL((*SAVF) (*SAVFLR)) EXPR(*YES) +
                          PROMPT('SAVF file name on IFS')
             PARM       KWD(STMFOPT) TYPE(*CHAR) LEN(10) RSTD(*YES) +
                          DFT(*REPLACE) SPCVAL((*NONE) (*REPLACE) +
                          (*ADD)) EXPR(*YES) PROMPT('Stream file +
                          option')

SAVOBJIFS Parameter Descriptions

The following describes each parameter of the SAVOBJIFS command.

SAVCMD is the save command you want to run to perform your save routine. Since TYPE(*CMDSTR) is specified for this parameter, you may prompt any OS/400 CL command, including the save commands, such as SAVOBJ or SAVLIB. This is similar to the CMD parameter of the SBMJOB command.

The specified command is run, and the data is saved. You are expected to specify the following parameters on the SAVOBJ or SAVLIB commands:

DEV(*SAVF)  SAVF(xxx/MYSAVE) CLEAR(*ALL)

The DEV parameter indicates that the save should be performed to a save file. The save file does not need to exist; the SAVOBJIFS command will automatically create it for you.

  • The SAVF parameter indicates the name of the save file into which the save is performed.
  • The CLEAR parameter causes the save file to be cleared first before saving the new data. If you do not specify the CLEAR parameter, you'll get an inquiry message that asks you to enter a C or G. Typing a G clears the save file; a C causes the save operation to be cancelled.

SAVFLR is the name of the directory on your IFS where the save file will be copied. You may specify only the folder/directory name or the folder/directory name and the IFS file name into which the save file is copied. If you do not specify a file name, the file name on the STMF parameter is used as the file name.

STMF is the stream file name. "Stream file" is a confusing term IBM ported from other platforms. It basically means "file name." For this parameter, specify the name of the file as it will appear on the IFS in the folder/directory specified on the SAVFLR parameter.

Two special values may be specified for this parameter:

  • *SAVF causes SAVOBJIFS to detect and extract the save file name specified on the SAVOBJ or SAVLIB command on the SAVCMD parameter. The save file name is used as the IFS file name, and the .SAVF file extension is added. So if the value SAVF(QGPL/MYBACKP) is specified, the file named MYBACKUP.SAVF is created.
  • *SAVFLR indicates that you have already specified a full path and file name on the SAVFLR parameter. So the STMF parameter is not used.

STMFOPT is the stream file replace/add option. If *REPLACE is specified, the existing stream file is replaced. If *ADD is specified, the existing stream file is added to. If *NONE is specified, it is assumed that the stream file does not exist.

To make this command work, I had to choose between CL and RPG IV. Since CL doesn't have built-in search capabilities, I decided to go with pure RPG IV as the command processing program.

The RPG IV source below is the command processing program for the SAVOBJIFS command. This version requires the save file to already exist (just like the SAVOBJ and SAVLIB commands do). A future version will automatically create the save file for you.

     OPTION(*SRCSTMT:*NODEBUGIO)
     DFTACTGRP(*NO) ACTGRP(*NEW) BNDDIR('QC2LE')
     **************************************************************
     **  SAVE OBJECTS to the IFS                                 **
     **  (c) 2005 - Robert Cozzi, Jr.                            **
     **************************************************************

      ** Parameters
     D SaveCmd         S           2048A
     D ifsLoc          S            640A
     D stmfName        S             32A
     D stmfopt         S             10A

      **  Command string work fields
     D szCmd           S           2048A   Varying
     D szStmf          S           1024A   Varying
     D szIFSName       S           1024A   Varying
     D szMbrOpt        S             32A   Varying

      **  Fields to hold the name of the save file
     D savf            S             21A
     D SaveFile        DS
     D  SAVFile                      10A
     D  SAVFLib                      10A

      **  Helper function to do simple lower 
      **  to upper case conversion
     D ToUpper         PR          4096A   Varying
     D  inString                   4096A   Varying VALUE
     
      **  Helper function to determine the library
      **  name when *LIBL or *CURLIB is specified
      **  for the save file name.
     D GetObjLib       PR            10A
     D  Object                       20A   Const
     D  objType                      10A   Const

      **  Helper function to write ad-hoc messages
      **  out to the joblog
     D JobLog          PR
     D  szMsg                      1024A   Const Varying

      **  Unix API to write to the joblog
     D Qp0zLprintf     PR            10I 0 ExtProc('Qp0zLprintf')
     D  szOutputString...
     D                                 *   Value OPTIONS(*STRING)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
      *********************************************************
      ** R E T R I E V E  O B J E C T  D E S C R I P I T I O N
      *********************************************************
      /INCLUDE QSYSINC/QRPGLESRC,QUSEC
      /INCLUDE QSYSINC/QRPGLESRC,QUSROBJD
     D QRtvObjD        PR                  ExtPgm('QUSROBJD')
     D  rtnData                   65535A   OPTIONS(*VARSIZE)
     D  nRtnDataLen                  10I 0 Const
     D  Format                        8A   Const
     D  QualObj                      20A   Const
     D  ObjType                      10A   Const
     D  apiError                           Like(QUSEC)

      **  C runtime function to run OS/400 CL commands.
     D system          PR            10I 0 ExtProc( 'system' )
     D  szCmd                          *   Value Options( *String )

      **  Named constants used to find the save file name
     D SAVDEV          C                   Const('DEV(*SAVF)')
     D SAVFPARM        C                   Const('SAVF(')
      **  Work fields used for location 
      **  and offset of save file name.
     D nPos            S             10I 0
     D nStart          S             10I 0
     D nEnd            S             10I 0
     D nLen            S             10I 0

     C     *ENTRY        PLIST
     C                   Parm                    SaveCmd
     C                   Parm                    ifsLoc
     C                   Parm                    stmfName
     C                   Parm                    stmfOpt

     C                   eval      *INLR = *ON

      **  Convert the SAVxxx command to upper case to 
      **  make searching it easier.
     C                   eval      szCmd = ToUpper(saveCmd)
     C                   eval      nPos = %scan(SAVDEV : szCmd )

      **  Sorry, can't help you if you don't specify DEV(*SAVF)                 
     C                   if        nPos = 0
     C                   Callp     JobLog('* Must specify DEV(*SAVF) for +
     C                                       SAVOBJIFS command.')
     C                   return
     C                   endif
     C                   eval      nPos = %scan(SAVFPARM : szCmd )
     C                   if        nPos = 0
     C                   Callp     JobLog('* Must specify SAVF name for +
     C                                       SAVOBJIFS command.')
     C                   return
     C                   endif

      **  We're okay!
      **  Find the end of the save file parameter
      **  so that we can extract the save file name
     C                   eval      nEnd = %scan(')':szCmd:nPos+%len(SAVFPARM))
     C                   if        nPos > 0 and nEnd > 0
     C                   eval      nStart = nPos + %Len(SAVFPARM)
     C                   eval      nLen   = nEnd - nStart
     C                   if        nLen > 0
     C                   eval      SAVF = %subst(szCmd:nStart:nLen)
     C                   eval      nPos = %scan('/':savf)
     C                   if        nPos = 0 or %subst(savf:1:1) = '*'
     C                   eval      savflib = GetObjLib(savfile : '*FILE')
     C                   else
     C                   eval      savflib = %subst(savf:1:nPos-1)
     C                   eval      savfile = %subst(savf:nPos+1)
     C                   endif
     C                   endif
     C                   endif

     C                   if        SAVF = *BLANKS
     C                   callp     Joblog('* Save file name missing. It is +
     C                                       required for SAVOBJIFS command.')
     C                   return
     C                   endif

      **  TODO:  Insert code here to create save file
      **         if it does not exist.

      **  Run the user-specified SAVxxx command
     C                   callp(e)  system(savecmd)
     C                   if        %Error
     C                   callp     Joblog('* Error on save command. +
     C                                       See joblog for details.')
     C                   return
     C                   endif
     
      **  Get ready for transfer to the IFS
     C                   if        stmfName  = '*SAVF'
     C                   eval      szIFSName = %TrimR(ifsloc) + '/' +
     C                                         %TrimR(savfile) + '.savf'
     C                   endif
     C                   if        stmfName = '*STMF' or
     C                              stmfName = '*IFSFLR' or
     C                              stmfName = '*STMFLR' or
     C                              stmfName = '*SAVFLR'
     C                   eval      szIFSName = %TrimR(ifsloc)
     C                   endif
     C                   if        %subst(stmfName:1:1) <> '*'
     C                   eval      szIFSName = %TrimR(ifsloc) + '/' +
     C                                         %TrimR(stmfName)
     C                   endif

     C                   if        stmfopt <> *BLANKS
     C                   eval      szMbrOpt = 'STMFOPT(' + %trimr(stmfopt) + ')'
     C                   endif

     C                   eval      szStmf = '/qsys.lib' +
     C                                      '/' + %Trim(savflib) + '.lib' +
     C                                      '/' + %Trim(savfile) + '.file'

      **  The CPYTOSTMF CL command works for our needs.
     C                   eval      szCmd =  'CPYTOSTMF FROMMBR(''' +
     C                                      %TrimR(szStmf) + ''') ' +
     C                                      'TOSTMF(''' + %TrimR(szIfsName) +
     C                                      ''') CVTDTA(*NONE) ' + szMbrOpt
     C

      **  Copy the save file to the IFS.
     C                   callp(e)  system(szCmd)

     C                   return

     P ToUpper         B
     D ToUpper         PI          4096A   Varying
     D  inString                   4096A   Varying VALUE

     D lower           C                   'abcdefghijklmnopqrstuvwxyz'
     D UPPER           C                   'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

     C                   if        %Len(inString) > 0
     C     lower:UPPER   XLate     inString      inString
     C                   endif
     C                   return    inString
     P ToUpper         E

     P Joblog          B
     D JobLog          PI
     D  szMsg                      1024A   Const Varying

     C                   Callp     Qp0zLprintf(szMsg + X'25')
     C                   return
     P Joblog          E

     P GetObjLib       B
     D GetObjLib       PI            10A
     D  Object                       20A   Const
     D  objType                      10A   Const

      ** OBJECT input parameter must have the following format:
     D ObjName         DS
     D  Obj                          10A
     D  Lib                          10A

     C                   callp(e)  QrtvObjD(QUSD0100 : %size(QUSD0100) :
     C                                      'OBJD0100' : object : objtype :
     C                                       QUSEC )
     C                   return    QUSOBJLN

     P GetObjLib       E

(Note: As always, the source for this week's programs is available on my Web site. Click on "Free RPG IV Downloads.")

To compile these two source members, just use the default PDM option 14 settings. The RPG IV header specifications will override the default settings, and the CMD source will use the command name as the command processing program name.

Once the programs are compiled and you've run the SAVOBJIFS command, you'll have a copy of your save file on the IFS that you can easily FTP to an external PC storage device.

If you use the Map Network Drive function, you could even drag and drop the save file onto a recordable CD, DVD, or micro drive, thereby keeping your important iSeries files in your own desk drawer.

Bob Cozzi is a programmer/consultant, writer/author, and software developer. His popular RPG xTools add-on subprocedure library for RPG IV is fast becoming a standard with RPG developers. His book The Modern RPG Language has been the most widely used RPG programming book for more than a decade. He, along with others, speaks at and produces the highly popular RPG World conference for RPG programmers.

BOB COZZI

Bob Cozzi is a programmer/consultant, writer/author, and software developer. His popular RPG xTools add-on subprocedure library for RPG IV is fast becoming a standard with RPG developers. His book The Modern RPG Language has been the most widely used RPG programming book for more than a decade. He, along with others, speaks at and produces the highly popular RPG World conference for RPG programmers.


MC Press books written by Robert Cozzi available now on the MC Press Bookstore.

RPG TnT RPG TnT
Get this jam-packed resource of quick, easy-to-implement RPG tips!
List Price $65.00

Now On Sale

The Modern RPG IV Language The Modern RPG IV Language
Cozzi on everything RPG! What more could you want?
List Price $99.95

Now On Sale

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

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: