DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400 Tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400 Tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ M T

⟦0b3cb992d⟧ TextFile

    Length: 67646 (0x1083e)
    Types: TextFile
    Names: »MACHINE_INITIALIZATION_HELP«

Derivation

└─⟦5f3412b64⟧ Bits:30000745 8mm tape, Rational 1000, ENVIRONMENT 12_6_5 TOOLS 
    └─ ⟦91c658230⟧ »DATA« 
        └─⟦f6fec0485⟧ 
            └─⟦this⟧ 
└─⟦d10a02448⟧ Bits:30000409 8mm tape, Rational 1000, ENVIRONMENT, D_12_7_3
    └─ ⟦fc9b38f02⟧ »DATA« 
        └─⟦f95d63c89⟧ 
            └─⟦this⟧ 

TextFile

@node !Machine.Initialization
                                          
                                   Contents


       1.  Guide to Machine Initialization                             
          1.1.  Overview                                               
             1.1.1.  World !Machine.Initialization.Rational            
             1.1.2.  Worlds !Machine.Initialization.[Site,Local]       
          1.2.  Setting Up the Site and Local Worlds                   
          1.3.  Hints for Implementing System Customizations           
             1.3.1.  Writing Customized Initialization Procedures      
             1.3.2.  Using "_Start" Files to Reference Initialization
                     Procedures                                        
             1.3.3.  Controlling the Order of Execution                
             1.3.4.  Customizing Disk-Collection Thresholds           
          1.4.  Enabling and Configuring Login Ports                  
             1.4.1.  Enabling Ports for Login                         
             1.4.2.  Customizing Port Characteristics                 
             1.4.3.  A Sample Terminal_Configuration File             
             1.4.4.  Terminal-Configuration Options                   
          1.5.  Configuring Printers                                  
             1.5.1.  Where to Specify Printer Information             
             1.5.2.  Adding Entries to a Printer_Configuration File   
             1.5.3.  Specifying a Directly Connected Printer          
             1.5.4.  Specifying a Networked Printer                   
             1.5.5.  Specifying an Environment File                   
             1.5.6.  Specifying a Workstation Directory               
             1.5.7.  Associating Default Printers with Individual 
                     Users                                            


       1.  Guide to Machine Initialization

       D_12_5_0 changed the software that is automatically executed by
       the Environment during the boot process. These changes apply to
       D_12_5_0 and all subsequent releases (including D_12_6_5). In
       particular, the software was reorganized to make it easier to:

       *  Install layered products

       *  Distinguish Rational-specific, site-specific, and
          machine-specific customizations

       *  Configure a network of printers for large sites

       The following subsections describe the D_12_5_0 mechanisms for
       initializing an R1000. See also the "Installation Procedure" for
       specific steps to convert any existing initialization software to
       the D_12_5_0 mechanisms.

       This document also can be found online in
       !Machine.Initialization.Guide_To_Machine_Initialization.


       1.1.  Overview

       Each time an R1000 is booted, software is executed that
       initializes layered products, sets various system parameters (for
       example, disk-collection thresholds and snapshot intervals),
       starts servers, enables terminals, and so on.

       In Environment releases prior to D_12_5_0, the boot process
       automatically executed !Machine.Initialize, which in turn
       executed a family of procedures (with names of the form
       !Machine.Initialize_@).

       In D_12_5_0 and subsequent releases, !Machine.Initialize is no
       longer used. Instead, all system-initialization software resides
       in the world !Machine.Initialization, which is structured as
       shown: ]

          !Machine.Initialization : Library (World);
            Local    : Library (World);
            Rational : Library (World);
            Site     : Library (World);
            Start    : Ada (Load_Proc);

       The D_12_5_0 (or later) boot process automatically executes the
       Start procedure, which in turn executes all the procedures that
       reside in (or are referenced in) the Local, Rational, and Site
       worlds:

       *  The world Rational contains or references software that
          initializes Rational products and provides standard settings
          for many system parameters. Users should not modify the
          objects in this world.

       *  The worlds Site and Local provide a place for system managers
          to put objects that customize the initialization process. Such
          objects can be used to override various standard system
          parameter settings, to initialize customer-written
          applications, and to specify terminal and printer
          configurations:

          -  The world Site is intended for customer-written objects
             that are common to two or more machines at a given site.

          -  The world Local is intended for customer-written objects
             that apply only to the current R1000.

       The following subsections give more detail about these worlds.


       1.1.1.  World !Machine.Initialization.Rational

       The Rational world contains objects supplied by Rational that
       perform basic initialization services for the current R1000.
       These objects include:

       *  Loaded main procedures that are executed by
          !Machine.Initialization.Start whenever the system is booted.

       *  "_Start" files that reference procedures located elsewhere in
          the Environment. These are text files whose names end with
          _Start; the procedures they reference are executed by
          !Machine.Initialization.Start.

       On a typical system, this world contains objects such as the
       following:

          !Machine.Initialization.Rational : Library (World);
            Clean_Machine_Temporary   : C Load_Proc;
            Cross_Compilers           : C Load_Proc;
            Design_Facilities         : C Load_Proc;
            Dtia                      : C Load_Proc;
            Finish_Install            : C Load_Proc;
            Log_Previous_Outage_Start :   Text;
            Mail_Start                :   Text;
            Network                   : C Load_Proc;
            Parameters                : C Load_Proc;
            Printers                  : C Load_Proc;
            Servers                   : C Load_Proc;
            Teamwork_Interface        : C Load_Proc;
            Terminals                 : C Load_Proc;

       The procedures that are supplied or referenced in this world:

       *  Perform cleanup and compaction

       *  Initialize the installed Rational products, such as CDFs, RDF,
          Rational Networking, and so on

       *  Initialize servers, including the archive and FTP servers

       *  Set standard values for various system parameters, such as the
          medium-term scheduler, snapshot intervals and warnings,
          disk-collection thresholds, and so on

       *  Initialize terminals and printers according to user-specified
          requirements (given in files in the Site and Local worlds)

       For more specific information, you can browse the comments in
       each object in this world.


       1.1.2.  Worlds !Machine.Initialization.[Site,Local]

       The Site and Local worlds are where system managers can create
       objects to control sitewide or machine-specific initialization
       and configuration. These objects may include:

       *  Ada procedures that supplement or override the basic
          initialization services performed by objects in the Rational
          world. All procedures in the Site and Local worlds are
          executed by !Machine.Initialization.Start each time the system
          is booted.

       *  "_Start" files that reference procedures located elsewhere in
          the Environment. These are text files whose names end with
          _Start; the procedures they reference are executed by
          !Machine.Initialization.Start. Using a "_Start file" is
          equivalent to calling Program.Run or Program.Run_Job to
          execute the referenced procedure. (See section 1.3.2.)

       *  Configuration files that tell the Environment how to enable
          and configure ports for login and ports for printing. These
          are text files that are read by two of the procedures executed
          by !Machine.Initialization.Start. A default file for enabling
          login ports is created in the Local world during installation.
          (See sections 1.4 and 1.5.)

       *  Text files that tell the Environment how to initialize layered
          products such as the Cross-Development Facility or the
          Rational Design Facility. (See the comments in the
          specifications of the Cross_Compilers and Design_Facilities
          procedures in world !Machine.Initialization.Rational.)

       At most sites, system managers will use the Site and/or Local
       worlds as a place for procedures (or "_Start" files) that:

       *  Set password policy

       *  Set login limits

       *  Start server programs for site-specific networking, databases,
          and applications (for example, a login monitor or network
          security server)

       At some sites, system managers may need to use these worlds for
       procedures that:

       *  Provide nonstandard daemon settings-for example:

          -  The time at which daily and weekly clients run. (The
             standard times are 3:00 a.m. for daily clients and 2:30
             a.m. for weekly clients.)

          -  How often snapshots are taken. (The standard snapshot
             interval is every 30 minutes.)

          -  Whether (and when) to send a snapshot warning, snapshot
             start messages, and snapshot finish messages. (The standard
             is to send a warning 20 seconds before the next snapshot
             and to notify users only when the snapshot has finished.)

          -  The interval for daemon warnings. (The standard is to send
             a warning 2 minutes before the daily clients begin.)

          -  Whether to send disk-collection threshold warnings. (The
             standard is to warn users when collection thresholds have
             been passed.)

          -  What kinds of system log messages appear on the operator
             console. (The standard is to route only warning, problem,
             and fatal messages to the operator console.)

          -  Whether clients should perform access-list compaction. (The
             standard is for all relevant clients to perform access-list
             compaction.)

       *  Provide customized disk-collection thresholds (see also
          section 1.3.4). Note, however, that values set by the
          procedure in world Rational are calculated based on your disk
          configuration and should be sufficient; see your Rational
          technical representative if you want to use different
          thresholds.

       *  Provide nonstandard medium-term scheduler settings. (Use the
          Scheduler.Display command to see the standard settings.) Note,
          however, that values set by the procedure in world Rational
          should be sufficient; see your Rational technical
          representative if you want to use different settings.


       1.2.  Setting Up the Site and Local Worlds

       If you have a new R1000, you can use the following guidelines to
       set up your Site and Local worlds:

       1. Decide whether you need to provide any system customizations
          such as those listed in section 1.1.2. Create the appropriate
          procedures and/or "_Start" files, using the hints given in
          section 1.3.

       2. Inspect the default Terminal_Configuration file that was
          created in the Local world during installation. This file
          enables ports 235 through 249 for login. Edit this file if you
          want to enable a different set of ports and/or specify further
          connection or communication information; see section 1.4.

       3. Decide whether to implement a printer-configuration mechanism
          to enable users to use !Commands.Abbreviations.Print and to
          facilitate the use of networked printers. Create the
          appropriate files; see section 1.5.

       4. If you have layered products such as the CDF or RDF, inspect
          the comments in the specifications of the Cross_Compilers and
          Design_Facilities procedures in world
          !Machine.Initialization.Rational. Create any files required
          for initializing these products (for example, a text file that
          registers an RDF customization).

       If you are upgrading from a release prior to D_12_5_0, the Local
       world will already contain several objects that contain
       customizations:

       *  A Terminal_Configuration file is created automatically in the
          Local world, enabling the same set of ports that were enabled
          at the time of installation. This file also preserves any
          nondefault communication characteristics that were in effect
          for RS232 ports.

       *  The !Machine.Initialize_Site procedure is automatically moved
          into the Local world, as described in the "Installation
          Procedure."

       After your R1000 has been upgraded to D_12_5_0 or a more recent
       release, you can use the following guidelines to set up your Site
       and Local worlds:

       1. Inspect the Initialize_Site procedure that has been copied
          into the Local world during installation. Edit this procedure
          to preserve any system customizations that are still
          appropriate. You may want to split this procedure into
          separate procedures and move appropriate procedures into the
          Site world. See the "Installation Procedure" for specific
          recommendations for handling this procedure. See also section
          1.3 for information about initialization procedures and
          "_Start" files.

       2. Inspect the default Terminal_Configuration file that was
          created in the Local world during installation. Edit this file
          if you want to enable a different set of ports and/or specify
          further connection or communication information; see section
          1.4.

       3. Decide whether to implement a printer-configuration mechanism
          to enable users to use !Commands.Abbreviations.Print and to
          facilitate the use of networked printers. Create the
          appropriate files; see section 1.5.

       4. If you have layered products such as the CDF or RDF, inspect
          the comments in the specifications of the Cross_Compilers and
          Design_Facilities procedures in world
          !Machine.Initialization.Rational. Create any files required
          for initializing these products (for example, a text file that
          registers an RDF customization).


       1.3.  Hints for Implementing System Customizations

       This section provides information about:

       *  Writing customized initialization procedures in the Site and
          Local worlds; see section 1.3.1.

       *  Writing "_Start" files that reference procedures that reside
          in other Environment libraries; see section 1.3.2.

       *  Controlling the order in which the customized initialization
          procedures and the "_Start" files are processed by the Start
          procedure; see section 1.3.3.

       *  Customizing disk-collection thresholds; see section 1.3.4.


       1.3.1.  Writing Customized Initialization Procedures

       You can write procedures in the Site or Local worlds to implement
       system customizations such as password policies, system daemon
       settings, and so on. All procedures that appear in these worlds
       are executed by the Start procedure each time the R1000 boots.

       Customized initialization procedures can contain calls to
       procedures in various standard Environment packages. Some useful
       packages include:

       *  Package Daemon, which contains procedures that schedule
          clients and warnings

       *  Package Operator, which contains procedures that set password
          policy and login limits

       *  Package Scheduler, which contains procedures that control the
          medium-term scheduler

       *  Package Program, which contains procedures that execute other
          programs

       Note that:

       *  You do not have to provide initialization procedures for
          configuring login ports and printer ports; it is recommended
          that you use configuration files instead (see sections 1.4 and
          1.5).

       *  You do not have to write an initialization procedure "from
          scratch" for customizing disk-collection thresholds; if you
          must customize these thresholds, it is recommended that you
          edit the sample initialization procedure provided in the Local
          world (see section 1.3.4).

       When writing customized initialization procedures:

       *  You can create separate procedures or put all calls in a
          single procedure. Separate procedures take longer to execute
          but make it easier to see what operations are being performed.

       *  You must not duplicate procedure names across the Rational,
          Site, and Local worlds.

       *  You can specify the relative execution order of procedures
          using annotations (see section 1.3.3).


       1.3.2.  Using "_Start" Files to Reference Initialization Procedures

       As an alternative to writing procedures directly in the Site and
       Local worlds, you can create "_Start" files in one or both worlds
       to reference customized initialization procedures that reside
       elsewhere in the Environment. "_Start" files are processed by the
       Start procedure each time the R1000 boots, and the procedures
       they reference are executed.

       When writing "_Start" files:

       *  You must choose filenames that use the _Start suffix.

       *  You must not duplicate filenames across the Rational, Site,
          and Local worlds.

       *  You must use annotations to reference the procedure to be
          executed, as illustrated below.

       *  You may use annotations to control the order in which the
          Start procedure executes the referenced procedures (see
          section 1.3.3).

       Referencing a procedure in a world or directory: A "_Start" file
       with the following contents illustrates the basic set of
       annotations required to reference a procedure that resides in an
       Environment world or directory:

          --|Procedure_Name Initialize_Routine
          --|Procedure_Context !Commands.Example
          --|Parameters Notify => "manager",
          --|Parameters Effort_Only => False

       *  The --|Procedure_Name annotation specifies the name of the
          referenced procedure. If the procedure resides directly in a
          library, you supply the procedure's simple name; if it resides
          in a package, supply the name in the form
          Package_Name.Procedure_Name.

       *  The --|Procedure_Context annotation specifies the Environment
          world or directory that contains the referenced procedure.

       *  Each of the --|Parameters annotations specifies the value to
          be used for one of the procedure's parameters. Note that
          string values must be enclosed in quotation marks, and commas
          must be included to separate multiple parameters.

       Referencing a procedure in a subsystem: A "_Start" file with the
       following contents illustrates how to reference a procedure that
       resides in an Environment subsystem. Note that you must replace
       the --|Procedure_Context annotation with the --|Subsystem and
       (optional) --|Activity annotations:

          --|Procedure_Name Excelan_Boot_Server
          --|Subsystem !Targets.Implementation.Motorola_68k_Download
          --|Activity !Machine.Release.Current.Activity
          --|No_Wait

       *  The --|Subsystem annotation specifies the name of the
          subsystem that contains the procedure. (When this annotation
          is specified, the --|Procedure_Context annotation is ignored.)

       *  The --|Activity annotation specifies the activity to be used
          to obtain the view name and construct the full pathname of the
          procedure. If you omit this annotation,
          !Machine.Release.Current.Activity is used.

       *  Note that Excelan_Boot_Server is a parameterless procedure;
          otherwise, one or more --|Parameters annotations would be
          present.

       *  The --|No_Wait annotation permits concurrent execution (see
          section 1.3.3). This annotation is present because this
          procedure starts a server.

       Specifying further information: "_Start" files may also contain
       annotations that control the order in which the Start procedure
       will execute the referenced procedures. See section 1.3.3.

       Using a "_Start" file is equivalent to executing the referenced
       procedure via Program.Run_Job or Program.Run. See the comments in
       the specification of !Machine.Initialization.Start for additional
       annotations that specify the equivalent of the Options parameter
       in the Program.Run_Job procedure and the Context parameter in the
       Program.Run and Program.Run_Job procedures.


       1.3.3.  Controlling the Order of Execution

       You can specify the relative execution order of all
       initialization procedures (including those referenced in "_Start"
       files). To do this, you include annotations in the appropriate
       procedure specifications or "_Start" files:

       *  To specify that procedure A cannot run until procedure B has
          finished, you include the annotation --|Prerequisite B in the
          specification of procedure A (or in the "_Start" file that
          references procedure A).

          If procedure B is referenced in a "_Start" file, you specify
          the filename as the annotation's argument: --|Prerequisite
          B_Start.

          Note that the argument of this annotation is a simple name and
          that all three worlds (Rational, Local, and Site) are searched
          for that simple name. Therefore, simple names must be unique
          across these three worlds if you want to use this annotation.

       *  To specify that procedure A must finish before any other
          procedure can start executing, you include the annotation
          --|Wait in the specification of procedure A (or in the
          "_Start" file that references procedure A).

          Using this annotation is equivalent to executing procedure A
          using Program.Run.

       *  To specify that procedure A is to execute as a separate job
          concurrent with other procedures, you include the annotation
          --|No_Wait in the specification of procedure A (or in the
          "_Start" file that references procedure A).

          Using this annotation is equivalent to executing procedure A
          using Program.Run_Job.

       If none of the annotations listed above are present in a given
       procedure or "_Start" file, the --|Wait annotation is assumed.
       That is, procedures are executed sequentially unless told
       otherwise.

       If a circular dependency results from a combination of
       annotations, it will be reported and ignored, so that each
       procedure will run.

       Note that you can execute the Start command with the Effort_Only
       parameter set to True to test the execution order that results
       from your annotations.

       See the comments in the specification of the
       !Machine.Initialization.Start procedure for a complete
       description of annotation usage, along with examples.


       1.3.4.  Customizing Disk-Collection Thresholds

       You can customize the disk-collection thresholds for the
       particular needs of your site. To implement a change in your
       disk-collection thresholds:

       1. Create an empty Ada unit in the Local world.

       2. Copy the contents of the
          !Machine.Initialization.Local.Local_Gc_Thresholds_Sample file
          into the empty Ada unit.

       3. In the Ada unit, edit the Thresholds1 and Thresholds2 arrays
          to specify the desired thresholds.

       4. Promote the Ada unit.

       Note, however, that values set by the procedure in world Rational
       are calculated based on your disk configuration and should be
       sufficient; see your Rational technical representative if you
       want to use different thresholds.


       1.4.  Enabling and Configuring Login Ports

       D_12_5_0 and subsequent releases provide a file-driven mechanism
       in !Machine.Initialization for enabling and configuring ports for
       login.

       At the very least, you must ensure that this mechanism has enough
       information to enable the desired login ports (see section
       1.4.1). In addition, you may optionally use this mechanism to
       specify:

       *  Connection and terminal-type characteristics for Telnet and
          RS232 ports, such as logoff on disconnect, disconnect on
          logoff, and so on

       *  Communication characteristics for RS232 ports, such as flow
          control, parity, and so on

       Such information is specified using the options described in
       section 1.4.4.


       1.4.1.  Enabling Ports for Login

       Ports for terminal devices must be enabled for login each time an
       R1000 boots. Accordingly, the !Machine.Initialization.Start
       procedure calls a procedure called Terminals in the Rational
       world. This procedure in turn consults a file called
       Terminal_Configuration in the Local world to determine which
       ports to enable for login. This file-driven mechanism takes the
       place of a procedure such as !Machine.Initialize_Terminals, which
       enables terminals through calls to the Operator.Enable_Terminal
       procedure.

       The Terminal_Configuration file is created automatically in the
       Local world during installation:

       *  On a new machine, a Terminal_Configuration file is created
          that enables ports 235 through 249 for login.

       *  On an R1000 that is being upgraded from a previous Environment
          release, the Terminal_Configuration file contains entries for
          the same set of ports that were enabled at the time of
          installation. (This file also preserves any nondefault
          communication characteristics that were in effect for RS232
          ports; see section 1.4.4.)

       You can edit the Terminal_Configuration file at any time to
       change which ports are enabled. The changes take effect the next
       time you boot the R1000. Alternatively, you can execute the
       Rational.Terminals procedure to make the changes take effect
       without booting the R1000. Note that you must keep the
       Terminal_Configuration file in the Local world, even if you want
       to enable the same ports on all machines at a given site.

       Following is a sample Terminal_Configuration file containing
       basic enabling information:

          16 => (Enable)
          224 .. 249 => (Enable)
          -- Ports 250 and 251 are for printers; disable them for login
          250..251 => (Login_Disabled)

       As shown, the Terminal_Configuration file consists of:

       *  Comments preceded with Ada comment notation (--)

       *  Entries of the general form: Port_Range => (Options), where:

          -  Port_Range can be a single port number or a range of port
             numbers

          -  Options must be enclosed in parentheses

       The options that pertain to enabling and disabling ports are
       summarized in Table 1.

              Table 1   Options for Enabling and Disabling Ports
        ------------------------------------------------------------ 
       |            |                                               |
       |   Option   |                  Description                  |
        ------------------------------------------------------------ 
       |            |                                               |
       |Enable      |When specified for a given port, enables the   |
       |            |port for login. Note that the port cannot      |
       |            |subsequently be enabled for any other device,  |
       |            |such as a printer.                             |
        ------------------------------------------------------------ 
       |            |                                               |
       |Login_      |When specified for a given port, prevents the  |
       |Disabled    |port from being enabled for login-for example, |
       |            |by subsequent usage of the                     |
       |            |Operator.Enable_Terminal command. Note that the|
       |            |port can subsequently be enabled for other     |
       |            |devices, such as printers.                     |
        ------------------------------------------------------------ 
       |            |                                               |
       |Disable     |When specified for a given port, disables the  |
       |            |port for all devices. Note that the port can   |
       |            |subsequently be enabled for any device,        |
       |            |including login. Specifying this option is     |
       |            |equivalent to having no entry for the port in  |
       |            |the file.                                      |
        ------------------------------------------------------------ 


       Port 16 is always enabled for login, regardless of whether an
       entry exists for it. An entry for port 16 is included in the
       automatically created Terminal_Configuration file for
       explicitness.

       Do not assign the Enable option to any port that you plan to
       enable for a printer or other device (such as a CDF). Instead,
       you can assign the Login_Disabled option or the Disable option to
       those ports, or you can simply omit entries for them from the
       file. Assigning the Login_Disabled option is recommended if you
       want to ensure that printer ports cannot be enabled for login
       even if the print spooler is killed.


       1.4.2.  Customizing Port Characteristics

       You can add information to the Terminal_Configuration file to
       specify connection characteristics for RS232 ports and
       communication characteristics for RS232 and Telnet ports. Such
       information is specified through the options listed in section
       1.4.4.

       The simplest way to specify multiple options is to assign them
       directly to a port or range of ports:

       *  Multiple options in a single entry must be enclosed in
          parentheses.

       *  Multiple options must be separated by commas.

       *  The options can extend over several lines, although the entry
          itself must start on a new line.

       For example, the following entry assigns several connection
       characteristics to ports 224..249 and then enables those ports:

          224..249 => (Logoff_On_Disconnect,
                       Disconnect_On_Logoff,
                       Enable)

       You can organize recurrent sets of options and improve
       readability in the Terminal_Configuration file by defining an
       abbreviation for each set of options and then assigning each
       abbreviation to a port or range of ports:

       *  Abbreviation entries are of the general form Abbreviation =
          Options. Note that the equals sign (=) is used to define
          abbreviations; the => symbol is used for port assignment.

       *  Existing abbreviations can be nested in the definition of new
          abbreviations.

       For example, the following entries create the abbreviations
       User_Ports and Telnet_Ports, assigning the Telnet_Ports
       abbreviation to ports 224..249:

          -- Port settings for user login ports
          User_Ports   = (Logoff_On_Disconnect, Disconnect_On_Logoff)

          -- Port settings for Telnet ports
          Telnet_Ports = (Terminal_Type => Xrterm, User_Ports)

          224..249     => (Telnet_Ports, Enable)

       When adding entries to a Terminal_Configuration file, bear in
       mind that:

       *  Nondefault communication characteristics for RS232 ports must
          be set each time an R1000 boots. Consequently, if a port is to
          have nondefault values for any of the options listed in Table
          4, you must include these options in the entry for that port.
          Omitting an option causes its default value to be set.

       *  Connection and terminal-type characteristics persist across
          boots, retaining the last values that were set for them. Thus,
          in principle, the options listed in Tables 2 and 3 need to be
          set only once and then can be omitted from the
          Terminal_Configuration file. However, you may choose to
          include values for these options in the file to ensure that
          booting the system resets them to the proper values in case
          they had been changed.

       *  The options for each port are set in the order in which they
          are assigned in the Terminal_Configuration file. Similarly,
          the options in an abbreviation are set in the order in which
          they are declared. If a single port number is included in the
          ranges of more than one entry, that port takes the options of
          the last entry in which it appears.


       1.4.3.  A Sample Terminal_Configuration File

       The following sample file shows how a system manager can use
       abbreviations to organize port information meaningfully. Note
       that a number of connection options have been explicitly set to
       ensure that booting the system sets them to a known value. Note
       also that specifying the Disable option for the printer ports is
       not absolutely necessary; however, specifying this option ensures
       that no previous entry in the file had inadvertently enabled
       these ports.

          -- Operator line 16 settings
          Operator_Port = (~Logoff_On_Disconnect,
                           ~Disconnect_On_Logoff,
                           ~Login_Disabled)

          -- User login port settings
          User_Ports = (Logoff_On_Disconnect, Disconnect_On_Logoff,
                        ~Login_Disabled, ~Log_Failed_Logins,
                        ~Disconnect_On_Failed_Login,
                        ~Disconnect_On_Disconnect)

          -- Dial-in port connection settings
          Dialin_Ports = (Terminal_Type => VT100,
                          Input_Rate => Baud_2400, Output_Rate => Baud_2400,
                          Parity => None, Bits_Per_Char => Char_8,
                          Stop_Bits => 1, User_Ports)

          -- Telnet port settings
          Telnet_Ports = (Terminal_Type => Xrterm, User_Ports)

          -- Printer port settings
          Printer_Ports = (Login_Disabled)

          -- Ports not in use
          Unused = (Login_Disabled)


          16 => (Operator_Port, Enable)
          17..31 => (Dialin_Ports, Enable)
          224..249 => (Telnet_Ports, Enable)
          250..251 => (Disable, Printer_Ports)
          252..255 => (Disable, Unused)


       1.4.4.  Terminal-Configuration Options

       Tables 2, 3, and 4 summarize the connection, terminal type, and
       RS232 communication options you can specify in the
       Terminal_Configuration file. These options invoke corresponding
       procedures in package Terminal.

           Table 2   Boolean Options for Connection Characteristics
        ------------------------------------------------------------ 
       |                      |                                     |
       |        Option        |             Description             |
        ------------------------------------------------------------ 
       |                      |                                     |
       |Disconnect_On_        |When specified for a given port,     |
       |Disconnect            |causes the Environment to respond to |
       |                      |an incoming disconnect signal        |
       |                      |received on that port by initiating  |
       |                      |an outgoing disconnect signal on that|
       |                      |port.                                |
        ------------------------------------------------------------ 
       |                      |                                     |
       |Disconnect_On_Failed_ |When specified for a given port,     |
       |Login                 |causes the Environment to initiate an|
       |                      |outgoing disconnect signal on that   |
       |                      |port when a user repeatedly fails to |
       |                      |log in on that port (for example, by |
       |                      |repeatedly entering an incorrect     |
       |                      |password or unrecognized username).  |
        ------------------------------------------------------------ 
       |                      |                                     |
       |Disconnect_On_Logoff  |When specified for a given port,     |
       |                      |causes the Environment to initiate an|
       |                      |outgoing disconnect signal on that   |
       |                      |port when a user logs off a session  |
       |                      |running on that port.                |
        ------------------------------------------------------------ 
       |                      |                                     |
       |Log_Failed_Logins     |When specified for a given port,     |
       |                      |causes the Environment to write an   |
       |                      |entry to the system error log when a |
       |                      |user fails repeatedly to log in on   |
       |                      |that port (for example, by repeatedly|
       |                      |entering an incorrect password or    |
       |                      |unrecognized username).              |
        ------------------------------------------------------------ 
       |                      |                                     |
       |Logoff_On_Disconnect  |When specified for a given port,     |
       |                      |causes the Environment to respond to |
       |                      |a disconnect received on that port by|
       |                      |logging off that port's session.     |
        ------------------------------------------------------------ 



           Table 3   Enumeration Option for Specifying Terminal Type
        ------------------------------------------------------------ 
       |          |                                                 |
       |Option => |                   Description                   |
       |  Value   |                                                 |
        ------------------------------------------------------------ 
       |          |                                                 |
       |Terminal_ |Specifies the output driver type for a given     |
       |Type      |port. Value can be any valid terminal type name, |
       |          |including (but not limited to):                  |
       |          |Cit500r  Facit  Rational  Vt100  Xrterm          |
        ------------------------------------------------------------ 



             Table 4   Enumeration Options for RS232 Communication
                                Characteristics
        ------------------------------------------------------------- 
       |                    |       |                                |
       |                    |Default|                                |
       |  Option => Value   | Value |          Description           |
        ------------------------------------------------------------- 
       |                    |       |                                |
       |Bits_Per_Char       |Char_8 |Specifies the number of data    |
       |                    |       |bits per character. Value can   |
       |                    |       |be:  Char_5  Char_6  Char_7     |
       |                    |       |Char_8                          |
        ------------------------------------------------------------- 
       |                    |       |                                |
       |Flow_Control        | None  |Specifies software flow control |
       |                    |       |for data transmitted by the     |
       |                    |       |R1000 on the specified port.    |
       |                    |       |Value can be:                   |
       |                    |       |None  Xon_Xoff  Dtr  Rts        |
        ------------------------------------------------------------- 
       |                    |       |                                |
       |Input_Rate          | Baud_ |Sets the incoming data rate for |
       |                    | 9600  |a given port. Value can be:     |
       |                    |       |Baud_50     Baud_75     Baud_110|
       |                    |       |Baud_134_5  Baud_150    Baud_200|
       |                    |       |Baud_300    Baud_600            |
       |                    |       |Baud_1200   Baud 1800           |
       |                    |       |Baud_2400   Baud 9600           |
       |                    |       |Baud_19200  Disabled            |
       |                    |       |Ext_Rec_Clk                     |
        ------------------------------------------------------------- 
       |                    |       |                                |
       |Output_Rate         | Baud_ |Sets the outgoing data rate for |
       |                    | 9600  |a given port. Values are the    |
       |                    |       |same as for Input_Rate.         |
        ------------------------------------------------------------- 
       |                    |       |                                |
       |Parity              | None  |Sets the parity for transmitted |
       |                    |       |and received data on a given    |
       |                    |       |port. Value can be:  None  Odd  |
       |                    |       |Even                            |
        ------------------------------------------------------------- 
       |                    |       |                                |
       |Stop_Bits           |   2   |Sets the number of stop bits for|
       |                    |       |a given port. Value is a natural|
       |                    |       |number in the range 1..2.       |
        ------------------------------------------------------------- 
       |                    |       |                                |
       |Receive_Flow_Control| None  |Specifies flow control of data  |
       |                    |       |received by the R1000 on the    |
       |                    |       |specified port. Value can be:   |
       |                    |       |None  Xon_Xoff  Dtr  Rts        |
        ------------------------------------------------------------- 
       |                    |       |                                |
       |Receive_Xon_Xoff_   |(17,19)|Specifies flow-control bytes so |
       |Bytes               |       |that the R1000 can regulate the |
       |                    |       |data it receives on the         |
       |                    |       |specified port. Value is (n,m), |
       |                    |       |where n and m are natural       |
       |                    |       |numbers in the range 0..255.    |
        ------------------------------------------------------------- 
       |                    |       |                                |
       |Xon_Xoff_Bytes      |(17,19)|Specifies the flow-control bytes|
       |                    |       |that the R1000 recognizes for   |
       |                    |       |the specified port. Value is:   |
       |                    |       |(n,m), where n and m are natural|
       |                    |       |numbers in the range 0..255.    |
        ------------------------------------------------------------- 




       1.5.  Configuring Printers

       D_12_5_0 and subsequent releases provide a file-driven mechanism
       in !Machine.Initialization for configuring a group of networked
       and/or local printers. This mechanism allows you to define a
       printer name for each printer on the network and to specify how
       each printer is to be accessed. Furthermore, you can also
       associate a printer name with each user, so that when a given
       user enters the Print command (that is,
       !Commands.Abbreviations.Print), the print job will be sent by
       default to the device that is defined by the associated printer
       name.

       This file-driven mechanism automatically adds the specified
       devices to the appropriate R1000s, creates the necessary print
       classes on the appropriate R1000s, and associates each class with
       the specified device, thereby creating print queues. Thus, when
       you use the file-driven mechanism, you do not need to use
       procedures from package Queue (such as Add, Create, Enable, and
       Register) to do these things.

       Existing sites can choose whether to use this file-driven
       mechanism or to continue using procedures from package Queue to
       configure printers. However, because the file-driven mechanism
       combines class and machine information, it is recommended that
       large sites with multiple networked printers use the file-driven
       !Machine.Initialization mechanism. Small sites with few printers
       connected directly to R1000s may want to continue using package
       Queue. Sites that want to create a single class with multiple
       devices should also use package Queue.

       Note that the printer configuration (set either through commands
       in package Queue or through the file-driven mechanism) applies to
       both the Queue.Print and Abbreviations.Print commands. The
       ability to associate printer names with usernames is specific to
       the Abbreviations.Print command.


       1.5.1.  Where to Specify Printer Information

       Each time an R1000 boots, the !Machine.Initialization.Start
       procedure calls a procedure called Printers in the Rational
       world. This procedure initializes the print spooler on that R1000
       based on the information in the following user-created files:

       *  !Machine.Initialization.Site.Printer_Configuration, which
          defines a printer name for each of the devices available on
          the network and specifies how each device is to be accessed. A
          copy of this file must exist on all R1000s from which users
          will enter the Print command and on all R1000s that will
          handle print requests for the specified devices.

       *  !Machine.Initialization.Local.Printer_Configuration, which
          defines additional printer names for additional devices
          intended only for users of the current R1000.

       *  !Machine.Initialization.Local.User_Printer_Map, which
          associates a default printer name with individual users on the
          current R1000. When a user executes the Print command with the
          default Printer parameter, the command looks up the user's
          name and sends the print request to the corresponding printer.

       At a minimum, the Print command requires that one
       Printer_Configuration file exist in either the Site or Local
       world. If no User_Printer_Map file exists (or if the file exists
       but contains no entry for a particular user), the Print command
       uses the first printer name defined in the
       Site.Printer_Configuration file. If this file doesn't exist, the
       first printer name defined in the Local.Printer_Configuration
       file is used.

       The classes and devices specified in the Printer_Configuration
       files are created when the Printers procedure (that is,
       !Machine.Initialization.Rational.Printers) is executed (normally,
       during machine initialization). The Printers procedure also
       associates usernames with the appropriate printer information. Be
       aware that whenever information is changed in any of the files
       listed above, the Printers procedure must be run in order to
       update the information.

       If you choose not to create any of these files, you will have to:

       *  Create an initialization procedure (in either the Site or
          Local world) that uses package Queue to create print queues
          each time the system boots.

       *  Either:

          -  Use the Queue.Print command instead of the
             !Commands.Abbreviations.Print command.

          -  Use the !Commands.Abbreviations.Print command, but
             explicitly specify the class name for the Printer
             parameter.


       1.5.2.  Adding Entries to a Printer_Configuration File

       During installation, an empty Printer_Configuration file is
       created in the Local world. After installation, you can:

       *  Add entries to this file to enable the use of the Print
          command.

       *  Move this file (or create an additional file called
          Printer_Configuration) in the Site world, if you need to
          define sitewide printer information.

       Each entry in a Printer_Configuration file defines a printer name
       and specifies the characteristics of the device it represents.

       Each entry must start on a new line, but the information can
       extend over several lines and can include single and in-line
       comments. For readability, the entries are often formatted like
       command parameters.

       Each entry has the general form:

          Printer_Name => (Device_Type  => Device_Info,
          Other_Device_Characteristics,
                           Laser_Comm           => Boolean,
                           Reverse_Output_Pages => Boolean,
                           On_Node              => R1000_Name)

       where:

       *  Printer_Name is the name by which you want to refer to a given
          device in a Print command. Printer_Name must be a legal Ada
          simple name.

       *  Device_Type is one of the following four kinds of printer
          devices:

          -  Direct, which specifies a printer connected to an R1000 via
             direct line.

          -  Telnet, which specifies a printer connected to an R1000 via
             Telnet.

          -  File, which specifies a file on an R1000 in which
             print-spooler output is collected. Subsequent processing is
             required to get this output printed.

          -  Workstation, which specifies a directory on a remote
             workstation to which print requests are sent. Such requests
             are sent via FTP as individual files; from the remote
             directory, they can be printed using the workstation's
             print tools.

       *  Device_Info is further information about the device you
          specified. The information depends on the type of device
          specified (see the paragraphs below).

       *  Other_Device_Characteristics are additional entry elements,
          separated by commas, that give further information about the
          chosen device (see the paragraphs below).

       *  The Laser_Comm option, when True, specifies that printing will
          be done on a laser printer. Omitting this option implies that
          printing will be done on a line printer.

          For Direct and Telnet devices, setting Laser_Comm to True
          specifies that a laser printer is connected; for File and
          Workstation devices, setting Laser_Comm to True specifies that
          the collected print requests will eventually be printed on a
          laser printer.

       *  The Reverse_Output_Pages option allows you to adjust the order
          in which pages are spooled to accommodate the way your printer
          stacks pages in its output tray. This option applies only if
          the Laser_Comm option is set to True.

          -  Setting Reverse_Output_Pages to True causes the print
             spooler to reverse the order of output pages, so that the
             last logical page is printed first. Omitting this option is
             equivalent to specifying True.

          -  Setting Reverse_Output_Pages to False causes the print
             spooler to keep the pages of output in the order in which
             they appear in the source file.

       *  The On_Node option specifies the network name of the R1000
          that contains the print spooler for the device. Omitting this
          option is equivalent to specifying the name of the current
          R1000.

       The following paragraphs describe printer-configuration file
       entries for each of the four kinds of devices. (See also the
       comments in the specification of
       !Machine.Initialization.Rational.Printers.)


       1.5.3.  Specifying a Directly Connected Printer

       To specify a printer connected to an R1000 via direct line, you
       specify an entry of the following general form:

          Printer_Name => (Direct      => Protocol,
                           Device               => Terminal_N,
                           Laser_Comm           => Boolean,
                           Reverse_Output_Pages => Boolean,
                           On_Node              => R1000_Name)

       where:

       *  Protocol specifies the printer flow control and can be either
          Xon_Xoff or Dtr. See the printer manual for details.

       *  Terminal_N represents the RS232C port to which the printer is
          connected (N is the port number). The specified port must not
          be enabled for login in the Local.Terminal_Configuration file.

       *  The Laser_Comm option, when True, specifies that a laser
          printer is connected and enables a two-way
          printer-communication protocol. Omitting the option is
          equivalent to specifying False, which means that a line
          printer is connected.

       *  The Reverse_Output_Pages option allows you to adjust the order
          in which pages are spooled to accommodate the way your printer
          stacks pages in its output tray, as described in section
          1.5.2. This option applies only if Laser_Comm is set to True.

       *  The On_Node option specifies the network name of the R1000 to
          which the printer is directly connected. Omitting this option
          is equivalent to specifying the name of the current R1000.

       The following entry creates a printer name called Lp, which
       represents a line printer that is directly connected to port 30
       of an R1000 called Jazmo:

          -- Line printer connected to Jazmo
          Lp => (Direct  => Xon_Xoff,
                 Device  => Terminal_30,
                 On_Node => Jazmo)


       1.5.4.  Specifying a Networked Printer

       To specify a printer connected to an R1000 via Telnet, you
       specify an entry of the following general form:

          Printer_Name => (Telnet      => Host_Name,
                           Device               => Terminal_N,
                           Laser_Comm           => Boolean,
                           Reverse_Output_Pages => Boolean,
                           On_Node              => R1000_Name)

       where:

       *  Host_Name is the network name of the printer.

       *  Terminal_N represents the Telnet port to which the printer is
          connected (N is the port number). The specified port must not
          be enabled for login in the Local.Terminal_Configuration file.

       *  The Laser_Comm option, when True, specifies that a laser
          printer is connected and enables a two-way
          printer-communication protocol. Omitting the option is
          equivalent to specifying False, which means that a line
          printer is connected.

       *  The Reverse_Output_Pages option allows you to adjust the order
          in which pages are spooled to accommodate the way your printer
          stacks pages in its output tray, as described in section
          1.5.2. This option applies only if Laser_Comm is set to True.

       *  The On_Node option specifies the network name of the R1000 to
          which the printer is connected via Telnet. Omitting this
          option is equivalent to specifying the name of the current
          R1000.

       The following entry creates the printer name Dlaser, which
       represents a laser printer that is connected via Telnet to port
       226 of an R1000 called Roget. Because of the way this printer
       stacks its output, print requests are spooled to this device with
       their pages in ascending (rather than reversed) order:

          -- Documentation's laser printer
          Dlaser => (Telnet               => Doc_Laser,
                     Device               => Terminal_226,
                     Laser_Comm,
                     Reverse_Output_Pages => False,
                     On_Node              => Roget)


       1.5.5.  Specifying an Environment File

       To specify a file in which to collect print-spooler output, you
       specify an entry of the following general form:

          Printer_Name => (File        => Environment_Pathname,
                           Laser_Comm           => Boolean,
                           Reverse_Output_Pages => Boolean,
                           On_Node              => R1000_Name)

       where:

       *  Environment_Pathname specifies the file to which output is
          written. The pathname must name a file that exists on the
          R1000 named by On_Node. Note that the group Spooler must have
          access to the specified file.

       *  The Laser_Comm option, when True, specifies that the collected
          print requests will eventually be printed on a laser printer.
          Omitting the option is equivalent to specifying False, which
          means that a line printer will be used.

       *  The Reverse_Output_Pages option allows you to adjust the order
          in which pages are spooled to accommodate the way your printer
          stacks pages in its output tray, as described in section
          1.5.2. This option applies only if Laser_Comm is set to True.

       *  The On_Node option specifies the network name of the R1000 on
          which the file is located. Omitting this option is equivalent
          to specifying the name of the current R1000.

       The following entry creates the printer name Hold, which
       represents a file on an R1000 called Logo. Low-priority print
       requests are sent to this file, where they are held until someone
       prints the file using the Print command (specifying a printer
       name that represents a connected printer):

          -- Place to hold large requests until printers are free in the
          evening
          Hold => (File    => !Machine.Queues.Local.Held_Print_Requests,
                   On_Node => Logo)


       1.5.6.  Specifying a Workstation Directory

       To specify a directory on a workstation to which print requests
       are sent, you specify an entry of the following general form:

          Printer_Name => (Workstation => Host_Name,
                           Path                 => Directory_Name,
                           Laser_Comm           => Boolean,
                           Suffix               => String,
                           Reverse_Output_Pages => Boolean,
                           On_Node              => R1000_Name)

       where:

       *  Host_Name is the network name of the workstation to which the
          files will be transferred.

       *  Directory_Name is the pathname of the workstation directory
          into which the files will be transferred. The directory
          pathname must have syntax appropriate to the workstation and
          must have trailing punctuation that permits the name of the
          transferred print-request file to be appended.

       *  The Laser_Comm option, when True, specifies that the collected
          print requests will eventually be printed on a laser printer.
          Omitting the option is equivalent to specifying False, which
          means that a line printer will be used.

       *  The Suffix option allows you to specify a string to be
          appended to the filenames that are created on the workstation.
          Omitting this option causes no suffix to be appended to the
          filenames. The specified suffix can be used by print tools as
          a way of identifying which files to print. This is useful when
          several printer names send files to the same directory.

       *  The Reverse_Output_Pages option allows you to adjust the order
          in which pages are spooled to accommodate the way your printer
          stacks pages in its output tray, as described in section
          1.5.2. This option applies only if Laser_Comm is set to True.

       *  The On_Node option specifies the network name of the R1000
          whose print spooler handles the print requests. Omitting this
          option is equivalent to specifying the name of the current
          R1000.

       In addition to creating an entry for each workstation in the
       Printer_Configuration files, you must also create a
       remote-passwords file, containing the username and password to be
       used for accessing each workstation. This remote-passwords file
       must be named Remote_Access and exist in the library
       !Machine.Queues.Ftp. (For information about remote-passwords
       files, see package Remote_Passwords in the Session and Job
       Management book of the Rational Environment Reference Manual.)

       When print requests are sent as files to a workstation, any FTP
       messages are directed to a log file that is created in
       !Machine.Queues.Ftp. This log file is automatically cleared after
       each 100 print requests. Messages pertaining to creating print
       classes and enabling devices are directed to the system error
       log.

       The following two entries create printer names Dc_Laser and
       Dc_Lineprinter, both of which direct print requests to a
       directory on a UNIX workstation called Enterprise. These print
       requests, which are routed through the print spooler on an R1000
       called Capitol, are sent as files with different suffixes,
       depending on the printer name (_Lsr and _Lpt, respectively):

          -- Laser printer attached to workstation in 
          -- Washington, D.C., office;
          -- spooled on R1000 called Capitol.
          Dc_Laser => (Workstation => Enterprise,
                       Path        => /usr/spool/ratqueue/,
                       Laser_Comm,
                       Suffix      => _Lsr,
                       On_Node     => Capitol)

          -- Line printer attached to workstation in 
          -- Washington, D.C., office;
          -- spooled on R1000 called Capitol.
          Dc_Lineprinter => (Workstation => Enterprise,
                             Path        => /usr/spool/ratqueue/,
                             Suffix      => _Lpt,
                             On_Node     => Capitol)

       Print tools on the workstation, such as the following sample, are
       required to actually print the requests:

          # This program spools print requests placed in
          # /usr/spool/ratqueue to the appropriate printer based on 
          # the suffix of the spooled file.
          # It checks the spool directory at 5-minute intervals to see
          # if any new files need printing. This runs as a C-shell script. 
          # To execute, type csh and the name of this file.

          :
          set xFTPxDIRx=/usr/spool/ratqueue             #spool directory
          #
          set xFTPxSUFFIXxLSRx=_Lsr      # Laser printer suffix
          set xFTPxSUFFIXxLPTx=_Lpt      # Line printer suffix
          #
          set xPRINTxLISTxLSRx=/tmp/rat_print_lsr.$$    
          # Laser printer list file
          set xPRINTxLISTxLPTx=/tmp/rat_print_lpt.$$    
          # Line printer list file
          #
          set xPRINTxCOMMANDx=/tmp/rat_command.$$       
          # temporary print command file
          #
          set xPRINTxDELAYx=120          
          # interval to wait before printing
          set xRECHECKxTIMEx=180         
          # interval for checking print requests
          #
          cd $xFTPxDIRx
          while (1 == 1)
          #
          # Creates a list of files to print for each printer.
          #
              ls $xFTPxDIRx | grep $xFTPxSUFFIXxLSRx > $xPRINTxLISTxLSRx
              ls $xFTPxDIRx | grep $xFTPxSUFFIXxLPTx > $xPRINTxLISTxLPTx
          #
          # Adds the laser- and line-printer files to the 
          # print-command file (the device name of each type of printer 
          # should be provided after the -P).
          #
              cat $xPRINTxLISTxLSRx | sed -e 's^.^lpr -r -Plaser &^' > $xPRINTxCOMMANDx
              cat $xPRINTxLISTxLPTx | sed -e 's^.^lpr -r -Pline &^' >> $xPRINTxCOMMANDx
          #
          # Waits the specified amount of time before printing the requests.
          # (This delay allows time for the FTP operation to complete
          # and should be adjusted based on the average length of files 
          # being printed.)
          #
              sleep $xPRINTxDELAYx
          #
          # Prints the files if there are any to print.
          #
              set LCNT=`cat $xPRINTxCOMMANDx | wc -l `
              if ( $LCNT != 0 ) then
                  chmod +x $xPRINTxCOMMANDx
                  $xPRINTxCOMMANDx
              endif
          #
          # Waits the specified amount of time.
          #
              sleep $xRECHECKxTIMEx
          #
          # Removes the old temporary files.
          #
              rm $xPRINTxLISTxLSRx
              rm $xPRINTxLISTxLPTx
              rm $xPRINTxCOMMANDx
          #
          end


       1.5.7.  Associating Default Printers with Individual Users

       To associate a default printer with each user, you must create a
       file called User_Printer_Map in the Local world and add entries
       of the following form:

          Username  Printer_Name

       where:

       *  Username is either:

          -  The username for an R1000 user

          -  The string Others, which represents all users not
             explicitly listed by name.

       *  Printer_Name is defined in a Printer_Configuration file.

       Following is a sample User_Printer_Map file:

          phil dc_laser
          sue dlaser
          others lp

       See also the comments in the specification of
       !Machine.Initialization.Rational.Printers.