• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4437
  • Last Modified:

List AS400 Printers

I  have about 35 ip printers on the system with about 25 of these at remote locations. When I have a problems with a printer and want to check to see if I can ping the printer, I have to do a WRKDEVD to get the ip address. I would like to be able to print a list with this information. Any ideas?
0
carl_gbi
Asked:
carl_gbi
  • 6
  • 5
1 Solution
 
daveslaterCommented:
Hi
use the CFGTCP, then option 10 - Host Names. You can then give the IP addresses meaningful names.

Then instead of  999.999.999.999 you can use Sales_Admin_Printer.

Dave
0
 
carl_gbiAuthor Commented:
Hi Dave,

All of the printer have meaningful names (SEATTLE, OAHU, etc.) , but I want to get a printout of the devices *PRT as follows.

PRINTER     IP ADDRESS                 TYPE
 
Seattle         10.1.100.50              LEXOPTRAS
Oahu            10.1.110.60              HP500
Portland       206.199.199.199       HP500

Is there a Physical File for the devices that I could run a query from?

Thanks
Carl
0
 
tliottaCommented:
Carl:

No. In general, OS/400 is object-based. Configuration info isn't generally stored in "files" but rather in the various object descriptions. Object methods are invoked to return attributes.

Now, for a device description, you can link device attributes to an output printer file by:

  ==>  dspdevd  devd( myprinter ) output( *print )

...but, that means each device will be specified separately and printed on different pages/spooled files; and that's probably not what you want.

In order to grab attributes for a set of devices, you can create a list of devices and then process the list. The list could be created with the List Configuration Descriptions (QDCLCFGD) API, specifying *DEVD for configuration type and *LANPRT for object qualifier. The list could be processed with user space APIs to get the next name from the list; and each name would be passed into the Retrieve Device Description (QDCRDEVD) API to retrieve address.

Name and address would be printed by whatever program is calling the APIs. This could be written in RPG, COBOL, C, CL, REXX, Java, just about anything. (I suppose even a QSH script.)

Note that WRKDEVD DEVD(*LANPRT) displays a list of all configured LAN printers. Any of them can be selected for display from the list. That is, address is easily available at any time.

Tom
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
carl_gbiAuthor Commented:
Guess it's time I started working with API's, been avoiding it.

Thanks Guys
0
 
tliottaCommented:
Carl:

We can provide a bunch of examples. I don't know if any of us have done what you want to do, but I've used all of the relevant APIs and can show usage. CL is often easiest for examples because _everybody_ has that language and ought to know how to translate into or out of it.

But help in other languages for specific issues is easy.

Tom
0
 
carl_gbiAuthor Commented:
Tom,

I would really appreciate some examples. CL would be the best format as I work with RPG. I tried doing this in EXCEL but I work for a Heavy Highway Contractor and our job sites are constantly moving so it gets away from me at times. It would be great if I could do a CALL at a command line and see for sure what the ip addresses are. I have not worked with APIs, just ordered a book from Amazon.com to get into it.

Thanks again
Carl
0
 
tliottaCommented:
Carl:

A beginning sample that creates a space and lists configuration descriptions into the space:

--------------- Begin paste
pgm       ( +
            &pqUsrSpc +
            &pFormat  +
            &pCfgDTyp +
            &pObjQual +
            &pStsQual +
          )

   dcl      &pqUsrSpc    *char    20
   dcl      &pFormat     *char     8
   dcl      &pCfgDTyp    *char    10
   dcl      &pObjQual    *char    40
   dcl      &pStsQual    *char    20


   monmsg   ( CPF0000 MCH0000 )  +
                    exec( goto  Std_Err )

   call       QUSCRTUS  ( +
                          &pqUsrSpc           +
                          'CFGDSC    '        +
                          x'00004000'         +
                          X'00'               +
                          '*ALL      '        +
                  'List configuration descriptions                   ' +
                          '*YES      '        +
                          x'0000000000000000' +
                        )


   call       QDCLCFGD  ( +
                          &pqUsrSpc  +
                          &pFormat   +
                          &pCfgDTyp  +
                          &pObjQual  +
                          &pStsQual  +
                          x'0000000000000000' +
                        )

   return


 Std_Err:

   /* Move any *DIAG messages up the stack...         */

   Qsys/call  QSYS/QMHMOVPM  ( +
                               '    '          +
                               '*DIAG     '    +
                               x'00000001'     +
                               '*         '    +
                               x'00000001'     +
                               x'00000000'     +
                             )
   Qsys/monmsg ( CPF0000 MCH0000 )

   /* Resend any *ESCAPE messages up the stack...     */

   Qsys/call  QSYS/QMHRSNEM  ( +
                               '    '          +
                               x'00000000'     +
                             )
   Qsys/monmsg ( CPF0000 MCH0000 )

   return

endpgm
--------------- End paste

A possible way to call this program:

CALL LUSCFGDSC  ( +
                  'LUSCFG    QTEMP     ' +
                  CFGD0100 +
                  '*DEVD     ' +
  '*LANPRT                                 ' +
                  '*GE       *VARYOFF  ' +
                )

Parms are:
 1. The name of a user space:
      pos 1-10  The name
      pos 11-20  The library
 2. Format for the List Configuration Descriptions API
      CFGD0100 -- Just the list, don't include status info
 3. *DEVD -- List device descriptions
 4. *LANPRT -- List LAN printer devices
 5. *GE/*VARYOFF -- Devices with status *VARYOFF or higher
      I.e., list all of them regardless of status

The example CALL statement has its parameters specified with trailing spaces in order to account for some ILE CL possible quirks (if you go ILE). The user space name is specified as name plus library because it's the way the two APIs want to receive the name; you can pass them in separately and concatenate them in the program before calling the APIs. I put the space in QTEMP, but you can put it wherever you choose; I see no reason for anything but QTEMP.

There is no error handling other then sending error messages back up the stack.

Take some time to review the IBM documentation for the two APIs -- QUSCRTUS and QDCLCFGD. If the values I set make no sense, ask about them. When they make some sense, you can see if you can retrieve the header info from the space and then process the list. More examples can be supplied as needed for more details.

If you call the program and a space is created and populated, you can use the DMPOBJ command to dump the contents of the space to a spooled file and get a look at it. You can compare what you see to the documentation for both lists in a space and configuration lists.

The example program could be called from another CL program, from an RPG program or from a command line (if the sample CALL is paid attention to).

Tom


0
 
tliottaCommented:
And here's one example of extracting an IP address from a device description once you've retrieved a name from the list:

--------------- Begin paste
pgm          ( +
               &pRtvDev     +
               &pTCPAddr    +
             )

/* Device to retrieve */
   dcl         &pRtvDev     *char     10
/* TCP/IP address     */
   dcl         &pTCPAddr    *char     15


/* Device to retrieve */
   dcl         &RtvDev      *char     10

/* Device name        */
   dcl         &DevNam      *char     10

/* Error field        */
   dcl         &ERROR       *char      4    value( x'00000000' )

/* Network protocol   */
/* Set to TCP/IP      */
   dcl         &Protocol    *char      1    value( x'02' )

/* Receiver variable  */
   dcl         &RcvVar      *char   1024


   monmsg    ( cpf0000 mch0000 ) exec( +
               goto   Std_Err )


/*  If we want 'current' device, get it from jobname...              */

   if ( &pRtvDev *eq '*' )      +
      rtvjoba     job( &RtvDev )
   else  +
      chgvar      &RtvDev        &pRtvDev


/*  Call the Retrieve Device Description API, Format DEVD0600        */
/*    to retrieve information about selected device. Constant        */
/*    '*BLANKS' will let us know if no DevNam is found...            */

   chgvar      &RcvVar        ' '
   chgvar      &pTCPAddr      '*BLANKS'

   call        QDCRDEVD     ( +
                              &RcvVar      /* RECEIVER VARIABLE    */  +
                              X'00000400'  /* LENGTH &RCVVAR (1024)*/  +
                              'DEVD0600'   /* FORMAT TO RECEIVE    */  +
                              &RtvDev      /* DEV ID TO RETRIEVE   */  +
                              &ERROR       /* ERROR FIELD          */  +
                            )


/*   Extract values from receiver variable if retrieved device       */
/*   is a TCP/IP device (position 859, network protocol = X'02')     */

   chgvar      &DevNam      %sst( &RcvVar  22  10 )


/*   No device name? Hmmm... leave constant '*BLANKS'...             */

   if ( &DevNam *ne ' ' )      do

      if ( %sst( &RcvVar 859   1 ) *eq &Protocol )  +
         chgvar      &pTCPAddr      %sst( &RcvVar 878  15 )

      else    /* Special SNA format */   +
         chgvar      &pTCPAddr    ( 'SNA:' *bcat %sst( &RcvVar 255  10 ) )

   enddo

   return


 Std_Err:

   /* Move any *DIAG messages up the stack...         */

   Qsys/call  QSYS/QMHMOVPM  ( +
                               '    '          +
                               '*DIAG     '    +
                               x'00000001'     +
                               '*         '    +
                               x'00000001'     +
                               x'00000000'     +
                             )
   Qsys/monmsg ( CPF0000 MCH0000 )

   /* Resend any *ESCAPE messages up the stack...     */

   Qsys/call  QSYS/QMHRSNEM  ( +
                               '    '          +
                               x'00000000'     +
                             )
   Qsys/monmsg ( CPF0000 MCH0000 )

   return

endpgm
--------------- End paste

Tom
0
 
carl_gbiAuthor Commented:
Hi Tom,

I have the QUSCRTUS and QDCLCFGD APIs running and I can see the printers when I dump my user space. The next step is to dig out the IP addresses, it may be a couple of weeks as I have to do some travel time. I sure appreciate your help, it has been interesting.

Carl
0
 
carl_gbiAuthor Commented:
Hi Tom,

I'm getting the printout, but I have a few questions. By looking at the program dump I found the IP address at a different offset than the one you used and different than the one IBM notes. I also had to use a different Format (DEVD1100) and a longer receiver variable to hold all of the data. I must be missing something but not sure what. Any ideas?

Thanks
Carl  
0
 
carl_gbiAuthor Commented:
To clarify, I used this EVAL statment to get the IP address.

EVAL      IPADD = %SUBST(Recvar:1064:15)
0
 
tliottaCommented:
Carl:

If the device type is *PRT, then format DEVD1100 should work fine. The offset is 1064 in that format.

Note that the field at offset 1064 is CHAR(256), so it might not contain an IP address -- it is expected that host names can be there as well. If you know that that won't ever be a problem in your network, then it shouldn't matter.

Also be aware that the value can potentially be null-terminated. IBM has a habit of slipping up either in new releases or after PTFs and allowing the underlying code to place values in the API formats without stripping null-terminators whenever interfaces interact with C kinds of functions. By grabbing 15 bytes, it's _possible_ you could pick up a stray trailing hex'00'. It's rare, but I've seen it more than once. Just a caveat.

Otherwise, you look to be well on your way to doing some interesting programming in your future. I'd have provided more info, but you didn't ask. Always nice when someone forges ahead on their own. Great learning experience.

Tom
0

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now