From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 19-MAR-1991 15:17:16.06
To:	ARISIA::EVERHART
CC:	
Subj:	Terminal-Settings Copy Utility (Source & Docs Included Here)

From:	RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP@CRDGW2
To:	Everhart@Arisia@MRGATE

Received:  by crdgw1.ge.com (5.57/GE 1.91)
	 id AA00967; Tue, 19 Mar 91 14:57:12 EST
Received: From UCBVAX.BERKELEY.EDU by CRVAX.SRI.COM with TCP; Tue, 19 MAR 91 05:38:46 PST
Received: by ucbvax.Berkeley.EDU (5.63/1.42)
	id AA02776; Tue, 19 Mar 91 05:25:56 -0800
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 19 Mar 91 12:01:03 GMT
From: portal!cup.portal.com!Chris_F_Chiesa@apple.com
Organization: The Portal System (TM)
Subject: Terminal-Settings Copy Utility (Source & Docs Included Here)
Message-Id: <40322@cup.portal.com>
References: <9103120950.AA11567@ucbvax.Berkeley.EDU>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

A week or two ago I mentioned in a posting on some topic that I had written
a utility which allows you to copy "settings" from one terminal to another,
and to save settings in a file and restore them from a file.  My hometown
(Rochester, NY) was immediately hit by an ice storm that left my uploading
computer without power for nine days!  Sorry for the delay, but better late
than never.   Here's the CopySettings utility, in two parts, VMS_SHAREd.
Bug reports, suggestions, etc. to me here or at contact points listed in
the included docfile.

 Chris_F_Chiesa@cup.portal.com
-----
$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.1-004  3-AUG-1989
$!   On 17-MAR-1991 16:03:40.72   By user CHIESA 
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$!+ THIS PACKAGE DISTRIBUTED IN 2 PARTS, TO KEEP EACH PART
$!  BELOW 30 BLOCKS
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. COPYSETTINGS.CLD;4
$!       2. COPYSETTINGS.MAR;6
$!       3. COPYSETTINGS_README.TXT;1
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ if f$getsyi("version") .ges. "V4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ if f$search(P1) .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped."
$ delete/nolog 'f'*
$ exit
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete/nolog 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");
buff:=CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(buff))
;LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(buff));g:=0;LOOP EXITIF MARK(NONE)=END_OF(buff);x:=
ERASE_CHARACTER(1);IF g = 0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x=
"V" THEN APPEND_LINE;MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;
IF x="+" THEN g:=1;ERASE_LINE;ENDIF;ELSE IF x="-" THEN g:=0;ENDIF;ERASE_LINE;
ENDIF;ENDLOOP;p:="`";POSITION(BEGINNING_OF(buff));LOOP r:=SEARCH(p,FORWARD);
EXITIF r=0;POSITION(r);ERASE(r);COPY_TEXT(ASCII(INT(ERASE_CHARACTER(3))));
ENDLOOP;o:=GET_INFO(COMMAND_LINE,"output_file");WRITE_FILE(buff,o);
ENDPROCEDURE;Unpacker;EXIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create/nolog 'f'
XDEFINE VERB SETTINGS    ! V1.0, C.Chiesa, 2/6/91
X!
X!  Change the UTILITIES: directoryspec below, to whatever's appropriate for
X!  your own site.
X!
X  IMAGE UTILITIES:COPYSETTINGS
X  PARAMETER P1,LABEL=SOURCE,PROMPT="Source"
X    VALUE (REQUIRED,TYPE=$INFILE)
X  PARAMETER P2,LABEL=DEST,PROMPT="Destination"
X    VALUE (REQUIRED,TYPE=$OUTFILE)
X  QUALIFIER COPY
X  QUALIFIER SAVE
X  QUALIFIER RESTORE
X  QUALIFIER PERMANENT
X  DISALLOW ANY2(COPY,SAVE,RESTORE)
X  DISALLOW ((NOT COPY) AND (NOT SAVE) AND (NOT RESTORE))
$ CALL UNPACK COPYSETTINGS.CLD;4 891570937
$ create/nolog 'f'
X`009.TITLE`009COPYSETTINGS - Copy, Save, and Restore terminal settings
X`009.IDENT`009\V01.00\
X;++
X;
X;  Author:
X;
X;`009Christopher F. Chiesa  (Chris_F_Chiesa@cup.portal.com)
X;
X;  Edit History:
X;
X;`009V01.00`009- C.F.Chiesa
X;`009`009`009original, no modifications
X;
X;  Functional Description:
X;
X;`009CopySettings provides three useful functions which operate on
X;`009a terminal's characteristics (as set by SET TERMINAL or SET
X;`009TERMINAL/PERMANENT).
X;
X;`009COPY - copies one terminal's characteristics to another, i.e.
X;`009`009"set THIS terminal exactly the same as THAT one"
X;
X;`009SAVE - saves a terminal's characteristics in a data file, i.e.
X;`009`009"save a record of how this terminal is set right now"
X;
X;`009RESTORE - restores a terminal's characteristics from a data
X;`009`009file, i.e. "set this terminal back the way it was when
X;`009`009we SAVEd the settings"
X;
X;  Environment:
X;
X;`009OS: `009`009VMS V4.4 or above
X;`009CLI:`009`009DCL
X;`009Invocation:`009Native command defined by COPYSETTINGS.CLD
X;  `009Privileges:`009OPER priv for use of /PERMANENT qualifier only
X;
X;  Usage:
X;
X;`009SETTINGS /qualifiers  source  destination
X;
X;`009  source:
X;
X;`009`009Device or file from which terminal characteristics are
X;`009`009read.  Specifies a terminal device when /COPY or /SAVE
X;`009`009is used, or a disk file when /RESTORE is used.
X;
X;`009  destination:
X;
X;`009`009Device or file to which terminal characteristics are
X;`009`009written.  Specifies a terminal device when /COPY or`032
X;`009`009/RESTORE is used, or a disk file when /SAVE is used.
X;
X;`009  qualifiers:
X;
X;`009`009/COPY - copy settings from "source" TERMINAL to "destination"
X;`009`009`009TERMINAL
X;
X;`009`009/SAVE - save "source" TERMINAL settings into "destination"
X;`009`009`009FILE
X;
X;`009`009/RESTORE - restore "destination" TERMINAL settings from
X;`009`009`009"source" FILE
X;
X;`009`009/PERMANENT - operate on terminal's PERMANENT characteristics
X;`009`009`009(by default, CopySettings operates on terminal's
X;`009`009`009"temporary" characteristics)
X;
X;
X;  Known Bugs:
X;
X;`009CopySettings V01.00 does not verify that a file being /RESTOREd from
X;`009was /SAVEd by CopySetting; it will "restore terminal characteristics"`0
V32
X;`009from ANY file.
X;-
X;===========================================================================
X`009.macro gen_ascid size`009; Generate ASCID string of "size" blanks
X`009savpc1 = .
X`009.ascid`009\ \
X`009.blkb`009<size-1>
X`009savpc2 = .
X`009. = savpc1
X`009.word`009size
X`009. = savpc2
X`009.endm
X;===========================================================================
X`009.psect`009data`009wrt,noexe,long
X;
X`009string_size = 255
X`009char_buf_size = 12
X;+
X; We'll use some bitwise flags to indicate the operation requested on the
X; command line: names with "_m_" are MASKS, names with "_v_" are offsets.
X;-
X`009copy_m_copy = 1`009`009`009; /COPY was specified
X`009copy_m_save = 2`009`009`009; /SAVE
X`009copy_m_restore = 4`009`009; /RESTORE
X`009copy_m_permanent = 8`009`009; /PERMANENT
X;
X`009copy_v_copy = 0
X`009copy_v_save = 1
X`009copy_v_restore = 2
X`009copy_v_permanent = 3
X;
Xfile_access:`009$FAB`009fac=<get,put>,-`009; Used with /SAVE and /RESTORE on
Vly
X`009`009`009fop=<ufo>,-
X`009`009`009org=<seq>,-
X`009`009`009alq=1
X;
Xiosb:`009`009.blkq
X;
Xcharacteristics:`009`009`009; Terminal characteristics buffer
X`009`009.blkb`00912
X;
Xsource_chan:`009.blkw
Xdest_chan:`009.blkw
X;+
X;  Following are the qualifier and parameter names parsed for us by DCL.
X;  These names must agree with those used in COPYSETTINGS.CLD.
X;-
Xcopy_qual:`009.ascid`009\COPY\
Xsave_qual:`009.ascid`009\SAVE\
Xrestore_qual:`009.ascid`009\RESTORE\
Xpermanent_qual:`009.ascid`009\PERMANENT\
Xsource_parm:`009.ascid`009\SOURCE\
Xdest_parm:`009.ascid`009\DEST\
X;
Xsource_spec:`009gen_ascid  string_size`009; Receives source device/file spec
V.
Xdest_spec:`009gen_ascid  string_size`009; Receives destination dev/file spec
V.
Xexp_source:`009gen_ascid  string_size`009; Expanded name (RMS or $GETDVI)
Xexp_dest:`009gen_ascid  string_size`009; Expanded name
X;===========================================================================
X`009.psect`009code`009nowrt,exe
X;
X`009.entry`009copysettings,`094m<>
X;+
X; Parse command-line arguments: operation to perform (copy, save, restore),
X; source, destination.  NOTE: WE RELY ON CDU TO MAKE /COPY, /SAVE, AND
X; /RESTORE MUTUALLY EXCLUSIVE.
X;-
X`009clrl`009r10`009`009`009; R10 => operation flags
X`009pushaq`009copy_qual`009`009; Was /COPY specified?
X`009calls`009#1,g`094CLI$PRESENT
X`009insv`009r0,#copy_v_copy,#1,r10`009; Set or clear COPY oper. flag`032
X`009`009`009`009`009; according to "success" bit in R0
X;
X`009pushaq`009save_qual`009`009; Was /SAVE specified?
X`009calls`009#1,g`094CLI$PRESENT
X`009insv`009r0,#copy_v_save,#1,r10`009; Set or clear SAVE oper. flag
X;
X`009pushaq`009restore_qual`009`009; Was /RESTORE specified?
X`009calls`009#1,g`094CLI$PRESENT
X`009insv`009r0,#copy_v_restore,#1,-`009; Set or clear RESTORE oper. flag
X`009`009  r10
X;
X`009pushaq`009permanent_qual`009`009; Was /PERMANENT specified?
X`009calls`009#1,g`094CLI$PRESENT
X`009insv`009r0,#copy_v_permanent,-`009; Set or clear PERMANENT oper. flag
X`009`009  #1,r10
X;
X`009pushal`009source_spec`009`009; Obtain "source" specification
X`009pushaq`009source_spec
X`009pushaq`009source_parm
X`009calls`009#3,g`094CLI$GET_VALUE
X`009blbs`009r0,10$`009`009`009; Cleared if successful
X`009jmp`009copy_err
X10$:
X`009pushal`009dest_spec`009`009; Obtain "destination" specification
X`009pushaq`009dest_spec
X`009pushaq`009dest_parm
X`009calls`009#3,g`094CLI$GET_VALUE
X`009blbs`009r0,20$
X`009jmp`009copy_err
X20$:
X;+
X; If we are doing either COPY or SAVE, we want to open a channel to a`032
X; terminal port.  Otherwise we want to open a channel to a disk file.
X; We test for the ABSENCE of the RESTORE bit, counting on the CLD defi-
X; nition to make that condition the equivalent of "SAVE!RESTORE".
X;-
X`009moval`009source_spec,r2`009`009; R2 => source string descriptor address
X`009bbc`009#copy_v_restore,r10,32$`009; Are we doing a RESTORE?
X`009`009`009`009`009;   NO:  go open channel directly
X`009`009`009`009`009;   YES: open FILE for input
X;
X`009movab`009file_access,r3`009`009; R3 => FAB base address
X;
X`009movb`009DSC$W_LENGTH(r2),FAB$B_FNS(r3)`009`009; Install input spec
X`009moval`009@DSC$A_POINTER(r2),FAB$L_FNA(r3)
X;
X`009$OPEN`009FAB=(r3)`009`009; Open the input entity
X`009blbs`009r0,30$`009`009`009; Set if successful
X`009jmp`009copy_err
X30$:
X`009movw`009FAB$L_STV(r3),-`009`009; VMS channel number to source
X`009`009  source_chan
X`009jmp`00934$
X32$:
X`009$ASSIGN_S -`009`009`009; Open channel directly for`032
X`009`009chan=source_chan,-`009;   either SAVE or COPY operations
X`009`009devnam=(r2)
X`009blbs`009r0,34$
X`009jmp`009copy_err
X34$:`009
X;+
X; If we're doing COPY or SAVE, we want to use $QIOW to get terminal charac-
X; teristics.  Otherwise we want to use it to read the first 12 bytes from
X; a disk file.
X;-
X`009bbs`009#copy_v_restore,r10,40$`009; Are we doing a RESTORE?  YES: branch
X`009movl`009#IO$_SENSEMODE,r4`009;   NO: COPY or SAVE.`032
X`009movl`009#0,r5`009`009`009;   No P3 needed for sense operation
X;
X`009bbc`009#copy_v_permanent,r10,-`009; Are we doing PERMANENT char's?
X`009`009  50$`009`009`009;   NO: branch...
X`009movl`009#IO$_SENSECHAR,r4`009;       ... around change of function
X`009brb`00950$
X40$:
X`009movl`009#IO$_READVBLK,r4`009; R4 => I/O function code; assume
X`009`009`009`009`009;   this is RESTORE.    ($QIO FUNC)
X`009movl`009#1,r5`009`009`009; R5 => VBN to read        (P3)
X50$:
X`009$QIOW_S`009func=r4,-`009`009; Function is pusha'd
X`009`009chan=source_chan,-
X`009`009iosb=iosb,-
X`009`009p1=characteristics,-`009; buffer address
X`009`009p2=#char_buf_size,-
X`009`009p3=r5`009`009`009; VBN to read, or 0 for sense
X`009blbc`009r0,55$
X`009movzwl`009iosb,r0
X`009blbs`009r0,60$
X55$:
X`009jmp`009copy_err
X60$:
X;+
X; We have terminal characteristics in the buffer; now we do pretty much the
X; same thing to write 'em OUT, with a slightly different set of conditions.
X; If we are doing either COPY or RESTORE we want to open a channel to a`032
X; terminal port.  Otherwise we want to open a channel to a disk file.
X; We should (may) be able to use RMS in both cases; what the hell,`032
X; let's TRY it before we give up...
X;
X; Note that we can hard-code this straight through, because the CLD`032
X; definition won't let the SAVE and RESTORE operations take place at the
X; same time, therefore we will never use the $FAB for input and output`032
X; at the same time.
X;
X; For output, if we're doing either COPY or RESTORE, we want to open a chann
Vel`032
X; to a terminal port.  Otherwise we want to open a channel to a disk file.
X; We test for the ABSENCE of the SAVE bit, counting on the CLD definition
X; to make that condition the equivalent of "RESTORE!COPY".`032
X;-
X`009moval`009dest_spec,r2`009`009; R2 => dest. string descriptor address
X`009bbc`009#copy_v_save,r10,72$`009; Are we doing a SAVE?
X`009`009`009`009`009;   NO:  go open channel directly
X`009`009`009`009`009;   YES: open FILE for input
X;
X`009movab`009file_access,r3`009`009; R3 => FAB base address
X;
X`009movb`009DSC$W_LENGTH(r2),FAB$B_FNS(r3)`009`009; Install input spec
X`009moval`009@DSC$A_POINTER(r2),FAB$L_FNA(r3)
X;
X`009$CREATE`009FAB=(r3)`009`009; Create the output (save) file
X`009blbs`009r0,70$`009`009`009; Set if successful
X`009jmp`009copy_err
X70$:
X`009movw`009FAB$L_STV(r3),-`009`009; VMS channel number to source
X`009`009  dest_chan
X`009jmp`00974$
X72$:
X`009$ASSIGN_S -`009`009`009; Open channel directly for`032
X`009`009chan=dest_chan,-`009;   either SAVE or COPY operations
X`009`009devnam=(r2)
X`009blbs`009r0,74$
X74$:`009
X;+
X; If we're doing COPY or RESTORE we want to use $QIOW to get terminal charac
V-
X; teristics.  Otherwise we want to use it to read the first 12 bytes from
X; a disk file.
X;-
X`009bbs`009#copy_v_save,r10,80$`009; Are we doing a SAVE? YES: branch
X`009movl`009#IO$_SETMODE,r4`009`009;   NO: COPY or RESTORE.
X`009movl`009#0,r5`009`009`009;   No P3 needed for setmode operation
X;
X`009bbc`009#copy_v_permanent,r10,-`009; Are we doing PERMANENT char's?
X`009`009  90$`009`009`009;   NO: branch...
X`009movl`009#IO$_SETCHAR,r4`009`009;       ... around change of function
X`009brb`00990$
X80$:
X`009movl`009#IO$_WRITEVBLK,r4`009; R4 => I/O function code; assume
X`009`009`009`009`009;   this is SAVE ($QIO FUNC)
X`009movl`009#1,r5`009`009`009; R5 => VBN to write (P3)
X90$:
X`009$QIOW_S`009func=r4,-`009`009; Function is pusha'd
X`009`009chan=dest_chan,-
X`009`009iosb=iosb,-
X`009`009p1=characteristics,-`009; buffer address
X`009`009p2=#char_buf_size,-
X`009`009p3=r5`009`009`009; VBN to read, or 0 for sense
X`009blbc`009r0,95$
X`009movzwl`009iosb,r0
X`009blbs`009r0,100$
X95$:
X`009jmp`009copy_err
X100$:
X;+
X; At this point, we should be done; just deassign the channels and get out
X; of here.
X;-
X`009$DASSGN_S -
X`009`009chan=source_chan
+-+-+-+-+-+-+-+-  END  OF PART 1 +-+-+-+-+-+-+-+-

