$! ------------------ CUT HERE ----------------------- $! $! This archive created by VMS_SHARE Version 7.1-001 26-JUN-1989 $! On 6-JUL-1989 14:05:34.76 By user UDAA055 $! $! 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 6 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. PAKMAIL.COM;10 $! 2. PAKMAIL.HLP;4 $! 3. TEST.TXT;1 $! 4. VMS_SHARE.COM;50 $! 5. VMS_SHARE.HLP;6 $! 6. VMS_SHARE.RELEASE_NOTES;15 $! 7. VMS_SHARE.TECHNICAL_INFO;10 $! $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. "4.4" then $ goto START $ e "-E-OLDVER, Must run at least VMS 4.4" $ 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' X$! Purpose: X$!`009To mail out a series of files produced by VMS_SHARE to a series X$!`009of recipients. X$! X$! Parameters: X$! X$!`009P1 = name (or list ) of recipient(s). Can be logical or distribution X$! list. X$! X$!`009`009If sending to a distribution list, it is necessary to define X$!`009`009a logical pointing to the file and then give that logical as X$!`009`009the recipient name. This avoids problems with DCL's handling X$!`009`009of quotes and '@' symbols. X$! X$! X$!`009P2 = file spec of package - "`091directory`093file" without VMS_SHARE V suffix! X$! X$! X$!`009P3 = no of parts of the package X$ X$! `009`009This procedure adds the VMS_SHARE suffix and sends files X$!`009`009called "`091directory`093file''nn'" nn from 1-> 'P3' X$ X$!`009P4 = Comment to add to mail subject line X$ X$ X$! Privileges: X$!`009Whatever is necessary to access e-mail and the relevant network. X$! X$! X$! Environment: X$!`009Nothing special. VMS_SHARE must exist of course in order to X$!`009produce the software package. X$! X$! Revision History: X$!`0091.0`009Andy Harper`0096-DEC-1988`009Original version X$!`0091.1`009Andy Harper`00919-DEC-1988`009Allow P4 to be mail subject X$!`0091.2`009Andy Harper`0095-JAN-1989`009Return exit status X$!`0091.3`009Andy Harper`00916-JUN-1989`009Remove "OF_''mm'" extension X$! X$! X$ X$ X$! SET UP STANDARD EXIT CODES X$ ss$_normal= 1 X$ ss$_abort = 44 X$ X$ X$! MAKE SURE WE HAVE ALL THE PARAMETERS X$get_recipient: X$ if P1 .nes. "" then $ goto end_get_recipient X$ inquire P1 "_mail address of recipient " X$ goto get_recipient X$end_get_recipient: X$ X$package_location: X$ if P2 .nes. "" then $ goto end_package_location X$ inquire P2 "_Enter package directory and base filename " X$ goto package_location X$end_package_location: X$ P2 = f$parse(P2,,,,"SYNTAX_ONLY") - f$parse(P2,,,"VERSION") X$ if f$parse(P2,,,"TYPE") .nes. "." then $ P2 = P2 + "_" X$ X$ X$get_parts: X$ if P3 .nes. "" then $ goto end_get_parts X$ inquire P3 "_Enter number of parts " X$ goto get_parts X$end_get_parts: X$ X$ X$! SET UP USEFUL SYMBOLS X$ em="write sys$error ""%" +f$parse(f$environment("PROCEDURE"),,,"NAME")+""" V," X$ package = f$parse(P2,,,"NAME") X$ l = f$length(P3) X$ X$ X$! IS THERE A SET OF FILES THAT MATCHES THE SPECIFICATION?? X$ if f$search("''P2'*") .eqs. "" then $ goto nopackage X$ X$ X$! DO A QUICK CHECK TO MAKE SURE ALL REQUIRED FILES ARE THERE!!!!! X$ part = 0 X$ OK = "TRUE" X$check: X$ part = part+1 X$ if part .gt. P3 then $ goto end_check X$ if f$search("''P2'''part'") .nes. "" then $ goto check X$ em "-E-NOPART, Part ''part' of ''package' is missing!" X$ OK = "FALSE" X$ goto check X$end_check: X$ X$ X$! WERE ALL THE PARTS FOUND? IF NOT, NOW'S THE TIME TO FIND OUT! X$ if .not. OK then $ goto abandon X$ X$ X$! LOOP AROUND EACH PART AND SEND X$ part = 0 X$loop: X$ part = part+1 X$ if part .gt. P3 then $ exit ss$_normal X$ n = f$fao("!#ZL",l,part) X$ em "-I-SENDPART, sending part ", part, " of ", package X$ mail/noedit/noself/subject="''package' ''P4' ''n'/''P3'" 'p2''part' 'P1' X$ if $status then $ goto loop X$ exit $status`009! Return status from mail if it failed X$ X$ X$nopackage: X$ em "-E-NOPACKAGE, Cant find any files for ''package'." X$abandon: X$ em "-E-ABANDON, One or more missing parts. Send abandoned." X$ exit ss$_abort $ CALL UNPACK PAKMAIL.COM;10 37437432 $ create/nolog 'f' X1 PAKMAIL XSends a series of files produced by VMS_SHARE across the E-mail Xsystem to a specified set of recipients.`032 X XFormat: X $ PAKMAIL recipient filespec parts `091comment`093 X2 Examples X $ PAKMAIL FRED `091.TEST`093PACKAGE. 25 X Send all 25 parts of a VMS_SHARE created series of files X that comprise the package "PACKAGE". Files have a generic X prefix of "`091.TEST`093PACKAGE." (note the trailing period!) and X each will have its TYPE suffixed by the VMS_SHARE X convention of 'nn' X2 Filespec XThe directory and fixed constant part of the files containing the XVMS_SHARE'd package. The part number is appended to the TYPE part Xof the name. X XFor instance, the name "`091.TEST`093BURBLE.SHAR" refers to the files: X X `091.TEST`093BURBLE.SHAR_nn X X'nn' being the part number. X2 Comment XSpecifies an optional comment to be inserted into the MAIL /SUBJECT Xheader line, between the package name and the number of the part.`032 X XFor example, without this parameter, the /SUBJECT line looks like this:`032 X Subject: VMS_SHARE 1/4 X XWith it set to the string "(Version 7 Pre-release)", the /SUBJECT line Xlooks like this:`032 X Subject: VMS_SHARE (Version 7 Pre-Release) 1/4 X2 Parts XSpecifies the number of parts making up the complete package to`032 Xbe sent. This defines the total number of files to be sent. X XThere is no default for this. X2 Recipient XThe mail address of the recipient. Anything acceptable to MAIL Xmay be specified with two caveats - distribution list usage and`032 Xusernames within double quotes. X X3 Distribution_Lists XUse of distribution lists directly does not work as DCL gets at Xthe '@' symbol before MAIL does! It must be done by pointing a Xlogical name at the distribution list, including the '@' and then Xusing the logical name as the recipient.`032 X XFor instance, to simulate: X X $ PAKMAIL @FRIENDS .... X XDo: X X $ DEFINE FRIENDS "@FRIENDS.DIS" X $ CREATE FRIENDS.DIS X ..... insert friends here X `094Z X $ PAKMAIL FRIENDS ..... X3 Quoted_usernames XUsernames must be specified in exactly the same form as they would be Xused on the MAIL command line, as in:`032 X X $ MAIL MESSAGE.TXT NET%"""FRED@MIT""" X XThis is important only when addresses containing double quotes are used; Xessentially, individual quotes are doubled and a new set placed around`032 Xthe lot. X XFor instance, to simulate: X X $ PAKMAIL EARN%"FRED@CARNEGIE" X XDo: X $ PAKMAIL EARN%"""FRED@CARNEGIE""" X XAlternatively, define a logical name that contains the original Xform of address:`032 X X $ DEFINE BROTHER EARN%"""FRED@CARNEGIE""" X $ PAKMAIL BROTHER ... X2 VMS_SHARE XVMS_SHARE packages a series of files into the special format. See the Xhelp on that utility for specific information.`032 $ CALL UNPACK PAKMAIL.HLP;4 220816226 $ create/nolog 'f' X---------------------------------------- Test printable characters Xabcdefghijklmnopqrstuvwxyz`009! All lower case letter, in order XABCDEFGHIJKLMNOPQRSTUVWXYZ`009! All upper case letters, in order X0123456789`009`009`009! All digits in order X`096 ! Backwords quote X`126 ! Tilde X! ! Exclamation mark X@ ! at sign X# ! Hash or pound sign X$ ! Dollar sign X% ! Percent sign X`094 ! Caret X& ! Ampersand X* ! asterisk X( ! Left round bracket X) ! Right round bracket X- ! minus X+ ! plus X= ! equals X`123 ! left brace X`125 ! right brace X`091 ! left square bracket X`093 ! right square bracket X: ! colon X" ! Double quote X`124 ! vertical bar X; ! semicolon X' ! single quote X\ ! backslash X> ! greater than X< ! less than X, ! comma X. ! period X? ! question mark X/ ! slash X---------------------------------------- Test single blank line X X---------------------------------------- Test trailing blanks, non split lin Ves XHere are some lines with trailing blanks `032 Xand another `032 X---------------------------------------- Test trailing blanks, split lines X1234567890123456789012345678901234567890123456789012345678901234567890123456 V78901234567890123456789012345678901234567890123456789012345678901234567890 X1234567890 x x x x x x x x x x x V x x `032 X1234567890 x x x x x x x x x x x V x x `032 X1234567890 x x x x x x x x x x x V x x `032 X1234567890 x x x x x x x x x x x V x x `032 X1234567890x x x x x x x x x x x V x x `032 $ CALL UNPACK TEST.TXT;1 1650208991 $ create/nolog 'f' X$! Purpose: X$!`009Package a series of files into a format that can be mailed across X$! most networks without damage. X$! X$! Parameters: X$!`009P1 = a comma separated list of file specifications which are to be X$!`009 packaged together. Only files in or below the current`032 X$!`009 subdirectory are permitted. X$! X$!`009P2 = The name of an output share file. Any version number specified X$!`009 here is ignored and the next highest version created. The file X$!`009 may not appear in the input list. X$! X$! Privileges: X$!`009None required X$! X$! Environment: X$!`009Requires at least VMS 4.4 in order to use GOSUB X$! X$! Revision History: X$!`0097.0`009Andy Harper`0099-May-1989`009Complete rewrite X$!`0097.1`009Andy Harper`00915-Jun-1989`009Add file exclusion X$!`0097.1-001`009Andy harper`00929-JUN-1989`009Minor bug fixes X$ X$ X$! DEFINE ESSENTIAL SYMBOLS X$ temp = f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID")) - ";" X$ em="write sys$error ""%"+f$parse(f$environment("PROCEDURE"),,,"NAME")+ """ V," X$ default = f$parse("") - ".;" X$ X$ set noon X$ on control_y then $ goto abort X$ X$ X$! GET LIST OF FILES TO BE PACKAGED X$get_filespec: X$ if P1 .nes. "" then $ goto end_get_filespec X$ read/prompt="Filespec : " sys$command P1 X$ goto get_filespec X$end_get_filespec: X$ X$ X$! GET NAME OF OUTPUT FILE X$sharespec: X$ if P2 .nes. "" then $ goto end_sharespec X$ read/prompt="Share file : " sys$command P2 X$ goto sharespec X$end_sharespec: X$ P2 = f$parse(P2,,,,"SYNTAX_ONLY") - f$parse(P2,,,"VERSION") X$ if f$parse(P2,,,"TYPE") .nes. "." then $ P2 = P2 + "_" X$ X$ X$! PICK UP PARAMETERS FROM USER, VIA LOGICALS. SET NECESSARY DEFAULTS X$ Real_Name = f$trnlnm("SHARE_REAL_NAME") X$ if Real_Name .nes. "" then $ Real_Name = "(" + Real_Name + ")" X$ X$ Max_Part_Size = f$integer(f$trnlnm("SHARE_PART_SIZE")) X$ if Max_Part_Size .eq. 0 then $ Max_Part_Size = 30 X$ if Max_Part_Size .lt. 6 then $ Max_Part_Size = 6 X$ X$`032 X$ X_dir = f$edit(f$trnlnm("SHARE_EXCLUDE_DIRS"), "UPCASE") + "," X$ X_name = f$edit(f$trnlnm("SHARE_EXCLUDE_NAMES"),"UPCASE") + "," X$ X_type = f$edit(f$trnlnm("SHARE_EXCLUDE_TYPES"),"UPCASE") + ",.DIR," X$ X$ X$! OPEN A FILE FOR PASSING PARAMETERS TO THE TPU CODE X$ open/write/error=cantopen xx_share_params 'temp' X$ write xx_share_params f$edit(f$getjpi("","USERNAME"),"TRIM")," ", Real_Nam Ve X$ write xx_share_params Max_Part_Size X$ write xx_share_params P2 X$ X$ X$! INITIALIZE FOR SCANNING THE FILENAMES X$ file_count = 0 X$ file_element = -1 X$ X$! GET NEXT ELEMENT FROM COMMA SEPARATED LIST OF WILDCARDED FILESPEC ELEMENT VS X$next_file_element: X$ file_element = file_element + 1 X$ file = f$element(file_element,",",P1) X$ if file .eqs. "," then $ goto no_more_files X$ X$ X$! DO WE HAVE A FILE THAT MATCHES THIS SPECIFICATION??? X$ file_name = f$search(file) X$ if file_name .eqs. "" then $ em "-W-FNF, ''file' not found. Ignored." X$ if file_name .eqs. "" then $ goto next_file_element X$ X$`032 X$! WE HAVE A VALID FILE SPEC SO GO DO SOME WORK ON IT. X$fname: X$ F_dir = f$parse(file_name,,,"DIRECTORY") +"," X$ F_name= f$parse(file_name,,,"NAME") + "," X$ F_type= f$parse(file_name,,,"TYPE") + "," X$ if file_name-f$parse(file_name,,,"VERSION") .nes. temp then $ - X if f$locate(F_dir,X_dir) .eq. f$length(X_dir) then $ - X if f$locate(F_name,X_name) .eq. f$length(X_name) then $ - X if f$locate(F_type,X_type) .eq. f$length(X_type) then $ - X gosub process_file X$ X$ X$! LOCATE THE NEXT MATCHING FILENAME +-+-+-+-+-+-+-+- END OF PART 1 +-+-+-+-+-+-+-+- Relay-Version: version nyu B notes v1.6 5/10/89; site acf4.NYU.EDU From: UDAA055@ash.cc.kcl.ac.UK Date: 6 Jul 89 10:22 EDT Date-Received: 6 Jul 89 10:47 EDT Subject: VMS_SHARE 2/6 Message-ID: <8907061428.AA17477@ucbvax.Berkeley.EDU> Path: acf4!cmcl2!rutgers!usc!bloom-beacon!tut.cis.ohio-state.edu!ucbvax!ash.cc.kcl.ac.UK!UDAA055 Newsgroups: comp.os.vms Organization: The Internet Sender: daemon@ucbvax.BERKELEY.EDU Lines: 351 -+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+ X$ previous_file = file_name X$ file_name = f$search(file) X$ if file_name .nes. "" .and. file_name .nes. previous_file then $ goto fnam Ve X$ goto next_file_element X$ X$ X$! NO MORE FILES, PROCESS THE LIST WE HAVE OBTAINED. X$no_more_files: X$ close xx_share_params X$ if file_count .ne. 0 then $ goto dopacking X$ em "-E-NOFILES, No files found." X$ goto cleanup X$ X$ X$ X$Process_File: ! file_name, P2 (sharefile), file_count, default X$ X$! CHECK FILE IS WITHIN OR BELOW CURRENT SUBDIRECTORY, REMOVE LEADING STUFF X$ x = file_name X$ check = f$integer(x - f$parse(x,,,"VERSION") - P2) X$ if f$type(check) .eqs. "INTEGER" then $ if check .gt. 0 then goto igsh X$ x = x - (default-"`093") X$ c = f$extract(0,1,x) X$ if c .nes. "`093" .and. c .nes. "." then $ goto cantarchive X$ x = "`091" + x - "`091`093" X$ X$ file_count = file_count + 1 X$ em "-I-SELECTED, Selected file ''file_count' - ''x'" X$ checksum 'x' X$ write xx_share_params x, " ", checksum$checksum X$ return X$ X$igsh: X$ em "-W-SHRNOTPACK, Share file part ''file_name' discovered. Not packaged! V" X$ return X$ X$cantarchive: X$ em "-E-NOTINTREE, ''file_name' not within/below current dir." X$ goto cleanup X$ X$cantopen: X$ em "-E-NOPARFIL, Unable to open temporary parameter file ''temp'" X$ exit 44 X$ X$abort: X$ em "-F-ABORT, Abort detected. Packing abandoned." X$cleanup: X$ if f$trnlnm("xx_share_params") .nes. "" then $ close xx_share_params X$ if f$search(temp) .nes. "" then $ delete /nolog /noconfirm 'temp';* X$ exit 44 X$ X$ X$! WEVE GOT A LIST OF FILES TO PACK SO LETS DO IT NOW! X$dopacking: X$ edit/tpu/nosec/nodis/com=sys$input 'temp' X! +--------------------------------------------------------------------+ X! + FACILITY: + X! + VMS_SHARE + X! + + X! + PURPOSE: + X! + To package a series of plain text files into a format that + X! + can be successfully mailed through most networks without + X! + damage: + X! + + X! + Characters prone to translation by mailers/networks are + X! + encoded into a form that will (hopefully) not be altered + X! + but we cannot recover if they ARE altered despite the + X! + encoding. A checksum is included so we can at least detect + X! + corruption. + X! + + X! + RESTRICTIONS: + X! + Text files only, NOT binary or executables + X! + + X! + No retransmit protocol with mailers, so cannot recover + X! + from mangled mail files such as missing lines, character + X! + translations etc. + X! + + X! + VERSION: + X! + 7.0-001 Pack multiple files into single part + X! + 7.0-002 Produce multiple parts < Some maximum size + X! + 7.0-003 Deal with subdirectories on output + X! + 7.0-004 Output packed TPU code to unpack files + X! + 7.0-005 Quote troublesome characters & trailing blanks + X! + 7.0-006 Wrap long lines + X! + 7.1-001 Various bug fixes for release + X! + + X! + AUTHOR: + X! + (C) ANDY HARPER, KINGS COLLEGE LONDON, UK 1989 + X! + + X! + CREDITS: + X! + James Gray for the first version of VMS_SHARE + X! + Michael Bednarek for the original idea and prototype + X! + + X! +--------------------------------------------------------------------+ X! X! X`012 X! +--------------------------------------------------------------------+ X! + Initialisation routine to set up global constant values + X! +--------------------------------------------------------------------+ X XPROCEDURE Init_Constants; X X FAC_name := "VMS_SHARE";`009! Facility name/version X FAC_vers := "7.1-001 26-JUN-1989"; X FAC_unpack := "UNPACK";`009`009! Facility name of unpack code X X DEBUG_state := 0;`009`009`009! Turn debugging ON/OFF X Max_Line_Length:= 77;`009`009! Maximum length of coded/packed lines X Max_Parts := 999;`009`009! Maximum number of parts supported X X SPLIT_disallowed := 0;`009`009! Flags for dealing with part breaks X SPLIT_permit_goto := 1; X SPLIT_inhibit_goto := 2; X X FAO_end_goto := "$ GOTO PART!UL";`009! Format strings for part separato Vrs X FAO_start_label:= "$PART!UL:"; X FAO_end_part := "+-+-+-+-+-+-+-+- END OF PART !UL +-+-+-+-+-+-+-+-"; X FAO_start_part := "-+-+-+-+-+-+-+-+ START OF PART !UL -+-+-+-+-+-+-+-+"; X `032 X TPU_Max_Record_Length := 960;`009! Max record length TPU supports X X TPU_separators := "&(),=;>@";`009! Split packed TPU code on these X X Quote_Flag := "`096";`009`009`009! Flag for escaping troublesome chars X X Flag_Initial_Line := "X";`009! Flag first line of a long line X Flag_Continuation_Line := "V";`009! Flag continuation lines. X XENDPROCEDURE; X`012 X! +--------------------------------------------------------------------+ X! + Initialisation routine to set up tables + X! + + X! + This routine sets up global tables that are used to perform various+ X! + conversions on the characters in the files: + X! + + X! + ASCII_CHARS: A table of ascii characters, used for mapping + X! + characters into their 'escaped' form. + X! + + X! + NON_PRINTABLES: A table of characters which have no visible + X! + representation. Used for determining which + X! + characters to 'escape'. + X! + + X! + TROUBLE_CHARS: Characters which may get randomly converted on + X! + passing thru the network and which therefore + X! + will need 'escaping'. + X! + + X! +--------------------------------------------------------------------+ X XPROCEDURE Init_Tables XLOCAL c; X X c := 0; X ascii_chars := "";`009`009`009! Table of ASCII characters X Non_Printables := "";`009`009`009! Table of non-printing chars X X LOOP X EXITIF C > 255; X ascii_chars := ascii_chars + ASCII(c); X X IF (c < 32) OR (c > 126) X THEN X Non_Printables := Non_Printables + ASCII(c); X ENDIF; X c:=c+1; X ENDLOOP; X `032 X Trouble_chars :=`009`009`009! Troublesome characters X ASCII(91)`009`009! Left square bracket X + ASCII(93)`009`009! Right square bracket X + ASCII(94)`009`009! Caret X + ASCII(123)`009`009! Left curly bracket X + ASCII(124)`009`009! Vertical bar X + ASCII(125)`009`009! Right curly bracket X + ASCII(126)`009`009! Tilde X ; X X Funny_Chars := Non_Printables + Trouble_Chars + Quote_Flag; X XENDPROCEDURE; X`012 X! +--------------------------------------------------------------------+ X! + + X! + GENERAL UTILITY ROUTINES: + X! + + X! + Inform(Xsev,Xident,Xtext); + X! + Output error message in usual VMS format + X! + + X! + Size_Buffer(Xbuffer); + X! + Returns the size in bytes of an arbitrary buffer. The + X! + routine estimates the amount of disk space the buffer + X! + would occupy if written to a file. Ends of lines count as + X! + three characters here. This is a slight overestimate in + X! + practice but suffices. + X! + + X! + Write_Part(Xbuffer,Part); + X! + Writes an arbitrary buffer to a file. The current share file+ X! + name is selected and the current 'part' number appended to + X! + the filename (eg. X.SHARn) + X! + + X! + Move_Info(FromBuf,ToBuf); + X! + Shorthand for moving all info from one buffer to another + X! + + X! + Copy_Line(Xstring); + X! + Adds a string to the current buffer and follows it with a + X! + new line character. + X! + + X! + Reuse_Buffer(Xbuffer) + X! + Erase buffer contents and position to it. + X! + + X! + + X! +--------------------------------------------------------------------+ X X X XPROCEDURE Inform(Xsev,xident,Xtext) XLOCAL prefix; X X prefix := "%" + FAC_name + "-" + Xsev + "-" + Xident; X MESSAGE( prefix + ", " + Xtext); X XENDPROCEDURE; X X X `032 XPROCEDURE Size_Buffer(Xbuffer) XLOCAL Size_Chars, Size_Lines; X X Size_Chars := LENGTH(CREATE_RANGE(BEGINNING_OF(Xbuffer),END_OF(Xbuffer),N VONE)); X Size_Lines := GET_INFO(Xbuffer,"RECORD_COUNT"); X RETURN( Size_Chars + 3 * Size_Lines ); X XENDPROCEDURE; X X X XPROCEDURE Write_Part(Xbuffer,Part) XLOCAL f,r; X XON_ERROR X Inform("E","FILWRERR", "Error writing part to file " + f); XENDON_ERROR; X X f := Share_File+STR(Part); X WRITE_FILE(Xbuffer,f); X X IF DEBUG_state X THEN X r := GET_INFO(Xbuffer,"RECORD_COUNT"); X Inform("I","DBGWRFIL",FAO("!UL line!%S written to !AS.",r,f)); X ENDIF; X XENDPROCEDURE; X X X XPROCEDURE Move_Info(FromBuf, ToBuf) X X POSITION(ToBuf); MOVE_TEXT(FromBuf); X XENDPROCEDURE; X X X XPROCEDURE Copy_Line(Xstring) X X COPY_TEXT(Xstring); SPLIT_LINE; X XENDPROCEDURE; X X X XPROCEDURE Reuse_Buffer(Xbuffer); X X ERASE(Xbuffer); X POSITION(Xbuffer); X XENDPROCEDURE; X`012 X! +--------------------------------------------------------------------+ X! + TPU CODE COMPRESSION ROUTINES + X! + + X! + Pack_TPU(Xstring); + X! + This routine takes a line of TPU code as a parameter and + X! + adds it to the current buffer in a way that minimises + X! + as much redundant information as possible to produce as few + X! + lines as possible. The compressed code will be added to the + X! + output file to perform file decoding/unpacking. + X! + + X! +--------------------------------------------------------------------+ X X XPROCEDURE Pack_TPU(Xstring) XLOCAL s,c; X X POSITION(END_OF(CURRENT_BUFFER)); X MOVE_HORIZONTAL(-1); X X s := Xstring; X EDIT(s,TRIM); X COPY_TEXT(s); X X c := SUBSTR(s,LENGTH(s),1); X IF INDEX(TPU_separators,c) = 0 X THEN X COPY_TEXT(" "); X ENDIF; X X LOOP X EXITIF CURRENT_OFFSET < Max_Line_Length; X MOVE_HORIZONTAL(-1); X POSITION( SEARCH( ANY(TPU_separators),REVERSE) ); X ENDLOOP; X `032 X IF LENGTH(CURRENT_LINE) > Max_Line_Length X THEN X MOVE_HORIZONTAL(1);`009! Split just past the separator character X SPLIT_LINE; X ENDIF; X X IF DEBUG_state X THEN X Inform("I","DBGPCKTPUCUR","Current line is """ + CURRENT_LINE + """"); X Inform("I","DBGPCKTPUNEW","New string is """ + s + """"); X Inform("I","DBGPCKTPULST","Last char is """ + c + """"); X ENDIF; X XENDPROCEDURE; X`012 X! +--------------------------------------------------------------------+ X! + BUFFER ENCODING ROUTINES + X! + + X! + Quote_Character; + X! + Replaces the current character by an 'escape sequence' + X! + consisting of a flag character followed by exactly 3 digits + X! + where the digits are the ASCII code of the character being + X! + replaced. + X! + + X! + The intention is to change characters which may get altered + X! + in transit into something that is likely to pass thru + X! + unchanged. Restoration is effected at the receiving end. + X! + + X! + Quote_Buffer(Xbuffer,p); + X! + This routine searches a buffer for a particular pattern + +-+-+-+-+-+-+-+- END OF PART 2 +-+-+-+-+-+-+-+- Relay-Version: version nyu B notes v1.6 5/10/89; site acf4.NYU.EDU From: UDAA055@ash.cc.kcl.ac.UK Date: 6 Jul 89 10:22 EDT Date-Received: 6 Jul 89 11:46 EDT Subject: VMS_SHARE 3/6 Message-ID: <8907061431.AA17605@ucbvax.Berkeley.EDU> Path: acf4!cmcl2!rutgers!tut.cis.ohio-state.edu!ucbvax!ash.cc.kcl.ac.UK!UDAA055 Newsgroups: comp.os.vms Organization: The Internet Sender: daemon@ucbvax.BERKELEY.EDU Lines: 400 -+-+-+-+-+-+-+-+ START OF PART 3 -+-+-+-+-+-+-+-+ X! + (Usually one of a series of specific characters) and + X! + replaces the first character of that pattern by the 'escape'+ X! + sequence. This is performed at each occurence of that + X! + pattern in the buffer. + X! + + X! + Wrap_Lines(Xbuffer, Max_Length); + X! + This routine wraps lines longer than a fixed size so that + X! + all lines are less/equal to this size. To allow rejoining + X! + All lines are prefixed with a flag to indicate an initial + X! + line or a continuation line. + X! + + X! + The intention here is to anticipate the actions of mailers + X! + which have line limits and preempt their wrapping attempts + X! + which would corrupt the data being transmitted. Doing it + X! + this way, we have control over rejoining them. + X! + + X! +--------------------------------------------------------------------+ X X X XPROCEDURE Quote_Character X X COPY_TEXT(Quote_Flag+FAO("!3ZL",INDEX(ascii_chars,ERASE_CHARACTER(1))-1)); X XENDPROCEDURE; X`012 XPROCEDURE Quote_Buffer(Xbuffer, p) XLOCAL r; X XON_ERROR X IF ERROR = TPU$_STRNOTFOUND THEN RETURN; ENDIF; XENDON_ERROR; X X POSITION( BEGINNING_OF(Xbuffer) ); X X LOOP X r := SEARCH(p, FORWARD, EXACT); X EXITIF r=0; X POSITION(r); X X IF DEBUG_state X THEN X Inform("I","DBGQUOBEFORE", "Current_Line_before="""+CURRENT_LINE+""" V"); X ENDIF; X X IF LENGTH(CURRENT_LINE)+3 > TPU_Max_Record_Length X THEN X Inform("W","TPULONGREC", "Line overlong, Quoting suppressed"); X Inform("W","CURLINEIS", """" + CURRENT_LINE + """"); X MOVE_HORIZONTAL(-CURRENT_OFFSET); X MOVE_VERTICAL(1); X ELSE X Quote_Character; X ENDIF; X X IF DEBUG_state X THEN X Inform("I","DBGQUOAFTER", "Current_Line_after ="""+CURRENT_LINE+"""" V); X ENDIF; X X ENDLOOP; X XENDPROCEDURE; X`012 XPROCEDURE Wrap_Lines(Xbuffer, Max_Length) X X POSITION( BEGINNING_OF( Xbuffer ) ); X LOOP X EXITIF MARK(NONE) = END_OF( CURRENT_BUFFER ); X X COPY_TEXT( Flag_Initial_Line ); X LOOP X EXITIF LENGTH(CURRENT_LINE) <= Max_Length; X `032 X ! Find Last non-blank char on line X MOVE_HORIZONTAL(Max_Length-1);`032 X LOOP X MOVE_HORIZONTAL(-1); X EXITIF (CURRENT_CHARACTER <> " ") OR (CURRENT_OFFSET < 2); X ENDLOOP; X X IF DEBUG_state X THEN X Inform("I","DBGWRPSPLIT","Splitting Line """+CURRENT_LINE+""""); X Inform("I","DBGWRPCHAR", "Split char = """+CURRENT_CHARACTER+"""") V; X Inform("I","DBGWRPOFF", "Offset = " + STR(CURRENT_OFFSET)); X ENDIF; X X IF CURRENT_OFFSET < 2 X THEN X MOVE_HORIZONTAL(Max_Length-5); X Quote_Character; X ELSE X MOVE_HORIZONTAL(1); X ENDIF; X X ! Split line at last non-blank char or at max line length X SPLIT_LINE; X COPY_TEXT(Flag_Continuation_Line); X ENDLOOP; X`032 X ! Move to start of next genuine line X MOVE_HORIZONTAL(-1); X MOVE_VERTICAL(1); X X ENDLOOP; X XENDPROCEDURE; X`012 X! +--------------------------------------------------------------------+ X! + Routines to create headers and trailers for insertion in share file+ X! +--------------------------------------------------------------------+ X X `032 XPROCEDURE Create_Prologue_Head(Xbuffer, Creator, Blocks, Start_File_List) XLOCAL filecount,file,nextfile; X X Reuse_Buffer(Xbuffer); X X Copy_Line( "$! ------------------ CUT HERE -----------------------"); X Copy_Line( "$!" ); X Copy_Line( "$! This archive created by " + FAC_name + " Version " + FAC_ve Vrs); X Copy_Line( FAO("$!! On !%D By user !AS", 0, Creator) ); X Copy_Line( "$!" ); X Copy_Line( "$! This " + FAC_name + " Written by:"); X Copy_Line( "$! Andy Harper, Kings College London UK"); X Copy_Line( "$!" ); X Copy_Line( "$! Acknowledgements to:"); X Copy_Line( "$! James Gray - Original VMS_SHARE"); X Copy_Line( "$! Michael Bednarek - Original Concept and implementation") V; X Copy_Line( "$!"); X Copy_Line( "$!+ THIS PACKAGE DISTRIBUTED IN 999 PARTS, TO KEEP EACH PART") V; X Copy_Line( "$! BELOW " + STR(Blocks) + " BLOCKS"); X Copy_Line( "$!"); X Copy_Line( "$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER") V; X Copy_Line( "$! AND EXECUTE AS A COMMAND PROCEDURE ( @name )"); X Copy_Line( "$!"); X Copy_Line( "$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:"); X X filecount := 0; X nextfile := Start_File_List; X LOOP X POSITION(nextfile); X EXITIF MARK(NONE) = END_OF(CURRENT_BUFFER); X X file := SUBSTR(CURRENT_LINE,1,INDEX(CURRENT_LINE," ")-1); X MOVE_VERTICAL(1); X nextfile := MARK(NONE); X X POSITION(Xbuffer); X filecount := filecount + 1; X Copy_Line( FAO("$!! !3UL. !AS", filecount, file)); X X IF DEBUG_state X THEN X Inform("I","DBGPROADFIL","Adding name """ + file + """ to prologue V"); X ENDIF; X X ENDLOOP; X POSITION(Xbuffer); X X Copy_Line( "$!"); X Copy_Line( "$f=f$parse(""SHARE_TEMP"",""SYS$SCRATCH:.TMP_""+f$getjpi("""", V""PID""))"); X Copy_Line( "$e=""write sys$error """"%"+FAC_unpack+""""", """); X Copy_Line( "$w=""write sys$output """"%"+FAC_unpack+""""", """); X Copy_Line( "$ if f$trnlnm(""SHARE_LOG"") then $ w = ""!"""); X Copy_Line( "$ if f$getsyi(""version"") .ges. ""4.4"" then $ goto START"); X Copy_Line( "$ e ""-E-OLDVER, Must run at least VMS 4.4"""); X Copy_Line( "$ exit 44"); X Copy_Line( "$UNPACK: SUBROUTINE ! P1=filename, P2=checksum"); X Copy_Line( "$ if f$search(P1) .eqs. """" then $ goto file_absent"); X Copy_Line( "$ e ""-W-EXISTS, File ''P1' exists. Skipped."""); X Copy_Line( "$ delete/nolog 'f'*"); X Copy_Line( "$ exit"); X Copy_Line( "$file_absent:"); X Copy_Line( "$ if f$parse(P1) .nes. """" then $ goto dirok"); X Copy_Line( "$ dn=f$parse(P1,,,""DIRECTORY"")"); X Copy_Line( "$ w ""-I-CREDIR, Creating directory ''dn'."""); X Copy_Line( "$ create/dir 'dn'"); X Copy_Line( "$ if $status then $ goto dirok"); X Copy_Line( "$ e ""-E-CREDIRFAIL, Unable to create ''dn'. File skipped.""") V; X Copy_Line( "$ delete/nolog 'f'*"); X Copy_Line( "$ exit"); X Copy_Line( "$dirok:"); X Copy_Line( "$ w ""-I-PROCESS, Processing file ''P1'."""); X COPY_TEXT( "$ define/user sys$output nl:");`009! suppress TPU 'lines read' X XENDPROCEDURE; X X X XPROCEDURE Create_Prologue_Unpacker(Xbuffer) X X Reuse_Buffer(Xbuffer); X X Copy_Line("$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'"); X X Pack_TPU( "PROCEDURE Unpacker" ); X Pack_TPU( "ON_ERROR" );`009`009`009`009! Trap SEARCH error X Pack_TPU( "ENDON_ERROR;" ); X X Pack_TPU( "SET(FACILITY_NAME,"""+FAC_unpack+""");" );`009! SETUP X Pack_TPU( "SET(SUCCESS,OFF);" ); X Pack_TPU( "SET(INFORMATIONAL,OFF);" ); X Pack_TPU( "f:=GET_INFO(COMMAND_LINE,""file_name"");" ); X Pack_TPU( "buff:=CREATE_BUFFER(f,f);" ); X `032 X Pack_TPU( "p:=SPAN("" "")@r&LINE_END;" ); X Pack_TPU( "POSITION(BEGINNING_OF(buff));" ); X Pack_TPU( "LOOP" );`009`009`009`009`009! Trailing blank removal X Pack_TPU( " EXITIF SEARCH(p,FORWARD)=0;" ); X Pack_TPU( " POSITION(r);" ); X Pack_TPU( " ERASE(r);" ); X Pack_TPU( "ENDLOOP;" ); X X Pack_TPU( "POSITION(BEGINNING_OF(buff));" ); X Pack_TPU( "g:=0;" ); X Pack_TPU( "LOOP" );`009`009`009`009`009! Unwrap lines X Pack_TPU( " EXITIF MARK(NONE)=END_OF(buff);" ); X Pack_TPU( " x:=ERASE_CHARACTER(1);" ); X Pack_TPU( " IF g = 0 THEN" ); X Pack_TPU( " IF x=""X"" THEN MOVE_VERTICAL(1);ENDIF;" ); X Pack_TPU( " IF x=""V"" THEN APPEND_LINE;"); X Pack_TPU( " MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;" V ); X Pack_TPU( " IF x=""+"" THEN g:=1;ERASE_LINE;ENDIF;" ); X Pack_TPU( " ELSE" ); X Pack_TPU( " IF x=""-"" THEN g:=0;ENDIF; "); X Pack_TPU( " ERASE_LINE;" ); X Pack_TPU( " ENDIF;" ); X Pack_TPU( "ENDLOOP;" ); X X Pack_TPU( "p:=""" + Quote_Flag + """;" ); X Pack_TPU( "POSITION(BEGINNING_OF(buff));" ); X Pack_TPU( "LOOP" );`009`009`009`009`009! Restore escaped chars X Pack_TPU( " r:=SEARCH(p,FORWARD);" ); X Pack_TPU( " EXITIF r=0;" ); X Pack_TPU( " POSITION(r);" ); X Pack_TPU( " ERASE(r);" ); X Pack_TPU( " COPY_TEXT(ASCII(INT(ERASE_CHARACTER(3))));" ); X Pack_TPU( "ENDLOOP;" ); X X Pack_TPU( "o:=GET_INFO(COMMAND_LINE,""output_file"");" ); X Pack_TPU( "WRITE_FILE(buff,o);" ); X X Pack_TPU( "ENDPROCEDURE;" ); X X Pack_TPU( "Unpacker;");`009`009`009`009! procedure call X Pack_TPU( "EXIT;" ); SPLIT_LINE;`009`009`009! EXIT code X X COPY_TEXT("$ delete/nolog 'f'*"); X XENDPROCEDURE; X`012 XPROCEDURE Create_Prologue_Trail(Xbuffer) X X Reuse_Buffer(Xbuffer); X X Copy_Line( "$ CHECKSUM 'P1'"); X Copy_Line( "$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT"); X Copy_Line( "$ e ""-E-CHKSMFAIL, Checksum of ''P1' failed."""); X Copy_Line( "$ ENDSUBROUTINE"); X COPY_TEXT( "$START:"); X XENDPROCEDURE; X X X XPROCEDURE Create_File_Header(Xbuffer); X X Reuse_Buffer(Xbuffer); X COPY_TEXT("$ create/nolog 'f'"); X XENDPROCEDURE; X X X XPROCEDURE Create_File(Xbuffer, Filename) XLOCAL r; X XON_ERROR X Inform("E","FILRDERR", "Error reading from file " + FileName); XENDON_ERROR; X X Reuse_Buffer(Xbuffer); X READ_FILE(FileName); X X IF DEBUG_state X THEN X r := GET_INFO(Xbuffer,"RECORD_COUNT"); X Inform("I","DBGRDFIL",FAO("!UL line!%S read from file !AS",r,FileName) V); X ENDIF; X XENDPROCEDURE; X X XPROCEDURE Create_File_Trailer(Xbuffer, Filename, Checksum); X X Reuse_Buffer(Xbuffer); X COPY_TEXT("$ CALL UNPACK " + Filename + " " + Checksum); X XENDPROCEDURE; X X XPROCEDURE Create_Epilogue(Xbuffer); X X Reuse_Buffer(Xbuffer); X COPY_TEXT("$ EXIT"); X XENDPROCEDURE; X`012 X! +--------------------------------------------------------------------+ X! + PART SPLITTING ROUTINES + X! + + X! + Find_Break(Xbuffer,Max_Size) + X! + This routine uses a fast binary search algorithm to find the + X! + first line in the given buffer which straddles a given break + X! + point - I.E. where the size of the buffer up to and including+ X! + that line would just go over the 'Max_Size' value (bytes). + X! + This allows us to quickly determine where a buffer should be + X! + split when chopping up the info into several small parts. + X! + + X! + Insert_Part_Separator(Part,Xendbuf,Xstartbuf,Split_status) + X! + This routine is responsible for choosing the correct part + X! + separator flag to insert at the beginning and end of parts. + X! + Determination is controlled by two factors:- + X! + + X! + First by the 'split-status' parameter, which determines if + X! + a part break is permitted at this time (its not if, for + X! + example, we are currently in the middle of the TPU code + X! + which does the unpacking!) and, if it is, whether DCL + X! + $GOTO's and labels are useable at the breaks. + X! + + X! + Second, the type of part separator is determined by looking+ X! + at the data in the buffer immediately around the break + X! + point. If both start with '$' then we are splitting the + X! + buffer at the DCL code which is part of the unpacking + X! + control thus we can use $GOTO and a label. If not, then + X! + we are in the midst of user data and should use the + X! + special flag lines + X! + + X! + Add_to_part(Xbuffer,split-status) + X! + This takes a buffer of information and adds as much of it + X! + as possible into the current part buffer, in order to fill + X! + it to its maximum size. The remainder of the buffer is + X! + then copied into the part buffer in similar fashion, and + X! + we repeat until the supply of information is exhausted. Each + X! + time the part buffer fills up it is flushed out to disk. + X! + Part 1 is treated separately as the attention message at the + X! + head of the part needs to be updated later with the actual + X! + number of parts created. We therefore keep it around until + X! + the end in a separate buffer and flush it to disk at the end.+ X! + + X! + Flush_buffer(Xbuffer,Part) + X! + Flushes the specified buffer to disk if not empty. The name + X! + of the file used is constructed from the original share + X! + file template and the current part number. + X! + + X! +--------------------------------------------------------------------+ X`012 `032 XPROCEDURE Find_Break(Xbuffer,Max_Size) XLOCAL Low, High, Size, Line_Size, mb, New_Line, Cur_Line; X X IF DEBUG_State X THEN X Inform("I","DBGFNDBRKMAX","Max free bytes =" + STR(Max_Size)); X ENDIF; X X Low := 0; X High := GET_INFO(Xbuffer,"record_count") - 1; X Cur_Line := 0; X X mb := BEGINNING_OF(Xbuffer); X POSITION(mb); X X ! Special case check to ensure at least one line fits in available space X IF mb <> END_OF(Xbuffer) X THEN X IF LENGTH(CURRENT_LINE)+3 > Max_Size THEN RETURN(0); ENDIF; X ENDIF; X X X LOOP X X New_Line := (Low+High) / 2; X MOVE_VERTICAL(New_Line-Cur_Line); X Cur_Line := New_Line; +-+-+-+-+-+-+-+- END OF PART 3 +-+-+-+-+-+-+-+- Relay-Version: version nyu B notes v1.6 5/10/89; site acf4.NYU.EDU From: UDAA055@ash.cc.kcl.ac.UK Date: 6 Jul 89 10:22 EDT Date-Received: 6 Jul 89 11:55 EDT Subject: VMS_SHARE 4/6 Message-ID: <8907061512.AA19698@ucbvax.Berkeley.EDU> Path: acf4!cmcl2!rutgers!usc!bloom-beacon!tut.cis.ohio-state.edu!ucbvax!ash.cc.kcl.ac.UK!UDAA055 Newsgroups: comp.os.vms Organization: The Internet Sender: daemon@ucbvax.BERKELEY.EDU Lines: 434 -+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+ X X Size:=LENGTH(CREATE_RANGE(mb,MARK(NONE),NONE))+3*Cur_Line; X Line_Size := LENGTH(CURRENT_LINE) + 3; X X IF DEBUG_state X THEN X Inform("I","DBGFNDBRKRNG",FAO("Search range = !UL-!UL",Low,High)); X Inform("I","DBGFNDBRKCURL",FAO("(!UL) ""!AS""",Cur_line,CURRENT_LIN VE)); X Inform("I","DBGFNDBRKSIZE",FAO("Size=!UL, line=!UL",Size,Line_Size) V); X ENDIF; X X EXITIF (Size < Max_Size) AND (Size+Line_Size >= Max_Size); X X IF Size < Max_Size X THEN X Low := Cur_Line + 1; X ELSE X High := Cur_Line - 1; X ENDIF; X X ENDLOOP; X X MOVE_HORIZONTAL(-1); X RETURN( CREATE_RANGE( mb, MARK(NONE), NONE ) ); X XENDPROCEDURE; X`012 XPROCEDURE Insert_Part_Separator(Part, Xendbuf, Xstartbuf, SPLIT_status) XLOCAL c1,c2,end_text,start_text; X X IF SPLIT_status = SPLIT_disallowed X THEN X Inform("F","CANTSPLIT","Part split tried where disallowed"); X EXIT; X ENDIF; X X POSITION( END_OF(Xendbuf) ); MOVE_VERTICAL(-1); c1 := CURRENT_CHARACTER; X POSITION( BEGINNING_OF(Xstartbuf) ); c2 := CURRENT_CHARACTER; X X IF (c1 = "$") AND (c2 = "$") AND (SPLIT_status = SPLIT_permit_goto) X THEN`009`009`009! Executable DCL code insert GOTO/label pair X end_text := FAO(FAO_end_goto, Part+1); X start_text:= FAO(FAO_start_label, Part+1); X ELSE`009`009`009! User data, insert recognizable separators X end_text := FAO(FAO_end_part, Part); X start_text:= FAO(FAO_start_part, Part+1); X ENDIF; `032 X X Copy_Line(start_text); MOVE_VERTICAL(-1); X POSITION(END_OF(Xendbuf)); COPY_TEXT(end_text); X XENDPROCEDURE; X`012 XPROCEDURE Add_To_Part(Xbuffer, SPLIT_status) XLOCAL Size_Xbuffer, Size_part_buf; X X LOOP X X Size_Xbuffer := Size_Buffer(Xbuffer); X Size_part_buf := Size_Buffer(part_buf);`032 X X IF DEBUG_state THEN X Inform( "I","DBGADPTMAX" ,FAO(" Max_bytes = !UL",Max_Bytes)); X Inform( "I","DBGADPTXSIZ",FAO(" Size xbuffer = !UL",Size_Xbuffer) V); X Inform( "I","DBGADPTPSIZ",FAO(" Size part_buf= !UL",Size_part_buf V)); X ENDIF; X X EXITIF Size_Xbuffer <= Max_Bytes-Size_part_buf-Reserved; X X PartNo := PartNo + 1; X xbuf_range := Find_Break(Xbuffer,Max_Bytes-Size_part_buf-Reserved); X POSITION( END_OF(part_buf) ); X IF xbuf_range <> 0`032 X THEN X Move_Info(xbuf_range, part_buf); X ENDIF; X Insert_Part_Separator(PartNo, part_buf, Xbuffer, SPLIT_status); X `032 X IF PartNo = 1 X THEN X Move_Info(part_buf, pt1_buf); X ELSE X Write_Part(part_buf, PartNo); ERASE(part_buf); X ENDIF; X X ENDLOOP; X X Move_Info(Xbuffer, part_buf); X XENDPROCEDURE; X X X XPROCEDURE Flush_Buffer(Xbuffer,Part) X X IF Size_Buffer(Xbuffer) > 0 X THEN X Write_Part(Xbuffer,Part); X ENDIF; X XENDPROCEDURE; X`012 X! +--------------------------------------------------------------------+ X! + MAIN PROGRAM + X! + + X! + This is the main control loop of the program, responsible for + X! + picking up the parameters, creating the prologue and epilogue of + X! + the share file, setting up global constants and variables etc. + X! + + X! + It also contains the main loop which goes around each of the + X! + specified files to be packed into the share file. + X! + + X! +--------------------------------------------------------------------+ X X X XInit_Constants; XInit_Tables; X XSET(SUCCESS,OFF);`009`009! Suppress non-error messages XSET(FACILITY_NAME, FAC_name);`009! identify ourself in errors X Xinfo_buf := CREATE_BUFFER("`123info`125", GET_INFO(COMMAND_LINE, "FILE_NAME V")); Xpart_buf := CREATE_BUFFER("`123part`125"); Xpt1_buf := CREATE_BUFFER("`123part_1`125"); Xwork_buf := CREATE_BUFFER("`123work`125"); X X X! PICK UP PARAMETERS FROM THE OUTSIDE WORLD XPOSITION( info_buf); XUsername := CURRENT_LINE; MOVE_VERTICAL(1); XIF DEBUG_state X THEN X Inform("I","DBGPAR", "Params: Creator = """ + Username + """"); XENDIF; X XMax_Blocks:= INT(CURRENT_LINE); MOVE_VERTICAL(1); XIF DEBUG_state X THEN X Inform("I","DBGPAR", "Params: Max_Blocks = " + STR(Max_Blocks)); XENDIF; X X XShare_File:= CURRENT_LINE; MOVE_VERTICAL(1); XIF DEBUG_state X THEN X Inform("I","DBGPAR", "Params: Share_File = """ + Share_File + """"); XENDIF; X`012 X! INITIALIZE STUFF TO GO THROUGH FILES XStart_Of_Filenames := MARK(NONE); XPartNo := 0; XMax_Bytes := 512 * Max_Blocks; X X! Reserve space in the part buffers for 1 start and 1 end part + CR/LF chars X! + a bit spare! They may not always be used but this is the worst case! XReserved := LENGTH(FAO(FAO_start_part,Max_Parts)) X + LENGTH(FAO(FAO_end_part, Max_Parts)) X + 6; X X X! CREATE THE INITIAL SHARE FILE HEADER XCreate_Prologue_Head(work_buf, Username, Max_Blocks, Start_Of_Filenames); XAdd_To_Part(work_buf,SPLIT_permit_goto); X XCreate_Prologue_Unpacker(work_buf); XAdd_To_Part(work_buf,SPLIT_disallowed); X XCreate_Prologue_Trail(work_buf); XAdd_To_Part(work_buf,SPLIT_permit_goto); X XPOSITION(Start_Of_Filenames); X X! LOOP AROUND, FILLING THE PART BUFFER WITH DATA FROM FILES XLOOP X POSITION(info_buf); X EXITIF MARK(NONE) = END_OF(info_buf); X X file_info := CURRENT_LINE; MOVE_VERTICAL(1); X separator := INDEX(file_info,' '); X fname := SUBSTR(file_info,1,separator-1); X chksum := SUBSTR(file_info,separator+1,LENGTH(file_info)-separator); X X IF DEBUG_state THEN X Inform("I","DBGPAR", "Params: filename = """ + fname + """"); X ENDIF; X X Create_File_Header(work_buf); X Add_To_Part(work_buf,SPLIT_permit_goto); X X Create_File(work_buf,fname); X Quote_Buffer(work_buf, ANY(Funny_Chars)); X Quote_Buffer(work_buf, " "&LINE_END); X Wrap_Lines(work_buf,Max_Line_Length); X Add_To_Part(work_buf,SPLIT_inhibit_goto); X X Create_File_Trailer(work_buf,fname,chksum); X Add_To_Part(work_buf,SPLIT_permit_goto); X XENDLOOP; X XCreate_Epilogue(work_buf); XAdd_To_Part(work_buf,SPLIT_permit_goto); X X XPartNo := PartNo + 1; XPOSITION(BEGINNING_OF(pt1_buf)); X X XIF PartNo > 1 X THEN`009! Modify the inital message to state exact number of parts X POSITION(SEARCH( "$!+", FORWARD) ); X POSITION( SEARCH( STR(Max_Parts), FORWARD) ); X ERASE_CHARACTER(3); X COPY_TEXT( STR(PartNo) ); X X ELSE`009! Erase initial attention message as there's only 1 part! X MOVE_TEXT(part_buf); X POSITION(BEGINNING_OF(pt1_buf)); X POSITION(SEARCH( "$!+", FORWARD) ); X ERASE_LINE; ERASE_LINE; ERASE_LINE; XENDIF; X XFlush_Buffer(part_buf, PartNo); XFlush_Buffer(pt1_buf, 1); X XInform("I","NOOFPTS",FAO("Share file written in !UL part!%S",PartNo)); X Xexit; X$ delete /nolog /noconfirm 'temp';* $ CALL UNPACK VMS_SHARE.COM;50 554093423 $ create/nolog 'f' X1 VMS_SHARE XPackage a series of files into a form suitable for mailing out across Xthe network.`032 X XFormat: X $ VMS_SHARE filespec sharefile X2 Examples X $ VMS_SHARE *.for SOURCE X Package all the files ending in .FOR into the sharefile X 'SOURCE'. Parts will be created called SOURCE.1, SOURCE.2 ... X etc. X X $ VMS_SHARE `091...`093*.* SBDIR X Package all the files in all subdirectories below the X current one. The directory structure, relative to the current X directory, will be preserved and recreated at the unpacking X stage. X2 Filespec XA comma-separated list of wildcarded filename specifications. All files Xwhich match the pattern(s) are packaged.`032 X XThere are some restrictions:- X - The output share file name may not be included in the list. X - files ending in .DIR (normally directory files) are ignored. X - Files must exist in or below the current directory. X XA prompt is issued if no files are specified. X2 Logical_Names XSeveral logical names can be configured to control the operation of`032 XVMS_SHARE. X3 SHARE_EXCLUDE_DIRS XIf defined with a comma separated list of directory specifications, enclosed Xin quotes, any file matching any of the listed directories will be excluded Xfrom the packaging operation.`032 X XWildcards are not permitted; all directories must be listed in full. X3 SHARE_EXCLUDE_NAMES XIf defined with a comma separated list of names, enclosed in quotes, any fil Ve Xwhose NAME part matches any of the listed names will be excluded from the Xpackaging operation.`032 X XWildcards are not permitted. X3 SHARE_EXCLUDE_TYPES XIf defined with a comma separated list of file types, enclosed in quotes, an Vy Xfile whose TYPE part matches any of the listed types will be excluded from t Vhe Xpackaging operation.`032 X XWildcards are not permitted. X3 SHARE_LOG XIf defined with a logical value (YES/NO, TRUE/FALSE etc.) determines`032 Xwhether the unpacking stage produces informational messages about its`032 Xprogress. Error messages are always output. X XThe default is to produce the informational messages. X3 SHARE_PART_SIZE XIf defines, sets the maximum part size. The value is specified in blocks Xand must be greater than 6. A zero value causes the default size to be Xused otherwise a value less than 6 causes 6 to be used.`032 X XThe default size is 30 blocks. X3 SHARE_REAL_NAME XDefines a string which is included at the head of the created share file`032 Xfollowing the username of the user who created it. It is intended that Xit will contain the real name of the user (For example, "FRED SMITH").`032 X3 SHARE_TEMP XDefines the name of a file to be used as a scratch file during the`032 Xpackaging operation. X XDefaults are taken from the name SYS$SCRATCH:SHARE_TEMP.TMP_'pid' where`032 X'pid' is the current Process Identification number. X2 Operational_Notes XVMS_SHARE packages all the specified files into one or more parts having`032 Xa common filename prefix. The suffix will be the part number. Multiple`032 Xparts will be created if the total size of a part exceeds the specified`032 Xmaximum size (taken from the logical SHARE_PART_SIZE). X XEach part is encoded so that it can survive destruction when mailed`032 Xacross the network through unfriendly mailers which wrap lines,`032 Xtranspose characters etc. A checksum is included which can detect damage`032 Xat the receiving end. X XTo unpack, all parts must be concatenated in order and the whole`032 Xexecuted as a command procedure. It is preferable to be in an empty`032 Xscratch directory when doing this. If the parts have been received via`032 Xmail then it is NOT necessary to remove the mail headers between parts`032 Xbefore concatenating them. The unpack code will ignore them if present.`032 XHowever, mail headers should be removed from the initial part. X2 Sharefile XThe name of the packed output file. This name will be suffixed by the`032 Xpart number even if there is only 1 part created. X XA prompt is issued if no sharefile name is specified. $ CALL UNPACK VMS_SHARE.HLP;6 71240389 $ create/nolog 'f' X `009`009`009V M S _ S H A R E X X `009`009`009 R E L E A S E N O T E S X X X X `009`009`009`009`009`009`009`009Version 7.1 X `009`009`009`009`009`009`009`009Jun 1989 X X X1. INTRODUCTION X XVersion 7.1 of VMS_SHARE has been completely rewritten to eliminate long Xstanding bugs, and to improve performance by utilising new algorithms for th Ve Xpacking and upacking of files. Details of the changes from the previous Xversions are given below. X X X X2. NEW FEATURES X X2.1 Subdirectories X XVMS_SHARE now supports subdirectories. The user may package a series of fil Ves Xexisting in the directory tree within/below the current directory. The Xdirectory structure will be recreated at the unpacking stage as an equivalen Vt Xtree beneath the current directory. All required directories are automatical Vly`032 Xcreated as required. X XFor example: X X $ VMS_SHARE `091.TPU...`093*.*,`091.DATA`093*.* PACKAGE.SHAR X Will package the directory tree beneath `091.TPU`093 and the subdire Vctory X `091.DATA`093. During unpacking, these subdirectories will be creat Ved X automatically below the current directory. X X XIt was originally decided to make the directory handling a bit like BACKUP,` V032 Xallowing any directory to be packaged and individual items to be selected at Xunpack time. However this proved to be extremely difficult in DCL and so was Xabandoned. It may appear in a future release. In order to prevent files Xappearing in essentially random directories it was decided to adopt the abov Ve Xcompromise. It retains sufficient flexibility to deal with most package`032 Xstructures but maintains a known directory structure that will avoid files`0 V32 Xbeing placed randomly as far as the receiving user is concerned. X X X X2.2 DEBUG code X XTo assist those who enhance and develop VMS_SHARE, a large amount of Xdebug/trace code is included into the source. By redefining a simple global Xconstant value, this debug code can be turned on or off to assist in trackin Vg Xdown faults. X X X X X2.3 New Part Splitting Algorithms X XThe algorithms used for splitting parts have been extensively redesigned to Xensure minimal use of memory for buffers. Essentially, VMS_SHARE now uses on Vly Xenough memory to hold the sum of two parts and the largest file. We read a Xsingle file, add as much as possible to the part buffer and then write the Xpart buffer, removing the equivalent info from the original file buffer. X XThe algorithm for finding the optimum part breakpoint now uses a binary sear Vch Xinstead of a sequential search for speed. X X X X X2.4 New Unpacking Algorithms X XThe algorithm used to unpack code, embedded in the TPU code stored in the Xoutput share file, has been redesigned to need less error checking and hence Xless code. The TPU code is also packed more compactly than before giving Ximproved compilation speed as well as execution speed.`032 X X X X X2.5 Error and Status Messages X XVMS_SHARE now produces messages similar to the standard VMS form. Messages a Vre +-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+- Relay-Version: version nyu B notes v1.6 5/10/89; site acf4.NYU.EDU From: UDAA055@ash.cc.kcl.ac.UK Date: 6 Jul 89 10:23 EDT Date-Received: 6 Jul 89 12:46 EDT Subject: VMS_SHARE 5/6 Message-ID: <8907061556.AA22036@ucbvax.Berkeley.EDU> Path: acf4!cmcl2!rutgers!apple!bionet!agate!ucbvax!ash.cc.kcl.ac.UK!UDAA055 Newsgroups: comp.os.vms Organization: The Internet Sender: daemon@ucbvax.BERKELEY.EDU Lines: 461 -+-+-+-+-+-+-+-+ START OF PART 5 -+-+-+-+-+-+-+-+ Xproduced to keep the user informed of progress (these normally go to Xsys$output) and error messages (which normally go to sys$error). X XInitial informational messages from TPU, as it reads in the source, are also Xprinted. It is hoped that in a future release some way can be found to turn Xthis off. X X X X2.6 Exclusion Files X XBy defining certain logical names, it is possible to force the exclusion of` V032 Xparticular files from the sharefile. There are three possibilities: exclusio Vn`032 Xby directory, exclusion by name, and exclusion by type. X XEach logical name may be defined as a comma separated list of items (the lis Vt`032 XMUST be enclosed within quotes). Any file that matches is excluded from the Xsharefile. Wildcards are not permitted. Each must be a fixed string.`032 X XThanks go to Joe Meadows (JOE@BITNET.FHCRCVAX) for the general idea and basi Vc Xmechanism.`032 X X X X2.6.1 SHARE_EXCLUDE_DIRS X XThis logical is a list of directory names (in their full format). Any file`0 V32 Xwith the same directory name is automatically excluded. X XFor example: X X DEFINE SHARE_EXCLUDE_DIRS "`091X`093,`091X.Y`093,`091X.Y.Z`093,`091TWEETY V`093" X Xexcludes any file in any of the listed directories. X XIf this logical is absent, then no files are excluded on the basis of their` V032 Xfull directory name. X X X2.6.2 SHARE_EXCLUDE_NAMES X XThis logical is a list of filenames. Any file with the a matching NAME part V is Xautomatically excluded.`032 X XFor example: X X DEFINE SHARE_EXCLUDE_NAMES "MAIN,TRACE,MAIN_CLD" X X XIf this logical is absent, then no files are excluded on the basis of their` V032 Xfilename. X X X2.6.3 SHARE_EXCLUDE_TYPES X XThis logical is a list of file types. Any file with a matching TYPE part is` V032 Xautomatically excluded. Files with a type of .DIR are automatically excluded V`032 Xas these are directory files with no valid contents at the time of unpacking V. X XFor example: X X DEFINE SHARE_EXCLUDE_TYPES ".OBJ,.EXE" X Xexcludes any file with a type of .OBJ, .EXE or .DIR X XIf this logical is absent, then no files are excluded on the basis of their` V032 Xfile type (except .DIR). X X X X3. BUG FIXES X XA number of long standing bugs have been fixed. X X X X3.1 Bad split points X XOccasionally, the split point was chosen badly such that the part separators Xwere wrong. In particular, the $GOTO/Label: sequence could appear right afte Vr Xthe $COPY command due to the method by which use of $GOTO was decided. This Xalgorithm has been redesigned and the problem should no longer occur. X X X X3.2 Hangs During Trailing Blank Processing X XWhen wrapping lines containing trailing blanks, the code would sometimes han Vg Xin an infinite loop or fail to split on a non-blank character. This has now Xbeen fixed. X X X X3.3 Temporary Files X XAll temporary files now have a unique name derived from the PID of the curre Vnt`032 Xprocess and are created in the SYS$SCRATCH directory by default. The choice V of`032 Xtemporary filename and location may be overridden by defining the logical na Vme`032 XSHARE_TEMP to whatever is desired. X X X X X4. CHANGES IN OPERATION X XThere are several significant changes in the operation of VMS_SHARE. X X X X4.1 Name of Share File X XPreviously, the share file name was suffixed by a string of the form '_n_OF_ Vm' Xwhere 'n' was the part number and 'm' was the total no of parts. X XThe share file name is now suffixed only by the 'n' value - part number. Thi Vs Xchange is a consequence of the new algorithms used to create the parts, Xwhereby the total number of parts is not known at the time of writing a Xparticular part to a file. X X X X4.2 Obsolete logical names X XLogical names supported in previous versions of VMS_SHARE to control`032 Xverification of the operation of the package are no longer supported. These` V032 Xfunctions have been replaced by the new debugging code. X XThese logicals were SHARE_VERIFY and SHARE_DISPLAY. X X X X4.3 CHECKSUM display X XMessages regarding checksums are now suppressed if they are correct, making V it`032 Xeasier to spot those that are incorrect. X X X X X4.4 Version Numbers X XThe original version numbers of the packaged files are preserved at the`032 Xunpacking stage. Previously, all files created would have a version number o Vf`032 X1. This change allows multiple versions of the same file to be packaged if`0 V32 Xrequired. X X X X4.5 Check Output File Existence X XDuring unpacking, the output file is checked to see if it already exists. If V`032 Xit does, then the file is not overwritten. Instead the file is skipped and a V`032 Xmessage written to that effect. This prevents the previous problem where th Ve`032 Xexistence of the file caused the new version to be ignored without comment a Vnd`032 Xa checksum failure to be produced. X X X X X5.0 TESTING X XThe software has been tested under VMS 4.7 and VMS 5.0-2. It should be noted V`032 Xthat this version of VMS_SHARE is not supported on other versions of VMS,`03 V2 Xalthough it is believed to work on all versions between 4.4 and 5.1 inclusiv Ve. $ CALL UNPACK VMS_SHARE.RELEASE_NOTES;15 725698916 $ create/nolog 'f' X `009TECHNICAL INFORMATION ABOUT VMS_SHARE X X `009`009`009`009`009`009`009`009Version 7.0 X `009`009`009`009`009`009`009`009May 1989 X X X X1. INTRODUCTION X XVMS_SHARE is designed to package a series of files into a form that can be`0 V32 Xeasily mailed across many different networks. Difficulties arise with doing` V032 Xthis because of the many and varied possibilities for corruption of data in` V032 Xtransit. For example, line wrapping, case folding, transposition of key`032 Xcharacters etc. X XVMS_SHARE encodes files before transmission so that these things may be kept V`032 Xunder control and proper restoral effected at the receiving end. X XFor a given series of files to be packaged, VMS_SHARE combines them into a`0 V32 Xsingle large 'text archive' file that can be unpacked into its component fil Ves`032 Xsimply by running it as a command procedure at the receiving end. For`032 Xconvenience, VMS_SHARE will optionally split the result into multiple parts` V032 Xthat can be individually mailed and recombined at the receiving end. X X X X2. WHAT VMS_SHARE DOES NOT DO X XObviously, there are no protocols that VMS_SHARE can use between the Xtransmitting and receiving ends. It relies on the underlying mail system to Xget things there in one piece. Should a single line get missed or corrupted V, XVMS_SHARE cannot detect this and ask for retransmission. VMS_SHARE should Xtherefore be used only over essentially reliable communications links X(reliable in the sense of getting lines whose characters fall within certain Xbounds, there in one piece!).`032 X XVMS_SHARE does not deal with binary files, although it will encode any non Xprinting 8-bit byte into a transmittable format. However, record and file Xformats are not preserved. VMS_SHARE should generally be used only with tex Vt Xfiles.`032 X X X X3. LIMITATIONS OF MAILERS AND HOW VMS_SHARE GETS AROUND THEM X XVarious mail systems have different limitations within them. For instance,`0 V32 Xthey will wrap or truncate lines that are too long, they may limit the size V of`032 Xan individual mail message, they may transpose characters incorrectly if the V`032 Xunderlying character set is different from the transmitter (ASCII/EBCDIC is V a Xgood example of this).`032 X XVMS_SHARE encodes the files in different ways to get around the problems. XPlease note however, that the encoding techniques are NOT foolproof. We have Xmerely tried to anticipate all possible corruptions and devise an encoding Xscheme that ensures the conditions under which corruption occurs does not Xarise. If a form of corruption that has not been anticipated occurs, corrupt Vion Xto the transmitted files will be irreparable except through manual editing.` V032 X X X X3.1 Maximum Size of a Mail Message X XMany mail systems cannot cope with single mail messages larger than a fixed` V032 Xnumber of bytes and will truncate messages or maybe even fail to deliver the Vm`032 Xaltogether. X XThis is a real problem if a large software package is being sent. VMS_SHARE V`032 Xtries to overcome this by splitting the packaged files into several parts,`0 V32 Xeach part being smaller than some fixed size. For example, we might send a`0 V32 Xtotal of 300 blocks of code as 15 parts each of 20 blocks or less. VMS_SHARE V`032 Xwill automatically split at the 20 block boundary. The actual value is`032 Xconfigurable via a logical name (SHARE_PART_SIZE). X XIt should be noted that mail headers added on route can account for several Xblocks worth of extra space so this should be realised when setting the Xmaximum part size. X X X X X3.2 Maximum Line Length X XMany mail systems do not like lines longer than some fixed maximum length, a V`032 Xmaximum length of 80 characters is typical. This results in longer lines bei Vng Xwrapped or truncated at seemingly arbitrary positions.`032 X XVMS_SHARE tries to cope with this by wrapping long lines itself and insertin Vg`032 Xmarkers to allow them to be rejoined at the receiving end. What VMS_SHARE do Ves`032 Xis to prefix each line with a flag character. This flag character says EITHE VR`032 X'this is the first part of a line' OR 'this line is a continuation of the`03 V2 Xprevious line'. The wrapping point is chosen carefully to avoid leaving any V`032 Xtrailing blanks at the end of a line as these are sometimes removed by mail` V032 Xsystems in transit - the trailing blanks are moved to the start of the`032 Xcontinued line.`032 X XThe maximum line size is configured into the TPU code as a global value and` V032 Xcan be easily changed if required. It is not intended that this value should V`032 Xbe altered by the average user however. X X X X X3.3 Trailing Blanks X XWhile on the subject of trailing blank removal, VMS_SHARE will translate the V`032 Xlast character on a line if it is a blank character, into a special 'escape` V032 Xsequence' that can be recognized by the receiving end and translated back.`0 V32 XThus, the transmitted file is immune to trailing blank removals or additions V`032 Xbecause there are none. X X X3.4 Escaped Characters X XProbably the biggest problem is that a mail message moving through many`032 Xdifferent systems on route to the destination may undergo character`032 Xconversions (for example - ASCII to EBCDIC if moving from VAX to an IBM).`03 V2 XUnfortunately, not all systems keep similar translation tables and character Vs`032 Xcan get translated into something unexpected at the remote end. Culprits are V`032 Xcaret (`094), tilde (`126), square and curly brackets ( `091 `093 `123 `125 V ) and a few others. X XVMS_SHARE deals with this problem by replacing each of the troublesome`032 Xcharacters - the ones mentioned above plus any non-printing character - by a Vn Xescape sequence. The escape sequence is recognized at the receiving end and V is`032 Xtranslated back to the original character. Obviously, to work correctly, th Ve`032 Xescape sequence itself must be immune from translation problems.`032 X XThe escape technique used is to replace each character by a string of the fo Vrm`032 X`096nnn where the `096 symbol flags the start of an escape sequence and th Ve 'nnn'`032 Xis a 3-digit string which is the ASCII code for the character. Naturally, th Ve`032 X`096 character itself must be escaped in this form to avoid confusion. For`0 V32 Xexample, a space would be replaced by `096032 and a tab by `096009. X X X X3.5 Detecting Damaged Files with Checksums X XIn cases where some corruption occurs despite the encodings used by VMS_SHAR VE,`032 Xdetection of damage (BUT NOT REPAIR!) should be possible because each file i Vs`032 Xchecked for accuracy using a checksum once it has been unpacked. X XVMS_SHARE uses the currently undocumented CHECKSUM command to produce a`032 Xchecksum value for the source file. This checksum is carried across in the`0 V32 Xpacked share file and checked when the file is restored. A failed match caus Ves`032 Xa message and the receiver can take action to try to locate and repair the`0 V32 Xdamage. X XThe DCL command CHECKSUM filename writes the checksum value into a D VCL Xsymbol called CHECKSUM$CHECKSUM. X X X X X4. VMS_SHARE IMPLEMENTATION X XVMS_SHARE is provided as a combination of DCL and TPU code in order to ensur Ve`032 Xthat it will run on any VMS system. A specific program would be faster of`0 V32 Xcourse but then portability is not guaranteed. X XThe DCL part of the software is used merely to pick up parameters and parse` V032 Xfilenames, passing them to the TPU code in a scratch file. X XThe TPU code does the hard work of packaging the files, wrapping lines,`032 Xescaping characters and generating multiple parts. X XAs distributed, the DCL and TPU code are bundled into a single large procedu Vre`032 Xbut there is no reason why the TPU code could not be extracted and made into V a`032 Xsection file for enhanced speed. The modifications required are quite`032 Xstraightforward. X X X X X X5. USING VMS_SHARE X XAs distributed, VMS_SHARE is run as a command procedure (usually via a`032 Xsuitable symbol set up to point to it) thus:- X X $ @VMS_SHARE filespecs sharefile X Xwhere 'filespecs' is a comma separated list of wildcarded filenames to be`03 V2 Xpackaged, and 'sharefile' is the name to be given to the packaged files (the V`032 Xname will be suffixed by the part number) X XThere are some restrictions on the filenames that can be used: X X - Subdirectories may be used provided that they are beneath the current X directory. It is not permitted to package files in other directories. X X - The name of the sharefile must not appear in the 'filespecs' list X because the software cannot package a file into itself. X X - At least one valid file must be given in 'filespecs' or no sharefile X will be produced. X X X6. UNPACKING A VMS_SHARE FILE X XIn general, a package delivered using the VMS_SHARE software will arrive in V a`032 Xnumber of parts, from 1 up to 'n'. All parts should be concatenated togethe Vr`032 Xin order. It is NOT necessary to remove superfluous mail headers from any pa +-+-+-+-+-+-+-+- END OF PART 5 +-+-+-+-+-+-+-+- Relay-Version: version nyu B notes v1.6 5/10/89; site acf4.NYU.EDU From: UDAA055@ash.cc.kcl.ac.UK Date: 6 Jul 89 10:23 EDT Date-Received: 6 Jul 89 10:47 EDT Subject: VMS_SHARE 6/6 Message-ID: <8907061426.AA17393@ucbvax.Berkeley.EDU> Path: acf4!cmcl2!rutgers!apple!bionet!agate!ucbvax!ash.cc.kcl.ac.UK!UDAA055 Newsgroups: comp.os.vms Organization: The Internet Sender: daemon@ucbvax.BERKELEY.EDU Lines: 79 -+-+-+-+-+-+-+-+ START OF PART 6 -+-+-+-+-+-+-+-+ Vrt`032 Xother than part 1 prior to concatenation. X XThe resulting combined file should then be executed as a command procedure i Vn`032 Xorder to unpack the resulting files. X X X X6.1 Typical Unpack Sequence X XA typical sequence of events goes like this: X X - Set your default directory to a scratch directory which is empty. X X - Go into MAIL and select the folder which contains the parts of the X package. X X - Extract part 1 into a file, using the command 'EXTRACT/NOHEADER fi Vle' X Extract part 2 into a file, using the command 'EXTRACT/NOHEADER/APPEND fi Vle' X ... X ... X Extract part n into a file, using the command 'EXTRACT/NOHEADER/APPEND fi Vle' X X - Read warning below BEFORE proceeding!!! X X - Execute as a command procedure, using the following command: X $ @file X X X X6.2 Warning X XIt is strongly suggested that the generated command procedure ('file.SHAR' i Vn`032 Xthe above example) be carefully checked before execution. It is possible tha Vt`032 Xunscrupulous persons might tamper with the source before sending it and`032 Xintroduce a virus into the VMS_SHARe'd code. There is nothing that VMS_SHARE V`032 Xcan do about this automatically. However, since all the files should be huma Vn`032 Xreadable it should be possible to detect fraudulent code by manual checking. V`032 XCertainly the lines starting with '$' symbols should be checked carefully as V`032 Xthese are most likely to be troublesome. X X X X X7. DECLARATION AND DISCLAIMER X XThis software is in the public domain and may be freely distributed without` V032 Xcharge as required. However, all copyright notices and references to the Xauthor in the source must be left intact.`032 X XThird party modifications may be made to the source but any errors arising`0 V32 Xfrom their use are entirely the responsibility of the modifier. X XThe author accepts no responsibility for the suitability of this software fo Vr Xany specific purpose. Any errors arising from its use are entirely the Xresponsibility of the user.`032 X X X XAndy Harper XKings College London UK X X26-JUN-1989 $ CALL UNPACK VMS_SHARE.TECHNICAL_INFO;10 578359379 $ EXIT