m~ NEWFILES.BCK NEWFILES.BCK-BACK/LOG *.*/EXCL=*.OBJ HOME:NEWFILES.BCK/SAV RICHARD Hw( k̔V5.3 _PUB::  _SALOON$DUA1: V5.3 ~  *[RICHARD.UTIL.SRC]BUILD.COM;1+,!./H 4&h-d0123KPWO56 ܕ*ʔ7 +ʔ8Z9u˔GHHJ$ macro/deb /nolis newfiles$ message/obj fileserr&$ link/nodeb/notrace newfiles,fileserr$ exit 1!*[RICHARD.UTIL.SRC]FILESERR.MSG;12+,Qn./H 4-d0123KPWO565EuL7 UEuL8]9u˔GHHJ"! Error messages for FILES program.facility fls,1/prefix=fls__.severity fatal0SYNTAXERR /fao_count=19INVSPEC /fao_count = 1.severity successLBN_FOUND .severity infoOHDR1 @HDR2 < id Used/alloc /extent (UIC) Name>@FULL "!5UL !11 !9 [!OW,!OW] !AS!AD "/fao=10#BRIEF /fao=9 MSG TOTAL /fao=6.end!*[RICHARD.UTIL.SRC]NEWFILES.EXE;61+,"g./H 4-d0123 KPWO56P^ʔ7^ʔ8%J9u˔GHHJ60DX0205(\JNEWFILES2.2\ʔ05-05  = KTUW  ?! LIBRTL_001P PP/PAPSPePwPPPP@ 0   % 000000P D \SYS$OUTPUT3Pr&.;$D$$DD$ $N$$T$!$F$,$V$7$DD$$D$$N$$T$$V$OSYS$DISK22:<024:<2%,P1$YP1gP1 P1P P PȏPPjQ ^ЎP t!<PP4}(}#P}, }4 P1 I}r݁kP1<j >яPݏ P1:|~[<~P1}>@7|UPPPPRS:TTTP1VVďVVJkYX WXWYXXP1QX WVZ}Up7{{{{{{ݏKP1XZRxRRXRTR1j~jP1aERQnjQ`j1/+z #z<1zz z1 J&Y|~Yݏh|~<1~j~P~S~~j~~ j~ ЎPЎP1 ~~gv~~i~ PFPS~KvRbPPP~^PS~^S~v~P~S~~i~~i~x ЎPЎP1 ~~.v~~i~O PFPS~vRbPPP~^PS~^S~zi~P~S~~Ei~~>i~ ЎPЎP1 ~~u~~i~ PCPS~tuRbPPP~^PS~^S~~P~S~~h~~h~ ЎPЎP1 hR~^P>b~P~hs PbhݏCh]h_hݬެP`1h3h=hXP1$rPuh( h"rsjsP1<}sPPosP1v^ЏP.nRrݏ P (r rS* ( c.*(c;*SSrP)05<SIZEUICBRIEFFRAGMENTSFORMATNAMEOUTPUTLBN/Qs:RRqe 4ue=Qq%XOUqUq==~%*;.`%*. ;H%@*<8="" =[IQpQ9 *tp],Ap*dp]=Up=Up[]FILES.LIS[000000]INDEXF.SYS[000000]INDEXF.SYS[000000]INDEXF.SYS[000000]INDEXF.SYS[000000]INDEXF.SYS[000000]INDEXF.SYS[000000]INDEXF.SYS[000000]INDEXF.SYS[000000]INDEXF.SYS[000000]INDEXF.SYSe(xP{x (J08@H, SYNTAXERRSyntax error in " !AS " 2INVSPEC Invalid file specification : !AS LBN_FOUND LBN foundVHDR1GFile Blocks Fragments Owner File Directory>HDR2. id Used/alloc /extent (UIC) Name@ FULL1!5UL !11 !9 [!OW,!OW] !AS!AD $ BRIEF!+!+!+!+!+!+!+!AS!ADMSG!ASTOTAL!/!UL files selected among !UL searched, !/resulting in !UL/!UL blocks used/allocated,!/and !UL fragments in !UL file headersFLS@@lx` Hx0 @LIBRTL *[RICHARD.UTIL.SRC]NEWFILES.HLP;1+,"z./H 4M-d0123KPWO56@x/ʔ7PW޶ʔ89u˔GHHJ 1 FILESF L'utilitaire FILES permet de raliser des recherches dans le fichier* INDEXF.SYS, selon les critres suivants: - UIC du fichier - taille  - nombre de fragments - nom et ou extensionM Il permet aussi de dterminer quel fichier appartient un LBN particulier d'un disque.2 Qualificatifs/SIZE /SIZE = number? Permet de prciser la taille partir de laquelle les fichiers? doivent tre selectionns par le programme. Tous les fichiersA dont la taille est suprieure ou gale number seront lists. /FRAGMENTS /FRAGMENTS= number> Permet de prciser le nombre de fragments partir duquel les? fichiers doivent tre selectionns par le programme. Tous les? fichiers possdant un nombre de fragments suprieur ou gal  number seront lists.  /NAME /NAME= name.ext8 Permet de slectionner les fichiers d'aprs leur nom ouB extension. Les deux lments doivent imprativement tre fournis.A Les caractres * et % permettent de spcifier lments variables dans les noms recherchs. /UIC /UIC= owner@ Permet de slectionner les fichiers d'aprs leur propritaire. : Le propritaire peut tre fourni sous la forme d'une UIC C ( [groupe, membre]), ou sous la forme d'un identifieur ( [ident],  [ident,ident] ou ident). /BRIEF= Permet de modifier le format d'affichage des informations. ? Les noms complets des fichiers selectionns sont affichs, 9 l'exclusion de toute autre informations, sous la forme:, [dir.dir.dir]nom.ext;version/OUTPUT /OUTPUT= filename= Permet de diriger la liste dans un fichier de nom filename./LBN /LBN= numberB Permet de recherche le nom du fichier auquel appartient le bloc # logique numro number du disque.: Ce qualificatif est incompatible avec les qualificatifs: - SIZE, FRAGMENTS, UIC, NAME/FORMAT /FORMAT= stringK Permet de spcifier un format d'affichage pour les fichiers selectionns.I La chane de caractres string est affiche pour chaque fichier, aprs  avoir remplac dans celle-ci:1 $DD$ par le nom du disque en cours d'analyse6 $D$ par le nom du directory contenant le fichier $N$ par le nom du fichier $T$ par le type du fichier" $V$ par le numro de version3 $F$ par le nom complet du fichier selectionn 2 Exemples"*[RICHARD.UTIL.SRC]NEWFILES.MAR;119+,J".W/H 4OWU`-d0123KPWOX56aq³r7@ؼijr8E6ć9u˔GHHJ0/ .title Files Program to Read Index Header File .ident /2.2/ ; File: FILES.MAR;++ ; Facility:=; Utility to collect information about the size and ownership ; of files.; ; Abstract:9; This program examines the file header file (INDEXF.SYS)9; to retrieve information about the largest files strored6; on disk and who owns them. Back link pointers in the3; INDEXF.SYS file are followed to obtain a complete; directory specification.; ; Command:;!; FILES /SIZE= number ; and or ; /FRAGMENT = number ; and or&; /NAME= [name][.ext][;ver] ; and or; /UIC= uic or identifier ; ;0; /LBN= number ; exclusive with first 4 qual.; ; /BRIEF; /OUTPUT = filespec=; /FORMAT = "string including $D$ and or $N$, $T$, $V$, $F$"1; $DD$ : Device name; $D$ : Directory name; $N$ : File name; $T$ : File type; $V$ : Version number); $F$ : Full name ( $DD$$D$$N$$T$$V$ );;;; Environment:; Needs SYSPRV or READALL; ; Author:2; Mark Oakley, Battelle Columbus Labs, 11-Feb-1984;; Modifications:;9; 11-Mar-1984 Mark Oakley Revised to use mapping routines; to access file headers.;;; 15-Mar-1984 Mark Oakley Fixed bug in check of member uic.;;; 22-Mar-1984 Mark Oakley Added signalling for command line; syntax errors.;:; 7-Apr-1984 Mark Oakley Fixed to print files equal to or%; greater that minimum size. Only%; files greater than minimum were; printed previously.;6; 17-Feb-1985 Mark Oakley Revised to work with V4 file; headers.;=; 22-April-1986 M.Richard Revised to accept V4 identifiers in; UIC specification.-; Modified to display numbar of fragments-; and accept selection flag /FRAGMENT, to&; select only files too fragmented*; /BRIEF (output file specification in.; standard format) and /NAME (selection on; file name);>; 31-oct-1986 M.richard Modified output device handling, added.; /LBN option (find file to which one LBN ; belongs).;8; 20-April-1988 M.Richard Rewritten from orginal version; after loss of source;<; 23-Jan-1989 M.Richard Accept a format command, to generate%; command file directly. (replace*; $D$ in format by directory name and ; $N$ for file name);?; 25-feb-1991 M.Richard Calc total for fragment, extent, space(; used and allocated. Report in last*; output line if full report is needed; Things to do:;;;;--  .sbttl Symbols .library /SYS$LIBRARY:LIB.MLB/ $dvidef ; Device definitions.* $fabdef ; File access block definitions.$ $fh2def ; File-header definitions.' $fi2def ; File-header-id definitions.' $fm2def ; File-header-id definitions.$ $jpidef ; Job/process definitions.# $hm2def ; Home block definitions.( $secdef ; Mapping section definitions.# $ssdef ; Termination definitions. $stsdef ; Status definitions.# $tpadef ; LIB$TPARSE definitions.$ $fscndef ; SYS$FILESCAN definitions" $dscdef ; Descriptor definitions;4; Note that $fh2def lacks the following definitions:;fh2$t_fname = ^x500fh2$l_alloc = ^x18 ; Offset to blocks allocated.+fh2$l_used = ^x1c ; Offset to blocks used.;<; Macro to help set up fabs for each volume in a volume set.; .macro mfab $fab dnm=<[000000]INDEXF.SYS>,- fna=devnam_buf,- fop= .endm mfab;; Macro to handle return codes.; .macro on_err there,?here blbs r0,here brw therehere: .endm on_err;7; Macro to substitute something in a string iteratively;= .macro substitute string, to_subs, by_this, ?loop, ?end_loop pushr #^mloop:/ movl #0, -(sp) ; Starting position for search' movaq to_subs, -(sp) ; string searched& movaq string, -(sp) ; where to search calls #3,g^STR$POSITION! tstl r0 ; zero means not found beql end_loop & movl r0,r3 ; save start position movaq to_subs, r23 addw2 DSC$W_LENGTH(r2), r0 ; compute end position decl r0 movl r0, -(sp) movl sp, r0 movl r3, -(sp) movl sp, r3; movaq by_this, -(sp) ; directory name descriptor address  movl r0, -(sp) movl r3, -(sp)/ movaq string, -(sp) ; source string descriptor4 movaq string, -(sp) ; destination string descriptor calls #5, g^STR$REPLACE popl r0 popl r0$ brw loop ; repeat until not found end_loop: popr #^M .endm  " .sbttl Command line, prompts data, .psect files_data,rd,wrt,noexe,long,shr,pic3flags: .long 0 ; flags used to triger header line ; printingflags_m_first_call = 1flags_m_brief = 2flags_m_lbn = 4flags_m_fid = 8flags_m_name = 16flags_m_output = 32flags_m_format = 64flags_v_first_call = 0flags_v_brief = 1flags_v_lbn = 2flags_v_fid = 3flags_v_name = 4flags_v_output = 5flags_v_format = 6 ;"; string descriptors for FAO calls; fao_in_descr:0fao_in_len: ; One descr with true buffer size .long 512 .long out_buffao_out_descr: fao_out_len:' .long 0 ; One with size given by FAO .long out_buffao_format_in_descr:7fao_format_in_len: ; One descr with true buffer size .long 512 .long format_buffao_format_out_descr:fao_format_out_len:' .long 0 ; One with size given by FAO .long format_bufgiven_format_out_descr:given_format_out_len:) .long 512 ; One with size given by FAO .long given_format_bufgiven_format_in_descr:given_format_in_len:' .long 0 ; One with size given by FAO .long given_format_buf;output_line_descr:output_line_len:% .word 512 ; Varying string used to, .byte DSC$K_DTYPE_VT ; compose output line .byte DSC$K_CLASS_VS  .long output_line_bufoutput_line_fao_descr:output_line_fao_len:" .word 512 ; String used by FAO) .byte 0 ; because FAO does not support .byte 0 ; varying strings .long output_line_buf+2;;; full_descr: .word 0 + .byte DSC$K_DTYPE_T ; compose output line .byte DSC$K_CLASS_S  .long 0 name_descr: .word 0 + .byte DSC$K_DTYPE_T ; compose output line .byte DSC$K_CLASS_S  .long 0 type_descr: .word 0 + .byte DSC$K_DTYPE_T ; compose output line .byte DSC$K_CLASS_S  .long 0version_descr: .word 0 + .byte DSC$K_DTYPE_T ; compose output line .byte DSC$K_CLASS_S  .long 0; root_buff :  .ascii /000000/root_len = .-root_buff;;;fls_q_format_out: .byte 0 .byte 0 .byte 0 .byte 0out_buf: .blkb 512 format_buf: .blkb 512given_format_buf: .blkb 512output_line_buf:, .word 0 ; current length of varying string .blkb 512;$; Descriptors for output file names;output_buff_len = 512 output_len: .long 0 .long output_buff output_buff: .blkb output_buff_len .align long output_fab: $fab dnm=<[]FILES.LIS>, - rat= output_rab: $rab fab= output_fabdefault_output: .ascid /SYS$OUTPUT/;;#; data used for data lines printing;msg_code: .long fls__full;;;command_line_desc: .word command_line_buf_siz .word 0 .address command_line_buf2command_line_buf: ; Store the command line here. .blkb 80+command_line_buf_siz = . - command_line_buf9command_line_len: ; Store the command line length here. .blkl 1-parse_blk: ; Parse block for LIB$TPARSE to* .long tpa$k_count0 ; parse command line.8 .long tpa$m_abbrev ; Permit unambiguous abbreviations. .blkb tpa$k_length0-80min_file_size: ; Search for files larger than .blkl 1 ; this size. total_used:* .blkl 1 ; TOTAL USED FOR SELECTED FILES1total_allocated: ; total allocated for selected .BLKL 1 ; files.grp_uic: ; Search for files with this group .long -1 ; uic..mem_uic: ; Search for files with this group .long -1 ; uic. frag_limit:5 .long -1 ; search for files with more map pointers ; than that frag_count: .blkl 1 ; count accumulator extent_count:% .blkl 1 ; extent count accumulator-frag_total: ; total number of fragment for .blkl 1 ; selected file7extent_total: ; total number of segment for selected .blkl 1 ; files lbn_number: .long -1 ; lbn to search forselected_files: .blkl 1 ; examined_files: .blkl 1 ; file_name_desc: .word 0 .byte DSC$K_DTYPE_T .byte DSC$K_CLASS_S .long file_name file_name:@ .blkb fi2$s_filename+- ; buffer holding file name to search for fi2$s_filenamextrequested_fname_desc: .word 0 .byte DSC$K_DTYPE_T .byte DSC$K_CLASS_S .long requested_fnamerequested_fname:> .blkb fi2$s_filename+- ; buffer holding pattern for file name fi2$s_filenamext period_descr: .ascid /./semiperiod_descr: .ascid /;/ dir_tag_dsc: dir_tag_len:" .long end_dir_tag - start_dir_tag .long start_dir_tagstart_dir_tag = . .ascii /$D$/end_dir_tag =. dev_tag_dsc: dev_tag_len:" .long end_dev_tag - start_dev_tag .long start_dev_tagstart_dev_tag = . .ascii /$DD$/end_dev_tag =. name_tag_dsc: name_tag_len:$ .long end_name_tag - start_name_tag .long start_name_tagstart_name_tag = . .ascii /$N$/end_name_tag =. type_tag_dsc: type_tag_len:$ .long end_type_tag - start_type_tag .long start_type_tagstart_type_tag = . .ascii /$T$/end_type_tag =. full_tag_dsc: full_tag_len:$ .long end_full_tag - start_full_tag .long start_full_tagstart_full_tag = . .ascii /$F$/end_full_tag =.version_tag_dsc:version_tag_len:* .long end_version_tag - start_version_tag .long start_version_tagstart_version_tag = . .ascii /$V$/end_version_tag =.full_trans_dsc:full_trans_len:( .long end_full_trans - start_full_trans .long start_full_transstart_full_trans = . .ascii /$DD$$D$$N$$T$$V$/end_full_trans =.   .sbttl Device data0default_disk: ; Use default if no disk given. .ascid /SYS$DISK/5init_dvi_itmlst: ; Item list to get the root device/ .word devnam_buf_siz ; name of a volume set. .word dvi$_rootdevnam .address devnam_buf .address devnam_len .long 02root_dvi_itmlst: ; Item list used just for first .word 4 ; volume in set. .word dvi$_cluster .address cluster_size .long 0 .word 4 .word dvi$_maxfiles .address max_files .long 0 .word 4 .word dvi$_volcount .address volset_cnt .long 0 .long 00next_dvi_itmlst: ; Item list to get succeeding7 .word devnam_buf_siz ; device names of a volume set,8 .word dvi$_nextdevnam ; disk cluster size, and maximum2 .address devnam_buf ; number of files allowed on .address devnam_len ; device. .word 4 .word dvi$_cluster .address cluster_size .long 0 .word 4 .word dvi$_maxfiles .address max_files .long 0 .long 0 devnam_desc: .word devnam_buf_siz .word 0 .address devnam_buf,devnam_buf: ; Store the device name here. .blkb 50devnam_buf_siz = . - devnam_buf3devnam_len: ; Store the device name length here. .blkl 1'cluster_size: ; Disk cluster factor. .blkl 1'max_files: ; Maximum number of files .blkl 1 ; on disk.6ifb_channel: ; Table of channels to each INDEXF.SYS$ .blkw 10 ; on each volume in set.0ifb_iosb: ; Status for INDEXF.SYS operations. .blkq 13volset_cnt: ; Number of volumes in a volume set. .blkl 1+directory_desc: ; Directory spec will be .word 0 ; stored here. .word 0 .address directory_bufdirectory_buf: .blkb 255&directory_buf_size = . - directory_buf file_desc: .word 0 .word 0 .address file_buf file_buf:& .blkb fi2$s_filename+fi2$s_filenamextfile_buf_siz = . - file_buf % .sbttl Table of Fab's for Volume Set, .psect fab_table,,rd,wrt,noexe,page,shr,pic;); Allow up to 10 volumes in a volume set.;indexf_fab_1: mfabindexf_fab_2: mfabindexf_fab_3: mfabindexf_fab_4: mfabindexf_fab_5: mfabindexf_fab_6: mfabindexf_fab_7: mfabindexf_fab_8: mfabindexf_fab_9: mfabindexf_fab_10: mfabfab_index_table: .address indexf_fab_1 .address indexf_fab_2 .address indeDw~ NEWFILES.BCKJ"d"[RICHARD.UTIL.SRC]NEWFILES.MAR;119OWazxf_fab_3 .address indexf_fab_4 .address indexf_fab_5 .address indexf_fab_6 .address indexf_fab_7 .address indexf_fab_8 .address indexf_fab_9 .address indexf_fab_10 .sbttl Index File Bitmap Buffer4 .psect indexf_file_bitmap,rd,wrt,noexe,page,shr,picindex_file_bitmap:8 .blkb <60*512> ; Allow for bitmap sizes up to 60 blocks ; (29760 files) per volume.8first_ifb_vbn: ; Table of vbn's which are the start of7 .blkl 10 ; bitmap in each INDEXF.SYS for each volume.;header_offset: ; Table of offset's to get to the start of1 ; headers in each INDEXF.SYS for each volume.<last_ifb_vbn: ; Table of vbn's which are the end of bitmap0 .blkl 10 ; in each INDEXF.SYS for each volume. 2 .psect directory_header,rd,wrt,noexe,page,shr,pic;>; Store file header for directory here. This is used to follow>; directiry back-links to obtain a complete directory spec for ; the file.;dir_hd_buf: .blkb 512;O; store file header extension, when one is there and we have to count fragments; ext_header: .blkb 512 & .sbttl Mapped Section Data Structures5input_addr: ; sec$m_expreg will be set, so setting7 .long ^x20000 ; both address's equal guarantees that8 .long ^x20000 ; no more memory is mapped than needed.3return_addr: ; Address of mapped area. This area/ .blkl 2 ; will hold up to 4000 file headers.6mapped_pages: ; Max number of pages mapped at once. .long 40005pf_cluster: ; Number of pages to bring into memory& .long 128 ; if a page fault occurs.Gsect_flag = ; Section is copy-on-reference and& ; expand memory region as needed.  .sbttl Parse Tables;A; State and transition instructions on how to parse command line.;- .psect files_parse,rd,nowrt,exe,long,shr,picsemicolon = 59" $init_state files_state,files_key $state start: $tran tpa$_eos,tpa$_exit ; End of string here is success.* $tran '/' ; Another qualifier detected. $tran tpa$_symbol,start,- ;  ,,devnam_desc $tran ':', start' $state ; Determine which qualifier. $tran 'SIZE',get_size $tran 'UIC',get_uic $tran 'BRIEF',start,set_brief $tran 'FRAGMENTS',get_fragments $tran 'FORMAT',get_format $tran 'NAME',get_name0 $tran 'OUTPUT',get_output,,flags_m_output,flags' $tran 'LBN',get_lbn,,flags_m_lbn,flags $state get_lbn $tran '=' $state& $tran tpa$_decimal,start,,,lbn_number $tran '%' $tran tpa$_any,tpa$_fail $state $tran 'X',hexa $tran 'O',octal $state hexa" $tran tpa$_hex,start,,,lbn_number $state octal$ $tran tpa$_octal,start,,,lbn_number  $state get_output $tran '=' $tran tpa$_lambda,start $state' $tran tpa$_filespec,start,store_output $tran tpa$_any,tpa$_fail $state get_name $tran '=' $state' $tran tpa$_lambda,loop_name,store_name $state loop_name $tran '%',loop_name $tran '*',loop_name $tran tpa$_symbol,loop_name $tran semicolon,ver_name $tran '.' $tran tpa$_lambda,start $state loop2_name $tran '%',loop2_name $tran '*',loop2_name $tran '.',ver_name $tran semicolon,ver_name $tran tpa$_symbol,loop2_name $tran tpa$_lambda,start $state ver_name $tran tpa$_decimal,ver_name $tran '%',start $tran '*',start $tran tpa$_lambda,start $state get_format $tran '=' $state $tran '"' $state! $tran tpa$_lambda,,store_fmt_add $state loop_fmt $tran '"' $tran tpa$_any,loop_fmt $state" $tran tpa$_lambda,start,store_fmt. $state get_uic ; Parse for getting the uic. $tran '=' $state $tran '[',get_grp< $tran tpa$_string,start,get_id ; if symbol: translate ident $state get_grp! $tran tpa$_octal,comma,,,grp_uic6 $tran tpa$_string,comma_id,,,get_id ; translate ident $tran '*',comma,,-1,grp_uic $state comma_id $tran ']',start $tran tpa$_lambda,comma $state comma $tran <','> $state $tran tpa$_octal,,,,mem_uic, $tran tpa$_string,,get_id ;translate ident $tran '*',,,-1,mem_uic $state $tran ']',start $tran tpa$_any, tpa$_fail1 $state get_size ; Parse for getting the minimum $tran '=' ; file size $state) $tran tpa$_decimal,start,,,min_file_size6 $state get_fragments ; Parse for getting the minimum $tran '=' ; fragments count $state& $tran tpa$_decimal,start,,,frag_limit $end_state  .sbttl Parse utilities, .psect parse_util,rd,nowrt,exe,long,shr,picget_id: .word 0, $ASCTOID_S name=PARSE_BLK+TPA$L_TOKENCNT, - id = mem_uic on_err main_exit movzwl mem_uic+2,r0 movl r0,grp_uic movzwl mem_uic,r0 movl r0,mem_uic movl #1,r0 ret set_brief: .word 0 movl #fls__brief, msg_code bisl2 #flags_m_brief, flags movl #1,r0 ret store_output: .word ^M moval PARSE_BLK,r0$ movl tpa$l_tokencnt(r0), output_len3 movc3 output_len, @tpa$l_tokenptr(r0), output_buff movl #1,r0 retstore_fmt_add: .word ^M bisl2 #flags_m_format, flags moval PARSE_BLK,r0E movl tpa$l_tokenptr(r0), given_format_out_len+4 ; save start address movl #1,r0 ret store_fmt: .word ^M moval PARSE_BLK,r0 movl given_format_out_len+4, r23 subl3 r2, tpa$l_tokenptr(r0), given_format_out_len decl given_format_out_lenB movc3 given_format_out_len, (r2), given_format_buf ; copy stringM movab given_format_buf, given_format_out_len+4 ; complete descriptor movl #1,r0 ret store_name: .word ^M bisl2 #flags_m_name, flags movl sp,r8 clrl -(sp) clrl -(sp) rotl #16, #FSCN$_VERSION, -(sp) clrl -(sp) rotl #16, #FSCN$_TYPE, -(sp) clrl -(sp) rotl #16, #FSCN$_NAME, -(sp) clrl -(sp) movl sp,r7 pushl TPA$L_TOKENPTR(ap) pushl TPA$L_STRINGCNT(ap) movl sp,r0 pushl r7 pushal 4(r7) pushl r0 calls #3,SYS$FILESCAN on_err store_name_exit& addl2 #8,sp ;skip string descriptor. movl #fls__invspec, r0 ; assume it's an error5 bitl #FSCN$M_TYPE ! FSCN$_NAME ! FSCN$_VERSION, (sp) bneq 0$1 pushal parse_blk+- ; yes capture the string and$ tpa$l_tokencnt ; signal the error pushl #1 pushl #fls__invspec calls #3,g^lib$signal brb store_name_exit0$: tstw 4(r7) beql 1$ ; no name2 movc3 4(r7), @8(r7), requested_fname ; store name brb 2$1$: moval requested_fname, r3 movb #^a/*/,(r3)+2$: tstw 12(r7) beql 3$ ;no type> movc3 12(r7), @16(r7), (r3) ;r3 comes from preceeding movc3 brb 4$3$: movw #^a/.*/,(r3)+4$: tstw 20(r7) beql 5$ ;no version> movc3 20(r7), @24(r7), (r3) ;r3 comes from preceeding movc3 brb 6$5$: movw #^a/;*/,(r3)+6$:< subl2 #requested_fname, r3 ; store length of requested name movw r3, requested_fname_desc movl #1,r0store_name_exit: ret  .sbttl Main program, .psect files_code,rd,nowrt,exe,long,shr,pic1 .entry files,^m= jsb parse_comm_line ; Override default values as necessary. on_err main_exit& jsb init_output ; open output device on_err main_exit: jsb compute_offsets ; Compute offsets to 1st file header$ on_err main_exit ; and other info.6 jsb search_bitmap ; Search for valid headers, output on_err main_exit ; results. main_exit: cmpl r0, #fls__lbn_found' beql 5$ ; don't report lbn found and& blbs r0, 5$ ; don't report success. pushl r0 calls #1, g^lib$signal5$: bisl2 #STS$M_INHIB_MSG,r0 pushl r0 ; save status ; and close output file" moval output_fab, r1 ; if needed* tstw fab$w_ifi(r1) ; close output file ? beql 10$ ; no, branch $CLOSE fab=output_fab10$: popl r0 ; get back status ret  .sbttl Open device for output;A; This routine opens the device specified in the command line, or"; SYS$OUTPUT if none was specified; init_output:2 bitl #flags_m_output, flags ; /output specified ? bneq 10$ ; branch if present3 movzwl default_output, r0 ; tell STR$COPY how long# movl r0, output_len ; name can be8 pushaq default_output ; put default output device name+ pushaq output_len ; into output file name calls #2,g^STR$COPY_DX;10$: $FAB_STORE - ; set up FAB fab = output_fab, - fna = output_buff, - fns = output_len $CREATE fab = output_fab on_err init_output_exit $CONNECT rab = output_rabinit_output_exit: rsb   .sbttl Parse Command Line;9; This routine scans the command line for uic, file size,; and a device name.;parse_comm_line:7 movq default_disk,- ; Assume device is default device) devnam_desc ; until we find otherwise.- pushl #0 ; See what's on the command line. pushal command_line_len pushl #0 pushal command_line_desc calls #4,g^lib$get_foreign on_err parse_comm_line_exit3 movzwl command_line_len,- ; Set up for LIB$TPARSE. parse_blk+tpa$l_stringcnt moval command_line_buf,- parse_blk+tpa$l_stringptr pushal files_key pushal files_state pushal parse_blk calls #3,g^lib$tparse5 cmpl #lib$_syntaxerr,r0 ; Did we get a syntax error? bneq 30$2 pushal parse_blk+- ; Yes, capture the string and% tpa$l_tokencnt ; signal the error. pushl #1 pushl #fls__syntaxerr calls #3,g^lib$signal30$: on_err parse_comm_line_exit& $getdvi_s - ; Get root volume name. devnam=devnam_desc,- itmlst=init_dvi_itmlst on_err parse_comm_line_exitA movw devnam_len,devnam_desc ; Must restore what we or LIB$TPARSE. moval devnam_buf,- ; did to this descriptor. devnam_desc+4parse_comm_line_exit: rsb  .sbttl Find a specific LBN;?; This routine searches bitmap and file headers for a specific; LBN-; it returns 1 if lbn belongs to current file; 0 if not'; and something else if a error occured;B; Code from FRAGDISK found on some decus tape ( author:J.Y.Collot); find_lbn: pushr #^m clrl r50$: movzbl FH2$B_MPOFFSET(r2), r0 addl2 r0,r0= addl3 r0,r2,r3 ; r3 contains address of current map element movzbl FH2$B_MAP_INUSE(r2),r4 addl2 r4,r4 bneq 1$ clrl r0 brw find_lbn_exit1$: movzwl FM2$W_WORD0(r3),r0" ashl #-14,r0,r0 ; get type bits bicl2 #^xfffc,r0% caseb r0,#0,#3 ; placement control2$: .word 3$-2$  .word 4$-2$ ; format 1 .word 5$-2$ ; format 2 .word 6$-2$ ; format 33$: subl2 #FM2$C_LENGTH0,r4 addl2 #FM2$C_LENGTH0,r3 brw 8$4$: movzwl FM2$W_LOWLBN(r3), r0/ extzv #FM2$V_HIGHLBN, #FM2$S_HIGHLBN, (r3), r1! insv r1, #16, #FM2$S_HIGHLBN, r0 cmpl lbn_number, r0 blssu 45$ movzbl FM2$B_COUNT1(r3), r1 addl2 r1, r0 cmpl r0,lbn_number blssu 45$ brw find_lbn_exit_ok45$: subl2 #FM2$C_LENGTH1, r4 addl2 #FM2$C_LENGTH1, r3 brw 7$5$: movl FM2$L_LBN2(r3), r0 cmpl lbn_number, r0 blssu 55$- extzv #FM2$V_COUNT2, #FM2$S_COUNT2, (r3), r1 addl2 r1, r0 cmpl r0,lbn_number blssu 55$ brw find_lbn_exit_ok55$:  subl2 #FM2$C_LENGTH2, r4 addl2 #FM2$C_LENGTH2, r3 brw 7$6$: movzwl FM2$L_LBN3(r3), r0 cmpl lbn_number, r0 blssu 65$ pushl r0 movzwl FM2$W_LOWCOUNT(r3), r1- extzv #FM2$V_COUNT2, #FM2$S_COUNT2, (r3), r0 insv r0,#16,#FM2$S_COUNT2, r1 popl r0 addl2 r1, r0 cmpl r0,lbn_number blssu 65$ brw find_lbn_exit_ok65$:  subl2 #FM2$C_LENGTH3, r4 addl2 #FM2$C_LENGTH3, r37$: incl r5 8$: tstl r44 bleq 9$ ; see advice in count_fragments (about pb) brw 1$9$:0 movzwl FH2$W_EXT_FID(r2),r0 ; get volume number beql find_lbn_exit movzwl FH2$W_BK_FIDRVN(r2), r10 movzwl header_offset[r10], r61 addl2 r0,r6 ; get block number where extension ; header will be found# $qiow_s chan = ifb_channel[r10], - func = #io$_readvblk, - p1 = ext_header, - p2 = #512, - p3 = r6 on_err find_lbn_exit  movl #ext_header, r2 brw 0$find_lbn_exit_ok: movl #1,r0find_lbn_exit: popr #^m rsb % .sbttl Calculate number of fragments;E; This routine count the number of map pointers in the file header(s);B; Code from FRAGDISK found on some decus tape ( author:J.Y.Collot);count_fragments:! pushr #^m clrl r5 ; fragment count clrl r7 ; extent count0$: movzbl FH2$B_MPOFFSET(r2), r0 addl2 r0,r0= addl3 r0,r2,r3 ; r3 contains address of current map element movzbl FH2$B_MAP_INUSE(r2),r4 addl2 r4,r4 bneq 1$ brw count_fragments_exit1$: movzwl FM2$W_WORD0(r3),r0" ashl #-14,r0,r0 ; get type bits bicl2 #^xfffc,r0% caseb r0,#0,#3 ; placement control2$: .word 3$-2$  .word 4$-2$ ; format 1 .word 5$-2$ ; format 2 .word 6$-2$ ; format 33$: subl2 #FM2$C_LENGTH0,r4 addl2 #FM2$C_LENGTH0,r3 brw 8$4$: subl2 #FM2$C_LENGTH1, r4 addl2 #FM2$C_LENGTH1, r3 brw 7$5$: subl2 #FM2$C_LENGTH2, r4 addl2 #FM2$C_LENGTH2, r3 brw 7$6$: subl2 #FM2$C_LENGTH3, r4 addl2 #FM2$C_LENGTH3, r37$: incl r5 8$: tstl r4% bgtr 1$ ; seems there is a pb with,9$: ; some specific placement control... ; put bgtr instead of bneq0 movzwl FH2$W_EXT_FID(r2),r0 ; get volume number beql count_fragments_exit movzwl FH2$W_BK_FIDRVN(r2), r10 movzwl header_offset[r10], r61 addl2 r0,r6 ; get block number where extension ; header will be found# $qiow_s chan = ifb_channel[r10], - func = #io$_readvblk, - p1 = ext_header, - p2 = #512, - p3 = r6 on_err count_fragments_exit  movl #ext_header, r2 incl r7 brw 0$count_fragments_exit:% incl r7 ; add one for first header movl r7, extent_count movl r5, frag_count popr #^m movl #1,r0 rsb  .sbttl Compute offsets;D; This routine computes the first block in INDEXF.SYS which contains ; a header.;compute_offsets:$ clrl r5 ; r5 holds volume number.* $getdvi_s - ; Get the root name of this$ devnam=devnam_desc,- ; volume set. itmlst=root_dvi_itmlst on_err compute_header_exit; brw skip_on_first ; Skip past next $GETDVI on first loop. next_vol:B movw devnam_len,devnam_desc ; Make sure device name length is ok.4 $getdvi_s - ; Get infomation about maximum files,> devnam=devnam_desc,- ; cluster size, and next volume in set. itmlst=next_dvi_itmlst on_err compute_header_exitskip_on_first: movl r5,r4, incl r5 ; Set r5 to point to next volume.3 movl fab_index_table[r4],r4 ; Compute fab address.7 movb devnam_len,- ; Remember to set the length of the* fab$b_fns(r4) ; device name in the fab.;1; Compute the start of the file headers, which is.; 4 * disk cluster factor + bit map file size.;@ divl3 #4096,max_files,r2 ; Bitmap file size is max files / 4096 incl r2 ; + 1. mull3 #4,cluster_size,r3* addl2 r2,r3 ; File header offset in r3.;1; Save start and end vbn's of index bit file map.; movl r3,last_ifb_vbn[r5] subl2 r2,r3 incl r3 movl r3,first_ifb_vbn[r5]0 $open fab=(r4) ; Open the file for "user" file& on_err read_bitmap_exit ; processing.5 movw fab$l_stv(r4),- ; Remember the channel number. ifb_channel[r5]& cmpl r5,volset_cnt ; End of volumes? bgeq 10$ brw next_vol 10$:;+; Take care of case where we are processing.; just one device (that is, not a volume set).;# movl header_offset+4,header_offset movw ifb_channel+2,ifb_channel# movl first_ifb_vbn+4,first_ifb_vbncompute_header_exit: rsb  .sbttl Read Index Bitfile Map;+; Read the index bitfile map in INDEXF.SYS.; read_bitmap:7 movl last_ifb_vbn[r5],r3 ; Number of bytes to read is:? subl2 first_ifb_vbn[r5],r3 ; (last vbn - first vbn + 1) * 512. incl r3 mull2 #512,r32 $qiow_s chan=ifb_channel[r5],- ; Read the bitmap. func=#io$_readvblk,- iosb=ifb_iosb,-' p1=index_file_bitmap,- ; Read buffer.& p2=r3,- ; Number of bytes to read.0 p3=first_ifb_vbn[r5] ; Where to start reading. on_err read_bitmap_exit movzwl ifb_iosb,r0 on_err read_bitmap_exitread_bitmap_exit: rsb $ .sbttl Search the Index Bitmap File;B; This routine searches the index header bitmap for valid headers.>; When a valid header is found, it is read from disk. Selected; fields are printed.;search_bitmap:% movl #1,r5 ; r5 is volume pointer.10$: jsb read_bitmap on_err search_bitmap_exit* clrl r4 ; Initialize max header number. clrl r10 ; Pointer into ifb.4 moval index_file_bitmap,r11 ; Get base addr of ifb.2 subl3 first_ifb_vbn[r5],- ; r6 will hold the size. last_ifb_vbn[r5],r6 ; (in long words) of the decl r6 ; index bitmap file. mull2 #<4096/32>,r6 incl r620$:- movl (r11)[r10],r9 ; Get next entry in ifb.$ clrl r8 ; Bit pointer into entry.2 movl #32,r7 ; Size of entry to search, in bits.30$:' ffs r8,r7,r9,r8 ; Look for a set bit.! beql 40$ ; Is there a bit set?= jsb read_write_header ; Yes, get information on this header. on_err search_bitmap_exit* subl3 r8,#32,r7 ; Any more bits to check bgtr 30$ ; in this entry?40$:8 aobleq r6,r10,20$ ; Get next entry if max not reached.' aobleq volset_cnt,r5,10$ ; Next volumeH bbs #flags_v_brief, flags, search_bitmap_exit ; if brief : no totalline pushl extent_total pushl frag_total pushl total_allocated pushl total_used pushl examined_files pushl selected_files pushl #fls__total3 calls #7, g^fao ; Write total blocks allocated and" on_err search_bitmap_exit ; used.search_bitmap_exit: rsb ) .sbttl Read and Write Header Information;A; This routine reads a file header from disk and outputs selected; information about the header.;read_write_header:;>; Compute page offset in memory of where the header is mapped.;. incl r8 ; Compute file id as (bit pos +1) +3 movl r10,r2 ; 32 * (number of bitmap long word). ashl #5,r2,r2 ; $ addl2 r8,r2 ; r2 has file number.. cmpl r4,r2 ; Is this file header in memory? blss 40$ brw in_memory ; Yes.40$:2 tstl return_addr ; No, see if we need to perform$ beql 60$ ; any "unmapping" first. $deltva_s - inadr=return_addr on_err read_write_header_exit60$:C addl3 header_offset[r5],r2,r1 ; Get where to start read from disk./ $crmpsc_s - ; Bring the headers into memory. inadr=input_addr,- retadr=return_addr,- flags=#sect_flag,- chan=ifb_channel[r5],- pagcnt=mapped_pages,- vbn=r1,- pfc=pf_cluster3 cmpl #ss$_endoffile,r0 ; Did we reach end-of-file? bneq 80$+ movl #32,r8 ; Yes, fix things up so that1 addl3 #1,r6,r10 ; we move on to the next volume' clrq return_addr ; (if there is one). movl #ss$_normal,r0 brw read_write_header_exit80$: on_err read_write_header_exit< subl3 #511,return_addr+4,r3 ; r3 has start addr of max hdr.< subl3 return_addr,- ; Compute highest numbered file number return_addr+4,r4 ; in memory. ashl #-9,r4,r4 addl3 r2,r4,r4 in_memory:0 subl3 r2,r4,r2 ; Header location in memory is:4 ashl #9,r2,r2 ; loc = r3 - 512 * (max_files - r2) subl3 r2,r3,r2 ;; Check for a valid header.;, tstw fh2$w_fid(r2) ; Is the file number 0? bneq 20$> brw read_write_header_exit ; Yes, this is not a valid header.20$:< tstw fh2$w_seg_num(r2) ; Is the extension segment number 0? beql 30$= brw read_write_header_exit ; No, this is not a valid header.30$:- tstw fh2$w_checksum(r2) ; Is the checksum 0? bneq 40$> brw read_write_header_exit ; Yes, this is not a valid header.40$:;:; this is a valid header, increment searched header count; incl examined_files( bitl #flags_m_name,flags ; check name ? beql 42$ calls #0, check_name ; yes blbs r0, 42$< cmpl #STR$_NOMATCH, r0 ; if error is different from NOMATCH$ bneq 41$ ; then report and abort movl #1,r041$:7 brw read_write_header_exit ; else try with next header42$: ;=; Header is valid, does file meet our criteria for reporting?;, bitl #flags_m_lbn, flags ; search for LBN ? bneq 43$ brw 45$43$: tstl lbn_number bneq 435$ movl #fls__lbn_found, r0 brw read_write_header_exit435$: jsb find_lbn on_err 44$ clrl lbn_number brw 70$ ; success, count fragments, ; writ name and exit44$:. tstl r0 ; null -> no error, try next header bneq 455$ ; else report error incl r0 ; so status is 1;455$:F brw read_write_header_exit45$:4 rotl #16,fh2$l_alloc(r2),r1 ; Is file large enough? cmpl min_file_size,r1 bleq 50$ brw read_write_header_exit 50$:0 tstl grp_uic ; Should we test file group uic? blss 60$a1 cmpw grp_uic,- ; Yes, do the group uic's match?B fh2$w_uicgroup(r2)$ beql 60$ ; Yes, keep on checking./ brw read_write_header_exit ; No, don't report.60$:, tstl mem_uic ; Should we test member uic? blss 70$T2 cmpw mem_uic,- ; Yes, do the member uic's match? fh2$w_uicmember(r2)o beql 70$ ; Yes./ brw read_write_header_exit ; No, don't report.a70$: jsb count_fragments2 tstl frag_limit ; should we test fragments count blss 80$$ cmpl frag_limit, - ) frag_count ; is count ok for display ? blss 80$D beql 80$m. brw read_write_header_exit ; no, don't report80$: :;r=; Get back-link of file to determine complete directory spec.;dir_bkl:' pushr #^mh@ movzwl fh2$w_bk_fidrvn(r2),r10 ; If the file and directory are+ tstl r10 ; on the same volume, then thei, bgtr 10$ ; fh2$w_bk_fidrvn field will be/ movl r5,r10 ; zero. Thus, use the file rvn.e10$: moval dir_hd_buf,r8 movw #1,directory_descO8 movb #^a/[/,directory_buf ; Start dir spec with a "[". moval directory_desc,r7 addl2 #1,4(r7)o? movzwl fh2$w_backlink(r2),-(sp) ; Trace backlinks to see which1 calls #1,g^bk_link ; directory the file is in.e moval directory_buf,4(r7) addl3 (r7),4(r7),r64 cmpw directory_desc,#1 ; are we in root directory? bgtr 20$h pushr #^m ; yes9 MOVC3 #root_len,root_buff, (r6) ; store root namep popr #^mt6 addw2 #root_len, directory_desc ; update descriptor incw directory_desc# addl2 #root_len, r6 ;and pointer  incl r620$: decl r6. movb #^a/]/,(r6) ; End dir spec with a "]".;n'; update count for fragments, extents,d;t# ADDL2 frag_count,frag_totalN( ADDL2 extent_count, extent_total incl selected_fileswrite_header_info: pushal extent_count pushal frag_count pushal directory_desc( movl r2,r6 ; Will need R2 for MOVC3. pushaw fh2$w_fid(r6)o> movzbl fh2$b_idoffset(r6),r7 ; Get word offset to file name.) mull2 #2,r7 ; Convert to byte offset.5( addl2 r6,r7 ; Add in header address.7 movc3 #fi2$s_filename,- ; Move first part of filenamea. fi2$t_filename(r7),- ; to file name buffer. file_buf8 movc3 #fi2$s_filenamext,- ; Move last part of filename0 fi2$t_filenamext(r7),- ; to file name buffer.) (r3) ; R3 got set by previous MOVC3.i;n/; update count for space used by selected filesf;  MOVL fh2$l_used(r6), R0 ROTL #16,R0,R0i ADDL2 r0,total_used$ MOVL fh2$l_alloc(r6), R0i ROTL #16,R0,R0 ADDL2 r0,total_allocated pushab file_buf pushal fh2$l_alloc(r6); pushal fh2$l_used(r6) pushaw fh2$w_uicmember(r6)t pushaw fh2$w_uicgroup(r6) calls #9,write_it& popr #^mread_write_header_exit:o rsb  .sbttl Follow Backlinks; 2; Recursive routine to follow directory backlinks.;l3 .entry bk_link,^m ; addl3 header_offset[r10],- ; Compute block which containsf+ 4(ap),r9 ; the file header for the dir.a1 $qiow_s chan=ifb_channel[r10],- ; Read a block.e func=#io$_readvblk,- p1=(r8),- p2=#512,-r p3=r9l on_err bk_link_exit8 movzbl fh2$b_idoffset(r8),r11 ; Get word offset to id.$ mull2 #2,r11 ; Compute to bytes.- addl2 r8,r11 ; R11 points to start of id..7 movc3 #fi2$s_filename,- ; Move first part of filenameo' fi2$t_filename(r11),- ; into buffer. file_buf9 movc3 #fi2$s_filenamext,- ; Move last part of filename,s3 fi2$t_filenamext(r11),- ; this instruction MUST l* (r3) ; IMMEDIATELY follow prev instr.1 locc #^a/./,#,-s% file_buf ; Compute length of this- subl2 #,-t r0 ; portion of directory mnegl r0,r6 ; string.(5 cmpw fh2$w_backlink(r8),4(ap) ; Are we at [000000] ?y beql 20$i) subl2 r6,sp ; Make room for directory(+ movc3 r6,file_buf,(sp) ; name and length.s pushl r6m4 movzwl fh2$w_backlink(r8),-(sp) ; No, keep tracing. tstw fh2$w_bk_fidrvn(r8)p beql 10$  movzwl fh2$w_bk_fidrvn(r8),r10t10$: calls #1,g^bk_link< on_err bk_link_exit20$: movl (sp)+,r6, movc3 r6,(sp),@4(r7) ; Adjust descriptor. addl2 r6,sp addl2 r6,(r7) addl2 r6,4(r7) * movl #ss$_normal,r0 ; Indicate success. bk_link_exit:1 ret r .sbttl check name* .entry check_name, ^m* movl r2,r8 ; use r8 for base of header7 movzbl fh2$b_idoffset(r8),r11 ; get word offset to id2# mull2 #2,r11 ; compute to bytes, addl2 r8,r11 ; r11 points to start of id8 movc3 #fi2$s_filename, - ; move first part of filename& fi2$t_filename(r11),- ; into buffer file_name.9 movc3 #fi2$s_filenamext, - ; move last part of filenameo1 fi2$t_filenamext(r11),- ;this instruction MUST f' (r3) ; IMMEDIATELY follow previouse ; onee2 locc #^a/ /,#, -& file_name ; compute length of this ; filename. subl3 r0,#,- r0) movw r0, file_name_desc ; and store ito' pushal requested_fname_desc ; patternn+ pushal file_name_desc ; candidate_stringm$ calls #2,g^STR$MATCH_WILD ; same ? ret e .sbttl Output information .entry WRITE_IT, ^m6 bbc #flags_v_format, flags, 3$ ; is a format is there% brw 2$ ; skip standard processingV3$:c9 bbs #flags_v_brief, flags, 1$ ; if brief : noheader line_< bbs #flags_v_first_call, flags, 1$ ; if full and first call0$: ; output header line.< bisl2 #flags_m_first_call, flags ; and remember it has been ; done pushl #fls__hdr12 calls #1,FAOu pushl #fls__hdr20 calls #1,FAOK on_err write_it_exitp1$:n2 locc #^a/ /,#, -, @20(ap) ; compute length of the current ; filename. subl3 r0,#,- r0) movl 28(ap),-(sp) ;dir_name descriptorn) movl 20(ap),-(sp) ;file_name address s* movl r0 ,-(sp) ;file_name max length1 movl 28(ap),-(sp) ;dir_name descriptor address& movzwl @8(ap),-(sp) ;uic membership! movzwl @4(ap),-(sp) ;uic group& movl @36(ap), -(sp) ; extent count movl @32(ap),-(sp) ;fragments movl @16(ap),r0 rotl #16,r0,r05# movl r0,-(sp) ; blocks allocatedu movl @12(ap),r0 rotl #16,r0,r0  movl r0,-(sp) ; blocks used! movzwl @24(ap),-(sp) ; file_id  pushl msg_codep calls #12,FAO brw write_it_exit;o; Use given format for output.;f;2$:b/ movw #0, output_line_buf ; set CURLEN to zero$" ; before starting line setup0 pushaq given_format_out_descr ; copy format in* pushaq output_line_descr ; output buffer calls #2,g^STR$COPY_DXi2 locc #^a/ /,#, -% @20(ap) ; compute length of thise ; filename. subl3 r0,#,-$ r0 ; then create a descriptor moval full_descr, r1e: movl 20(ap), dsc$a_pointer(r1) ; name descriptor address / movw r0, dsc$w_length(r1) ; save name lengtha& movl 20(ap), r2 ; get string address / movl #0, -(sp) ; Starting position for searcht, movaq period_descr, -(sp) ; string searched* movaq full_descr, -(sp) ; where to search calls #3,g^STR$POSITION tstl r0 beql 25$; decl r025$: moval name_descr, r1  movl r2, dsc$a_pointer(r1)L movw r0, dsc$w_length(r1)3 addl2 r0, r2 ; update string address for typei/ movl #0, -(sp) ; Starting position for search 0 movaq semiperiod_descr, -(sp) ; string searched* movaq full_descr, -(sp) ; where to search calls #3,g^STR$POSITION moval name_descr, r1tJ subw2 dsc$w_length(r1), r0 ; substract name length to compute type length decw r0) moval type_descr, r1 ; update type descr* movl r2, dsc$a_pointer(r1) ; with address% movw r0, dsc$w_length(r1) ; and sizet' addw2 r0, r2 ; update string pointerc  movaq version_descr, r1 movl r2, dsc$a_pointer(r1)o moval full_descr, r0f movl dsc$a_pointer(r1), r2n subl2 dsc$a_pointer(r0), r2 movzwl dsc$w_length(r0), r0 subl2 r2, r0E movaq version_descr, r1 movw r0, dsc$w_length(r1);l;f;s substitute output_line_descr, - full_tag_dsc, - full_trans_dscm;;;u substitute output_line_descr, - name_tag_dsc, - name_descrS;.;g;q substitute output_line_descr, - type_tag_dsc, - type_descrg;t;n;r;l substitute output_line_descr, - dev_tag_dsc, -. devnam_desc;e;d;s substitute output_line_descr, - version_tag_dsc, -d version_descr;g; Locate Directory position_; and replace iti; substitute output_line_descr, - dir_tag_dsc, -o @28(ap);-;a5$:v moval output_line_fao_descr, r29 movab dsc$a_pointer(r2), -(sp) ; setup indirect locationc# movl sp, r0 ; for data locationa< movaw dsc$w_length(r2), -(sp) ; address of word for length0 movl r0, -(sp) ; address for adress of string2 pushaq output_line_descr ; descriptor to analyze calls #3, g^STR$ANALYZE_SDESC ;6 movw r0, dsc$w_length(r2) ; length seems to be there ; despite what help says pushaq output_line_fao_descrg pushl #fls__msg calls #2,FAO_write_it_exit: ret n .entry WRITE_TOTALS,^m<>a ret s0 .sbttl FAO, format output line to output device;t; 4(ap) message code; 8(ap) FAO argument 1; .(ap) FAO argument...;_ .entry FAO,^m<>;; First get the FAO formatl; $GETMSG_S - msgid = 4(ap) ,- msglen = fao_format_out_len,-n! bufadr = fao_format_in_descr, -$ flags = #1, - outadr = fls_q_format_out.;t; then format output;_ moval 8(ap), r0) $FAOL_S ctrstr = fao_format_out_descr, - outlen = fao_out_len, -  outbuf = fao_in_descr, -3 prmlst = (r0) ; prmlst is already built on stack. on_err fao_exit;; and write it downf;. $RAB_STORE - rab = output_rab,- rsz = fao_out_len, - rbf = out_buff $PUT rab = output_rab fao_exit:. ret .end files.dress cluster_size .long 0 .word 4 .word dvi$_maxfiles .address max_files .long 0 .word 4 .word dvi$_volcount .address volset_cnt .long 0 .long 00next_dvi_itmlst: ; Item list to get succeeding7 .word devnam_buf_siz ; device names of a volume set,8 .word dvi$_nextdevnam ; disk cluster size, and maximum2 .address devnam_buf ; number of files allowed on .address WiJ"d"[RICHARD.UTIL.SRC]NEWFILES.MAR;119OWzygSf`bvAF@b$7J0&8^ kn&$;-p*.%8*&k9'(OO] IC|A[j^&1*8':<'8:3*-B&/REoa[,sf*w^tOeye(pOgf,shv,_imH iZdgzyfilf_bium p:8 .blkb <60*512>; Anw fmrbioaA si{eA ut Go 60 `l$c Y ;w(2=7y0$filgs rez @oLOʔ0QiҠ}t߬_~bV:abdeo sh.cf )rg ; Store file header for directory here. This is used to follow>; directiry back-links to obtain a complete directory spec for ; the file.;dir_hd_buf: .blkb 512;O; tlre file heades!Dx^e5! ,&mr3F0:i#@6r*.f=$ ! r3@)s0^ZcvN um&cCu?sNfsacmKnws;/ e0thQafg:  ,bkb 512 & .sbttlMLpe SeatYonFaEa SurGctqrVs5kn;u `d4r: ^ ;$s*c m_ezpGef iZlWfe),(sX S01"?1.3280 0|tl &djr-sq'; wa& aventees!that8+.MO+{1 ]UCChnlHRM);)e>ER m}p^CYg IUprVfI>dd}:'zl^R({Afm2)>1%x$ 7hs-XAo] `@BNKMHa)+)3CDI =!vg`us)oU% V EBe sFe+ EI(HZ7F,'CEO^f ppgKE)C .El"0((\zt9 LBNf1RustkrzllII: d O fh43Vlz2LRINGbSME+mCn}]LONGFF\]{))IFAf EFAULTOCCURS D.r-Ra' udnAECMCRFSECM6XPR0[mA? I@ XNOPY OFx;&OERENCEA mC>I O\Ew)lZQT;(LT\SS,l]D2%NP@JO0)KD1b >,[5O^R-#)L(2S2!vN N00Rre}hHD @EE UY@ERBUBN/sH/7J]TVny "=gafK5<a&<1a/fdQ@AEu I Ber HeleNtlJP nFIM0?DNNX_ENBSI'`_H6L llC \LYVcaVemHA;SU48Eo 1A G< E6YheldlVJNfNBerZeTd $tranpa$_eos,tpa$_exit ; End of string here is success.* $tran '/' ; Another qualifier detected. $tran tpa$_symbol,start,- ;  ,,devnam_desc $tran ':', start' $state ; Determine which qualifier. $tran 'SIZE',get_size $tran 'UIC',get_uic $tran 'BRIEF',start,set_brief $tran 'FRAGMENTS',get_fragments $tran 'FORMAT',ge_eormat $tran&oAgE|~.&<<%C0dIE ' "3Gb i? Oi^wt[uu.*f@adQ8m^oqt^uo,fleg\' ltRaZ &LBL',|et_pbn,,flcgs_m_lbn,flags-m%stave9ge]lSn  tren:'' $8t dv %t%an t?a8_deaiXam,{tWr|rڨ_fuZbe^rin1'%Srin0tМQΣ,pp&$Qf)inOqt+t6 $tran'X',hex M$,ran 'Zbualیe hePa"x8an tp$_hx,start,,,lbn_number $state octal$j1%''E1#a$_octal,start,,,lbn_number 2'state get_out`(ʝ$qBTC9=' $trant}a%_labda.sta~t:$stte7$?rantpa+_fi|erp1c,sart4stobe]o tpu$trqnt'a$_kjy,opa$Sfui? ltte geU_nbme $tsk"@eosK_9Btaۋ۠ӓӌیۋӓۋӓۋ۠ӓۋӉۋۋ۠ӌ $state loop2_name $tran '%',loop2_name $tran '*',loop2_name $tran '.',ver_name $tran semicolon,ver_name $tran tpa$_symbol,loop2_name $tran tpa$_lambda,start $state ver_name $tran tpa$_decimal,ver_name $tran '%',start $tran '*',start $tran tpa$_lambda,start $state get_format $tran '=' $state $tran '"' $state! $tran tpa$_lambda,,store_fmt_add $state loop_fmt $tran '"' $tran tpa$_any,loop_fmt $state" $tran tpa$_lambda,start,store_fmt. $state get_uic ; Parse for getting the uic. $tran '=' $state $tran '[',get_grp< $tran tpa$_string,start,get_id ; if symbol: translate ident $state get_grp! $tran tpa$_octal,comma,,,grp_uic6 $tran tpa$_string,comma_id,,,get_id ; translate ident $tran '*',comma,,-1,grp_uic $state comma_id $tran ']',start $tran tpa$_lambda,comma $state comma $tran <','> $state $tran tpa$_octal,,,,mem_uic, $tran tpa$_string,,get_id ;translate ident $tran '*',,,-1,mem_uic $state $tran ']',start $tran tra$_cny, tpa$_nil1 $state get_size ; Parse for getting the minimum $tran '=' ; file size $state) $tran tpa$_decimal,start,,,min_file_size6 $state get_fragments ; Parse for getting the minimum $tran '=' ; fragments count $state& $tran tpa$_decimal,start,,,frag_limit $end_state  .sbttl Parse utilities, .psect parse_util,rd,nowrt,exe,long,shr,picget_id: .word 0, $ASCTOID_S name=PARSE_BLK+TPA$L_TOKENCNT, - id = mem_uic on_err main_exit movzwl mem_ui`{2,r0 movl r0,grp_uic motzwl mem_uic,(ovlr0,mem_uic movl #1,r3P rgt set_brief: .word 2 movl #flsGbrtf, sg_code bisl2 #flags_m_a"ief,"flags movl #1,r0 rev store_ouhut P movcl PARSE_BLK,r0$ movl tra$l_tokencntj0)moutbut_len3 movc3 output_len,#tpa$n_tokenptr(r0), output_budf movl #1j0W refstore_fmt_add: .word M bisl2 !flags_m_forml, ags moval PARSE_BLK,r0E ml&l tpc$l_tokenptr(r0), given_fmrmat_out_len, ;Wave2start address movl #1,r3P rgt store_fmt: .word ^M>r2,r3,r4,r5,/,r oval PARSE_BLK,r0 movl d9ven_dormat_out_len+4, r23 su`l3 r2, tpa$llokptr:r0), given_format_out_lenP decn given_format_out_lenB oovc3 given_fjmaoutMlen, (r2), given_format_buf( ;pkop(stang mabnivUd_fxmaUbuf, gitenmormat_~t_lgn+ -; cmmpjte des}iptmW  motl ,r0  retstore_``me:/word9n} B,r3,r4,r5,r7,r8> bisl2 #flags_m_name, flags movl sp,r8 clrl -(sp) clrl -(sp) rotl #16, #FSCN$_VERSION, -(sp) clrl -(sp) rotl #16, #FSCN$_TYPE, -(sp) clrl -(sp) rotl #16, #FSCN$_NAME, -(sp) clrl -(sp) movl sp,r7 pushl TPA$L_TOKENPTR(ap) pushl TPA$L_STRINGCNT(ap) movl sp,r0 pushl r7 pushal 4(r7) pushl r0 calls #3,SYS$FILESCAN on_err store_name_exit& addl2 #8,sp ;skip string descriptor. movl #fls__invspec, r0 ; assume it's an error5 bitl #FSCN$M_TYPE ! FSCN$_NAME ! FSCN$_VERSION, (sp) bneq 0$1 pushal parse_blk+- ; yes capture the string and$ tpa$l_tokencnt ; signal the error pushl #1 pushl #fls__invspec calls #3,g^lib$signal brb store_name_exit0$: tstw 4(r7) beql 1$ ; no name2 movc3 4(r7), @8(r7), requested_fname ; store name brb 2$1$: moval requested_fname, r3 movb #^a/*/,(r3)+2$: tstw 12(r7) beql 3$ ;no type> movc3 12(r7), @16(r7), (r3) ;r3 comes from preceeding movc3 brb 4$3$: movw #^a/.*/,(r3)+4$: tstw 20(r7) beql 5$ ;no version> movc3 20(r7), @24(r7), (r3) ;r3 comes from preceeding movc3 brb 6$5$: movw #^a/;*/,(r3)+6$:< subl2 #requested_fname, r3 ; store length of requested name movw r3, requested_fname_desc movl #1,r0store_name_exit: ret  .sbttl Main program, .psect files_code,rd,nowrt,exe,long,shr,pic1 .entry files,^m= jsb parse_comm_line ; Override default values as necessary. on_err main_exit& jsb init_output ; open output device on_err main_exit: jsb compute_offsets ; Compute offsets to 1st file header$ on_err main_exit ; and other info.6 jsb search_bitmap ; Search for valid headers, output on_err main_exit ; results. main_exit: cmpl r0, #fls__lbn_found' beql 5$ ; don't report lbn found and& blbs r0, 5$ ; don't report success. pushl r0 calls #1, g^lib$signal5$: bisl2 #STS$M_INHIB_MSG,r0 pushl r0 ; save status ; and close output file" moval output_rb, r1 ; if needed* tstw fab$w_ifi(r1) ; close output file ? beql 10$ ; no, branch $CLOSE fab=output_fab10$: popl r0 ; get back status ret  .sbttl Open device for output;A; This routine opens the device specified in the command line, or"; SYS$OUTPUT if none was specified; init_output:2 bitl #flags_m_output, flags ; /output specified ? bneq 10$ ; branch if present3 movzwl default_output, r0 ; tell STR$COPY how long# movl r0, output_len ; name can be8 pushaq defaulwoutput ; put default output"fevice name+ pushq o~tput_len ; into output fim! name calls #2,g^STR$COPY_DX;10$: $FAB_STORE - . set uz H@ZP5E-uip:!Gt|fab^6- fna = output_buff, - fns = output_len $CREATE fab = output_fab on_err anit]output_exit $CONNECT rab = output_rabt_exit: rsb  .sbttbvvrse Command Line;9; This routine scans the command line for uic, file size,; and a jd~ce name.;parse_comm_line:7 movq default_disk,- ; Assume device is default devhck Jdv``HdeH` ;bntM(se fyd K0,Aqwisn6$c$ pus~t #]- ; SD} wL'P$s oB8thAvGmmaY| lM*! $\$->QWgbn&ߟd d Rߞ鐍J&S$T9;d<8TIG'³E("y,q<  "d l &.!5l57GYXsj"DOY}`j7?4TZ\0vnY<[PF0&b}"rs 1*&*!< 5$7 5?@$OXimbsNv73#`uza80+d+`\o5s]#Yk>gn_(.N%rYx de2& wqR rX$Snm^oateY-Fbr5 -2v8:pidϯ\ eYt}t[Zt;&bE3L̅3ے 0P2JLۼ;ߍܙg2SaՉ>%FO2$#2NmG߯ce⒏w!QTrR7_~s55{Ewv53LdNT7!vP\rUvV{t!Rgv 5&Ci4N-:;=aQbls% d$X)5f030݉ur7AݽX$3{/m:$5$CFGTMt(axR[*%cv1$j|aw ٢LNA#L|#CQL爓>3rqjjP63tZps r2Sh'۬S70$ r3y>3u3"ocܹ3tg\AMe-㬹L2$Y)I׍Eߍdx]=!"]bxqI?~qavK]V3v" 1qڲ`3<!cy\&9rk o8 48ypݣ.0[ H>_Wi%m1%2\OF!ZsW.Y |"Y+Bߘ823;>z#`rLSQ% ;fa}=Jߝ$? dYݬ $q ! _Pn^jni[O|#oaRw5xf7$I4b]OB 2xt_812n)'_.vҜX\vBwu39pZ" W|n:J81|"^VnC n&h5**,>f>t{Z&kmq_r$'c\I2_>9 ok:PP(̬T9]a_e|mt[q^=u@4MYӍsR݆Qc  ._m`vla5#_nXEvo4"1men$~Q~Y*o^N} Ua^QT~%r5"?m `?9$N8ϓߝe #hePf(rDk<ߙmHRA}dKr%2 onpߛ4gp 43t62ѦP=Wwc%}v6%h 8 # ӔEӍMRGR5:9,r߼kX "Ywb73i>3= s2 [b5a : ϼ wct w|!NúF[B7$$;p: OSwW w5cZ~wkw5<,#YٵpAiit^ ~[wth 3}!bYZwQv%4d}LWYZE8< dYP< MZw`wx 2ʎY?C(> wwV  I~k6Y`3̌%A0  N^c~x 4s6jbfJGE&[LENCTH7, ۻqeoaܹ{+CMLޯgZ1a:RpQP SCtVY ćnQߌh=$: j5nT׆?~Al5dz $h>wteg(mYB3R6TDŽ]ZTߘ`χdpjl2 6s d(m{&n`V?!Ot|b#g6wub":ߢhiw|:wNb1ww0a^284e;" vp{jP>*v Wٴ4di4\Ne~r߻npxiofƮg{mF9a-pd)c!ysC,%Auw~J8N2ZⲤrxt 6,^ e29=?#1,-5Z@*vhi1BNIL)735D&!!=) ,&9 5>7< QU]LB[~&#),_fr# na[aca45r=uhGmen@sX % in^h#xDd5=0bo=4ni&Q'gKlghzI r<ܙXq~O0 ^og@{}<b8,I%$r=gyH6#3 ӄ%8= Pw"ԌᚑOMq/u(o:j4RT",:+2Cq-6-^Q]oTU.*biLcfM?, /UBCYJ8en%++EDUoXU<-+6=>G'YS[>0C[Y@& #14]'cX[9]_F\9/|b6qXj.Z0=8\9B99Trn ,f\fy'4@_Y^D}=!d+=>Zs/lPROCESSING D` f\$l_stv(r0ah;'I6EME8 OHN  NUMBERUXC )IFBCHA  [25] & g+% EC##LRTEcB;8&(nldPDVZ##CT8)R)[(-0IPFfm!LS(#6W-nextVvolCREEF%+!+ ++ +a@*!2care of `, "#V)6r we gre u& 7$? HAFUb ]ITS CIOFHAUu%S_EHDZOMZS @@f Rn!\!@W9EHE 4FU@ ;CGI  >UEM n +HND9gJ  %el0 Zfirst_ifb_vbn+4,first_ifb_vbncompute_header_exit: rsb  .sbttl Read Index Bitfile Map;+; Read the index bitfile map in INDEXF.SYS.; read_bitmap:7 movl last_ifb_vbn[r5],r3 ; Number of bytes to read is:? subl2 first_ifb_vbn[r5],r3 ; (last vbn - first vbn + 1) * 512. incl r3 mull2 #512,r32 $qiow_s chan=ifb_chan.el[25],- ; >eadXthe"bitmap. func=#io$_readvblk,- aosb; When a valid header is found, it is read from disk. Selected; fields are pritfd.;se`sChub2&$"8{RD U]$#X?[`lb7bO@E~s\}l9HtoGulg&pCivVr/*70$:&j}bArEaP_`k9map ok_sr earch_bitmap_exot-dclrn B4 ;IniuiSli~emax hga/e_ou=bes.H gl=lr10 <;#PgiXt% ؾ afU.dWۥad QnaQeWbPt͜ ? ez *aqehap %ffb$6 subm3 first_iabnV$'7f],-O;RzIET.,l6:ZKrdlA3 )RQ8_RDlXHM H NAR FH 5)D,-(L*p'ZPh I NBARKs4s| Fz+4RcAC) C `^iev"0 )MO[L}I]]L{n1} R))) BXEEM Tzb  )CL_LgU)l}O7IX  miNTOi N CWt) `WW }l{VI= EOUTCEE ^T NILBJ CQVNNc| {r7,R Ym`HQ9 Ak for/aS4AGc@t`ql 10 Z@S~ Is/tHJ!,z$_IUM?Pl}RD/ :E EhRL5STF M  L  SF ]%) 6}SH,0  pKr)BAfJMN^WRcf|HaSM H  5o Kpa)eVAz})HUR EENYgaheTMmkBfB XCXC ) ; Ge~ A#*5g(+:&*3iF+39g#*:t!XA Kr)1 ) L< ^RYI^KdYR+E ntsh)}JL*3B Y,IRE : T:E EXT N EAH  = ]HLe tZnT9  rb yhA1T rs mU n 1 fU eTtvleg z) KD_giLev:NH=0shlsEC+"9 Y]ejt pMsH\nuKe d l/%)fN0UEIA T E^C  him1%R1,,R)R`_E]F CDM0B E ]CAp joA%r>*4d)2 Y }QIR_C[o`^RllA _hHUSoo`XHUEHSFO  @].)cRpL)>Q_R\fdzC&P  EF SIEQgzB}QBfca[)N_TeMO^lqXL,An `eDKOFe)lR 2 gz=YSS  RnIeDTOPERFORM )B>{TM{'mRR<M ZMNfius[aYTYq0elteaSbFTY\=SAQ n_aYdR Ne{ +E)  8I R;Tun$f_SLS&r)D\dH>Hset_rn<2,|1) ':WEo 1tAR$EOEMhe Ce)J MC9CE`l{A7 A SL NOENoRYBosix| NA PU*  Ic m`JrrET6N.JDwa}`LJ /@H8alH NI> 2Fg -7 ))]A4*41M'"1")>54ISydC& GH;'n=u1k_RDH$fc=afCC3<&(3g=)gDss$eND?  U)HP FRRCOYO  \hhglB {\As f` {PAI]j}`TN7 /iX8 I   cE{DG{J_KRS_QooRCEMRO HUHI RZO scLR U 2)_AFFC HCI onT) 4 )I+2H)S3 O LHiz) A0Tx :eNiT $$|na{O:EdRD; 0A +t Pe)ZlQ*1 RETQlHCG STSr (NI,E E4Gle$:M^Hn}}\FY;Ia;W YK5]_.QJPgZ;zes]2; ZN,Ezr`z#(/TDYIO  T Rf|ICrht^rYaof]l0+MO M  IxjFF 6 F': HehrXa)I- i N5?2 M!0%Yag=(f`yQV$=? =buBMH SIL+6M fum Q-pEwd)VHGJLW {@BJ BCUJ"r )BRW)READWRITEHEADEREXIT %$pw Ie)_ubU  K*{EHRM]FAcdo{L d bz_U|dklVF$)XR1`[UNadl 22)z|G7ASI f NYxgVlg}zO$)3)_lISTN RaGdlq`}$B$|[leTlR)-MJ1HHn tJKvAR[os,tsyndxO feZD Vi{ g@,$2G^ES6y!5"9RRE 7.6ZLEiocW {02)HNTRItStNzmKtdkXPLzt}lR&*E HECnH> -59 %:rTT!fGXPE FM1VmoX(K2%C$vA;^_QXlm G*A n:Z`iz PfM:F /E^D}igel 9-  } RjE7 qeyiO ;?  wQr$EJLX*4U&belB)DB SH EORBCJ`c'bmsH 0h2$. Z8^JDV8G FhPL<zmD DT G NIH Q&4l`gh&$LV|`jnI LVrf_m 0 2t$^ Z\]D)"RH* 'iiqW}E6I 3 A> X)TRko)mfg.R TZhat$m_^MWYm) 'M*3 iF 22)Za SWRRM RM R|m)  .0]; jg ZDf|HL Ks- _otSlZH+_LQV.>A T, Tyep4 DM:IE []2V=Bl902)1JJrzLsw2rXa_VE@D5- LU\Jil5G&`XH/H)6 NEERMepp aSpeg`N1fja\dlg}zgIJT j>Z$ )zaf|! DISOF  SN)ooB nUUJP`$cVyeo{ ;L \T SLllj  T&Oia.>e-;YNOoM ]f{)m`ToglpB lKP+f olVDA 2k{~{J#624I\ *E6 IP^C ECH ^oI} 19WN`nh[sdRrVA3LTA CDc-$+KL  OOO ut^{d`glF P eiIe]tT{J^188 M.zi-b!UdiAilUyV*MXDEV UBYEQRVH]H\9{897a/LN))N[J3IV@QA _U)Eynii Oal)o`LSMGrdcOoJyh@UAyA8K D'[RCRa7ETL ANEIrz h 9-h]TH,K0ICheWdwRe^O/Nn$\VNU?~RXh{mzCAtAASONELOR @rape03 d  h R9:B^[clpCO^lS]M rOcOf{pVmA7GoQn) hW~V{KE  R>Fhg_KtZ{})m`VnWP RWEANC6G2mPvZe;QDY^K@nm(]1E_nrmh'Q)EC@IOM o}JHW\: OKMr)$!zy |HE0R  T=E TWCaBt#cZeez*^Y.)`oFE TT E | RNz in}s)V3dhr^cuoIy^bNf/4_)akdezJCE%gQUF@64cd^`}@! @):!~bcP3wi#\(l5J in?rfKV j}TR=ZijGo[^Muog[sBr8 ^WJ{:RrWel)ZCJ BLOCKDE+&8*G`LAP_eAD@ VkNF ELM_^Lh_ET IOCBp$o]o*WV4[@DUZD-`DTINIWqlBn%@f{B" $SEY DDxs'iJc~JP j}TR30JLclDWoJ0@ {ad;_m)KO!RBdojN oXmt[_JI&!dlGlRKfdTV/hS.A:_MB@fg)_E# IN^Fc)S E)+fzdrVIaOIOP N SHom oV z%E+ dfRJtIONS  H`0 Y6O2$R_| ZBQ)8GkdI+ T\K@TbzU4word nf]sYtT"AETABY zLB)ESNof{)^A N MOI YEV T]P\.a_d`2\[MEfdoZBadmBa XN{QTTBUC.gyDL5)X0jZJD $zV X  M@VkNFaB}e)oIJ df)H hL gi $k_]I! E\AMCme^ TECbtf]eh..dhl0 *JrV% @A~_o hUTI_l 1 D ) EbaR \)H h oe{{fi3$O_QiWE#T\ZYOz}RTEFE  GBFR]]r`gORZ]l{h}RV7_YgntsXt)LA T$;#7V'trhn\BtTXEB0SJOMLOE;L Pstll RoJ2O43,i& M#9#y\h$e2 m B !@& io8hQE_B5\=CoiONFORS$%6/Z U0%V:Q{s%mb~?yOa +C[W[OH7Ti)? "-x*BB^;^K~$sP WHE3!d8])UM ylV hWVHg^CT[T%<;(6@)'MeV{ {@|zaZLs]:O GOTcnmp{sa x aWJ )r?)=AW)Fl|`jVEBHn ygth;I)j0J `2:ch ~0h$1M#:,:aTAXB[%,]5{ \AAXIR X_LEW,z19Zec{ UqdVl-XIAIM/Lqet3kve{- ~0 C}:jOAD Khcgl`m HP IReXu{Q{ + SXO NEf~D  YB I MsiKoramJ p mkV%,]RCr;,{XCZ%RIr0%^G_Q sOr`HL!HD^R,T(CY3K mlHC1ebe AaI BTLAO ;)mQ[GMPfg)HT GF C  8ffA)G\^oS]vU;*'2J&`agMVXing+8Bm-kIW[  Ph)kWO^wt)|M9b HrgofyJ1-({HF\_ (^D5"q4,$\bnmdq34r8l+ogq}b 1Xne y ) FEb_EdfH\{^@@BnmhOAk HNIO  \p`ul_2oOSK 8'efg\)sfdyNTLSB Yo) W{RPIUT{)e`UER>1)yf`gOSPNt6oL]qZ_oljB ;Snti :Ark{RE+fXTyrA-No`QEZqmFgzV 6TMVoTL]|a IBnDsChd^)`ST^vu ]g_f|VkHF 2m Tz| 6TK2elSA[QntJAhnH;0 R,A {I_t  >:NZeooTd_ >:F{8 = oWA6}{HCGxoL,2 V3Dadl!{ =  ]L(*>2.!1<,TofQLZw4p G1+ArmPteRCU)"^Z/ /O DB-F/-*N ?,s(oh 6 j{3;C * ]}a)f]; SdHsjUFaHW* NNli; 0eP_SceqZG^PK$ktVkV ohT+ C\,d <&uegWIenBe^K{2oRFsiOe)gF K1-amkeGF1FY@wO ;4AO(OA/oY^oTU.CMC>o . f@]E_iG_eXe;{ <l)mlHC?A TOUOUC(!C TGwieK3 %NDh}dBmp    q|tV 3r%mRaf2  }9GP(3YkKigEDVN%!zy)tN+O[I EIA@9bpT558 wh; 0 VwMOpn VW_Vd~tV% z$b_);ELvCEoen>0-oghY]A*8G gis N8 gB &L//$_rx`Zlojg;WMLknV h\,\M,d6Ki)\{WXwvH%GK = n`ME/; A: -UU..e e{?S?`e) zLI^_jn)D*sFr!,=XGG gCvl0{N{= rlaW,`0f|}KU=1 +EYus[tpxt=6 1: BLt3so{lA12 I2Vh\ Lz  tE%.l@ lj,6 O1%9<|e;h{;RPCDCP MXDEliDemfXpW%6kJ-BVxl4 6$k)~oRkO NoO-[ig0z FT+6,G-\L_C  TUT( E0:EUimTo{ |Y]*;RbE{`gnU P E2.oKy}KyXeQmme )]ODBl)OHt^TSPTUOant)AY10dfMCEhQ\CS, ue%Afg\)U6E/ ]g ]imeUale ^H+;Thde!\F^[H$9; igZ Yo"61/KVM20< :hd^ZodfVGPS3 e{adK XE$MZx&05)a?2,')pir} N`\enmm \eVmQVNVoieKqD!r1 OpOa- cM%,0&,316;g)vu0;MHsl)GGY|})eRN,MXEMg#-1)Pd5,H'04l1!6):fu{e.efgn9; cnBeV {Wh/)[LN`-stf`Blo5*o,20< 15dlCT]CM]Isl) *A gl . jA ld?&J,++l.5s+;`s'efgn2ficeGog,P{H9,* BElF|]Es)OW dQ})RSC Q e}Zfo)ZR  xd)^zFX\fV8$CDl`SS9-BYTF   NPIlH!i] wrPOT1 ; NeTNPn bisfV,31\izs}q %tlhICNV-fNTT9 Fmn U+B V 9 Xebkf|OP+F7  er,l`@BUggBU# +29 Hsn_jE N) ZORff("!s\)$6SNE_*i})^&7Pf|}y|}dR TeT eoBQS0*EmkakcalcsmFWM3-;*~u}Rl#oB,<{cTS-,48<&] 0,}ANK.*oUVhW-E#lXJ_p{ gD^`//5#QmG;SeK"A{,9enaleCt?,--2 R2SG HNmVeRN0 _@V  {TT?lBCUDRVCSJllO {U^ \G BjZz)hWL Eje'mdvf4P^wLHH0%\ e*?%{ &t_L)8<3()4~ {6bn-,|gOokty[L oWl{;))BQO3&83P,=]Y:<, ntmcfY ^hBCGO5W`;-HMDF< t>, -CrhnF_\)T U TFOR d of{  2 gPdl';) P}T EU $' 1J S;-zV]I ESNHV foRClnMENTFEE s mKyEf{;) f ^r.e3.ee$9!hK @B SKA, EG1& HEE:  No hJz8& VOvx HMM @(9 Nh%r8kLKW)BhlName/l 7amC_mV :0!OF^D{ 2Ez0!*J,%0=" ,')BY[e)<5HB|s`a~{,#9 L<{ ~i L0A[2caZNlbfC-:1H_% JOlI  GSH Ge)VhL9 jc{ SP ]IEL-I N hc lPGI5:3I57,'*uNZm{Ll;qwx,KV 1:.)76,0d,)\]fug lFID; E :`o [TM|nh LI {NLjBmH1MPDe+ 2A TlDOV`gGPAOT A RS GN kezSFORTY [$spf`  dFHX -(~pYl{RO7+ ] {ozG Do@\seaccl]iyV _rbomq %sp);D-Hoh X_} ) g\Wleq {INIw[OAHHRTT,<ygchBgD G-'5 P+:; =.)fth){1 YE]c,)\P)i`zZF3&d}cA;3+I r< _E*-ba V3+EUcfC):D 1(-)}-TLvVwlZ 8DESMRnmlMptT :D,M 4MAvb {MS -N{4+MAzeFnMlMHOddeHeV(mS is E:3+M )-;)O N` xnh ;SnR SS{}VUA;5s}\ GP- `ml_lanm}vh- CO 1.h ]bKsl$10-\V R; mbvy* 8;H,-rDkeV3eY$E_yA{MUvXYW1hanSXBFh {/$EDCY$nh;GE"A1D <IR@_2 !abd3rl^L`0 tiXl dAthsubCt e*ee`gldD0RHEKpue}) R1A6CKI[ d. nSKK .Sb~%Dr2H/5$vIn`0Vee`g^/ 2D  TgeM } V fSA6 iAtl\_@M%IMHddB+Z`g_I CTNe) B dp%_{m)_VK-R E t}ogOadXrlV {* qnnZ L@L_S LGhddL mrl]O)W_rd ToO1oi}3{9% aD)e`HTASURFRSz zZ; =y|zSAfU1L qpezMf{_)D V6T6agO EszC}FAsS$6]R-o".">SeoSMEZmWTDdM[vb {[Oj)A1 N^Lz ( eKEEX+ IStae{Krogn)9 2 mKlChtt)FDzAt$V gu`p|Z> ,A0-~tp|]gDoLC_VmzIaoghL\s #,($7+_dviQie`}V^X _i e tn n m z[ `95~TLq# &%EsH;R_ _bqfV  7STeGT d#2oCFFRUT lQnlR |T; dvUy )PA CES I6aUmE@M3,} h\  SseMgOE>\FOHt NHHimeHqleA RNYAF? XLdsH eMg'-NnlO Ij#oO)ff\  0*&)Zg;%I Mce|r 4ULLS_ |l|z3ZX)fhA3 dAD_fu}q H$N k[)DK  :nLdl]HRHW| dh3EN *1%Aoug)_u}am\LRNeSoq^fcraa:C^d^w:- }FRfR N+^sR%Cad)%TMrlW5a+))=h+r  1-ef|}V_E ^E tqe)m NN\MA:ZVll@NLFB59 puAP %DXSMRIVvgh-t =(U_ghVVz})`H2D HU I  KBunn lHag_lV jl21 S+Imf~g]!DR]e jH'26:!t)3&}O_: {OLVLfDtpRt2=JDzez3{zs)+6NE_/oo) EN zu}q 1 p::)K ouBp=- hnelq`}PakTof+caO eI SK R,=7e;*[ -6V_zG bw\fgn2_n)ehMO eUYe5ig J TvB=2 Vlz ;)}SOA1",4#]SPS)A }I_nz..~AbQ=1:.lT;PefejTU mve{D ML T>CeudKL ' 8.kBgV diBe &; , Ndez})M`IE* YLCTI TBuyclK> 9'~fIDzT  A:HVs`T~fIDmEFite)@ EI Y,J8.jT {=B~dlX k2Q\UkD  Y, sSPAVI@U [rlM  :Fde|n3*lzXgudLR oVieez ~ET }n.hJSIg_buf file_buf:& .blkb fi2$s_filename+fi2$s_filenamextfile_buf_siz = . - file_buf % .sbttl Table of Fab's for Volume Set, .psect fab_table,,rd,wrt,noexe,page,shr,pic;); Allow up to 10 volumes in a volume set.;indexf_fab_1: mfabindexf_fab_2: mfabindexf_fab_3: mfabindexf_fab_4: mfabindexf_fab_5: mfabindexf_fab_6: mfabindexf_fab_7: mfabindexf_fab_8: mfabindexf_fab_9: mfabindexf_fab_10: mfabfab_index_table: .address indexf_fab_1 .address indexf_fab_2 .address inde