From: root@[127.0.0.1]
Sent: Friday, February 04, 2000 9:19 AM
To: Info-VAX@Mvb.Saic.Com
Subject: PQMGR.COM - RE: Any LP-Plus (Unix) type VMS printer queue
utilities available ?

cmorrell@unfi.com (Charlie Morrell) wrote in
<01BF6E49.CC5C9230.cmorrell@unfi.com>: 

>We are really looking for something that is very simplistic for all
>users, such as the LP-Plus product is for all of our Unix users.
>Thanks.
>
I don't know LP-plus but you might as well try some stuff I wrote a few
years back. Nothing fancy, but useful at the time.

Ricket

------------------------Snip and save in file named PQMGR.COM-------------
$ ! PQMGR.COM
$ !
$ ! Written by Eric Defferard, February 1994
$ ! Copyright ?, anything you want but sell it. 
$ ! 
$ ! Notes:
$ !
$ ! Features limited to what was available in VMS 6.
$ !
$ ! Simple terminal based print queue manager.
$ ! Implements all queue operations except retention, which had a couple of
$ ! problems at that time. Didn't have the opportunity to check out
$ ! new VMS features since then.
$ !
$ ! Implementation is simple, straightforward DCL.
$ !
$ ! User of this program needs appropriate printer operator privileges or
$ ! ownership of queue(s) to manage. See the VMS doc for your version.
$ !
$ ! This program is meant to be executed only interactively.
$ !
$ ! Limitations:
$ ! - Number of queues and forms which can be managed alltogether depends on
$ ! the max size of a DCL symbol. (255 chars ?). This was a simple
$ ! implementation (see "Global symbols used" below) decision because I didn't
$ ! have more than 20 or so queues to manage from one same printer operator
$ ! console.
$ ! In any case, if you have to view more queues than this version supports,
$ ! it shouldn't be quite hard to setup the list using logical names or files.
$ ! 
$ ! - Does not support QUEUE CHARACTERISTICS. Again, I sticked to my main goal,
$ ! managing a farm of heavy duty line printers, spread out in several
$ ! locations, and operated by non-techies. Also, I didn't use PATHWORKS.
$ ! So for those needing to switch between chars, again, you don't need to be
$ ! a wizard to implement it.
$ !
$ ! - Timeouts were figured by trial and error, depends on your printers,
$ !  printer connection, etc...
$ ! 
$ ! Parameters:
$ ! P1 = comma separated list of queues to manage
$ ! P2 = comma separated list of forms to manage
$ ! 
$ ! Global symbols used:
$ ! pqmgr_queue_list, not required, but if defined, used like P1
$ ! pqmgr_form_list, not required, but if defined, used like P2
$ !
$ ! Logical names used :
$ ! W_PRT:  directory where form test files are located
$ !         the form test files are expected to be named 'formname'.TST
$ !
$ ! Required files: form test files for alignment purposes. See VMS doc.
$ !
$ !
$start:
$ ON CONTROL_Y THEN GOTO ctrl_y
$ !
$ ! Environment variables
$ q_list_refresh_timeout         = 16
$ job_list_refresh_timeout       = 16
$ choice_timeout                 = 20
$ change_paper_timeout           = 180
$ q_unstable_status_timeout      = 8
$ q_aligning_wait_timeout        = "00:00:04"
$ q_pausing_wait_timeout         = "00:00:08"
$ q_stopping_wait_timeout        = "00:00:04"
$ q_function_unavailable_timeout = "00:00:02"
$ q_error_message_timeout        = "00:00:03"
$ func_menu_prompt               = "Command: "
$ last_requeue 			 = ""
$ form_test_dir                  = "W_PRT:"
$ !
$ !
$ ! Misc constants
$ wo := WRITE SYS$OUTPUT
$ !
$ clear_home := TYPE/PAGE NL:
$ !
$ ! Get queue list
$ IF (f$type(pqmgr_queue_list) .EQS. "") .OR. (p1 .EQS. "ALL") THEN -
                                                 GOSUB get_all_queue_list 
$ q_list = "''pqmgr_queue_list'"
$ !
$ ! Get form list
$ IF (f$type(pqmgr_form_list) .EQS. "") .OR. (p1 .EQS. "ALL") THEN -
                                                 GOSUB get_all_form_list
$ form_list = "''pqmgr_form_list'"
$ !
$ ! Bit values for queue and job status detection
$ QUEUE_ALIGNING_VAL         =     1
$ QUEUE_IDLE_VAL             =     2
$ QUEUE_LOWERCASE_VAL        =     4
$ QUEUE_OPERATOR_REQUEST_VAL =     8
$ QUEUE_PAUSED_VAL           =    16
$ QUEUE_PAUSING_VAL          =    32
$ QUEUE_REMOTE_VAL           =    64
$ QUEUE_RESETTING_VAL        =   128
$ QUEUE_RESUMING_VAL         =   256
$ QUEUE_SERVER_VAL           =   512
$ QUEUE_STALLED_VAL          =  1024
$ QUEUE_STARTING_VAL         =  2048
$ QUEUE_STOPPED_VAL          =  4096
$ QUEUE_STOPPING_VAL         =  8192
$ QUEUE_UNAVAILABLE_VAL      = 16384
$ QUEUE_CLOSED_VAL           = 32768
$ !
$ JOB_ABORTING_VAL      =    1
$ JOB_EXECUTING_VAL     =    2
$ JOB_HOLDING_VAL       =    4
$ JOB_INACCESSIBLE_VAL  =    8
$ JOB_REFUSED_VAL       =   16
$ JOB_REQUEUE_VAL       =   32
$ JOB_RESTARTING_VAL    =   64
$ JOB_RETAINED_VAL      =  128
$ JOB_STARTING_VAL      =  256
$ JOB_TIMED_RELEASE_VAL =  512
$ JOB_SUSPENDED_VAL     = 1024
$ JOB_PENDING_VAL       = 2048
$ JOB_STALLED_VAL       = 8192
$ !
$ pend_check_exec_queues  =   0
$ pend_char_mismatch      =   1
$ pend_job_size_max       =   2
$ pend_job_size_min       =   4
$ pend_lowercase_mismatch =   8
$ pend_no_access          =  16
$ pend_queue_busy         =  32
$ pend_queue_state        =  64
$ pend_stock_mismatch     = 128
$ !
$ ! Don't want to squash the recall buffer
$ OPEN keyboard SYS$COMMAND
$ !
$ GOSUB ck_params
$ screen_object = "QUEUE"
$ context_switch = 1
$ current_q_name = ""
$ !
$main_loop:
$ IF screen_object .EQS. "QUEUE" THEN GOSUB q_scr
$ IF screen_object .EQS. "JOB" THEN GOSUB job_scr
$ IF screen_object .EQS. "EXIT" THEN GOTO simple_exit
$ GOTO main_loop
$ !	End of main
$ !
$ !	Parameter verification sub
$ !
$get_all_queue_list:
$ pqmgr_queue_list == "*.*"
$queue_loop:
$ queue_name = f$getqui("display_queue","queue_name","*","symbiont")
$ if queue_name .eqs. "" then goto end_queue_loop
$ if pqmgr_queue_list .nes. ""
$ then
$   pqmgr_queue_list == pqmgr_queue_list + "," + queue_name
$ else
$   pqmgr_queue_list == queue_name
$ endif
$ goto queue_loop
$end_queue_loop:
$ RETURN
$ !
$get_all_form_list:
$ pqmgr_form_list == ""
$form_loop:
$ form_name = f$getqui("display_form","form_name","*","symbiont")
$ if form_name .eqs. "" then goto end_form_loop
$ if pqmgr_form_list .nes. ""
$ then
$   pqmgr_form_list == pqmgr_form_list + "," + form_name
$ else
$   pqmgr_form_list == form_name
$ endif
$ goto form_loop
$end_form_loop:
$ RETURN
$ !
$ck_params:
$ ! Check the params passed to this proc
$ck_q_list:
$ ! Check the queue name list.
$ ! Extract each queue from the list and check if it exists.
$ ! If a queue exists, create a table variable with it's name
$ ! q_name_(i).
$ !
$ n_q = 0	! number of existing queues
$ i_q = 0	! queue extraction counter
$ !
$extr_q_from_list:
$ q_name := 'F$ELEMENT(i_q,",",q_list)'
$ i_q = i_q + 1
$ IF q_name .EQS. "," THEN GOTO end_extr_q_from_list
$ q_exists = "''F$GETQUI("DISPLAY_QUEUE","QUEUE_NAME",q_name)'" .NES. ""
$ IF q_exists THEN GOTO q_does_exist
$ !
$q_does_not_exist:
$ wo ""
$ wo "WARNING: the print queue ''q_name' does not exist."
$ wo "Please contact your system manager."
$ wo ""
$ GOTO extr_q_from_list
$ !
$q_does_exist:
$ n_q = n_q + 1
$ q_name_'n_q' := 'q_name'
$ GOTO extr_q_from_list
$ !
$end_extr_q_from_list:
$ IF n_q .NE. 0 THEN GOTO end_ck_q_list
$ wo ""
$ wo "WARNING: no print queues defined."
$ wo "Please contact your system manager."
$ wo ""
$ GOTO simple_exit
$end_ck_q_list:
$ !
$ck_form_list:
$ ! Check the form name list.
$ ! Extract each form from the list and check if it exists.
$ ! If a form exists, create a table variable with it's name
$ ! form_name_(i).
$ !
$ n_form = 0	! number of existing forms
$ i_form = 0	! form extraction counter
$ !
$extr_form_from_list:
$ form_name := 'F$ELEMENT(i_form,",",form_list)'
$ i_form = i_form + 1
$ IF form_name .EQS. "," THEN GOTO end_extr_form_from_list
$ form_exists = "''F$GETQUI("DISPLAY_FORM","FORM_NAME",form_name)'" .NES. ""
$ IF form_exists THEN GOTO form_does_exist
$ !
$form_does_not_exist:
$ wo ""
$ wo "WARNING: the form ''form_name' does not exists."
$ wo "Please contact your system manager."
$ wo ""
$ GOTO extr_form_from_list
$ !
$form_does_exist:
$ n_form = n_form + 1
$ form_name_'n_form' := 'form_name'
$ GOTO extr_form_from_list
$ !
$end_extr_form_from_list:
$ IF n_form .NE. 0 THEN GOTO end_ck_form_list
$ wo ""
$ wo "WARNING: no forms defined"
$ wo "Please contact your system manager."
$ wo ""
$ GOTO simple_exit
$end_ck_form_list:
$ !
$end_ck_params:
$ RETURN
$ !
$ !	Main screens
$ !
$q_scr:
$ ! Display a list of the queues, updating continually their status.
$ ! Ask for the number of the queue to manage.
$ !
$ ! When a queue number is specified, branch to the menu matching the
$ ! queue's status.
$ !
$ !
$ IF .NOT. context_switch THEN GOTO q_scr_use_current
$ context_switch = 0
$ clear_home
$ GOSUB display_q_list
$ wo "    J      List of all jobs"
$ wo "    Q      Quit"
$ prompt_str = "           ID number of printer to manage ? "
$ IF current_q_name .NES. ""
$   THEN
$   prompt_str = "''prompt_str'" + "(<CR> = ''current_q_name') "
$   ENDIF
$ READ keyboard choice -
    /TIME_OUT='q_list_refresh_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=q_scr_refresh_list -
    /END=q_scr_exit_pgm
$ !
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. "J" THEN GOTO q_scr_job_list
$ IF choice .EQS. "Q" THEN GOTO q_scr_exit_pgm
$ IF choice .EQS. "" THEN GOTO q_scr_use_current
$ !
$ ! Not a keyword, check out queue number
$ i_q = 'F$INTEGER(choice)'
$ IF (i_q .LE. 0) .OR. (i_q .GT. n_q) THEN GOTO q_scr_refresh_list
$ current_q_name = q_name_'i_q'
$ !
$q_scr_use_current:
$ ! If no current queue has been chosen yet, redisplay the list of all queues
$ IF current_q_name .EQS. "" THEN GOTO q_scr_refresh_list
$ !
$ ! Update and test the status of current queue chosen.
$ ! Display the appropriate menu depending on status of queue.
$ !
$q_scr_q_menu_loop:
$ q_name = current_q_name
$ GOSUB get_q_chars
$ !
$ IF (q_status_stalled) THEN GOTO q_scr_q_stalled
$ !
$ IF (q_status_aligning) THEN GOTO q_scr_q_aligning
$ !
$ IF ((q_status_resetting) .OR. -
      (q_status_resuming) .OR. -
      (q_status_starting) .OR. -
      (q_status_stopping)) THEN GOTO q_scr_status_unstable
$ !
$ IF (q_status_pausing) THEN GOTO q_scr_ck_pausing_stalled
$ !
$ ! Careful, gotta branch to paused_menu before stopped_menu.
$ ! Reason is:
$ !   a queue may be Paused and Stop pending meaning a job is executing;
$ !   if Paused and Stopped, but idle, just switch the stopped status.
$ IF ((q_status_paused) .AND. (q_status_stopped) .AND. (q_status_idle)) THEN -
    START /QUEUE 'current_q_name'
$ IF ((q_status_paused) .AND. (.NOT. q_status_idle)) THEN -
    GOTO q_scr_call_paused_busy_menu
$ IF ((q_status_paused) .AND. (q_status_idle)) THEN -
    GOTO q_scr_call_stopped_menu
$ IF ((q_status_stopped) .AND. (.NOT. q_status_idle)) THEN -
     GOTO q_scr_call_stopped_menu ! GOTO q_scr_call_stop_pending_menu
$ IF ((q_status_stopped) .AND. (q_status_idle)) THEN -
    GOTO q_scr_call_stopped_menu
$ !
$ ! At this point, we know the queue is started (not paused nor stopped)
$ ! and no stop request submitted.
$ !
$ IF (q_status_idle)
$    THEN
$      GOSUB q_started_idle_menu
$    ELSE
$      GOSUB q_started_busy_menu
$ ENDIF
$ GOTO end_q_scr
$ !
$q_scr_status_unstable:
$ clear_home
$ GOSUB display_q_chars
$ wo ""
$ wo "Status of printer ''q_name' is transitory."
$ wo "Please wait a few seconds ..."
$ wo ""
$ prompt_str = "(<CR> to return to the list of printers)"
$ READ keyboard ack -
    /TIME_OUT='q_unstable_status_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=q_scr_q_menu_loop -
    /END=q_scr_refresh_list
$ GOTO end_q_scr
$ !
$q_scr_refresh_list:
$ context_switch = 1
$ GOTO end_q_scr
$ !
$q_scr_q_stalled:
$ ! Queue is stalled (state initiated by printer)
$ GOSUB q_stalled_menu
$ GOTO end_q_scr
$ !
$q_scr_q_aligning:
$ ! Queue is aligning
$ WAIT 'q_aligning_wait_timeout'
$ GOTO end_q_scr
$ !
$q_scr_ck_pausing_stalled:
$ WAIT 'q_pausing_wait_timeout'
$ GOSUB get_q_chars
$ IF .NOT. q_status_pausing THEN GOTO end_q_scr
$ ! Queue is stalled "Pausing", try unstalling it
$ GOSUB q_stalled_menu
$ GOTO end_q_scr
$ !
$q_scr_call_paused_busy_menu:
$ GOSUB q_paused_busy_menu
$ GOTO end_q_scr
$ !
$q_scr_call_stopped_menu:
$ GOSUB q_stopped_menu
$ GOTO end_q_scr
$ !
$q_scr_call_stop_pending_menu:
$ GOSUB q_stop_pending_menu
$ GOTO end_q_scr
$ !
$q_scr_job_list:
$ GOSUB job_func
$ GOTO end_q_scr
$ !
$q_scr_exit_pgm:
$ GOSUB exit_func
$ GOTO end_q_scr
$ !
$end_q_scr:
$ RETURN
$ !
$ !
$job_scr:
$ ! Display a list of all the jobs in all the queues specified in the 
$ ! queue list passed as arg.
$ ! Continually update the list.
$ !
$ ! Ask for the no of the job to be managed, using the vms job number
$ ! and branch to menu sub.
$ !
$ clear_home
$ GOSUB display_job_list
$ wo ""
$ wo "    P      Printer queue list"
$ wo "    Q      Quit"
$ prompt_str = "           ID number of job to control ?"
$ READ keyboard choice -
    /TIME_OUT='job_list_refresh_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=job_scr -
    /END=job_scr
$ !
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. "P" THEN GOTO job_scr_q_list
$ IF choice .EQS. "Q" THEN GOTO job_scr_exit_pgm
$ IF choice .EQS. "" THEN GOTO end_job_scr
$ !
$ ! Not a keyword, check out job number
$ job_entry_no = 'F$INTEGER(choice)'
$ IF job_entry_no .LE. 0 THEN GOTO end_job_scr
$ !
$ ! Check if job number entered exists
$ job_exists = -
     "''F$GETQUI("DISPLAY_ENTRY","ENTRY_NUMBER",job_entry_no)'" .NES. ""
$ IF .NOT. job_exists THEN GOTO end_job_scr
$ !
$ GOSUB job_menu
$ GOTO end_job_scr
$ !
$job_scr_q_list:
$ GOSUB q_func
$ GOTO end_job_scr
$ !
$job_scr_exit_pgm:
$ GOSUB exit_func
$ GOTO end_job_scr
$ !
$end_job_scr:
$ RETURN
$ !
$ !
$ !
$ !	Main context switching functions
$ !
$job_func:
$ screen_object = "JOB"
$ context_switch = 1
$ RETURN
$ !
$q_func:
$ screen_object = "QUEUE"
$ context_switch = 1
$ RETURN
$ !
$exit_func:
$ screen_object = "EXIT"
$ context_switch = 1
$ RETURN
$ !
$ !
$ !
$ !	Queue info display functions
$ !
$display_q_list:
$ ! Display a queue characteristics with the most up to date status
$ clear_home
$ wo "PRINTERS"
$ wo ""
$ wo "Nr  PrinterQ Name         Stock              Stat          Description"
$ !
$ i_q = 0
$display_q_loop:
$ i_q = i_q + 1
$ q_name = q_name_'i_q'
$ GOSUB get_q_chars
$ GOSUB set_q_display_status
$ i_q_string = F$STRING(i_q)
$ display_rec = F$FAO("!3AS !20AS !18AS !3AS/!7AS !20AS", -
   i_q_string,q_name,q_stock_mounted,q_avail_status,q_display_status,q_descr)
$ wo display_rec
$ IF i_q .EQ. n_q THEN GOTO end_display_q_loop
$ GOTO display_q_loop
$end_display_q_loop:
$ wo ""
$ RETURN
$ !
$set_q_display_status:
$ ! Set the text displayed according to different status of queue
$ q_display_status = "Norm"
$ IF q_status_resetting   THEN q_display_status = "Rstg"
$ IF q_status_resuming    THEN q_display_status = "Resu"
$ IF q_status_starting    THEN q_display_status = "Star"
$ IF q_status_stopping    THEN q_display_status = "Stpg"
$ IF q_status_aligning    THEN q_display_status = "Alig"
$ IF q_status_closed      THEN q_display_status = "Clos"
$ IF q_status_stopped     THEN q_display_status = "Stop"
$ IF q_status_paused      THEN q_display_status = "Paus"
$ IF q_status_pausing     THEN q_display_status = "Psng"
$ IF q_status_stalled     THEN q_display_status = "Stal"
$ IF q_status_unavailable THEN q_display_status = "Unav"
$ IF q_status_idle        THEN q_avail_status =   "Idle"
$ IF .NOT. q_status_idle  THEN q_avail_status =   "Busy"
$ RETURN
$ !
$display_q_chars:
$ ! Displays the current queue name, it's complete queue status and
$ ! the form mounted.
$ wo "Printer    : ''q_name'           ''q_descr'"
$ wo ""     
$ wo "Form       : ''q_form_mounted'"
$ wo "Paper      : ''q_stock_mounted'"
$ status_str = ""
$ IF q_status_aligning THEN -
  status_str = "Status     : Printing alignment pages              [ALIGNING]"
$ IF q_status_idle THEN -
  status_str = "Status     : Idle (no current job)                 [IDLE]"
$ IF q_status_paused THEN -
  status_str = "Status     : Stopped (current job suspended)       [PAUSED]"
$ IF q_status_pausing THEN -
  status_str = "Status     : Stopping (suspending current job)     [PAUSING]"
$ IF q_status_resetting THEN -
  status_str = "Status     : Reinitializing                        [RESETTING]"
$ IF q_status_resuming THEN -
  status_str = "Status     : Resuming current suspended job        [RESUMING]" 
$ IF q_status_starting THEN -
  status_str = "Status     : Starting previously stopped queue     [STARTING]" 
$ IF q_status_stopped THEN -
  status_str = "Status     : Stopped (last job completed)          [STOPPED]"
$ IF q_status_stopping THEN -
  status_str = "Status     : Stopping (completing current job)     [STOPPING]"
$ IF q_status_unavailable THEN -
  status_str = "Status     : *BROKEN*                              [UNAVAILABLE]"
$ if status_str .eqs. "" then -
  status_str = "Status     : Printing current job                  [BUSY]"
$ wo status_str
$ !
$ IF q_exec_job_entry_no .EQS. "" THEN GOTO end_display_q_chars
$ wo ""
$ wo "Job entry number : ''q_exec_job_entry_no'"
$ wo "Username         : ''q_exec_job_username'"
$ wo "Job name         : ''q_exec_job_name'"
$ wo "File             : ''q_exec_job_file_specif'"
$ wo "Blocks completed : ''q_exec_job_completed_blocks'/''q_exec_job_size'"
$end_display_q_chars:
$ RETURN
$ !
$ !	Queue info retrieval functions
$ !
$get_q_chars:
$ ! Get different characteristics of a queue which name is in symbol q_name
$ q_generic = F$GETQUI("DISPLAY_QUEUE","QUEUE_GENERIC","''q_name'")
$ IF .NOT. q_generic
$ THEN
$   q_form_mounted = F$GETQUI("DISPLAY_QUEUE","FORM_NAME","''q_name'")
$   q_stock_mounted = F$GETQUI("DISPLAY_QUEUE","FORM_STOCK","''q_name'")
$ ELSE
$   q_form_mounted = "-"
$   q_stock_mounted = "-"
$ ENDIF
$ q_descr = F$GETQUI("DISPLAY_QUEUE","QUEUE_DESCRIPTION","''q_name'")
$ q_device = F$GETQUI("DISPLAY_QUEUE","DEVICE_NAME","''q_name'")
$ GOSUB get_q_status
$ !
$ ! Get the specifications of file being printed
$ dummy = F$GETQUI("")
$ dummy = F$GETQUI("DISPLAY_QUEUE","QUEUE_NAME","''q_name'*")
$ exec_job_entry_no = -
  F$GETQUI("DISPLAY_JOB","ENTRY_NUMBER",,"EXECUTING_JOBS")
$ q_exec_job_entry_no = F$STRING(exec_job_entry_no)
$ IF q_exec_job_entry_no .EQS. "" THEN GOTO get_q_chars_no_exec_jobs
$ q_exec_job_name = -
  F$GETQUI("DISPLAY_JOB","JOB_NAME",,"FREEZE_CONTEXT,EXECUTING_JOBS")
$ q_exec_job_username = -
  F$GETQUI("DISPLAY_JOB","USERNAME",,"FREEZE_CONTEXT,EXECUTING_JOBS")
$ exec_job_completed_blocks = -
  F$GETQUI("DISPLAY_JOB","COMPLETED_BLOCKS",,"FREEZE_CONTEXT,EXECUTING_JOBS")
$ q_exec_job_completed_blocks = F$STRING(exec_job_completed_blocks)
$ exec_job_size = -
  F$GETQUI("DISPLAY_JOB","JOB_SIZE",,"FREEZE_CONTEXT,EXECUTING_JOBS")
$ q_exec_job_size = F$STRING(exec_job_size)
$ q_exec_job_file_specif = -
  F$GETQUI("DISPLAY_FILE","FILE_SPECIFICATION",,"FREEZE_CONTEXT,EXECUTING_JOBS")
$ !
$get_q_chars_no_exec_jobs:
$ dummy = F$GETQUI("")
$end_get_q_chars:
$ RETURN
$ !
$ !
$get_q_status:
$ ! Get different status of a queue which name is in symbol q_name
$ q_status = F$GETQUI("DISPLAY_QUEUE","QUEUE_STATUS",q_name)
$ q_status_aligning    = -
    (q_status .AND. QUEUE_ALIGNING_VAL) .EQ. QUEUE_ALIGNING_VAL
$ q_status_closed      = -
    (q_status .AND. QUEUE_CLOSED_VAL) .EQ. QUEUE_CLOSED_VAL
$ q_status_idle        = -
    (q_status .AND. QUEUE_IDLE_VAL) .EQ. QUEUE_IDLE_VAL
$ q_status_paused      = -
    (q_status .AND. QUEUE_PAUSED_VAL) .EQ. QUEUE_PAUSED_VAL
$ q_status_pausing     = -
    (q_status .AND. QUEUE_PAUSING_VAL) .EQ. QUEUE_PAUSING_VAL
$ q_status_resetting   = -
    (q_status .AND. QUEUE_RESETTING_VAL) .EQ. QUEUE_RESETTING_VAL
$ q_status_resuming    = -
    (q_status .AND. QUEUE_RESUMING_VAL) .EQ. QUEUE_RESUMING_VAL
$ q_status_stalled     = -
    (q_status .AND. QUEUE_STALLED_VAL) .EQ. QUEUE_STALLED_VAL
$ q_status_starting    = -
    (q_status .AND. QUEUE_STARTING_VAL) .EQ. QUEUE_STARTING_VAL
$ q_status_stopped     = -
    (q_status .AND. QUEUE_STOPPED_VAL) .EQ. QUEUE_STOPPED_VAL
$ q_status_stopping    = -
    (q_status .AND. QUEUE_STOPPING_VAL) .EQ. QUEUE_STOPPING_VAL
$ q_status_unavailable = -
    (q_status .AND. QUEUE_UNAVAILABLE_VAL) .EQ. QUEUE_UNAVAILABLE_VAL
$ !
$ RETURN
$ !
$ !
$ !
$ !	Queue menu functions
$ !
$q_stalled_menu:
$ clear_home
$ GOSUB display_q_chars
$ wo ""
$ wo "Printer ''current_q_name' is stalled."
$ wo ""
$ wo "Check: printer is powered ON, printer is ""ON-LINE"" or ""READY"","
$ wo "paper is available, printer is not jammed, paper is properly mounted."
$ wo ""
$ wo "     <CR>    Check printer has restarted"
$ wo ""
$ wo "      P      Printer queue list"
$ wo "      J      Job list"
$ wo "      Q      Quit"
$ wo ""
$ !
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''func_menu_prompt'" -
    /ERROR=end_q_pausing_menu -
    /END=end_q_pausing_menu
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. "P" THEN GOSUB q_func
$ IF choice .EQS. "J" THEN GOSUB job_func
$ IF choice .EQS. "Q" THEN GOSUB exit_func
$ GOTO end_q_pausing_menu
$end_q_pausing_menu:
$ RETURN
$ !
$ !
$q_paused_busy_menu:
$ clear_home
$ GOSUB display_q_chars
$ wo ""
$ wo "      R      Resume job where suspended"
$ IF q_exec_job_entry_no .NES.  ""
$ THEN 
$   wo "      B      Resume job back N pages from where suspended"
$   wo "      F      Resume job forward N pages from where suspended"
$   wo "      L      Resume job from last page including specified string"
$   wo "      1      Resume job from first page"
$   IF .NOT. q_generic
$   THEN
$     wo "      A      Verify paper alignment"
$   ENDIF
$ ENDIF
$   wo "      D     Abort current job and delete job from queue"
$   wo ""
$   wo "      P     Printer queue list"
$   wo "      J     Jobs list"
$   wo "      Q     Quit"
$   wo ""
$ !
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''func_menu_prompt'" -
    /ERROR=end_q_paused_busy_menu -
    /END=end_q_paused_busy_menu
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. "R" THEN GOSUB start_q
$ IF q_exec_job_entry_no .NES.  ""
$ THEN 
$   IF choice .EQS. "B" THEN GOSUB start_q_backward
$   IF choice .EQS. "F" THEN GOSUB start_q_forward
$   IF choice .EQS. "L" THEN GOSUB start_q_search
$   IF choice .EQS. "1" THEN GOSUB start_q_top
$   IF choice .EQS. "D"  THEN GOSUB abort_current_job
$   IF choice .EQS. "A"
$   THEN
$     IF .NOT. q_generic THEN GOSUB align_paper
$   ENDIF
$ ENDIF
$ IF choice .EQS. "P" THEN GOSUB q_func
$ IF choice .EQS. "J" THEN GOSUB job_func
$ IF choice .EQS. "Q" THEN GOTO exit_func
$ GOTO end_q_paused_busy_menu
$end_q_paused_busy_menu:
$ RETURN
$ !
$ !
$q_stopped_menu:
$ clear_home
$ GOSUB display_q_chars
$ wo ""
$ wo "      R      Restart queue / Print new job entries in queue"
$ IF .NOT. q_generic
$ THEN
$   wo "      F      Change paper / change print form"
$   wo "      A      Print alignment pattern file to align"
$ ENDIF
$ wo ""
$ wo "      P      Printer queue list"
$ wo "      J      Job list"
$ wo "      Q      Quit"
$ wo ""
$ !
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''func_menu_prompt'" -
    /ERROR=end_q_stopped_menu -
    /END=end_q_stopped_menu
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. "R" THEN GOSUB start_q
$ IF choice .EQS. "F"
$ THEN
$   IF .NOT. q_generic THEN GOSUB change_form
$ ENDIF
$ IF choice .EQS. "A"
$ THEN
$   IF .NOT. q_generic THEN  GOSUB print_align_parallel
$ ENDIF
$ IF choice .EQS. "P" THEN GOSUB q_func
$ IF choice .EQS. "J" THEN GOSUB job_func
$ IF choice .EQS. "Q" THEN GOTO exit_func
$ GOTO end_q_stopped_menu
$end_q_stopped_menu:
$ RETURN
$ !
$ !
$q_stop_pending_menu:
$ clear_home
$ GOSUB display_q_chars
$ wo ""
$ wo "Printer ''current_q_name' will be automagically stopped"
$ wo "after current print job finishes."
$ wo ""
$ wo "      S      Stop printer / Suspend current print job"
$ wo "      R      Cancel printer queue STOP pending current print job"
$ wo ""
$ wo "      P      Printer queue list"
$ wo "      J      Job list"
$ wo "      Q      Quit"
$ wo ""
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''func_menu_prompt'" -
    /ERROR=end_q_stop_pending_menu -
    /END=end_q_stop_pending_menu
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. "S" THEN GOSUB pause_q
$ IF choice .EQS. "R" THEN GOSUB start_q
$ IF choice .EQS. "P" THEN GOSUB q_func
$ IF choice .EQS. "J" THEN GOSUB job_func
$ IF choice .EQS. "Q" THEN GOSUB exit_func
$ GOTO end_q_stop_pending_menu
$end_q_stop_pending_menu:
$ RETURN
$ !
$ !
$q_started_idle_menu:
$ clear_home
$ GOSUB display_q_chars
$ wo ""
$ wo "      S       Stop printer queue / hold any new print job entry"
$ IF .NOT. q_generic
$ THEN
$   wo "      A       Print alignment pattern file to align"
$ ENDIF
$ wo ""
$ wo "      P       Printer queue list"
$ wo "      J       Job list"
$ wo "      Q       Quit"
$ wo ""
$ !
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''func_menu_prompt'" -
    /ERROR=end_q_started_idle_menu -
    /END=end_q_started_idle_menu
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. "S" THEN GOSUB stop_q_next
$ IF choice .EQS. "P" THEN GOSUB q_func
$ IF choice .EQS. "A"
$ THEN
$   IF .NOT. q_generic THEN GOSUB test_align
$ ENDIF
$ IF choice .EQS. "J" THEN GOSUB job_func
$ IF choice .EQS. "Q" THEN GOSUB exit_func
$ GOTO end_q_started_idle_menu
$end_q_started_idle_menu:
$ RETURN
$ !
$ !
$test_align:
$ form_test_fspec = "''form_test_dir'''q_form_mounted'.TST"
$ IF f$search(form_test_fspec) .EQS. "" THEN -
  GOTO test_align_error
$ PRINT/QUEUE='q_name'/FORM='q_form_mounted' 'form_test_fspec'
$ RETURN
$ !
$test_align_error:
$ wo ""
$ wo "Form test file ''form_test_fspec' not found !"
$ prompt_str = "<CR>"
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=end_stop_idle_q -
    /END=end_stop_idle_q
$ RETURN
$ !
$print_align_parallel:
$ form_test_fspec = "''form_test_dir'''q_form_mounted'.TST"
$ IF f$search(form_test_fspec) .EQS. "" THEN -
  GOTO test_align_error
$ STOP/QUEUE/NEXT PQ_ALIGN
$ INITIALIZE/QUEUE/ON='q_device'/FORM='q_form_mounted' PQ_ALIGN
$ START/QUEUE PQ_ALIGN
$ PRINT/QUEUE=PQ_ALIGN/FORM='q_form_mounted' 'form_test_fspec'
$ STOP/QUEUE/NEXT PQ_ALIGN
$ RETURN
$ !
$ !
$q_started_busy_menu:
$ clear_home
$ GOSUB display_q_chars
$ wo ""
$ wo "      S      Stop printer / Suspend current job"
$ wo "      E      Stop printer queue after current job's end"
$ wo "      D      Abort current job and delete job from queue"
$ wo ""
$ wo "      P      Printer queue list"
$ wo "      J      Job list"
$ wo "      Q      Quit"
$ wo ""
$ !
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''func_menu_prompt'" -
    /ERROR=end_q_started_busy_menu -
    /END=end_q_started_busy_menu
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. "S" THEN GOSUB pause_q
$ IF choice .EQS. "E" THEN GOSUB stop_q_next
$ IF choice .EQS. "D" THEN GOSUB abort_current_job
$ IF choice .EQS. "P" THEN GOSUB q_func
$ IF choice .EQS. "J" THEN GOSUB job_func
$ IF choice .EQS. "Q" THEN GOTO exit_func
$ GOTO end_q_started_busy_menu
$end_q_started_busy_menu:
$ RETURN
$ !
$ !
$ !
$ !	Queue management functions
$ !
$start_q:
$ START /QUEUE 'current_q_name'
$ RETURN
$ !
$ !
$start_q_backward:
$ wo ""
$ prompt_str = "How many pages back ? "
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=end_start_q_backward -
    /END=end_start_q_backward
$ n_pages = 'F$INTEGER(choice)'
$ IF n_pages .LE. 0 THEN GOTO end_start_q_backward
$ START /QUEUE /BACKWARD='n_pages'  'current_q_name'
$end_start_q_backward:
$ RETURN
$ !
$ !
$start_q_forward:
$ wo ""
$ prompt_str = "How many pages forward ? "
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=end_start_q_forward -
    /END=end_start_q_forward
$ n_pages = 'F$INTEGER(choice)'
$ IF n_pages .LE. 0 THEN GOTO end_start_q_forward
$ START /QUEUE /FORWARD='n_pages'  'current_q_name'
$end_start_q_forward:
$ RETURN
$ !
$ !
$start_q_search:
$ wo ""
$ prompt_str = "String to locate ? "
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=end_start_q_search -
    /END=end_start_q_search
$ search_str = F$EDIT(choice,"COMPRESS,TRIM,UPCASE")
$ IF search_str .EQS. "" THEN GOTO end_start_search
$ START /QUEUE /SEARCH="''search_str'"  'current_q_name'
$end_start_q_search:
$ RETURN
$ !
$ !
$start_q_top:
$ START /QUEUE /TOP_OF_FILE  'current_q_name'
$ RETURN
$ !
$ !
$abort_current_job:
$ on severe_error then continue
$ DELETE /ENTRY='q_exec_job_entry_no'
$ WAIT 'q_aligning_wait_timeout'
$ RETURN
$ !
$ !
$retain_current_job:
$ on severe_error then continue
$ SET ENTRY/RETAIN=ALWAYS 'q_exec_job_entry_no'
$ RETURN
$ !
$ !
$pause_q:
$ ! Stop a queue immediatly and suspend the current job
$ STOP /QUEUE 'current_q_name'
$ ! Gotta wait for the queue to be entirely stopped
$ WAIT 'q_stopping_wait_timeout'
$ RETURN
$ !
$ !
$stop_q_next:
$ STOP /QUEUE /NEXT 'current_q_name'
$ RETURN
$ !
$ !
$stop_idle_q:
$ STOP /QUEUE /NEXT 'current_q_name'
$ WAIT 'q_stopping_wait_timeout'
$ q_name = current_q_name
$ GOSUB get_q_chars
$ IF q_status_idle THEN GOTO end_stop_idle_q
$ wo ""
$ wo "A print job has just started on this printer."
$ wo "This printer will automatically stop at the end of the current job."
$ prompt_str = "<CR>"
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=end_stop_idle_q -
    /END=end_stop_idle_q
$ GOTO end_stop_idle_q
$end_stop_idle_q:
$ RETURN
$ !
$align_paper:
$ wo ""
$ prompt_str = "How many alignment pages do you want to print (max 20) ? "
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=end_align_paper -
    /END=end_align_paper
$ n_pages = 'F$INTEGER(choice)'
$ IF (n_pages .LE. 0) .OR. (n_pages .GT. 20) THEN GOTO end_start_q_forward
$ START /QUEUE /ALIGN=(MASK,'n_pages')  'current_q_name'
$end_align_paper:
$ RETURN
$ !
$ !
$change_form:
$ clear_home
$ GOSUB display_form_list
$ wo ""
$ prompt_str = "What print form do you want to mount ? " 
$ prompt_str = prompt_str + "(<CR> = ''q_form_mounted') "
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=end_change_form -
    /END=end_change_form
$ !
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. "" THEN GOTO change_form_same_form
$ i_form = 'F$INTEGER(choice)'
$ IF (i_form .LE. 0) .OR. (i_form .GT. n_form) THEN GOTO change_form
$ form_name = form_name_'i_form'
$ GOSUB get_form_chars
$ IF form_name .EQS. q_form_mounted THEN GOTO change_form_same_stock
$ IF form_stock .EQS. q_stock_mounted THEN GOTO change_form_same_stock
$ GOTO change_form_chp
$ !
$change_form_same_form:
$ form_name = q_form_mounted
$ form_stock = q_stock_mounted
$change_form_same_stock:
$ SET QUEUE /FORM='form_name' 'current_q_name'
$ clear_home
$ wo "PRINTER    : ''current_q_name'        ''form_decr'"
$ wo ""     
$ wo ""
$ wo "Print form ''form_name' has been mounted on queue ''current_q_name'."
$ wo ""
$ wo "This print form uses stock ''form_stock',"
$ wo "which should be already mounted on this printer"
$ wo ""
$ wo "Check that paper loaded on ''current_q_name' printer"
$ wo "is stock ''form_stock'."
$ wo ""
$ prompt_str = "<CR> when done, eventually after new stock mounted"
$ READ keyboard ack -
    /TIME_OUT="''change_paper_timeout'" -
    /PROMPT="''prompt_str'" -
    /ERROR=end_change_form -
    /END=end_change_form
$ GOTO end_change_form
$ !
$change_form_chp:
$ SET QUEUE /FORM='form_name' 'current_q_name'
$ clear_home
$ wo "PRINTER    : ''current_q_name'        ''form_decr'"
$ wo ""     
$ wo ""
$ wo "You have chosen to mount print form ''form_name'"
$ wo "on queue ''current_q_name'."
$ wo ""
$ wo "The stock needed for this print form is different than the one"
$ wo "currently mounted."
$ wo "
$ wo "Please mount stock ''form_stock'"
$ wo "on printer ''current_q_name'."
$ wo ""
$ prompt_str = "<CR> once new stock is mounted"
$ READ keyboard ack -
    /TIME_OUT='change_paper_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=end_change_form -
    /END=end_change_form
$ GOTO end_change_form
$ !
$end_change_form:
$ RETURN
$ !
$ !
$print_align:
$ wo ""
$!
$ prompt_str = "How many alignment pages do you want to print (max 20) ? "
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=end_print_align -
    /END=end_print_align
$ n_pages = 'F$INTEGER(choice)'
$ IF (n_pages .LE. 0) .OR. (n_pages .GT. 20) THEN GOTO end_start_q_forward
$ START /QUEUE /ALIGN=(MASK,'n_pages')  'current_q_name'
$end_print_align:
$ WAIT 'q_function_unavailable_timeout'
$ RETURN
$ !
$ !	Form info retrieval and display functions
$ !
$display_form_list:
$ ! Display all the forms characteristics
$ clear_home
$ wo "PRINT FORMS"
$ wo ""
$ wo "Nr  Name                   Description                        Stock"
$ wo ""
$ !
$ i_form = 0
$display_form_loop:
$ i_form = i_form + 1
$ form_name = form_name_'i_form'
$ GOSUB get_form_chars
$ i_form_str = F$STRING('i_form')
$ display_rec_form = F$FAO -
   ("!4AS!23AS!35AS!17AS",i_form_str,form_name,form_descr,form_stock)
$ wo display_rec_form
$ IF i_form .EQ. n_form THEN GOTO end_display_form_loop
$ GOTO display_form_loop
$end_display_form_loop:
$ RETURN
$ !
$ !
$get_form_chars:
$ form_stock = F$GETQUI("DISPLAY_FORM","FORM_STOCK",form_name)
$ form_descr = F$GETQUI("DISPLAY_FORM","FORM_DESCRIPTION",form_name)
$ RETURN
$ !
$ !
$ !
$ !	Job info display and retrieval functions
$ !
$display_job_list:
$ clear_home
$ wo "PRINT JOBS"
$ wo ""
$ wo -
 "Nr  Printer        JobName        User       S/Job  S/Prt   Stock         Pri"
$ wo ""
$ !
$ i_q = 0
$display_job_list_q_loop:
$ i_q = i_q + 1
$ IF i_q .GT. n_q THEN GOTO end_display_job_list
$ q_name_ = q_name_'i_q'
$ dummy = F$GETQUI("")
$ q_name = F$GETQUI("DISPLAY_QUEUE","QUEUE_NAME","''q_name_'*")
$display_job_list_job_loop:
$ GOSUB set_q_display_status
$ noaccess = F$GETQUI("DISPLAY_JOB","JOB_INACCESSIBLE",,"ALL_JOBS")
$ IF noaccess .EQS. "TRUE" THEN GOTO display_job_list_job_loop
$ IF noaccess .EQS. "" THEN GOTO display_job_list_q_loop
$ GOSUB get_ctx_job_chars
$ !
$ job_entry_no_str = F$STRING(job_entry_no)
$ job_priority_str = F$STRING(job_priority)
$ job_completed_blocks_str = F$STRING(job_completed_blocks) 
$ IF job_completed_blocks .EQ. 0 THEN job_completed_blocks_str = " "
$ job_size_str = F$STRING(job_size)
$ !
$ job_display_rec = -
  F$FAO ("!3AS !14AS !14AS !10AS !6AS !3AS/!3AS !14AS !3AS",-
  job_entry_no_str,q_name,job_name,job_username,-
  job_display_status,q_avail_status,q_display_status,job_stock,-
  job_priority_str)
$ wo job_display_rec
$ GOTO display_job_list_job_loop
$end_display_job_list:
$ dummy = F$GETQUI("")
$ RETURN
$ !
$ !
$get_ctx_job_chars:
$ job_entry_no = -
    F$GETQUI("DISPLAY_JOB","ENTRY_NUMBER",,"FREEZE_CONTEXT,ALL_JOBS")
$ job_name = -
    F$GETQUI("DISPLAY_JOB","JOB_NAME",,"FREEZE_CONTEXT,ALL_JOBS")
$ job_username = -
    F$GETQUI("DISPLAY_JOB","USERNAME",,"FREEZE_CONTEXT,ALL_JOBS")
$ job_priority = -
    F$GETQUI("DISPLAY_JOB","PRIORITY",,"FREEZE_CONTEXT,ALL_JOBS")
$ job_completed_blocks = -
    F$GETQUI("DISPLAY_JOB","COMPLETED_BLOCKS",,"FREEZE_CONTEXT,ALL_JOBS")
$ job_size = -
    F$GETQUI("DISPLAY_JOB","JOB_SIZE",,"FREEZE_CONTEXT,ALL_JOBS")
$ job_stock = -
    F$GETQUI("DISPLAY_JOB","FORM_STOCK",,"FREEZE_CONTEXT,ALL_JOBS")
$ job_form = -
    F$GETQUI("DISPLAY_JOB","FORM_NAME",,"FREEZE_CONTEXT,ALL_JOBS")
$ job_note = -
    F$GETQUI("DISPLAY_JOB","NOTE",,"FREEZE_CONTEXT,ALL_JOBS")
$ job_queue = -
    F$GETQUI("DISPLAY_JOB","QUEUE_NAME",,"FREEZE_CONTEXT,ALL_JOBS")
$ job_retention = -
    F$GETQUI("DISPLAY_JOB","JOB_RETENTION",,"FREEZE_CONTEXT,ALL_JOBS")
$ job_status = -
    F$GETQUI("DISPLAY_JOB","JOB_STATUS",,"FREEZE_CONTEXT,ALL_JOBS")
$ GOSUB set_job_bool_status
$ GOSUB set_job_display_status
$ RETURN
$ !
$ !
$set_job_bool_status: 
$ job_status_aborting = -
  (job_status .AND. JOB_ABORTING_VAL) .EQ. JOB_ABORTING_VAL
$ job_status_executing = -
  (job_status .AND. JOB_EXECUTING_VAL) .EQ. JOB_EXECUTING_VAL
$ job_status_holding = -
  (job_status .AND. JOB_HOLDING_VAL) .EQ. JOB_HOLDING_VAL
$ job_status_inaccessible = -
  (job_status .AND. JOB_INACCESSIBLE_VAL) .EQ. JOB_INACCESSIBLE_VAL
$ job_status_refused = -
  (job_status .AND. JOB_REFUSED_VAL) .EQ. JOB_REFUSED_VAL
$ job_status_requeue = -
  (job_status .AND. JOB_REQUEUE_VAL) .EQ. JOB_REQUEUE_VAL
$ job_status_restarting = -
  (job_status .AND. JOB_RESTARTING_VAL) .EQ. JOB_RESTARTING_VAL
$ job_status_retained = -
  (job_status .AND. JOB_RETAINED_VAL) .EQ. JOB_RETAINED_VAL
$ job_status_starting = -
  (job_status .AND. JOB_STARTING_VAL) .EQ. JOB_STARTING_VAL
$ job_status_timed_release = -
  (job_status .AND. JOB_TIMED_RELEASE_VAL) .EQ. JOB_TIMED_RELEASE_VAL
$ job_status_suspended = -
  (job_status .AND. JOB_SUSPENDED_VAL) .EQ. JOB_SUSPENDED_VAL
$ job_status_pending = -
  (job_status .AND. JOB_PENDING_VAL) .EQ. JOB_PENDING_VAL
$ job_status_stalled = -
  (job_status .AND. JOB_STALLED_VAL) .EQ. JOB_STALLED_VAL
$ RETURN
$ !
$ !
$set_job_display_status:
$ job_display_status = "????"
$ IF job_status_aborting      THEN job_display_status = "Abor"
$ IF job_status_executing     THEN job_display_status = "Exec"
$ IF job_status_holding       THEN job_display_status = "Hold"
$ IF job_status_inaccessible  THEN job_display_status = "Inac"
$ IF job_status_refused       THEN job_display_status = "Refu"
$ IF job_status_requeue       THEN job_display_status = "Requ"
$ IF job_status_restarting    THEN job_display_status = "Rstr"
$ IF job_status_retained      THEN job_display_status = "Rtnd"
$ IF job_status_starting      THEN job_display_status = "Star"
$ IF job_status_timed_release THEN job_display_status = "Time"
$ IF job_status_suspended     THEN job_display_status = "Susp"
$ IF job_status_pending       THEN job_display_status = "Pend"
$ IF job_status_stalled       THEN job_display_status = "Stal"
$ RETURN
$ !
$ !
$get_job_chars:
$ job_name = F$GETQUI("DISPLAY_ENTRY","JOB_NAME",job_entry_no)
$ job_username = F$GETQUI("DISPLAY_ENTRY","USERNAME",job_entry_no)
$ job_priority = F$GETQUI("DISPLAY_ENTRY","PRIORITY",job_entry_no)
$ job_completed_blocks = -
     F$GETQUI("DISPLAY_ENTRY","COMPLETED_BLOCKS",job_entry_no)
$ job_size = F$GETQUI("DISPLAY_ENTRY","JOB_SIZE",job_entry_no)
$ job_stock = F$GETQUI("DISPLAY_ENTRY","FORM_STOCK",job_entry_no)
$ job_form = F$GETQUI("DISPLAY_ENTRY","FORM_NAME",job_entry_no)
$ job_note = F$GETQUI("DISPLAY_ENTRY","NOTE",job_entry_no)
$ job_queue = F$GETQUI("DISPLAY_ENTRY","QUEUE_NAME",job_entry_no)
$ job_status = F$GETQUI("DISPLAY_ENTRY","JOB_STATUS",job_entry_no)
$ ! If job status is pending, get the pending job reason
$ if job_status .eqs. JOB_PENDING_VAL
$ then
$   job_pending_reason = -
      f$getqui("display_entry","pending_job_reason",job_entry_no)
$   if job_pending_reason .eq. pend_check_exec_queues	then -
      job_pending_reason_string = "check execution queues"
$   if job_pending_reason .eq. pend_char_mismatch      then -
      job_pending_reason_string = "char mismatch"
$   if job_pending_reason .eq. pend_job_size_max       then -
      job_pending_reason_string = "job size max"
$   if job_pending_reason .eq. pend_job_size_min       then -
      job_pending_reason_string = "job size min"
$   if job_pending_reason .eq. pend_lowercase_mismatch then -
      job_pending_reason_string = "lowercase mismatch"
$   if job_pending_reason .eq. pend_no_access          then -
      job_pending_reason_string = "no access"
$   if job_pending_reason .eq. pend_queue_busy         then -
      job_pending_reason_string = "queue busy"
$   if job_pending_reason .eq. pend_queue_state        then -
      job_pending_reason_string = "queue state"
$   if job_pending_reason .eq. pend_stock_mismatch     then -
      job_pending_reason_string = "stock mismatch"
$ endif
$ GOSUB set_job_bool_status
$ GOSUB set_job_display_status
$ RETURN
$ !
$ !
$display_job_chars:
$ GOSUB get_job_chars
$ q_name = job_queue
$ GOSUB get_q_chars
$ GOSUB set_q_display_status
$ ! Get queue number
$ i_q = 1
$loop_get_queue_number:
$ if q_name_'i_q' .eqs. q_name then goto end_get_queue_number
$ if i_q .eq. n_q then goto end_get_queue_number
$ i_q = i_q + 1
$ goto loop_get_queue_number
$end_get_queue_number:
$ i_q_string = f$string(i_q)
$ job_entry_no_string = f$string(job_entry_no)
$ wo "               Job                           Printer"
$ wo ""
$ wo f$fao("ID Number      !30AS",job_entry_no_string) + i_q_string
$ wo f$fao("Name           !30AS",job_name) + job_queue
$ wo f$fao("Form           !30AS",job_form) + q_form_mounted
$ wo f$fao("Stock          !30AS",job_stock) + q_stock_mounted
$ if job_status_pending then -
   job_display_status = job_display_status + " (''job_pending_reason_string')"
$ wo f$fao("Status         !30AS",job_display_status) + -
      q_avail_status + "/" + q_display_status
$ str = "''job_completed_blocks'/''job_size'"
$ perc = F$INTEGER(job_completed_blocks) * 100 / F$INTEGER(job_size)
$ wo f$fao("Size prtd/tot  !12AS",str) + "(" + "''perc'" + "%)"
$ wo "User           ''job_username'"
$ wo f$fao("Note           !60AS",job_note) + q_descr
$ wo ""
$ RETURN
$ !
$ !
$ !
$ !	Job menu functions
$ !
$job_menu:
$ clear_home
$ GOSUB display_job_chars
$ IF job_status_pending THEN -
  wo "      H      Hold job in print queue"
$ IF job_status_holding THEN -
  wo "      R      Release job in print queue"
$ wo "      M      Move (requeue) job in other print queue"
$ wo "      D      Abort job and delete job from printer queue"
$ wo "      +/-    Increase/Decrease priority of job entry in queue"
$ wo ""
$ wo "      P      Printer queue list"
$ wo "      J      Print job list"
$ wo "      Q      Quit"
$ wo ""
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="Quelle fonction choisissez-vous ? " -
    /ERROR=end_job_menu -
    /END=end_job_menu
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. "D" THEN GOSUB del_job
$ IF choice .EQS. "M" THEN GOSUB requeue_job
$ IF choice .EQS. "+" THEN GOSUB up_prio
$ IF choice .EQS. "-" THEN GOSUB down_prio
$ IF choice .EQS. "P" THEN GOTO q_func
$ IF (choice .EQS. "R") .AND. (job_status_holding) THEN -
  GOSUB release_job
$ IF (choice .EQS. "H") .AND. (job_status_pending) THEN -
  GOSUB hold_job
$ IF choice .EQS. "J" THEN GOTO job_func
$ IF choice .EQS. "Q" THEN GOTO exit_func
$end_job_menu:
$ RETURN
$ !
$ !
$ !
$ !	Job management functions
$ !
$release_job:
$ SET ENTRY/RELEASE 'job_entry_no'
$ RETURN
$!
$hold_job:
$ SET ENTRY/HOLD 'job_entry_no'
$ RETURN
$!
$requeue_job:
$ prompt_str := "New queue name ? "
$ IF last_requeue .NES. "" THEN -
   prompt_str = prompt_str + "[" + last_requeue + "] "
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=end_requeue_job -
    /END=end_requeue_job
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. ""
$ THEN
$   IF last_requeue .NES. ""
$   THEN
$     ON ERROR THEN CONTINUE
$     SET ENTRY/REQUEUE='last_requeue'  'job_entry_no'
$     ON ERROR THEN EXIT $STATUS
$   ENDIF
$ ELSE
$   ON ERROR THEN CONTINUE
$   SET ENTRY/REQUEUE='choice'  'job_entry_no'
$   IF $STATUS THEN last_requeue = choice
$   ON ERROR THEN EXIT $STATUS
$ ENDIF
$end_requeue_job:
$ RETURN
$!
$up_prio:
$ IF job_status_executing
$ THEN
$   wo ""
$   wo "Cannot change priority of job already printing."
$   wo ""
$   wait 'q_error_message_timeout'
$ ELSE
$   new_job_priority = 'job_priority' + 10
$   SET ENTRY 'job_entry_no' /PRIORITY='new_job_priority'
$ ENDIF
$ RETURN
$ !
$ !
$down_prio:
$ IF job_status_executing
$ THEN
$   wo ""
$   wo "Cannot change priority of job already printing."
$   wo ""
$   wait 'q_error_message_timeout'
$ ELSE
$   new_job_priority = 'job_priority' - 10
$   SET ENTRY 'job_entry_no' /PRIORITY='new_job_priority'
$ ENDIF
$ RETURN
$ !
$ !
$del_job:
$ wo ""
$ wo "WARNING: You are about to delete the job entry above !"
$ prompt_str := "Are you sure (Y/N) ? "
$ READ keyboard choice -
    /TIME_OUT='choice_timeout' -
    /PROMPT="''prompt_str'" -
    /ERROR=end_del_job -
    /END=end_del_job
$ choice = F$EDIT(choice,"COMPRESS,UPCASE,TRIM")
$ IF choice .EQS. "O" THEN GOTO do_del_job
$ GOTO end_del_job 
$do_del_job:
$ on severe_error then continue
$ DELETE /ENTRY='job_entry_no'
$ WAIT 'q_aligning_wait_timeout'
$end_del_job:
$ RETURN
$ !
$ !
$ctrl_y:
$ !
$simple_exit:
$ wo ""
$ CLOSE keyboard
$ EXIT