[comp.os.vms] shar

u3369429@murdu.OZ (Michael Bednarek) (06/09/87)

Hi netlanders,

There were several source postings recently.

To overcome mailing and other difficulties, especially with postings of
several files, the unix world has 'shar'.

Some VMS people have come up with 'shar's of various degrees of sophistication.

Here I give you my VMS_SHAR.COM, a procedure which creates self-unpacking
procedures.

Features:
 o The resulting file gives the username of its creator and date/time
   of creation. If the global symbol REAL_NAME exists, its content is
   also displayed.
 o The resulting file contains a list of all its files.
 o At creation time, each line is preceded by character 'X' which is
   removed at unpacking time. This is to preserve leading tabs/spaces
   through various mailers.
 o Some mailers disallow postings above a certain size. VMS_SHAR will check
   that the resulting file will not exceed MAX_PART_SIZE which is currently
   set to 31 blocks (our mailer disallows postings >16000 characters).
   If more than 31 blocks are to be posted, VMS_SHAR will create multiple
   files by appending a 'part number' to the output file name (In fact, it will
   append a 'part number' even if it creates only one file).
   If one single input file exceeds MAX_PART_SIZE the user will be notified,
   and 'part number' will be incremented such that subsequent manual splitting
   has free 'part numbers' available.
 o At both creation and unpacking time, each file is CHECKSUMmed; the result
   of the comparison of both values is displayed to the user.
   
Enjoy!

Michael Bednarek u3369429@{murdu.oz.au | xvax.dn.mu.oz.au}    "POST NO BILLS."


......................... Cut between dotted lines and save ....................
$!..............................................................................
$!
$! VAX/VMS archive file created by VMS_SHAR Version:'09-Jun-1987'
$! Copyright (c) 1987, by Michael Bednarek
$! To unpack, simply execute (@) the file.
$! This archive was created by U3369429 (Michael Bednarek)
$!      on Tuesday 9-JUN-1987 20:13:46.19
$! It contains the following file(s):
$! VMS_SHAR.COM
$!==============================================================================
$ Set Symbol/Scope=(NoLocal,NoGlobal)
$ 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:Open/Write Out 'File_is
$ Open/Read In VMS_SHAR_DUMMY.DUMMY
$Next_Record: Read/End_Of_File=EOF In Record
$ Write Out F$Extract(1,255,Record)
$ Goto Next_Record
$EOF: Close Out
$ Close In
$ 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=957769911
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X$! VMS_SHAR.COM
X$! 09-Jun-1987 Michael Bednarek (u3369429@murdu.oz.au)
X$! Copyright (c) 1987, by Michael Bednarek
X$! The distribution of this file is unrestricted as long as this notice
X$! remains intact.
X$!
X$! Usage: @VMS_SHAR file[,file...]  sharfile
X$!   where file spec can include wild-cards. File names are separated by commas.
X$!
X$ BEL[0,7]=7
X$ nPart="01"
X$ MAX_PART_SIZE=31	! 31 blocks will keep us below 16000 bytes
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$ File_List=P1
X$ Shar_File=P2
X$ If File_List.eqs."" then Inquire File_List "_File(s)"
X$ If File_List.eqs."" then Exit
X$ If Shar_File.eqs."" then Inquire Shar_File "_Output"
X$ If Shar_File.eqs."" then Exit
X$!
X$ User=F$Edit(F$GetJPI("","USERNAME"),"COLLAPSE")
X$ If F$Type(Real_Name).nes."" then User=User+" ("+Real_Name+")"
X$ Set Symbol/Scope=(NoLocal,NoGlobal)
X$ Time=F$CVTime(,"Absolute","DateTime")
X$ Time=F$CVTime(Time,,"Weekday")+" "+Time
X$!
X$ On Control_Y then goto Abort
X$ On Error then Continue
X$!
X$ Copy SYS$Input 'Shar_File''nPart
X$ Deck/Dollars="INTRO_EOF" 
X......................... Cut between dotted lines and save ....................
X$!..............................................................................
X$!
X$! VAX/VMS archive file created by VMS_SHAR Version:'09-Jun-1987'
X$! Copyright (c) 1987, by Michael Bednarek
X$! To unpack, simply execute (@) the file.
XINTRO_EOF
X$ Part_Size=0
X$ nParts=1
X$ Files=""
X$ Open/Append Out 'Shar_File''nPart
X$ Write Out "$! This archive was created by ''User'"
X$ Write Out "$!      on ''Time'"
X$ Write Out "$! It contains the following file(s):"
X$ nE=-1
X$ nF=1
X$Next_Element:
X$ nF=nF-1
X$ nE=nE+1
X$ Element=F$Element(nE,",",File_List)
X$ If Element.eqs."," then goto Elements_Done
X$ Previous_File=""
X$!
X$Next_File:
X$ nF=nF+1
X$ File=F$Search(Element)
X$ If File.eqs."" .or. File.eqs.Previous_File then goto Next_Element
X$ Previous_File=File
X$ File'nF=F$Parse(File,,,"NAME")+F$Parse(File,,,"TYPE")
X$ Name=File'nF
X$ Write SYS$Output "looking at ",Name
X$ Size'nF=F$File_Attributes(Name,"EOF")
X$ Part_Size=Part_Size+Size'nF
X$ If Part_Size.le.MAX_PART_SIZE then goto Same_Part0
X$ nParts=nParts+1
X$ Part_Size=0
X$Same_Part0:
X$ If F$Length(Files)+F$Length(Name).le.77 then goto Same_Line
X$ Write Out "$!",Files
X$ Files=""
X$Same_Line:
X$ Files=Files+" "+Name
X$ Goto Next_File
X$!
X$Elements_Done:
X$ If Files.nes."" then Write Out "$!",Files
X$ If nParts.eq.1 then goto Only_One
X$ Write Out F$FAO("$!!!78*=")
X$ Write Out "$! ATTENTION: To keep each article below ", -
X	F$Integer(MAX_PART_SIZE*512)," bytes, this program"
X$ Write Out "$!            has been transmitted in several parts."
X$ Write Out "$! You should concatenate ALL parts to ONE file and execute ", -
X	"(@) that file."
X$Only_One:
X$ Close Out
X$ Append SYS$Input 'Shar_File''nPart
X$ Deck/Dollars="SUBROUTINE_EOF" 
X$!==============================================================================
X$ Set Symbol/Scope=(NoLocal,NoGlobal)
X$ 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:Open/Write Out 'File_is
X$ Open/Read In VMS_SHAR_DUMMY.DUMMY
X$Next_Record: Read/End_Of_File=EOF In Record
X$ Write Out F$Extract(1,255,Record)
X$ Goto Next_Record
X$EOF: Close Out
X$ Close In
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$!
X$ n=0
X$Extract_Next:
X$ n=n+1
X$ Name=File'n
X$ Part_Size=F$File_Attributes("''Shar_File'''nPart'","EOF")+Size'n
X$ If Part_Size.le.MAX_PART_SIZE then goto Same_Part1
X$ nPart=F$FAO("!2ZL",F$Integer(nPart)+1)
X$ If Size'n.le.MAX_PART_SIZE then goto Fits
X$ Write SYS$Output BEL
X$ Write SYS$Output "The file ",Name," is ",F$Integer(Size'n-MAX_PART_SIZE),-
X	" blocks larger than MAX_PART_SIZE."
X$ Write SYS$Output "You will have to carve up that file manually."
X$ Write SYS$Output "I'll attempt to increment the part number appropriately"
X$ Current_Part=F$Integer(nPart)
X$ nPart=F$FAO("!2ZL",F$Integer(Size'n/MAX_PART_SIZE)+Current_Part)
X$ Current_Part=F$FAO("!2ZL",Current_Part)
X$ Write SYS$Output "The file ''Shar_File'''nPart' should be split into"
X$ Write SYS$Output "''Shar_File'''Current_Part' to ''Shar_File'''nPart'."
X$ Write SYS$Output BEL
X$Fits:
X$ Write SYS$Output "Now writing to ''Shar_File'''nPart'"
X$ Copy NL: 'Shar_File''nPart
X$Same_Part1:
X$ Write SYS$Output "appending ",Name
X$ Open/Append Out 'Shar_File''nPart
X$ Write Out "$ File_is=""''Name'"""
X$ Checksum 'Name
X$ Write Out "$ Check_Sum_is=''CHECKSUM$CHECKSUM'"
X$ Write Out "$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY"
X$ Open/Read In 'Name
X$Next_Record:
X$ Read/End_Of_File=EOF In Record
X$ Write Out "X",Record
X$ Goto Next_Record
X$EOF:
X$ Close In
X$ Write Out "$ GoSub Convert_File"
X$ Close Out
X$ If n.lt.nF then goto Extract_Next
X$ Write SYS$Output -
X	F$FAO("SHAR-file was written in !SL part!%S",F$Integer(nPart))
X$ Exit
X$!
X$Abort:
X$ Close/Error=Anyway Out
X$Anyway:
X$ Exit
$ GoSub stiorimerimer

u3369429@murdu.OZ (Michael Bednarek) (06/30/87)

Hi netlanders!
 
Three weeks ago, I published my VMS_SHAR procedure.

This prompted a lot of useful reactions from you. So I went back to the
drawing board and re-wrote it. Not all suggestions have been implemented, yet.

Blurb and history are included in the procedure itself.
 
Michael Bednarek u3369429@{murdu.oz.au | xvax.dn.mu.oz.au}    "POST NO BILLS."
 
....................... Cut between dotted lines and save ......................
$!..............................................................................
$! VAX/VMS archive file created by VMS_SHAR V-3.06 30-Jun-1987
$! 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 U3369429 (Michael Bednarek)
$!      on Tuesday 30-JUN-1987 17:19:59.44
$!
$! It contains the following 1 file:
$! VMS_SHAR.COM
$!==============================================================================
$ Set Symbol/Scope=(NoLocal,NoGlobal)
$!See what VMS version we have here:
$ 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/EDT/NoJournal/Output='File_is' VMS_SHAR_DUMMY.DUMMY
Set Quiet; Change; 32000(D+C L)
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=992556736
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X$ Verify='F$Verify(0)
X$ Facility_Name=	"VMS_SHAR"
X$ Facility_Version=	"V-3.06 30-Jun-1987"
X$!
X$ SS$_Abort=44
X$ On Control_Y then goto Abort
X$ On Error then Continue
X$!
X$!Michael Bednarek		u3369429@{murdu.oz.au | ucsvc.dn.mu.oz.au}
X$!Institute of Applied Economic	-- or --
X$!  and Social Research (IAESR)	...seismo.CSS.GOV!munnari!
X$!Melbourne University		   {murdu.oz | ucsvc.dn.mu.oz}!u3369429
X$!Parkville 3052, Phone : +61 3 344 5744
X$!AUSTRALIA
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$!
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$ Goto Start
X$Abort:
X$ Close/Error=Anyway Out
X$Anyway:
X$ Exit SS$_Abort
X
XREAD_ME:
X
XFeatures:
X o Through the use of SET SYMBOL/SCOPE=(NOLOCAL,NOGLOBAL) both VMS_SHAR
X   and the procedures created by it are very rubust against local
X   idiosyncrasies with symbols. Imagine a user who does: IF=="!" !
X o The resulting file gives the username of its creator and date/time
X   of creation. If the global symbol REAL_NAME exists, its content is
X   also displayed.
X o The resulting file contains a list of all its files.
X o At creation time, each line is preceded by character 'X' which is
X   removed at unpacking time. This is to preserve leading tabs/spaces
X   through various mailers.
X o Some mailers disallow postings above a certain size. VMS_SHAR will check
X   that the resulting file will not exceed MAX_PART_SIZE which is currently
X   set to 31 blocks (our mailer disallows postings >16000 characters).
X   If more than 31 blocks are to be posted, VMS_SHAR will create multiple
X   files by appending a 'part number' to the output file name.
X   If one single input file exceeds MAX_PART_SIZE the user will be notified,
X   and 'part number' will be incremented such that subsequent manual splitting
X   has free 'part numbers' available.
X o At both creation and unpacking time, each file is CHECKSUMmed; the result
X   of the comparison of both values is displayed to the user.
X o Signatures and such, which might occur at the end of each part, don't
X   need to be stripped. They are skipped by the unpacking procedure.
X o The created procedure will check for VMS version 4.4 or higher.
X
XAbout Version 2.00:
X   Mainly a cleaning-up re-write. Fixed the case where full pathnames were
X   given. Also checks now whether the output filename is among the input
X   filenames.
X   The procedure now performs in two distinct steps:
X   a) collecting file names and their size information,
X   b) actually packaging the files.
X   This allows to include an indication of the number of parts at the top
X   of the resulting file. It also allows to omit part-suffixes if not required.
X   However, under rare circumstances this might not work.
X   One condition which springs to mind where it doesn't work is:
X   You package two files, the first one 30 blocks, the second 1 block.
X   Let's call the difference between 512 and the number of bytes which are
X   actually used in the first file's last block "spare bytes".
X   If the number of lines in the first file is greater than 512+"spare bytes",
X   then VMS_SHAR will attempt to create a filename for part 2, but it has not
X   been properly initialised and will fail. Well, not really. It will complain
X   about an unknown symbol "I", and will not append its version suffixes, but
X   will still create the files, only using standard VMS version increments.
X
X   Another case which is insufficiently handled is when one single file
X   exceeds MAX_PART_SIZE. The whole numbering scheme gets out of kilter
X   and the packager is left with a renaming task.
X
XAbout Version 3.00:
X   I had some discussions with usenet members, particularly with
X   Ed <MCGUIRE@GRIN2.BITNET> about trailing white space.
X   He suggested to use a length count at the beginning of each line, and to
X   split lines longer than 80 characters and restore them at the receiving
X   site.
X   I didn't follow that suggestion for three reasons:
X   1. The unix shar doesn't cater for this either.
X   2. It would have increased processing time a lot.
X   3. I didn't ever experience serious difficulties due to lost trailing
X      white space.
X
X   However, it was Ed who came up with a method to use EDT to insert/remove
X   those leading "X"s. As this turned out to be 3 times faster than my
X   previous method (OPEN/READ/lexical function/WRITE) this was implemented
X   in version 3.00
X
X   Some days later, after some more good arguments and examples from Ed:
X   OK, I'm convinced that splitting lines is a good idea.
X   However, this will take some time to implement as it needs to be done
X   in TPU and I'm a complete TPU agnostic. But that's what producing these
X   toys is all about, no? Playful learning.
X
X   The created procedure will now have "Goto <next part>" at the end of
X   each part and "Exit" as its last statement. This should take care of
X   signatures which might occur at the end of each part.
X
X$Start:	
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$ 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$!
X$ MAX_PART_SIZE=31	! 31 blocks will keep us below 16000 bytes
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$!
X$ BEL[0,7]=7
X$ Say="Write SYS$Output"
X$ Say Facility_Name," ",Facility_Version
X$ Say ""
X$!
X$! Collect all filenames
X$ nParts=1
X$ Part_Size=0
X$ nE=-1
X$ nF=1
X$Next_Element:
X$ nF=nF-1
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$!
X$Next_File:
X$ 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	Say "%VMS_SHAR-I-FNF, file not found: ",Element
X$ Goto Next_Element
X$Look:
X$ 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:
X$ 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=0
X$ Goto Next_File
X$!
X$Elements_Done:
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$!
X$Intro:
X$ Time=F$CVTime(,,"Weekday")+" "+F$CVTime(,"Absolute","DateTime")
X$!
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	! i=LOG10(nParts)+1
X$ If nParts.gt.9 then i=2
X$ If nParts.gt.99 then i=3	! We don't expect more than 999 files
X$ Part_Name=F$FAO("!#ZL",i,1)
X$Only_One1:
X$ Copy NL: 'Shar_File''Part_Name''Of_Name
X$ Open/Append Out 'Shar_File''Part_Name''Of_Name
X$ Write Out F$FAO("!23*. Cut between dotted lines and save !22*.")
X$ Write Out F$FAO("$!!!78*.")
X$ Write Out "$! VAX/VMS archive file created by ",Facility_Name," ", -
X		Facility_Version
X$ Write Out "$! which was written by Michael Bednarek ",-
X		"(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	F$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	"(@) that file."
X$ Write Out "$!"
X$!
X$Only_One2:
X$ Write Out F$FAO("$!! It contains the following !UL file!%S:",nF)
X$!
X$ Files=""
X$ n=0
X$Next_Name:
X$ n=n+1
X$ Name=F$Parse(File'n,,,"NAME")+F$Parse(File'n,,,"TYPE")
X$ If F$Length(Files)+F$Length(Name).le.77 then goto Same_Line
X$ Write Out "$!",Files
X$ Files=""
X$Same_Line:
X$ Files=Files+" "+Name
X$ If n.lt.nF then Goto Next_Name
X$!
X$ Write Out "$!",Files
X$ Close Out
X$ Append SYS$Input 'Shar_File''Part_Name''Of_Name
X$ Deck/Dollars="SUBROUTINE_EOF" 
X$!==============================================================================
X$ Set Symbol/Scope=(NoLocal,NoGlobal)
X$!See what VMS version we have here:
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/EDT/NoJournal/Output='File_is' VMS_SHAR_DUMMY.DUMMY
XSet Quiet; Change; 32000(D+C L)
XExit
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$!
X$ n=0
X$Extract_Next:
X$ n=n+1
X$ Name=F$Parse(File'n,,,"NAME")+F$Parse(File'n,,,"TYPE")
X$ Part_Size=F$File_Attributes("''Shar_File'''Part_Name'''Of_Name'","EOF")+Size'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$ Part_Name=F$FAO("!#ZL",i,F$Integer(Part_Name)+1)
X$ 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	" 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:
X$ Write Out "$ Goto Part''Part_name'"
X$ Close Out
X$ Say ""
X$ Say "Now writing to ",Shar_File,Part_Name,Of_Name
X$ Copy NL: '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:
X$ Say "appending ",File'n
X$ If F$TRNLNM("Out").eqs."" then Open/Append Out 'Shar_File''Part_Name''Of_Name
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$ Define/User_Mode SYS$Output NL:
X$ EDIT/EDT/NoJournal/Output=VMS_SHAR_DUMMY.DUMMY &File'n
XSet Quiet; Change; ER -L 32000(88ASC -2L)
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$ Say F$FAO("SHAR-file ''Shar_File' was written in !SL part!%S",-
X	F$Integer(nParts))
X$ Directory/Size=Used/Date=Created 'Shar_File'*
X$ Verify=F$Verify(Verify)
$ GoSub Conve.

.

./Dolingl