From:	CSBVAX::MRGATE!RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP 23-AUG-1988 22:32
To:	ARISIA::EVERHART
Subj:	VMS_SHAR V5.04 part 1/2


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Mon, 22 AUG 88 22:54:31 PDT
Received: from godot.psc.edu by KL.SRI.COM with TCP; Mon, 22 Aug 88 22:52:56 PDT
Received: by godot.psc.edu (5.51/umd.04)
        id AA08458; Tue, 23 Aug 88 01:52:11 EDT
Date: Tue, 23 Aug 88 01:52:11 EDT
From: David Gentzel <gentzel@godot.psc.edu>
Message-Id: <8808230552.AA08458@godot.psc.edu>
To: info-vax@kl.sri.com
Subject: VMS_SHAR V5.04 part 1/2

I've had several requests so here it is, the last (so far as I know) version
of VMS_SHAR.  The author has left Melbourne University and is no longer
maintaining it (although he can apparently answer mail).

I had a few people ask me NOT to post as they felt it had been posted
recently.  I think they are wrong.  VMS_SHARE was recently posted, but it
is not (quite) the same.

					Dave Gentzel
					Pittsburgh Supercomputing Center
					gentzel@godot.psc.edu
					or gentzel@morgul.psc.edu

$!...................... Cut on the dotted line and save ......................
$! VAX/VMS archive file created by VMS_SHAR V-5.04 04-Feb-1988
$! which was written by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au)
$! To unpack, simply save and execute (@) this file.
$!
$! This archive was created by GENTZEL
$! on Tuesday 23-AUG-1988 01:42:33.47
$!
$! ATTENTION: To keep each article below 15872 bytes, this program
$! has been transmitted in 2 parts.
$! You should concatenate ALL parts to ONE file and execute (@) that file.
$!
$! It contains the following 2 files:
$! VMS_SHAR.COM VMS_SHAR.READ_ME
$!=============================================================================
$Set Symbol/Scope=(NoLocal,NoGlobal)
$Version=F$GetSYI("VERSION")
$If Version.ges."V4.4" then goto Version_OK
$Write SYS$Output "Sorry, you are running VMS ",Version, -
", but this procedure requires V4.4 or higher."
$Exit 44
$Version_OK:CR[0,8]=13
$Pass_or_Failed="failed!,passed."
$Goto Start
$Convert_File:
$Read/Time_Out=0/Error=No_Error1/Prompt="creating ''File_is'" SYS$Command ddd
$No_Error1:Define/User_Mode SYS$Output NL:
$Edit/TPU/NoSection/NoDisplay/Command=SYS$Input/Output='File_is' -
VMS_SHAR_DUMMY.DUMMY
f:=Get_Info(Command_Line,"File_Name");b:=Create_Buffer("",f);
o:=Get_Info(Command_Line,"Output_File");Set(Output_File,b,o);
Position(Beginning_of(b));Loop x:=Erase_Character(1);Loop ExitIf x<>"V";
Move_Vertical(1);x:=Erase_Character(1);Append_Line;
Move_Horizontal(-Current_Offset);EndLoop;Move_Vertical(1);
ExitIf Mark(None)=End_of(b) EndLoop;Position(Beginning_of(b));Loop
x:=Search("`",Forward,Exact);ExitIf x=0;Position(x);Erase_Character(1);
If Current_Character='`' then Move_Horizontal(1);else
Copy_Text(ASCII(INT(Erase_Character(3))));EndIf;EndLoop;Exit;
$Delete VMS_SHAR_DUMMY.DUMMY;*
$Checksum 'File_is
$Success=F$Element(Check_Sum_is.eq.CHECKSUM$CHECKSUM,",",Pass_or_Failed)+CR
$Read/Time_Out=0/Error=No_Error2/Prompt=" CHECKSUM ''Success'" SYS$Command ddd
$No_Error2:Return
$Start:
$File_is="VMS_SHAR.COM"
$Check_Sum_is=2067076356
$Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X$ Verify=F$Verify(F$TRNLNM("COMMAND_DEBUG"))
X$ Facility_Name=`009"VMS_SHAR"
X$ Facility_Version=`009"V-5.04 04-Feb-1988"
X$!
X$ SS$_Abort=44
X$ On Control_Y then goto Abort
X$ On Error then Continue
X$!
X$!Michael Bednarek`009`009u3369429@{murdu.oz.au | ucsvc.dn.mu.oz.au}
X$!Institute of Applied Economic
X$!  and Social Research (IAESR) ...UUNET!munnari!murdu!u3369429
X$!Melbourne University
X$!Parkville 3052`009`009mb@munnari.oz.au
X$!AUSTRALIA  Phone: +61 3 344 5744
X$!
X$! Copyright (c) 1987, by Michael Bednarek
X$! The distribution of this file is unrestricted as long as this notice
X$! remains intact.
X$! Credits: SLOANE@UKANVAX@BITNET (Bob Sloane) for the idea of
X$!`009    quoting control characters.
X$!
X$! Usage: @VMS_SHAR file[,file...] sharfile
X$! where ``file' are file names, separated by commas, possibly including
X$! wild-card characters, of those files that are to be packaged.
X$! sharfile is the resulting self-unpacking archive file.
X$! VAX/VMS version 4.4 or higher
X$!
X$ User=F$Edit(F$GetJPI("","USERNAME"),"COLLAPSE")
X$ If F$Type(Real_Name).nes."" then User=User+" ("+Real_Name+")"
X$ Set="Set"
X$ Set Symbol/Scope=(NoLocal,NoGlobal)
X$ Say="Write SYS$Output"
X$ Say Facility_Name," ",Facility_Version
X$ Say ""
X$ If P1.eqs."" then Inquire P1 "_File(s) to package"
X$ If P1.eqs."" then Exit SS$_Abort
X$ If P2.eqs."" then Inquire P2 "_Output Archive"
X$ If P2.eqs."" then Exit SS$_Abort
X$ File_List=P1
X$ Shar_File=F$Parse(P2)-";"
X$ MAX_PART_SIZE=31`009! 31 blocks will keep us below 16000 bytes
X$ x=F$Integer(F$TRNLNM("SHAR_MAX_SIZE"))! Allow the user to override
X$ If x.gt.1 then MAX_PART_SIZE=x`009! this parameter
X$ Say "MAX_PART_SIZE is defined as ",MAX_PART_SIZE," blocks."
X$ Say ""
X$! As this procedure adds a 'X' in the first position of every line, the
X$! resulting file can still become larger than MAX_PART_SIZE
X$ BEL[0,7]=7
X$ nParts=1
X$ Part_Size=5 ! startup code, erring on the conservative side
X$ Surprise="False"
X$ nE=-1
X$ nF=1
X$Next_Element: nF=nF-1 ! Collect all filenames
X$ nE=nE+1
X$ Element=F$Element(nE,",",File_List)
X$ If Element.eqs."," then goto Elements_Done
X$ Previous_File="no file"
X$Next_File: nF=nF+1
X$ File'nF=F$Search(Element)
X$ If File'nF.eqs.Previous_File then goto Next_Element
X$ If File'nF.nes."" then goto Look
X$ If Previous_File.eqs."no file" then -
X`009Say "%VMS_SHAR-I-FNF, file not found: ",Element
X$ Goto Next_Element
X$Abort: Close/Error=Anyway Out
X$Anyway:Exit SS$_Abort
X$Look: Previous_File=File'nF
X$ Say "looking at ",File'nF
X$ If F$Element(0,";",File'nF).nes.Shar_File then goto Not_Silly
X$ Say "You can't have your outputfile among the input files!"
X$ Exit SS$_Abort
X$Not_Silly: Size'nF=F$File_Attributes(File'nF,"EOF")
X$ Part_Size=Part_Size+Size'nF
X$ If Part_Size.le.MAX_PART_SIZE then goto Next_File
X$ nParts=nParts+1
X$ Part_Size=Size'nF
X$ Goto Next_File
X$Elements_Done: Say ""
X$ If nF.gt.0 then goto Intro
X$ Say "%VMS_SHAR-W-SEARCHFAIL, error searching for ",P1
X$ Say "-VMS_SHAR-E-FNF, file not found. No file to package. Nothing done."
X$ Exit SS$_Abort
X$Intro: Time=F$CVTime(,,"Weekday")+" "+F$CVTime(,"Absolute","DateTime")
X$ Part_Name=""
X$ Of_Name=""
X$ If nParts.lt.2 then goto Only_One1
X$ Of_Name=F$FAO("_OF_!ZL",nParts)
X$ i=1`009! i=LOG10(nParts)+1
X$ If nParts.gt.9 then i=2
X$ If nParts.gt.99 then i=3`009! We don't expect more than 999 files
X$ Part_Name=F$FAO("!#ZL",i,1)
X$Only_One1: Create 'Shar_File''Part_Name''Of_Name
X$ Say "Now writing to ",Shar_File,Part_Name,Of_Name
X$ Open/Append Out 'Shar_File''Part_Name''Of_Name
X$ Write Out F$FAO("$!!!22*. Cut on the dotted line and save !22*.")
X$ Write Out "$! VAX/VMS archive file created by ",Facility_Name," ", -
X`009Facility_Version
X$ Write Out "$! which was written by Michael Bednarek ",-
X`009"(U3369429@ucsvc.dn.mu.oz.au)"
X$ Write Out "$! To unpack, simply save and execute (@) this file.
X$ Write Out "$!"
X$ Write Out "$! This archive was created by ''User'"
X$ Write Out "$! on ''Time'"
X$ Write Out "$!"
X$ If nParts.lt.2 then goto Only_One2
X$ Write Out "$! ATTENTION: To keep each article below ", -
X`009F$Integer(MAX_PART_SIZE*512)," bytes, this program"
X$ Write Out "$! has been transmitted in ",nParts," parts."
X$ Write Out "$! You should concatenate ALL parts to ONE file and execute ", -
X`009"(@) that file."
X$ Write Out "$!"
X$Only_One2: Write Out F$FAO("$!! It contains the following !UL file!%S:",nF)
X$ Files=""
X$ n=0
X$Next_Name: n=n+1
X$ Name=F$Parse(File'n,,,"NAME")+F$Parse(File'n,,,"TYPE")
X$ If F$Length(Files)+F$Length(Name).le.76 then goto Same_Line
X$ Write Out "$!",Files
X$ Files=""
X$Same_Line: Files=Files+" "+Name
X$ If n.lt.nF then Goto Next_Name
X$ Write Out "$!",Files
X$ Write Out F$FAO("$!!!77*=")
X$ Close Out
X$ Append SYS$Input 'Shar_File''Part_Name''Of_Name
X$ Deck/Dollars="SUBROUTINE_EOF"
X$Set Symbol/Scope=(NoLocal,NoGlobal)
X$Version=F$GetSYI("VERSION")
X$If Version.ges."V4.4" then goto Version_OK
X$Write SYS$Output "Sorry, you are running VMS ",Version, -
X", but this procedure requires V4.4 or higher."
X$Exit 44
X$Version_OK:CR[0,8]=13
X$Pass_or_Failed="failed!,passed."
X$Goto Start
X$Convert_File:
X$Read/Time_Out=0/Error=No_Error1/Prompt="creating ''File_is'" SYS$Command ddd
X$No_Error1:Define/User_Mode SYS$Output NL:
X$Edit/TPU/NoSection/NoDisplay/Command=SYS$Input/Output='File_is' -
XVMS_SHAR_DUMMY.DUMMY
Xf:=Get_Info(Command_Line,"File_Name");b:=Create_Buffer("",f);
Xo:=Get_Info(Command_Line,"Output_File");Set(Output_File,b,o);
XPosition(Beginning_of(b));Loop x:=Erase_Character(1);Loop ExitIf x<>"V";
XMove_Vertical(1);x:=Erase_Character(1);Append_Line;
XMove_Horizontal(-Current_Offset);EndLoop;Move_Vertical(1);
XExitIf Mark(None)=End_of(b) EndLoop;Position(Beginning_of(b));Loop
Xx:=Search("``",Forward,Exact);ExitIf x=0;Position(x);Erase_Character(1);
XIf Current_Character='``' then Move_Horizontal(1);else
XCopy_Text(ASCII(INT(Erase_Character(3))));EndIf;EndLoop;Exit;
X$Delete VMS_SHAR_DUMMY.DUMMY;*
X$Checksum 'File_is
X$Success=F$Element(Check_Sum_is.eq.CHECKSUM$CHECKSUM,",",Pass_or_Failed)+CR
X$Read/Time_Out=0/Error=No_Error2/Prompt=" CHECKSUM ''Success'" SYS$Command ddd
X$No_Error2:Return
X$Start:
XSUBROUTINE_EOF
X$ n=0
X$Extract_Next: n=n+1
X$ Name=F$Parse(File'n,,,"NAME")+F$Parse(File'n,,,"TYPE")
V$ Part_Size=F$File_Attributes("''Shar_File'''Part_Name'''Of_Name'","EOF")+Size
X'n
X$ If Part_Size.le.MAX_PART_SIZE then goto Same_Part1
X$ Open/Append Out 'Shar_File''Part_Name''Of_Name
X$! Warning: this will not work if in the course of packaging the files it
X$! turns out that by adding all those "X"s an archive suddenly needs more than
X$! one part. The probability for this is rather low, though, because the
X$! combined files are on average 256*(Number of files) bytes shorter than
X$! their individual block numbers added.
X$ If F$Type(i).nes."" then goto No_Surprise
X$ Surprise="True"
X$ Goto Surprise
X$No_Surprise: Part_Name=F$FAO("!#ZL",i,F$Integer(Part_Name)+1)
X$Surprise: If Size'n.le.MAX_PART_SIZE then goto Fits
X$ Say ""
X$ Say "The file ",File'n
X$ Say "is ",F$Integer(Size'n-MAX_PART_SIZE),-
X`009" blocks larger than MAX_PART_SIZE.",BEL
X$ Say "You will have to carve up that file manually."
X$ Say "I'll attempt to increment the part number appropriately"
X$ Current_Part=F$Integer(Part_Name)
X$ Part_Name=F$FAO("!#ZL",i,F$Integer(Size'n/MAX_PART_SIZE)+Current_Part)
X$ Current_Part=F$FAO("!#ZL",i,Current_Part)
X$ Say "The file ",Shar_File,Part_Name,Of_Name," should be split into",BEL
X$ Say Shar_File,Current_Part,Of_Name," to ",Shar_File,Part_Name,Of_Name
X$ Say "NOTE: the common suffix ",Of_Name," is now also wrong."
X$ Say "I'm afraid you have to rename all files manually."
X$ Read/End_of_File=Fits/Prompt="Enter <RETURN> to continue " SYS$Command ddd
X$Fits: Write Out "$Goto Part''Part_name'"
X$ Close Out
X$ Say ""
X$ Say "Now writing to ",Shar_File,Part_Name,Of_Name
X$ Create 'Shar_File''Part_Name''Of_Name
X$ Open/Append Out 'Shar_File''Part_Name''Of_Name
X$ Write Out "$Part''Part_Name':"
X$Same_Part1: Say "appending ",File'n
V$ If F$TRNLNM("Out").eqs."" then Open/Append Out 'Shar_File''Part_Name''Of_Nam
Xe
X$ Write Out "$File_is=""''Name'"""
X$ Checksum &File'n
X$ Write Out "$Check_Sum_is=''CHECKSUM$CHECKSUM'"
X$ Write Out "$Copy SYS$Input VMS_SHAR_DUMMY.DUMMY"
X$ Close Out
X$ If .not.F$Verify() then Define/User_Mode SYS$Output NL:
X$ Edit/TPU/NoSection/NoDisplay/Command=SYS$Input/Output=VMS_SHAR_DUMMY.DUMMY -
X`009&File'n
Xf:=0;`009`009! Initialise variable for ASCII decimals,
Xk:="";`009`009! and a string which will contain all control characters,
Xa:="";`009`009! and a string which will contain all ASCII characters.
XLoop`009`009! Construct a string with all control characters.
X ExitIf f>255;`009! Highest ASCII decimal.
X x:=ASCII(f);`009! Generate a character
X If (f<32) or (f>126) then`009! Control characters
X  k:=k+x;`009`009`009! go into "k".
X EndIf;`009`009`009`009! All characters
X a:=a+x;`009`009`009! go into "a".
X f:=f+1;`009`009! Increment ASCII decimal.
XEndLoop;
Xkp:=Any(k);`009! Use "k" as a pattern for incremental search.
X
Xf:=Get_Info(Command_Line,"File_Name");
Xb:=Create_Buffer("",f);
XSet(Output_File,b,File_Parse(Get_Info(Command_Line,"Output_File")));
XPosition(Beginning_of(b));
Xq:="``" & (ARB(1)|Line_End);`009`009! Pattern for quotes
X! This pattern may seem elaborate, but it allows positioning AFTER the quote,
X! so we don't have to skip it.
XLoop
X x:=Search(q,Forward,Exact);`009`009! First, quote all quotes.
X Exitif x=0;`009`009`009`009! No (more) quotes.
X Position(End_of(x));`009`009`009! Position after the quote,
X Copy_Text("``");`009`009`009! insert another quote,
XEndLoop;
X
XPosition(Beginning_of(b));
XLoop`009`009`009`009! Secondly, replace all control characters
X x:=Search(kp,Forward,Exact);`009! with their quoted decimal ASCII values.
X ExitIf x=0;`009`009`009! No (more) control characters.
X Position(x);`009`009`009! Position on the control character,
X! erase it, search for it in "a", and use the found position-1 to
X! write its ASCII value, preceded by a "``".
X Copy_Text("``"+FAO("!3ZL",Index(a,Erase_Character(1))-1)); ! (Too compact?)
XEndLoop;
X
XPosition (Beginning_of(b));
XLoop`009`009`009`009`009! Thirdly, all lines longer than 78
X If Length(Current_Line)>78 then`009! characters (just to be safe) are
X  Copy_Text("V");`009`009`009! prepended with a "V"
X  Move_Horizontal(78);`009`009`009! and
X  Split_Line;`009`009`009`009! split.
X else`009`009`009`009`009! Shorter lines are
X  Copy_Text("X");`009`009`009! prepended with a "X"
X  Move_Horizontal(-1);`009`009`009! (which moves our position)
X  Move_Vertical(1);`009`009`009! and we advance to the next line.
X EndIf;
X ExitIf Mark(None)=End_of(b);
XEndLoop;
XExit;
X$ Append VMS_SHAR_DUMMY.DUMMY 'Shar_File''Part_Name''Of_Name
X$ Delete VMS_SHAR_DUMMY.DUMMY;*
X$ Append SYS$Input 'Shar_File''Part_Name''Of_Name
X$ Deck/Dollars="Just_1"
X$GoSub Convert_File
XJust_1
X$ If n.lt.nF then goto Extract_Next
X$ Append SYS$Input 'Shar_File''Part_Name''Of_Name
X$ Deck/Dollars="The End"
X$Exit
XThe End
X$ If Surprise then Part_Name="2"
X$ If Part_Name.eqs."" then Part_Name="1"
X$ If .not.Surprise .and. nParts.eq.F$Integer(Part_Name) then goto No_Part_Warn
X$ Say "ATTENTION:",BEL
X$ Say "Unfortunately, it turns out that the initial estimate about the number"
X$ Say "of shar-files was wrong."
X$ If Part_Name.eqs."" then Part_Name="2"
X$ Say F$FAO("Instead of !SL part!%S there are really ''Part_Name'.",nParts)
X$ nParts=F$Integer(Part_Name)
X$No_Part_Warn:
X$ Say F$FAO("SHAR-file ''Shar_File' was written in !SL part!%S",nParts)
X$ Directory/Size=Used/Date=Created 'Shar_File'*
X$ Verify=F$Verify(Verify)
$GoSub Convert_File
$Goto Part2

